TS流解析之PAT表格解析

//PAT表格定义如下:
typedef struct TS_PAT_Program
{
    unsigned program_number    :16;		//节目号
    unsigned program_map_PID   :13;		//节目映射表的PID,节目号大于0时对应的PID,每个节目对应一个
}TS_PAT_Program;

//PAT表结构体
typedef struct TS_PAT
{
	unsigned table_id					: 8; //固定为0x00 ,标志是该表是PAT
	unsigned section_syntax_indicator	: 1; //段语法标志位,固定为1
	unsigned zero						: 1; //0
	unsigned reserved_1					: 2; // 保留位
	unsigned section_length				: 12; //表示这个字节后面有用的字节数,包括CRC32
	unsigned transport_stream_id		: 16; //该传输流的ID,区别于一个网络中其它多路复用的流
	unsigned reserved_2					: 2;// 保留位
	unsigned version_number				: 5; //范围0-31,表示PAT的版本号
	unsigned current_next_indicator		: 1; //发送的PAT是当前有效还是下一个PAT有效
	unsigned section_number				: 8; //分段的号码。PAT可能分为多段传输,第一段为00,以后每个分段加1,最多可能有256个分段
	unsigned last_section_number		: 8;  //最后一个分段的号码
	std::vector<TS_PAT_Program> program;
	unsigned reserved_3					: 3; // 保留位
	unsigned network_PID				: 13; //网络信息表(NIT)的PID,节目号为0时对应的PID为network_PID
	unsigned CRC_32						: 32;  //CRC32校验码
} TS_PAT;

	
//解析代码如下:

HRESULT CTS_Stream_Parse::adjust_PAT_table( TS_PAT * packet, unsigned char * buffer)
{
    packet->table_id						= buffer[0];
    packet->section_syntax_indicator		= buffer[1] >> 7;
    packet->zero							= buffer[1] >> 6 & 0x1;
    packet->reserved_1						= buffer[1] >> 4 & 0x3;
    packet->section_length					= (buffer[1] & 0x0F) << 8 | buffer[2];
    packet->transport_stream_id				= buffer[3] << 8 | buffer[4];
    packet->reserved_2						= buffer[5] >> 6;
    packet->version_number					= buffer[5] >> 1 &  0x1F;
    packet->current_next_indicator			= (buffer[5] << 7) >> 7;
    packet->section_number					= buffer[6];
    packet->last_section_number				= buffer[7];

    int len									= 0;
    len										= 3 + packet->section_length;
    
	packet->CRC_32                        = (buffer[len-4] & 0x000000FF) << 24
    | (buffer[len-3] & 0x000000FF) << 16
    | (buffer[len-2] & 0x000000FF) << 8
    | (buffer[len-1] & 0x000000FF);
    
	int n = 0;
    
	for ( n = 0; n < packet->section_length - 12; n += 4 )
    {
        unsigned  program_num = buffer[8 + n ] << 8 | buffer[9 + n ];
        packet->reserved_3                = buffer[10 + n ] >> 5;
        packet->network_PID = 0x00;
        if ( program_num == 0x00)
        {
            packet->network_PID = (buffer[10 + n ] & 0x1F) << 8 | buffer[11 + n ];
            TS_network_Pid = packet->network_PID; //记录该TS流的网络PID
            TRACE(" packet->network_PID %0x \n\n", packet->network_PID );
        }
        else
        {
            TS_PAT_Program PAT_program;
            PAT_program.program_map_PID = (buffer[10 + n] & 0x1F) << 8 | buffer[11 + n];
            PAT_program.program_number = program_num;
            packet->program.push_back( PAT_program );
            TS_program.push_back( PAT_program );//向全局PAT节目数组中添加PAT节目信息
        }
    }
    return 0;
}

//因此,PAT数据解析结果如下:
//PAT数据
int printPAT()
{
	print("
			table_id					:0x00		// 8
			section_syntax_indicator	:0x01		// 1
			'0'							:0x00		// 1
			reserved					: 0x03		// 2
			section_length				:0x00d		// 12
			transport_stream_id			:0x0000	// 16
			reserved					:0x03		// 2
			version_number				:0x00		// 5
			current_next_indicator		:0x01		// 1
			section_number              :0x00		// 8
			last_section_number         :0x00		// 8
			program_number				:0x0001	// 16
			reserved					:0x07		// 3
			program_map_PID				:0x03e8	// 13
			CRC							:0x f0 0b d7 79
			");
	return 0;
}

由解析结构可知,该PAT表格中没有网络信息包信息,只包含一个节目,其PID为0x03e8




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值