TS协议解析第二部分(PMT)

2024-02-05 09:58
文章标签 协议 解析 第二 部分 ts pmt

本文主要是介绍TS协议解析第二部分(PMT),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://blog.csdn.net/u013354805/article/details/51586086


1. PMT:

PMT(Program Map Table):节目映射表,该表的PID是由PAT提供给出的。通过该表可以得到一路节目中包含的信息,例如,该路节目由哪些流构成和这些流的类型(视频,音频,数据),指定节目中各流对应的PID,以及该节目的PCR所对应的PID。

PMT表中包含的数据如下:

(1) 当前频道中包含的所有Video数据的PID
(2) 当前频道中包含的所有Audio数据的PID
(3) 和当前频道关联在一起的其他数据的PID(如数字广播,数据通讯等使用的PID)

2. 分析MPT包:

2.1 PMT包数据:


2.2 包头:

TS包头只有4个字节(47 60 81 10),除掉第一个字节0x47,剩下就3个,重新分组如下:

0    1    1  0000010000001    00    01    0000

sync_byte

同步字节

0x47:

transport_error_indicator

传输错误标识

0:

payload_unit_start_indicator

负载单元开始标识

1:

transport_priority

传输优先级

1:

pid

PID

0x81:因为在PAT中查找到program_map_PID为0x81,因此就查找到PMT。

transport_scrambling_control

传输扰乱控制

00:

adaptation_field_control

自适应区域控制

01:

00是保留值。
01负载中只有有效载荷。
10负载中只有自适应字段。
11先有自适应字段,再有有效载荷。

continuity_counter

连续计数器

0x0:

2.3 TS包:

1) 在payload_unit_start_indicator为1时,在前4个字节后会有一个调整字节。所以实际数据应该为去除第一个字节00后的数据。(47 60 81 10 00 02 B0 17 00 01 C1 00 00 E8 10 F0 00 1B E8 10 F0 00 03 E8 14 F0 00 66 74 A4 2D

2) 02 B0 17:0000 0010 1011 0000 0001 0111
section_length:23 47 60 81 10 00 02 B0 17 00 01 C1 00 00 E8 10 F0 00 1B E8 10 F0 00 03 E8 14 F0 00 66 74 A4 2D

3)
00 01:0000 0000 0000 0001
C1:1100 0001
00 00:0000 0000 0000 0000
E8 10:1110 1000 0001 0000
F0 00:1111 0000 0000 0000
1B E8 10 F0 00:0001 1011 1110 1000 0001 0000 1111 0000 0000 0000
03 E8 14 F0 00:0000 0011 1110 1000 0001 0100 1111 0000 0000 0000

table_id

0x02:对于PMT,该字段置为0x02

section_syntax_indicator

1:对于PMT,该字段置为1

0

0:

reserved

11:

section_length

0000 0001 0111:前两位置为00,该字段指示分段的字节数,由分段长度字段开始,包括CRC,其值不超过1021。

Program_number

0x 00 01:对应于PAT中的Program_nmuber。

reserved

11:

version_number

00000:该字段指出了TS中program_map_section的版本号。

current_next_indicator

1:当该字段置为1时,表示当前传送的program_map_section可用;当该字段置0时,表示当前传送的program_map_section不可用,下一个TS的program_map_section有效。

section_number

0x00:section_number:该字段值总是置0x00

last_section_number

0x00:该字段值总是置0x00

reserved

111:

PCR_PID

0x810:该字段指示TS包的PID值。该TS包含有PCR字段,而PCR值对应于有节目好指定的节目。

reserved

1111:

Program_info_length

0x000:

stream_type

1B:表示这个流时h264格式的,通俗点就是视频

reserved

111:

Elementary_pid

0x810:表示PID时810的TS包就是用来装h264数据的

reserved

1111:

es_info_length

0x000:

Stream_type:

0x03:

reserved:

111:

Elementary_pid

0x814

reserved

1111:

Es_info_lenth

0x000:

Crc_32

0x 03 E8 14 F0 00:


PMT

table_id

8

1个字节

section_syntax_indicator

1

 

2个字节

‘0’

1

reserved

2

section_length

12

program_number

16

2个字节

reserved

2

 

1个字节

version_number

5

current_next_indicator

1

section_number

8

1个字节

last_section_number

8

1个字节

reserved

3

 

2个字节

PCR_PID

13

reserved

4

2个字节

program_info_length

12

循环:descriptor()(0-N)

循环开始(0-N1)

stream_type

8

1个字节

reserved

3

2个字节

elementary_PID

13

reserved

4

2个字节

ES_info_length

12

循环:descriptor()(0-N2)

循环结束

CRC_32

32

4个字节


3. 实现:

3.1 PMT表格定义如下:

[cpp]  view plain copy
  1. typedef struct TS_PMT_Stream  
  2. {  
  3.  unsigned stream_type     : 8; //指示特定PID的节目元素包的类型。该处PID由elementary PID指定  
  4.  unsigned elementary_PID  : 13; //该域指示TS包的PID值。这些TS包含有相关的节目元素  
  5.  unsigned ES_info_length  : 12; //前两位bit为00。该域指示跟随其后的描述相关节目元素的byte数  
  6.  unsigned descriptor;  
  7. }TS_PMT_Stream;  


3.2 PMT表结构体:
[cpp]  view plain copy
  1. typedef struct TS_PMT  
  2. {  
  3.     unsigned table_id                   : 8; //固定为0x02, 表示PMT表  
  4.     unsigned section_syntax_indicator    : 1; //固定为0x01  
  5.    unsigned zero                       : 1; //0x01  
  6.    unsigned reserved_1                 : 2; //0x03  
  7.    unsigned section_length : 12;//首先两位bit置为00,它指示段的byte数,由段长度域开始,包含CRC  
  8.    unsigned program_number             : 16;// 指出该节目对应于可应用的Program map PID  
  9.    unsigned reserved_2                 : 2; //0x03  
  10.    unsigned version_number             : 5; //指出TS流中Program map section的版本号  
  11.     unsigned current_next_indicator  : 1; //当该位置1时,当前传送的Program map section可用  
  12.      //当该位置0时,指示当前传送的Program map section不可用,下一个TS流的Program map section有效  
  13.    unsigned section_number            : 8; //固定为0x00  
  14.    unsigned last_section_number      : 8; //固定为0x00  
  15.    unsigned reserved_3               : 3; //0x07  
  16.    nsigned PCR_PID                   : 13; //指明TS包的PID值,该TS包含有PCR域,  
  17.       //该PCR值对应于由节目号指定的对应节目,如果对于私有数据流的节目定义与PCR无关,这个域的值将为0x1FFF。  
  18.    unsigned reserved_4            : 4;  //预留为0x0F  
  19.    unsigned program_info_length  : 12; //前两位bit为00。该域指出跟随其后对节目信息的描述的byte数。  
  20.       
  21.  std::vector<TS_PMT_Stream> PMT_Stream;  //每个元素包含8位, 指示特定PID的节目元素包的类型。该处PID由elementary PID指定  
  22.     unsigned reserved_5                : 3; //0x07  
  23.    unsigned reserved_6                : 4; //0x0F  
  24.    unsigned CRC_32                    : 32;   
  25. } TS_PMT;   


3.3 解析代码:

[cpp]  view plain copy
  1. HRESULT CTS_Stream_Parse::adjust_PMT_table ( TS_PMT * packet, unsigned char * buffer )  
  2. {   
  3.     packet->table_id                         = buffer[0];  
  4.     packet->section_syntax_indicator         = buffer[1] >> 7;  
  5.     packet->zero                             = buffer[1] >> 6 & 0x01;   
  6.     packet->reserved_1                       = buffer[1] >> 4 & 0x03;  
  7.     packet->section_length                   = (buffer[1] & 0x0F) << 8 | buffer[2];      
  8.     packet->program_number                   = buffer[3] << 8 | buffer[4];  
  9.     packet->reserved_2                       = buffer[5] >> 6;  
  10.     packet->version_number                   = buffer[5] >> 1 & 0x1F;  
  11.     packet->current_next_indicator           = (buffer[5] << 7) >> 7;  
  12.     packet->section_number                   = buffer[6];  
  13.     packet->last_section_number              = buffer[7];  
  14.     packet->reserved_3                       = buffer[8] >> 5;  
  15.     packet->PCR_PID                          = ((buffer[8] << 8) | buffer[9]) & 0x1FFF;  
  16.   
  17.     PCRID = packet->PCR_PID;  
  18.   
  19.     packet->reserved_4                       = buffer[10] >> 4;  
  20.     packet->program_info_length              = (buffer[10] & 0x0F) << 8 | buffer[11];   
  21.     // Get CRC_32  
  22.     int len = 0;  
  23.     len = packet->section_length + 3;      
  24.     packet->CRC_32                = (buffer[len-4] & 0x000000FF) << 24  
  25.       | (buffer[len-3] & 0x000000FF) << 16  
  26.       | (buffer[len-2] & 0x000000FF) << 8  
  27.       | (buffer[len-1] & 0x000000FF);   
  28.   
  29.   int pos = 12;  
  30.   // program info descriptor  
  31.   if ( packet->program_info_length != 0 )  
  32.         pos += packet->program_info_length;      
  33.   // Get stream type and PID      
  34.   for ( ; pos <= (packet->section_length + 2 ) -  4; )  
  35.   {  
  36.     TS_PMT_Stream pmt_stream;  
  37.     pmt_stream.stream_type =  buffer[pos];  
  38.     packet->reserved_5  =  buffer[pos+1] >> 5;  
  39.     pmt_stream.elementary_PID = ((buffer[pos+1] << 8) | buffer[pos+2]) & 0x1FFF;  
  40.     packet->reserved_6    =  buffer[pos+3] >> 4;  
  41.     pmt_stream.ES_info_length =  (buffer[pos+3] & 0x0F) << 8 | buffer[pos+4];  
  42.     
  43.     pmt_stream.descriptor = 0x00;  
  44.     if (pmt_stream.ES_info_length != 0)  
  45.     {  
  46.        pmt_stream.descriptor = buffer[pos + 5];  
  47.      
  48.        forint len = 2; len <= pmt_stream.ES_info_length; len ++ )  
  49.        {  
  50.          pmt_stream.descriptor = pmt_stream.descriptor<< 8 | buffer[pos + 4 + len];  
  51.        }  
  52.        pos += pmt_stream.ES_info_length;  
  53.     }  
  54.     pos += 5;  
  55.     packet->PMT_Stream.push_back( pmt_stream );  
  56.     TS_Stream_type.push_back( pmt_stream );  
  57.    }  
  58.    return 0;  
  59. }  


1
0





这篇关于TS协议解析第二部分(PMT)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/680549

相关文章

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

MySQL中FIND_IN_SET函数与INSTR函数用法解析

《MySQL中FIND_IN_SET函数与INSTR函数用法解析》:本文主要介绍MySQL中FIND_IN_SET函数与INSTR函数用法解析,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一... 目录一、功能定义与语法1、FIND_IN_SET函数2、INSTR函数二、本质区别对比三、实际场景案例分

Nginx中配置HTTP/2协议的详细指南

《Nginx中配置HTTP/2协议的详细指南》HTTP/2是HTTP协议的下一代版本,旨在提高性能、减少延迟并优化现代网络环境中的通信效率,本文将为大家介绍Nginx配置HTTP/2协议想详细步骤,需... 目录一、HTTP/2 协议概述1.HTTP/22. HTTP/2 的核心特性3. HTTP/2 的优

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

关于WebSocket协议状态码解析

《关于WebSocket协议状态码解析》:本文主要介绍关于WebSocket协议状态码的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录WebSocket协议状态码解析1. 引言2. WebSocket协议状态码概述3. WebSocket协议状态码详解3

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

Oracle数据库常见字段类型大全以及超详细解析

《Oracle数据库常见字段类型大全以及超详细解析》在Oracle数据库中查询特定表的字段个数通常需要使用SQL语句来完成,:本文主要介绍Oracle数据库常见字段类型大全以及超详细解析,文中通过... 目录前言一、字符类型(Character)1、CHAR:定长字符数据类型2、VARCHAR2:变长字符数

使用Jackson进行JSON生成与解析的新手指南

《使用Jackson进行JSON生成与解析的新手指南》这篇文章主要为大家详细介绍了如何使用Jackson进行JSON生成与解析处理,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 核心依赖2. 基础用法2.1 对象转 jsON(序列化)2.2 JSON 转对象(反序列化)3.

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@