打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【转】 Android通过软解码播放视频

Android通过软解码播放视频

    一般情况下Android的平台都是硬解码视频的,尤其是在Arm平台这种成熟的硬件平台上面(硬解码代码由芯片厂商提供)。但是Android移植到MIPS平台时间还不长,还不成熟,还需要自己实现硬件解码的工作。为了早日让Android在MIPS平台运行起来,我选择了先用软解码播放视频。

     我的Android代码是从Android on MIPS社区获得的代码。发现软解码视频播放过程中会发生崩溃。经过分析好像是内存分配的问题。

     经过研究OpenCore库(Android框架是通过OpenCore来播放视频的,网上有很多关于OpenCore的介绍,这里就不多说了),并参考Android平台——Surfaceflinger机制。发现问题出在源文件:

frameworks/base/libs/surfaceflinger/LayerBuffer.cpp

的LayerBuffer::BufferSource::postBuffer方法中:

............buffer = new LayerBuffer::Buffer(buffers, offset);............

类LayerBuffer::Buffer的构造函数代码如下:

LayerBuffer::Buffer::Buffer(const ISurface::BufferHeap& buffers, ssize_t offset): mBufferHeap(buffers){NativeBuffer& src(mNativeBuffer);src.img.handle = 0;gralloc_module_t const * module = LayerBuffer::getGrallocModule();if (module && module->perform) {int err = module->perform(module,GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER,buffers.heap->heapID(), buffers.heap->getSize(),offset, buffers.heap->base(),&src.img.handle);if (err == NO_ERROR) {src.crop.l = 0;src.crop.t = 0;src.crop.r = buffers.w;src.crop.b = buffers.h;src.img.w       = buffers.hor_stride ?: buffers.w;src.img.h       = buffers.ver_stride ?: buffers.h;src.img.format  = buffers.format;src.img.base    = (void*)(intptr_t(buffers.heap->base()) + offset);}}}

LayerBuffer::getGrallocModule方法的调用到的Gralloc为:

hardware/libhardware/modules/gralloc/gralloc.cpp

因为的没有实现在自己的硬件只能用通用的Gralloc,经过分析发现通用的Gralloc没有实现module->perform函数指针,module->perform为NULL,所以不会对Buffer进行必要的初始化(我觉得应该是一个疏忽,只是不知道是谷歌的疏忽,还是MIPS移植人员的疏忽,最起码应该能够让通用硬件能跑起来)。参考其他的硬件实现一个perform函数指针到通用Gralloc中。

     在源文件:

hardware/libhardware/modules/gralloc/mapper.cpp

增加如下的函数定义:

int gralloc_perform(struct gralloc_module_t const* module,int operation, ... ){int res = -EINVAL;va_list args;va_start(args, operation);switch (operation) {case GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER: {int fd = va_arg(args, int);size_t size = va_arg(args, size_t);size_t offset = va_arg(args, size_t);void* base = va_arg(args, void*);native_handle_t** handle = va_arg(args, native_handle_t**);private_handle_t* hnd = (private_handle_t*)native_handle_create(private_handle_t::sNumFds, private_handle_t::sNumInts);hnd->magic = private_handle_t::sMagic;hnd->fd = fd;hnd->flags = private_handle_t::PRIV_FLAGS_USES_PMEM;hnd->size = size;hnd->offset = offset;hnd->base = intptr_t(base) + offset;hnd->lockState = private_handle_t::LOCK_STATE_MAPPED;*handle = (native_handle_t *)hnd;res = 0;break;}}va_end(args);return res;}

然后在gralloc.cpp中增加,gralloc_perform的声明:

extern int gralloc_perform(struct gralloc_module_t const* module,int operation, ... );

并修改HAL_MODULE_INFO_SYM的定义,增加perform字段的定义:

struct private_module_t HAL_MODULE_INFO_SYM = {base: {.......perform: gralloc_perform,},......};

     重新编译gralloc模块,再次用Gallary应用程序通过软解码播放视频,就可以流畅的播放了,软解码的效率挺高的,没有卡的感觉!赞一个。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
显示Gralloc模块分配内存(buffer
Android6.0 显示系统(四) 图像显示相关
用C++为nodejs 写组件,提高node处理效率
Android HAL的被调用流程
GUI系统之SurfaceFlinger(6)BufferQueue中的缓冲区分配
ion orphaned memory
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服