作者:anddymao
背景
MediaCodec 作为Android自带的视频编解码工具,可以直接利用底层硬件编解码能力,现在已经逐渐成为主流了。API21已经支持NDK方法了,MediaCodec api设计得非常精妙,另一个方面也是很多人觉得不好懂。

内容
MediaCodec的两个Buffer和三板斧
MediaCodec内部包含InputBuffer和OutputBuffer,内部有一个自启线程,不断去查询两个Buffer,是一个生产者消费者模型。
进行数据处理时主要靠三板斧。
- 第一步:取buffer地址
AMediaCodec_dequeueInputBuffer
- 第二步:获取buffer数据
AMediaCodec_getInputBuffer
- 第三步:buffer入队
AMediaCodec_queueInputBuffer
InputBuffer和OutputBuffer基本是对称的:
- 第一步:取buffer地址
AMediaCodec_dequeueOutputBuffer
- 第二步:获取buffer数据
AMediaCodec_getOutputBuffer
- 第三步:buffer释放
AMediaCodec_releaseOutputBuffer
只有第三步不同,AMediaCodec_queueInputBuffer是数据入队等待消费,AMediaCodec_releaseOutputBuffer是释放数据。
编码和解码过程,InputBuffer和OutputBuffer就互相置换下。
解码:原始数据(视频流)-> 提取器AMediaExtractor->InputBuffer->OutputBuffer->帧数据(YUV420sp,PCM)
编码:帧数据(视频流)->InputBuffer->OutputBuffer->合成器AMediaMuxer
解码
解码配置
解码开始需要配置AMediaCodec和AMediaExtractor,MediaCodec start后就可以开始解码。
AMediaExtractor需要设置文件描述符,通过AAssetManager_open或者fopen就可以得到。起始点和长度也同样。然后设置进提取器。
AMediaExtractor_setDataSourceFd(mExtractor,
virtualFile.fd,
virtualFile.start,
virtualFile.length);
AMediaCodec创建需要设置数据格式,通过AMediaExtractor获取到的AMediaFormat可以得到mime和format。
mCodec = AMediaCodec_createDecoderByType(mime);
AMediaCodec_configure(mCodec, format, NULL, NULL, 0);
AMediaCodec_start(mCodec);
解码配置第三个参数为NativeWindow,加了后解码后可以直接吐到surface上,GPU数据直接渲软,效率高但不够灵活。不加的话解码数据就需要输出拷贝。
解码流程
解码也就是操作两个Buffer的过程,执行玩三板斧就可以,然后有一些状态需要处理。
if (!mInputEof) {
ssize_t bufidx = AMediaCodec_dequeueInputBuffer(mCodec, 1);
log_info(NULL, "input buffer %zd", bufidx);
if (bufidx >= 0) {
size_t bufsize;
uint8_t *buf = AMediaCodec_getInputBuffer(mCodec, bufidx, &bufsize);
int sampleSize = AMediaExtractor_readSampleData(mExtractor, buf, bufsize);
if (sampleSize < 0) {
sampleSize = 0;
mInputEof = true;
log_info(NULL, "video producer input EOS");
}
int64_t presentationTimeUs = AMediaExtractor_getSampleTime(mExtractor);
AMediaCodec_queueInputBuffer(mCodec, bufidx, 0, sampleSize, presentationTimeUs,

本文详细介绍了如何在Android NDK环境下使用MediaCodec进行视频的编解码操作。MediaCodec作为Android的硬件编解码工具,通过InputBuffer和OutputBuffer实现生产者消费者模型。解码时,数据从视频流经提取器AMediaExtractor进入MediaCodec,解码后的数据可以输出到surface或拷贝使用。编码过程则涉及渲染、编码和合成,需要将渲染后的数据编码成视频流并通过MediaMuxer写入文件。通过掌握MediaCodec的双缓冲和核心操作,可以更好地理解和应用视频编解码。
最低0.47元/天 解锁文章
615

被折叠的 条评论
为什么被折叠?



