由于stagefright和openmax运行在两个不同的进程上,所以他们之间的通讯要经过Binder进行处理,本小结不考虑音频这一块,假设视频为MP4封装的AVC编码文件.

先简单的看一下stagefright是怎么工作的, stagefright使用event来进行驱动,event调度器和event运行在同一个线程中,播放器向队列插入event来驱动整个解码流程,event调度器的工作抽象流程如下:
1. 检测队列是否为空,为空则等待event的插入
2. 获取队列中的第一个event
3. 计算event所要求的delay time后进行延时操作
4. 将event从队列中剔除后执行该event
event调度器通过不断循环这样的过程来进行调度,在具体代码中还会根据特殊情况进而改变调度过程,目前event事件有如下几种:
1. onVideoEvent
2. onStreamDone
3. onBufferingUpdate
4. onCheckAudioStatus
5. onPrepareAsyncEvent

stagefright的播放器类为AwesomePlayer,这个类主要有以下几个成员(排除Audio部分):
1. mVideoSource(解码视频)
2. mVideoTrack(从多媒体文件中读取视频数据)
3. mVideoRenderer(对解码好的视频进行格式转换,android使用的格式为RGB565)
4. mISurface(重绘图层)
5. mQueue(event事件队列)

stagefright运行时的抽象流程如下:

下面以一个mp4文件(avc编码)来分析AwesomePlayer的抽象工作流程(排除Audio部分)
1) 设置mUri为xxxx.MP4的绝对路径
2) 启动mQueue,这会创建一个线程来运行threadEntry,并命名为TimedEventQueue,这个线程就是event调度器
3) 打开mUri所指定的文件,xxxx.MP4文件的头部为(....ftypisom....),则会选择MPEG4Extractor来作为分离器
4) 使用MPEG4Extractor对MP4进行音视频轨道的分离,并返回MPEG4Source类型的视频轨道给mVideoTrack
5) 根据mVideoTrack中的编码类型来选择解码器,avc的编码类型会选择AVCDecoder (假设不使用OMX),并返回给mVideoSource,并设置mVideoSource中的mSource为mVideoTrack
6) 插入onVideoEvent到Queue中,开始解码播放
7) 通过mVideoSource对象来读取解析好的视频buffer
8) 如果解析好的buffer还没到AV时间戳同步的时刻,则推迟到下一轮操作
9) mVideoRenderer为空,则进行初始化,如果不使用OMX会将mVideoRenderer设置为AwesomeLocalRenderer
10) 通过mVideoRenderer对象将解析好的视频buffer转换成RGB565格式并发给display模块进行图像绘制
11) 将onVideoEvent重新插入event调度器来循环

OMX IL作为底层解码部件的集合层,为上层多媒体框架提供了统一的接口,在Android2.2的stagefright中, stagefright使用的是opencore中的OMX IL实现,使用该OMX IL框架需要将mVideoSource设置为OMXCodec类,OMX IL层的对外接口主要有以下几种:
1) stagefright使用OMX_MasterInit初始化OMX框架,加载component
2) stagefright使用OMX_MasterGetHandle匹配OMX中的component,匹配成功则返回OMX_HANDLETYPE用于OMXCodec与component之间进行通信
3) OMXCodec使用OMX_SendCommand来设置component的状态,操作component的port
4) OMXCodec使用EventHandler通知OMXCodec的Command执行结果
5) OMXCodec使用OMX_GetParameter和OMX_SetParameter来获取和设置component的属性参数
6) OMXCodec使用OMX_UseBuffer设置compoment使用的buffer为OMXCodec分配的buffer
7) OMXCodec使用OMX_EmptyThisBuffer传递未解码的buffer给component,用于解码
8) OMXCodec使用OMX_FillThisBuffer传递空的bffer给component用于存储解码后的帧
9) compoment使用EmptyBufferDone通知OMXCodec已完成inputport buffer的读取
10) compoment使用FillBufferDone通知OMXCodec已完成outputport buffer的填充
初始化流程如下:

OMX component的数据主要通过port来进行交互,port分为input和output , port通过和OMXCodec共享buffer来进行编解码,如下图:

buffer的处理主要由以下4个命令来进行驱动:
 OMXCodec使用OMX_EmptyThisBuffer传递未解码的buffer给component,component收到该命令后会读取input port buffer中的数据,将其组装成帧进行解码,读取buffer中的数据完成后会调用EmptyBufferDone通知OMXCodec
 compoment使用EmptyBufferDone通知OMXCodec已完成inputport buffer的读取, OMXCodec收到该命令后会通过mVideoTrack读取新的视频buffer到input port的buffer中,并调用OMX_EmptyThisBuffer通知component
 OMXCodec使用OMX_FillThisBuffer传递空的bffer给component用于存储解码后的帧,component收到该命令后将解码好的帧数据复制到该buffer上,然后调用FillBufferDone通知OMXCodec
 compoment使用FillBufferDone通知OMXCodec已完成outputport buffer的填充, OMXCodec收到该命令后将解码好的帧传递给mISurface进行图像绘制,绘制完毕后使用OMX_FillThisBuffer通知component有空的buffer可填充
抽象图如下:

OMX IL中的解码分成了两个部分,以AVC的解码为例:
1) 使用AssemblePartialFrames将input port的buffer组装成帧
2) 将帧传递给AvcDecoder_OMX进行解码后输出到output port的buffer中
如下图:

假设input port buffer中有2个buffer,分别为buffer_1和buffer_2,并且这两个buffer所携带的数据可构成1帧,则AssemblePartialFrames首先申请一块内存区域tmp_buffer_1,将buffer_1的有效数据拷贝到tmp_buffer_1上,然后再申请一块内存区域tmp_buffer_2,申请完后第一步将tmp_buffer_1的数据拷贝到自身的前半部,第二步将buffer_2的有效数据拷贝到后半部来组合成为1帧.
组合完成后将tmp_buffer_2和output port的buffer交给AvcDecoder_OMX进行解码, AvcDecoder_OMX将解码后的帧数据拷贝到output port buffer中.

stagefright omx小结的更多相关文章

  1. Android4.2.2下Stagefright下OMX编解码器组件的控制流

    本文均属自己阅读源代码的点滴总结.转账请注明出处谢谢. 欢迎和大家交流. qq:1037701636 email:gzzaigcn2012@gmail.com Android源代码版本号Version ...

  2. StageFright框架流程解读

    1.    StageFright介绍     Android froyo版本号多媒体引擎做了变动,新加入�了stagefright框架,而且默认情况android选择stagefright,并没有全 ...

  3. android媒体--stagefright概述【一】

    近期杂七杂八的忙碌着,前几天看了下这部分主要是stagefright模块的,所以更改下名字 做了挺长时间的android平台的媒体开发,对之前的分析进行一个阶段性的总结. 一.android结构图(上 ...

  4. Android多媒体开发-stagefright及AwesomePlayer相关知识梳理

    android的多媒体框架中, stagefright其实是AwesomePlayer的代理,就是个皮包公司. status_t StagefrightPlayer::setDataSource( c ...

  5. stagefright框架(四)-Video Buffer传输流程

    這篇文章將介紹Stagefright中是如何和OMX video decoder传送buffer. (1) OMXCodec會在一開始的時候透過read函式來傳送未解碼的data給decoder,並且 ...

  6. stagefright框架(三)-选择Video Decode

    在<Stagefright (1) – Video Playback的流程>中,我们并没有详述Stagefright是如何根据影片档的类型来选择适合的video decoder,现在,就让 ...

  7. stagefright框架(二)- 和OpenMAX的運作

    Stagefright的編解碼功能是利用OpenMAX框架,而且用的還是OpenCORE之OMX的實作,我們來看一下Stagefright和OMX是如何運作的. (1) OMX_Init OMXCli ...

  8. Android stagefright与opencore对比

      [转载至其它博客] http://blog.csdn.net/djy1992/article/details/9339917 1引言 Android froyo版本多媒体引擎做了变动,新添加了st ...

  9. Android4.2.2的Stagefright维护编解码器的数据流

    这里是他们自己的源代码阅读点滴总结属性,转请注明出处,谢谢. 欢迎和大家分享.qq:1037701636 email:gzzaigcn2012@gmail.com Android源代码版本号Versi ...

随机推荐

  1. Javascript进阶篇——(DOM—getAttribute()、setAttribute()方法)—笔记整理

    getAttribute()方法通过元素节点的属性名称获取属性的值.语法: elementNode.getAttribute(name) 1. elementNode:使用getElementById ...

  2. .net的WebForm模拟MVC进行模型绑定,让自己少操劳

    一.前言 用过MVC的兄弟们都知道,MVC有模型绑定表单提交的数据功能,那么我也想偷个懒也写个WebForm版的模型绑定.这里主要定义一个泛型方法,然后通过反射把表单上对应属性名字的值赋值到反射创建类 ...

  3. NFinal 视图—模板

    创建模板 1.新建Header.ascx用户控件,此控件就是模板,修改内容如下: <%@ Control Language="C#" AutoEventWireup=&quo ...

  4. WebApi2官网学习记录---Html Form Data

    HTML Forms概述 <form action="api/values" method="post"> 默认的method是GET,如果使用GE ...

  5. Mysql学习(慕课学习笔记3)数据类型

    数据类型 数据类型是指.存储过程参数.表达式和局部变量的数据特征, 它决定了数据的存储格式,代表了不同的信息类型. 整型 Tinyint      有符号位 -128到127   无符号位 0到255 ...

  6. 记“debug alipay”一事

    背景:客户支付成功,无法返回支付结果 ===================================== 查找原因,追踪代码: verified = AlipayNotify.verify(p ...

  7. 在windows下获取硬盘序列号(win7 32位,Windows Server 64位测试,希望在其他平台测试,遇到问题的网友留言分享)

    #include <Windows.h> #include <stdio.h> // IOCTL控制码 // #define DFP_SEND_DRIVE_COMMAND CT ...

  8. 异常处理:你不可能总是对的 - 零基础入门学习Python032

    异常处理:你不可能总是对的 让编程改变世界 Change the world by program 因为我们是人,不是神,所以我们经常会犯错.当然程序员也不例外,就算是经验丰富的码农,也不能保证写出来 ...

  9. iOS 断网处理

    iOS 断网处理 (2014-01-13 18:13:21) 转载▼ 标签: it   - (BOOL)application:(UIApplication *)application didFini ...

  10. oracle client server那点事

    oracle网络配置三个配置文件 listener.ora.sqlnet.ora.tnsnames.ora ,都是放在$ORACLE_HOME\network\admin目录下. 1.  sqlnet ...