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

update the ts_info parse the PMT and PES header

This commit is contained in:
winlin 2013-11-18 23:49:18 +08:00
parent 89332789d1
commit a47a53f271
3 changed files with 1077 additions and 648 deletions

View file

@ -1,5 +1,5 @@
# the listen ports, split by space. # the listen ports, split by space.
listen 1937; listen 1935;
# the default chunk size is 128, max is 65536, # the default chunk size is 128, max is 65536,
# some client does not support chunk size change, # some client does not support chunk size change,
# however, most clients supports it and it can improve # however, most clients supports it and it can improve

View file

@ -10,6 +10,8 @@ g++ -o ts_info ts_info.cpp -g -O0 -ansi
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#include <vector>
#define trace(msg, ...) printf(msg"\n", ##__VA_ARGS__); #define trace(msg, ...) printf(msg"\n", ##__VA_ARGS__);
#define srs_freep(p) delete p; p = NULL #define srs_freep(p) delete p; p = NULL
#define srs_freepa(p) delete[] p; p = NULL #define srs_freepa(p) delete[] p; p = NULL
@ -63,11 +65,65 @@ Annex A
#define AFC_BOTH 0x03 #define AFC_BOTH 0x03
#endif #endif
struct TSPacket // Table 2-29 Stream type assignments. page 66.
enum TSStreamType
{ {
// 4B ts packet header. /*defined by ffmpeg*/
struct Header TSStreamTypeVideoMpeg1 = 0x01,
{ TSStreamTypeVideoMpeg2 = 0x02,
TSStreamTypeAudioMpeg1 = 0x03,
TSStreamTypeAudioMpeg2 = 0x04,
TSStreamTypePrivateSection = 0x05,
TSStreamTypePrivateData = 0x06,
TSStreamTypeAudioAAC = 0x0f,
TSStreamTypeVideoMpeg4 = 0x10,
TSStreamTypeVideoH264 = 0x1b,
TSStreamTypeAudioAC3 = 0x81,
TSStreamTypeAudioDTS = 0x8a,
};
/**
* the actually parsed type.
*/
enum TSPidType
{
TSPidTypeReserved = 0, // TSPidTypeReserved, nothing parsed, used reserved.
TSPidTypePAT, // Program associtate table
TSPidTypePMT, // Program map table.
TSPidTypeVideo,
TSPidTypeAudio,
};
// forward declares.
class TSHeader;
class TSAdaptionField;
class TSPayload;
class TSPayloadReserved;
class TSPayloadPAT;
class TSPayloadPMT;
class TSPayloadPES;
class TSContext;
// TSPacket declares.
class TSPacket
{
public:
TSHeader* header;
TSAdaptionField* adaption_field;
TSPayload* payload;
TSPacket();
virtual ~TSPacket();
int demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
int finish();
};
// TSHeader declares.
class TSHeader
{
public:
// 1B // 1B
int8_t sync_byte; //8bits int8_t sync_byte; //8bits
// 2B // 2B
@ -80,48 +136,16 @@ struct TSPacket
int8_t adaption_field_control; //2bits int8_t adaption_field_control; //2bits
u_int8_t continuity_counter; //4bits u_int8_t continuity_counter; //4bits
int get_size() TSHeader();
{ virtual ~TSHeader();
return 4; int get_size();
} int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
};
int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p) // variant ts packet adation field. page 40.
{ class TSAdaptionField
int ret = 0; {
public:
// ts packet header.
sync_byte = *p++;
if (sync_byte != 0x47) {
trace("ts+sync_bytes invalid sync_bytes: %#x, expect is 0x47", sync_byte);
return -1;
}
pid = 0;
((char*)&pid)[1] = *p++;
((char*)&pid)[0] = *p++;
transport_error_indicator = (pid >> 15) & 0x01;
payload_unit_start_indicator = (pid >> 14) & 0x01;
transport_priority = (pid >> 13) & 0x01;
pid &= 0x1FFF;
continuity_counter = *p++;
transport_scrambling_control = (continuity_counter >> 6) & 0x03;
adaption_field_control = (continuity_counter >> 4) & 0x03;
continuity_counter &= 0x0F;
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);
return ret;
}
} *header;
// variant ts packet adation field.
struct AdaptionField
{
// 1B // 1B
u_int8_t adaption_field_length; //8bits u_int8_t adaption_field_length; //8bits
// 1B // 1B
@ -180,29 +204,288 @@ struct TSPacket
// user defined data size. // user defined data size.
int __user_size; int __user_size;
AdaptionField() TSAdaptionField();
{ virtual ~TSAdaptionField();
int get_size();
int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
};
// variant ts packet payload.
// PES packet or PSI table.
// TSPayloadPAT: page 61.
class TSPayload
{
public:
/**
* the size of payload(payload plush the 1byte pointer_field).
*/
int size;
int pointer_field_size;
TSPidType type;
/**
* 2.4.4.2 Semantics definition of fields in pointer syntax
*/
u_int8_t pointer_field;
TSPayloadReserved* reserved;
TSPayloadPAT* pat;
TSPayloadPMT* pmt;
TSPayloadPES* pes;
/**
* 2.4.3.6 PES packet. page 49.
*/
TSPayload();
virtual ~TSPayload();;
void read_pointer_field(TSPacket* pkt, u_int8_t*& p);
int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
};
/**
* 2.4.4.3 Program association Table. page 61.
*/
class TSPayloadPAT
{
public:
// 1B
u_int8_t table_id; //8bits
// 2B
int8_t section_syntax_indicator; //1bit
int8_t const0_value; //1bit
// 2bits reserved.
u_int16_t section_length; //12bits
// 2B
u_int16_t transport_stream_id; //16bits
// 1B
// 2bits reerverd.
int8_t version_number; //5bits
int8_t current_next_indicator; //1bit
// 1B
u_int8_t section_number; //8bits
// 1B
u_int8_t last_section_number; //8bits
// multiple 4B program data.
// program_number 16bits
// reserved 2bits
// 13bits data: 0x1FFF
// if program_number program_map_PID 13bits
// else network_PID 13bytes.
int program_size;
int32_t* programs; //32bits
// 4B
int32_t CRC_32; //32bits
TSPayloadPAT();
virtual ~TSPayloadPAT();
int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
};
class TSPMTESInfo
{
public:
// 1B
u_int8_t stream_type; //8bits
// 2B
// 3bits reserved
int16_t elementary_PID; //13bits
// 2B
// 4bits reserved
int16_t ES_info_length; //12bits
char* ES_info; //[ES_info_length] bytes.
TSPMTESInfo();
virtual ~TSPMTESInfo();
};
/**
* 2.4.4.8 Program Map Table. page 64.
*/
class TSPayloadPMT
{
public:
// 1B
u_int8_t table_id; //8bits
// 2B
int8_t section_syntax_indicator; //1bit
int8_t const0_value; //1bit
// 2bits reserved.
u_int16_t section_length; //12bits
// 2B
u_int16_t program_number; //16bits
// 1B
// 2bits reerverd.
int8_t version_number; //5bits
int8_t current_next_indicator; //1bit
// 1B
u_int8_t section_number; //8bits
// 1B
u_int8_t last_section_number; //8bits
// 2B
// 2bits reserved.
int16_t PCR_PID; //16bits
// 2B
// 4bits reserved.
int16_t program_info_length; //12bits
char* program_info_desc; //[program_info_length]bytes
// array of TSPMTESInfo.
std::vector<TSPMTESInfo*> ES_info;
// 4B
int32_t CRC_32; //32bits
TSPayloadPMT();
virtual ~TSPayloadPMT();
int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
};
/**
* 2.4.3.7 Semantic definition of fields in PES packet. page 49.
*/
class TSPayloadPES
{
public:
// 3B
int32_t packet_start_code_prefix; //24bits
// 1B
u_int8_t stream_id; //8bits
// 2B
u_int16_t PES_packet_length; //16bits
TSPayloadPES();
virtual ~TSPayloadPES();
int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
};
class TSPayloadReserved
{
public:
int size;
char* bytes;
TSPayloadReserved();
virtual ~TSPayloadReserved();
int demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p);
};
struct TSPid
{
TSPidType type;
int16_t pid;
};
// ts context
class TSContext
{
public:
/**
* consumed pids.
*/
int pid_size;
TSPid* pids;
TSContext();
virtual ~TSContext();
bool exists(int16_t pid);
TSPid* get(int16_t pid);
void push(TSPidType type, int16_t pid);
};
TSContext::TSContext()
{
pid_size = 0;
pids = NULL;
}
TSContext::~TSContext()
{
srs_freepa(pids);
}
bool TSContext::exists(int16_t pid)
{
for (int i = 0; i < pid_size; i++) {
if (pid == pids[i].pid) {
return true;
}
}
return false;
}
TSPid* TSContext::get(int16_t pid)
{
for (int i = 0; i < pid_size; i++) {
if (pid == pids[i].pid) {
return &pids[i];
}
}
return NULL;
}
void TSContext::push(TSPidType type, int16_t pid)
{
if (exists(pid)) {
return;
}
TSPid* p = new TSPid[pid_size + 1];
memcpy(p, pids, sizeof(TSPid) * pid_size);
p[pid_size] = (TSPid){type, pid};
pid_size++;
srs_freepa(pids);
pids = p;
}
TSAdaptionField::TSAdaptionField()
{
transport_private_data = NULL; transport_private_data = NULL;
af_ext_reserved = NULL; af_ext_reserved = NULL;
af_reserved = NULL; af_reserved = NULL;
__user_size = 0; __user_size = 0;
} }
virtual ~AdaptionField() TSAdaptionField::~TSAdaptionField()
{ {
srs_freepa(transport_private_data); srs_freepa(transport_private_data);
srs_freepa(af_ext_reserved); srs_freepa(af_ext_reserved);
srs_freepa(af_reserved); srs_freepa(af_reserved);
} }
int get_size() int TSAdaptionField::get_size()
{ {
return __user_size; return __user_size;
} }
int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p) int TSAdaptionField::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
{ {
int ret = 0; int ret = 0;
adaption_field_length = *p++; adaption_field_length = *p++;
@ -333,58 +616,24 @@ struct TSPacket
} }
return ret; return ret;
} }
} *adaption_field;
// variant ts packet payload. TSPayloadReserved::TSPayloadReserved()
// PES packet or PSI table. {
struct Payload
{
/**
* the size of payload(payload plush the 1byte pointer_field).
*/
int size;
int pointer_field_size;
/**
* the actually parsed type.
*/
enum Type
{
TypeUnknown=-1,
TypeReserved, // TypeReserved, nothing parsed, used reserved.
TypePAT, //TypePAT, PAT parsed, in pat field.
} type;
/**
* 2.4.4.2 Semantics definition of fields in pointer syntax
*/
u_int8_t pointer_field;
/**
* if not parsed, store data in this field.
*/
struct Reserved
{
int size;
char* bytes;
Reserved()
{
size = 0; size = 0;
bytes = NULL; bytes = NULL;
} }
virtual ~Reserved() TSPayloadReserved::~TSPayloadReserved()
{ {
srs_freepa(bytes); srs_freepa(bytes);
} }
int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p) int TSPayloadReserved::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
{ {
int ret = 0; int ret = 0;
size = ppkt->payload->size - ppkt->payload->pointer_field_size; size = pkt->payload->size - pkt->payload->pointer_field_size;
// not parsed bytes. // not parsed bytes.
if (size > 0) { if (size > 0) {
@ -394,66 +643,20 @@ struct TSPacket
} }
return ret; return ret;
} }
} *reserved;
/** TSPayloadPAT::TSPayloadPAT()
* 2.4.4.3 Program association Table. page 61. {
*/
struct PAT {
// 1B
u_int8_t table_id; //8bits
// 2B
int8_t section_syntax_indicator; //1bit
int8_t const0_value; //1bit
// 2bits reserved.
u_int16_t section_length; //12bits
// 2B
u_int16_t transport_stream_id; //16bits
// 1B
// 2bits reerverd.
int8_t version_number; //5bits
int8_t current_next_indicator; //1bit
// 1B
u_int8_t section_number; //8bits
// 1B
u_int8_t last_section_number; //8bits
// multiple 4B program data.
// program_number 16bits
// reserved 2bits
// 13bits data: 0x1FFF
// if program_number program_map_PID 13bits
// else network_PID 13bytes.
int program_size;
int32_t* programs; //32bits
// 4B
int32_t CRC_32; //32bits
PAT()
{
programs = NULL; programs = NULL;
} }
virtual ~PAT() TSPayloadPAT::~TSPayloadPAT()
{ {
srs_freepa(programs); srs_freepa(programs);
} }
int get_program(int index) int TSPayloadPAT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
{ {
srs_assert(index < program_size);
return programs[index] & 0x1FFF;
}
int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
{
int ret = 0; int ret = 0;
table_id = *p++; table_id = *p++;
@ -489,6 +692,9 @@ struct TSPacket
pp[2] = *p++; pp[2] = *p++;
pp[1] = *p++; pp[1] = *p++;
pp[0] = *p++; pp[0] = *p++;
int16_t pid = programs[i] & 0x1FFF;
ctx->push(TSPidTypePMT, pid);
} }
} }
@ -499,79 +705,251 @@ struct TSPacket
pp[0] = *p++; pp[0] = *p++;
return ret; return ret;
}
TSPMTESInfo::TSPMTESInfo()
{
ES_info_length = 0;
ES_info = NULL;
}
TSPMTESInfo::~TSPMTESInfo()
{
srs_freepa(ES_info);
}
TSPayloadPMT::TSPayloadPMT()
{
program_info_length = 0;
program_info_desc = NULL;
}
TSPayloadPMT::~TSPayloadPMT()
{
srs_freepa(program_info_desc);
for (std::vector<TSPMTESInfo*>::iterator it = ES_info.begin(); it != ES_info.end(); ++it) {
TSPMTESInfo* info = *it;
srs_freep(info);
} }
} *pat; ES_info.clear();
}
/** int TSPayloadPMT::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
* 2.4.3.6 PES packet. page 49. {
*/ int ret = 0;
Payload() table_id = *p++;
{
char* pp = (char*)&section_length;
pp[1] = *p++;
pp[0] = *p++;
u_int8_t* pos = p;
section_syntax_indicator = (section_length >> 15) & 0x01;
const0_value = (section_length >> 14) & 0x01;
section_length &= 0x0FFF;
pp = (char*)&program_number;
pp[1] = *p++;
pp[0] = *p++;
current_next_indicator = *p++;
version_number = (current_next_indicator >> 1) & 0x1F;
current_next_indicator &= 0x01;
section_number = *p++;
last_section_number = *p++;
pp = (char*)&PCR_PID;
pp[1] = *p++;
pp[0] = *p++;
PCR_PID &= 0x1FFF;
pp = (char*)&program_info_length;
pp[1] = *p++;
pp[0] = *p++;
program_info_length &= 0xFFF;
if (program_info_length > 0) {
program_info_desc = new char[program_info_length];
memcpy(program_info_desc, p, program_info_length);
p += program_info_length;
}
// [section_length] - 4(CRC) - 9B - [program_info_length]
int ES_bytes = section_length - 4 - 9 - program_info_length;
while (ES_bytes > 0) {
TSPMTESInfo* info = new TSPMTESInfo();
info->stream_type = *p++;
ES_bytes--;
pp = (char*)&info->elementary_PID;
pp[1] = *p++;
pp[0] = *p++;
ES_bytes -= 2;
info->elementary_PID &= 0x1FFF;
pp = (char*)&info->ES_info_length;
pp[1] = *p++;
pp[0] = *p++;
ES_bytes -= 2;
info->ES_info_length &= 0x0FFF;
if (info->ES_info_length > 0) {
info->ES_info = new char[info->ES_info_length];
memcpy(info->ES_info, p, info->ES_info_length);
p += info->ES_info_length;
ES_bytes -= info->ES_info_length;
}
ES_info.push_back(info);
// TODO: support more video type.
if (info->stream_type == TSStreamTypeVideoH264) {
ctx->push(TSPidTypeVideo, info->elementary_PID);
}
// TODO: support more audio type.
if (info->stream_type == TSStreamTypeAudioAAC) {
ctx->push(TSPidTypeAudio, info->elementary_PID);
}
}
pp = (char*)&CRC_32;
pp[3] = *p++;
pp[2] = *p++;
pp[1] = *p++;
pp[0] = *p++;
return ret;
}
TSPayloadPES::TSPayloadPES()
{
}
TSPayloadPES::~TSPayloadPES()
{
}
int TSPayloadPES::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
{
int ret = 0;
char* pp = (char*)&packet_start_code_prefix;
pp[2] = *p++;
pp[1] = *p++;
pp[0] = *p++;
packet_start_code_prefix &= 0xFFFFFF;
stream_id = *p++;
pp = (char*)&PES_packet_length;
pp[1] = *p++;
pp[0] = *p++;
return ret;
}
/**
* 2.4.3.6 PES packet. page 49.
*/
TSPayload::TSPayload()
{
size = 0; size = 0;
pointer_field_size = 0; pointer_field_size = 0;
type = TypeUnknown; type = TSPidTypeReserved;
reserved = NULL; reserved = NULL;
pat = NULL; pat = NULL;
} pmt = NULL;
pes = NULL;
}
virtual ~Payload() TSPayload::~TSPayload()
{ {
srs_freep(reserved); srs_freep(reserved);
srs_freep(pat); srs_freep(pat);
} srs_freep(pmt);
srs_freep(pes);
}
int demux(TSPacket* ppkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p) void TSPayload::read_pointer_field(TSPacket* pkt, u_int8_t*& p)
{ {
int ret = 0; if (pkt->header->payload_unit_start_indicator) {
if (ppkt->header->payload_unit_start_indicator) {
pointer_field = *p++; pointer_field = *p++;
pointer_field_size = 1; pointer_field_size = 1;
} }
}
if (ppkt->header->pid == PID_PAT) { int TSPayload::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
type = TypePAT; {
pat = new PAT(); int ret = 0;
return pat->demux(ppkt, start, last, p);
if (pkt->header->pid == PID_PAT) {
read_pointer_field(pkt, p);
type = TSPidTypePAT;
pat = new TSPayloadPAT();
return pat->demux(ctx, pkt, start, last, p);
}
TSPid* pid = ctx->get(pkt->header->pid);
if (pid && pid->type == TSPidTypePMT) {
read_pointer_field(pkt, p);
type = pid->type;
pmt = new TSPayloadPMT();
return pmt->demux(ctx, pkt, start, last, p);
}
if (pid && (pid->type == TSPidTypeVideo || pid->type == TSPidTypeAudio)) {
type = pid->type;
pes = new TSPayloadPES();
return pes->demux(ctx, pkt, start, last, p);
} }
// not parsed bytes. // not parsed bytes.
type = TypeReserved; type = TSPidTypeReserved;
reserved = new Reserved(); reserved = new TSPayloadReserved();
if ((ret = reserved->demux(ppkt, start, last, p)) != 0) { if ((ret = reserved->demux(ctx, pkt, start, last, p)) != 0) {
return ret; return ret;
} }
return ret; return ret;
} }
} *payload;
TSPacket() TSPacket::TSPacket()
{ {
header = new Header(); header = new TSHeader();
adaption_field = new AdaptionField(); adaption_field = new TSAdaptionField();
payload = new Payload(); payload = new TSPayload();
} }
virtual ~TSPacket() TSPacket::~TSPacket()
{ {
srs_freep(header); srs_freep(header);
srs_freep(adaption_field); srs_freep(adaption_field);
srs_freep(payload); srs_freep(payload);
} }
int demux(u_int8_t* start, u_int8_t* last, u_int8_t*& p) int TSPacket::demux(TSContext* ctx, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
{ {
int ret = 0; int ret = 0;
if ((ret = header->demux(this, start, last, p)) != 0) { if ((ret = header->demux(ctx, this, start, last, p)) != 0) {
return ret; return ret;
} }
if (header->adaption_field_control == AFC_ADAPTION_ONLY || header->adaption_field_control == AFC_BOTH) { if (header->adaption_field_control == AFC_ADAPTION_ONLY || header->adaption_field_control == AFC_BOTH) {
if ((ret = adaption_field->demux(this, start, last, p)) != 0) { if ((ret = adaption_field->demux(ctx, this, start, last, p)) != 0) {
trace("ts+header af(adaption field) decode error. ret=%d", ret); trace("ts+header af(adaption field) decode error. ret=%d", ret);
return ret; return ret;
} }
@ -582,7 +960,7 @@ struct TSPacket
payload->size = TS_PACKET_SIZE - header->get_size() - adaption_field->get_size(); 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 == AFC_PAYLOAD_ONLY || header->adaption_field_control == AFC_BOTH) {
if ((ret = payload->demux(this, start, last, p)) != 0) { if ((ret = payload->demux(ctx, this, start, last, p)) != 0) {
trace("ts+header payload decode error. ret=%d", ret); trace("ts+header payload decode error. ret=%d", ret);
return ret; return ret;
} }
@ -594,13 +972,60 @@ struct TSPacket
payload->size - payload->pointer_field_size); payload->size - payload->pointer_field_size);
return finish(); return finish();
}
int TSPacket::finish()
{
return 0;
}
TSHeader::TSHeader()
{
}
TSHeader::~TSHeader()
{
}
int TSHeader::get_size()
{
return 4;
}
int TSHeader::demux(TSContext* ctx, TSPacket* pkt, u_int8_t* start, u_int8_t* last, u_int8_t*& p)
{
int ret = 0;
// ts packet header.
sync_byte = *p++;
if (sync_byte != 0x47) {
trace("ts+sync_bytes invalid sync_bytes: %#x, expect is 0x47", sync_byte);
return -1;
} }
int finish() pid = 0;
{ ((char*)&pid)[1] = *p++;
return 0; ((char*)&pid)[0] = *p++;
}
}; transport_error_indicator = (pid >> 15) & 0x01;
payload_unit_start_indicator = (pid >> 14) & 0x01;
transport_priority = (pid >> 13) & 0x01;
pid &= 0x1FFF;
ctx->push(TSPidTypePAT, pid);
continuity_counter = *p++;
transport_scrambling_control = (continuity_counter >> 6) & 0x03;
adaption_field_control = (continuity_counter >> 4) & 0x03;
continuity_counter &= 0x0F;
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);
return ret;
}
int main(int /*argc*/, char** /*argv*/) int main(int /*argc*/, char** /*argv*/)
{ {
@ -610,6 +1035,8 @@ int main(int /*argc*/, char** /*argv*/)
int ret = 0; int ret = 0;
trace("demuxer+read packet count offset T+0 T+1 T+2 T+3 T+x T+L2 T+L1 T+L0"); trace("demuxer+read packet count offset T+0 T+1 T+2 T+3 T+x T+L2 T+L1 T+L0");
TSContext ctx;
for (int i = 0, offset = 0; ; i++) { for (int i = 0, offset = 0; ; i++) {
u_int8_t ts_packet[TS_PACKET_SIZE]; u_int8_t ts_packet[TS_PACKET_SIZE];
memset(ts_packet, 0, sizeof(ts_packet)); memset(ts_packet, 0, sizeof(ts_packet));
@ -632,7 +1059,7 @@ int main(int /*argc*/, char** /*argv*/)
u_int8_t* last = ts_packet + TS_PACKET_SIZE; u_int8_t* last = ts_packet + TS_PACKET_SIZE;
TSPacket pkt; TSPacket pkt;
if ((ret = pkt.demux(start, last, p)) != 0) { if ((ret = pkt.demux(&ctx, start, last, p)) != 0) {
trace("demuxer+read decode ts packet error. ret=%d", ret); trace("demuxer+read decode ts packet error. ret=%d", ret);
return ret; return ret;
} }

View file

@ -41,7 +41,9 @@ file
..\core\srs_core_pithy_print.hpp, ..\core\srs_core_pithy_print.hpp,
..\core\srs_core_pithy_print.cpp, ..\core\srs_core_pithy_print.cpp,
..\core\srs_core_log.hpp, ..\core\srs_core_log.hpp,
..\core\srs_core_log.cpp; ..\core\srs_core_log.cpp,
research readonly separator,
..\..\research\ts_info.cpp;
mainconfig mainconfig
"" = "MAIN"; "" = "MAIN";