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

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

闲置电脑也能活出第二春?鲁大师AiNAS让你动动手指就能轻松部署

对于大多数人而言,在这个“数据爆炸”的时代或多或少都遇到过存储告急的情况,这使得“存储焦虑”不再是个别现象,而将会是随着软件的不断臃肿而越来越普遍的情况。从不少手机厂商都开始将存储上限提升至1TB可以见得,我们似乎正处在互联网信息飞速增长的阶段,对于存储的需求也将会不断扩大。对于苹果用户而言,这一问题愈发严峻,毕竟512GB和1TB版本的iPhone可不是人人都消费得起的,因此成熟的外置存储方案开

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

【Linux】应用层http协议

一、HTTP协议 1.1 简要介绍一下HTTP        我们在网络的应用层中可以自己定义协议,但是,已经有大佬定义了一些现成的,非常好用的应用层协议,供我们直接使用,HTTP(超文本传输协议)就是其中之一。        在互联网世界中,HTTP(超文本传输协议)是一个至关重要的协议,他定义了客户端(如浏览器)与服务器之间如何进行通信,以交换或者传输超文本(比如HTML文档)。

OWASP十大安全漏洞解析

OWASP(开放式Web应用程序安全项目)发布的“十大安全漏洞”列表是Web应用程序安全领域的权威指南,它总结了Web应用程序中最常见、最危险的安全隐患。以下是对OWASP十大安全漏洞的详细解析: 1. 注入漏洞(Injection) 描述:攻击者通过在应用程序的输入数据中插入恶意代码,从而控制应用程序的行为。常见的注入类型包括SQL注入、OS命令注入、LDAP注入等。 影响:可能导致数据泄

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [