Android通过软解码播放视频
来源:互联网 发布:怎么给淘宝店铺起名字 编辑:程序博客网 时间:2024/04/30 02:30
Android通过软解码播放视频,其实这个在源码目录hardware/msm7k/libgralloc和libgralloc-qsd8k已有实现,源码中的确没有。可以完全仿照该目录下进行更改。以下参考一篇文章,描述很详细,可以借鉴下。
参考:http://my.unix-center.net/~Simon_fu/?p=601
一般情况下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应用程序通过软解码播放视频,就可以流畅的播放了,软解码的效率挺高的,没有卡的感觉!赞一个。
- Android通过软解码播放视频
- Android通过软解码播放视频
- Android+FFmpeg+ANativeWindow视频解码播放
- Android中视频播放以及解码
- Android+FFmpeg+ANativeWindow视频解码播放
- Android本地视频播放器开发--视频解码
- Android本地视频播放器开发--视频解码
- Android本地视频播放器开发--视频解码
- Android本地视频播放器开发--视频解码
- 视频播放解码过程
- Android通过MediaPlayer实现播放视频实例
- Android 通过VideoView+MediaPlayer实现视频播放
- 通过Android实现VR视频的播放
- android下播放器(软解码YUV数据)视频输出方法总结
- Android 实时视频采集/编码/传输/解码/播放 方案调研
- Android利用mediacodec进行视频H264编码解码播放
- Android利用mediacodec进行视频H264编码解码播放
- Android利用mediacodec进行视频H264编码解码播放
- 设置 FTP / HTTP 访问 RAC ASM 磁盘组
- 1-9九个数字组成一个九位数 如果从左边起取出1个数字,需要能被1整除,取出两个数字组成的数能被2整除,取出三个数字组成的数能被3整除,依次类推
- Exists的妙用,大幅度提高查询速度
- 指针的一个应用
- Oracle 数据库安装步骤-图解
- Android通过软解码播放视频
- 了解NoSQL的必读资料
- 全自动安装雅黑字体
- 图片和文字对齐问题
- 将cooledit作为一个音频信号发生器(http://www.zsjys.net/JYJY/ShowArticle.asp?ArticleID=64)
- 一些Flex炫效果的网址
- Oracle中的decode/trunc/sign函数
- Struts之三:表单数据校验(All Input Is Evil)
- 获取目录文件数