DVB开发之重点掌握

1、PSI/SI都采用表的形式来存储相关信息,通常一个表又包含子表,段,描述子等元素构成。

(1)表(Table)

表最初由MPEG-2标准定义的一种存储信息的结构,通常由一个或者多个子表(Sub_table)组成,不同的表通过表的标识(table_id)进行区分,例如PMT的table_id=0x02,NIT的table_id=0x40;

(2)段(Section)

段用于完成PSI/SI信息到传输流包的映射,表或者子表通常由一个或者多个段组成,一个表允许被分成不多于256个段,每个段携带表的一部分;

Section段的通用结构如下:



(3)描述子(Descriptor)

描述子也叫做描述符,语意上比较完整的语法结构,用于提供特定的信息。所有描述子都是一个8位标识的“descripor_tag”开始后面紧跟一个8位的数表示描述子数据区的字节长度,从描述子第三个字节开始的数据则是各个描述子的具体内容。

其语法结构如下:

2、NIT表:

网络信息表(NIT)
包含通过一个网络传输的TS流的物理结构有关的信息,以及网络自身有关信息,如:网络基本信息:网络标识、网络名称、网络多语言名称、链接信息 。TS流信息:TS流标识、传输系统描述、频率列表、业务列表;

NIT表语法结构:



NIT表C代码,解析了通用表头部分信息:

static void ParseNIT_SectionHead(TS_NIT *pstTS_NIT, unsigned char *pucSectionBuffer)
{
int iNetworkDescriptorLen = 0;
int iNIT_Length = 0;
pstTS_NIT->table_id = pucSectionBuffer[0];
pstTS_NIT->section_syntax_indicator = pucSectionBuffer[1] >> 7;
pstTS_NIT->reserved_future_use_1 = (pucSectionBuffer[1] >> 6) & 0x01;
pstTS_NIT->reserved_1 = (pucSectionBuffer[1] >> 4) & 0x03;
pstTS_NIT->section_length = ((pucSectionBuffer[1] & 0x0F) << 8) | pucSectionBuffer[2];
pstTS_NIT->network_id = (pucSectionBuffer[3] << 8) | pucSectionBuffer[4];
pstTS_NIT->reserved_2 = pucSectionBuffer[5] >> 6;
pstTS_NIT->version_number = (pucSectionBuffer[5] >> 1) & 0x1F;
pstTS_NIT->current_next_indicator = (pucSectionBuffer[5] << 7) >> 7;
pstTS_NIT->section_number = pucSectionBuffer[6];
pstTS_NIT->last_section_number = pucSectionBuffer[7];
pstTS_NIT->reserved_future_use_2 = pucSectionBuffer[8] >> 4;
pstTS_NIT->network_descriptors_length = ((pucSectionBuffer[8] & 0x0F) << 8) | pucSectionBuffer[9];
iNetworkDescriptorLen = pstTS_NIT->network_descriptors_length;
memcpy(pstTS_NIT->network_descriptor, pucSectionBuffer + 10, iNetworkDescriptorLen);
pstTS_NIT->reserved_future_use_2 = pucSectionBuffer[10 + iNetworkDescriptorLen] >> 4;
pstTS_NIT->transport_stream_loop_length = ((pucSectionBuffer[10 + iNetworkDescriptorLen] & 0x0F) << 8)
| pucSectionBuffer[10 + iNetworkDescriptorLen + 1];
iNIT_Length = pstTS_NIT->section_length + 3;
pstTS_NIT->CRC_32 = (pucSectionBuffer[iNIT_Length - 4] << 24) | (pucSectionBuffer[iNIT_Length - 3] << 16)
| (pucSectionBuffer[iNIT_Length - 2] << 8) | pucSectionBuffer[iNIT_Length - 1];
}
3、PAT表:

节目关联表(PAT)

关联了节目编号(Program Number)与PMT所使用的PID以及给出NIT所用PID,它是PSI信息的根目录,只要找到PID为0的表,机顶盒就能获知PMT的PID,从而找到PMT表。

节目关联表语法结构:



PAT表C代码解析数据,只解析Section头:

static void ParsePAT_SectionHead(TS_PAT *pstTS_PAT, unsigned char *pucSectionBuffer)
{
int iPAT_Length = 0;
pstTS_PAT->table_id = pucSectionBuffer[0];
pstTS_PAT->section_syntax_indicator = pucSectionBuffer[1] >> 7;
pstTS_PAT->zero = (pucSectionBuffer[1] >> 6) & 0x1;
pstTS_PAT->reserved_1 = (pucSectionBuffer[1] >> 4) & 0x3;
pstTS_PAT->section_length = ((pucSectionBuffer[1] & 0x0F) << 8) | pucSectionBuffer[2];
pstTS_PAT->transport_stream_id = (pucSectionBuffer[3] << 8) | pucSectionBuffer[4];
pstTS_PAT->reserved_2 = pucSectionBuffer[5] >> 6;
pstTS_PAT->version_number = (pucSectionBuffer[5] >> 1) & 0x1F;
pstTS_PAT->current_next_indicator = (pucSectionBuffer[5] << 7) >> 7;
pstTS_PAT->section_number = pucSectionBuffer[6];
pstTS_PAT->last_section_number = pucSectionBuffer[7];
iPAT_Length = 3 + pstTS_PAT->section_length;
pstTS_PAT->CRC_32 = (pucSectionBuffer[iPAT_Length - 4] << 24) | (pucSectionBuffer[iPAT_Length - 3] << 16)
| (pucSectionBuffer[iPAT_Length - 2] << 8) | pucSectionBuffer[iPAT_Length - 1];
}

4、PMT表:

节目映射表(PMT)

描述了组成当前传输流的某个节目的视频流,音频流,数据流信息和PID以及该节目参考时钟PRC的PID,通过PMT表机顶盒可以从传输流中提取出组成该节目的基本流,并予以解码重放,一个PMT表对应一个传输流中的一个节目。

节目映射表语法结构:

PMT表C语言解析表头数据信息:

static void ParsePMT_SectionHead(TS_PMT *pstTS_PMT, unsigned char *pucSectionBuffer)
{
int iPMT_Length = 0;
pstTS_PMT->table_id = pucSectionBuffer[0];
pstTS_PMT->section_syntax_indicator = pucSectionBuffer[1] >> 7;
pstTS_PMT->zero = (pucSectionBuffer[1] >> 6) & 0x01;
pstTS_PMT->reserved_1 = (pucSectionBuffer[1] >> 4) & 0x03;
pstTS_PMT->section_length = ((pucSectionBuffer[1] & 0x0F) << 8) | pucSectionBuffer[2];
pstTS_PMT->program_number = (pucSectionBuffer[3] << 8) | pucSectionBuffer[4];
pstTS_PMT->reserved_2 = pucSectionBuffer[5] >> 6;
pstTS_PMT->version_number = (pucSectionBuffer[5] >> 1) & 0x1F;
pstTS_PMT->current_next_indicator = (pucSectionBuffer[5] << 7) >> 7;
pstTS_PMT->section_number = pucSectionBuffer[6];
pstTS_PMT->last_section_number = pucSectionBuffer[7];
pstTS_PMT->reserved_3 = pucSectionBuffer[8] >> 5;
pstTS_PMT->PCR_PID = ((pucSectionBuffer[8] << 8) | pucSectionBuffer[9]) & 0x1FFF;
pstTS_PMT->reserved_4 = pucSectionBuffer[10] >> 4;
pstTS_PMT->program_info_length = ((pucSectionBuffer[10] & 0x0F) << 8) | pucSectionBuffer[11];
if (0 != pstTS_PMT->program_info_length)
{
memcpy(pstTS_PMT->program_info_descriptor, pucSectionBuffer + 12, pstTS_PMT->program_info_length);
}
iPMT_Length = pstTS_PMT->section_length + 3;
pstTS_PMT->CRC_32 = (pucSectionBuffer[iPMT_Length - 4] << 24) | (pucSectionBuffer[iPMT_Length - 3] << 16)
| (pucSectionBuffer[iPMT_Length - 2] << 8) | pucSectionBuffer[iPMT_Length - 1];
}
当然不止这些表,这些仅仅只是罗列出了DVB开发中常见的几种表!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值