关于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有什么优势呢?
以上来自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仅为可行性论证,在连接到开始播放的速度上没有软解的快,当然也可能是没有优化,如果后期有这方面的需求可以花点时间上来优化。