Skip to content

Commit a671f1a

Browse files
feixintianxiaxiaozhihongchundonglinlinwinlinvip
authored
Fix RBSP issue, where 0x03 should be removed. (#3597)
ISO_IEC_14496-10-AVC-2012.pdf, page 65 7.4.1.1 Encapsulation of an SODB within an RBSP (informative) ... 00 00 03 xx, the 03 byte should be drop where xx represents any 2 bit pattern: 00, 01, 10, or 11. --------- Co-authored-by: john <[email protected]> Co-authored-by: chundonglinlin <[email protected]> Co-authored-by: winlin <[email protected]>
1 parent 6f42ca6 commit a671f1a

9 files changed

+339
-86
lines changed

trunk/conf/full.conf

-4
Original file line numberDiff line numberDiff line change
@@ -1328,7 +1328,6 @@ vhost stream.control.com {
13281328
vhost publish.srs.com {
13291329
# the config for FMLE/Flash publisher, which push RTMP to SRS.
13301330
publish {
1331-
# about MR, read https://github.com/ossrs/srs/issues/241
13321331
# when enabled the mr, SRS will read as large as possible.
13331332
# Overwrite by env SRS_VHOST_PUBLISH_MR for all vhosts.
13341333
# default: off
@@ -1401,7 +1400,6 @@ vhost refer.anti_suck.com {
14011400
# the security to allow or deny clients.
14021401
vhost security.srs.com {
14031402
# security for host to allow or deny clients.
1404-
# @see https://github.com/ossrs/srs/issues/211
14051403
security {
14061404
# whether enable the security for vhost.
14071405
# default: off
@@ -1781,7 +1779,6 @@ vhost hls.srs.com {
17811779
# the hls m3u8 target duration ratio,
17821780
# EXT-X-TARGETDURATION = hls_td_ratio * hls_fragment // init
17831781
# EXT-X-TARGETDURATION = max(ts_duration, EXT-X-TARGETDURATION) // for each ts
1784-
# @see https://github.com/ossrs/srs/issues/304#issuecomment-74000081
17851782
# Overwrite by env SRS_VHOST_HLS_HLS_TD_RATIO for all vhosts.
17861783
# default: 1.5
17871784
hls_td_ratio 1.5;
@@ -1800,7 +1797,6 @@ vhost hls.srs.com {
18001797
# ignore, disable the hls.
18011798
# disconnect, require encoder republish.
18021799
# continue, ignore failed try to continue output hls.
1803-
# @see https://github.com/ossrs/srs/issues/264
18041800
# Overwrite by env SRS_VHOST_HLS_HLS_ON_ERROR for all vhosts.
18051801
# default: continue
18061802
hls_on_error continue;

trunk/conf/security.deny.publish.conf

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
# security config for srs, allow play and deny publish.
2-
# @see https://github.com/ossrs/srs/issues/211#issuecomment-68507035
32
# @see full.conf for detail config.
43

54
listen 1935;

trunk/doc/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ The changelog for SRS.
77
<a name="v6-changes"></a>
88

99
## SRS 6.0 Changelog
10+
* 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)
1011
* v6.0, 2023-09-08, Merge [#3794](https://github.com/ossrs/srs/pull/3794): Support SRS Stack token for authentication. v6.0.74 (#3794)
1112
* 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)
1213
* 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.
8687
<a name="v5-changes"></a>
8788

8889
## SRS 5.0 Changelog
90+
* 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)
8991
* 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)
9092
* 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)
9193
* 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)

trunk/src/core/srs_core_version5.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99

1010
#define VERSION_MAJOR 5
1111
#define VERSION_MINOR 0
12-
#define VERSION_REVISION 177
12+
#define VERSION_REVISION 178
1313

1414
#endif

trunk/src/core/srs_core_version6.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99

1010
#define VERSION_MAJOR 6
1111
#define VERSION_MINOR 0
12-
#define VERSION_REVISION 74
12+
#define VERSION_REVISION 75
1313

1414
#endif

trunk/src/kernel/srs_kernel_codec.cpp

+47-78
Original file line numberDiff line numberDiff line change
@@ -867,6 +867,44 @@ bool SrsFormat::is_avc_sequence_header()
867867
&& video && video->avc_packet_type == SrsVideoAvcFrameTraitSequenceHeader;
868868
}
869869

870+
// Remove the emulation bytes from stream, and return num of bytes of the rbsp.
871+
int srs_rbsp_remove_emulation_bytes(SrsBuffer* stream, std::vector<uint8_t>& rbsp)
872+
{
873+
int nb_rbsp = 0;
874+
while (!stream->empty()) {
875+
rbsp[nb_rbsp] = stream->read_1bytes();
876+
877+
// .. 00 00 03 xx, the 03 byte should be drop where xx represents any
878+
// 2 bit pattern: 00, 01, 10, or 11.
879+
if (nb_rbsp >= 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
880+
// read 1byte more.
881+
if (stream->empty()) {
882+
nb_rbsp++;
883+
break;
884+
}
885+
886+
// |---------------------|----------------------------|
887+
// | rbsp | nalu with emulation bytes |
888+
// |---------------------|----------------------------|
889+
// | 0x00 0x00 0x00 | 0x00 0x00 0x03 0x00 |
890+
// | 0x00 0x00 0x01 | 0x00 0x00 0x03 0x01 |
891+
// | 0x00 0x00 0x02 | 0x00 0x00 0x03 0x02 |
892+
// | 0x00 0x00 0x03 | 0x00 0x00 0x03 0x03 |
893+
// | 0x00 0x00 0x03 0x04 | 0x00 0x00 0x03 0x04 |
894+
// |---------------------|----------------------------|
895+
uint8_t ev = stream->read_1bytes();
896+
if (ev > 3) {
897+
nb_rbsp++;
898+
}
899+
rbsp[nb_rbsp] = ev;
900+
}
901+
902+
nb_rbsp++;
903+
}
904+
905+
return nb_rbsp;
906+
}
907+
870908
srs_error_t SrsFormat::video_avc_demux(SrsBuffer* stream, int64_t timestamp)
871909
{
872910
srs_error_t err = srs_success;
@@ -1224,26 +1262,9 @@ srs_error_t SrsFormat::hevc_demux_vps(SrsBuffer *stream)
12241262

12251263
// decode the rbsp from vps.
12261264
// rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes.
1227-
std::vector<int8_t> rbsp(stream->size());
1265+
std::vector<uint8_t> rbsp(stream->size());
12281266

1229-
int nb_rbsp = 0;
1230-
while (!stream->empty()) {
1231-
rbsp[nb_rbsp] = stream->read_1bytes();
1232-
1233-
// XX 00 00 03 XX, the 03 byte should be drop.
1234-
if (nb_rbsp > 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
1235-
// read 1byte more.
1236-
if (stream->empty()) {
1237-
break;
1238-
}
1239-
rbsp[nb_rbsp] = stream->read_1bytes();
1240-
nb_rbsp++;
1241-
1242-
continue;
1243-
}
1244-
1245-
nb_rbsp++;
1246-
}
1267+
int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp);
12471268

12481269
return hevc_demux_vps_rbsp((char*)&rbsp[0], nb_rbsp);
12491270
}
@@ -1370,26 +1391,9 @@ srs_error_t SrsFormat::hevc_demux_sps(SrsBuffer *stream)
13701391

13711392
// decode the rbsp from sps.
13721393
// rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes.
1373-
std::vector<int8_t> rbsp(stream->size());
1394+
std::vector<uint8_t> rbsp(stream->size());
13741395

1375-
int nb_rbsp = 0;
1376-
while (!stream->empty()) {
1377-
rbsp[nb_rbsp] = stream->read_1bytes();
1378-
1379-
// XX 00 00 03 XX, the 03 byte should be drop.
1380-
if (nb_rbsp > 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
1381-
// read 1byte more.
1382-
if (stream->empty()) {
1383-
break;
1384-
}
1385-
rbsp[nb_rbsp] = stream->read_1bytes();
1386-
nb_rbsp++;
1387-
1388-
continue;
1389-
}
1390-
1391-
nb_rbsp++;
1392-
}
1396+
int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp);
13931397

13941398
return hevc_demux_sps_rbsp((char*)&rbsp[0], nb_rbsp);
13951399
}
@@ -1571,28 +1575,11 @@ srs_error_t SrsFormat::hevc_demux_pps(SrsBuffer *stream)
15711575
// nuh_layer_id + nuh_temporal_id_plus1
15721576
stream->skip(1);
15731577

1574-
// decode the rbsp from sps.
1578+
// decode the rbsp from pps.
15751579
// rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes.
1576-
std::vector<int8_t> rbsp(stream->size());
1577-
1578-
int nb_rbsp = 0;
1579-
while (!stream->empty()) {
1580-
rbsp[nb_rbsp] = stream->read_1bytes();
1581-
1582-
// XX 00 00 03 XX, the 03 byte should be drop.
1583-
if (nb_rbsp > 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
1584-
// read 1byte more.
1585-
if (stream->empty()) {
1586-
break;
1587-
}
1588-
rbsp[nb_rbsp] = stream->read_1bytes();
1589-
nb_rbsp++;
1580+
std::vector<uint8_t> rbsp(stream->size());
15901581

1591-
continue;
1592-
}
1593-
1594-
nb_rbsp++;
1595-
}
1582+
int nb_rbsp = srs_rbsp_remove_emulation_bytes(stream, rbsp);
15961583

15971584
return hevc_demux_pps_rbsp((char*)&rbsp[0], nb_rbsp);
15981585
}
@@ -2270,31 +2257,13 @@ srs_error_t SrsFormat::avc_demux_sps()
22702257

22712258
// decode the rbsp from sps.
22722259
// rbsp[ i ] a raw byte sequence payload is specified as an ordered sequence of bytes.
2273-
std::vector<int8_t> rbsp(vcodec->sequenceParameterSetNALUnit.size());
2260+
std::vector<uint8_t> rbsp(vcodec->sequenceParameterSetNALUnit.size());
22742261

2275-
int nb_rbsp = 0;
2276-
while (!stream.empty()) {
2277-
rbsp[nb_rbsp] = stream.read_1bytes();
2278-
2279-
// XX 00 00 03 XX, the 03 byte should be drop.
2280-
if (nb_rbsp > 2 && rbsp[nb_rbsp - 2] == 0 && rbsp[nb_rbsp - 1] == 0 && rbsp[nb_rbsp] == 3) {
2281-
// read 1byte more.
2282-
if (stream.empty()) {
2283-
break;
2284-
}
2285-
rbsp[nb_rbsp] = stream.read_1bytes();
2286-
nb_rbsp++;
2287-
2288-
continue;
2289-
}
2290-
2291-
nb_rbsp++;
2292-
}
2262+
int nb_rbsp = srs_rbsp_remove_emulation_bytes(&stream, rbsp);
22932263

22942264
return avc_demux_sps_rbsp((char*)&rbsp[0], nb_rbsp);
22952265
}
22962266

2297-
22982267
srs_error_t SrsFormat::avc_demux_sps_rbsp(char* rbsp, int nb_rbsp)
22992268
{
23002269
srs_error_t err = srs_success;

trunk/src/utest/srs_utest_kernel.cpp

+75-1
Original file line numberDiff line numberDiff line change
@@ -3887,6 +3887,80 @@ VOID TEST(KernelCodecTest, VideoFormatSepcial)
38873887
}
38883888
}
38893889

3890+
VOID TEST(KernelCoecTest, VideoFormatRbspData)
3891+
{
3892+
if (true) {
3893+
vector<uint8_t> nalu = {
3894+
0x25, 0x00, 0x1f, 0xe2, 0x22, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0xab, 0xff
3895+
};
3896+
3897+
SrsBuffer b((char*)nalu.data(), nalu.size());
3898+
vector<uint8_t> rbsp(nalu.size());
3899+
int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
3900+
3901+
ASSERT_EQ(nb_rbsp, (int)nalu.size());
3902+
EXPECT_TRUE(srs_bytes_equals(rbsp.data(), nalu.data(), nb_rbsp));
3903+
}
3904+
3905+
if (true) {
3906+
SrsFormat f;
3907+
vector<uint8_t> nalu = {
3908+
0x25, 0x00, 0x1f, 0xe2, 0x22, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x80, 0xab, 0xff
3909+
};
3910+
vector<uint8_t> expect = {
3911+
0x25, 0x00, 0x1f, 0xe2, 0x22, 0x00, 0x00, 0x02, 0x00, 0x00, 0x80, 0xab, 0xff
3912+
};
3913+
3914+
// |----------------|----------------------------|
3915+
// | rbsp | nalu with emulation bytes |
3916+
// |----------------|----------------------------|
3917+
// | 0x00 0x00 0x00 | 0x00 0x00 0x03 0x00 |
3918+
// | 0x00 0x00 0x01 | 0x00 0x00 0x03 0x01 |
3919+
// | 0x00 0x00 0x02 | 0x00 0x00 0x03 0x02 |
3920+
// | 0x00 0x00 0x03 | 0x00 0x00 0x03 0x03 |
3921+
// |----------------|----------------------------|
3922+
for (int i = 0; i <= 3; ++i) {
3923+
nalu[8] = uint8_t(i);
3924+
expect[7] = uint8_t(i);
3925+
3926+
SrsBuffer b((char*)nalu.data(), nalu.size());
3927+
vector<uint8_t> rbsp(nalu.size());
3928+
int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
3929+
3930+
ASSERT_EQ(nb_rbsp, (int)expect.size());
3931+
EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
3932+
}
3933+
3934+
// 0x00 0x00 0x04 ~ 0x00 0x00 0xFF, no need to add emulation bytes.
3935+
for (int i = 4; i <= 0xff; ++i) {
3936+
nalu[8] = uint8_t(i);
3937+
3938+
SrsBuffer b((char*)nalu.data(), nalu.size());
3939+
vector<uint8_t> rbsp(nalu.size());
3940+
int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
3941+
3942+
ASSERT_EQ(nb_rbsp, (int)nalu.size());
3943+
EXPECT_TRUE(srs_bytes_equals(rbsp.data(), nalu.data(), nb_rbsp));
3944+
}
3945+
}
3946+
3947+
if (true) {
3948+
vector<uint8_t> nalu = {
3949+
0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x04
3950+
};
3951+
vector<uint8_t> expect = {
3952+
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x03, 0x00, 0x00, 0x04
3953+
};
3954+
3955+
SrsBuffer b((char*)nalu.data(), nalu.size());
3956+
vector<uint8_t> rbsp(nalu.size());
3957+
int nb_rbsp = srs_rbsp_remove_emulation_bytes(&b, rbsp);
3958+
3959+
ASSERT_EQ(nb_rbsp, (int)expect.size());
3960+
EXPECT_TRUE(srs_bytes_equals(rbsp.data(), expect.data(), nb_rbsp));
3961+
}
3962+
}
3963+
38903964
VOID TEST(KernelCodecTest, VideoFormat)
38913965
{
38923966
srs_error_t err;
@@ -6346,4 +6420,4 @@ VOID TEST(KernelUtilityTest, Base64Decode)
63466420
HELPER_EXPECT_FAILED(srs_av_base64_decode("YWRtaW46YWRtaW", plaintext));
63476421
EXPECT_STRNE("admin:admin", plaintext.c_str());
63486422
}
6349-
}
6423+
}

trunk/src/utest/srs_utest_kernel.hpp

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <srs_kernel_ts.hpp>
2222
#include <srs_kernel_ps.hpp>
2323
#include <srs_kernel_stream.hpp>
24+
#include <srs_kernel_utility.hpp>
2425

2526
class MockSrsFile
2627
{
@@ -155,5 +156,7 @@ class MockPsHandler : public ISrsPsMessageHandler
155156
MockPsHandler* clear();
156157
};
157158

159+
extern int srs_rbsp_remove_emulation_bytes(SrsBuffer* stream, std::vector<uint8_t>& rbsp);
160+
158161
#endif
159162

0 commit comments

Comments
 (0)