TS码流解析-2-获取完整的TABLE

任务二

根据指定的table id 和 pid 获取完整的table。这是比较重要的一个环节,后面涉及到相关表的解析,都需要用到这里的函数。

相关知识

1.首先了解TS数据包包头的结构,在这里贴一张ts包头的结构图

在这里插入图片描述

各字段的解释:

# 标识 位数 说明
0 sync_byte 8 bits 同步字节,固定是0x47
1 transport_error_indicator 1 bits 错误指示信息(1:该包至少有1bits传输错误)
2 payload_unit_start_indicator 1 bits 负载单元开始标志(packet不满188字节时需填充)
3 transport_priority 1 bits 传输优先级标志(1:优先级高)
4 PID 13 bits Packet ID号码,唯一的号码对应不同的包
5 transport_scrambling_control 2 bits 加密标志(00:未加密;其他表示已加密)
6 adaptation_field_control 2 bits 附加区域控制
7 continuity_counter 4 bits 包递增计数器

在目前阶段,我们主要关注的字段有
payload_unit_start_indicator->用于判断是否为一个section的开始,值为1表示section开头,0表示后续的section数据
PID ->用于判断是否为我们需要的ts包
adaptation_field_control ->用于判断有效载荷的开始位置

描述
00 保留,为将来ISO/IEC使用
01 没有自适应域,仅仅只有有效载荷
10 仅有自适应域,没有有效载荷
11 自适应域之后紧跟着有效载荷

2.了解section的头部结构,在这里同样也贴一张section头部信息结构图

在这里插入图片描述

# 字段名 占位 说明
0 table_id 8 bits 用于标识是什么table
1 section_syntax_indicator 1 bit 段语法标志位,固定为1
2 reserved_future_use 1 bit 保留
3 reserved 2 bits 保留
4 section_length 12 bits 标识section的长度,不包括前三个字节
5 transport_stream_id 16 bits ‭TS的识别号
6 reserved 2 bits 保留
7 version_number 5 bits 一旦TABLE有变化,版本号加1
8 current_next_indicator 1 bit 当前传送的表可以使用,若为0则要等待下一个表
9 section_number 8 bits 给出section号,在sub_table中,第一个section其section_number为"0x00",每增加一个section,section_number加一
10 last_section_number 8 bits sub_table中最后一个section的section_number

注意:这里给的字段以及section头的在所有表中前8个字节是适用的,不管是PAT还是PMT等,前八个字节都是一样的,命名可能不一样,但是大小是一样的。
同样,在这里我们重点关注的有:
table_id->表类型的唯一标识符
section_length->section的长度
version_number->版本号,变化时候,意味着table的内容发生改变
section_number->section的编号
last_section_number->最后一个section的编号

3.package、section、table之间的关系

在这里插入图片描述
简单说,就是数据(table)在传输之前,被切分成一段一段的数据(section),然后段之前加上标识,接着再进行切分,并且加上流的标识符(ts package),这时候就变成了一个个固定包长的流,然后我们就通过该流进行传输。接受方收到数据后,按照相关的规则把它们拼接起来,就可以看到原先的样子了。
关系与区别:

  1. 三者之中,只有TS package是固定长度的,section和table的长度都是不固定的
  2. 一个section可能包含一个或者多个TS package
  3. 一个table可能包含一个或者多个section,section之间用section number区分
  4. 一个EIT section的最大长度是4096字节,其他的section最大长度是1024字节

解析过程

1 数据结构的定义

#define MAX_SECTION_LENGTH      4096

typedef struct
{
   
    unsigned int table_id                      :8;
    unsigned int section_syntax_indicator      :1;
    unsigned int zero                          :1;
    unsigned int reserved1                     :2;
    unsigned int section_length                :12;
    unsigned int service_id                    :16;
    unsigned int reserved2                     :2;
    unsigned int version_number                :5;
    unsigned int current_next_indicator        :1;
    unsigned int section_number                :8;
    unsigned int last_section_number           :8;    
}TS_SECTION_HEAD;

typedef struct section
{
   
    unsigned char section_buffer[MAX_SECTION_LENGTH];
    unsigned int section_length;
    unsigned int section_number;
    struct section *next;
}SECTION;

typedef int(*TABLE_CHECK)(unsigned char table_id);

2 获取对应的section

1 流程图

在这里插入图片描述

2 相关代码
//获取有效载荷的开始位置
static unsigned int get_section_start(TS_PACKAGE_HEAD ts_package_head, unsigned char *package_buffer)
{
   
    int section_start_position = 0;

    switch (ts_package_head.adaptation_field_control)
    {
   
        case 0:
            break;
        case 1:
            section_start_position = 4;
            break;
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值