Android端实现TS流数据解析和Jni2Java回调

2018-06-21  本文已影响166人  Felix_lin

为了解析传输到手机的TS流有效视频数据,进行预览播放和录制等功能,在网上看到的部分关于android播放TS流,如UDP预览播放,采取的方式真是够标新立异,如通过保存到本地ts文件然后播放,会有闪屏现象等,当然也有很多的播放器支持播放,如ffmepg-android,vlc-android,vitamio等等。我感觉这些库要么太大,要么有很多都不满足我的需求,所以我自己尝试学习和通过jni调用c++去解析ts流

以下文章是我本文学习并参考的部分感觉非常不错的,希望大家学习时可以看看,方便全面学习:

一、TS流简介

  1. 什么是TS流 : TS(Transport Stream,传输流),全称则是MPEG2-TS,主要应用于实时传送的节目,如实时广播的电视节目,机顶盒等。它的主要格式分别为h264/mpeg4,acc/MP3等,MPEG2-TS格式的特点就是要求从视频流的任一片段开始都是可以独立解码的。

  2. 在学习TS流是需要了解的部分定义:

    • ES流:基本码流,不分段的音频、视频或其他信息的连续码流。
    • PES流:分包的ES流,通过添加PES头进行标记,PES包的长度是可变的
    • TS流:传输流,固定长度的封包(188B),便于解析和恢复错包,它包含三个部分:ts header、adaptation field、payload,如下图结构,ts header通过PID去识别数据包的内容,adaptation field为补充内容,payload即我们需要解析的pes数据。

    • 需要注意的是,一端TS流里面可能包含多个节目,这些在解析PAT和PMT时可以通过打印信息得到,在我代码里有注释,我的项目里固定只包含了一个,所以适配代码需要自己改动

  3. 解析TS流的重点在于理解他的表结构:解析TS流的流程主要是通过对应的PID去分布解析我们需要的信息,从而截取出对应的有效数据

    • 节目关联表Program Association Table (PAT) 0x0000,通过PAT我们可以解析对应的PMT表的PID
    • 节目映射表Program Map Tables (PMT) 在PMT中解析出对应的视频和音频的PID值
    • 条件接收表Conditional Access Table (CAT) 0x0001
    • 网络信息表Network Information Table(NIT) 0x0010
    • 部分参数或者结构说明我在代码注释中给出
    图片来源:https://www.cnblogs.com/jiayayao/p/6832614.html
  1. 解析流程:具体的对应结构在我上面列出的参考文章中都讲解的非常详细,本文主要写一个简单流程引导,做到一个快速集成到项目的目的
    1. 遍历TS流,通过同步字节查到ts header,sync byte: 1B,其值固定为0x47(需要考虑差错,buff拼接的情况)
    2. 获取PAT
    3. 根据PAT查询的PMT_PID查询对应的PMT的表
    4. 根据PMT查询对应的VEDIO_PID和AUDIO_PID
    5. 对应的PID解析视频和音频ParsePES
    6. 以下为解析流程结构图:


      2.png

二、TS流解析代码

本文给出的TS解析代码根据项目https://github.com/js2854/TSParser改动得来,该开源项目主要实现对TS文件的解析和各种信息的打印,我这边参考添加的改动:更改为TS流实现相应解析,增加的PES-音视频有效数据的解析,并通过jni输出到java层,添加android jni实现,数据缓存buff等,详细的方法都有部分注释,如有不明白,错误或侵权方面的问题请私信我,谢谢

三、数据处理过程

以下以H264视频数据处理为例:

  1. 初始化内存InitH264Memory()-->在fifo中存入空的数组ResetH264Buf()
  2. 从fifo中取出出GetEmptyH264Buf(),填入数据
    -->存入H264数据到fifo : PushYuvBuf(mfxBitstream * pbuf)
  3. 在线程中处理结果时:从H264数据fifo里取出:GetYuvBuf()
    --->处理完后数据置空再存入空的fifo里PushDirytH264Buf(mfxBitstream * pbuf)
  4. 处理结果线程结束:清理内存ReleaseH264Buf();

数据处理线程:

四、总结

在处理1080P的TS流数据时,测试从解析流到android硬解码预览显示,总延迟约140ms~200ms(晓龙835处理器),发现在硬解码部分耗时较大,有堵塞整个数据通道的嫌疑,具体优化方案在以后给出。

上一篇下一篇

猜你喜欢

热点阅读