pad-monitor: Update checks for MISSING_DISCONT
authorEdward Hervey <edward@centricular.com>
Fri, 20 May 2016 07:07:01 +0000 (09:07 +0200)
committerEdward Hervey <bilboed@bilboed.com>
Mon, 23 May 2016 13:59:44 +0000 (15:59 +0200)
* Some SEGMENT might be updates caused by calling gst_pad_set_offset(),
  which will send the same segment but with an updated offset and/or
  based field. For those segments, we don't require a DISCONT on the
  following buffer.
* Ignore differences in flags, they aren't relevant for now to figure
  out whether the segment is an update or not
* Ignore difference in 'position', it's only meant for internal usage
  by elements.
* Changes in the end position (stop in forward playback and start in
  reverse playback) are considering updates

Furthermore, also expect a DISCONT flag on the first buffer following
a STREAM_START.

validate/gst/validate/gst-validate-pad-monitor.c

index d7f4973..b523035 100644 (file)
@@ -1703,6 +1703,31 @@ gst_validate_monitor_find_next_buffer (GstValidatePadMonitor * pad_monitor)
     pad_monitor->current_buf = tmp;
 }
 
+/* Checks whether a segment is just an update of another,
+ * That is to say that only the base and offset field differ and all
+ * other fields are identical */
+static gboolean
+is_segment_update (GstSegment * a, const GstSegment * b)
+{
+  /* Note : We never care about the position field, it is only
+   * used for internal usage by elements */
+  if (a->rate == b->rate &&
+      a->applied_rate == b->applied_rate &&
+      a->format == b->format && a->time == b->time) {
+    /* Changes in base/offset are considered updates */
+    /* Updating the end position of a segment is an update */
+    /* Updating the duration of a segment is an update */
+    if (a->rate > 0.0) {
+      if (a->start == b->start)
+        return TRUE;
+    } else {
+      if (a->stop == b->stop)
+        return TRUE;
+    }
+  }
+  return FALSE;
+}
+
 static GstFlowReturn
 gst_validate_pad_monitor_downstream_event_check (GstValidatePadMonitor *
     pad_monitor, GstObject * parent, GstEvent * event,
@@ -1717,6 +1742,10 @@ gst_validate_pad_monitor_downstream_event_check (GstValidatePadMonitor *
 
   /* pre checks */
   switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_STREAM_START:
+      /* Buffers following a STREAM_START should have the DISCONT flag set */
+      pad_monitor->pending_buffer_discont = TRUE;
+      break;
     case GST_EVENT_SEGMENT:
       /* parse segment data to be used if event is handled */
       gst_event_parse_segment (event, &segment);
@@ -1744,8 +1773,6 @@ gst_validate_pad_monitor_downstream_event_check (GstValidatePadMonitor *
       }
 
       pad_monitor->pending_eos_seqnum = seqnum;
-      /* Buffers following a SEGMENT should have the DISCONT flag set */
-      pad_monitor->pending_buffer_discont = TRUE;
 
       if (GST_PAD_DIRECTION (pad) == GST_PAD_SINK) {
         gst_validate_pad_monitor_add_expected_newsegment (pad_monitor, event);
@@ -1839,6 +1866,10 @@ gst_validate_pad_monitor_downstream_event_check (GstValidatePadMonitor *
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_SEGMENT:
       if (ret == GST_FLOW_OK) {
+        /* If the new segment is not an update of the previous one, then
+         * the following buffer should have the DISCONT flag set */
+        if (!is_segment_update (&pad_monitor->segment, segment))
+          pad_monitor->pending_buffer_discont = TRUE;
         if (!pad_monitor->has_segment
             && pad_monitor->segment.format != segment->format) {
           gst_segment_init (&pad_monitor->segment, segment->format);