baseparse: always use incoming DTS
authorMathieu Duponchelle <mathieu@centricular.com>
Mon, 26 Oct 2020 22:17:59 +0000 (23:17 +0100)
committerMathieu Duponchelle <mathieu@centricular.com>
Tue, 27 Oct 2020 00:58:32 +0000 (01:58 +0100)
When parsing interlaced video streams, ignoring incoming DTS could
cause the parser to end up with PTS < DTS output buffers, for example
when increasing next_dts using the duration of the last pushed
buffer.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/681>

libs/gst/base/gstbaseparse.c

index 31916fe..4e3cc9f 100644 (file)
@@ -242,7 +242,6 @@ struct _GstBaseParsePrivate
   GstClockTime next_pts;
   GstClockTime next_dts;
   GstClockTime prev_pts;
-  GstClockTime prev_dts;
   gboolean prev_dts_from_pts;
   GstClockTime frame_duration;
   gboolean seen_keyframe;
@@ -1366,7 +1365,6 @@ gst_base_parse_sink_event_default (GstBaseParse * parse, GstEvent * event)
       parse->priv->last_pts = GST_CLOCK_TIME_NONE;
       parse->priv->last_dts = GST_CLOCK_TIME_NONE;
       parse->priv->prev_pts = GST_CLOCK_TIME_NONE;
-      parse->priv->prev_dts = GST_CLOCK_TIME_NONE;
       parse->priv->prev_dts_from_pts = FALSE;
       parse->priv->discont = TRUE;
       parse->priv->seen_keyframe = FALSE;
@@ -2863,7 +2861,6 @@ gst_base_parse_start_fragment (GstBaseParse * parse)
   parse->priv->next_pts = GST_CLOCK_TIME_NONE;
   parse->priv->prev_pts = GST_CLOCK_TIME_NONE;
   parse->priv->next_dts = GST_CLOCK_TIME_NONE;
-  parse->priv->prev_dts = GST_CLOCK_TIME_NONE;
   parse->priv->prev_dts_from_pts = FALSE;
   /* prevent it hanging around stop all the time */
   parse->segment.position = GST_CLOCK_TIME_NONE;
@@ -3266,8 +3263,8 @@ gst_base_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
       updated_prev_pts = TRUE;
     }
 
-    if (GST_CLOCK_TIME_IS_VALID (dts) && (parse->priv->prev_dts != dts)) {
-      parse->priv->prev_dts = parse->priv->next_dts = dts;
+    if (GST_CLOCK_TIME_IS_VALID (dts)) {
+      parse->priv->next_dts = dts;
       parse->priv->prev_dts_from_pts = FALSE;
     }
 
@@ -3277,10 +3274,9 @@ gst_base_parse_chain (GstPad * pad, GstObject * parent, GstBuffer * buffer)
     if (parse->priv->infer_ts &&
         parse->priv->pts_interpolate &&
         !GST_CLOCK_TIME_IS_VALID (dts) &&
-        (!GST_CLOCK_TIME_IS_VALID (parse->priv->prev_dts)
-            || (parse->priv->prev_dts_from_pts && updated_prev_pts))
-        && GST_CLOCK_TIME_IS_VALID (pts)) {
-      parse->priv->prev_dts = parse->priv->next_dts = pts;
+        parse->priv->prev_dts_from_pts &&
+        updated_prev_pts && GST_CLOCK_TIME_IS_VALID (pts)) {
+      parse->priv->next_dts = pts;
       parse->priv->prev_dts_from_pts = TRUE;
     }
 
@@ -4983,8 +4979,8 @@ gst_base_parse_set_ts_at_offset (GstBaseParse * parse, gsize offset)
   if (GST_CLOCK_TIME_IS_VALID (pts) && (parse->priv->prev_pts != pts))
     parse->priv->prev_pts = parse->priv->next_pts = pts;
 
-  if (GST_CLOCK_TIME_IS_VALID (dts) && (parse->priv->prev_dts != dts)) {
-    parse->priv->prev_dts = parse->priv->next_dts = dts;
+  if (GST_CLOCK_TIME_IS_VALID (dts)) {
+    parse->priv->next_dts = dts;
     parse->priv->prev_dts_from_pts = FALSE;
   }
 }