Android MediaCodec 状态(States)转换分析
*由于工作需要,需要利用MediaCodec实现Playback及Transcode等功能,故在学习过程中翻译了Google官方的MediaCodec API文档,由于作者水平限制,文中难免有错误和不恰当之处,望批评指正。
*转载请注明出处:http://www.cnblogs.com/roger-yu/
=====================================================================================================
Android MediaCodec系列文章:
(一)Android多媒体--MediaCodec 中文API文档
(二)Android MediaCodec 的实例化方法
(三)Android MediaCodec 状态(States)转换分析
(四)Android MediaCodec的数据处理方式分析
=====================================================================================================
概述
在MediaCodec的生命周期内存在三种状态:Stopped, Executing or Released,其中
Stopped状态包含三种子状态:Uninitialized, Configured and Error
Executing状态包含三种子状态:Flushed, Running and End-of-Stream
由于MediaCodec在不同的数据处理模式下状态间的转换会有些许差别,故接下来我们分别对同步处理模式及异步处理模式下的状态转换做详细分析
同步模式下的状态转换(Synchronous Processing using Buffers)
首先我们先看一下状态转换的流程图,如下:
1. 当通过 MediaCodec.createByCodecName(...) or MediaCodec.
createDecoderByType(...) or MediaCodec.
createEncoderByType(...)三种方法中的任一种创建一个MediaCodec对象实例后,Codec将会处于 Uninitialized 状态;
2. 当你调用 MediaCodec.configure(...)方法对Codec进行配置后,Codec将进入 Configured 状态;
3. 之后可以调用 MediaCodec.start() 方法启动Codec,Codec会转入 Executing 状态,start后Codec立即进入 Flushed 子状态,此时的Codec拥有所有的input and output buffers,Client无法操作这些buffers;
4. 一旦第一个input buffer 出队列,也即Client通过调用 MediaCodec.dequeueInputBuffer(...)请求得到了一个有效的input buffer index, Codec立即进入到了 Running 子状态,在这个状态下Codec会进行实际的数据处理(解码、编码)工作,度过它生命周期的主要阶段;
5. 当输入端入队列一个带有 end-of-stream 标记的input buffer时(queueInputBuffer(EOS)),Codec将转入 End of Stream 子状态。在此状态下,Codec不再接受新的input buffer数据,但仍会处理之前入队列而未处理完的input buffer并产生output buffer,直到end-of-stream 标记到达输出端,数据处理的过程也随即终止;
6. 在 Executing状态下可以调用 MediaCodec.flush()方法使Codec进入 Flushed 子状态;
7. 在 Executing状态下可以调用 MediaCodec.stop()方法使Codec进入
子状态,可以对Codec进行重新配置;Uninitialized
8. 极少数情况下Codec会遇到错误进入 Error 状态,可以调用 MediaCodec.reset() 方法使其再次可用;
9. 当MediaCodec数据处理任务完成时或不再需要MediaCodec时,可使用 MediaCodec.release()方法释放其资源。
异步模式下的状态转换(ASynchronous Processing using Buffers)
首先我们先看一下状态转换的流程图,如下:
异步模式下状态转换与同步模式下大同小异,主要有两点区别:
1. 调用 MediaCodec.start() 方法启动Codec,Codec会直接转入 Running 子状态;
2. 当调用 MediaCodec.flash() 方法进入 Flushed 子状态后,必须调用 MediaCodec.start() 方法Codec才会进入 Running 子状态。
其他情况下均与同步模式下相同,就不在此赘述。
微信扫一扫,关注玖零日记,获取更多相关资讯及源码 -- 虽无面朝大海,依旧春暖花开