《今天开始准备边学习边整理 Mediacodec部分,如有错误请大家指导》
先来看下 MediaCodec /frameworks/av/services/mediacodec/ 路径Android.bp 主要编出 两个 bin 档:
cc_binary name: "mediaswcodec", //这个猜测是 Codec2 Service,继续往下看 cc_binary name: "android.hardware.media.omx@1.0-service", //这个看起来是 omx service 1. main_codecservice.cpp 是启动 omx service 的,OMX 目前在被Codec2 逐步取代,就不仔细追下去了,有兴趣的可以自己学习一下
/frameworks/av/services/mediacodec/main_codecservice.cpp
26 #include <media/stagefright/omx/1.0/Omx.h>
27 #include <media/stagefright/omx/1.0/OmxStore.h>
39 int main(int argc __unused, char** argv)
40 {
41 strcpy(argv[0], "media.codec");
42 LOG(INFO) << "mediacodecservice starting";
43 signal(SIGPIPE, SIG_IGN);
44 SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
45
46 android::ProcessState::initWithDriver("/dev/vndbinder");
47 android::ProcessState::self()->startThreadPool();
48
49 ::android::hardware::configureRpcThreadpool(64, false);
50
51 // Default codec services
52 using namespace ::android::hardware::media::omx::V1_0;
53 sp<IOmx> omx = new implementation::Omx();
54 if (omx == nullptr) {
55 LOG(ERROR) << "Cannot create IOmx HAL service.";
56 } else if (omx->registerAsService() != OK) {
57 LOG(ERROR) << "Cannot register IOmx HAL service.";
58 } else {
59 LOG(INFO) << "IOmx HAL service created.";
60 }
61 sp<IOmxStore> omxStore = new implementation::OmxStore(
62 property_get_int64("vendor.media.omx", 1) ? omx : nullptr);
63 if (omxStore == nullptr) {
64 LOG(ERROR) << "Cannot create IOmxStore HAL service.";
65 } else if (omxStore->registerAsService() != OK) {
66 LOG(ERROR) << "Cannot register IOmxStore HAL service.";
67 }
68
69 ::android::hardware::joinRpcThreadpool();
70 }
===============
/frameworks/av/services/mediacodec/android.hardware.media.omx@1.0-service.rc
1 service vendor.media.omx /vendor/bin/hw/android.hardware.media.omx@1.0-service
2 class main
3 user mediacodec
4 group camera drmrpc mediadrm
5 ioprio rt 4
6 task_profiles ProcessCapacityHigh
2. main_swcodecservice.cpp 应该就是注册 Codec2 service
/frameworks/av/services/mediacodec/main_swcodecservice.cpp
36 int main(int argc __unused, char** argv)
37 {
38 LOG(INFO) << "media swcodec service starting";
39 signal(SIGPIPE, SIG_IGN);
40 SetUpMinijail(kSystemSeccompPolicyPath, kVendorSeccompPolicyPath);
41 strcpy(argv[0], "media.swcodec");
42
43 ::android::hardware::configureRpcThreadpool(64, false);
44
45 RegisterCodecServices(); //主要看这步在做什么
46
47 ::android::hardware::joinRpcThreadpool();
48 }
主要是 RegisterCodecServicesRegisterCodecServices() :是在注册 codec2 sevrice了,看下实现:
/frameworks/av/media/module/codecserviceregistrant/CodecServiceRegistrant.cpp
408 extern "C" void RegisterCodecServices() {
409 LOG(INFO) << "Creating software Codec2 service...";
410 std::shared_ptr<C2ComponentStore> store =
411 android::GetCodec2PlatformComponentStore(); //Step 1
417 using namespace ::android::hardware::media::c2;
418
419 int platformVersion = android_get_device_api_level();
420
421 if (platformVersion >= __ANDROID_API_S__) {
422 android::sp<V1_2::IComponentStore> storeV1_2 =
423 new V1_2::utils::ComponentStore(store); //Step 2
424 if (storeV1_2->registerAsService("software") != android::OK) { //step 3
425 LOG(ERROR) << "Cannot register software Codec2 v1.2 service.";
426 return;
427 }
428 } ...
447 if (!ionPropertiesDefined()) { //ion相关的设置,默认ionPropertiesDefined 为false
448 using IComponentStore =
449 ::android::hardware::media::c2::V1_0::IComponentStore;
450 std::string const preferredStoreName = "default";
451 sp<IComponentStore> preferredStore = //step 4
452 IComponentStore::getService(preferredStoreName.c_str());
453 if (preferredStore) {
454 ::android::SetPreferredCodec2ComponentStore( //step 5
455 std::make_shared<H2C2ComponentStore>(preferredStore));
456 LOG(INFO) <<
457 "Preferred Codec2 store is set to \"" <<
458 preferredStoreName << "\".";
459 } else {
460 LOG(INFO) <<
461 "Preferred Codec2 store is defaulted to \"software\".";
462 }
463 }
464 LOG(INFO) << "Software Codec2 service created and registered.";
465 }
Step1: GetCodec2PlatformComponentStore 获取 C2ComponentStore 实例,
所以 GetCodec2PlatformComponentStore 只是是为了获取到 C2ComponentStore 的shared_ptr,不过 C2ComponentStore 只是个抽象基类,要再看下实际是获取的那哪个子类?
/frameworks/av/media/codec2/vndk/C2Store.cpp
1231 std::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore() {
1232 static std::mutex mutex;
1233 static std::weak_ptr<C2ComponentStore> platformStore;
1234 std::lock_guard<std::mutex> lock(mutex);
1235 std::shared_ptr<C2ComponentStore> store = platformStore.lock(); //lock 获取到 weak_ptr 的 shared_ptr
1236 if (store == nullptr) { //第一次会去创建
1237 store = std::make_shared<C2PlatformComponentStore>();
1238 platformStore = store;
1239 }
1240 return store;
1241 }
======================
// C2ComponentStore 是一个抽象基类,这边的函数比较重要
/frameworks/av/media/codec2/core/include/C2Component.h
773 class C2ComponentStore {
774 public:
788 virtual C2String getName() const = 0;
806 virtual c2_status_t createComponent(
807 C2String name, std::shared_ptr<C2Component>* const component) = 0;
828 virtual c2_status_t createInterface(
829 C2String name, std::shared_ptr<C2ComponentInterface>* const interface) = 0;
832 // * Returns the list of components supported by this component store.
838 virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() = 0;
842 // on-demand buffer layout conversion (swizzling)
843 //
844 virtual c2_status_t copyBuffer(
845 std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) = 0;
851 // * Queries a set of system-wide parameters.
879 virtual c2_status_t query_sm(
880 const std::vector<C2Param*> &stackParams,
881 const std::vector<C2Param::Index> &heapParamIndices,
882 std::vector<std::unique_ptr<C2Param>>* const heapParams) const = 0;
885 // * Sets a set of system-wide parameters.
918 virtual c2_status_t config_sm(
919 const std::vector<C2Param*> ¶ms,
920 std::vector<std::unique_ptr<C2SettingResult>>* const failures) = 0;
926 // * Returns the parameter reflector.
935 virtual std::shared_ptr<C2ParamReflector> getParamReflector() const = 0;
938 // * Returns the set of supported parameters.
947 virtual c2_status_t querySupportedParams_nb(
948 std::vector<std::shared_ptr<C2ParamDescriptor>> * const params) const = 0;
951 // * Retrieves the supported values for the queried fields.
966 virtual c2_status_t querySupportedValues_sm(
967 std::vector<C2FieldSupportedValuesQuery> &fields) const = 0;
这边如果没有获取到 platformStore 就会去创建 C2PlatformComponentStore;
主要:初始化 mReflector mInterface,以及将 soft compent 添加到 mComponents 中去
这些 soft compent 都是google 实现的软解;
/frameworks/av/media/codec2/vndk/C2Store.cpp
652 class C2PlatformComponentStore : public C2ComponentStore {
653 public:
654 virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() override;
655 virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override;
656 virtual C2String getName() const override;
657 virtual c2_status_t querySupportedValues_sm(
658 std::vector<C2FieldSupportedValuesQuery> &fields) const override;
....
===============
//看下构造函数
1066 C2PlatformComponentStore::C2PlatformComponentStore()
1067 : mVisited(false),
1068 mReflector(std::make_shared<C2ReflectorHelper>()),
1069 mInterface(mReflector) {
1070
1071 auto emplace = [this](const char *libPath) {
1072 mComponents.emplace(libPath, libPath);
1073 };
1074
1075 // TODO: move this also into a .so so it can be updated
1076 emplace("libcodec2_soft_aacdec.so");
1077 emplace("libcodec2_soft_aacenc.so");
1078 emplace("libcodec2_soft_amrnbdec.so");
1079 emplace("libcodec2_soft_amrnbenc.so");
1080 emplace("libcodec2_soft_amrwbdec.so");
1081 emplace("libcodec2_soft_amrwbenc.so");
1082 //emplace("libcodec2_soft_av1dec_aom.so"); // deprecated for the gav1 implementation
1083 emplace("libcodec2_soft_av1dec_gav1.so");
1084 emplace("libcodec2_soft_av1enc.so");
1085 emplace("libcodec2_soft_avcdec.so");
1086 emplace("libcodec2_soft_avcenc.so");
1087 emplace("libcodec2_soft_flacdec.so");
1088 emplace("libcodec2_soft_flacenc.so");
1089 emplace("libcodec2_soft_g711alawdec.so");
1090 emplace("libcodec2_soft_g711mlawdec.so");
1091 emplace("libcodec2_soft_gsmdec.so");
1092 emplace("libcodec2_soft_h263dec.so");
1093 emplace("libcodec2_soft_h263enc.so");
1094 emplace("libcodec2_soft_hevcdec.so");
1095 emplace("libcodec2_soft_hevcenc.so");
1096 emplace("libcodec2_soft_mp3dec.so");
1097 emplace("libcodec2_soft_mpeg2dec.so");
1098 emplace("libcodec2_soft_mpeg4dec.so");
1099 emplace("libcodec2_soft_mpeg4enc.so");
1100 emplace("libcodec2_soft_opusdec.so");
1101 emplace("libcodec2_soft_opusenc.so");
1102 emplace("libcodec2_soft_rawdec.so");
1103 emplace("libcodec2_soft_vorbisdec.so");
1104 emplace("libcodec2_soft_vp8dec.so");
1105 emplace("libcodec2_soft_vp8enc.so");
1106 emplace("libcodec2_soft_vp9dec.so");
1107 emplace("libcodec2_soft_vp9enc.so");
1108
1109 }
Setp 1 主要是为了获取 C2ComponentStore 对象;
Step 2:android::sp<V1_2::IComponentStore> storeV1_2 = new V1_2::utils::ComponentStore(store);
这步在创建 V1_2::utils::ComponentStore 对象,看下具体做了什么:
/frameworks/av/media/codec2/hal/hidl/1.2/utils/ComponentStore.cpp
133 ComponentStore::ComponentStore(const std::shared_ptr<C2ComponentStore>& store)
134 : mConfigurable{new CachedConfigurable(std::make_unique<StoreIntf>(store))},
135 mParameterCache{std::make_shared<StoreParameterCache>(this)},
136 mStore{store} {
137
138 std::shared_ptr<C2ComponentStore> platformStore = android::GetCodec2PlatformComponentStore(); //这边又去调用了 GetCodec2PlatformComponentStore,但是 platformStore 却没有用到
139 SetPreferredCodec2ComponentStore(store);
140
141 // Retrieve struct descriptors
142 mParamReflector = mStore->getParamReflector();
143
144 // Retrieve supported parameters from store
145 using namespace std::placeholders;
146 mInit = mConfigurable->init(mParameterCache);
147 }
Step 2 -(1)创建 CachedConfigurable 对象赋值给 mConfigurable;
而 CachedConfigurable 的构造函数主要就使用入参 store 初始化了 std::unique_ptr<ConfigurableC2Intf> mIntf;
/frameworks/av/media/codec2/hal/hidl/1.0/utils/Configurable.cpp
36 CachedConfigurable::CachedConfigurable(
37 std::unique_ptr<ConfigurableC2Intf>&& intf)
38 : mIntf{std::move(intf)} {
39 }
================
/frameworks/av/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/Configurable.h
51 struct ConfigurableC2Intf {
73 ConfigurableC2Intf(const C2String& name, uint32_t id)
74 : mName{name}, mId{id} {}
Step 2 -(2)android::GetCodec2PlatformComponentStore() 没有看出这步的作用?
Step 2 -(3)SetPreferredCodec2ComponentStore:设置 gPreferredComponentStore 和 allocatorStore->setComponentStore; allocatorStore 是设置 alloc 用的store 这边先挖个坑,等后面再去 看!
/frameworks/av/media/codec2/vndk/C2Store.cpp
410 void SetPreferredCodec2ComponentStore(std::shared_ptr<C2ComponentStore> componentStore) {
414 // update preferred store
415 {
416 std::lock_guard<std::mutex> lock(gPreferredComponentStoreMutex);
417 gPreferredComponentStore = componentStore; //设置 PreferredComponentStore
418 }
419
420 // update platform allocator's store as well if it is alive
421 std::shared_ptr<C2PlatformAllocatorStoreImpl> allocatorStore;
422 {
423 std::lock_guard<std::mutex> lock(gPlatformAllocatorStoreMutex);
424 allocatorStore = gPlatformAllocatorStore.lock();
425 }
426 if (allocatorStore) {
427 allocatorStore->setComponentStore(componentStore); //这步应该是设置 alloc 的 ComponentStore
428 }
429 }
-----------
296 void C2PlatformAllocatorStoreImpl::setComponentStore(std::shared_ptr<C2ComponentStore> store) {
300 {
301 std::lock_guard<std::mutex> lock(_mComponentStoreReadLock);
302 _mComponentStore = store;
303 }
04 std::shared_ptr<C2AllocatorIon> ionAllocator;
305 {
306 std::lock_guard<std::mutex> lock(gIonAllocatorMutex);
307 ionAllocator = gIonAllocator.lock();
308 }
309 if (ionAllocator) {
309 if (ionAllocator) {
310 UseComponentStoreForIonAllocator(ionAllocator, store);
311 }
312 std::shared_ptr<C2DmaBufAllocator> dmaAllocator;
313 {
314 std::lock_guard<std::mutex> lock(gDmaBufAllocatorMutex);
315 dmaAllocator = gDmaBufAllocator.lock();
316 }
317 if (dmaAllocator) {
318 UseComponentStoreForDmaBufAllocator(dmaAllocator, store);
319 }tStoreForIonAllocator(ionAllocator, store);
311 }
Step 2 -(4)getParamReflector
mParamReflector = mStore->getParamReflector(); 这步是获取 Retrieve struct descriptors? 。 先看下子类吧 应该是调用的 C2PlatformComponentStore 这个:
返回值 mReflector 是C2PlatformComponentStore 构造中初始化的,mReflector(std::make_shared<C2ReflectorHelper>()) (应该是用于参数反射??)
/frameworks/av/media/codec2/vndk/C2Store.cpp
1227 std::shared_ptr<C2ParamReflector> C2PlatformComponentStore::getParamReflector() const {
1228 return mReflector;
1229 }
======================
//要再看下 std::shared_ptr<C2ReflectorHelper> mReflector;
/frameworks/av/media/codec2/vndk/include/util/C2InterfaceHelper.h
44 /**
45 * Helper class to implement parameter reflectors. This class is dynamic and is designed to be
46 * shared by multiple interfaces. This allows interfaces to add structure descriptors as needed.
47 */
48 class C2ReflectorHelper : public C2ParamReflector {
52 virtual std::unique_ptr<C2StructDescriptor> describe(
53 C2Param::CoreIndex paramIndex) const override;
55 /**
56 * Adds support for describing the given parameters.
57 *
58 * \param Params types of codec 2.0 structs (or parameters) to describe
59 */
60 template<typename... Params>
61 C2_INLINE void addStructDescriptors() {
62 std::vector<C2StructDescriptor> structs;
63 addStructDescriptors(structs, (_Tuple<Params...> *)nullptr);
64 }
65
66 /**
67 * Adds support for describing a specific struct.
68 *
69 * \param strukt descriptor for the struct that will be moved out.
70 */
71 void addStructDescriptor(C2StructDescriptor &&strukt);
------------------
//主要看下这边,函数看起来就是 根据 paramIndex 获取到其值
36 std::unique_ptr<C2StructDescriptor>
37 C2ReflectorHelper::describe(C2Param::CoreIndex paramIndex) const {
38 std::lock_guard<std::mutex> lock(_mMutex);
39 auto it = _mStructs.find(paramIndex);
40 if (it == _mStructs.end()) {
41 return nullptr;
42 } else {
43 return std::make_unique<C2StructDescriptor>(it->second);
44 }
45 };
==================
//再来看下父类,父类很简单,只有 describe
1486 /**
1487 * Parameter reflector class.
1488 *
1489 * This class centralizes the description of parameter structures. This can be shared
1490 * by multiple components as describing a parameter does not imply support of that
1491 * parameter. However, each supported parameter and any dependent structures within
1492 * must be described by the parameter reflector provided by a component.
1493 */
1494 class C2ParamReflector {
1496 /**
1497 * Describes a parameter structure.
1512 */
1513 virtual std::unique_ptr<C2StructDescriptor> describe(C2Param::CoreIndex coreIndex) const = 0;
1514
1515 protected:
1516 virtual ~C2ParamReflector() = default;
1517 };
Step 2 -(5) 最后再来看下 mInit = mConfigurable->init(mParameterCache);
入参:mParameterCache{std::make_shared<StoreParameterCache>(this)},
/frameworks/av/media/codec2/hal/hidl/1.0/utils/Configurable.cpp
41 c2_status_t CachedConfigurable::init(
42 const std::shared_ptr<ParameterCache>& cache) {
43 // Retrieve supported parameters from store
44 c2_status_t init = mIntf->querySupportedParams(&mSupportedParams);
45 c2_status_t validate = cache->validate(mSupportedParams);
46 return init == C2_OK ? C2_OK : validate;
47 }
-------
std::unique_ptr<ConfigurableC2Intf> mIntf
mIntf->querySupportedParams(&mSupportedParams); 这边是获取到所有的 param 及其value;
/frameworks/av/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/Configurable.h
51 struct ConfigurableC2Intf {
64 /** C2ComponentInterface::querySupportedParams_nb */
65 virtual c2_status_t querySupportedParams(
66 std::vector<std::shared_ptr<C2ParamDescriptor>>* const params) const = 0;
================
/frameworks/av/media/codec2/hal/hidl/1.2/utils/ComponentStore.cpp
59 struct StoreIntf : public ConfigurableC2Intf {
90 virtual c2_status_t querySupportedParams(
91 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params
92 ) const override {
93 return mStore->querySupportedParams_nb(params);
94 }
-------
118 std::shared_ptr<C2ComponentStore> mStore;
====================
/frameworks/av/media/codec2/vndk/C2Store.cpp
652 class C2PlatformComponentStore : public C2ComponentStore {
1213 c2_status_t C2PlatformComponentStore::querySupportedParams_nb(
1214 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
1215 return mInterface.querySupportedParams(params);
1216 }
----
Interface mInterface;
mReflector(std::make_shared<C2ReflectorHelper>()),
mInterface(mReflector) {
===================
/frameworks/av/media/codec2/vndk/util/C2InterfaceHelper.cpp
48 class C2ReflectorHelper : public C2ParamReflector {
814 c2_status_t C2InterfaceHelper::querySupportedParams(
815 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
816 std::lock_guard<std::mutex> lock(mMutex);
817 return _mFactory->querySupportedParams(params);
818 }
--------
538 C2InterfaceHelper::C2InterfaceHelper(std::shared_ptr<C2ReflectorHelper> reflector)
539 : mReflector(reflector),
540 _mFactory(std::make_shared<FactoryImpl>(reflector)) { }
==============
// 这个函数看起来是把 _mParams 所有的param 和value 存到 参数 params 中回调给上层
/frameworks/av/media/codec2/vndk/util/C2InterfaceHelper.cpp
443 struct C2InterfaceHelper::FactoryImpl : public C2InterfaceHelper::Factory {
495 c2_status_t querySupportedParams(
496 std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const {
497 for (const auto &it : _mParams) {
499 params->push_back(
500 std::const_pointer_cast<C2ParamDescriptor>(it.second->getDescriptor()));
501 }
503 return C2_OK;
504 }
-----------
std::map<ParamRef, std::shared_ptr<ParamHelper>> _mParams;
cache->validate(mSupportedParams); // std::shared_ptr<ParameterCache>& cache
这边就是在判断 query 到的 Param 是否 valid
/frameworks/av/media/codec2/hal/hidl/1.0/utils/include/codec2/hidl/1.0/Configurable.h
89 struct ParameterCache {
90 virtual c2_status_t validate(
91 const std::vector<std::shared_ptr<C2ParamDescriptor>>&) = 0;
===============
/frameworks/av/media/codec2/hal/hidl/1.0/utils/ComponentStore.cpp
113 struct ComponentStore::StoreParameterCache : public ParameterCache {
120 virtual c2_status_t validate(
121 const std::vector<std::shared_ptr<C2ParamDescriptor>>& params
122 ) override {
123 std::scoped_lock _lock(mStoreMutex);
124 return mStore ? mStore->validateSupportedParams(params) : C2_NO_INIT;
125 }
===============
/frameworks/av/media/codec2/hal/hidl/1.0/utils/ComponentStore.cpp
157 c2_status_t ComponentStore::validateSupportedParams(
158 const std::vector<std::shared_ptr<C2ParamDescriptor>>& params) {
159 c2_status_t res = C2_OK;
160
161 for (const std::shared_ptr<C2ParamDescriptor> &desc : params) {
162 if (!desc) {
163 // All descriptors should be valid
164 res = res ? res : C2_BAD_VALUE;
165 continue;
166 }
167 C2Param::CoreIndex coreIndex = desc->index().coreIndex();
168 std::lock_guard<std::mutex> lock(mStructDescriptorsMutex);
169 auto it = mStructDescriptors.find(coreIndex);
170 if (it == mStructDescriptors.end()) {
171 std::shared_ptr<C2StructDescriptor> structDesc =
172 mParamReflector->describe(coreIndex);
173 if (!structDesc) {
174 // All supported params must be described
175 res = C2_BAD_INDEX;
176 }
177 mStructDescriptors.insert({ coreIndex, structDesc });
178 }
179 }
180 return res;
181 }
Step 3:
storeV1_2->registerAsService("software") 这边就是 注册 为 Codec2 软解的service;
总结:到这边其实就完成了 software 软解 service 的注册了!
分割:Step 4、5 是获取 default service 即vendor 硬解部分:
Step 4:
using IComponentStore =::android::hardware::media::c2::V1_0::IComponentStore;
sp<IComponentStore> preferredStore = IComponentStore::getService(preferredStoreName.c_str());
这边是调用 Codec2 hidl service(这个我们在下面一篇再看),其实寻找 default 的service 其实就是 Codec2 硬解 service。
/frameworks/av/media/codec2/vndk/C2Store.cpp
652 class C2PlatformComponentStore : public C2ComponentStore {
653 public:
654 virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() override;
655 virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override;
656 virtual C2String getName() const override;
657 virtual c2_status_t querySupportedValues_sm(
658 std::vector<C2FieldSupportedValuesQuery> &fields) const override;
...
//这个类有点庞大,晚点看
767 };
=================
//先看下构造函数
1112 C2PlatformComponentStore::C2PlatformComponentStore(
1113 std::vector<std::tuple<C2String,
1114 C2ComponentFactory::CreateCodec2FactoryFunc,
1115 C2ComponentFactory::DestroyCodec2FactoryFunc>> funcs)
1116 : mVisited(false),
1117 mReflector(std::make_shared<C2ReflectorHelper>()),
1118 mInterface(mReflector),
1119 mCodec2FactoryFuncs(funcs) {
1120
1121 for(auto const& func: mCodec2FactoryFuncs) {
1122 mComponents.emplace(std::get<0>(func), func);
1123 }
1124 }
Step 5:
::android::SetPreferredCodec2ComponentStore(std::make_shared<H2C2ComponentStore>(preferredStore)); 这步就是 把硬解设置为 Preferred