前言:前一篇的mediaPlayer框架,对于各个模块的关系,得先从核心类MediaPlayer铺开,同样看下今天的Agenda:

MediaPlayer从create到setDisplay时序图 MediaPlayer的create过程 MediaPlayer的setDataSource过程 MediaPlayer的setDisplay过程

今天分析的是从MediaPlayer创建到MediaPlayer调用setDataSource过程

以往总是把时序图放在最后总结,有些人觉得一上来没有个大概,无从下手,所以,先把时序图附上,一步一步对着时序图看看每个阶段经历的过程

MediaPlayer时序图一(create->setDataSource, 后面文章还有,暂且这么命名):

当外部调用MediaPlayer.create(this,”http://www.xxx.mp4“)时,进入我们MediaPlayer的创建过程:

以上代码可以总结为:当MediaPlayer通过Create方式创建播放器时,内部new出MediaPlayer对象 ,并setDataSource,并做好prepare的动作。这时外面只须调用下start方法,音视频资源将能播放起来。喎�"/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwPs2os6PO0sPH08PNqLn9ubnU7E1lZGlhUGxheWVyo6zIu7rz19S8unNldERhdGFTb3VyY2WjrHByZXBhcmW1yLLZ1/eho87ewtvExNbWtrzSqs/Ivq25/W5ldyBNZWRpYVBsYXllcigpLM7Sw8e/tM/CubnU7NbQ1/bBy8qyw7Sy2df3o7o8L3A+DQo8cD48aW1nIGFsdD0="这里写图片描述" src="/uploadfile/Collfiles/20160901/20160901092553362.png" title="" />

注意这里有个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操作,我们看下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是最好不过的选择了。 连通性,正向调用将值进行传入,反向调用把处理过值通知回去。相当于一根管道一样。

接下来看下在setDataSource之后,开始进行mp.setDisplay(holder)

MediaPLayer.java -> setDisplay

对于2,同样在android_media_MediaPlayer.cpp找到其对应方法:

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 multimedia框架总结,Android Multimedia框架总结(三)MediaPlayer中创建到setDataSource过程...相关推荐

  1. 【Android 逆向】使用 Python 代码解析 ELF 文件 ( PyCharm 中创建 Python 程序 | 导入 ELFFile 库 | 解析 ELF 文件 )

    文章目录 一.PyCharm 中创建 Python 程序 二.导入 ELFFile 依赖库 三. 解析 ELF 文件 四. 博客源码 一.PyCharm 中创建 Python 程序 在 PyCharm ...

  2. android矢量动画 充电,android矢量动画

    android矢量动画! 直接来个例子就明白了!(这里我把与动画无关的属性都用-表示) 首先你要有个矢量图 比如这个矢量图xml文件叫"vector1",文件在res\drawab ...

  3. 【Android 逆向】使用 Python 代码解析 ELF 文件 ( PyCharm 中进行断点调试 | ELFFile 实例对象分析 )

    文章目录 一.PyCharm 中进行断点调试 二.ELFFile 实例对象分析 一.PyCharm 中进行断点调试 在上一篇博客 [Android 逆向]使用 Python 代码解析 ELF 文件 ( ...

  4. Android 2.3 SD卡挂载流程浅析(三)

    在前面两篇博文<Android 2.3 SD卡挂载流程浅析(一)><Android 2.3 SD卡挂载流程浅析(二)>中,主要简单介绍了SD卡的挂载流程以及所涉及的关键文件.在 ...

  5. Android之记录并研究Volley框架中知识点

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/50916258 本文出自:[顾林海的博客] ##前言 在上一遍<对 ...

  6. 【Android FFMPEG 开发】Android 中执行 FFMPEG 指令 ( 集成 mobile-ffmpeg 框架 | 完整代码示例 )

    文章目录 一.配置远程 Maven 仓库 二.配置依赖 三.Kotlin 中执行 FFmpeg 命令 四.FFmpeg 命令执行结果查看 五.源码下载 一.配置远程 Maven 仓库 在 Androi ...

  7. 【Android 系统开发】Android框架 与 源码结构

    一. Android 框架 Android框架层级 : Android 自下 而 上 分为 4层; -- Linux内核层; -- 各种库 和 Android运行环境层; -- 应用框架层; -- 应 ...

  8. android调频收音机代码,android 收音机 FM 驱动 hal层 框架层以及应用层代码

    [实例简介] android 收音机 FM 驱动 hal层 框架层以及应用层代码 方法一 不需要framework部分 1.fm放到 \hardware\rk2x 2.FmRadio 放到 packa ...

  9. Android免Root环境下Hook框架Legend原理分析

    0x1 应用场景 现如今,免Root环境下的逆向分析已经成为一种潮流! 在2015年之前的iOS软件逆向工程领域,要想对iOS平台上的软件进行逆向工程分析,越狱iOS设备与安装Cydia是必须的!几乎 ...

  10. android动画延迟执行,Android 过渡动画框架

    为了帮助视图层次内部和视图之间的过渡更加容易实现动画效果,Android 提供了 Transition 框架.这一套框架能够在视图之间提供一种或者多种动画过渡效果.过渡动画要解决的另一个主要问题就是对 ...

最新文章

  1. git user name is not defined
  2. Math.ceil(),Math.floor()与Math.round()三个函数的定义。
  3. iOS 可能用到的三方框架
  4. [导入]看图说话,编写VS2005插件,增强VS2005 IDE
  5. C++中vector容器为什么扩容时按照2倍或者1.5倍进行扩容
  6. vb检测电脑温度_电脑硬件温度多少正常?如何查看电脑硬件温度?
  7. linux安装apache+mysql+php3.8练习环境
  8. 电脑控制手机屏幕软件_手机屏幕如何投屏到电脑
  9. 整理索引碎片,提升SQL Server速度 SQL Server“吃内存”的解决(转载)
  10. 计算机代码大全,电脑运行代码大全
  11. 【入门】R语言最详细Windows安装指南
  12. (转)驾驶证到期换证指南
  13. LTE 核心 MME SGW PGW作用:
  14. 【总结】从0到1的项目经历
  15. 中学化学教学参考杂志社中学化学教学参考编辑部2022年第15期目录
  16. HTML——HTML 简介
  17. Linux挖矿病毒事件应急响应演练(dbused木马)
  18. 人脸识别调研报告2021
  19. 阿里 Arthas 读书笔记
  20. 导航网站盈利模式存在问题分析

热门文章

  1. Hadoop学习笔记—6.Hadoop Eclipse插件的使用
  2. MySQL时区错误导致server time zone value 'Öйú±ê׼ʱ¼ä' 错误
  3. WebAPI Delete方法报错405 Method Not Allowed
  4. Ubuntu 安装deb格式的安装包(收集)
  5. Hello China操作系统STM32移植指南(三)
  6. 学习document.location.href和document.location.replace 区别
  7. 群体智能优化算法之烟花算法(Fireworks Algorithm,FWA)
  8. 【Redis学习笔记】Redis特性
  9. 【事件驱动】【数码管识别】 一台电脑能接多少台USB设备
  10. 智能优化算法:鹰栖息算法-附代码