Android Multimedia框架总结(十)Stagefright框架之音视频输出过程
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52560012
前言:上篇文中最后介绍了数据解码放到Buffer过程,今天分析的是stagefright框架中音视频输出过程:
先看下今天的Agenda:
- 一张图回顾数据处理过程
- 视频渲染器构建过程
- 音频数据到Buffer过程
- AudioPlayer在AwesomePlayer运行过程
- 音视频同步
- 音视频输出
- 一张图看音视频输出
一张图回顾数据处理过程
视频渲染器构建过程
在构造时,new AweSomeEvent时,就开始把AwesomePlayer把onVideoEvent注入进去。
以上代码最会调用initRenderer_l函数
从上面代码来看:AwesomeRemoteRenderer的本质由OMX::createRenderer会先建立一个hardware renderer就是:mVideoRenderer =
new AwesomeNativeWindowRenderer(mNativeWindow, rotationDegrees);若失败,则建立new AwesomeLocalRenderer(mNativeWindow, format);
接下来看下:
而另一个AwesomeLocalRenderer在构造时new SoftwareRenderer(nativeWindow)
AwesomeLocalRender的本质上是由OMX:createRenderer,createRenderer会建立一个渲染器。如果video decoder是software component,则建立一个AwesomeLocalRenderer作为mVideoRenderer
AwesomeLocalRenderer的constructor会呼叫本身的init函数,其所做的事和OMX::createRenderer一模一样。可以理解为把read的数据显示在渲染器中。
渲染器渲染出画面后,我们可能会想,MediaExtractor把音视频进行分开,那音频呢?谁来让他们保持同步的呢?
音频数据到Buffer过程
无论是音频也好,还是视频,都是bufferdata,音频或视频总有一个来维持时间线的流。举个例子:我们看过双簧,一个人说话,一个人演示动作,动作快了不行,话说快,动作跟不上也不行。中间在联系台词时,自然有一些停顿或暗号。在OpenCore中,设置了一个主clock,而audio和video就分别以此作为输出的依据。而在Stagefright中,audio的输出是透过callback函式来驱动,video则根据audio的timestamp来做同步。在这之前,我们得了解下音频相关playback过程:
Stagefright框架中,audio的部分是交由AudioPlayer来处理,它是在AwesomePlayer::play_l中被建立的。贴一段以前分析过的代码:只不过当时没有向AudioPlayer方向向下看
创建AudioPlayer
再接着看下startAudioPlayer_l函数,
接下来看下音频mAudioPlayer->start(true)的操作,上面的过程都是在AwesomePlayer中,接下来变到AudioPlayer.cpp类中:
这里首先要介绍一下mAudioSink ,当mAudioSink不为NULL的时候,AudioPlayer会将其传入构造函数。
而且AudioPlayer中的播放操作都会依考mAudioSink来完成。
此处mAudioSink是从MediaPlayerService注册而来的AudioOut对象。具体代码在MediaPlayerservice中
间接地调用到stagefrightplayer->setAudioSink,最终到awesomeplayer中,如下:
而构造AudioPlayer时用到的就是mAudioSink成员,因此后面分析传入的mAudioSink的操作时,记住实际的对象为AudioOut对象,在MediaPlayerService定义。
本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52560012
AudioPlayer在AwesomePlayer运行过程
下面看AudioPlayer构造函数
主要是进行初始化,并将传入的mAudioSink存在成员mAudioSink中
再回到上面的start函数中
总结如下:
- 调用mSource->read 启动解码,解码第一帧相当于启动了解码循环
- 获取音频参数:采样率、声道数、以及量化位数(这里只支持PCM_16_BIT)
- 启动输出:这里若mAudioSink非空,则启动mAudioSink进行输出,否则构造一个AudioTrack进行音频输出,这里AudioTrack是比较底层的接口 AudioOut是AudioTrack的封装。
- 在start方法中主要是调用mAudioSink进行工作,主要代码如下:
刚介绍过mAudioSink是AudioOut对象,看下实际的实现(代码在mediaplayerservice.cpp中)
首先mAudioSink->open 需要注意的是传入的参数中有个函数指针 AudioPlayer::AudioSinkCallback ,其主要作用就是audioout播放pcm的时候会定期调用此回调函数填充数据,具体实现如下
以上代码总结为:
- 1、处理传入的参数,回调函数保存在mCallback中, cookie代表的是AudioPlayer对象指针类型,接下来是根据采样率声道数等计算 frameCount。
- 2、构造AudioTrack对象,并且赋值给t
- 3、将audiotrack对象存储在mTrack成员中
当以上过程完成后,继续分析AudioPlayer.start函数时,最后都会实例化一个AudioTrack对象,然后获取帧大小,比特等信息,然后调用mAudioTrack.start,最后到达mediaplayerservice音频输出start函数。
调用mTrack->start,audiotrack启动后就会周期性的调用 回调函数从解码器获取数据.
本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52560012
音视频同步
回到我们前面的问题:音视频如何同步?通过fillBuffer,不断填充buffer。
代码如下:
以上代码总结为:当callback函数回调AudioPlayer读取解码后的数据时,AudioPlayer会取得两个时间戳:mPositionTimeMediaUs和mPositionTimeRealUs,mPositionTimeMediaUs是数据里面所持有的时间戳(timestamp);mPositionTimeRealUs则是播放此数据的实际时间(依据frame number及sample rate得出)。
以上代码总结为:
- 在构造audioplayer的时候会执行mTimeSource = mAudioPlayer,
即将AudioPlayer作为参考时钟, - 上述代码中成员变量mSeekTimeUs是由如下语句获得:CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &timeUs));
- realTimeOffset = getRealTimeUsLocked() - mPositionTimeRealUs; 当显示画面是第一帧时,表示当前的audio的播放时间与第一帧video的时间差值
- 其中变量是通过mAudioPlayer->getMediaTimeMapping( int64_t *realtime_us, int64_t *mediatime_us) {
Mutex::Autolock autoLock(mLock)得到
二者的差值表示这一包pcm数据已经播放了多少。Stagefright中的video便依据从AudioPlayer得出来之两个时间戳的差值,作为播放的依据
音视频输出
最后回到本文开头的onVideoEvent方法中,
这样最终音视频数据通过渲染器就到Surface显示画面,就可看到视频和听到声音了。
本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52560012
一张图看音视频输出
第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。
如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易
Android Multimedia框架总结(十)Stagefright框架之音视频输出过程的更多相关文章
- Android多媒体框架总结(1) - 利用MediaMuxer合成音视频数据流程分析
场景介绍: 设备端通过服务器传向客户端(Android手机)实时发送视频数据(H.264)和音频数据(g711a或g711u), 需要在客户端将音视频数据保存为MP4文件存放在本地,用户可以通过APP ...
- Android IOS WebRTC 音视频开发总结(七十)-- 移动端音视频技术优化的七个方向
最近直播很火,很多朋友对背后的技术比较感兴趣,所以今天我们整理一篇关于移动端视频优化的文章,这篇文章是我朋友在一个技术大会上分享过的,更多内容请关注我们的微信公众号:rtcblacker 视频直播为什 ...
- 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)
随笔分类 - webrtc Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...
- 堪称教科书级别的Android音视频入门进阶学习手册,开源分享!
概述 随着整个互联网的崛起,数据传递的形式也在不断升级变化,总的流行趋势如下: 纯文本的短信,QQ -> 空间,微博,朋友圈的图片文字结合 -> 微信语音 -> 各大直播软件 -&g ...
- Android Multimedia框架总结(十五)Camera框架之Camera2补充
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52751055 前言:监于5.0之 ...
- Android Multimedia框架总结(九)Stagefright框架之数据处理及到OMXCodec过程
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼:http://blog.csdn.net/hejjunlin/article/details/52532085 不知不觉到第九篇了,感觉还有 ...
- Android Multimedia框架总结(八)Stagefright框架之AwesomePlayer及数据解析器
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼:http://blog.csdn.net/hejjunlin/article/details/52503057 前言:前面一篇分析了medi ...
- Android Multimedia框架总结(二十四)MediaMuxer实现手机屏幕录制成gif图
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53866405 前言:上篇中,介绍 ...
- Android Multimedia框架总结(十一)CodeC部分之AwesomePlayer到OMX服务
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52623882 前言:上篇文< ...
随机推荐
- [HNOI2011]卡农
题目描述 众所周知卡农是一种复调音乐的写作技法,小余在听卡农音乐时灵感大发,发明了一种新的音乐谱写规则.他将声音分成 n 个音阶,并将音乐分成若干个片段.音乐的每个片段都是由 1 到 n 个音阶构成的 ...
- 洛谷mNOIP模拟赛Day2-星空
题目背景 pdf题面和大样例链接:http://pan.baidu.com/s/1cawM7c 密码:xgxv 命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷. 你来过,然后你走后,只留下星空. ...
- [BZOJ]3532: [Sdoi2014]Lis
Time Limit: 10 Sec Memory Limit: 512 MB Description 给定序列A,序列中的每一项Ai有删除代价Bi和附加属性Ci.请删除若干项,使得4的最长上升子序 ...
- 【Codeforces Round 418】An impassioned circulation of affection DP
C. An impassioned circulation of affection ...
- [BZOJ]2017省队十连测推广赛1 T2.七彩树
题目大意:给你一棵n个点的树,每个点有颜色,m次询问,每次询问一个点x的子树内深度不超过depth[x]+d的节点的颜色数量,强制在线.(n,m<=100000,多组数据,保证n,m总和不超过5 ...
- PTA 字符串关键字的散列映射(25 分)
7-17 字符串关键字的散列映射(25 分) 给定一系列由大写英文字母组成的字符串关键字和素数P,用移位法定义的散列函数H(Key)将关键字Key中的最后3个字符映射为整数,每个字符占5位:再用除留余 ...
- Linux必备操作vim
vim被称作为编辑器之神,那么在我们操作linux系统时,进行编辑操作有没有感觉心有余而力不足?今天我讲自己总结的一些vim的操作命令和大家进行一下分享,有不足之处还请指出. vim的三种模式大家还记 ...
- Android SDK下载安装及配置教程
2017年12月07日 13:33:32 4942 转载自:http://blog.csdn.net/dr_neo/article/details/49870587 Android开发环境搭建可以分为 ...
- text-align:center属性失效
text-align:center只对inline元素有效,失效的情况下 给它所有的子元素加上 display:inline-block即可 inline-block不兼容ie6
- CentOS6.8虚拟机安装及ORALCE安装记录
CENTOS6.8安装数据库及设置自启动脚本教程 作者:张欣橙 本文所需要的所有参数均位于文末附录中 一.新建虚拟机 选择下一步 选择下一步 选择稍后安装操作系统 选择LINUX 版本 CentOS ...