IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 9.0 multimedia框架(一)加载media extractor组件 -> 正文阅读

[移动开发]Android 9.0 multimedia框架(一)加载media extractor组件

Extractor概念

Extractor在multimedia框架扮演着解析器的角色,用于解析文件的封装。extractor会把视频文件解析成音频流和视频流,把音频文件解析成音频流。

关键类说明

  1. NuMediaExtractor:在NuMediaExtractor中,会去保存RemoteMediaExtractor的远程代理对象,也就是binder client。它其实就是针对MediaExtractor的再一次封装,比如它在调用RemoteMediaExtractor获取文件格式的时候,获取得到的是MetaData,然后它会对MetaData进行处理,转化成AMessage,然后再送给调用者。这个类一般是调用SoundPool解析音频文件的时候才会用到的。使用MediaPlayer播放音频文件是不会走这个类的。

  2. RemoteMediaExtractor:binder server。RemoteMediaExtractor跟RemoteDataSource的作用是相似的,它也是将MediaExtractor保存为私有变量中,它的binder client通过它可以访问到MediaExtractor,间接解析多媒体文件。

  3. MediaExtractorFactory:工具类,里面都是static函数。用于加载extractor组件,创建idatasource等

  4. MediaExtractor:extractor组件需继承它。在9.0的版本中,它只是一个类而已,通过其他binder服务来调用它,间接binder化。通过它可以获得解析器的音频轨或者视频轨的信息。

  5. ExtractorPlugin:解析器组件。每一个extractor so都对应一个组件,这个组件会保存so库的句柄,路径及库中定义的解析器信息。

  6. FileSource:根据构造时传递的文件描述符或者文件路径对多媒体文件进行读取等操作。

  7. RemoteDataSource:binder server。在加载解析器的过程中,FileSource被保存位RemoteDataSource的本地对象,供代理进行文件读取的操作。所以,通过RemoteDataSource这个binder服务,extractor可以跨进程访问文件数据。

  8. CallbackDataSource:顾名思义就是用于回调DataSource,在加载extractor过程中,它保存了RemoteDataSource的远程对象在自己的私有变量sp mIDataSource中,通过mIDataSource,CallbackDataSource跨进程操作FileSource,从而访问多媒体文件。

  9. TinyCacheSource:从字面上理解就是:小型缓冲数据源。它保存了CallbackDataSource的对象,通过CallbackDataSource访问多媒体文件。

流程图

因为我们的分析是从SoundPool 的decode开始引入的,所以流程图从decode开始

在这里插入图片描述
上面的时序图,体现了SoundPool解析ogg等多媒体文件时,加载extractor的过程。主要包含几个过程:
1、创建FileSource,然后为FileSource创建binder server: RemoteDataSource,目的是为了提供IDataSource的接口,这样就可以跨进程访问FileSource
2、创建TinyCacheSource,封装IDataSource接口,供media.extractor可以使用
3、UpdateExtractors,遍历system/lib(lib64)/extractors、vendor/lib(lib64)/extractors和RegisterExtractorsInApk,最终会保存到MediaExtractorFactory的gPlugins成员变量中
4、sniff过程,将之前创建的TinyCacheSource传递给所有的extractor,调用每一个的sniff函数评分,最后确定一个extractor来解析此文件
5、创建RemoteMediaExtractor,封装IMediaExtractor接口,方便后续解码使用

通过时序图最后我们发现registerMediaExtractor所有的extractor都会保存在sExtractors这个动态数组中,那么我们可以通过dumpsys media.extractor 命令快速查看
在这里插入图片描述

DataSource

通过DataSource可以获取到文件名及文件路径等信息,在SoundPool设置数据源的时候会传入一个fd趣创建FileSource(FileSource是DataSource一个子类)。我们看下DataSource的一个相关类的框架

在这里插入图片描述
RemoteDataSource 属于binder Server,CallbackDataSource拥有IDataSource binder接口;TinyCacheSource的mSource就是CallbackDataSource,并且TinyCacheSource的toString()就是调用mSource的toString()。所以,只要调用TinyCacheSource的toString就可以获得FileSource保存的文件路径名。在 new TinyCacheSource 创建出来的对象作为localSource参数传递给了MediaExtractorFactory::CreateFromService,然后经过一系列内部调用在调用(*it)->def.sniff的时候把刚才传递进来的localSource作为参数传递进去。这里的sniff就是每一个extractor的静态函数

UpdateExtractors

在调用MediaExtractorFactory::UpdateExtractors时会去遍历system/lib(lib64)/extractors/ 、vendor/lib(lib64)/extractors/下的所有so库,调用dlopen,对每一个存在GETEXTRACTORDEF符号的库的信息保存到ExtractorPlugin中(当然这里会判断是否已经注册了),最后把这个信息列表保存到gPlugins。如果newUpdateApkPath != nullptr,会去找对应的apk,并看对应的是否有extractor.so库,有的话也会将信息保存到列表中

IMediaExtractor

获取到IMediaExtractor就可以访问binder server RemoteMediaExtractor。RemoteMediaExtractor里面保存有MediaExtractor,一个MediaExtractor对应一个RemoteMediaExtractor。这里的MediaExtractor是个功能基类,谷歌自带的或者自己实现的解析器都需要继承它。比如系统中的解析器有:MP3Extractor、MPEG2TSExtractor.cpp、AACExtractor.cpp、FLACExtractor.cpp等等。
从时序图中可以看出,在MediaExtractorFactory::sniff中,会取出gPlugins保存的每一个extractor库,然后调用它们的sniff函数。例如MP3Extractor中的sniff函数会去判断这个数据源是不是属于MP3格式的,如果是则会设置confidence的分数。MediaExtractorFactory::sniff会返回confidence值最大的那个extractor的CreatorFunc。CreatorFunc是每一个extractor 库需要创建的一个static函数,用于构造extractor。

在MediaExtractorFactory的CreateFromService函数中,会用到这个extractor对象,会将这个创建好的MediaExtractor、属于它的FileSource以及ExtractorPlugin都传给RemoteMediaExtractor,构造出一个RemoteMediaExtractor对象。

因为MediaExtractor仅仅是一个本地类,无法提供跨进程访问接口,所以需要一个binder server为它提供接口,这个server就是RemoteMediaExtractor。
RemoteMediaExtractor::RemoteMediaExtractor( MediaExtractor *extractor, const sp<DataSource> &source, const sp<RefBase> &plugin) :mExtractor(extractor), mSource(source), mExtractorPlugin(plugin)
RemoteMediaExtractor就是MediaExtractor的wrapper(封装),只要获得IMediaExtractor,就可以跨进程访问MediaExtractor,比如MP3Extractor。最后就是调用registerMediaExtractor把IMediaExtractor保存到ExtractorInstance里面,方便后面使用。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-23 10:54:40  更:2021-07-23 10:54:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/28 16:11:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码