Android12 MultiMedia框架之MediaExtractorService
上节学到setDataSource()时会创建各种Source,source用来读取音视频源文件,读取到之后需要demux出音、视频、字幕数据流,然后再送去解码。那么负责进行demux功能的media extractor模块是在什么时候阶段创建的?这里暂时不考虑APP创建的情况,以前面学过的GenericSource为例,它是在prepare阶段被创建的。本节暂时不分析GenericSource创建extractor的流程,先来看看MediaExtractorService的启动过程。
mediaextractor
MediaExtractorService的服务名为mediaextractor:
//frameworks/av/services/mediaextractor/mediaextractor.rc
service mediaextractor /system/bin/mediaextractorclass mainuser mediaexgroup drmrpc mediadrmioprio rt 4writepid /dev/cpuset/foreground/tasks
直接看main函数:
//frameworks/av/services/mediaextractor/main_extractorservice.cpp
int main(int argc __unused, char** argv)
{#if __has_feature(hwaddress_sanitizer)ALOGI("disable media.extractor memory limits (hwasan enabled)");
#elseALOGI("enable media.extractor memory limits");limitProcessMemory("ro.media.maxmem", /* property that defines limit */SIZE_MAX, /* upper limit in bytes */20 /* upper limit as percentage of physical RAM */);
#endifsignal(SIGPIPE, SIG_IGN);//b/62255959: this forces libutis.so to dlopen vendor version of libutils.so//before minijail is on. This is dirty but required since some syscalls such//as pread64 are used by linker but aren't allowed in the minijail. By//calling the function before entering minijail, we can force dlopen.android::report_sysprop_change();SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);strcpy(argv[0], "media.extractor");sp<ProcessState> proc(ProcessState::self());sp<IServiceManager> sm = defaultServiceManager();MediaExtractorService::instantiate();ProcessState::self()->startThreadPool();IPCThreadState::self()->joinThreadPool();
}
由于MediaExtractorService继承自模板类BinderService,所以直接调用它的instantiate()来创建service且加入service manager中:
//frameworks/native/include/binder/BinderService.h
static void instantiate() { publish(); }static status_t publish(bool allowIsolated = false,int dumpFlags = IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT) {sp<IServiceManager> sm(defaultServiceManager());return sm->addService(String16(SERVICE::getServiceName()), new SERVICE(), allowIsolated,dumpFlags);
}
接下来主要看MediaExtractorService构造函数做了什么:
//frameworks/av/services/mediaextractor/MediaExtractorService.cpp
MediaExtractorService::MediaExtractorService() {MediaExtractorFactory::LoadExtractors();
}
其直接调用到MediaExtractorFactory中的LoadExtractors()方法:
//frameworks/av/media/libstagefright/MediaExtractorFactory.cpp
// static
void MediaExtractorFactory::LoadExtractors() {Mutex::Autolock autoLock(gPluginMutex);if (gPluginsRegistered) {return;}gIgnoreVersion = property_get_bool("debug.extractor.ignore_version", false);std::shared_ptr<std::list<sp<ExtractorPlugin>>> newList(new std::list<sp<ExtractorPlugin>>());android_namespace_t *mediaNs = android_get_exported_namespace("com_android_media");if (mediaNs != NULL) {const android_dlextinfo dlextinfo = {.flags = ANDROID_DLEXT_USE_NAMESPACE,.library_namespace = mediaNs,};RegisterExtractors("/apex/com.android.media/lib"
#ifdef __LP64__"64"
#endif"/extractors", &dlextinfo, *newList);} else {ALOGE("couldn't find media namespace.");}RegisterExtractors("/system/lib"
#ifdef __LP64__"64"
#endif"/extractors", NULL, *newList);RegisterExtractors("/system_ext/lib"
#ifdef __LP64__"64"
#endif"/extractors", NULL, *newList);newList->sort(compareFunc);gPlugins = newList;for (auto it = gPlugins->begin(); it != gPlugins->end(); ++it) {if ((*it)->def.def_version == EXTRACTORDEF_VERSION_NDK_V2) {for (size_t i = 0;; i++) {const char* ext = (*it)->def.u.v3.supported_types[i];if (ext == nullptr) {break;}gSupportedExtensions.push_back(std::string(ext));}}}gPluginsRegistered = true;
}
简单描述下这段代码所做的操作:
- 创建一个list用来保存即将获取到的指向ExtractorPlugin对象的sp指针。
- 依次到如下目录通过RegisterExtractors()方法逐个注册ExtractorPlugin到list中:
- /apex/com.android.media/lib(64)/extractors
- /system/lib(64)/extractors
- /system_ext/lib(64)/extractors
- 将list内的内容按extractor_name从小到大的顺序重新排序,并将其保存到gPlugins中。
- 最后一个for循环,主要是将各个extractor所支持的mime type或者文件扩展名保存到gSupportedExtensions中,可用于后续查询。
再简单看看RegisterExtractors()方法:
//frameworks/av/media/libstagefright/MediaExtractorFactory.cpp
void MediaExtractorFactory::RegisterExtractors(const char *libDirPath, const android_dlextinfo* dlextinfo,std::list<sp<ExtractorPlugin>> &pluginList) {ALOGV("search for plugins at %s", libDirPath);DIR *libDir = opendir(libDirPath);if (libDir) {struct dirent* libEntry;while ((libEntry = readdir(libDir))) {if (libEntry->d_name[0] == '.') {continue;}String8 libPath = String8(libDirPath) + "/" + libEntry->d_name;if (!libPath.contains("extractor.so")) {continue;}void *libHandle = android_dlopen_ext(libPath.string(),RTLD_NOW | RTLD_LOCAL, dlextinfo);if (libHandle == nullptr) {ALOGI("dlopen(%s) reported error %s", libPath.string(), strerror(errno));continue;}GetExtractorDef getDef =(GetExtractorDef) dlsym(libHandle, "GETEXTRACTORDEF");if (getDef == nullptr) {ALOGI("no sniffer found in %s", libPath.string());dlclose(libHandle);continue;}ALOGV("registering sniffer for %s", libPath.string());RegisterExtractor(new ExtractorPlugin(getDef(), libHandle, libPath), pluginList);}closedir(libDir);} else {ALOGI("plugin directory not present (%s)", libDirPath);}
}
主要功能如下:
- 遍历指定目录下的所有后缀为"extractor.so"的库并将其通过dlopen()打开。
- 再通过dlsym()方法获取到GETEXTRACTORDEF()函数的指针。
- 对于每一个extractor创建一个对应的ExtractorPlugin,然后将他们一个个的加入pluginList中。
到此,MediaExtractorService就启动完成了,所做的事情也是相当简单:加载目标目录下所有的extractor并保存到一个list中。
MediaExtractorService还提供了另外两个接口:makeExtractor()和makeIDataSource()。通过搜索code,大概总结一下:
- makeIDataSource():提供给GenericSource调用,用于根据本地播放文件创建出一个IDataSource对象。这个对象进一步会被封装成一个TinyCacheSource对象,用于后面创建extractor。
- makeExtractor():会被封装到MediaExtractorFactory::Create()方法中,该方法会被GenericSource调用,还会被JNI/JAVA调用来创建extractor。
简单以图来总结下:

相关文章:
Android12 MultiMedia框架之MediaExtractorService
上节学到setDataSource()时会创建各种Source,source用来读取音视频源文件,读取到之后需要demux出音、视频、字幕数据流,然后再送去解码。那么负责进行demux功能的media extractor模块是在什么时候阶段创建的?这里暂时不考虑APP创建…...
Chapter 8 Feedback
Chapter 8 Feedback 这一章我们介绍feedback 反馈运放的原理. 负反馈是模拟电路强有力的工具. 8.1 General Considerations 反馈系统如下图所示 Aolamp open-loop gain即开环增益. Aolxo/xi β \beta β 是 feedback factor, 注意方向. β x f x o \beta\frac{x_{f}}{x_{o…...
Administrators就最高了???system是什么??本地用户提权内网学习第三天 你知道uac是什么??
我们今天来说说本地用户提权的操作,我们在有webshell过后我们要进行进一步的提权操作,要不然对我们后期的内网渗透会有一些阻碍的操作。比如说我们使用mimikatz来进行抓取密码,就不能够成功。 Administrators与system的区别 我们来说说Admin…...
回溯 | Java | LeetCode 39, 40, 131 做题总结(未完)
Java Arrays.sort(数组) //排序 不讲究顺序的解答,都可以考虑一下排序是否可行。 39. 组合总和 错误解答 在写的时候需要注意,sum - candidates[i];很重要,也是回溯的一部分。 解答重复了。是因为回溯的for循环理解错了。 class Solutio…...
Linux系统上部署Whisper。
Whisper是一个开源的自动语音识别(ASR)模型,最初由OpenAI发布。要在本地Linux系统上部署Whisper,你可以按照以下步骤进行: 1. 创建虚拟环境 为了避免依赖冲突,建议在虚拟环境中进行部署。创建并激活一个新…...
申请一张含100个域名的证书-免费SSL证书
挑战一下,申请一张包含100个域名的证书 首先,我们访问来此加密网站,进入登录页面,输入我的账号密码。 登录后,咱们就可以开始申请证书,首先说一下,咱账号是SVIP哦,只有SVIP才可以申…...
爬数据是什么意思?
爬数据的意思是:通过网络爬虫程序来获取需要的网站上的内容信息,比如文字、视频、图片等数据。网络爬虫(网页蜘蛛)是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。 学习一些爬数据的知识有什么用呢&#x…...
Pytorch实战(二)
文章目录 前言一、LeNet5原理1.1LeNet5网络结构1.2LeNet网络参数1.3LeNet5网络总结 二、AlexNext2.1AlexNet网络结构2.2AlexNet网络参数2.3Dropout操作2.4PCA图像增强2.5LRN正则化2.6AlexNet总结 三、LeNet实战3.1LeNet5模型搭建3.2可视化数据3.3加载训练、验证数据集3.4模型训…...
wordpress 付费主题modown分享,可实现资源付费
该主题下载地址 下载地址 简介 Modown是基于Erphpdown 会员下载插件开发的付费下载资源、付费下载源码、收费附件下载、付费阅读查看隐藏内容、团购下载的WordPress主题,一款针对收费付费下载资源/付费查看内容/付费阅读/付费视频/VIP会员免费下载查看/虚拟资源售…...
【INTEL(ALTERA)】NIOS II调试器中的重新启动按钮不起作用
目录 说明 解决方法 说明 在 Nios II SBT 调试Eclipse时,如果单击 重新启动 图标, 执行被暂停, 以下错误消息: Dont know how to run. Try "help target." 解决方法 终止程序,再次下载,并启…...
Hive On Spark语法
内层对象定义之特殊数据类型 Array DROP TABLE IF EXISTS test_table_datatype_array; CREATE TABLE test_table_datatype_array (ids array<INT> ) LOCATION test/test_table_datatype_array;SELECTnames,names[1]array(names[2],names[3])names[5],names[-1],array_c…...
利用 fail2ban 保护 SSH 服务器
利用 fail2ban 保护 SSH 服务器 一、关于 fail2ban1. 基本功能与特性2. 工作原理 二、安装与配置1. Debian/Ubuntu系统:2. CentOS/RHEL系统: 三、保护 SSH四、启动 fail2ban 服务五、测试和验证六、查看封禁的 IP 地址七、一些配置八、注意事项 作者&…...
在TkinterGUI界面显示WIFI网络摄像头(ESP32s3)视频画面
本实验结合了之前写过的两篇文章Python调用摄像头,实时显示视频在Tkinter界面以及ESP32 S3搭载OV2640摄像头释放热点(AP)工作模式–Arduino程序,当然如果手头有其他可以获得网络摄像头的URL即用于访问摄像头视频流的网络地址&…...
Yolov8训练时遇到报错SyntaxError: ‘image_weights‘ is not a valid YOLO argument.等问题解决方案
报错说明 line 308, in check_dict_alignmentraise SyntaxError(string CLI_HELP_MSG) from e SyntaxError: image_weights is not a valid YOLO argument. v5loader is not a valid YOLO argument. fl_gamma is not a valid YOLO argument. 解决方法 将训练文件中model.tr…...
javaweb(四)——过滤器与监听器
文章目录 过滤器Filter基本概念滤波器的分类: 时域和频域表示滤波器类型1. 低通滤波器(Low-Pass Filter)2. 高通滤波器(High-Pass Filter)3. 带通滤波器(Band-Pass Filter)4. 带阻滤波器(Band-Stop Filter) 滤波器参数1. 通带频率(Passband Frequency)2. 截止频率(Cutoff Frequ…...
冗余电源的应用,哪些工作站支持冗余电源
冗余电源是一种通过多组电源模块进行备份的技术手段,采用热备插拔式设计,使备用电源在主要电源失效时自动启动,从而确保电源供应不间断。 冗余电源通常应用于对电力要求极高的关键设备和系统,如医疗设备、核电站、数据中心等。在…...
[信号与系统]IIR滤波器与FIR滤波器相位延迟定量的推导。
IIR滤波器与FIR滤波器最大的不同:相位延迟 IIR滤波器相位延迟分析 相位响应和延迟 这里讨论一下理想延迟系统的相位延迟。 对于一个给定的系统频率响应 H ( e j w ) H(e^{jw}) H(ejw)可以表示为 H ( e j w ) ∣ H ( e j w ) ∣ e Φ ( w ) H(e^{jw}) |H(e^{jw…...
Python海量数据处理脚本大集合:pyWhat
pyWhat:精简海联数据,直达数据弱点要害- 精选真开源,释放新价值。 概览 pyWhat是Github社区上一款比较实用的开源Python脚本工具。它能够快速提取信息中的 IP 地址、邮箱、信用卡、数字货币钱包地址、YouTube 视频等内容。当你遇到了一串莫名…...
postgresql搭建
搭建postgresql-11.3,和客户端工具 1,准备对应的包,右键直接下一步安装完即可, 将postgresql设置为本地服务,方便启动, 2,用对应客户端软件连接,新建一个数据库controlDB 新建用户…...
Web 品质标准
Web 品质标准 引言 随着互联网的快速发展,Web应用已经渗透到我们生活的方方面面。为了确保Web应用的质量,提高用户体验,Web品质标准应运而生。这些标准涵盖了多个方面,包括性能、安全性、可访问性、用户体验等。本文将详细介绍这些标准,并探讨它们在实际开发中的应用。 …...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
linux之kylin系统nginx的安装
一、nginx的作用 1.可做高性能的web服务器 直接处理静态资源(HTML/CSS/图片等),响应速度远超传统服务器类似apache支持高并发连接 2.反向代理服务器 隐藏后端服务器IP地址,提高安全性 3.负载均衡服务器 支持多种策略分发流量…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...
MySQL 主从同步异常处理
阅读原文:https://www.xiaozaoshu.top/articles/mysql-m-s-update-pk MySQL 做双主,遇到的这个错误: Could not execute Update_rows event on table ... Error_code: 1032是 MySQL 主从复制时的经典错误之一,通常表示ÿ…...
ubuntu22.04有线网络无法连接,图标也没了
今天突然无法有线网络无法连接任何设备,并且图标都没了 错误案例 往上一顿搜索,试了很多博客都不行,比如 Ubuntu22.04右上角网络图标消失 最后解决的办法 下载网卡驱动,重新安装 操作步骤 查看自己网卡的型号 lspci | gre…...
