Ticket #6981: replex_fix_sync.3.diff

File replex_fix_sync.3.diff, 10.4 KB (added by Joe Ripley <vitaminjoe@…>, 10 years ago)

Merged replex_fix_sync.2.diff with updates to mythburn.py, added '-g' option

  • mythtv/programs/mythtranscode/replex/element.h

     
    124124        uint32_t mode_extension;
    125125        uint32_t emphasis;
    126126        uint32_t framesize;
     127        uint32_t frametime;
    127128        uint32_t off;
    128129       
    129130} audio_frame_t;
  • mythtv/programs/mythtranscode/replex/replex.c

     
    4141#include "replex.h"
    4242#include "pes.h"
    4343
     44#include "avcodec.h"
     45#include "avformat.h"
     46
    4447#ifndef O_LARGEFILE
    4548#define O_LARGEFILE 0
    4649#endif
     
    7881        return -1;
    7982}
    8083
     84int encode_mp2_audio(audio_frame_t *aframe, uint8_t *buffer, int bufsize)
     85{
     86       AVCodec *codec;
     87       AVCodecContext *c= NULL;
     88       int frame_size, j, out_size;
     89       short *samples;
     90       
     91       fprintf(stderr, "encoding an MP2 audio frame\n");
    8192
     93       /* find the MP2 encoder */
     94       codec = avcodec_find_encoder(CODEC_ID_MP2);
     95       if (!codec) {
     96               fprintf(stderr, "codec not found\n");
     97               return 1;
     98       }
     99 
     100       c = avcodec_alloc_context();
     101
     102       /* put sample parameters */
     103       c->bit_rate = aframe->bit_rate;
     104       c->sample_rate = aframe->frequency;
     105       c->channels = 2;
     106         
     107       /* open it */
     108       if (avcodec_open(c, codec) < 0) {
     109               fprintf(stderr, "could not open codec\n");
     110               av_free(c);
     111               return 1;
     112       }
     113
     114       /* the codec gives us the frame size, in samples */
     115       frame_size = c->frame_size;
     116       samples = malloc(frame_size * 2 * c->channels);
     117       
     118       /* create samples for a single blank frame */
     119       for (j=0;j<frame_size;j++) {
     120               samples[2*j] = 0;
     121               samples[2*j+1] = 0;
     122       }
     123               
     124       /* encode the samples */
     125       out_size = avcodec_encode_audio(c, buffer, bufsize, samples);
     126       
     127       if (out_size != bufsize) {
     128               fprintf(stderr, "frame size (%d) does not equal required size (%d)?\n",
     129                               out_size, bufsize);
     130               free(samples);
     131               avcodec_close(c);
     132               av_free(c);
     133               return 1;
     134       }
     135
     136       free(samples);
     137       avcodec_close(c);
     138       av_free(c);
     139       
     140       return 0;
     141}
     142
    82143static int audio_jump(struct replex *rx)
    83144{
    84145        int i;
     
    255316                                return c;
    256317                        }
    257318                       
    258                         if (aframe->framesize > diff){
     319                        if ((int) aframe->framesize > diff){
    259320                                if ( re == -3){
    260                                         c+= pos+1;
     321                                        c += pos+1;
    261322                                        return c;
    262323                                }
    263324                               
     
    268329                                return c;
    269330                        }
    270331                }
    271                 if (aframe->framesize > diff){
     332                if ((int) aframe->framesize > diff){
    272333                        c += pos+2;
    273334                        //fprintf(stderr,"WRONG HEADER2 %d\n", diff);
    274335                        return c;
    275336                }
    276337        }
    277338       
    278        
     339        // try to fix audio sync - only works for mpeg audio for now
     340        if (aframe->set && rx->fix_sync && first && type == MPEG_AUDIO){
     341                int frame_time = aframe->frametime;
     342                int64_t diff;
     343                diff = ptsdiff(trans_pts_dts(p->pts), add_pts_audio(0, aframe,*acount + 1) + *fpts);
     344                if (abs ((int)diff) >= frame_time){
     345                        fprintf(stderr,"fixing audio PTS inconsistency - diff: ");
     346                        printpts(abs(diff));
     347
     348                if (diff < 0){
     349                                diff = abs(diff);
     350                                int framesdiff = diff / frame_time;
     351                                fprintf(stderr, " - need to remove %d frame(s)\n", framesdiff);
     352                               
     353                                // FIXME can only remove one frame at a time for now
     354                                if (framesdiff > 1)
     355                                        framesdiff = 1;
     356                                iu->pts = add_pts_audio(0, aframe, -framesdiff);
     357                                c += aframe->framesize;
     358                        } else {
     359                                int framesdiff = diff / frame_time;
     360                                fprintf(stderr, " - need to add %d frame(s)\n", framesdiff);
     361                               
     362                                // limit inserts to a maximum of 5 frames
     363                                if (framesdiff > 5)
     364                                        framesdiff = 5;
     365
     366                                // alloc memmory for  audio frame
     367                                uint8_t *framebuf;
     368                                if ( !(framebuf = (uint8_t *) malloc(sizeof(uint8_t) * aframe->framesize))) {
     369                                        fprintf(stderr,"Not enough memory for audio frame\n");
     370                                        exit(1);
     371                                }
     372
     373                                // try to encode a blank frame
     374                                if (encode_mp2_audio(aframe, framebuf, sizeof(uint8_t) * aframe->framesize) != 0) {
     375                                        // encode failed so just use a copy of the current frame
     376                                        int res;
     377                                        res = ring_peek(rbuf, framebuf, aframe->framesize, 0);
     378                                        if (res != (int) aframe->framesize) {
     379                                                fprintf(stderr,"ring buffer failed to peek frame res: %d\n", res);
     380                                                exit(1);
     381                                        }
     382                                }       
     383                               
     384                                // add each extra frame required direct to the output file
     385                                int x;
     386                                for (x = 0; x < framesdiff; x++){
     387                                        if (type == AC3)
     388                                                write(rx->dmx_out[pos+1+rx->apidn], framebuf, aframe->framesize);
     389                                        else
     390                                                write(rx->dmx_out[pos+1], framebuf, aframe->framesize);
     391                                        *acount += 1;
     392                                }
     393                               
     394                                free(framebuf);
     395                        }
     396                }
     397        }       
     398
    279399        if (aframe->set){
    280400                if(iu->active){
    281401                        iu->length = ring_posdiff(rbuf,
     
    480600                iu->start = (p->ini_pos+pos+c)%bsize;
    481601        }
    482602        c += pos;
    483         if (c + aframe->framesize > len){
     603        if (c + (int) aframe->framesize > len){
    484604//                              fprintf(stderr,"SHORT %d\n", len -c);
    485605                c = len;
    486606        } else {
     
    13301450        for (i=0; i<rx->apidn;i++){
    13311451                if ((aavail = ring_avail(&rx->index_arbuffer[i])
    13321452                     /sizeof(index_unit)) < LIMIT)
    1333                         if (fill < ring_free(&rx->arbuffer[i]))
     1453                        if (fill < (int) ring_free(&rx->arbuffer[i]))
    13341454                                fill = ring_free(&rx->arbuffer[i]);
    13351455        }
    13361456
    13371457        for (i=0; i<rx->ac3n;i++){
    13381458                if ((ac3avail = ring_avail(&rx->index_ac3rbuffer[i])
    13391459                     /sizeof(index_unit)) < LIMIT)
    1340                         if (fill < ring_free(&rx->ac3rbuffer[i]))
     1460                        if (fill < (int) ring_free(&rx->ac3rbuffer[i]))
    13411461                                fill = ring_free(&rx->ac3rbuffer[i]);
    13421462        }
    13431463
     
    13641484        uint16_t vpid=0, apid=0, ac3pid=0;
    13651485       
    13661486        fprintf(stderr,"Trying to find PIDs\n");
    1367         while (!afound && !vfound && count < rx->inflength){
     1487        while (!afound && !vfound && count < (int) rx->inflength){
    13681488                if (rx->vpid) vfound = 1;
    13691489                if (rx->apidn) afound = 1;
    13701490                if ((re = save_read(rx,buf,IN_SIZE))<0)
     
    14241544        memset (ac3pid , 0 , MAXAC3PID*sizeof(uint16_t));
    14251545       
    14261546        fprintf(stderr,"Trying to find PIDs\n");
    1427         while (count < rx->inflength-IN_SIZE){
     1547        while (count < (int) rx->inflength-IN_SIZE){
    14281548                if ((re = save_read(rx,buf,IN_SIZE))<0)
    14291549                        perror("reading");
    14301550                else
     
    24892609        printf ("  --input_stream,     -i <string>   :  set input stream type (string = TS(default), PS, AVI)\n");
    24902610        printf ("  --allow_jump,       -j            :  allow jump in the PTS and try repair\n");
    24912611        printf ("  --keep_PTS,         -k            :  keep and don't correct PTS information of original\n");
     2612        printf ("  --fix_sync,         -n            :  try to fix audio sync while demuxing\n");
    24922613        printf ("  --min_jump,         -l <integer>  :  don't try to fix jumps in PTS larger than <int> but treat them as a cut (default 100ms)\n");
    24932614        printf ("  --of,               -o <filename> :  set output file\n");
    24942615        printf ("  --fillzero          -p            :  fill audio frames with zeros (only MPEG AUDIO)\n");
     
    25342655                        {"input_stream", required_argument, NULL, 'i'},
    25352656                        {"allow_jump",required_argument, NULL, 'j'},
    25362657                        {"keep_PTS",required_argument, NULL, 'k'},
     2658                        {"fix_sync",no_argument, NULL, 'n'},
    25372659                        {"min_jump",required_argument, NULL, 'l'},
    25382660                        {"of",required_argument, NULL, 'o'},
    25392661                        {"fillzero",required_argument, NULL, 'p'},
     
    25472669                        {0, 0, 0, 0}
    25482670                };
    25492671                c = getopt_long (argc, argv,
    2550                                  "a:c:d:e:fg:hi:jkl:o:pq:st:v:xy:z",
     2672                                        "t:o:a:v:g:i:hp:q:d:c:n:fkd:e:zy:sx",
    25512673                                 long_options, &option_index);
    25522674                if (c == -1)
    25532675                        break;
     
    26242746                case 'z':
    26252747                        rx.demux = 1;
    26262748                        break;
     2749                case 'n':
     2750                        rx.fix_sync =1;
     2751                        break;
    26272752                case 'h':
    26282753                case '?':
    26292754                default:
     
    26312756                }
    26322757        }
    26332758
     2759        if (rx.fix_sync)
     2760                av_register_all();
     2761
    26342762        if (rx.allow_jump && min_jump) rx.allow_jump = min_jump;
    26352763
    26362764        if (fillzero) rx.fillzero = 1;
  • mythtv/programs/mythtranscode/replex/replex.h

     
    4949        int otype;
    5050        int ignore_pts;
    5151        int keep_pts;
     52        int fix_sync;
    5253        uint64_t allow_jump;
    5354        uint64_t inflength;
    5455        uint64_t finread;
  • mythtv/programs/mythtranscode/replex/element.c

     
    623623        }
    624624        af->off = c;
    625625        af->set = 1;
     626        af->frametime = ((samples [3-af->layer] * 27000000ULL) / af->frequency);
    626627        af->framesize = calculate_mpg_framesize(af);
    627628        //af->framesize = af->bit_rate *slots [3-af->layer]/ af->frequency;
    628629        if (DEBUG && verb) fprintf(stderr," frame size: %d \n", af->framesize);
     
    675676
    676677        af->off = c;
    677678        af->set = 1;
    678         return c;
     679         
     680        //FIXME calculate frametime
     681        af->frametime = 0;
     682
     683    return c;
    679684}
    680685
    681686
  • mythplugins/mytharchive/mythburn/scripts/mythburn.py

     
    26692669def deMultiplexMPEG2File(folder, mediafile, video, audio1, audio2):
    26702670
    26712671    if getFileType(folder) == "mpegts":
    2672         command = "mythreplex --demux --fix_sync -t TS -o %s " % (folder + "/stream")
     2672        command = "mythreplex -g 12 --demux --fix_sync -t TS -o %s " % (folder + "/stream")
    26732673        command += "-v %d " % (video[VIDEO_ID])
    26742674
    26752675        if audio1[AUDIO_ID] != -1:
     
    26852685                command += "-c %d " % (audio2[AUDIO_ID])
    26862686
    26872687    else:
    2688         command = "mythreplex --demux --fix_sync -o %s " % (folder + "/stream")
     2688        command = "mythreplex -g 12 --demux --fix_sync -o %s " % (folder + "/stream")
    26892689        command += "-v %d " % (video[VIDEO_ID] & 255)
    26902690
    26912691        if audio1[AUDIO_ID] != -1: