basesink: Only drop buffer if their PTS is out of segment
authorNicolas Dufresne <nicolas.dufresne@collabora.com>
Wed, 5 Aug 2015 19:51:27 +0000 (15:51 -0400)
committerNicolas Dufresne <nicolas.dufresne@collabora.com>
Wed, 5 Aug 2015 19:51:27 +0000 (15:51 -0400)
As of now, even for stream completly inside segment, there is no
guarantied that the DTS will be inside the segment. Specifically
for H.264 with B-Frames, the first few frames often have DTS that
are before the segment.

Instead of using the sync timestamp to clip out of segment buffer,
take the duration from the start/stop provided by the sub-class, and
check if the pts and pts_end is out of segment.

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

libs/gst/base/gstbasesink.c

index cd759ac..f5fea82 100644 (file)
@@ -3400,10 +3400,21 @@ gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad,
   GST_DEBUG_OBJECT (basesink, "got times start: %" GST_TIME_FORMAT
       ", end: %" GST_TIME_FORMAT, GST_TIME_ARGS (start), GST_TIME_ARGS (end));
 
-  /* a dropped buffer does not participate in anything */
+  /* a dropped buffer does not participate in anything. Buffer can only be
+   * dropped if their PTS falls completly outside the segment, while we sync
+   * preferably on DTS */
   if (GST_CLOCK_TIME_IS_VALID (start) && (segment->format == GST_FORMAT_TIME)) {
+    GstClockTime pts = GST_BUFFER_PTS (sync_buf);
+    GstClockTime pts_end = GST_CLOCK_TIME_NONE;
+
+    if (!GST_CLOCK_TIME_IS_VALID (pts))
+      pts = start;
+
+    if (GST_CLOCK_TIME_IS_VALID (end))
+      pts_end = pts + (end - start);
+
     if (G_UNLIKELY (!gst_segment_clip (segment,
-                GST_FORMAT_TIME, start, end, NULL, NULL)))
+                GST_FORMAT_TIME, pts, pts_end, NULL, NULL)))
       goto out_of_segment;
   }