Android MediaCodec 状态(States)转换分析
*由于工作需要,需要利用MediaCodec实现Playback及Transcode等功能,故在学习过程中翻译了Google官方的MediaCodec API文档,由于作者水平限制,文中难免有错误和不恰当之处,望批评指正。
*转载请注明出处:http://www.cnblogs.com/roger-yu/
概述
在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 子状态。
其他情况下均与同步模式下相同,就不在此赘述。
微信扫一扫,关注玖零日记,获取更多相关资讯及源码 -- 虽无面朝大海,依旧春暖花开

Android MediaCodec 状态(States)转换分析的更多相关文章
- Android MediaCodec的数据处理方式分析
*由于工作需要,需要利用MediaCodec实现Playback及Transcode等功能,故在学习过程中翻译了Google官方的MediaCodec API文档,由于作者水平限制,文中难免有错误和不 ...
- Android Multimedia框架总结(二十)MediaCodec状态周期及Codec与输入/输出Buffer过程(附实例)
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53183718 前言:前面几节都是 ...
- Java线程Thread的状态解析以及状态转换分析 多线程中篇(七)
线程与操作系统中线程(进程)的概念同根同源,尽管千差万别. 操作系统中有状态以及状态的切换,Java线程中照样也有. State 在Thread类中有内部类 枚举State,用于抽象描述Java线程的 ...
- [Android]Android系统启动流程源码分析
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/5013863.html Android系统启动流程源码分析 首先 ...
- Linux网络地址转换分析
Linux网络地址转换分析 地址转换用来改变源/目的端口,是netfilter的一部分,也是通过hook点上注册相应的结构来工作. Nat注册的hook点和conntrack相同,只是优先级不同,数据 ...
- SSH框架之-hibernate 三种状态的转换
一.遇到的神奇的事情 使用jpa操作数据库,当我使用findAll()方法查处一个List的对象后,给对这个list的实体进行了一些操作,并没有调用update 或者 saveOrUpdate方法,更 ...
- Android:日常学习笔记(2)——分析第一个Android应用程序
Android:日常学习笔记(2)——分析第一个Android应用程序 Android项目结构 整体目录结构分析 说明: 除了APP目录外,其他目录都是自动生成的.APP目录的下的内容才是我们的工作重 ...
- Android A/B System OTA分析(一)概览【转】
本文转载自:https://blog.csdn.net/guyongqiangx/article/details/71334889 Android从7.0开始引入新的OTA升级方式,A/B Syste ...
- Gradle之Android Gradle Plugin 主要 Task 分析(三)
[Android 修炼手册]Gradle 篇 -- Android Gradle Plugin 主要 Task 分析 预备知识 理解 gradle 的基本开发 了解 gradle task 和 plu ...
随机推荐
- Mashup
简介 mashup是糅合,是当今网络上新出现的一种网络现象,将两种以上使用公共或者私有数据库的web应用,加在一起,形成一个整合应用.一般使用源应用的API接口,或者是一些rss输出(含atom)作为 ...
- Expm 4_2 有向无环图中的最短路径问题
[问题描述] 建立一个从源点S到终点E的有向无环图,设计一个动态规划算法求出从S到E的最短路径值,并输出相应的最短路径. 解: package org.xiu68.exp.exp4; import j ...
- 深入浅出 JavaScript 关键词 -- this
深入浅出 JavaScript 关键词 -- this 要说 JavaScript 这门语言最容易让人困惑的知识点,this 关键词肯定算一个.JavaScript 语言面世多年,一直在进化完善,现在 ...
- mysql5.7安装教程图解
启动安装包: 左边是你电脑上可以连接到mysql的软件,比如Visual Studio,Eclipse,PyCharm等,中间是需求的版本或者额外组件,右边是状态. 选择一个选项,然后点击下面的che ...
- 分享一些 Java 无关基础方面的书籍
个人认为看书有两个点好处: 1. 能出版出来的书一定是经过反复思考,雕琢和审核的,因此从专业性的角度来说,一本好书的价值超其他资料 2. 对着书上的代码自己敲的时候方便 “看完书之后再次提升自我的最好 ...
- LeetCode(4):两个排序数组的中位数
Hard! 题目描述: 有两个大小为 m 和 n 的排序数组 nums1 和 nums2 . 请找出两个排序数组的中位数并且总的运行时间复杂度为 O(log (m+n)) . 示例 1: nums1 ...
- python接口自动化测试二十五:执行所有用例,并生成HTML测试报告
import requestsimport unittest class TestQQ(unittest.TestCase): '''测试QQ号接口''' # 此注释将展示到测 ...
- 如何用命令将本地项目上传到git,git基本使用
1.(先进入项目文件夹)通过命令 git init 把这个目录变成git可以管理的仓库 git init 2.把文件添加到版本库中,使用命令 git add .添加到暂存区里面去,不要忘记后面的小数点 ...
- 快速定位 Android APP 当前页面的三种方法(Activity / Fragment)
方法一.通过adb命令打印当前页面: Android 如何快速定位当前页面是哪个Activity or Fragment (1)查看当前Activity :adb shell "dumpsy ...
- #9 //[SDOI2017]新生舞会
题解: 分数规划+费用流 常数巨大开o2加inline加register还是不行 我也不知道为什么 代码: #include <bits/stdc++.h> using namespace ...