diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c index 5c65826e28ff03faf02f99fde9644d8c1ef8f189..7d04339b7952a690896b601be60ea3cc9b54e31b 100644 --- a/gst/videoparsers/gsth264parse.c +++ b/gst/videoparsers/gsth264parse.c @@ -953,7 +953,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) case GST_H264_NAL_SPS: /* reset state, everything else is obsolete */ - h264parse->state = 0; + h264parse->state &= GST_H264_PARSE_STATE_GOT_PPS; pres = gst_h264_parser_parse_sps (nalparser, nalu, &sps); process_sps: diff --git a/tests/check/elements/h264parse.c b/tests/check/elements/h264parse.c index de5297c974adfb9f6c69e963907c1cdbaedb733a..6ce1e5e0dcc0c6951a20df05f110b45dcdddd469 100644 --- a/tests/check/elements/h264parse.c +++ b/tests/check/elements/h264parse.c @@ -1082,6 +1082,75 @@ GST_START_TEST (test_parse_sliced_nal_au) GST_END_TEST; +GST_START_TEST (test_parse_sliced_sps_pps_sps) +{ + GstHarness *h = gst_harness_new ("h264parse"); + GstBuffer *buf; + + gst_harness_set_caps_str (h, + "video/x-h264,stream-format=byte-stream,alignment=nal,parsed=false,framerate=30/1", + "video/x-h264,stream-format=byte-stream,alignment=au,parsed=true"); + + buf = wrap_buffer (h264_slicing_sps, sizeof (h264_slicing_sps), 100, 0); + fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK); + + buf = wrap_buffer (h264_slicing_pps, sizeof (h264_slicing_pps), 100, 0); + fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK); + + buf = wrap_buffer (h264_idr_slice_1, sizeof (h264_idr_slice_1), 100, 0); + fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK); + + /* no output yet, it will be pushed as soon as + * the parser recognizes the new AU */ + fail_unless_equals_int (gst_harness_buffers_in_queue (h), 0); + + buf = wrap_buffer (h264_slicing_sps, sizeof (h264_slicing_sps), 200, 0); + fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK); + + /* no PP, just a SPS here is valid */ + + buf = wrap_buffer (h264_idr_slice_1, sizeof (h264_idr_slice_1), 200, 0); + fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK); + + fail_unless_equals_int (gst_harness_buffers_in_queue (h), 1); + + buf = wrap_buffer (h264_idr_slice_1, sizeof (h264_idr_slice_1), 300, 0); + fail_unless_equals_int (gst_harness_push (h, buf), GST_FLOW_OK); + + fail_unless_equals_int (gst_harness_buffers_in_queue (h), 2); + + { + GstMapInfo info; + + buf = composite_buffer (100, 0, 4, + h264_aud, sizeof (h264_aud), + h264_slicing_sps, sizeof (h264_slicing_sps), + h264_slicing_pps, sizeof (h264_slicing_pps), + h264_idr_slice_1, sizeof (h264_idr_slice_1)); + gst_buffer_map (buf, &info, GST_MAP_READ); + + pull_and_check_full (h, info.data, info.size, 100, 0); + + gst_buffer_unmap (buf, &info); + gst_buffer_unref (buf); + + buf = composite_buffer (200, 0, 3, + h264_aud, sizeof (h264_aud), + h264_slicing_sps, sizeof (h264_slicing_sps), + h264_idr_slice_1, sizeof (h264_idr_slice_1)); + gst_buffer_map (buf, &info, GST_MAP_READ); + + pull_and_check_full (h, info.data, info.size, 200, 0); + + gst_buffer_unmap (buf, &info); + gst_buffer_unref (buf); + } + + gst_harness_teardown (h); +} + +GST_END_TEST; + static Suite * h264parse_sliced_suite (void) @@ -1093,6 +1162,7 @@ h264parse_sliced_suite (void) tcase_add_test (tc_chain, test_parse_sliced_nal_nal); tcase_add_test (tc_chain, test_parse_sliced_au_nal); tcase_add_test (tc_chain, test_parse_sliced_nal_au); + tcase_add_test (tc_chain, test_parse_sliced_sps_pps_sps); return s; }