From c8bf98e8e23920535edd17a801bd84426ba82d67 Mon Sep 17 00:00:00 2001 From: Haibo Chen Date: Fri, 27 Aug 2021 07:27:33 +0800 Subject: [PATCH] Support for multiple SPS/PPS, then pick the first one. (#2544) --- trunk/doc/CHANGELOG.md | 1 + trunk/src/core/srs_core_version4.hpp | 2 +- trunk/src/kernel/srs_kernel_codec.cpp | 62 ++++++++++++++++----------- trunk/src/utest/srs_utest_kernel.cpp | 16 +++++++ 4 files changed, 56 insertions(+), 25 deletions(-) diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md index daa3774a8..1543e7351 100644 --- a/trunk/doc/CHANGELOG.md +++ b/trunk/doc/CHANGELOG.md @@ -8,6 +8,7 @@ The changelog for SRS. ## SRS 4.0 Changelog +* v4.0, 2021-08-27, RTC: Merge [#2544](https://github.com/ossrs/srs/pull/2544), Support for multiple SPS/PPS, then pick the first one. 4.0.158 * v4.0, 2021-08-17, RTC: Merge [#2470](https://github.com/ossrs/srs/pull/2470), RTC: Fix rtc to rtmp sync timestamp using sender report. 4.0.157 * v4.0, 2021-08-14, Support Github Actions to publish SRS. 4.0.155 * v4.0, 2021-08-14, RTC: Merge [#2533](https://github.com/ossrs/srs/pull/2533), fix SDP comparison bug. 4.0.154 diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index fb0dd9d0b..6c918046a 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -9,6 +9,6 @@ #define VERSION_MAJOR 4 #define VERSION_MINOR 0 -#define VERSION_REVISION 157 +#define VERSION_REVISION 158 #endif diff --git a/trunk/src/kernel/srs_kernel_codec.cpp b/trunk/src/kernel/srs_kernel_codec.cpp index dc5670ee8..69138c5cd 100644 --- a/trunk/src/kernel/srs_kernel_codec.cpp +++ b/trunk/src/kernel/srs_kernel_codec.cpp @@ -806,41 +806,55 @@ srs_error_t SrsFormat::avc_demux_sps_pps(SrsBuffer* stream) } int8_t numOfSequenceParameterSets = stream->read_1bytes(); numOfSequenceParameterSets &= 0x1f; - if (numOfSequenceParameterSets != 1) { + if (numOfSequenceParameterSets < 1) { return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS"); } - if (!stream->require(2)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS size"); - } - uint16_t sequenceParameterSetLength = stream->read_2bytes(); - if (!stream->require(sequenceParameterSetLength)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS data"); - } - if (sequenceParameterSetLength > 0) { - vcodec->sequenceParameterSetNALUnit.resize(sequenceParameterSetLength); - stream->read_bytes(&vcodec->sequenceParameterSetNALUnit[0], sequenceParameterSetLength); + // Support for multiple SPS, then pick the first non-empty one. + for (int i = 0; i < numOfSequenceParameterSets; ++i) { + if (!stream->require(2)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS size"); + } + uint16_t sequenceParameterSetLength = stream->read_2bytes(); + if (!stream->require(sequenceParameterSetLength)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS data"); + } + if (vcodec->sequenceParameterSetNALUnit.size() > 0) { + stream->skip(sequenceParameterSetLength); + continue; + } + if (sequenceParameterSetLength > 0) { + vcodec->sequenceParameterSetNALUnit.resize(sequenceParameterSetLength); + stream->read_bytes(&vcodec->sequenceParameterSetNALUnit[0], sequenceParameterSetLength); + } } + // 1 pps if (!stream->require(1)) { return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS"); } int8_t numOfPictureParameterSets = stream->read_1bytes(); numOfPictureParameterSets &= 0x1f; - if (numOfPictureParameterSets != 1) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS"); + if (numOfPictureParameterSets < 1) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode SPS"); } - if (!stream->require(2)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS size"); + // Support for multiple PPS, then pick the first non-empty one. + for (int i = 0; i < numOfPictureParameterSets; ++i) { + if (!stream->require(2)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS size"); + } + uint16_t pictureParameterSetLength = stream->read_2bytes(); + if (!stream->require(pictureParameterSetLength)) { + return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS data"); + } + if (vcodec->pictureParameterSetNALUnit.size() > 0) { + stream->skip(pictureParameterSetLength); + continue; + } + if (pictureParameterSetLength > 0) { + vcodec->pictureParameterSetNALUnit.resize(pictureParameterSetLength); + stream->read_bytes(&vcodec->pictureParameterSetNALUnit[0], pictureParameterSetLength); + } } - uint16_t pictureParameterSetLength = stream->read_2bytes(); - if (!stream->require(pictureParameterSetLength)) { - return srs_error_new(ERROR_HLS_DECODE_ERROR, "decode PPS data"); - } - if (pictureParameterSetLength > 0) { - vcodec->pictureParameterSetNALUnit.resize(pictureParameterSetLength); - stream->read_bytes(&vcodec->pictureParameterSetNALUnit[0], pictureParameterSetLength); - } - return avc_demux_sps(); } diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp index f41fe7e59..366a70cde 100644 --- a/trunk/src/utest/srs_utest_kernel.cpp +++ b/trunk/src/utest/srs_utest_kernel.cpp @@ -3723,6 +3723,22 @@ VOID TEST(KernelCodecTest, VideoFormatSepcial) }; HELPER_EXPECT_SUCCESS(f.on_video(0, (char*)buf, sizeof(buf))); } + + if (true) { + SrsFormat f; + HELPER_EXPECT_SUCCESS(f.initialize()); + uint8_t buf[] = { + 0x17, // 1, Keyframe; 7, AVC. + 0x00, // 0, Sequence header. + 0x00, 0x00, 0x00, // Timestamp. + // AVC extra data, SPS/PPS. + 0x00, 0x00, 0x00, 0x00, + 0x00, // lengthSizeMinusOne + 0x02, 0x00, 0x00, 0x00, 0x00, // 2 SPS, + 0x02, 0x00, 0x00, 0x00, 0x00 // 2 PPS, + }; + HELPER_EXPECT_SUCCESS(f.on_video(0, (char*)buf, sizeof(buf))); + } } VOID TEST(KernelCodecTest, VideoFormat)