一、EIT表简介
EIT按时间顺序提供每一个节目业务中包含的节目段的信息。
二、TS包头结构
其中EIT表的PID为0X12;
要根据这个PID值从TS码流中过滤出所有属于EIT的ts包;
除了PID,TS包头中还需要考虑的参数有:
syn_byte=0x47(标识正确的包的起始位置)
transport_error_indicator=0(标识当前传输的ts包无明显错误)
payload_unit_start_indicator(很重要的一个参数,为1标识该包为一个段的起始ts包,且ts包有效负载第一位为指针pointer_field;为0,则标识有效负载中没有指针。)
adaptation_field_control(当其值为00或10时,标识continuity_counter不连续,该ts包及该段中之前的ts要被丢弃)
三、EIT表结构
筛选出PID==0x12的ts包,并按一定规则拼接为段后,我们要分析EIT短信息。
因为我们分析的是P/F信息,因此只取 table_id=0x4E的EIT段。其中需要考虑的参数有:
section_length(标识从下一个字节起,该section包含的字节数)
service_id(标识节目号)
version_number(版本号,随时间更新)
current_next_indicator(为1,标识当前表有效;为0,标识下一个子表才有用)
section_number(标识EIT表中包含的section个数,因为我们分析的P/F信息,只包含section_number为0和为1的段,因此该参数不用特意分析考虑,只需最后直接输出)
start_time(标识该节目的起始时间)
duration_time(标识该节目的持续时间)
descriptor_loop_length(接下来的循环包含的总的字节数)
discriptor有很多种,我们只分析包含名称信息的短节目段描述符,即选descriptor_tag==0X4D。该描述符的结构如下:
其中descriptor_length标识下一字节开始,该描述符的长度;
event_name_length标识名称信息占用的字节数;event_name_char标识节目名称信息。
四、码流分析仪中的EIT结构显示:
通过C++分析完一段数据后,可以比照码流分析仪中显示的时间、名称信息来看看自己的程序是否正确。
五、代码段
1、ts_packet类
//ts_packet类
#include<iostream>
#include <cstring>
class Ts_Packet
{
private:
unsigned sync_byte;
unsigned transport_error_indicator;
unsigned payload_unit_start_indicator;
unsigned PID;
unsigned adaptation_field_control;
//unsigned continuity_counter;
unsigned offset;
unsigned char payload[184];
public:
Ts_Packet();
Ts_Packet(unsigned char tsHeadbuff[188] );
~Ts_Packet(){};
unsigned get_sync_byte();
unsigned get_transport_error_indicator();
unsigned get_payload_unit_start_indicator();
unsigned get_PID();
unsigned get_adaptation_field_control();
//unsigned get_continuity_counter();
unsigned get_offset();
unsigned char *get_payload();
void print_tsheader();
};
2、ts_packet类的成员函数实现
#include"a_Ts_Packet.h"
Ts_Packet::Ts_Packet()
{
sync_byte = 0;
transport_error_indicator =0;
payload_unit_start_indicator =0;
PID =0;
adaptation_field_control=0;
offset=0;
memset(payload, 0, 184);
};
Ts_Packet::Ts_Packet(unsigned char tsHeadbuff[188])
{
sync_byte = tsHeadbuff[0];
transport_error_indicator = tsHeadbuff[1] >> 7;
payload_unit_start_indicator = ((tsHeadbuff[1] >> 6) & 0x01);
PID = ((tsHeadbuff[1] & 0x1F) << 8 ) | tsHeadbuff[2];
adaptation_field_control=(tsHeadbuff[3]&0x30)>>4;
offset=tsHeadbuff[5];
for(int i=0;i<184;i++)
{
payload[i]=tsHeadbuff[4+i];
}
}
unsigned Ts_Packet::get_sync_byte(){
return sync_byte;}
unsigned Ts_Packet::get_transport_error_indicator(){
return transport_error_indicator;};
unsigned Ts_Packet::get_payload_unit_start_indicator(){
return payload_unit_start_indicator;};
unsigned Ts_Packet::get_PID(){
return PID;};
unsigned Ts_Packet::get_offset(){
return offset;};
unsigned char*Ts_Packet::get_payload(){
return payload;};
unsigned Ts_Packet::get_adaptation_field_control(){
return adaptation_field_control;};
void Ts_Packet::print_tsheader()
{
printf("%02x ",sync_byte);
printf("%02x ",transport_error_indicator);
printf("%02x ",payload_unit_start_indicator);
printf(