1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-02-15 04:42:04 +00:00

SRT: Solve mpegts demux assert bug (#2670)

* solve mpegts demux bug

* remove assert

* add error log in mpegts demux

* sovle compile problem

Co-authored-by: shiwei <shiwei05@kuaishou.com>
This commit is contained in:
Alex.CR 2021-10-18 15:03:47 +08:00 committed by GitHub
parent 596dd8c523
commit 60c8724879
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -5,7 +5,7 @@
// //
#include "ts_demux.hpp" #include "ts_demux.hpp"
#include <assert.h> #include "srt_log.hpp"
#include <string.h> #include <string.h>
ts_demux::ts_demux():_data_total(0) ts_demux::ts_demux():_data_total(0)
@ -41,11 +41,6 @@ int ts_demux::decode_unit(unsigned char* data_p, std::string key_path, TS_DATA_C
pos++; pos++;
npos = pos; npos = pos;
//printf("ts header(0x%02x) payload_unit_start_indicator:%d, pid:%d, adaptation_field_control:%d, pos:%d\r\n",
// ts_header_info._sync_byte,
// ts_header_info._payload_unit_start_indicator, ts_header_info._PID,
// ts_header_info._adaptation_field_control, pos);
adaptation_field* field_p = &(ts_header_info._adaptation_field_info); adaptation_field* field_p = &(ts_header_info._adaptation_field_info);
// adaptation field // adaptation field
// 0x01 No adaptation_field, payload only // 0x01 No adaptation_field, payload only
@ -153,8 +148,16 @@ int ts_demux::decode_unit(unsigned char* data_p, std::string key_path, TS_DATA_C
_pat._section_number = data_p[pos]; _pat._section_number = data_p[pos];
pos++; pos++;
_pat._last_section_number = data_p[pos]; _pat._last_section_number = data_p[pos];
assert(_pat._table_id == 0x00);
assert((188 - npos) > (_pat._section_length+3)); // PAT = section_length + 3 if (_pat._table_id != 0x00) {
srt_log_error("pat table id(0x%02x) error, it must be 0x00", _pat._table_id);
return -1;
}
// PAT = section_length + 3
if((188 - npos) <= (_pat._section_length + 3)) {
srt_log_error("pat _section_length(%d) error, the left len:%d", _pat._section_length, (188 - npos));
return -1;
}
pos++; pos++;
_pat._pid_vec.clear(); _pat._pid_vec.clear();
for (;pos+4 <= _pat._section_length-5-4+9 + npos;) { // 4:CRC, 5:follow section_length item rpos + 4(following unit length) section_length + 9(above field and unit_start_first_byte ) for (;pos+4 <= _pat._section_length-5-4+9 + npos;) { // 4:CRC, 5:follow section_length item rpos + 4(following unit length) section_length + 9(above field and unit_start_first_byte )
@ -167,13 +170,11 @@ int ts_demux::decode_unit(unsigned char* data_p, std::string key_path, TS_DATA_C
if (pid_info._program_number == 0) { if (pid_info._program_number == 0) {
// // network_PID 13 uimsbf // // network_PID 13 uimsbf
pid_info._network_id = (data_p[pos]<<8|data_p[pos+1])&0x1FFF; pid_info._network_id = (data_p[pos]<<8|data_p[pos+1])&0x1FFF;
//printf("#### network id:%d.\r\n", pid_info._network_id);
pos += 2; pos += 2;
} }
else { else {
// // program_map_PID 13 uimsbf // // program_map_PID 13 uimsbf
pid_info._pid = (data_p[pos]<<8|data_p[pos+1])&0x1FFF; pid_info._pid = (data_p[pos]<<8|data_p[pos+1])&0x1FFF;
//printf("#### pmt id:%d.\r\n", pid_info._pid);
pos += 2; pos += 2;
} }
_pat._pid_vec.push_back(pid_info); _pat._pid_vec.push_back(pid_info);
@ -217,7 +218,12 @@ int ts_demux::decode_unit(unsigned char* data_p, std::string key_path, TS_DATA_C
//reserved 4 bslbf //reserved 4 bslbf
_pmt._program_info_length = ((data_p[pos]<<8)|data_p[pos+1])&0x0FFF;//program_info_length 12 uimsbf _pmt._program_info_length = ((data_p[pos]<<8)|data_p[pos+1])&0x0FFF;//program_info_length 12 uimsbf
pos += 2; pos += 2;
assert(_pmt._table_id==0x02); // 0x02, // TS_program_map_section
//0x02, // TS_program_map_section
if (_pmt._table_id != 0x02) {
srt_log_error("pmt tableid(0x%02x) error, it must be 0x02", _pmt._table_id)
return -1;
}
memcpy(_pmt._dscr, data_p+pos, _pmt._program_info_length); memcpy(_pmt._dscr, data_p+pos, _pmt._program_info_length);
// for (i = 0; i < N; i++) { // for (i = 0; i < N; i++) {
// descriptor() // descriptor()
@ -250,7 +256,6 @@ int ts_demux::decode_unit(unsigned char* data_p, std::string key_path, TS_DATA_C
pos += descriptor_length; pos += descriptor_length;
} }
// save program_number(stream num) elementary_PID(PES PID) stream_type(stream codec) // save program_number(stream num) elementary_PID(PES PID) stream_type(stream codec)
//printf("pmt pid:%d, streamtype:%d, pos:%d\r\n", pid_info._elementary_PID, pid_info._stream_type, pos);
_pmt._stream_pid_vec.push_back(pid_info); _pmt._stream_pid_vec.push_back(pid_info);
_pmt._pid2steamtype.insert(std::make_pair((unsigned short)pid_info._elementary_PID, pid_info._stream_type)); _pmt._pid2steamtype.insert(std::make_pair((unsigned short)pid_info._elementary_PID, pid_info._stream_type));
} }
@ -274,8 +279,8 @@ int ts_demux::decode_unit(unsigned char* data_p, std::string key_path, TS_DATA_C
on_callback(callback, _last_pid, key_path, _last_dts, _last_pts); on_callback(callback, _last_pid, key_path, _last_dts, _last_pts);
int ret = pes_parse(data_p+npos, npos, &ret_data_p, ret_size, dts, pts); int ret = pes_parse(data_p+npos, npos, &ret_data_p, ret_size, dts, pts);
assert(ret <= 188);
if (ret > 188) { if (ret > 188) {
srt_log_error("pes length(%d) error", ret);
return -1; return -1;
} }
@ -291,9 +296,6 @@ int ts_demux::decode_unit(unsigned char* data_p, std::string key_path, TS_DATA_C
} }
} }
} }
//if(!isFound){
// printf("unknown PID = %X \n", ts_header_info._PID);
//}
} }
} }
@ -380,13 +382,15 @@ int ts_demux::pes_parse(unsigned char* p, size_t npos,
pos += 3; pos += 3;
int stream_id = p[pos]; //stream_id 8 uimsbf int stream_id = p[pos]; //stream_id 8 uimsbf
pos++; pos++;
//printf("pes parse %02x %02x.\r\n", p[pos], p[pos+1]);
int PES_packet_length = ((unsigned int)p[pos]<<8)|p[pos+1]; //PES_packet_length 16 uimsbf int PES_packet_length = ((unsigned int)p[pos]<<8)|p[pos+1]; //PES_packet_length 16 uimsbf
(void)PES_packet_length; (void)PES_packet_length;
pos += 2; pos += 2;
//printf("pes parse packet_start_code_prefix:%d, npos:%lu, PES_packet_length:%d, stream_id:%d.\r\n",
// packet_start_code_prefix, npos, PES_packet_length, stream_id); if (0x00000001 != packet_start_code_prefix) {
assert(0x00000001 == packet_start_code_prefix); srt_log_error("pes packet start code prefix(%06x) error, it must be 0x00 00 01", packet_start_code_prefix);
return 255;
}
if (stream_id != 188//program_stream_map 1011 1100 if (stream_id != 188//program_stream_map 1011 1100
&& stream_id != 190//padding_stream 1011 1110 && stream_id != 190//padding_stream 1011 1110
&& stream_id != 191//private_stream_2 1011 1111 && stream_id != 191//private_stream_2 1011 1111
@ -397,6 +401,10 @@ int ts_demux::pes_parse(unsigned char* p, size_t npos,
&& stream_id != 248//ITU-T Rec. H.222.1 type E stream 1111 1000 && stream_id != 248//ITU-T Rec. H.222.1 type E stream 1111 1000
) )
{ {
if (0x80 != (p[pos] & 0xc0)) {
srt_log_error("the first 2 bits:0x%02x error, it must be 0x80.", (p[pos] & 0xc0));
return 255;
}
//skip 2bits//'10' 2 bslbf //skip 2bits//'10' 2 bslbf
int PES_scrambling_control = (p[pos]&30)>>4; //PES_scrambling_control 2 bslbf int PES_scrambling_control = (p[pos]&30)>>4; //PES_scrambling_control 2 bslbf
(void)PES_scrambling_control; (void)PES_scrambling_control;
@ -563,9 +571,6 @@ int ts_demux::pes_parse(unsigned char* p, size_t npos,
// } // }
*ret_pp = p+pos; *ret_pp = p+pos;
ret_size = 188-(npos+pos); ret_size = 188-(npos+pos);
//printf("pes parse body size:%lu, data:0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x, dts:%lu(%lu), pts:%lu(%lu)\r\n",
// ret_size, p[pos], p[pos+1], p[pos+2], p[pos+3], p[pos+4], p[pos+5],
// dts, dts/90, pts, pts/90);
} }
else if ( stream_id == 188//program_stream_map 1011 1100 BC else if ( stream_id == 188//program_stream_map 1011 1100 BC
|| stream_id == 191//private_stream_2 1011 1111 BF || stream_id == 191//private_stream_2 1011 1111 BF