Android Multimedia框架总结(十二)CodeC部分之OMXCodec与OMX事件回调流程
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼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事件回调流程的更多相关文章
- Android Multimedia框架总结(十一)CodeC部分之AwesomePlayer到OMX服务
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52623882 前言:上篇文< ...
- Android Multimedia框架总结(二十)MediaCodec状态周期及Codec与输入/输出Buffer过程(附实例)
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53183718 前言:前面几节都是 ...
- Android Multimedia框架总结(二十五)MediaProjection实现手机截屏(无须root)
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53966818 前言:一年半多以前 ...
- Android Multimedia框架总结(二十四)MediaMuxer实现手机屏幕录制成gif图
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53866405 前言:上篇中,介绍 ...
- Android Multimedia框架总结(二十二)MediaCodec中C++中创建到start过程及状态变换
上一章介绍MediaCodec中创建到start过程(到jni部分),从今天开始,将深入源码中看看其c++过程,看下Agenda如下: mediacodec.h CreateByType initMe ...
- Android Multimedia框架总结(二十三)MediaCodec补充及MediaMuxer引入(附案例)
请尊重分享成果,转载请注明出处,本文来自逆流的鱼yuiop,原文链接:http://blog.csdn.net/hejjunlin/article/details/53729575 前言:前面几章都是 ...
- Android Multimedia框架总结(二)MediaPlayer框架及播放网络视频案例
前言:前面一篇我们介绍MediaPlayer相关方法,有人说,没有实际例子,看得不是很明白,今天在分析MediaPlayer时,顺带一个播放网络视频例子.可以自行试试.今天分析的都是下几篇介绍各个模块 ...
- Android Multimedia框架总结(二十一)MediaCodec中创建到start过程(到jni部分)
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53386117 我最近正在参加CS ...
- Android Multimedia框架总结(十三)CodeC部分之OpenMAX框架初识及接口与适配层实现
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52629598 前言:上篇中介绍O ...
随机推荐
- mysql之连接查询小作业
#数据准备drop table if exists class;create table class( class_no int(2) unsigned zerofill primary key ...
- Java IO(五)==>>重点
打印流:PrintStream与PrintWriter PrintStream 该类的定义如下: public class PrintStream extends FilterOutputStream ...
- [HEOI2015]兔子与樱花
Description 很久很久之前,森林里住着一群兔子.有一天,兔子们突然决定要去看樱花.兔子们所在森林里的樱花树很特殊.樱花树由n个树枝分叉点组成,编号从0到n-1,这n个分叉点由n-1个树枝连接 ...
- [HNOI2013]比赛
题目描述 沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛.此次联 赛共N支球队参加,比赛规则如下: (1) 每两支球队之间踢一场比赛. (2) 若平局,两支球队各得1分. (3) ...
- 51nod 1270 数组的最大代价
1270 数组的最大代价题目来源: HackerRank基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 数组A包含N个元素A1, A2......AN.数组B包含N ...
- [BZOJ]2589: Spoj 10707 Count on a tree II
Time Limit: 20 Sec Memory Limit: 400 MB Description 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v),你需要回答u xor last ...
- hdu 5438(拓扑+bfs)
题意:建图,删掉所有连接点小于2的点,直到不能删为止,问最后剩余的联通块中,点的数量是奇数的联通块中的点的权值和. 思路:拓扑删点,bfs计算 #include <iostream> #i ...
- Unique-paths (动态规划)
题目描述 A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below) ...
- spring cloud 入门系列二:使用Eureka 进行服务治理
服务治理可以说是微服务架构中最为核心和基础的模块,它主要用来实现各个微服务实例的自动化注册和发现. Spring Cloud Eureka是Spring Cloud Netflix 微服务套件的一部分 ...
- ubuntu + 不识别无线网卡简易处理方式 + 需有线联网
进入ubuntu, 连接有线网; 系统设置 -> 软件和更新 -> 附加驱动 -> 找到无线网卡驱动并更新 若无候选的无线网卡驱动,我就没招了.