From 92392a47334ba8c63650d5d532ffdee79b056547 Mon Sep 17 00:00:00 2001 From: Stian Selnes Date: Thu, 13 Oct 2016 12:41:29 +0200 Subject: [PATCH] videodecoder: Default caps sets format I420 Also the format must be fixed on the default raw caps. If not gst_video_info_from_caps() will fail and gst_video_decoder_negotiate_default_caps() return FALSE. The test simulates the use case where a gap event is received before the first buffer causing the decoder to fall back to the default caps. https://bugzilla.gnome.org/show_bug.cgi?id=773103 --- gst-libs/gst/video/gstvideodecoder.c | 7 ++- tests/check/libs/videodecoder.c | 85 +++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/video/gstvideodecoder.c b/gst-libs/gst/video/gstvideodecoder.c index 57c5728350..fdbc7d2c76 100644 --- a/gst-libs/gst/video/gstvideodecoder.c +++ b/gst-libs/gst/video/gstvideodecoder.c @@ -1037,7 +1037,12 @@ gst_video_decoder_negotiate_default_caps (GstVideoDecoder * decoder) for (i = 0; i < caps_size; i++) { structure = gst_caps_get_structure (caps, i); - /* Random 1280x720@30 for fixation */ + /* Random I420 1280x720@30 for fixation */ + if (gst_structure_has_field (structure, "format")) + gst_structure_fixate_field_string (structure, "format", "I420"); + else + gst_structure_set (structure, "format", G_TYPE_STRING, "I420", NULL); + if (gst_structure_has_field (structure, "width")) gst_structure_fixate_field_nearest_int (structure, "width", 1280); else diff --git a/tests/check/libs/videodecoder.c b/tests/check/libs/videodecoder.c index b780079046..58d09bae53 100644 --- a/tests/check/libs/videodecoder.c +++ b/tests/check/libs/videodecoder.c @@ -24,6 +24,7 @@ #endif #include #include +#include #include #include @@ -80,6 +81,7 @@ struct _GstVideoDecoderTester guint64 last_buf_num; guint64 last_kf_num; + gboolean set_output_state; }; struct _GstVideoDecoderTesterClass @@ -97,6 +99,7 @@ gst_video_decoder_tester_start (GstVideoDecoder * dec) dectester->last_buf_num = -1; dectester->last_kf_num = -1; + dectester->set_output_state = TRUE; return TRUE; } @@ -122,10 +125,14 @@ static gboolean gst_video_decoder_tester_set_format (GstVideoDecoder * dec, GstVideoCodecState * state) { - GstVideoCodecState *res = gst_video_decoder_set_output_state (dec, - GST_VIDEO_FORMAT_GRAY8, TEST_VIDEO_WIDTH, TEST_VIDEO_HEIGHT, NULL); + GstVideoDecoderTester *dectester = (GstVideoDecoderTester *) dec; + + if (dectester->set_output_state) { + GstVideoCodecState *res = gst_video_decoder_set_output_state (dec, + GST_VIDEO_FORMAT_GRAY8, TEST_VIDEO_WIDTH, TEST_VIDEO_HEIGHT, NULL); + gst_video_codec_state_unref (res); + } - gst_video_codec_state_unref (res); return TRUE; } @@ -1073,6 +1080,75 @@ GST_START_TEST (videodecoder_query_caps_with_custom_getcaps) GST_END_TEST; +static const gchar *test_default_caps[][2] = { + { + "video/x-test-custom", + "video/x-raw, format=I420, width=1280, height=720, framerate=0/1" + }, { + "video/x-test-custom, width=1000", + "video/x-raw, format=I420, width=1000, height=720, framerate=0/1" + }, { + "video/x-test-custom, height=500", + "video/x-raw, format=I420, width=1280, height=500, framerate=0/1" + }, { + "video/x-test-custom, framerate=10/1", + "video/x-raw, format=I420, width=1280, height=720, framerate=10/1" + }, { + "video/x-test-custom, pixel-aspect-ratio=2/1", + "video/x-raw, format=I420, width=1280, height=720, framerate=0/1," + "pixel-aspect-ratio=2/1" + } +}; + +GST_START_TEST (videodecoder_default_caps_on_gap_before_buffer) +{ + GstVideoDecoderTester *dec = + g_object_new (GST_VIDEO_DECODER_TESTER_TYPE, NULL); + GstHarness *h = + gst_harness_new_with_element (GST_ELEMENT (dec), "sink", "src"); + GstEvent *event; + GstCaps *caps1, *caps2; + GstVideoInfo info1, info2; + + /* Don't set output state since we want trigger the default output caps */ + dec->set_output_state = FALSE; + gst_harness_set_src_caps_str (h, test_default_caps[__i__][0]); + + fail_unless (gst_harness_push_event (h, gst_event_new_gap (0, GST_SECOND))); + + fail_unless_equals_int (gst_harness_events_received (h), 4); + + event = gst_harness_pull_event (h); + fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START); + gst_event_unref (event); + + event = gst_harness_pull_event (h); + fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_CAPS); + gst_event_unref (event); + + event = gst_harness_pull_event (h); + fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT); + gst_event_unref (event); + + event = gst_harness_pull_event (h); + fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_GAP); + gst_event_unref (event); + + caps1 = gst_pad_get_current_caps (h->sinkpad); + caps2 = gst_caps_from_string (test_default_caps[__i__][1]); + gst_video_info_from_caps (&info1, caps1); + gst_video_info_from_caps (&info2, caps2); + gst_caps_unref (caps1); + gst_caps_unref (caps2); + + fail_unless (gst_video_info_is_equal (&info1, &info2)); + + gst_harness_teardown (h); + gst_object_unref (dec); +} + +GST_END_TEST; + static Suite * gst_videodecoder_suite (void) @@ -1096,6 +1172,9 @@ gst_videodecoder_suite (void) tcase_add_test (tc, videodecoder_backwards_buffer_after_segment); tcase_add_test (tc, videodecoder_flush_events); + tcase_add_loop_test (tc, videodecoder_default_caps_on_gap_before_buffer, 0, + G_N_ELEMENTS (test_default_caps)); + return s; }