|
关于PAD版本硬解隔行视频的总结和疑问
发表于 2016-1-15 15:53:17
浏览:7919
|
回复:9
打印
只看该作者
[复制链接]
楼主
本帖最后由 jingjin221 于 2016-1-28 09:51 编辑
这短时间在做一些关于ANDROID下视频硬解,基于RK3288 PAD版本SDK,总结如下!
第一:关于ANDROID下的A/V框架为STAGEFIRGHT,通调用OMX IL层来进行视频硬解,在具体的解码实现上分文了同步和异步两种方式,分别为OMXCodec(MediaPlayer)和ACodec(MediaCodec),需要对视频输出延时有高要求的同学建议用ACodec, 经过测试在1280x720@60p模式下ACodec比OMXCodec延时要低100ms
第二:我的视频输入源并不是标准的文件IO输入,而是通过SPI设备获取输入流(BUFFER输入),所以不能直接用ANDROID下的MediaExtractor,而是移植了LIBDVBPSI库,没有移植FFMEPG是因为FFMEPG太庞大研究都要研究好久,就直接放弃了FFMEPG,LIBDVBPSI只是一个解复用库(只适用于TS流)。后来查到资料好像ANDROID在4.0.3后就已经加入了对BUFFER流输入的支持,文件参照frameworks/av/media/stagfirght/cmd/stream.cpp.以后有机会再用吧
第三:在PAD的SDK上进行视频解码开发本身就是个错误!FIREFLY的工程师们已经把BOX上的强大的RK3288的解码功能阉割的差不多了,首先PAD版本在解码格式上就阉割了很多,不过我倒是不用关心,反正解封装我都是自己写代码。
第四:在解码能力上倒是没有阉割太多,就是不支持4K。在硬解上对我造成最大的困惑就是不能解码隔行视频,开始我是直接在JAVA层用MEDIACODEC来做,264,265都可以顺利解码,但是就是不能解码隔行视频。我又用同样的代码在BOX的SDK上跑,都是可以解码的!所以得出结论:应该是在A/V框架上有差异。于是放弃在JAVA层解码,全部在JNI下实现。STAGEFIRGHT下的AWESOMEPLAYER全是基于文件IO接口的输入流,所以就只有直接调用OMXCodec的API来解码,具体代码我已经发布在我的博客里,经过一段时间的折腾,终于可以解码播放了,但是奇了怪了,还是不支持隔行,我在解码后的NV12是直接交给ANDROID直接RENDER的,后来我吧解码后的NV12数据保存下来发现,NV12数据是对的,证明应该是直接RENDER NV12的时候出问题了,于是我采用软件NV12->RGB565再显示,成功了!但是太慢了,于是改为直接把nv12渲染到 surface(SOFTERENDER),速度提升的不是一个档次!本以为就此大功告成!但是,经过测试,我的这种凡是解码延时太高,比直接在JAVA层调用MEDIACODEC解码还高!当时还傻傻的以为MEDIACODEC和AWESOMPLAYER是一类货色!结果MEDIACODEC用的是ACodec,AWESOMPLAYER用的是OMXCodec。于是又在JNI下完成了基于MediaCodec的解码发现延迟确实是比AWESOMEPLAYER低,但是尼玛!还是不能解码隔行视频。
第五:那么问题确定了!就是该死的RENDER,在隔行模式下,为什么直接硬件RENDER不可以,SOFTRENDER就是可以!该死的FIREFLY工程师们究竟改了什么???
现在隔行的视频都通过SoftwareRenderer完成了,有一下两点疑问
第一:这里的SoftwareRenderer方式是属于AwesomeLocalRenderer里的直接渲染,这个过程是由显卡直接完成的吗?
第二:关于HardwareRenderer方式是属于AwesomeNativeWindowRenderer里的直接硬件Render,直接调用的mNativeWindow->queueBuffer(mNativeWindow.get(), buffer->graphicBuffer().get(), -1);来渲染,这种方式和上面的有什么区别呢?原理是
|
|