videotestsrc: keep track of the correct running time after renegotiations
authorThiago Santos <thiago.sousa.santos@collabora.com>
Wed, 29 Aug 2012 19:02:11 +0000 (16:02 -0300)
committerTim-Philipp Müller <tim@centricular.net>
Sun, 23 Sep 2012 16:48:56 +0000 (17:48 +0100)
Need to store the old running time and frame numbers when renegotiating and
start from 0 again when a new caps is set, preventing that framerate changes
cause timestamping issues.

For example, if a stream pushed 10 buffers on framerate=2/1, its
running time will be 5s. If a new framerate of 1/1 is set, it would
make the running time go to 10s as it would count those 10 buffers
as being sent on this new framerate.

Fixes camerbin unit test.

https://bugzilla.gnome.org/show_bug.cgi?id=682973

gst/videotestsrc/gstvideotestsrc.c
gst/videotestsrc/gstvideotestsrc.h

index 5f9a7cc..9c2a303 100644 (file)
@@ -704,6 +704,12 @@ gst_video_test_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
   videotestsrc->tmpline2 = g_malloc ((info.width + 8) * 4);
   videotestsrc->tmpline_u16 = g_malloc ((info.width + 16) * 8);
 
+  videotestsrc->accum_rtime += videotestsrc->running_time;
+  videotestsrc->accum_frames += videotestsrc->n_frames;
+
+  videotestsrc->running_time = 0;
+  videotestsrc->n_frames = 0;
+
   return TRUE;
 
   /* ERRORS */
@@ -783,6 +789,8 @@ gst_video_test_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
   } else {
     src->n_frames = 0;
   }
+  src->accum_frames = 0;
+  src->accum_rtime = 0;
   if (src->info.fps_n) {
     src->running_time = gst_util_uint64_scale (src->n_frames,
         src->info.fps_d * GST_SECOND, src->info.fps_n);
@@ -830,11 +838,19 @@ gst_video_test_src_fill (GstPushSrc * psrc, GstBuffer * buffer)
 
   gst_video_frame_unmap (&frame);
 
-  GST_BUFFER_DTS (buffer) = src->timestamp_offset + src->running_time;
+  GST_BUFFER_DTS (buffer) =
+      src->accum_rtime + src->timestamp_offset + src->running_time;
   GST_BUFFER_PTS (buffer) = GST_BUFFER_DTS (buffer);
-  GST_BUFFER_OFFSET (buffer) = src->n_frames;
+
+  GST_DEBUG_OBJECT (src, "Timestamp: %" GST_TIME_FORMAT " = accumulated %"
+      GST_TIME_FORMAT " + offset: %"
+      GST_TIME_FORMAT " + running time: %" GST_TIME_FORMAT,
+      GST_TIME_ARGS (GST_BUFFER_PTS (buffer)), GST_TIME_ARGS (src->accum_rtime),
+      GST_TIME_ARGS (src->timestamp_offset), GST_TIME_ARGS (src->running_time));
+
+  GST_BUFFER_OFFSET (buffer) = src->accum_frames + src->n_frames;
   src->n_frames++;
-  GST_BUFFER_OFFSET_END (buffer) = src->n_frames;
+  GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET (buffer) + 1;
   if (src->info.fps_n) {
     next_time = gst_util_uint64_scale_int (src->n_frames * GST_SECOND,
         src->info.fps_d, src->info.fps_n);
@@ -874,6 +890,8 @@ gst_video_test_src_start (GstBaseSrc * basesrc)
 
   src->running_time = 0;
   src->n_frames = 0;
+  src->accum_frames = 0;
+  src->accum_rtime = 0;
 
   return TRUE;
 }
index f64837e..a09e210 100644 (file)
@@ -130,9 +130,15 @@ struct _GstVideoTestSrc {
 
   /* private */
   gint64 timestamp_offset;              /* base offset */
+
+  /* running time and frames for current caps */
   GstClockTime running_time;            /* total running time */
   gint64 n_frames;                      /* total frames sent */
 
+  /* previous caps running time and frames */
+  GstClockTime accum_rtime;              /* accumulated running_time */
+  gint64 accum_frames;                  /* accumulated frames */
+
   /* zoneplate */
   gint k0;
   gint kx;