转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼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. 原生JS面向对象方法实现万年历

    ###面向对象的方法实现万年历 实现思路:    1.创建构造函数constructor    ```    function Calender(main){         this.current ...

  2. DDCTF 2018线上赛writeup

    第一题: d4e8e1f4a0f7e1f3a0e6e1f3f4a1a0d4e8e5a0e6ece1e7a0e9f3baa0c4c4c3d4c6fbb9b2b2e1e2b9b9b7b4e1b4b7e3e ...

  3. mysql事务,视图,权限管理,索引,存储引擎(胖胖老师)

    1: 视图什么是视图    视图是一个虚拟表, 它的内容来源于查询的实表, 本身没有真正的数据;视图的作用    对于复杂的查询时,每次查询时都需要编写一些重复的查询代码让编写sql的效率低下, 为了 ...

  4. [HNOI2014]江南乐

    Description 小A是一个名副其实的狂热的回合制游戏玩家.在获得了许多回合制游戏的世界级奖项之后,小A有一天突然想起了他小时候在江南玩过的一个回合制游戏.    游戏的规则是这样的,首先给定一 ...

  5. slab机制

    1.内部碎片和外部碎片 外部碎片 什么是外部碎片呢?我们通过一个图来解释: 假设这是一段连续的页框,阴影部分表示已经被使用的页框,现在需要申请一个连续的5个页框.这个时候,在这段内存上不能找到连续的5 ...

  6. bzoj3126[Usaco2013 Open]Photo 单调队列优化dp

    3126: [Usaco2013 Open]Photo Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 374  Solved: 188[Submit] ...

  7. Chrome的First Paint

    前言 First paint 直译过来的意思就是浏览器第一次渲染(paint),在First paint之前是白屏,在这个时间点之后用户就能看到(部分)页面内容. 所以研究这个First Paint的 ...

  8. python2.7入门---简介&基础语法

    Python 是一个高层次的结合了解释性.编译性.互动性和面向对象的脚本语言,具有很强的可读性,相比其他语言经常使用英文关键字,其他语言的一些标点符号,它具有比其他语言更有特色语法结构.基于上述原因, ...

  9. 学生管理系统(SSM简易版)总结

    之前用 Servlet + JSP 实现了一个简易版的学生管理系统,在学习了 SSM 框架之后,我们来对之前写过的项目重构一下! 技术准备 为了完成这个项目,需要掌握如下技术: Java 基础知识 前 ...

  10. xadmin库的下载安装及奇葩报错的解决方法

    今天主要讲xadmin库的下载和安装的.......各种问题....... 先注明:我使用的是python3.6,Django2.0,所以xadmin也应该是2.0版本会比较适配. 所以这里先给个xa ...