dec: use input timestamp diff for duration estimation
authorWim Taymans <wim.taymans@collabora.co.uk>
Sun, 12 Dec 2010 09:54:09 +0000 (10:54 +0100)
committerWim Taymans <wim.taymans@gmail.com>
Sun, 12 Dec 2010 10:20:22 +0000 (11:20 +0100)
Use the diff between input timestamps to estimate the duration when no duration
is set on input buffers. Only do this when there are no reordered input
timestamps. Improves interpolation in DTS mode when no input duration is set.

ext/ffmpeg/gstffmpegdec.c

index b09b12e..20f8751 100644 (file)
@@ -96,7 +96,7 @@ struct _GstFFMpegDec
   gboolean has_b_frames;
   gboolean reordered_in;
   GstClockTime last_in;
-  GstClockTime next_in;
+  GstClockTime last_diff;
   gboolean reordered_out;
   GstClockTime last_out;
   GstClockTime next_out;
@@ -498,7 +498,7 @@ static void
 gst_ffmpegdec_reset_ts (GstFFMpegDec * ffmpegdec)
 {
   ffmpegdec->last_in = GST_CLOCK_TIME_NONE;
-  ffmpegdec->next_in = GST_CLOCK_TIME_NONE;
+  ffmpegdec->last_diff = GST_CLOCK_TIME_NONE;
   ffmpegdec->last_out = GST_CLOCK_TIME_NONE;
   ffmpegdec->next_out = GST_CLOCK_TIME_NONE;
   ffmpegdec->reordered_in = FALSE;
@@ -1872,6 +1872,9 @@ gst_ffmpegdec_video_frame (GstFFMpegDec * ffmpegdec,
   } else if (GST_CLOCK_TIME_IS_VALID (dec_info->duration)) {
     GST_LOG_OBJECT (ffmpegdec, "using in_duration");
     out_duration = dec_info->duration;
+  } else if (GST_CLOCK_TIME_IS_VALID (ffmpegdec->last_diff)) {
+    GST_LOG_OBJECT (ffmpegdec, "using last-diff");
+    out_duration = ffmpegdec->last_diff;
   } else {
     /* if we have an input framerate, use that */
     if (ffmpegdec->format.video.fps_n != -1 &&
@@ -2482,10 +2485,15 @@ gst_ffmpegdec_chain (GstPad * pad, GstBuffer * inbuf)
   if (in_timestamp != -1) {
     /* check for increasing timestamps if they are jumping backwards, we
      * probably are dealing with PTS as timestamps */
-    if (!ffmpegdec->reordered_in && ffmpegdec->last_in != -1
-        && in_timestamp < ffmpegdec->last_in) {
-      GST_LOG_OBJECT (ffmpegdec, "detected reordered input timestamps");
-      ffmpegdec->reordered_in = TRUE;
+    if (!ffmpegdec->reordered_in && ffmpegdec->last_in != -1) {
+      if (in_timestamp < ffmpegdec->last_in) {
+        GST_LOG_OBJECT (ffmpegdec, "detected reordered input timestamps");
+        ffmpegdec->reordered_in = TRUE;
+        ffmpegdec->last_diff = GST_CLOCK_TIME_NONE;
+      } else if (in_timestamp > ffmpegdec->last_in) {
+        /* keep track of timestamp diff to estimate duration */
+        ffmpegdec->last_diff = in_timestamp - ffmpegdec->last_in;
+      }
     }
     ffmpegdec->last_in = in_timestamp;
   }