一、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解析相关推荐

  1. 从mpeg ts文件中提取I帧(1):将ts包拼装为section或pes包

    写在前面的话:         不觉中已经在数码工作了十年有余,十年的青春.十年的汗水,如今即将离开,个中滋味难以言表! 以后可能不会在广电行业工作了,就用这个小程序,为自己十年的广电工作画上一个句号 ...

  2. 从mpeg ts文件中提取I帧(3):pes包的解析

    本系列的第一篇文章讲解了如何把ts包拼装为pes包,本章主要讲解如何解析pes包. 一.pes包的格式如下图所示: 二.相关字段解析 packet_start_code_prefix          ...

  3. ffmpeg-从mp4、flv、ts文件中提取264视频流数据

    ffmpeg-从mp4.flv.ts文件中提取264视频流数据 main.c #include <stdio.h> #include <libavutil/log.h> #in ...

  4. 从TS文件中提取DVB Subtitle字幕的有效方法

     从TS文件中提取DVB Subtitle字幕的有效方法 深圳市同洲电子股份有限公司韦斌 (本文发表于<卫星电视与宽带多媒体>2013年16期) 摘要:DVB Subtitling标准 ...

  5. 使用ffmpeg从视频文件中提取音频文件、视频抽帧和切割视频

    目录 ffmpeg下载 使用ffmpeg从视频文件中提取音频文件 批量提取文件夹下多个视频文件的音频 使用ffmpeg从视频文件中提取视频帧 使用ffmpeg将按固定时长将视频切割成多个小片段 将分割 ...

  6. ffmpeg-从flv文件中提取AAC音频数据保存为文件

    AAC ADTS格式协议: 从flv文件中提取AAC音频数据保存为文件. 如果需要详细了解AAC ADTS格式,可以查询文档. 原文件: 提取aac文件: main.c #include <st ...

  7. [SimplePlayer] 4. 从视频文件中提取音频

    提取音频,具体点来说就是提取音频帧.提取方法与从视频文件中提取图像的方法基本一样,这里仅列出其中的不同点: 1. 由于目的提取音频,因此在demux的时候需要指定的是提取audio stream Au ...

  8. klg日志文件中提取RGBD图像数据

    main函数 本程序用于从klg日志文件中提取RGB图像和Depth图像信息,klg文件在ElasticFusion中被用于保存数据集. 涉及的相关开源代码如下: LogView mp3guy/Log ...

  9. 【流媒體】H264—MP4格式及在MP4文件中提取H264的SPS、PPS及码流

    原文地址为: [流媒體]H264-MP4格式及在MP4文件中提取H264的SPS.PPS及码流 [流媒體]H264-MP4格式及在MP4文件中提取H264的SPS.PPS及码流 SkySeraph A ...

最新文章

  1. JavaScript Collection
  2. 1.网络工具:ifconfig,ping,netstate,Redhat命令和图形化设置ip,finger,nslookup
  3. echarts php 数据处理,PHP+echarts读取地图数据
  4. c语言输出星期几的英语表达,C语言程序设计: 输入年月日 然后输出是星期几...
  5. 大数据学习(2-2)- 使用docker安装配置Hadoop环境
  6. LeetCode 684. 冗余连接(并查集)
  7. python集合运算符_Python 集合、字典、运算符
  8. python e_pythone函数基础(8)内置函数学习
  9. Python模拟登陆,解密js代码实例:知乎登陆
  10. php滑动轮播效果,js实现移动端手指滑动轮播图效果
  11. 2018年湖南居民人均可支配收入25241元 出行餐饮成消费热点
  12. Vue 自定义弹出框组件(类似淘宝选择规格)
  13. 闭环系统辨识matlab,系统辨识-12-闭环辨识
  14. 混合线性模型不同模型拟合的可视化
  15. DTCloud 报表格式
  16. 区块链重塑经济与世界
  17. “热榜第一”阿里年薪80W的Java架构师,到底是有着怎样的水平?
  18. 各互联网大厂工程师薪资新鲜出炉,速来围观!
  19. php python 源码安装教程,Python安装的图文教程分享
  20. Hand-Aurora-bm常见设计

热门文章

  1. 组播ipv6 mld proxy测试环境搭建
  2. win7系统备份还原软件_win7如何进入系统还原教程
  3. 制作无盘Windows 2003之无忧Ghost文件(转)
  4. 对于windows11,无法添加键盘,仅桌面,无法输入中文的问题(亲测,难顶)
  5. vue 后台管理系统实现字体自适应element ui
  6. 视频号如何选品进行分享?
  7. 求渐近线的流水线(/手动滑稽)
  8. java.sql.SQLException: Access denied for user ‘‘@‘localhost‘ (using password: YES) 出现原因和解决办法
  9. Centos7 安装Docker(2020最新亲测可用,直接复制粘贴即可)
  10. 从Facebook的新设计中窥探他们如何运用CSS技巧