From 9b578abe1540d6be9cd0c3c584ff5b98be61a4b6 Mon Sep 17 00:00:00 2001 From: Brad Hards Date: Fri, 17 Jan 2025 20:46:55 +1100 Subject: [PATCH] h264parse: add conditional values to AVCConfigurationRecord This adds the data required in AVCDecoderConfigurationRecord for higher profile (High variants) configurations - everything in the if(...) {...} part of ISO/IEC 14496-15:2024 Section 5.3.2.1.2. (or 5.3.3.1.2 in the 2019 version). Resolves an error flagged by ComplianceWarden when muxing this into ISOBMFF. Part-of: --- .../flow-expectations/log-parse-src-expected | 2 +- .../log-hlsdemux2-0-video_00-expected | 2 +- .../flow-expectations/log-parse-src-expected | 2 +- .../gst/videoparsers/gsth264parse.c | 20 ++++++++++++++++++- 4 files changed, 22 insertions(+), 4 deletions(-) diff --git a/subprojects/gst-integration-testsuites/testsuites/validate/h264/parse.trickmode_predicted.seek_trickmode_predicted/flow-expectations/log-parse-src-expected b/subprojects/gst-integration-testsuites/testsuites/validate/h264/parse.trickmode_predicted.seek_trickmode_predicted/flow-expectations/log-parse-src-expected index 06c9c3a0de..a24fc2be77 100644 --- a/subprojects/gst-integration-testsuites/testsuites/validate/h264/parse.trickmode_predicted.seek_trickmode_predicted/flow-expectations/log-parse-src-expected +++ b/subprojects/gst-integration-testsuites/testsuites/validate/h264/parse.trickmode_predicted.seek_trickmode_predicted/flow-expectations/log-parse-src-expected @@ -1,5 +1,5 @@ event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1; -event caps: video/x-h264, alignment=(string)au, bit-depth-chroma=(uint)8, bit-depth-luma=(uint)8, chroma-format=(string)4:2:0, codec_data=(buffer)01640014ffe1001867640014acd94141fb0110000003001773594000f142996001000568ebecb22c, coded-picture-structure=(string)frame, framerate=(fraction)30/1, height=(int)240, lcevc=(boolean)false, level=(string)2, parsed=(boolean)true, pixel-aspect-ratio=(fraction)1/1, profile=(string)high, stream-format=(string)avc, width=(int)320; +event caps: video/x-h264, alignment=(string)au, bit-depth-chroma=(uint)8, bit-depth-luma=(uint)8, chroma-format=(string)4:2:0, codec_data=(buffer)01640014ffe1001867640014acd94141fb0110000003001773594000f142996001000568ebecb22cfdf8f800, coded-picture-structure=(string)frame, framerate=(fraction)30/1, height=(int)240, lcevc=(boolean)false, level=(string)2, parsed=(boolean)true, pixel-aspect-ratio=(fraction)1/1, profile=(string)high, stream-format=(string)avc, width=(int)320; event segment: format=TIME, start=0:00:00.066666666, offset=0:00:00.000000000, stop=0:00:10.066666666, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.066666666 event tag: GstTagList-stream, taglist=(taglist)"taglist\,\ video-codec\=\(string\)\"H.264\\\ /\\\ AVC\"\,\ bitrate\=\(uint\)99582\,\ language-code\=\(string\)en\,\ container-specific-track-id\=\(string\)1\;"; event tag: GstTagList-global, taglist=(taglist)"taglist\,\ datetime\=\(datetime\)2013-09-03T16:21:39Z\,\ description\=\(string\)\"audiotest\\\ wave\"\,\ encoder\=\(string\)x264\,\ container-format\=\(string\)Quicktime\;"; diff --git a/subprojects/gst-integration-testsuites/testsuites/validate/hls/with_empty_segments/flow-expectations/log-hlsdemux2-0-video_00-expected b/subprojects/gst-integration-testsuites/testsuites/validate/hls/with_empty_segments/flow-expectations/log-hlsdemux2-0-video_00-expected index 9bbf042353..a1d83b0955 100644 --- a/subprojects/gst-integration-testsuites/testsuites/validate/hls/with_empty_segments/flow-expectations/log-hlsdemux2-0-video_00-expected +++ b/subprojects/gst-integration-testsuites/testsuites/validate/hls/with_empty_segments/flow-expectations/log-hlsdemux2-0-video_00-expected @@ -1,6 +1,6 @@ event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_SELECT, group-id=(uint)1; event stream-collection: stream-collection, collection=(GstStreamCollection)"\(GstStreamCollection\)\ adaptivedemux"; -event caps: video/x-h264, alignment=(string)au, bit-depth-chroma=(uint)8, bit-depth-luma=(uint)8, chroma-format=(string)4:2:0, codec_data=(buffer)01640033ffe1001027640033ac56700d8010fa6a0202020401000428ee3cb0, coded-picture-structure=(string)frame, colorimetry=(string)bt709, framerate=(fraction)0/1, height=(int)2160, interlace-mode=(string)progressive, level=(string)5.1, parsed=(boolean)true, pixel-aspect-ratio=(fraction)1/1, profile=(string)high, stream-format=(string)avc, width=(int)3456; +event caps: video/x-h264, alignment=(string)au, bit-depth-chroma=(uint)8, bit-depth-luma=(uint)8, chroma-format=(string)4:2:0, codec_data=(buffer)01640033ffe1001027640033ac56700d8010fa6a0202020401000428ee3cb0fdf8f800, coded-picture-structure=(string)frame, colorimetry=(string)bt709, framerate=(fraction)0/1, height=(int)2160, interlace-mode=(string)progressive, level=(string)5.1, parsed=(boolean)true, pixel-aspect-ratio=(fraction)1/1, profile=(string)high, stream-format=(string)avc, width=(int)3456; event segment: format=TIME, start=0:00:00.000000000, offset=0:00:00.000000000, stop=none, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.000000000 event gap: GstEventGap, duration=(guint64)100000000, timestamp=(guint64)0; event gap: GstEventGap, duration=(guint64)100000000, timestamp=(guint64)100000000; diff --git a/subprojects/gst-integration-testsuites/testsuites/validate/mp4/qtdemux_reverse_playback_full_gop.reverse_playback_full_gop/flow-expectations/log-parse-src-expected b/subprojects/gst-integration-testsuites/testsuites/validate/mp4/qtdemux_reverse_playback_full_gop.reverse_playback_full_gop/flow-expectations/log-parse-src-expected index 5b75e561cb..e295c44a74 100644 --- a/subprojects/gst-integration-testsuites/testsuites/validate/mp4/qtdemux_reverse_playback_full_gop.reverse_playback_full_gop/flow-expectations/log-parse-src-expected +++ b/subprojects/gst-integration-testsuites/testsuites/validate/mp4/qtdemux_reverse_playback_full_gop.reverse_playback_full_gop/flow-expectations/log-parse-src-expected @@ -1,5 +1,5 @@ event stream-start: GstEventStreamStart, flags=(GstStreamFlags)GST_STREAM_FLAG_NONE, group-id=(uint)1; -event caps: video/x-h264, alignment=(string)au, bit-depth-chroma=(uint)8, bit-depth-luma=(uint)8, chroma-format=(string)4:2:0, codec_data=(buffer)01640014ffe1001867640014acd94141fb0110000003001773594000f142996001000568ebecb22c, coded-picture-structure=(string)frame, framerate=(fraction)30/1, height=(int)240, lcevc=(boolean)false, level=(string)2, parsed=(boolean)true, pixel-aspect-ratio=(fraction)1/1, profile=(string)high, stream-format=(string)avc, width=(int)320; +event caps: video/x-h264, alignment=(string)au, bit-depth-chroma=(uint)8, bit-depth-luma=(uint)8, chroma-format=(string)4:2:0, codec_data=(buffer)01640014ffe1001867640014acd94141fb0110000003001773594000f142996001000568ebecb22cfdf8f800, coded-picture-structure=(string)frame, framerate=(fraction)30/1, height=(int)240, lcevc=(boolean)false, level=(string)2, parsed=(boolean)true, pixel-aspect-ratio=(fraction)1/1, profile=(string)high, stream-format=(string)avc, width=(int)320; event segment: format=TIME, start=0:00:00.066666666, offset=0:00:00.000000000, stop=0:00:10.066666666, time=0:00:00.000000000, base=0:00:00.000000000, position=0:00:00.066666666 event tag: GstTagList-stream, taglist=(taglist)"taglist\,\ video-codec\=\(string\)\"H.264\\\ /\\\ AVC\"\,\ bitrate\=\(uint\)99582\,\ language-code\=\(string\)en\,\ container-specific-track-id\=\(string\)1\;"; event tag: GstTagList-global, taglist=(taglist)"taglist\,\ datetime\=\(datetime\)2013-09-03T16:21:39Z\,\ description\=\(string\)\"audiotest\\\ wave\"\,\ encoder\=\(string\)x264\,\ container-format\=\(string\)Quicktime\;"; diff --git a/subprojects/gst-plugins-bad/gst/videoparsers/gsth264parse.c b/subprojects/gst-plugins-bad/gst/videoparsers/gsth264parse.c index 16c138dad2..af590a06d3 100644 --- a/subprojects/gst-plugins-bad/gst/videoparsers/gsth264parse.c +++ b/subprojects/gst-plugins-bad/gst/videoparsers/gsth264parse.c @@ -1690,7 +1690,13 @@ gst_h264_parse_make_codec_data (GstH264Parse * h264parse) && GST_H264_PARSE_FORMAT_AVC3 != h264parse->format)) return NULL; - buf = gst_buffer_new_allocate (NULL, 5 + 1 + sps_size + 1 + pps_size, NULL); + if ((profile_idc != 66) && (profile_idc != 77) && (profile_idc != 88)) { + buf = + gst_buffer_new_allocate (NULL, 5 + 1 + sps_size + 1 + pps_size + 4, + NULL); + } else { + buf = gst_buffer_new_allocate (NULL, 5 + 1 + sps_size + 1 + pps_size, NULL); + } gst_buffer_map (buf, &map, GST_MAP_WRITE); data = map.data; nl = h264parse->nal_length_size; @@ -1727,6 +1733,18 @@ gst_h264_parse_make_codec_data (GstH264Parse * h264parse) } } + if ((profile_idc != 66) && (profile_idc != 77) && (profile_idc != 88) + && (h264parse->nalparser->last_sps)) { + data[0] = 0xfc | h264parse->nalparser->last_sps->chroma_format_idc; + data++; + data[0] = 0xf8 | h264parse->nalparser->last_sps->bit_depth_luma_minus8; + data++; + data[0] = 0xf8 | h264parse->nalparser->last_sps->bit_depth_chroma_minus8; + data++; + data[0] = 0; // numOfSequenceParameterSetExt; + data++; + } + gst_buffer_unmap (buf, &map); return buf;