finger out the PES_packet_length is 0

pull/133/head
winlin 11 years ago
parent dc7f2cff86
commit a0ecc5a305

@ -228,52 +228,114 @@ TS
3031个ts包是空包解析有问题
47 41 00 38 07 50 05 09 5A A6 7E 00 00 00 01 E0
00 00 80 C0 0A 31 28 53 60 81 11 28 53 42 F9 00
00 00 01 09 F0 00 00 00 01 67 64 00 28 AC D1 C0
50 05 BB FF 00 2D 00 22 10 00 00 03 00 10 00 00
03 03 08 F1 83 11 E0 00 00 00 01 68 E9 AB 2C 8B
00 00 01 65 88 84 00 42 BF 08 EE 00 02 B2 75 8D
9F C4 24 E5 BD 27 87 F1 E4 09 A0 51 2D 12 FC F5
6E 31 3D C4 0E 3F 51 47 07 BD D2 8C AB 72 1C 2D
D0 FA 2F 7D EF AA FB 17 C1 08 AD 36 8D F1 41 35
E0 20 AE E8 75 66 39 15 78 88 01 E8 2E 4E 8A 8B
F8 04 68 BF EC 82 59 86 DE E1 66 32 37 FA 78 6D
01 EF C0 2C 6B A6 E9 36 44 4B C8 37
Adaptation fields
Adaptation_field_length: 7
discontinuity_indicator: False
random_access_indicator: True
ES_priority_indicator: False
PCR_flag: True
OPCR_flag: False
splicing_point_flag: False
transport_private_data_flag: False
adaptation_field_extension_flag: False
PCR: 50699466000
PES header
stream_id: E0 (video stream 224)
PES_packet_length: 0 (undefined)
PES_scrambling: 0
PES_priority: False
data_alignment: False
copyright: False
original_or_copy: False
PTS_flag: True
DTS_flag: True
ESCR_flag: False
ES_rate_flag: False
DSM_trick_mode_flag: False
additional_copy_info_flag: False
PES_CRC_flag: False
PES_extension_flag: False
PES_header_data_length: 10
PTS: 169128000
DTS: 169124220
Video sequence
Sequence header code not found in this packet
AFD not found in this packet
第3030个包解析有点问题设置条件断点
condition 1 ctx->ts_packet_count == 3030
发现数据如下:
(gdb) x /188xb 0x7fffffffe2f0
0x7fffffffe2f0: 0x47 0x41 0x00 0x38 0x07 0x50 0x05 0x09
0x7fffffffe2f8: 0x5a 0xa6 0x7e 0x00 0x00 0x00 0x01 0xe0
0x7fffffffe300: 0x00 0x00 0x80 0xc0 0x0a 0x31 0x28 0x53
0x7fffffffe308: 0x60 0x81 0x11 0x28 0x53 0x42 0xf9 0x00
0x7fffffffe310: 0x00 0x00 0x01 0x09 0xf0 0x00 0x00 0x00
0x7fffffffe318: 0x01 0x67 0x64 0x00 0x28 0xac 0xd1 0xc0
0x7fffffffe320: 0x50 0x05 0xbb 0xff 0x00 0x2d 0x00 0x22
0x7fffffffe328: 0x10 0x00 0x00 0x03 0x00 0x10 0x00 0x00
0x7fffffffe330: 0x03 0x03 0x08 0xf1 0x83 0x11 0xe0 0x00
0x7fffffffe338: 0x00 0x00 0x01 0x68 0xe9 0xab 0x2c 0x8b
0x7fffffffe340: 0x00 0x00 0x01 0x65 0x88 0x84 0x00 0x42
0x7fffffffe348: 0xbf 0x08 0xee 0x00 0x02 0xb2 0x75 0x8d
0x7fffffffe350: 0x9f 0xc4 0x24 0xe5 0xbd 0x27 0x87 0xf1
0x7fffffffe358: 0xe4 0x09 0xa0 0x51 0x2d 0x12 0xfc 0xf5
0x7fffffffe360: 0x6e 0x31 0x3d 0xc4 0x0e 0x3f 0x51 0x47
0x7fffffffe368: 0x07 0xbd 0xd2 0x8c 0xab 0x72 0x1c 0x2d
0x7fffffffe370: 0xd0 0xfa 0x2f 0x7d 0xef 0xaa 0xfb 0x17
0x7fffffffe378: 0xc1 0x08 0xad 0x36 0x8d 0xf1 0x41 0x35
0x7fffffffe380: 0xe0 0x20 0xae 0xe8 0x75 0x66 0x39 0x15
0x7fffffffe388: 0x78 0x88 0x01 0xe8 0x2e 0x4e 0x8a 0x8b
0x7fffffffe390: 0xf8 0x04 0x68 0xbf 0xec 0x82 0x59 0x86
0x7fffffffe398: 0xde 0xe1 0x66 0x32 0x37 0xfa 0x78 0x6d
0x7fffffffe3a0: 0x01 0xef 0xc0 0x2c 0x6b 0xa6 0xe9 0x36
0x7fffffffe3a8: 0x44 0x4b 0xc8 0x37
header解析如下
(gdb) p *this
$74 = {_vptr.TSHeader = 0x4080b0, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 1 '\001', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypeBoth, continuity_counter = 8 '\b'}
(gdb) p ctx->get(pid)[0]
$76 = {type = TSPidTypeVideo, stream_type = TSStreamTypeVideoH264, pid = 256, continuity_counter = 8 '\b'}
(gdb) p ctx->get_msg(256)[0]
$124 = {_vptr.TSMessage = 0x408290, pid = 256, type = TSPidTypeVideo, stream_type = TSStreamTypeVideoH264,
continuity_counter = 8 '\b', PES_packet_length = 0, stream_id = 224 '\340', packet_start_code_prefix = 1,
packet_header_size = 13, parsed_packet_size = 144, packet_data_size = 144, packet_data = 0x60b300 ""}
特殊的是PES_packet_length为0也就是未知长度。
解析下一个包header为
(gdb) p header[0]
$123 = {_vptr.TSHeader = 0x408170, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 9 '\t'}
这个包的标识是continuity_counter为上一个包的连续。这个包里面是纯粹的数据
(gdb) x /184xb 0x7fffffffe2f4
0x7fffffffe2f4: 0x9c 0xfa 0x8c 0xc9 0x02 0x36 0xc2 0x46
0x7fffffffe2fc: 0x97 0x01 0x31 0x3d 0xfa 0x83 0xc2 0x88
0x7fffffffe304: 0x6b 0xb3 0x1c 0x63 0xcf 0xc6 0xc4 0xa6
0x7fffffffe30c: 0xe2 0xa7 0xb3 0x26 0x62 0x7e 0xb4 0xf0
0x7fffffffe314: 0x17 0x13 0x4c 0xd5 0x1b 0xee 0x80 0x37
0x7fffffffe31c: 0x8f 0x6a 0xad 0x41 0x8f 0x43 0x39 0xbe
0x7fffffffe324: 0x2f 0x51 0xb4 0x0a 0x54 0x62 0xab 0xdc
0x7fffffffe32c: 0x11 0x92 0x92 0x85 0x18 0x92 0x29 0xd5
0x7fffffffe334: 0xb5 0xbc 0x00 0x9e 0x26 0xc3 0xa4 0x04
0x7fffffffe33c: 0xb6 0x97 0x62 0x9b 0x3b 0x3c 0x09 0x6b
0x7fffffffe344: 0x68 0x15 0xe7 0xcc 0x71 0xd9 0xb5 0x02
0x7fffffffe34c: 0x19 0x8a 0x06 0x90 0x22 0xcd 0x3e 0x82
0x7fffffffe354: 0xff 0x48 0x73 0x8b 0x00 0xdc 0xe5 0xdb
0x7fffffffe35c: 0x83 0x13 0x5e 0xe8 0x63 0xe9 0xb6 0xf0
0x7fffffffe364: 0xc5 0x21 0x03 0x57 0xfb 0xb2 0xe1 0x9c
0x7fffffffe36c: 0x71 0x3e 0x36 0xe3 0x05 0xb7 0xf1 0x85
0x7fffffffe374: 0x88 0x0e 0x51 0x52 0xd8 0x3c 0x80 0x1a
0x7fffffffe37c: 0x34 0xff 0xd9 0x5f 0x69 0xb4 0x9d 0xd7
0x7fffffffe384: 0xc2 0x21 0xa8 0x85 0xc8 0xa2 0xdd 0xb8
0x7fffffffe38c: 0xa3 0x43 0x2f 0x7e 0xc8 0xac 0x1b 0x67
0x7fffffffe394: 0x17 0x6c 0x74 0xea 0x97 0xb8 0xa4 0xcf
0x7fffffffe39c: 0x43 0xf3 0x1c 0xad 0x89 0x91 0x28 0x49
0x7fffffffe3a4: 0xf2 0xe8 0x0c 0xbf 0x75 0x8a 0x1c 0xac
后续还有几个包:
$136 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 10 '\n'}
$137 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 11 '\v'}
$138 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 12 '\f'}
$141 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 13 '\r'}
$142 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 14 '\016'}
$143 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 15 '\017'}
然后这个包变了但是还是继续前面的包因为是0xF溢出
$144 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 0 '\000'}
$148 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 0 '\000', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 1 '\001'}
如此循环,可以循环很多次。一直到这个包:
$556 = {_vptr.TSHeader = 0x408250, sync_byte = 71 'G', transport_error_indicator = 0 '\000',
payload_unit_start_indicator = 1 '\001', transport_priority = 0 '\000', pid = 256,
transport_scrambling_control = 0 '\000', adaption_field_control = TSAdaptionTypePayloadOnly,
continuity_counter = 4 '\004'}
其中的payload_unit_start_indicator为1。

@ -13,6 +13,7 @@ g++ -o ts_info ts_info.cpp -g -O0 -ansi
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
@ -55,22 +56,33 @@ Annex A
// Transport Stream packets are 188 bytes in length.
#define TS_PACKET_SIZE 188
// Program Association Table(see Table 2-25).
#define PID_PAT 0x00
// Conditional Access Table (see Table 2-27).
#define PID_CAT 0x01
// Transport Stream Description Table
#define PID_TSDT 0x02
// null packets (see Table 2-3)
#define PID_NULL 0x01FFF
enum TSPidTable
{
// Program Association Table(see Table 2-25).
TSPidTablePAT = 0x00,
// Conditional Access Table (see Table 2-27).
TSPidTableCAT = 0x01,
// Transport Stream Description Table
TSPidTableTSDT = 0x02,
// null packets (see Table 2-3)
TSPidTableNULL = 0x01FFF,
};
/*adaptation_field_control*/
// No adaptation_field, payload only
#define AFC_PAYLOAD_ONLY 0x01
// Adaptation_field only, no payload
#define AFC_ADAPTION_ONLY 0x02
// Adaptation_field followed by payload
#define AFC_BOTH 0x03
/**
* Table 2-5 Adaptation field control values, page 38.
*/
enum TSAdaptionType
{
// Reserved for future use by ISO/IEC
TSAdaptionTypeReserved = 0x00,
// No adaptation_field, payload only
TSAdaptionTypePayloadOnly = 0x01,
// Adaptation_field only, no payload
TSAdaptionTypeAdaptionOnly = 0x02,
// Adaptation_field followed by payload
TSAdaptionTypeBoth = 0x03,
};
#endif
// Table 2-29 Stream type assignments. page 66.
@ -143,10 +155,10 @@ public:
int8_t transport_error_indicator; //1bit
int8_t payload_unit_start_indicator; //1bit
int8_t transport_priority; //1bit
u_int16_t pid; //13bits
TSPidTable pid; //13bits
// 1B
int8_t transport_scrambling_control; //2bits
int8_t adaption_field_control; //2bits
TSAdaptionType adaption_field_control; //2bits
u_int8_t continuity_counter; //4bits
TSHeader();
@ -214,8 +226,8 @@ public:
// left bytes.
char* af_reserved;
// user defined data size.
int __user_size;
// user defined total adaption field size.
int __field_size;
TSAdaptionField();
virtual ~TSAdaptionField();
@ -510,9 +522,13 @@ public:
*/
struct TSPid
{
TSStreamType stream_type;
TSPidType type;
int16_t pid;
// page 66.
TSStreamType stream_type;
// page 36
TSPidTable pid;
// page 36
u_int8_t continuity_counter;
};
/**
@ -523,12 +539,14 @@ class TSMessage
public:
// 2.4.3.2 Transport Stream packet layer. page 36
// the pid of PES packet.
int16_t pid;
TSPidTable pid;
// the type of pid.
TSPidType type;
// the type of stream, codec type.
TSStreamType stream_type;
// page 36
u_int8_t continuity_counter;
// 2.4.3.7 Semantic definition of fields in PES packet. page 49
// PES packet header size plus data size.
@ -569,15 +587,15 @@ public:
int pid_size;
TSPid* pids;
int64_t ts_packet_count;
std::map<int16_t, TSMessage*> msgs;
std::map<TSPidTable, TSMessage*> msgs;
TSContext();
virtual ~TSContext();
bool exists(int16_t pid);
TSPid* get(int16_t pid);
void push(TSStreamType stream_type, TSPidType type, int16_t pid);
bool exists(TSPidTable pid);
TSPid* get(TSPidTable pid);
void push(TSPidTable pid, TSStreamType stream_type, TSPidType type, u_int8_t continuity_counter);
TSMessage* get_msg(int16_t pid);
TSMessage* get_msg(TSPidTable pid);
void detach(TSMessage* msg);
};
@ -592,7 +610,7 @@ TSContext::~TSContext()
{
srs_freepa(pids);
std::map<int16_t, TSMessage*>::iterator it;
std::map<TSPidTable, TSMessage*>::iterator it;
for (it = msgs.begin(); it != msgs.end(); ++it) {
TSMessage* msg = it->second;
srs_freep(msg);
@ -600,7 +618,7 @@ TSContext::~TSContext()
msgs.clear();
}
bool TSContext::exists(int16_t pid)
bool TSContext::exists(TSPidTable pid)
{
for (int i = 0; i < pid_size; i++) {
if (pid == pids[i].pid) {
@ -611,7 +629,7 @@ bool TSContext::exists(int16_t pid)
return false;
}
TSPid* TSContext::get(int16_t pid)
TSPid* TSContext::get(TSPidTable pid)
{
for (int i = 0; i < pid_size; i++) {
if (pid == pids[i].pid) {
@ -622,23 +640,25 @@ TSPid* TSContext::get(int16_t pid)
return NULL;
}
void TSContext::push(TSStreamType stream_type, TSPidType type, int16_t pid)
void TSContext::push(TSPidTable pid, TSStreamType stream_type, TSPidType type, u_int8_t continuity_counter)
{
if (exists(pid)) {
return;
TSPid* p = get(pid);
if (!p) {
p = new TSPid[pid_size + 1];
memcpy(p, pids, sizeof(TSPid) * pid_size);
p[pid_size] = (TSPid){type, stream_type, pid, continuity_counter};
pid_size++;
srs_freepa(pids);
pids = p;
}
TSPid* p = new TSPid[pid_size + 1];
memcpy(p, pids, sizeof(TSPid) * pid_size);
p[pid_size] = (TSPid){stream_type, type, pid};
pid_size++;
srs_freepa(pids);
pids = p;
p->continuity_counter = continuity_counter;
}
TSMessage* TSContext::get_msg(int16_t pid)
TSMessage* TSContext::get_msg(TSPidTable pid)
{
if (msgs[pid] == NULL) {
TSMessage* msg = new TSMessage();
@ -656,7 +676,7 @@ void TSContext::detach(TSMessage* msg)
TSMessage::TSMessage()
{
pid = 0;
pid = TSPidTablePAT;
type = TSPidTypeReserved;
stream_type = TSStreamTypeReserved;
stream_id = 0;
@ -675,11 +695,21 @@ TSMessage::~TSMessage()
void TSMessage::append(u_int8_t*& p, int size)
{
if (size > 0) {
memcpy(packet_data + parsed_packet_size, p, size);
p += size;
parsed_packet_size += size;
if (size <= 0) {
return;
}
// for PES_packet_length is 0, the size is varient.
if (packet_data_size - parsed_packet_size < size) {
int realloc_size = size - (packet_data_size - parsed_packet_size);
packet_data = (char*)realloc(packet_data, packet_data_size + realloc_size);
packet_data_size += realloc_size;
}
memcpy(packet_data + parsed_packet_size, p, size);
p += size;
parsed_packet_size += size;
}
void TSMessage::detach(TSContext* ctx, TSMessage*& pmsg)
@ -729,7 +759,7 @@ TSAdaptionField::TSAdaptionField()
marker_bit2 = 0;
af_ext_reserved = NULL;
af_reserved = NULL;
__user_size = 0;
__field_size = 0;
}
TSAdaptionField::~TSAdaptionField()
@ -741,7 +771,7 @@ TSAdaptionField::~TSAdaptionField()
int TSAdaptionField::get_size()
{
return __user_size;
return __field_size;
}
int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p, TSMessage*& pmsg)
@ -750,7 +780,7 @@ int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int
adaption_field_length = *p++;
u_int8_t* pos_af = p;
__user_size = 1 + adaption_field_length;
__field_size = 1 + adaption_field_length;
if (adaption_field_length <= 0) {
trace("ts+af empty af decoded.");
@ -965,7 +995,7 @@ int TSPayloadPAT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
pp[0] = *p++;
int16_t pid = programs[i] & 0x1FFF;
ctx->push(TSStreamTypeReserved, TSPidTypePMT, pid);
ctx->push((TSPidTable)pid, TSStreamTypeReserved, TSPidTypePMT, pkt->header->continuity_counter);
}
}
@ -1102,12 +1132,12 @@ int TSPayloadPMT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
if (info->stream_type == TSStreamTypeVideoH264) {
// TODO: support more video type.
ctx->push((TSStreamType)info->stream_type, TSPidTypeVideo, info->elementary_PID);
ctx->push((TSPidTable)info->elementary_PID, (TSStreamType)info->stream_type, TSPidTypeVideo, pkt->header->continuity_counter);
trace("ts+pmt add pid: %d, type: H264 video", info->elementary_PID);
} else if (info->stream_type == TSStreamTypeAudioAAC) {
// TODO: support more audio type.
// see aac: 6.2 Audio Data Transport Stream, ADTS
ctx->push((TSStreamType)info->stream_type, TSPidTypeAudio, info->elementary_PID);
ctx->push((TSPidTable)info->elementary_PID, (TSStreamType)info->stream_type, TSPidTypeAudio, pkt->header->continuity_counter);
trace("ts+pmt add pid: %d, type: AAC audio", info->elementary_PID);
} else {
trace("ts+pmt ignore the stream type: %d", info->stream_type);
@ -1215,23 +1245,16 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
{
int ret = 0;
if (!pkt->header->payload_unit_start_indicator) {
TSMessage* msg = ctx->get_msg(pkt->header->pid);
if (msg->packet_start_code_prefix != 0x01) {
trace("ts+pes decode continous packet error, msg is empty.");
return -1;
}
msg->append(p, last - p);
msg->detach(ctx, pmsg);
return ret;
}
char* pp = (char*)&packet_start_code_prefix;
pp[2] = *p++;
pp[1] = *p++;
pp[0] = *p++;
packet_start_code_prefix &= 0xFFFFFF;
if (packet_start_code_prefix != 0x01) {
trace("ts+pes decode unit start packet error, msg is empty.");
return -1;
}
stream_id = *p++;
@ -1413,6 +1436,7 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
msg->type = pid->type;
msg->stream_type = pid->stream_type;
msg->continuity_counter = pid->continuity_counter;
msg->stream_id = stream_id;
msg->packet_start_code_prefix = packet_start_code_prefix;
@ -1426,6 +1450,9 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
msg->PES_packet_length = PES_packet_length;
msg->packet_header_size = p - pos_packet;
msg->packet_data_size = PES_packet_length - msg->packet_header_size;
if (PES_packet_length == 0) {
msg->packet_data_size = last - p - msg->packet_header_size;
}
if (msg->packet_data_size > 0) {
msg->packet_data = new char[msg->packet_data_size];
@ -1433,12 +1460,16 @@ int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t
// PES_packet_data_byte
int size = srs_min(msg->packet_data_size, last - p);
msg->append(p, size);
if (size > 0) {
msg->append(p, size);
}
msg->detach(ctx, pmsg);
if (PES_packet_length > 0) {
msg->detach(ctx, pmsg);
}
trace("ts+pes stream_id: %d size: %d pts: %"PRId64" dts: %"PRId64" packet_size: %d parsed_size: %d",
stream_id, PES_packet_length, pts, dts, msg->packet_data_size, msg->parsed_packet_size);
trace("ts+pes stream_id: %d size: %d pts: %"PRId64" dts: %"PRId64" total: %d header: %d packet_size: %d parsed_size: %d",
stream_id, PES_packet_length, pts, dts, msg->PES_packet_length, msg->packet_header_size, msg->packet_data_size, msg->parsed_packet_size);
} else if (stream_id == PES_program_stream_map
|| stream_id == PES_private_stream_2
|| stream_id == PES_ECM_stream
@ -1496,7 +1527,7 @@ int TSPayload::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* l
{
int ret = 0;
if (pkt->header->pid == PID_PAT) {
if (pkt->header->pid == TSPidTablePAT) {
read_pointer_field(pkt, p);
type = TSPidTypePAT;
@ -1550,7 +1581,7 @@ int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*&
return ret;
}
if (header->adaption_field_control == AFC_ADAPTION_ONLY || header->adaption_field_control == AFC_BOTH) {
if (header->adaption_field_control == TSAdaptionTypeAdaptionOnly || header->adaption_field_control == TSAdaptionTypeBoth) {
if ((ret = adaption_field->demux(ctx, this, start, last, p, pmsg)) != 0) {
trace("ts+header af(adaption field) decode error. ret=%d", ret);
return ret;
@ -1561,7 +1592,36 @@ int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*&
// calc the user defined data size for payload.
payload->size = TS_PACKET_SIZE - header->get_size() - adaption_field->get_size();
if (header->adaption_field_control == AFC_PAYLOAD_ONLY || header->adaption_field_control == AFC_BOTH) {
if (header->adaption_field_control == TSAdaptionTypePayloadOnly || header->adaption_field_control == TSAdaptionTypeBoth) {
TSMessage* msg = ctx->get_msg(header->pid);
// flush previous PES_packet_length(0) packets.
if (msg->packet_start_code_prefix == 0x01
&& header->payload_unit_start_indicator == 1
&& msg->PES_packet_length == 0
) {
msg->detach(ctx, pmsg);
// reparse current message
p = start;
return ret;
}
// parse continous packet.
if (!header->payload_unit_start_indicator) {
if (msg->packet_start_code_prefix != 0x01) {
trace("ts+pes decode continous packet error, msg is empty.");
return -1;
}
msg->append(p, last - p);
// for PES_packet_length is 0, donot attach it.
if (msg->PES_packet_length > 0) {
msg->detach(ctx, pmsg);
}
return ret;
}
// parse new packet.
if ((ret = payload->demux(ctx, this, start, last, p, pmsg)) != 0) {
trace("ts+header payload decode error. ret=%d", ret);
return ret;
@ -1588,9 +1648,9 @@ TSHeader::TSHeader()
transport_error_indicator = 0;
payload_unit_start_indicator = 0;
transport_priority = 0;
pid = 0;
pid = TSPidTablePAT;
transport_scrambling_control = 0;
adaption_field_control = 0;
adaption_field_control = TSAdaptionTypeReserved;
continuity_counter = 0;
}
@ -1614,23 +1674,27 @@ int TSHeader::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* la
return -1;
}
pid = 0;
((char*)&pid)[1] = *p++;
((char*)&pid)[0] = *p++;
int16_t _pid = 0;
char* pp = (char*)&_pid;
pp[1] = *p++;
pp[0] = *p++;
transport_error_indicator = (pid >> 15) & 0x01;
payload_unit_start_indicator = (pid >> 14) & 0x01;
transport_priority = (pid >> 13) & 0x01;
pid &= 0x1FFF;
transport_error_indicator = (_pid >> 15) & 0x01;
payload_unit_start_indicator = (_pid >> 14) & 0x01;
transport_priority = (_pid >> 13) & 0x01;
_pid &= 0x1FFF;
ctx->push(TSStreamTypeReserved, TSPidTypePAT, pid);
pid = (TSPidTable)_pid;
continuity_counter = *p++;
transport_scrambling_control = (continuity_counter >> 6) & 0x03;
adaption_field_control = (continuity_counter >> 4) & 0x03;
int8_t _adaption_field_control = (continuity_counter >> 4) & 0x03;
adaption_field_control = (TSAdaptionType)_adaption_field_control;
continuity_counter &= 0x0F;
ctx->push(pid, TSStreamTypeReserved, TSPidTypePAT, continuity_counter);
trace("ts+header sync: %#x error: %d unit_start: %d priotiry: %d pid: %d scrambling: %d adaption: %d counter: %d",
sync_byte, transport_error_indicator, payload_unit_start_indicator, transport_priority, pid,
transport_scrambling_control, adaption_field_control, continuity_counter);
@ -1934,24 +1998,27 @@ int main(int /*argc*/, char** /*argv*/)
u_int8_t* start = ts_packet;
u_int8_t* last = ts_packet + TS_PACKET_SIZE;
TSPacket pkt;
TSMessage* msg = NULL;
if ((ret = pkt.demux(&ctx, start, last, p, msg)) != 0) {
trace("demuxer+read decode ts packet error. ret=%d", ret);
return ret;
}
offset += nread;
if (!msg) {
continue;
}
if ((ret = consume(msg)) != 0) {
trace("demuxer+consume parse and consume message failed. ret=%d", ret);
break;
// maybe need to parse multiple times for the PES_packet_length(0) packets.
while (p == start) {
TSPacket pkt;
TSMessage* msg = NULL;
if ((ret = pkt.demux(&ctx, start, last, p, msg)) != 0) {
trace("demuxer+read decode ts packet error. ret=%d", ret);
return ret;
}
offset += nread;
if (!msg) {
continue;
}
if ((ret = consume(msg)) != 0) {
trace("demuxer+consume parse and consume message failed. ret=%d", ret);
break;
}
srs_freep(msg);
}
srs_freep(msg);
}
close(fd);

Loading…
Cancel
Save