android下视频文件从解码到播放需要
Android通过软解码播放视频
一般情况下Android的平台都是硬解码视频的,尤其是在Arm平台这种成熟的硬件平台上面(硬解码代码由芯片厂商提供)。但是Android移植到
MIPS平台时间还不长,还不成熟,还需要自己实现硬件解码的工作。 为了早日让Android在MIPS平台运行起来,我选择了先用软解码播放视频。
我的Android代码是从Android on MIPS社区获得的代码。发现软解码视频播放过程中会发生崩溃。 经过分析好像是内存分配的问题。
经过研究OpenCore库(Android框架是通过OpenCore来播放视频的,网上有很多关于OpenCore的介绍,这里就不...全部
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);
g。
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(),
& g。handle);
if (err == NO_ERROR) {
op。
l = 0;
op。t = 0;
op。r = buffers。w;
op。b = buffers。h;
g。w = buffers。hor_stride ?: buffers。
w;
g。h = r_stride ?: buffers。h;
rmat = rmat;
se = (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应用程序通过软解码播放视频,就可以流畅的播放了,软解码的效率挺高的,没有卡的感觉!。
收起