转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53386117
上一章介绍MediaCodec的说明及状态图,从今天开始,将深入源码中看看其过程,看下Agenda如下:
- 一张图看清MediaCodec从创建到start过程
- 补充MediaCodec基本用法
- MediaCodec中BufferInfo内部类:
- android_media_MediaCodec.cpp
- android_media_MediaCodec.h
一张图看清MediaCodec从创建到start过程(到jni部分)
补充MediaCodec基本用法
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。
MediaCodec中BufferInfo内部类:
本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53386117
MediaCodec和MediaPlayer在很多地方有相似之处,当java层调用MediaCodec.createByCodecName,MediaCodec.createDecoderByType,MediaCodec.createEncoderByType都会到达MediaCodec的构造,构造中都会调用native_setup,如下:
其中对应到有这么一段,相当于是作了一次映射
接着进入android_media_MediaCodec_native_setup函数
setMediaCodec函数如下:
接下来看下JMediaCodec的构造
以上几个步骤到得到MediaCodec对像后,就到达Java层调用MediaCodec.configure(format,surface,null,0)
通过获取format中map,就是一个hashmap,便利视频源的格式放到两个数组中,然后,再通过native_configure向下传递
本文出自逆流的鱼yuiop:
http://blog.csdn.net/hejjunlin/article/details/53386117
当调用start后,public native final void start();
JMediaCodec中start
最后看下对应jni的android_media_MediaCodec.h如下:
第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。
如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易