From 63e280df22073f06dc35a5cab03dad5d509eca71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Sat, 18 Feb 2017 20:18:50 +0200 Subject: [PATCH] rawbaseparse: Drop incomplete frames at EOS 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 | 12 +++++++++++ tests/check/elements/rawvideoparse.c | 32 ++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/gst/rawparse/gstrawbaseparse.c b/gst/rawparse/gstrawbaseparse.c index f5bb202e61..b41e4fa1c5 100644 --- a/gst/rawparse/gstrawbaseparse.c +++ b/gst/rawparse/gstrawbaseparse.c @@ -528,6 +528,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 diff --git a/tests/check/elements/rawvideoparse.c b/tests/check/elements/rawvideoparse.c index 477e7678e8..bca199921e 100644 --- a/tests/check/elements/rawvideoparse.c +++ b/tests/check/elements/rawvideoparse.c @@ -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; }