转载请把头部出处链接和尾部二维码一起转载,本文出自: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过程相关推荐

  1. Android MultiMedia框架完全解析 - 概览

    之前的工作中,一直在看Android MultiMedia的一些东西,关注我博客的同学也许知道我换工作了,以后将要从事Camera相关的工作,于是乎,将之前整理存放在有道云笔记里面的一些东西发出来,整 ...

  2. 8. Android MultiMedia框架完全解析 - prepareAsync的过程分析

    还是从mediaplayer.cpp文件开始分析: status_t MediaPlayer::prepareAsync() {ALOGV("prepareAsync");Mute ...

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

    原址:http://blog.csdn.net/hejjunlin/article/details/53866405 前言:上篇中,介绍是用MediaMuxer与MediaExtractor进入音视频 ...

  4. Android Multimedia框架总结(十七)音频开发基础知识

    原文链接:http://blog.csdn.net/hejjunlin/article/details/53078828 近年来,唱吧,全民K歌,QQ音乐,等成为音频软件的主流力量,音频开发一直是多媒 ...

  5. 10. Android MultiMedia框架完全解析 - MediaExtractor::Create函数的解析和FslExtractor分析

    先来看看MediaExtractor所处的位置: (一)创建流程 在GenericSource.cpp的NuPlayer::GenericSource::initFromDataSource()函数中 ...

  6. Android Multimedia框架总结(二十八)NuPlayer到OMX过程

    原址 NuPlayer是谷歌新研发的.  AwesomePlayer存在BUG,谷歌早已在android m 版本中弃用. sp<MediaPlayerBase> MediaPlayerS ...

  7. Android cocos2d-x开发(三)之创建Android工程和编译

    2019独角兽企业重金招聘Python工程师标准>>> 1.进入cocs2d-x目录,用文本编辑器打开create-android-project.bat 将_CYGBIN=设置为c ...

  8. Android 触摸事件机制(三) View中触摸事件详解

    本文将对View中触摸事件相关的内容进行介绍.重点介绍的是dispatchTouchEvent(), onTouchEvent()这两个API以及OnTouchListener接口. 注意:本文是基于 ...

  9. java 饼图 框架_Java 在 Excel 中创建饼图/环形图

    import com.spire.xls.*;importcom.spire.xls.charts.ChartSerie;importcom.spire.xls.charts.ChartSeries; ...

  10. Android Binder框架实现之Parcel详解之基本数据的读写

       Android Binder框架实现之Parcel详解之基本数据的读写 Android Binder框架实现目录: Android Binder框架实现之Binder的设计思想 Android ...

最新文章

  1. 怎么快速掌握一门新技术
  2. [分享]学历与学习力
  3. 反向传播BP 算法之一种直观的解释
  4. jre环境变量配置_详解java环境变量意思-用于解决环境搭建问题
  5. JAVASE阶段流程图
  6. java制作h5视频聊天_JAVA实现大华摄像头WEB方式实时显示视频,H5界面展示方式思路。...
  7. php无限评论回复_php如何制作无限级评论功能?
  8. 2009 managertool software download..........
  9. pyqt5 显示更新进度条_python如何通过pyqt5实现进度条
  10. 计算机应用与医学信息基础知识,第一篇医学信息基础知识.PDF
  11. 符合c语言语法规定的是,若变量已正确定义并赋值,符合C语言语法的表达式是 A。a=a+7; B.a=7+b+c,a++...
  12. 周立功ZCANPRO基础使用教程
  13. Opencv 移植 (亲测有效)
  14. matlab 自制闹钟程序,原生JS写的一个简单闹钟程序
  15. 推荐算法可以做到千人千面,但是千人千面的流量利用效率一定是优于人工分发吗?
  16. 智课雅思词汇---二十五、形容词后缀-ate-fic-ose-ulent-olent-ous-ulous-y
  17. 在你的应用里使用Jetty嵌入式
  18. 数据类型详解之字符串
  19. 线性代数学习笔记——行列式的性质及拉普拉斯定理——10. k阶子式、余子式、代数余子式
  20. long + ulong_ULONG_MAX常数,带C ++示例

热门文章

  1. java扫码盒_[腾讯 TMQ] JAVA 代码覆盖率工具 JaCoCo-实践篇
  2. 基于深度学习的单目图像深度估计
  3. 深度学习中的 Attention 机制总结与代码实现(2017-2021年)
  4. 2020,我的年终总结(附优惠券)
  5. 科技部正式发文:破除“唯论文”不良导向;网友:靠水论文拿奖励的人不开心了...
  6. 深度可分离卷积结构(depthwise separable convolution)计算复杂度分析
  7. bzoj 1604 奶牛的邻居
  8. 《团队作业第三、第四周》五小福团队作业--Scrum 冲刺阶段--Day1--领航
  9. 让VIM支持Python2 by update-alternatives
  10. onclick控制元素显示与隐藏时,点击第一次无反应的原因