关于PAD版本硬解隔行视频的总结和疑问
本帖最后由 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);来渲染,这种方式和上面的有什么区别呢?原理是
Rockchip 3188 Android4.2的libstagefright/AwesomePlayer.cpp的代码里,我看过有好像反交错的代码。现在因为还没开始研究3288的,不知道是什么情况:
#if USE_DEINTERLACE_DEV
if (NULL == pfrmanager->deint) {
pfrmanager->deint = new deinterlace_dev();
if (NULL == pfrmanager->deint) {
pfrmanager->deintFlag = 0;
}
}
if (pfrmanager->deint) {
if (pfrmanager->deint->test()) {
pfrmanager->deintFlag = 0;
}
} else {
ALOGW("failed to open deinterlace device");
pfrmanager->deintFlag = 0;
}
#else
希望对你有用 Mimosa 发表于 2016-1-27 22:40
Rockchip 3188 Android4.2的libstagefright/AwesomePlayer.cpp的代码里,我看过有好像反交错的代码。现在因 ...
谢谢你
我这里是直接调用OMXCodec和ACodec的API来解码,并没有用AwesomePlayer的api来做,也没有用到FrameQueueManage的东西,看来街交错是OMX DL层进行了调用!
本帖最后由 jingjin221 于 2016-1-28 09:49 编辑
现在已改为全部SoftwareRenderer可以解码隔行视频了,SoftwareRenderer具体参考此链接http://blog.csdn.net/tung214/article/details/3776248
本帖最后由 Mimosa 于 2016-1-28 10:17 编辑
@jingjin221 SoftwareRenderer软件的情况,rochchip在3066和3188时候是OK的,链接里那种写法需要在系统内编译,可以使用dlopen加载符号,这样更通用和灵活些。但在其他一些平台上,比如以前的TI 4430,这个SoftwareRenderer可能是低效的做法。新版的VLC支持硬件解码和硬件渲染,似乎在RK平台上可以工作。
对于视频这种,一定不仅要硬件解码,而且要硬件渲染,不然效果不是最佳
Mimosa 发表于 2016-1-28 10:15
@jingjin221 SoftwareRenderer软件的情况,rochchip在3066和3188时候是OK的,链接里那种写法需要在系统内编 ...
所谓的SofewareRenderer,并不是NV12转成RGB,而是直接渲染NV12数据,这种最终是属于显卡来完成yuv转rgbd的吗?
还有一种是直接渲染,不懂其中原理! Mimosa 发表于 2016-1-28 10:15
@jingjin221 SoftwareRenderer软件的情况,rochchip在3066和3188时候是OK的,链接里那种写法需要在系统内编 ...
查看了代码,在omx层里返回了Graphic的数据和解码后的数据!直接渲染就是直接取omx里的Graphic的数据来渲染。而SoftewareRender是要自己吧NV12数据映射到Graphic再渲染! Mimosa 发表于 2016-1-27 22:40
Rockchip 3188 Android4.2的libstagefright/AwesomePlayer.cpp的代码里,我看过有好像反交错的代码。现在因 ...
谢谢你的提醒,以前看这段的时候没有注意,现在认真看了下,终于发现为什么在PAD版本下无法解码隔行视频的原因了,默认的播放器采用的AwesomPlayer,这里需要将iommu关掉,在FrameQueueManager里mPlayerExtCfg.use_iommu = 0;这时候这个地方就打开iep设备开始解码隔行视频了!
但不知为什么,我自己直接调用OMXCodec。也没有打开iep设备,还是可以解码呢???只是不能直接渲染,必须SoftwareRenderer,但是解码是正常的!难道,解码器里面他会自动识别此视频是否是隔行视频来进行自动打开??????? jingjin221 发表于 2016-1-29 15:40
谢谢你的提醒,以前看这段的时候没有注意,现在认真看了下,终于发现为什么在PAD版本下无法解码隔行视频 ...
解码归解码,反交错是解码后期处理 Mimosa 发表于 2016-1-29 20:17
解码归解码,反交错是解码后期处理
是的。3288的反交错是放在解码里的IEP面做的
页:
[1]