diff --git a/trunk/conf/full.conf b/trunk/conf/full.conf
index 10a9f1db98..cfd4259c6e 100644
--- a/trunk/conf/full.conf
+++ b/trunk/conf/full.conf
@@ -1328,7 +1328,6 @@ vhost stream.control.com {
vhost publish.srs.com {
# the config for FMLE/Flash publisher, which push RTMP to SRS.
publish {
- # about MR, read https://github.com/ossrs/srs/issues/241
# when enabled the mr, SRS will read as large as possible.
# Overwrite by env SRS_VHOST_PUBLISH_MR for all vhosts.
# default: off
@@ -1401,7 +1400,6 @@ vhost refer.anti_suck.com {
# the security to allow or deny clients.
vhost security.srs.com {
# security for host to allow or deny clients.
- # @see https://github.com/ossrs/srs/issues/211
security {
# whether enable the security for vhost.
# default: off
@@ -1781,7 +1779,6 @@ vhost hls.srs.com {
# the hls m3u8 target duration ratio,
# EXT-X-TARGETDURATION = hls_td_ratio * hls_fragment // init
# EXT-X-TARGETDURATION = max(ts_duration, EXT-X-TARGETDURATION) // for each ts
- # @see https://github.com/ossrs/srs/issues/304#issuecomment-74000081
# Overwrite by env SRS_VHOST_HLS_HLS_TD_RATIO for all vhosts.
# default: 1.5
hls_td_ratio 1.5;
@@ -1800,7 +1797,6 @@ vhost hls.srs.com {
# ignore, disable the hls.
# disconnect, require encoder republish.
# continue, ignore failed try to continue output hls.
- # @see https://github.com/ossrs/srs/issues/264
# Overwrite by env SRS_VHOST_HLS_HLS_ON_ERROR for all vhosts.
# default: continue
hls_on_error continue;
diff --git a/trunk/conf/security.deny.publish.conf b/trunk/conf/security.deny.publish.conf
index fc2a2e809d..574b5fcec2 100644
--- a/trunk/conf/security.deny.publish.conf
+++ b/trunk/conf/security.deny.publish.conf
@@ -1,5 +1,4 @@
# security config for srs, allow play and deny publish.
-# @see https://github.com/ossrs/srs/issues/211#issuecomment-68507035
# @see full.conf for detail config.
listen 1935;
diff --git a/trunk/doc/CHANGELOG.md b/trunk/doc/CHANGELOG.md
index 7713cb1ecf..f0538ec957 100644
--- a/trunk/doc/CHANGELOG.md
+++ b/trunk/doc/CHANGELOG.md
@@ -7,6 +7,7 @@ The changelog for SRS.
## SRS 6.0 Changelog
+* v6.0, 2023-09-08, Merge [#3597](https://github.com/ossrs/srs/pull/3597): Fix RBSP stream parsing bug, should drop 0x03. v6.0.75 (#3597)
* v6.0, 2023-09-08, Merge [#3794](https://github.com/ossrs/srs/pull/3794): Support SRS Stack token for authentication. v6.0.74 (#3794)
* v6.0, 2023-09-07, Merge [#3795](https://github.com/ossrs/srs/pull/3795): Fix dash crash if format not supported. v6.0.73 (#3795)
* v6.0, 2023-08-30, Merge [#3776](https://github.com/ossrs/srs/pull/3776): Compile: Add aarch64 to the conditions of use of the cbrt function. v6.0.72 (#3776)
@@ -86,6 +87,7 @@ The changelog for SRS.
## SRS 5.0 Changelog
+* v5.0, 2023-09-08, Merge [#3597](https://github.com/ossrs/srs/pull/3597): Fix RBSP stream parsing bug, should drop 0x03. v5.0.178 (#3597)
* v5.0, 2023-09-07, Merge [#3795](https://github.com/ossrs/srs/pull/3795): Fix dash crash if format not supported. v5.0.177 (#3795)
* v5.0, 2023-08-30, Merge [#3779](https://github.com/ossrs/srs/pull/3779): Support HTTP-API for fetching reload result. v5.0.176 (#3779)
* v5.0, 2023-08-28, Merge [#3503](https://github.com/ossrs/srs/pull/3503): SrsContextId assignment can be improved without create a duplicated one. v5.0.175 (#3503)
diff --git a/trunk/src/core/srs_core_version5.hpp b/trunk/src/core/srs_core_version5.hpp
index 78c2ca80e9..163f2a2a67 100644
--- a/trunk/src/core/srs_core_version5.hpp
+++ b/trunk/src/core/srs_core_version5.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 5
#define VERSION_MINOR 0
-#define VERSION_REVISION 177
+#define VERSION_REVISION 178
#endif
diff --git a/trunk/src/core/srs_core_version6.hpp b/trunk/src/core/srs_core_version6.hpp
index 6883135174..e055cff175 100644
--- a/trunk/src/core/srs_core_version6.hpp
+++ b/trunk/src/core/srs_core_version6.hpp
@@ -9,6 +9,6 @@
#define VERSION_MAJOR 6
#define VERSION_MINOR 0
-#define VERSION_REVISION 74
+#define VERSION_REVISION 75
#endif
diff --git a/trunk/src/kernel/srs_kernel_codec.cpp b/trunk/src/kernel/srs_kernel_codec.cpp
index 727a9e7c44..cf4ec6cbe7 100644
--- a/trunk/src/kernel/srs_kernel_codec.cpp
+++ b/trunk/src/kernel/srs_kernel_codec.cpp
@@ -867,6 +867,44 @@ bool SrsFormat::is_avc_sequence_header()
&& video && video->avc_packet_type == SrsVideoAvcFrameTraitSequenceHeader;
}
+// Remove the emulation bytes from stream, and return num of bytes of the rbsp.
+int srs_rbsp_remove_emulation_bytes(SrsBuffer* stream, std::vector& rbsp)
+{
+ int nb_rbsp = 0;
+ while (!stream->empty()) {
+ rbsp[nb_rbsp] = stream->read_1bytes();
+
+ // .. 00 00 03 xx, the 03 byte should be drop where xx represents any
+ // 2 bit pattern: 00, 01, 10, or 11.
+ if (nb_rbsp >= 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
+ // read 1byte more.
+ if (stream->empty()) {
+ nb_rbsp++;
+ break;
+ }
+
+ // |---------------------|----------------------------|
+ // | rbsp | nalu with emulation bytes |
+ // |---------------------|----------------------------|
+ // | 0x00 0x00 0x00 | 0x00 0x00 0x03 0x00 |
+ // | 0x00 0x00 0x01 | 0x00 0x00 0x03 0x01 |
+ // | 0x00 0x00 0x02 | 0x00 0x00 0x03 0x02 |
+ // | 0x00 0x00 0x03 | 0x00 0x00 0x03 0x03 |
+ // | 0x00 0x00 0x03 0x04 | 0x00 0x00 0x03 0x04 |
+ // |---------------------|----------------------------|
+ uint8_t ev = stream->read_1bytes();
+ if (ev > 3) {
+ nb_rbsp++;
+ }
+ rbsp[nb_rbsp] = ev;
+ }
+
+ nb_rbsp++;
+ }
+
+ return nb_rbsp;
+}
+
srs_error_t SrsFormat::video_avc_demux(SrsBuffer* stream, int64_t timestamp)
{
srs_error_t err = srs_success;
@@ -1224,26 +1262,9 @@ srs_error_t SrsFormat::hevc_demux_vps(SrsBuffer *stream)
// decode the rbsp from vps.
// rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes.
- std::vector rbsp(stream->size());
+ std::vector rbsp(stream->size());
- int nb_rbsp = 0;
- while (!stream->empty()) {
- rbsp[nb_rbsp] = stream->read_1bytes();
-
- // XX 00 00 03 XX, the 03 byte should be drop.
- if (nb_rbsp > 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
- // read 1byte more.
- if (stream->empty()) {
- break;
- }
- rbsp[nb_rbsp] = stream->read_1bytes();
- nb_rbsp++;
-
- continue;
- }
-
- nb_rbsp++;
- }
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp);
return hevc_demux_vps_rbsp((char*)&rbsp[0], nb_rbsp);
}
@@ -1370,26 +1391,9 @@ srs_error_t SrsFormat::hevc_demux_sps(SrsBuffer *stream)
// decode the rbsp from sps.
// rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes.
- std::vector rbsp(stream->size());
+ std::vector rbsp(stream->size());
- int nb_rbsp = 0;
- while (!stream->empty()) {
- rbsp[nb_rbsp] = stream->read_1bytes();
-
- // XX 00 00 03 XX, the 03 byte should be drop.
- if (nb_rbsp > 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
- // read 1byte more.
- if (stream->empty()) {
- break;
- }
- rbsp[nb_rbsp] = stream->read_1bytes();
- nb_rbsp++;
-
- continue;
- }
-
- nb_rbsp++;
- }
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp);
return hevc_demux_sps_rbsp((char*)&rbsp[0], nb_rbsp);
}
@@ -1571,28 +1575,11 @@ srs_error_t SrsFormat::hevc_demux_pps(SrsBuffer *stream)
// nuh_layer_id + nuh_temporal_id_plus1
stream->skip(1);
- // decode the rbsp from sps.
+ // decode the rbsp from pps.
// rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes.
- std::vector rbsp(stream->size());
-
- int nb_rbsp = 0;
- while (!stream->empty()) {
- rbsp[nb_rbsp] = stream->read_1bytes();
-
- // XX 00 00 03 XX, the 03 byte should be drop.
- if (nb_rbsp > 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
- // read 1byte more.
- if (stream->empty()) {
- break;
- }
- rbsp[nb_rbsp] = stream->read_1bytes();
- nb_rbsp++;
+ std::vector rbsp(stream->size());
- continue;
- }
-
- nb_rbsp++;
- }
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp);
return hevc_demux_pps_rbsp((char*)&rbsp[0], nb_rbsp);
}
@@ -2270,31 +2257,13 @@ srs_error_t SrsFormat::avc_demux_sps()
// decode the rbsp from sps.
// rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes.
- std::vector rbsp(vcodec->sequenceParameterSetNALUnit.size());
+ std::vector rbsp(vcodec->sequenceParameterSetNALUnit.size());
- int nb_rbsp = 0;
- while (!stream.empty()) {
- rbsp[nb_rbsp] = stream.read_1bytes();
-
- // XX 00 00 03 XX, the 03 byte should be drop.
- if (nb_rbsp > 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
- // read 1byte more.
- if (stream.empty()) {
- break;
- }
- rbsp[nb_rbsp] = stream.read_1bytes();
- nb_rbsp++;
-
- continue;
- }
-
- nb_rbsp++;
- }
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&stream, rbsp);
return avc_demux_sps_rbsp((char*)&rbsp[0], nb_rbsp);
}
-
srs_error_t SrsFormat::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
{
srs_error_t err = srs_success;
diff --git a/trunk/src/utest/srs_utest_kernel.cpp b/trunk/src/utest/srs_utest_kernel.cpp
index f2b2e32b17..862c593815 100644
--- a/trunk/src/utest/srs_utest_kernel.cpp
+++ b/trunk/src/utest/srs_utest_kernel.cpp
@@ -3887,6 +3887,80 @@ VOID TEST(KernelCodecTest, VideoFormatSepcial)
}
}
+VOID TEST(KernelCoecTest, VideoFormatRbspData)
+{
+ if (true) {
+ vector nalu = {
+ 0x25, 0x00, 0x1f, 0xe2, 0x22, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0xab, 0xff
+ };
+
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ vector rbsp(nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)nalu.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), nalu.data(), nb_rbsp));
+ }
+
+ if (true) {
+ SrsFormat f;
+ vector nalu = {
+ 0x25, 0x00, 0x1f, 0xe2, 0x22, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x80, 0xab, 0xff
+ };
+ vector expect = {
+ 0x25, 0x00, 0x1f, 0xe2, 0x22, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0xab, 0xff
+ };
+
+ // |----------------|----------------------------|
+ // | rbsp | nalu with emulation bytes |
+ // |----------------|----------------------------|
+ // | 0x00 0x00 0x00 | 0x00 0x00 0x03 0x00 |
+ // | 0x00 0x00 0x01 | 0x00 0x00 0x03 0x01 |
+ // | 0x00 0x00 0x02 | 0x00 0x00 0x03 0x02 |
+ // | 0x00 0x00 0x03 | 0x00 0x00 0x03 0x03 |
+ // |----------------|----------------------------|
+ for (int i = 0; i <= 3; ++i) {
+ nalu[8] = uint8_t(i);
+ expect[7] = uint8_t(i);
+
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ vector rbsp(nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ // 0x00 0x00 0x04 ~ 0x00 0x00 0xFF, no need to add emulation bytes.
+ for (int i = 4; i <= 0xff; ++i) {
+ nalu[8] = uint8_t(i);
+
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ vector rbsp(nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)nalu.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), nalu.data(), nb_rbsp));
+ }
+ }
+
+ if (true) {
+ vector nalu = {
+ 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x04
+ };
+ vector expect = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04
+ };
+
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ vector rbsp(nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+}
+
VOID TEST(KernelCodecTest, VideoFormat)
{
srs_error_t err;
@@ -6346,4 +6420,4 @@ VOID TEST(KernelUtilityTest, Base64Decode)
HELPER_EXPECT_FAILED(srs_av_base64_decode("YWRtaW46YWRtaW", plaintext));
EXPECT_STRNE("admin:admin", plaintext.c_str());
}
-}
\ No newline at end of file
+}
diff --git a/trunk/src/utest/srs_utest_kernel.hpp b/trunk/src/utest/srs_utest_kernel.hpp
index ef93f437f9..5f4cbd56fb 100644
--- a/trunk/src/utest/srs_utest_kernel.hpp
+++ b/trunk/src/utest/srs_utest_kernel.hpp
@@ -21,6 +21,7 @@
#include
#include
#include
+#include
class MockSrsFile
{
@@ -155,5 +156,7 @@ class MockPsHandler : public ISrsPsMessageHandler
MockPsHandler* clear();
};
+extern int srs_rbsp_remove_emulation_bytes(SrsBuffer* stream, std::vector& rbsp);
+
#endif
diff --git a/trunk/src/utest/srs_utest_kernel2.cpp b/trunk/src/utest/srs_utest_kernel2.cpp
index ecaf4a9d15..42ed42a50f 100644
--- a/trunk/src/utest/srs_utest_kernel2.cpp
+++ b/trunk/src/utest/srs_utest_kernel2.cpp
@@ -526,3 +526,213 @@ VOID TEST(KernelCodecTest, VideoFormatSepcialAsan_DJI_M30)
memcpy(data, "\x27\x01\x00\x00\x00\x00\x00\x00\x00", sizeof(data));
HELPER_EXPECT_SUCCESS(f.on_video(0, data, sizeof(data)));
}
+
+VOID TEST(KernelCodecTest, VideoFormatRbspSimple)
+{
+ // |---------------------|----------------------------|
+ // | rbsp | nalu with emulation bytes |
+ // |---------------------|----------------------------|
+ // | 0x00 0x00 0x00 | 0x00 0x00 0x03 0x00 |
+ // | 0x00 0x00 0x01 | 0x00 0x00 0x03 0x01 |
+ // | 0x00 0x00 0x02 | 0x00 0x00 0x03 0x02 |
+ // | 0x00 0x00 0x03 | 0x00 0x00 0x03 0x03 |
+ // | 0x00 0x00 0x03 0x04 | 0x00 0x00 0x03 0x04 |
+ // |---------------------|----------------------------|
+ if (true) {
+ vector nalu = {0x00, 0x00, 0x03, 0x00};
+ vector expect = {0x00, 0x00, 0x00};
+
+ vector rbsp(nalu.size());
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ if (true) {
+ vector nalu = {0x00, 0x00, 0x03, 0x01};
+ vector expect = {0x00, 0x00, 0x01};
+
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ vector rbsp(nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ if (true) {
+ vector nalu = {0x00, 0x00, 0x03, 0x02};
+ vector expect = {0x00, 0x00, 0x02};
+
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ vector rbsp(nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ if (true) {
+ vector nalu = {0x00, 0x00, 0x03, 0x03};
+ vector expect = {0x00, 0x00, 0x03};
+
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ vector rbsp(nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ if (true) {
+ vector nalu = {0x00, 0x00, 0x03, 0x04};
+ vector expect = {0x00, 0x00, 0x03, 0x04};
+
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ vector rbsp(nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ if (true) {
+ vector nalu = {0x00, 0x00, 0x03, 0xff};
+ vector expect = {0x00, 0x00, 0x03, 0xff};
+
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ vector rbsp(nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+}
+
+VOID TEST(KernelCodecTest, VideoFormatRbspEdge)
+{
+ if (true) {
+ vector nalu = {0x00, 0x00, 0x03};
+ vector expect = {0x00, 0x00, 0x03};
+
+ vector rbsp(nalu.size());
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ if (true) {
+ vector nalu = {0xff, 0x00, 0x00, 0x03};
+ vector expect = {0xff, 0x00, 0x00, 0x03};
+
+ vector rbsp(nalu.size());
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ for (uint16_t v = 0x01; v <= 0xff; v++) {
+ vector nalu = {(uint8_t)v, 0x00, 0x00, 0x03};
+ vector expect = {(uint8_t)v, 0x00, 0x00, 0x03};
+
+ vector rbsp(nalu.size());
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+}
+
+VOID TEST(KernelCodecTest, VideoFormatRbspNormal)
+{
+ for (uint16_t v = 0x01; v <= 0xff; v++) {
+ vector nalu = {0x00, (uint8_t)v, 0x03, 0x00};
+ vector expect = {0x00, (uint8_t)v, 0x03, 0x00};
+
+ vector rbsp(nalu.size());
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ for (uint16_t v = 0x01; v <= 0xff; v++) {
+ vector nalu = {(uint8_t)v, 0x00, 0x03, 0x00};
+ vector expect = {(uint8_t)v, 0x00, 0x03, 0x00};
+
+ vector rbsp(nalu.size());
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ for (uint16_t v = 0x00; v <= 0xff; v++) {
+ vector nalu = {0x00, 0x00, (uint8_t)v};
+ vector expect = {0x00, 0x00, (uint8_t)v};
+
+ vector rbsp(nalu.size());
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ for (uint16_t v = 0x00; v <= 0xff; v++) {
+ vector nalu = {0x00, (uint8_t)v};
+ vector expect = {0x00, (uint8_t)v};
+
+ vector rbsp(nalu.size());
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ for (uint16_t v = 0x00; v <= 0xff; v++) {
+ vector nalu = {(uint8_t)v};
+ vector expect = {(uint8_t)v};
+
+ vector rbsp(nalu.size());
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ for (uint16_t v = 0x00; v <= 0xff; v++) {
+ vector nalu = {(uint8_t)v, (uint8_t)v};
+ vector expect = {(uint8_t)v, (uint8_t)v};
+
+ vector rbsp(nalu.size());
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+
+ for (uint16_t v = 0x00; v <= 0xff; v++) {
+ vector nalu = {(uint8_t)v, (uint8_t)v, (uint8_t)v};
+ vector expect = {(uint8_t)v, (uint8_t)v, (uint8_t)v};
+
+ vector rbsp(nalu.size());
+ SrsBuffer b((char*)nalu.data(), nalu.size());
+ int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
+
+ ASSERT_EQ(nb_rbsp, (int)expect.size());
+ EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
+ }
+}