Android Multimedia框架总结(三)MediaPlayer中创建到setDataSource过程
转载请把头部出处链接和尾部二维码一起转载,本文出自:http://blog.csdn.net/hejjunlin/article/details/52392430
前言:前一篇的mediaPlayer框架,对于各个模块的关系,得先从核心类MediaPlayer铺开,同样看下今天的Agenda:
- MediaPlayer从create到setDisplay时序图
- MediaPlayer的create过程
- MediaPlayer的setDataSource过程
- MediaPlayer的setDisplay过程
今天分析的是从MediaPlayer创建到MediaPlayer调用setDataSource过程
以往总是把时序图放在最后总结,有些人觉得一上来没有个大概,无从下手,所以,先把时序图附上,一步一步对着时序图看看每个阶段经历的过程
MediaPlayer从创建到setDisplay时序图
MediaPlayer时序图一(create->setDataSource, 后面文章还有,暂且这么命名):
MediaPlayer的创建过程
当外部调用MediaPlayer.create(this,”http://www.xxx.mp4“)时,进入我们MediaPlayer的创建过程:
以上代码可以总结为:当MediaPlayer通过Create方式创建播放器时,内部new出MediaPlayer对象 ,并setDataSource,并做好prepare的动作。这时外面只须调用下start方法,音视频资源将能播放起来。
通常我们用通过构造MediaPlayer,然后自己setDataSource,prepare等操作。无论哪种都要先经过new MediaPlayer(),我们看下构造中做了什么操作:
注意这里有个EventHandler,虽然今天不是重点要说的,我们可以先了解下它:
接下来看native层如何创建一个mediaplayer,在说native_up之前,我们注意,一般加载so都是在静态代码块中, 在MediaPlayer中有一段静态代码块,用于初始jni相关,早于构造方法,在加载类时就执行。一般是全局性的数据,变量,可以放在这。这里是加载media_jni.so文件。
开始进入android_media_MediaPlayer.cpp分析,第一个方法,就是在java静态代码块调入的native_init:
被native层调用,就是反向调用,仅被使用EventHandler post事件回到主线程中,很多用post开头,基本都是post到主线程,用软引用指向原生的MediaPlayer,以便native代码是安全的,当MediaPlayer可在native释放,调到java中的实现部分如下:
以上就是native_init方法,可以看到,就是做了一些准备工作,获取一些方法,一些要用的成员变量。接着回到之前说的,create中MediaPlayer构造函数,有一个native_setup,在android_media_MediaPlayer.cpp找到对应方法:
可以看到会设置一些回调用的listener及创建c++中的MediaPlayer对象。
MediaPlayer的setDataSource过程
上面就是MediaPlayer的构造过程:构造后接下来要设置数据源,进而到了setDataSource操作,我们看下setDataSource做了什么操作:
先看看如果送的setDataSource中的uri是文件类型:
开始进入jni层,发现找不到android_media_MediaPlayer_setDataSource方法,可以发现有一个方法名对应映射方法声明:
以上这个方法名字映射,如果看过JNIEnv * 源码的话,对上面这些并不陌生,无非也是映射,不影响我们分析,在这里我们接下来要去找android_media_MediaPlayer_setDataSourceFD这个函数看看:
接着看process_media_player_call方法:
以上代码总结为:当 mp->setDataSource(fd, offset, length)方法后得到status后,对各种状态进行notify。有异常的直接抛出,这样也就不会影响mediaplayer后面的执行过程。
接下来看下以http/rtsp传入到jni中,在java层对应的nativeSetDataSource方法:
在jni中通过映射表,可对应到android_media_MediaPlayer_setDataSourceAndHeaders:
到此,setDataSource的过程就完成了。这里要注意两个点,一个是从Java->jni->c++正向调用过程(前面从java到native都是正向过程),一种是c++ -> jni -> java层过程(如 mp->setDataSource( httpService, pathStr, headersVector.size() > 0? &headersVector : NULL),那有人肯定会问了?这样来回调的好处是什么?
- 安全性,封装在native层的代码以so形式,破环性风险小
- 效率快,在运行速度上c++执行时间快,且底层也是c++写的。可以对复杂的渲染及对时间要求高的,放在native是最好不过的选择了。
- 连通性,正向调用将值进行传入,反向调用把处理过值通知回去。相当于一根管道一样。
MediaPlayer的setDisplay过程
接下来看下在setDataSource之后,开始进行mp.setDisplay(holder)
MediaPLayer.java -> setDisplay
对于2,同样在android_media_MediaPlayer.cpp找到其对应方法:
这里有几个概念要理解下:
- SurfaceTexture: SurfaceTexture是从Android3.0(API 11)加入的一个新类。这个类跟SurfaceView很像,可以从video decode里面获取图像流(image stream)。但是,和SurfaceView不同的是,SurfaceTexture在接收图像流之后,不需要显示出来。SurfaceTexture不需要显示到屏幕上,因此我们可以用SurfaceTexture接收来自decode出来的图像流,然后从SurfaceTexture中取得图像帧的拷贝进行处理,处理完毕后再送给另一个SurfaceView用于显示即可。
- Surface: 处理被屏幕排序的原生的buffer,Android中的Surface就是一个用来画图形(graphics)或图像(image)的地方,对于View及其子类,都是画在Surface上,各Surface对象通过Surfaceflinger合成到frameBuffer,每个Surface都是双缓冲(实际上就是两个线程,一个渲染线程,一个UI更新线程),它有一个backBuffer和一个frontBuffer,Surface中创建了Canvas对象,用来管理Surface绘图操作,Canvas对应Bitmap,存储Surface中的内容。
- SurfaceView: 这个可能经常被说起,在Camera,MediaRecorder,MediaPlayer中用来显示图像的。SurfaceView是View的子类,且实现了Parcelable接口且实现了Parcelable接口,其中内嵌了一个专门用于绘制的Surface,SurfaceView可以控制这个Surface的格式和尺寸,以及Surface的绘制位置。可以理解为Surface就是管理数据的地方,SurfaceView就是展示数据的地方。
- SurfaceHolder:顾名思义,一个管理SurfaceHolder的容器。SurfaceHolder是一个接口,可理解为一个Surface的监听器。
通过回调方法addCallback(SurfaceHolder.Callback callback )监听Surface的创建
通过获取Surface中的Canvas对象,并锁定之。所得到的Canvas对象
通过当修改Surface中的数据完成后,释放同步锁,并提交改变Surface的状态及图像,将新的图像数据进行展示。 - 而最后综合:SurfaceView中调用getHolder方法,可以获得当前SurfaceView中的Surface对应的SurfaceHolder,SurfaceHolder开始对Surface进行管理操作。这里其实按MVC模式理解的话,可以更好理解。M:Surface(图像数据),V:SurfaceView(图像展示),C:SurfaceHolder(图像数据管理)。MediaPlayer.java中setDisPlay的操作就是对将要显示的视频设预设置。
以上就是setDisPlay过程,java中setDisPlay最后一行,就是通过jni返回的Surface,时时做好更新准备。
第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。
如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易
Android Multimedia框架总结(三)MediaPlayer中创建到setDataSource过程的更多相关文章
- MediaPlayer中创建AudioTrack的过程
使用MediaPlayer播放音视频时,会创建AudioTrack对象用于播放音频数据.下面就来看看MediaPlayer创建AudioTrack的过程: 1.创建AudioTrack对象MediaP ...
- Android Multimedia框架总结(七)C++中MediaPlayer的C/S架构补充及MediaService介绍
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼,文章链接: http://blog.csdn.net/hejjunlin/article/details/52465168 前面一篇主要介绍 ...
- Android Multimedia框架总结(四)MediaPlayer中从Java层到C++层类关系及prepare及之后其他过程
转载请把头部出处链接和尾部二维码一起转载,本文出自:http://blog.csdn.net/hejjunlin/article/details/52420803 前言:在上篇中,分析了MediaPl ...
- Android Multimedia框架总结(六)C++中MediaPlayer的C/S架构
转载请把头部出处链接和尾部二维码一起转载,本文出自: http://blog.csdn.net/hejjunlin/article/details/52435789 前面几节中,都是通过java层调用 ...
- Android Multimedia框架总结(二十二)MediaCodec中C++中创建到start过程及状态变换
上一章介绍MediaCodec中创建到start过程(到jni部分),从今天开始,将深入源码中看看其c++过程,看下Agenda如下: mediacodec.h CreateByType initMe ...
- Android Multimedia框架总结(一)MediaPlayer介绍之状态图及生命周期
请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52349221 前言:从本篇开始,将进入Multimedia框架,包含 ...
- Android Multimedia框架总结(十五)Camera框架之Camera2补充
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52751055 前言:监于5.0之 ...
- Android Multimedia框架总结(十一)CodeC部分之AwesomePlayer到OMX服务
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52623882 前言:上篇文< ...
- Android Multimedia框架总结(九)Stagefright框架之数据处理及到OMXCodec过程
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼:http://blog.csdn.net/hejjunlin/article/details/52532085 不知不觉到第九篇了,感觉还有 ...
随机推荐
- 在windows下使用cmd命令全速下载百度云文件
在windows下使用cmd命令全速下载百度云文件 需要的工具BaiduPCS-GO(链接:https://pan.baidu.com/s/19Sn8gmNi_GZHJwUPu79DPg 密码:gqi ...
- 【LSGDOJ1383】修改回文 dp
题目描述 为了跟踪所有的牛,农夫JOHN在农场上装了一套自动系统. 他给了每一个头牛一个电子牌号 当牛走过这个系统时,牛的名字将被自动读入. 每一头牛的电子名字是一个长度为M (1 <= M & ...
- 【bzoj3173-最长上升子序列-一题两解】
这道题不就是简单的DP吗,BZOJ在水我!不,你是错的. ·本题特点: 不断向不同位置插入数字(按数字1,2,3,4,5,6……),需要求出每一次插入后的最长上升子序列. ·分析 ...
- POJ 3415 不小于k的公共子串的个数
Common Substrings Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 9248 Accepted: 3071 ...
- 例10-2 uva12169(扩展欧几里得)
题意:已知xi=(a*xi-1+b) mod 10001,且告诉你x1,x3.........x2*t-1,让你求出其偶数列 思路: 枚举a,然后通过x1,x3求出b,再验证是否合适 1.设a, b, ...
- Linux之软链接与硬链接
什么是链接? 链接简单说实际上是一种文件共享的方式,是 POSIX 中的概念,主流文件系统都支持链接文件. 它是用来干什么的? 你可以将链接简单地理解为 Windows 中常见的快捷方式(或是 OS ...
- 【python教程01】 编辑器
工欲善其事,必先利其器.学习python,首先应该安装好开发中使用的编辑器. 那么在这里说一下我们推荐的两款:sublime text && pycharm 为什么推荐这两款编辑 ...
- SQL Server 2008作业失败无法确定所有者是否有服务器访问权限
调用作业---错误提示内容 该作业失败. 无法确定所有者 WIN-3TH1KNIT12D\Administrator (拥有作业 Database_Backup.step1)是否有服务器访问权限 (原 ...
- mysql获取某个表的所有字段名
http://www.netingcn.com/mysql-column-name.html mysql安装成功后可以看到已经存在mysql.information_schema和test这个几个数据 ...
- gulp填坑记(一)
gulp是基于Node.js的自动任务运行器.可以自动完成html.image.css和js等文件的检测.检查.合并.压缩.格式化等,并监听文件在改动后重复指定的这些步骤. 一.首先,我全局安装了gu ...