Skip to content

Fix RBSP issue, where 0x03 should be removed. v5.0.178 v6.0.75 #3597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Sep 9, 2023
4 changes: 0 additions & 4 deletions trunk/conf/full.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
1 change: 0 additions & 1 deletion trunk/conf/security.deny.publish.conf
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
2 changes: 2 additions & 0 deletions trunk/doc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ The changelog for SRS.
<a name="v6-changes"></a>

## 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)
Expand Down Expand Up @@ -86,6 +87,7 @@ The changelog for SRS.
<a name="v5-changes"></a>

## 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)
Expand Down
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core_version5.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

#define VERSION_MAJOR 5
#define VERSION_MINOR 0
#define VERSION_REVISION 177
#define VERSION_REVISION 178

#endif
2 changes: 1 addition & 1 deletion trunk/src/core/srs_core_version6.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@

#define VERSION_MAJOR 6
#define VERSION_MINOR 0
#define VERSION_REVISION 74
#define VERSION_REVISION 75

#endif
125 changes: 47 additions & 78 deletions trunk/src/kernel/srs_kernel_codec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<uint8_t>& 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;
Expand Down Expand Up @@ -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<int8_t> rbsp(stream->size());
std::vector<uint8_t> 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);
}
Expand Down Expand Up @@ -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<int8_t> rbsp(stream->size());
std::vector<uint8_t> 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);
}
Expand Down Expand Up @@ -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<int8_t> 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<uint8_t> 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);
}
Expand Down Expand Up @@ -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<int8_t> rbsp(vcodec->sequenceParameterSetNALUnit.size());
std::vector<uint8_t> 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;
Expand Down
76 changes: 75 additions & 1 deletion trunk/src/utest/srs_utest_kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3887,6 +3887,80 @@ VOID TEST(KernelCodecTest, VideoFormatSepcial)
}
}

VOID TEST(KernelCoecTest, VideoFormatRbspData)
{
if (true) {
vector<uint8_t> nalu = {
0x25, 0x00, 0x1f, 0xe2, 0x22, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0xab, 0xff
};

SrsBuffer b((char*)nalu.data(), nalu.size());
vector<uint8_t> 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<uint8_t> nalu = {
0x25, 0x00, 0x1f, 0xe2, 0x22, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x80, 0xab, 0xff
};
vector<uint8_t> 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<uint8_t> 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<uint8_t> 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<uint8_t> nalu = {
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x04
};
vector<uint8_t> expect = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04
};

SrsBuffer b((char*)nalu.data(), nalu.size());
vector<uint8_t> 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;
Expand Down Expand Up @@ -6346,4 +6420,4 @@ VOID TEST(KernelUtilityTest, Base64Decode)
HELPER_EXPECT_FAILED(srs_av_base64_decode("YWRtaW46YWRtaW", plaintext));
EXPECT_STRNE("admin:admin", plaintext.c_str());
}
}
}
3 changes: 3 additions & 0 deletions trunk/src/utest/srs_utest_kernel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <srs_kernel_ts.hpp>
#include <srs_kernel_ps.hpp>
#include <srs_kernel_stream.hpp>
#include <srs_kernel_utility.hpp>

class MockSrsFile
{
Expand Down Expand Up @@ -155,5 +156,7 @@ class MockPsHandler : public ISrsPsMessageHandler
MockPsHandler* clear();
};

extern int srs_rbsp_remove_emulation_bytes(SrsBuffer* stream, std::vector<uint8_t>& rbsp);

#endif

Loading