转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52629449

前言:上篇文中分析到AwesomePlayer到OMX服务,曾介绍到,OMX服务主要完成三个任务: NodeInstance列表的管理,NodeInstance的操作, 事件的处理。最后这个事件处理就是今天放大看的内容。要一步一步一Codec,事件传递必不可少,看下今天的Agenda:

  • OMXCodec与OMX callback事件的处理时序图
  • 如何从OMX中dispatch到OMXCodec(附时序图)
  • 缓冲区更新过程
  • onMessage回调

OMXCodec与OMX callback事件的处理时序图

OMXCodec与OMX callback事件的处理时序图:

从时序图看,首先我们要建立个OMXCodecObserver,该类是OMXCodec的内部类,在create函数中被创建,并把对应的OMXCodec加入都自己的观察范围内,具体代码如下:

framework/base/media/libstagefright/OMXCodec.cpp

其次初始化它的callback事件和事件的派发处理函数

OMX主要的callback事件有哪些呢?

在framework/base/media/libstagefright/omx/OMXNodeInstance.cpp中的kCallbacks函数有如下定义:

callback在哪定义呢?

看framework/base/media/libstagefright/omx/OMX.cpp中的

即每个component对应一组callback事件。

这些callback由哪些函数返回呢?具体的定义在framework/base/media/libstagefright/openmax/OMX_Core.h

有了callback事件,如何dispatch呢?其实我们在allocateNote函数已经定义好了我们的dispatch函数

mDispatchers.add(*node, new CallbackDispatcher(instance));

如何从OMX中dispatch到OMXCodec

有了oberser, callback event , callbackdispatcher,那么一个callback event 如何从OMX传到OMXCodec呢?

下面我们以emptybuffer流程来具体看下,时序图如下:

从时序图上看:首先mVideoSource->read,实际上就是调用了OMXCodec::read,对应代码如下:



接着调用drainInputBuffer,把输入通道中的所有输入缓存区,逐个传递给drainInputBuffer,即先把inputbuffer都读满,

然后一次性送给具体的component,让其慢慢解码,drainInputBuffer的实现如下:

以上代码总结为:

  • 第一次执行OMXCodec::read时的操作。
  • 当整个编解码流程运行起来之后,会面临着一个输入\输出缓冲区更新的问题。

缓冲区更新过程

输入缓冲区更新过程:

如果一个输入缓冲区数据被读取完了,OpenMAX会触发事件omx_message::EMPTY_BUFFER_DONE通知上层,

在这个事件处理流程中,会根据发送来的bufferid找到对应的输入缓冲区,

然后把这个缓冲区传递给drainInputBuffer,继续往下执行。

如下:

输出缓冲区更新过程:

  • 解码完毕后,OpenMAX组件触发omx_message::FILL_BUFFER_DONE,

    输出缓冲区会被传出交给上层使用(传递给surfaceflinger来显示),使用完后需要把这个缓存区重新交给OpenMax,
  • 上层使用完输出缓冲区后会调用MediaBuffer::release进行销毁,在这个接口中会把输出缓冲区的引用计数减1,
  • 然后调用signalBufferReturned,实际对应OMXCodec::signalBufferReturned接口,
  • 最后再下一层调用fillOutputBuffer,把这个缓冲区重新交给openMAX。

总结:这样就是通过第一次调用drainInputBuffers触发openMAX,然后后面依靠openMAX的事件驱动来完成数据的读取、解码操作。

下面我们用输出缓冲区为例,再放大下上面分析的流程:

openmax component解码完一帧之后,

会调用ppCallbacks->FillBufferDone,也就是调用了之前初始化好的OMX::OnFillBufferDone

接着看下CallbackDispatcher的post函数

接下来把这个msg开始分发出去

onMessage回调

在onMessage方法中,进行通知回去

通过调用OMXCodecObserver把msg通过onMessage函数接着传给OMXCodec。

代码如下:

通过上面的分析可以看到,虽然在OMX框架中 Input/OutPutPort上的buffer的生产和消费是异步,但是还是通过了一个Condition mBufferFilled来做同步。通过信号量机制来达到同步的目的。本质上是一个生产者/消费者模型。

第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。

如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易

Android Multimedia框架总结(十二)CodeC部分之OMXCodec与OMX事件回调流程的更多相关文章

  1. Android Multimedia框架总结(十一)CodeC部分之AwesomePlayer到OMX服务

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52623882 前言:上篇文< ...

  2. Android Multimedia框架总结(二十)MediaCodec状态周期及Codec与输入/输出Buffer过程(附实例)

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53183718 前言:前面几节都是 ...

  3. Android Multimedia框架总结(二十五)MediaProjection实现手机截屏(无须root)

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53966818 前言:一年半多以前 ...

  4. Android Multimedia框架总结(二十四)MediaMuxer实现手机屏幕录制成gif图

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53866405 前言:上篇中,介绍 ...

  5. Android Multimedia框架总结(二十二)MediaCodec中C++中创建到start过程及状态变换

    上一章介绍MediaCodec中创建到start过程(到jni部分),从今天开始,将深入源码中看看其c++过程,看下Agenda如下: mediacodec.h CreateByType initMe ...

  6. Android Multimedia框架总结(二十三)MediaCodec补充及MediaMuxer引入(附案例)

    请尊重分享成果,转载请注明出处,本文来自逆流的鱼yuiop,原文链接:http://blog.csdn.net/hejjunlin/article/details/53729575 前言:前面几章都是 ...

  7. Android Multimedia框架总结(二)MediaPlayer框架及播放网络视频案例

    前言:前面一篇我们介绍MediaPlayer相关方法,有人说,没有实际例子,看得不是很明白,今天在分析MediaPlayer时,顺带一个播放网络视频例子.可以自行试试.今天分析的都是下几篇介绍各个模块 ...

  8. Android Multimedia框架总结(二十一)MediaCodec中创建到start过程(到jni部分)

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53386117 我最近正在参加CS ...

  9. Android Multimedia框架总结(十三)CodeC部分之OpenMAX框架初识及接口与适配层实现

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52629598 前言:上篇中介绍O ...

随机推荐

  1. poj 1012——Toseph

    提交地址:http://poj.org/problem?id=1012                                                                 ...

  2. [HNOI 2010]Bounce 弹飞绵羊

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...

  3. [CQOI 2010]扑克牌

    Description 你有n种牌,第i种牌的数目为ci.另外有一种特殊的 牌:joker,它的数目是m.你可以用每种牌各一张来组成一套牌,也可以用一张joker和除了某一种牌以外的其他牌各一张组成1 ...

  4. ●BZOJ 2588 Spoj 10628. Count on a tree

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2588 题解: 主席树,在线,(求LCA)感觉主席树真的好厉害...在原树上建主席树.即对于原 ...

  5. ●BZOJ 3996 [TJOI2015]线性代数

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=3996 题解: 好题啊.(不太熟悉矩阵相关,所以按某些博主的模型转换来理解的)首先,那个式子可 ...

  6. quartzJob 例子

    KpiOfPoorQualityJob.javapackage com.eastcom_sw.inas.workorder.quartzJob.kpi; import net.sf.json.JSON ...

  7. 12_Python的(匿名函数)Lambda表达式_Python编程之路

    Python作为一门高级语言,与很多编程语言一样都具有匿名函数这一特征 匿名函数,也就Lambda表达式,通俗来讲就是不用命名的方法,直接定义,直接用即可 创建匿名函数需要用到Lambda关键字,下面 ...

  8. Windows下createfile函数用GENERIC_READ访问模式打不开磁盘

    这两天做毕设,快气死了!想读写磁盘扇区,我就百度了,都是这样写的: HANDLE hDevice = CreateFile(TEXT("\\\\.\\PhysicalDrive1" ...

  9. David MacKay:用信息论解释 '快速排序'、'堆排序' 本质与差异

    这篇文章是David MacKay利用信息论,来对快排.堆排的本质差异导致的性能差异进行的比较. 信息论是非常强大的,它并不只是一个用来分析理论最优决策的工具. 从信息论的角度来分析算法效率是一件很有 ...

  10. Printer for Me

    今天,良心系部终于给我配了打印机^^. 办公室门外还挂了牌子.