videoaggregator: handle gap buffers properly
authorMathieu Duponchelle <mathieu@centricular.com>
Thu, 30 Jan 2020 18:00:07 +0000 (19:00 +0100)
committerMathieu Duponchelle <mathieu@centricular.com>
Thu, 30 Jan 2020 18:02:44 +0000 (19:02 +0100)
This simply implies not trying to "prepare" those buffers,
as mapping an empty buffer to a video frame does not make
much sense.

This also adds a simple test in compositor that performs
some trivial checking of the handling of gap events, the test
was not failing before, but an error was logged, this is
no longer the case.

Fixes #717

gst-libs/gst/video/gstvideoaggregator.c
tests/check/elements/compositor.c

index 2d487f1..b62b62e 100644 (file)
@@ -1622,6 +1622,13 @@ prepare_frames (GstElement * agg, GstPad * pad, gpointer user_data)
   if (vpad->priv->buffer == NULL || !vaggpad_class->prepare_frame)
     return TRUE;
 
+  /* GAP event, nothing to do */
+  if (vpad->priv->buffer &&
+      gst_buffer_get_size (vpad->priv->buffer) == 0 &&
+      GST_BUFFER_FLAG_IS_SET (vpad->priv->buffer, GST_BUFFER_FLAG_GAP)) {
+    return TRUE;
+  }
+
   return vaggpad_class->prepare_frame (vpad, GST_VIDEO_AGGREGATOR_CAST (agg),
       vpad->priv->buffer, &vpad->priv->prepared_frame);
 }
index 8a9db39..a1cec01 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <gst/check/gstcheck.h>
 #include <gst/check/gstconsistencychecker.h>
+#include <gst/check/gstharness.h>
 #include <gst/video/gstvideometa.h>
 #include <gst/base/gstbasesrc.h>
 
@@ -2120,6 +2121,51 @@ GST_START_TEST (test_start_time_first_live_drop_3_unlinked_1)
 
 GST_END_TEST;
 
+GST_START_TEST (test_gap_events)
+{
+  GstBuffer *buf;
+  GstElement *comp = gst_element_factory_make ("compositor", NULL);
+  GstHarness *h = gst_harness_new_with_element (comp, "sink_%u", "src");
+  GstMapInfo info;
+
+  g_object_set (comp, "background", 1, NULL);
+
+  gst_harness_set_src_caps_str (h,
+      "video/x-raw, format=RGBA, width=1, height=1, framerate=25/1");
+
+  gst_harness_play (h);
+
+  gst_harness_push_event (h, gst_event_new_gap (0, 40 * GST_MSECOND));
+
+  buf = gst_buffer_new_allocate (NULL, 4, NULL);
+
+  gst_buffer_map (buf, &info, GST_MAP_WRITE);
+  memset (info.data, 42, info.size);
+  info.data[3] = 255;
+  gst_buffer_unmap (buf, &info);
+
+  GST_BUFFER_PTS (buf) = 40 * GST_MSECOND;
+  GST_BUFFER_DURATION (buf) = 40 * GST_MSECOND;
+  gst_harness_push (h, buf);
+
+  buf = gst_harness_pull (h);
+  gst_buffer_map (buf, &info, GST_MAP_READ);
+  fail_unless (info.data[0] == 0);
+  gst_buffer_unmap (buf, &info);
+  gst_buffer_unref (buf);
+
+  buf = gst_harness_pull (h);
+  gst_buffer_map (buf, &info, GST_MAP_READ);
+  fail_unless (info.data[0] == 42);
+  gst_buffer_unmap (buf, &info);
+  gst_buffer_unref (buf);
+
+  gst_harness_teardown (h);
+  gst_object_unref (comp);
+}
+
+GST_END_TEST;
+
 static Suite *
 compositor_suite (void)
 {
@@ -2158,6 +2204,7 @@ compositor_suite (void)
   tcase_add_test (tc_chain, test_start_time_first_live_drop_0);
   tcase_add_test (tc_chain, test_start_time_first_live_drop_3);
   tcase_add_test (tc_chain, test_start_time_first_live_drop_3_unlinked_1);
+  tcase_add_test (tc_chain, test_gap_events);
 
   return s;
 }