关于Android5.0开放的Native-codec测试一文中有提到4.0通过OpenMAX AL接口实现硬解码。可以先从分析native-media这个sample开始,可以在ndk目录中找到。
- 首先调用Java_com_example_nativemedia_NativeMedia_createEngine ?创建引擎和output mix 对象。
- Java_com_example_nativemedia_NativeMedia_setSurface 将java层的Surface对象转为NativeWindow对象用于视频显示
- Java_com_example_nativemedia_NativeMedia_createStreamingMediaPlayer ?初始化data source、?audio sink、image video sink、media player等对象 ,注册AndroidBufferQueueCallback?StreamChangeCallback两个回调,调用enqueueInitialBuffers预填充部分初始数据。
- enqueueInitialBuffers中通过读取ts文件获取足够量的buffer用于初始化
- AndroidBufferQueueCallback 的注释:?register the callback from which OpenMAX AL can retrieve the data to play,程序回调这里说明可以读buffer开始播放了
MPEG2-TS是唯一支持的数据格式,那么相比mp4有什么优势呢?
MPEG2-TS(Transport Stream“传输流”;又称 MTS、TS)是一种传输和存储包含音效、视频与通信协议各种数据的标准格式,用于数字电视广播系统,如?DVB、ATSC、IPTV?等等。
MP4,全称MPEG-4 Part 14,是一种使用MPEG-4的多媒体电脑文件格式,扩展名为.mp4,以存储数字音频及数字视频为主。MP4至今仍是各大影音分享网站所使用主流,即使他们是在网站上多加一层Flash的影音拨放接口。因为MP4可以在每分钟约4MB的压缩缩率下提供接近DVD质量的影音效果。优点:压缩质量优转换容易,目前智能型手机录影文件,9成以上皆为mp4文件。
以上来自wikipedia,TS定位就是一个流格式,MP4定位为文件格式,尽管也存在.ts格式的文件。
那么播放RTMP这种流,是否可以再转为TS流给OpenMAX AL以支持硬解码RTMP?
理论上是可行的。rtmp协议中第一个音视频包就包含了重要的用以封装为TS格式的数据,SPS,PPS,AudioSpecificConfig。当然这里谈的肯定是H264+AAC这种组合。
如何封装?
实现了nginx-rtmp-module的大神@arut早就实现了这部分代码:
https://github.com/arut/nginx-rtmp-module/blob/master/hls/ngx_rtmp_mpegts.c
那你实现了么?
是的 ?Demo:http://www.nodemedia.cn/zh/client/nodemediaplayer/
性能如何?
测试视频还是《侏罗纪世界》预告片 转为rtmp流
ffmpeg -re -i jurassicworld-biggame_h1080p.mov -c copy -f flv rtmp://192.168.0.10/live/demo2
播放流畅,cpu占用10~20,主要是mediaserver这个进程。
后记:
使用硬解码的优势,当然是更低的CPU占用更省电,适合长期播放。如果有直播高清视频的需求720P以上,相比软解码就更有优势。据此判断,并不限于rtmp流,任何流格式只要能获得必需的参数都能转为ts流进行硬解码播放。
限制就是只能解码H.264+AAC这种组合,当然这也是非常常见且标准的格式。
另外本Demo仅为可行性论证,在连接到开始播放的速度上没有软解的快,当然也可能是没有优化,如果后期有这方面的需求可以花点时间上来优化。
原创文章,转载请注明: 转载自贝壳博客
本文链接地址: Android 4.0以上系统硬件解码RTMP流的一种方式