当前位置: 首页 > wzjs >正文

漳州网站建设公司广州推动优化防控措施落地

漳州网站建设公司,广州推动优化防控措施落地,新邵县住房和城乡建设局网站,设计网站网站名称上一篇 MediaExtractor 笔记中我们学习了 extractor 以及 source 调用的层次结构,这一节我们会看一看部分的实现细节。 1、getFormat getFormat 是 IMediaSource 的一个方法,调用它可以获得指定 track 的格式信息。格式信息在 extractor 中被称为 Meta…

上一篇 MediaExtractor 笔记中我们学习了 extractor 以及 source 调用的层次结构,这一节我们会看一看部分的实现细节。

1、getFormat

getFormat 是 IMediaSource 的一个方法,调用它可以获得指定 track 的格式信息。格式信息在 extractor 中被称为 MetaData,里面存储有编码格式,视频的宽高,时长,音频的通道数,采样率等等信息,有的存储有解码所需要的 csd 信息。

在高版本的 Android 中,格式信息在 extractor 中一般以 AMediaFormat 的形式存储(例如 mp4 extractor),AMediaFormat 内部实际就是一个 AMessage,信息以 key-value 的形式存储,key 是字符串;有的会以 MetaData 的形式存储(例如 mpeg2 ts extractor),MetaData 也是以 key-value 的形式存储信息,但是它的 key 是int类型,存储的信息会更多一点:

bool MetaDataBase::setData(uint32_t key, uint32_t type, const void *data, size_t size);

可以看到出了 key-value 外还多了 type 和 size 信息。

之所以要这么设计是因为 format 需要通过 binder 跨进程传递给 mediaserver,传递的时候我们需要知道被传递内容的大小信息,而 type 大概是用做特殊的标记。

status_t MediaTrackCUnwrapper::getFormat(MetaDataBase& format) {sp<AMessage> msg = new AMessage();AMediaFormat *tmpFormat =  AMediaFormat_fromMsg(&msg);media_status_t ret = wrapper->getFormat(wrapper->data, tmpFormat);sp<MetaData> newMeta = new MetaData();convertMessageToMetaData(msg, newMeta);delete tmpFormat;format = *newMeta;return reverse_translate_error(ret);
}

从以上代码片我们可以知道,内部的 getFormat 方法传出参数为 AMediaFormat,也就是说无论内部 format 以何种形式存储,最终会转换为 AMediaFormat,以 MPEG2TSSource 为例,MetaData 会先被转换为 AMessage,再转换为 AMediaFormat 回传:

media_status_t MPEG2TSSource::getFormat(AMediaFormat *meta) {sp<MetaData> implMeta = mImpl->getFormat();sp<AMessage> msg;convertMetaDataToMessage(implMeta, &msg);copyAMessageToAMediaFormat(meta, msg);return AMEDIA_OK;
}

跨进程传递时 AMediaFormat 又要被转换为 MetaData,因为 MetaData 中有 writeToParcel 和 createFromParcel( 方法,很方便就完成 Parcel 的封装和解封装。

其实 AMessage 也有 writeToParcel 和 FromParcel,可以很轻松的让 AMessage 在进程间传递,但是这两个方法不能用于 vendor 和 apex。

上面说可以将 MetaData 和 AMessage 相互转换,但是由于它们的 key 的类型并不一样,所以一定有对照关系,这里我们要看 Utils.cpp 这边的几个 pair,pair 中没有的对照关系在 convertMessageToMetaData 和 convertMetaDataToMessage 中会指定转换关系。

如果我们需要自定义一些 Format 信息,那么必须要在 convertMessageToMetaData 和 convertMetaDataToMessage 实现转换关系,否则 extractor parse 出的信息将无法通过 binder 传递,mediaserver 端也无法解析到自定义的 format。

MetaData 所用的 key 位于 MetaDataBase.h,以 enum 的形式提供,如何使用可以参考 Utils.cpp 。

AMediaFormat 使用的 key 位于 NdkMediaFormat.cpp ,以字符串的形式提供,AMediaFormat 如何使用同样参考 Utils.cpp 。

2、MediaExtractor 与 MediaTrack(MediaSource) 设计结构

看代码我们可以发现基础实现 MediaExtractor 和 MediaTrack 分别继承于 MediaExtractorPluginHelperMediaTrackHelper,这两个基类的声明位于 MediaExtractorPluginHelper.h,除了这两个类外,还有非常重要的 MediaBufferHelper、MediaBufferGroupHelper、DataSourceHelper。

往上一层,与之相对应的 C 风格的 api 声明位于 MediaExtractorPluginApi.h,创建了 MediaExtractorPluginHelper 和 MediaTrackHelper 对象后,会将其封装到 CMediaExtractorCMediaTrack 供上层使用。wrap 方法在 MediaExtractorPluginHelper.h 中有提供,对 Helper 提供的 api 进行了封装。

再往上就到了 MediaExtractor MediaTrack,它们两个是基类提供了对外接口,对应的实现是 MediaExtractorCUnwrapper 和 MediaTrackCUnwrapper 。它们内部封装了对 CMediaExtractorCMediaTrack 的调用以及对返回结果的处理。

最外层是binder封装,这里就不细看了。

请添加图片描述

看到这里我们大致就可以了解,binder 调用的是 MediaExtractor 和 MediaTrack 提供的标准接口,它们对内部依赖进行了抽象,使其依赖于 CMediaExtractor 和 CMediaTrack,而不是依赖于具体的实现,具体实现封装在CMediaExtractor 和 CMediaTrack中。我觉得这里CMediaExtractor -> MediaExtractorPluginHelper 所用到的设计模式应该算是外观模式。

我并不是很理解为什么要设计中间层 CMediaExtractor 和 CMediaTrack,拿掉它们同样可以实现抽象与多态,如果有大神理解可以指点我一下。

http://www.dtcms.com/wzjs/506829.html

相关文章:

  • 免费b站有哪些黄冈网站推广软件费用是多少
  • 武汉网站建设招聘客服营销策略是什么意思
  • 欧美动物人物ppt免费模板下载网站外链代发免费
  • 网站专题栏目策划方案怎么把抖音关键词做上去
  • java 做的网站厨师培训学校
  • 排名优化网站建设广告投放数据分析
  • 邢台建设规划网站2020国内十大小说网站排名
  • cpa单页网站怎么做北京官网优化公司
  • 商丘疫情公司搜索seo
  • 网站建设课程设计网站 seo
  • 做ic什么网站好91手机用哪个浏览器
  • 电子商务网站按其实现的技术可分为辅导班
  • 做淘宝客网站教程网站流量查询服务平台
  • 做的比较好的企业网站太原网站建设谁家好
  • 成都上市的网站建设公司福建seo搜索引擎优化
  • 本地企业网站建设服务网站创建免费用户
  • wordpress div属性长沙seo智优营家
  • 做网站常用代码百度下载官方下载安装
  • 宿迁网站优化网络优化工程师需要学什么
  • 找素材去哪个网站群排名优化软件
  • 怎么做vip网站百度一下手机版首页
  • 百度收录的网站深圳网络推广有几种方法
  • python做网站的书网络营销师报名入口
  • 平台网站开发多少钱软文推广收费
  • 20m带宽做网站够用吗重庆seo的薪酬水平
  • 织梦如何做网站百度官网下载
  • 专业做网站app 真假网上如何做广告
  • 网站源码 带后台上线了建站
  • 做装修公司网站费用提高工作效率的软件
  • 广西中小型营销型网站建设公司网络营销期末考试试题及答案