audio timestamp drift compensation
authorMichael Niedermayer <michaelni@gmx.at>
Wed, 30 Jun 2004 14:47:29 +0000 (14:47 +0000)
committerMichael Niedermayer <michaelni@gmx.at>
Wed, 30 Jun 2004 14:47:29 +0000 (14:47 +0000)
Originally committed as revision 3272 to svn://svn.ffmpeg.org/ffmpeg/trunk

ffmpeg.c
tests/libav.regression.ref

index 59601d1..ef512b2 100644 (file)
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -201,7 +201,8 @@ static int bitexact = 0;
 static char *pass_logfilename = NULL;
 static int audio_stream_copy = 0;
 static int video_stream_copy = 0;
-static int sync_method= 1;
+static int video_sync_method= 1;
+static int audio_sync_method= 0;
 static int copy_ts= 0;
 
 static int rate_emu = 0;
@@ -432,6 +433,22 @@ static void do_audio_out(AVFormatContext *s,
 
     
     enc = &ost->st->codec;
+    
+    if(audio_sync_method){
+        double delta = ost->sync_ipts * enc->sample_rate - ost->sync_opts 
+                - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec.channels * 2);
+        //FIXME resample delay
+        if(fabs(delta) > 50){
+            int comp= clip(delta, -audio_sync_method, audio_sync_method);
+            assert(ost->audio_resample);
+            if(verbose > 2)
+                fprintf(stderr, "compensating audio timestamp drift:%f compensation:%d in:%d\n", delta, comp, enc->sample_rate);
+//            fprintf(stderr, "drift:%f len:%d opts:%lld ipts:%lld fifo:%d\n", delta, len/4, ost->sync_opts, (int64_t)(ost->sync_ipts * enc->sample_rate), fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec.channels * 2));
+            av_resample_compensate(*(struct AVResampleContext**)ost->resample, delta, enc->sample_rate);
+        }
+    }else
+        ost->sync_opts= lrintf(ost->sync_ipts * enc->sample_rate)
+                        - fifo_size(&ost->fifo, ost->fifo.rptr)/(ost->st->codec.channels * 2); //FIXME wrong
 
     if (ost->audio_resample) {
         buftmp = audio_buf;
@@ -467,10 +484,15 @@ static void do_audio_out(AVFormatContext *s,
                 pkt.pts= enc->coded_frame->pts;
             pkt.flags |= PKT_FLAG_KEY;
             av_interleaved_write_frame(s, &pkt);
+            
+            ost->sync_opts += enc->frame_size;
         }
     } else {
         AVPacket pkt;
         av_init_packet(&pkt);
+
+        ost->sync_opts += size_out / enc->channels;
+
         /* output a pcm frame */
         /* XXX: change encoding codec API to avoid this ? */
         switch(enc->codec->id) {
@@ -588,7 +610,7 @@ static void do_video_out(AVFormatContext *s,
                          AVOutputStream *ost, 
                          AVInputStream *ist,
                          AVFrame *in_picture,
-                         int *frame_size, AVOutputStream *audio_sync)
+                         int *frame_size)
 {
     int nb_frames, i, ret;
     AVFrame *final_picture, *formatted_picture;
@@ -610,7 +632,7 @@ static void do_video_out(AVFormatContext *s,
 
     *frame_size = 0;
 
-    if(sync_method){
+    if(video_sync_method){
         double vdelta;
         vdelta = ost->sync_ipts * enc->frame_rate / enc->frame_rate_base - ost->sync_opts;
         //FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c
@@ -1018,11 +1040,11 @@ static int output_packet(AVInputStream *ist, int ist_index,
     AVFrame picture;
     short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
     void *buffer_to_free;
-    
+//fprintf(stderr, "output_packet %d, dts:%lld\n", pkt->stream_index, pkt->dts);
     if (pkt && pkt->dts != AV_NOPTS_VALUE) { //FIXME seems redundant, as libavformat does this too
         ist->next_pts = ist->pts = pkt->dts;
     } else {
-        ist->pts = ist->next_pts;
+        assert(ist->pts == ist->next_pts);
     }
 
     if (pkt == NULL) {
@@ -1134,7 +1156,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
                         printf("%d: got pts=%0.3f %0.3f\n", i, 
                                (double)pkt->pts / AV_TIME_BASE, 
                                ((double)ist->pts / AV_TIME_BASE) - 
-                               ((double)ost->st->pts.val * ost->time_base.num / ost->time_base.den));
+                               ((double)ost->st->pts.val * ost->st->time_base.num / ost->st->time_base.den));
 #endif
                         /* set the input output pts pairs */
                         ost->sync_ipts = (double)(ist->pts + input_files_ts_offset[ist->file_index])/ AV_TIME_BASE;
@@ -1159,7 +1181,7 @@ static int output_packet(AVInputStream *ist, int ist_index,
                                         }
                                     }
 
-                                    do_video_out(os, ost, ist, &picture, &frame_size, audio_sync);
+                                    do_video_out(os, ost, ist, &picture, &frame_size);
                                     video_size += frame_size;
                                     if (do_vstats && frame_size)
                                         do_video_stats(os, ost, frame_size);
@@ -1460,27 +1482,20 @@ static int av_encode(AVFormatContext **output_files,
                             ost->audio_resample = 0;
                         else {
                             ost->audio_resample = 1;
-                            ost->resample = audio_resample_init(codec->channels, icodec->channels,
-                                                        codec->sample_rate, 
-                                                        icodec->sample_rate);
-                           if(!ost->resample)
-                             {
-                               printf("Can't resample.  Aborting.\n");
-                               av_abort();
-                             }
                         }
-                        /* Request specific number of channels */
-                        icodec->channels = codec->channels;
                     } else {
                         ost->audio_resample = 1; 
-                        ost->resample = audio_resample_init(codec->channels, icodec->channels,
-                                                        codec->sample_rate, 
-                                                        icodec->sample_rate);
-                       if(!ost->resample)
-                         {
-                           printf("Can't resample.  Aborting.\n");
-                           av_abort();
-                         }
+                    }
+                }
+                if(audio_sync_method)
+                    ost->audio_resample = 1;
+
+                if(ost->audio_resample){
+                    ost->resample = audio_resample_init(codec->channels, icodec->channels,
+                                                    codec->sample_rate, icodec->sample_rate);
+                    if(!ost->resample){
+                        printf("Can't resample.  Aborting.\n");
+                        av_abort();
                     }
                 }
                 ist->decoding_needed = 1;
@@ -2010,11 +2025,6 @@ static void opt_verbose(const char *arg)
     av_log_set_level(atoi(arg));
 }
 
-static void opt_sync_method(const char *arg)
-{
-    sync_method = atoi(arg);
-}
-
 static void opt_frame_rate(const char *arg)
 {
     if (parse_frame_rate(&frame_rate, &frame_rate_base, arg) < 0) {
@@ -3626,7 +3636,8 @@ const OptionDef options[] = {
     { "v", HAS_ARG, {(void*)opt_verbose}, "control amount of logging", "verbose" },
     { "target", HAS_ARG, {(void*)opt_target}, "specify target file type (\"vcd\", \"svcd\" or \"dvd\")", "type" },
     { "threads", HAS_ARG | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
-    { "sync", HAS_ARG | OPT_EXPERT, {(void*)opt_sync_method}, "sync method", "" },
+    { "vsync", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&video_sync_method}, "video sync method", "" },
+    { "async", HAS_ARG | OPT_INT | OPT_EXPERT, {(void*)&audio_sync_method}, "audio sync method", "" },
     { "copyts", OPT_BOOL | OPT_EXPERT, {(void*)&copy_ts}, "copy timestamps" },
 
     /* video options */
index d98225a..9b8b0dc 100644 (file)
@@ -9,7 +9,7 @@ ffmpeg regression test
 360251 ./data/b-libav.rm
 e0a9ed22a34e0277ec77c84e8b64afd9 *./data/b-libav.mpg
 387072 ./data/b-libav.mpg
-./data/b-libav.mpg CRC=ac661eb1
+./data/b-libav.mpg CRC=723a4225
 57a8dfc7926802bb337a9d8918de94a8 *./data/b-libav.swf
 41816 ./data/b-libav.swf
 ./data/b-libav.swf CRC=2b273fea