关于Android MediaCodec 的内容

原文:http://bigflake.com/mediacodec/

MediaCodec是一个可以对音视频数据进行编码和解码的Android类,本文给出代码范例并解答常见问题。

概述(可忽略)

Mediacodec类在Android 4.1(API 16)开始出现,目的是为了能够直接访问设备自带的编译码器,所以它提供的接口比较原始(raw),虽然Java和C++都有MediaCodec这个类,但Java的更常见。

在Android 4.3(API 18),MediaCodec新增了通过Surface对象提供输入的途径(createInputSurface),这样就可以由摄像头或OpenGL ES提交数据。同时Android 4.3 也是第一个在CTS(清除发送协议)下进行测试的版本,

Android 4.3同样介绍了新类MediaMuxer,MediaMuxer能够输出AVC格式(一种原始H.264基本流),不管有没有音频数据,AVC格式都可以在转换成MP4格式。

基本用法

MediaCodec的使用遵循一个基本模式:
1.创建和配置MediaCodec对象
2.进行以下循环:
如果一个输入缓冲区准备好:
读取部分数据,复制到缓冲区
如果一个输出缓冲区准备好:
复制到缓冲区
3.销毁MediaCodec对象

一个MediaCodec对象可以对特定类型的数据(MP3音频或H.264视频)进行编码或解码。因为是在原始数据上操作,所以任何文件头(比如ID3 tags)必须被剔除,MediaCodec不与任何更高层次的内容交互,所以无法通过扬声器播放音频或者从网络接收视频流。它只将缓冲区数据读入,再输出到缓冲区。MediaCodec可以把大部分的外层数据去掉。

有些编解码器对Buffer非常挑剔。比如,Buffer必须满足特定的内存对其方式,或者某个最值尺寸,或者同时满足几点。为了更强的兼容性,编解码器从应用程序获取分配Buffer的权限。所以,不是装有数据的Buffer直接给MediaCodec,而是想MediaCodec请求一个Buffer,再把数据拷进去。

    这样好像和“zero-copy”原则相违背,但其实在大多数情况下并不需要拷贝,因为编译码器并不是非得拷贝或调整数据来满足要求(What?)。在某些情况下,你可以直接使用那个Buffer,比如直接从硬盘或网络读取数据到Buffer,所以拷贝不是必须的(这不就是拷贝吗?)

    MediaCodec的输入必须处理成特定的格式。H264视频编码的时候输入就是一帧数据,H264解码指的就是一个NAL单元。但你不可能一次只提交单个数据或数据在需要处理的时候才出现(待商榷),这样看起来,输入更像是一个流。实际上,编解码器在输出前同时拥有多个Buffer。

强烈推荐从下面的例子开始学习,而不是通过这篇文档(毛?)。

范例(略)

FAQ

1.如何播放MediaCodec用“video/avc"生成的视频流?
答:这是H.264原始流。Linux下的Totem Movie Player可能可以,但其他的都不行。还是要再用MediaMuxer生成一个MP4文件

2.当创建一个解码器时,调用MediaCodec.configure()会报IllgalStateException呢?
答:这通常是因为没有指定编码器要求的“mandatory keys“

3.视频解码器配置了,但不接受数据,怎么回事?
答:请看原文

4.我能把数据以流的方式交给解码器吗?
答:能也不能。注意包的边界。

5.对摄像头的输出编码进一个YUV Buffer,为什么颜色不对?
答:摄像头输出的颜色格式和MediaCodec编码器接收的输入是不一样的。

6. EGL_RECORDABLE_ANDROID标志是什么?
答:告诉EGL它创建的surface必须和视频编解码器兼容。没有这个标志,EGL可能会使用一个MediaCodec不能理解的Buffer

7.能使用ImageReader和MediaCodec一起吗?
答:不

8.编码视频时,必须设置一个时间戳吗?
答:是的。

9.大部分的例子都是在API 18下的,我在API 16下编解码,有什么需要知道的?
答:有些特性知道18才有,而且有些在API 16下很难用。

10.能在AOSP仿真器上使用MediaCodec吗?
答:也许。

11.为什么输出错乱(全零,太短)?
答:最主要的错误是没有调整ByteBuffer和limit value


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值