Android Codec2 CCodec(二)服务启动

server/2024/10/7 14:04:24/

本篇文章我们会先简单了解Android Framework提供的Codec2软件编解码服务(SW Codec Service)的启动过程,然后分析C2Store的设计结构。

1、Codec2 SW Codec Service

Codec2 SW服务启动文件名为main_swcodecservice.cpp,它和OpenMAX服务的启动文件放在同一个文件夹。

int main(int argc __unused, char** argv)
{LOG(INFO) << "media swcodec service starting";signal(SIGPIPE, SIG_IGN);SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);strcpy(argv[0], "media.swcodec");::android::hardware::configureRpcThreadpool(64, false);RegisterCodecServices();::android::hardware::joinRpcThreadpool();
}

从代码中可以看到,Codec2 SW服务名为media.swcodec,而我们之前学习的OpenMAX服务名为media.codec。

$ ps -A | grep codec
mediacodec     489     1      67712   2144 binder_thread_read  0 S media.codec
mediacodec     600     1     102996   2012 binder_thread_read  0 S media.swcodec

media.swcodec是一个HIDL Service,所以它会有一个Manifest文件,比较奇怪的是media.swcodec的清单文件位于frameworks/av/media/mediaserver目录下:

<manifest version="1.0" type="framework"><hal><name>android.hardware.media.c2</name><transport>hwbinder</transport><version>1.2</version><interface><name>IComponentStore</name><instance>software</instance></interface></hal>
</manifest>

回过头来看main,主要是调用RegisterCodecServices创建ComponentStore实例。简化后的代码如下:

extern "C" void RegisterCodecServices() {// 创建C2ComponentStore实例std::shared_ptr<C2ComponentStore> store =android::GetCodec2PlatformComponentStore();using namespace ::android::hardware::media::c2;int platformVersion = android_get_device_api_level();// 创建IComponentStore/ComponentStore实例if (platformVersion >= __ANDROID_API_S__) {android::sp<V1_2::IComponentStore> storeV1_2 =new V1_2::utils::ComponentStore(store);if (storeV1_2->registerAsService("software") != android::OK) {LOG(ERROR) << "Cannot register software Codec2 v1.2 service.";return;}} else if (platformVersion == __ANDROID_API_R__) {android::sp<V1_1::IComponentStore> storeV1_1 =new V1_1::utils::ComponentStore(store);if (storeV1_1->registerAsService("software") != android::OK) {LOG(ERROR) << "Cannot register software Codec2 v1.1 service.";return;}} else if (platformVersion == __ANDROID_API_Q__) {android::sp<V1_0::IComponentStore> storeV1_0 =new V1_0::utils::ComponentStore(store);if (storeV1_0->registerAsService("software") != android::OK) {LOG(ERROR) << "Cannot register software Codec2 v1.0 service.";return;}} else {  // platformVersion < __ANDROID_API_Q__LOG(ERROR) << "The platform version " << platformVersion <<" is not supported.";return;}
}

RegisterCodecServices做了如下两件事:

  1. 调用GetCodec2PlatformComponentStore创建了一个C2ComponentStore对象,从函数名中的Platform可以看出,这个ComponentStore是由Android Framework提供;
  2. 根据Android版本,将C2ComponentStore对象封装到不同版本的IComponentStore中,并将创建的IComponentStore注册到hw binder中。

2、C2ComponentStore

std::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore() {static std::mutex mutex;static std::weak_ptr<C2ComponentStore> platformStore;std::lock_guard<std::mutex> lock(mutex);std::shared_ptr<C2ComponentStore> store = platformStore.lock();if (store == nullptr) {store = std::make_shared<C2PlatformComponentStore>();platformStore = store;}return store;
}

GetCodec2PlatformComponentStore最终创建的是一个C2PlatformComponentStore对象,该类型实现了C2ComponentStore的接口。另外,从上述方法可以看出,C2ComponentStore使用了单例,每个进程只有一个store实例。

C2PlatformComponentStore::C2PlatformComponentStore(): mVisited(false),mReflector(std::make_shared<C2ReflectorHelper>()),mInterface(mReflector) {auto emplace = [this](const char *libPath) {mComponents.emplace(libPath, libPath);};emplace("libcodec2_soft_h263dec.so");emplace("libcodec2_soft_h263enc.so");emplace("libcodec2_soft_hevcdec.so");emplace("libcodec2_soft_hevcenc.so");// ...
}

C2PlatformComponentStore在构造函数中做了三件事:

  1. 实例化C2ReflectorHelper;
  2. 实例化C2PlatformComponentStore::Interface;
  3. Android提供的Codec2 SW encoder/decoder Component添加到store中。

添加组件的步骤是不是似曾相识呢?和OMXStore是差不多的。

std::map<C2String, ComponentLoader> mComponents;

mComponents是一个键值列表,key是组件lib名,value是ComponentLoader对象,在给列表添加条目时使用了隐式转换。

ComponentLoader(std::string libPath): mLibPath(libPath) {}

3、ComponentStore

ComponentStore是HDIL接口实现,创建ComponentStore实例需要传入先前创建的C2ComponentStore对象。

struct ComponentStore : public IComponentStore {protected:sp<CachedConfigurable> mConfigurable;std::shared_ptr<C2ComponentStore> mStore;std::shared_ptr<StoreParameterCache> mParameterCache;
}ComponentStore::ComponentStore(const std::shared_ptr<C2ComponentStore>& store): mConfigurable{new CachedConfigurable(std::make_unique<StoreIntf>(store))},mParameterCache{std::make_shared<StoreParameterCache>(this)},mStore{store} {std::shared_ptr<C2ComponentStore> platformStore = android::GetCodec2PlatformComponentStore();SetPreferredCodec2ComponentStore(store);mParamReflector = mStore->getParamReflector();using namespace std::placeholders;mInit = mConfigurable->init(mParameterCache);
}
  1. ComponentStore的构造函数会实例化CachedConfigurable成员以及StoreParameterCache成员;
  2. 调用SetPreferredCodec2ComponentStore;
  3. 调用C2ComponentStore的getParamReflector;
  4. 调用CachedConfigurable的init方法。

在Codec2框架中,HIDL实现位于frameworks/av/media/codec2/hal/hidl/1.2/utils,服务最终调用的是Codec2 Core定义的接口。下图是ComponentStore相关的简单UML类图:

请添加图片描述


http://www.ppmy.cn/server/106322.html

相关文章

算法刷题笔记 试除法求约数(带有详细注释的C++实现)

文章目录 题目描述基本思路实现代码后记 题目描述 给定n个正整数ai&#xff0c;对于每个整数ai&#xff0c;请你按照从小到大的顺序输出它的所有约数。 输入格式 第一行包含整数n。接下来n行&#xff0c;每行包含一个整数ai。 输出格式 输出共n行&#xff0c;其中第i行输出…

解决执行npm run dev报错node: --openssl-legacy-provider is not allowed in NODE_OPTIONS

问题&#xff1a; 最近下载了一个开源系统&#xff0c;执行npm install很顺利&#xff0c;以为大功告成&#xff0c;结果运行npm run dev时报错node: --openssl-legacy-provider is not allowed in NODE_OPTIONS 解决方法&#xff1a; 应用程序配置&#xff08;package.json&a…

【AI赋能游戏】《黑神话:悟空》专属黑悟空无限创意生成器!(整合包分享)

最近最火的话题&#xff0c;肯定就是《黑神话&#xff1a;悟空》了&#xff01;这游戏实在是忒火火火了。。。全网破圈霸屏&#xff0c;连官媒央视都给了无死角宣传&#xff01; 《黑神话&#xff1a;悟空》登顶Steam历史售卖榜&#xff0c;同时在线玩家冲到了最高**222**万人&…

Sass实现网页背景主题切换

Sass 实现网页背景主题切换 前言准备工作一、 简单的两种主题黑白切换1.定义主题2. 添加主题切换功能3. 修改 data-theme 属性 二、多种主题切换1. 定义主题2. 动态生成 CSS 变量1.遍历列表2.遍历映射3.高级用法 3. 设置默认主题4. 切换功能HTML 三、多种主题多种样式切换1. 定…

Maven-06.依赖管理-依赖传递

一.依赖传递 什么是依赖传递&#xff1a;projectA依赖于JAR包和projectB&#xff0c;而JAR包又依赖于黄色的JAR包。而projectB依赖于projectC和其他JAR包。因此projectA依赖于projectB,projectC和图中的所有JAR包。这就是依赖的传递性。其中蓝绿色部分成为直接依赖。在当前项目…

Transformer总结(二):架构介绍(从seq2seq谈到Transformer架构)

文章目录 一、seq2seq应用介绍二、编码器解码器架构2.1 流程介绍2.2 原理说明 三、Transformer整体结构和处理流程3.1 Attention机制在seq2seq中的引入3.2 比较RNN与自注意力3.3 Transformer架构介绍3.4 处理流程3.4.1 编码器中处理流程3.4.2 解码器在训练阶段和预测阶段的差异…

Unity游戏开发——Unity脚本组件:游戏开发的灵魂

Unity游戏开发 “好读书&#xff0c;不求甚解&#xff1b;每有会意&#xff0c;便欣然忘食。” 本文目录&#xff1a; Unity游戏开发 Unity游戏开发Unity脚本组件&#xff1a;游戏开发的灵魂前言1.Standard Assets导入报错解决办法2. 什么是Unity脚本组件&#xff1f;3. 创建和…

注意力机制中的三种掩码技术及其PyTorch实现

在深度学习中&#xff0c;特别是处理序列数据时&#xff0c;注意力机制是一种非常关键的技术&#xff0c;广泛应用于各种先进的神经网络架构中&#xff0c;如Transformer模型。为了确保模型能够正确处理序列数据&#xff0c;掩码技术发挥了重要作用。本文将介绍三种常见的掩码技…