写在前面的话:
        不觉中已经在数码工作了十年有余,十年的青春、十年的汗水,如今即将离开,个中滋味难以言表!
以后可能不会在广电行业工作了,就用这个小程序,为自己十年的广电工作画上一个句号吧。
依旧是:版权没有 盗版不纠 欢迎转载。

本程序的功能:提取ts文件的视频I帧并显示输出,同时可以将I帧保存为yuv bmp格式的文件。
基本思路:
1、探测文件中ts包的长度 188?192?204?
2、将ts包拼装为section,解析pat section。
3、依据pat,解析所有的pmt section。
4、依据pmt,分析video pid是否合法。
5、将ts包拼装为pes,依据video pid获取video pes。
6、解析video pes,获取I帧。
7、使用ffmpeg解码I帧为 yuv bmp格式。
8、使用opencv显示yuv。

开发环境:
ubuntu-14.04-64位
gcc-4.8.4 
ffmpeg-3.0.0 
opencv-3.4.0
SlickEdit Pro 2016 感兴趣的可以参考:https://blog.csdn.net/maxzero/article/details/78728098

本章主要讲解如何将ts包拼装为section或pes包。依据的标准为ITU-T H.222.0建议书。

一、mpeg ts包的语法结构

1、ts包的长度有3种
     * 欧洲标准是 188B
     * 日本标准是 192B
     * 第三种是     204B 是在188B的基础上,加上16B的FEC(前向纠错).

2、相关字段解析
     * sync_byte  ts包的起始值,固定为0x47。
     * payload_unit_start_indicator 
       当传输流包有效载荷包含 PES 数据时: 
      1-指示此传输流包承载PES包的首字节。0-指示此传输流包不承载PES包的首字节。 
      当传输流包有效载荷包含 PSI 数据时: 
      1-指示此传输流包承载PSI分段的首字节,并存在pointer_field字段。
      0-指示此传输流包不承载PSI分段的首字节,不存在pointer_field字段。
    *data_byte 有效负载
    *pid 指示包有效载荷中存储的数据类型。
    *continuity_counter 连续性计数器。相同pid的ts包continuity_counter在0-15之间循环。可以用来判断是否丢包。

二、ts包拼装为section pes流程


为了图的简洁并未画出完整的ts header。已pat(pid=0)为例:
1、首先找到pid=0,payload_unit_start_indicator=1的ts包,该包为pat section的起始包,并记录continuity_counter的值n。
2、下一个包就应该是 pid=0,payload_unit_start_indicator=0 continuity_counter=n+1。
3、以此类推,当找到pid=0,payload_unit_start_indicator=1时,搜索结束。
4、去掉ts header将这些有效负载依次拼装起来就是完整的pat section。

说明:
1、对于section数据,我们拿到第一个ts包后,可以通过分析section头部的section_length字段获取section的总长度,
      并依据这个长度来接收剩余的section数据。
2、对于pes数据,其长度是可变的,只能依据上图描述的方法进行接收。

三、ts包的解析
重点注意:有效负载为0的情况和pointer_field字段即可。

int mpeg_tsp_packet_parse(transport_packet_t *ptspkt, uint8_t *data, uint32_t size, uint32_t type)
{uint8_t *ptr = data;if (NULL==ptr || NULL==ptspkt || size<MPEGTS_PACKET_SIZE) {print_err("ptspkt=%p data=%p size=%d\n", ptspkt, data, size);return -1;}ptspkt->sync_byte                    = ((ptr[0]));ptspkt->transport_error_indicator    = ((ptr[1]>>7));ptspkt->payload_unit_start_indicator = ((ptr[1]<<1) >> 7);ptspkt->transport_priority           = ((ptr[1]<<2) >> 7);ptspkt->pid                          = ((ptr[1]&0x1f)<<8) | ptr[2];ptspkt->transport_scrambling_control = ((ptr[3]&0xc0) >> 6);ptspkt->adaption_field_control       = ((ptr[3]&0x30) >> 4);ptspkt->continuity_counter           = ((ptr[3]&0x0f));if (0x47 != ptspkt->sync_byte) {print_err("sync_byte=0x%x\n", ptspkt->sync_byte);return -1;}if (1 == ptspkt->transport_error_indicator) {print_err("pid=0x%04x transport_error_indicator=0x%x\n", ptspkt->pid, ptspkt->transport_error_indicator);return -1;}ptr += 4;ptspkt->playload_offset += 4;/*处理adaption_field字段*/if (ptspkt->adaption_field_control==0x02 || ptspkt->adaption_field_control==0x00) {ptspkt->adaptation_field_length = ptr[0];ptspkt->playload_offset = 0;/*print_dbg("pid=0x%04x adaptation_field. no playload.\n", ptspkt->pid);*/return 0;}if (ptspkt->adaption_field_control == 0x03) {ptspkt->adaptation_field_length = ptr[0];ptr += (ptspkt->adaptation_field_length + 1);ptspkt->playload_offset += (ptspkt->adaptation_field_length + 1);}/*承载PSI/SI数据时才有pointer_field*/if (ptspkt->payload_unit_start_indicator==1 && MPEGTS_PACKET_TYPE_PSI==type) { ptspkt->pointer_field = ptr[0];ptr += 1;ptspkt->playload_offset += 1;}return 0;
}

mpeg2标准:https://download.csdn.net/download/maxzero/10402761
完整的代码:https://download.csdn.net/download/maxzero/10572383

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

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

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

  2. 从mpeg ts文件中提取I帧(2):pat pmt解析

    一.PAT用途 1.描述当前传输流中 PMT 的 PID 信息. 2.描述PMT,与SDT的对应关系. 3.program_number=0时为network pid即nit的pid,接收pmt时注意 ...

  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. 总结编程语言的空语句
  2. js实现横向跑马灯效果
  3. SEM那些被人混淆的事儿(已完结)
  4. ubuntu远程windows桌面
  5. Kubernetes与docker集群管理常见问题解析
  6. 单开双控_卧室或者楼梯灯怎么安装单联双控
  7. 前序遍历m-ary树_在Ruby中使用ary [start,length]- object进行数组元素分配
  8. [读书笔记]TCP/IP详解V1读书笔记-3
  9. 在周二正式发售前 新款MacBook Pro已开始向客户发货
  10. Is it cold in Shinjuku?
  11. 给dubbo接口添加白名单——dubbo Filter的使用
  12. 7-3 主从复制配置
  13. Java并发编程 ReentrantLock 源码分析
  14. springmvc中校验框架(hibernate)
  15. C语言程序的语法规范,C语言程序结构和语法规则
  16. [lammps安装教程]lammps并行版安装教程
  17. java输入小写字母_java中怎么实现从对话框输入一个大写字母将其转化为小写字母输出?...
  18. nginx静态图片路径映射
  19. 世界上最简单的会计书(现金流量表)
  20. 达内 Java 全套教程 NPM、PYPI、DockerHub 备

热门文章

  1. 弘辽科技:拼多多专属推广怎么设置时间。
  2. linux hexo使用教程,Linux下使用Hexo搭建github博客(示例代码)
  3. 当在浏览器中输入一个域名后,会发生什么
  4. oracle 朱志辉_甲骨文(Oracle)授权教育中心落户我校
  5. java时区问题_Java时区问题
  6. 《简明电路分析》——1.2节电学主要参数
  7. 【考研英语语法】冠词练习题
  8. 曲线救国--为Chrome安装Edge浏览器插件
  9. cesium学习笔记---经纬网
  10. 一个游戏账号竟卖到7.5万元!