rawbaseparse: Drop incomplete frames at EOS
authorSebastian Dröge <sebastian@centricular.com>
Sat, 18 Feb 2017 18:18:50 +0000 (20:18 +0200)
committerSebastian Dröge <sebastian@centricular.com>
Sun, 19 Feb 2017 10:52:33 +0000 (12:52 +0200)
See https://bugzilla.gnome.org/show_bug.cgi?id=773666

This would ideally be solved in baseparse but that requires further
thought at this point, and in the meantime it would be good to have
rawbaseparse not assert on this but handle it gracefully instead.

gst/rawparse/gstrawbaseparse.c
tests/check/elements/rawvideoparse.c

index 5fb8e73c84355e5eded945e65ef786c575458b7e..92514155a29f5a27067446fc662aa236f131ef8f 100644 (file)
@@ -547,6 +547,18 @@ gst_raw_base_parse_handle_frame (GstBaseParse * parse,
 
   in_size = gst_buffer_get_size (frame->buffer);
 
+  /* drop incomplete frame at the end of the stream
+   * https://bugzilla.gnome.org/show_bug.cgi?id=773666
+   */
+  if (GST_BASE_PARSE_DRAINING (parse) && in_size < frame_size) {
+    GST_DEBUG_OBJECT (raw_base_parse,
+        "Dropping %" G_GSIZE_FORMAT " bytes at EOS", in_size);
+    frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP;
+    GST_RAW_BASE_PARSE_CONFIG_MUTEX_UNLOCK (raw_base_parse);
+
+    return gst_base_parse_finish_frame (parse, frame, in_size);
+  }
+
   /* gst_base_parse_set_min_frame_size() is called when the current
    * configuration changes and the change affects the frame size. This
    * means that a buffer must contain at least as many bytes as indicated
index 477e7678e853d4371ec944871ee2e3c9ad85da2b..bca199921e527cadc7eaa79fe0879c1b5c10977d 100644 (file)
@@ -607,6 +607,37 @@ GST_START_TEST (test_change_caps)
 
 GST_END_TEST;
 
+GST_START_TEST (test_incomplete_last_buffer)
+{
+  GstVideoInfo vinfo;
+  GstCaps *caps;
+
+  /* Start processing with the sink caps config active, using the
+   * default width/height/format and 25 Hz frame rate for the caps.
+   * Push some data, then change caps (25 Hz -> 50 Hz).
+   * Check that the changed caps are handled properly. */
+
+  gst_video_info_set_format (&vinfo, TEST_FRAME_FORMAT, TEST_WIDTH,
+      TEST_HEIGHT);
+  GST_VIDEO_INFO_FPS_N (&vinfo) = 25;
+  GST_VIDEO_INFO_FPS_D (&vinfo) = 1;
+  caps = gst_video_info_to_caps (&vinfo);
+
+  setup_rawvideoparse (TRUE, FALSE, caps, GST_FORMAT_BYTES);
+
+  push_data_and_check_output (&sinkcaps_ctx, 192, 192, GST_MSECOND * 0,
+      GST_MSECOND * 40, 1, 0, 0, 0);
+  push_data_and_check_output (&sinkcaps_ctx, 192, 192, GST_MSECOND * 40,
+      GST_MSECOND * 40, 2, 1, 1, 0);
+  push_data_and_check_output (&sinkcaps_ctx, 100, 192, GST_MSECOND * 40,
+      GST_MSECOND * 40, 2, 1, 1, 0);
+  gst_pad_push_event (mysrcpad, gst_event_new_eos ());
+  fail_unless_equals_int (g_list_length (buffers), 2);
+
+  cleanup_rawvideoparse ();
+}
+
+GST_END_TEST;
 
 static Suite *
 rawvideoparse_suite (void)
@@ -621,6 +652,7 @@ rawvideoparse_suite (void)
   tcase_add_test (tc_chain, test_push_with_no_framerate);
   tcase_add_test (tc_chain, test_computed_plane_strides);
   tcase_add_test (tc_chain, test_change_caps);
+  tcase_add_test (tc_chain, test_incomplete_last_buffer);
 
   return s;
 }