从mpeg ts文件中提取I帧(2):pat pmt解析
一、PAT用途
1、描述当前传输流中 PMT 的 PID 信息。
2、描述PMT,与SDT的对应关系。
3、program_number=0时为network pid即nit的pid,接收pmt时注意跳过这nit。
4、pat是整个ts流的入口,依据pat描述的pmt pid就可以搜索出所有的pmt信息。
其语法结构如下图所示:
PAT解析代码:
int mpeg_psi_pat_parse(uint8_t *sec_buf, int32_t sec_len, int16_t pid)
{uint8_t* buf = sec_buf;uint32_t program_loop_length = (uint16_t)(((buf[1]&0x0f)<<8)|buf[2]) - 9;if (MPEGPSI_TID_PAT != buf[0]) {print_err("pat tid=%d\n", buf[0]);return -1;}printf("pat section pid=0x%04x\n", pid);printf(" |-table_id =0x%x\n", (uint8_t )( buf[0]) );printf(" |-section_syntax_indicator=0x%x\n", (uint8_t )(( buf[1]&0x80)>>7) );printf(" |-section_length =0x%x\n", (uint16_t)(((buf[1]&0x0f)<<8)|buf[2]));printf(" |-extend_table_id =0x%x\n", (uint16_t)(( buf[3]<<8)|buf[4]) );printf(" |-version_number =0x%x\n", (uint8_t )(( buf[5]&0x3e)>>1) );printf(" |-current_next_indicator =0x%x\n", (uint8_t )( buf[5]&0x01) );printf(" |-section_number =0x%x\n", (uint8_t )( buf[6]) );printf(" |-last_section_number =0x%x\n", (uint8_t )( buf[7]) );g_mpeg_transport.transport_stream_id = (uint16_t)(( buf[3]<<8)|buf[4]);g_mpeg_transport.program_numb = 0;buf = sec_buf + 8;while( program_loop_length > 0 ) { uint16_t program_number = (uint16_t)( buf[0]<<8 | buf[1]);uint16_t program_map_pid = (uint16_t)((buf[2]&0x1f)<<8 | buf[3]);printf(" |-program_number=0x%04x program_map_pid=0x%04x (%d)\n", program_number, program_map_pid, program_map_pid); if (g_mpeg_transport.program_numb < MPEGPSI_MAX_PROGRAM) {g_mpeg_transport.program_info[g_mpeg_transport.program_numb].program_number = program_number;g_mpeg_transport.program_info[g_mpeg_transport.program_numb].program_map_pid = program_map_pid;g_mpeg_transport.program_numb ++;}else {print_err("MPEGPSI_MAX_PROGRAM=%d overflow.\n", MPEGPSI_MAX_PROGRAM);}if( program_loop_length >= 4 ) {program_loop_length = program_loop_length - 4; buf = buf + 4;}else {printf("pat parse error !!!\n");break;} }buf = sec_buf + (sec_len-4);printf(" |-crc_32 = 0x%x 0x%x\n", (uint32_t)((buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|(buf[3])), mpeg_crc32(sec_buf, sec_len-4));printf("\n");return 0;
}
PAT解析运行结果:
pat section pid=0x0000|-table_id =0x0|-section_syntax_indicator=0x1|-section_length =0x25|-extend_table_id =0x2|-version_number =0x1|-current_next_indicator =0x1|-section_number =0x0|-last_section_number =0x0|-program_number=0x0000 program_map_pid=0x0010 (16)|-program_number=0x00c9 program_map_pid=0x0100 (256)|-program_number=0x00ca program_map_pid=0x0200 (512)|-program_number=0x00cb program_map_pid=0x0300 (768)|-program_number=0x00cc program_map_pid=0x0400 (1024)|-program_number=0x00cd program_map_pid=0x0500 (1280)|-program_number=0x00ce program_map_pid=0x0600 (1536)|-crc_32 = 0x6012d6e2 0x6012d6e2
二、PMT用途
1、当前频道中包含的所有Video数据的PID
2、当前频道中包含的所有Audio数据的PID
3、和当前频道关联在一起的其他数据的PID(如数字广播等使用的PID)
4、加扰节目授权控制信息 ECM PID
PMT解析代码:
int mpeg_psi_pmt_parse(uint8_t *sec_buf, int32_t sec_len, int16_t pid)
{uint8_t *buf = sec_buf;uint8_t *ptr = NULL;uint16_t program_info_length = (uint16_t)(((buf[10]&0x0f)<<8)|buf[11]);uint16_t stream_loop_length = 0;uint16_t section_length = (uint16_t)(((buf[1]&0x0f)<<8)|buf[2]);mpeg_program_t *program = NULL;int i = 0;if (MPEGPSI_TID_PMT != buf[0]) {print_err("pat tid=%d\n", buf[0]);return -1;}for (i=0; i<g_mpeg_transport.program_numb; i++) {if (g_mpeg_transport.program_info[i].program_map_pid == pid) {program = &(g_mpeg_transport.program_info[i]);break;}}printf("pmt section pid=0x%04x(%d)\n", pid, pid);printf("|-table_id = 0x%x\n", (uint8_t)( buf[0]) );printf("|-section_syntax_indicator = 0x%x\n", (uint8_t)(( buf[1]&0x80)>>7) );printf("|-section_length = 0x%x\n", (uint16_t)(((buf[1]&0x0f)<<8)|buf[2]));printf("|-program_number = 0x%x\n", (uint16_t)(( buf[3]<<8)|buf[4]) );printf("|-version_number = 0x%x\n", (uint8_t)(( buf[5]&0x3e)>>1) );printf("|-current_next_indicator = 0x%x\n", (uint8_t)( buf[5]&0x01) );printf("|-section_number = 0x%x\n", (uint8_t)( buf[6]) );printf("|-last_section_number = 0x%x\n", (uint8_t)( buf[7]) );printf("|-pcr_pid = 0x%x\n", (uint16_t)(((buf[8]&0x1f)<<8)|buf[9]));printf("|-program_info_length = 0x%x\n", program_info_length );pmt_descriptor_parse(buf+12, program_info_length, 0);stream_loop_length = section_length - program_info_length - 13;ptr = buf + 12 + program_info_length;while (stream_loop_length) {uint16_t es_info_length = 0;uint16_t stream_type = 0;uint16_t elementary_pid = 0;char x = '-';es_info_length = (uint16_t)(((ptr[3]&0x0f)<<8)|ptr[4]);if (es_info_length!=0) {x = '+';}elementary_pid = (uint16_t)(((ptr[1] & 0x1f) << 8) | ptr[2]);stream_type = ptr[0];printf("|%ces_pid = 0x%x stream_type = 0x%x\n", x, elementary_pid, stream_type);if (NULL != program) {if (program->stream_numb < MPEGPSI_MAX_STREAM) {program->stream_info[program->stream_numb].elementary_pid = elementary_pid;program->stream_info[program->stream_numb].stream_type = stream_type;program->stream_numb ++;}else {print_err("MPEGPSI_MAX_STREAM=%d overflow.\n", MPEGPSI_MAX_STREAM);}}pmt_descriptor_parse(ptr+5, es_info_length, 1);es_info_length += 5;if (stream_loop_length >= es_info_length) {stream_loop_length -= es_info_length;ptr +=es_info_length;}else {break;}}buf = sec_buf + (sec_len-4);printf("|-crc_32 = 0x%x 0x%x\n", (uint32_t)((buf[0]<<24)|(buf[1]<<16)|(buf[2]<<8)|(buf[3])), mpeg_crc32(sec_buf, sec_len-4));printf("\n");return 0;
}
PMT解析运行结果:
mt section pid=0x0100(256)
|-table_id = 0x2
|-section_syntax_indicator = 0x1
|-section_length = 0x4f
|-program_number = 0xc9
|-version_number = 0x1
|-current_next_indicator = 0x1
|-section_number = 0x0
|-last_section_number = 0x0
|-pcr_pid = 0x1ffe
|-program_info_length = 0x17
|+descriptor|-unknown_descriptor tag=0x0b len=0x2 4a 1f |-unknown_descriptor tag=0x0c len=0x4 80 b4 81 68 |-unknown_descriptor tag=0x0e len=0x3 c0 1e c6 |-unknown_descriptor tag=0x10 len=0x6 c0 1e c6 c0 08 00
|+es_pid = 0x101 stream_type = 0x2|-unknown_descriptor tag=0x02 len=0x3 1a 48 5f |-unknown_descriptor tag=0x52 len=0x1 00 |-unknown_descriptor tag=0x0e len=0x3 c0 1c f0 |-unknown_descriptor tag=0x06 len=0x1 02
|+es_pid = 0x102 stream_type = 0x4|-unknown_descriptor tag=0x03 len=0x1 67 |-unknown_descriptor tag=0x0a len=0x4 65 6e 67 00 |-unknown_descriptor tag=0x52 len=0x1 8a |-unknown_descriptor tag=0x0e len=0x3 c0 01 68
|-crc_32 = 0x580343a4 0x580343a4
三、为什要解析pat pmt
1、用来校验输入的视频pid是否合法,免去了遍历整个ts的开销。
2、当不知道视频pid时,可以通过pat pmt的解析,显示所有的视音频pid。
mpeg2标准:https://download.csdn.net/download/maxzero/10402761
完整的代码:https://download.csdn.net/download/maxzero/10572383
从mpeg ts文件中提取I帧(2):pat pmt解析相关推荐
- 从mpeg ts文件中提取I帧(1):将ts包拼装为section或pes包
写在前面的话: 不觉中已经在数码工作了十年有余,十年的青春.十年的汗水,如今即将离开,个中滋味难以言表! 以后可能不会在广电行业工作了,就用这个小程序,为自己十年的广电工作画上一个句号 ...
- 从mpeg ts文件中提取I帧(3):pes包的解析
本系列的第一篇文章讲解了如何把ts包拼装为pes包,本章主要讲解如何解析pes包. 一.pes包的格式如下图所示: 二.相关字段解析 packet_start_code_prefix ...
- ffmpeg-从mp4、flv、ts文件中提取264视频流数据
ffmpeg-从mp4.flv.ts文件中提取264视频流数据 main.c #include <stdio.h> #include <libavutil/log.h> #in ...
- 从TS文件中提取DVB Subtitle字幕的有效方法
从TS文件中提取DVB Subtitle字幕的有效方法 深圳市同洲电子股份有限公司韦斌 (本文发表于<卫星电视与宽带多媒体>2013年16期) 摘要:DVB Subtitling标准 ...
- 使用ffmpeg从视频文件中提取音频文件、视频抽帧和切割视频
目录 ffmpeg下载 使用ffmpeg从视频文件中提取音频文件 批量提取文件夹下多个视频文件的音频 使用ffmpeg从视频文件中提取视频帧 使用ffmpeg将按固定时长将视频切割成多个小片段 将分割 ...
- ffmpeg-从flv文件中提取AAC音频数据保存为文件
AAC ADTS格式协议: 从flv文件中提取AAC音频数据保存为文件. 如果需要详细了解AAC ADTS格式,可以查询文档. 原文件: 提取aac文件: main.c #include <st ...
- [SimplePlayer] 4. 从视频文件中提取音频
提取音频,具体点来说就是提取音频帧.提取方法与从视频文件中提取图像的方法基本一样,这里仅列出其中的不同点: 1. 由于目的提取音频,因此在demux的时候需要指定的是提取audio stream Au ...
- klg日志文件中提取RGBD图像数据
main函数 本程序用于从klg日志文件中提取RGB图像和Depth图像信息,klg文件在ElasticFusion中被用于保存数据集. 涉及的相关开源代码如下: LogView mp3guy/Log ...
- 【流媒體】H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流
原文地址为: [流媒體]H264-MP4格式及在MP4文件中提取H264的SPS.PPS及码流 [流媒體]H264-MP4格式及在MP4文件中提取H264的SPS.PPS及码流 SkySeraph A ...
最新文章
- JavaScript Collection
- 1.网络工具:ifconfig,ping,netstate,Redhat命令和图形化设置ip,finger,nslookup
- echarts php 数据处理,PHP+echarts读取地图数据
- c语言输出星期几的英语表达,C语言程序设计: 输入年月日 然后输出是星期几...
- 大数据学习(2-2)- 使用docker安装配置Hadoop环境
- LeetCode 684. 冗余连接(并查集)
- python集合运算符_Python 集合、字典、运算符
- python e_pythone函数基础(8)内置函数学习
- Python模拟登陆,解密js代码实例:知乎登陆
- php滑动轮播效果,js实现移动端手指滑动轮播图效果
- 2018年湖南居民人均可支配收入25241元 出行餐饮成消费热点
- Vue 自定义弹出框组件(类似淘宝选择规格)
- 闭环系统辨识matlab,系统辨识-12-闭环辨识
- 混合线性模型不同模型拟合的可视化
- DTCloud 报表格式
- 区块链重塑经济与世界
- “热榜第一”阿里年薪80W的Java架构师,到底是有着怎样的水平?
- 各互联网大厂工程师薪资新鲜出炉,速来围观!
- php python 源码安装教程,Python安装的图文教程分享
- Hand-Aurora-bm常见设计
热门文章
- 组播ipv6 mld proxy测试环境搭建
- win7系统备份还原软件_win7如何进入系统还原教程
- 制作无盘Windows 2003之无忧Ghost文件(转)
- 对于windows11,无法添加键盘,仅桌面,无法输入中文的问题(亲测,难顶)
- vue 后台管理系统实现字体自适应element ui
- 视频号如何选品进行分享?
- 求渐近线的流水线(/手动滑稽)
- java.sql.SQLException: Access denied for user ‘‘@‘localhost‘ (using password: YES) 出现原因和解决办法
- Centos7 安装Docker(2020最新亲测可用,直接复制粘贴即可)
- 从Facebook的新设计中窥探他们如何运用CSS技巧