Android硬编解码工具MediaCodec解析——从猪肉餐馆的故事讲起(二)

上篇回顾:


上一篇文章Android硬编解码利器MediaCodec解析——从猪肉餐馆的故事讲起(一)已经叙述了MediaCodec工作流程和工作周期状态机,今天开始进入实战,从代码角度详细解析MediaCodec。如果没有看过上篇,建议还是看下才能和本文无缝衔接。

MediaCodec代码实例


本次讲解的代码实例是Google官方MediaCodec的学习项目 grafika,grafika由多个demo组成,比如视频解码播放、实时录制视频并将视频编码为H264保存本地,录屏等功能,每个demo都有会侧重于某项技术。

以下为grafika的App首页,每一项代表一个demo:

今天,我们就从最基本的第一个demo讲起————解码一个本地MP4视频。

从gif可以看出,这是一个非常简单的视频,整个功能就是对mp4视频进行解码,然后将解码后的数据渲染到屏幕,对应的代码在com.android.grafika.PlayMovieActivity,基本流程结构图如下:

那么最核心的解码代码都在MoviePlayer中。

解复用代码解析


首先要明白的概念是复用,也可以叫做封装,即将已经压缩编码的视频数据和音频数据按照一定的格式打包到一起,比如热爱看片的我们都很熟悉的MP4,MKV,RMVB,TS,FLV,AVI,就是复用格式。

比如FLV格式的数据,是由H.264编码的视频码流和AAC编码的音频码流打包一起。

FLV复用格式是由一个FLV Header文件头和一个一个的Tag组成的。Tag中包含了音频数据以及视频数据。FLV的结构如下图所示(图来源于视音频数据处理入门:FLV封装格式解析

那么在解码视频之前,就必须先将H264视频数据从复用格式中取出来,Android平台已经提供了MediaExtractor这个工具让我们方便地进行解复用。

以下是官网提供的MediaExtractor使用代码模板:

MediaExtractorextractor=newMediaExtractor();
extractor.setDataSource(...);
intnumTracks=extractor.getTrackCount();

//遍历媒体复用文件中的每一条轨道数据流(音频或者视频流),得到我们需要处理的数据流的mime类型,并选中它

for (inti=0; i<numTracks; ++i) {

MediaFormatformat=extractor.getTrackFormat(i);

Stringmime=format.getString(MediaFormat.KEY_MIME);

if (weAreInterestedInThisTrack) {

//选中我们需要处理的数据流的mime类型的数据流

extractor.selectTrack(i);

}

}

ByteBufferinputBuffer=ByteBuffer.allocate(...)

//循环读取选中的音频或者视频流到inputBuffer中

while (extractor.readSampleData(inputBuffer, ...) >=0) {

inttrackIndex=extractor.getSampleTrackIndex();

longpresentationTimeUs=extractor.getSampleTime();

...

extractor.advance();

}

extractor.release();

extractor=null;

注释已经写的比较详细了,基本能看懂。

首先了解下MediaFormat,它是一个专门描述媒体文件格式的类,内部通过一系列键值对来描述媒体格式,比如通用的媒体格式KEY:

视频专有的格式KEY:

音频专有的格式KEY:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值