MediaCodec(一)Codec2 Service

《今天开始准备边学习边整理 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*> &params,
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

AndroidMediaCodec类可以用于录屏,下面是一个简单的实现步骤: 1.创建一个MediaCodec对象,用于编码视频数据。 2.创建一个MediaProjection对象,用于获取屏幕上的图像数据。 3.创建一个Surface对象,将MediaCodecMediaProjection连接起来,以便将屏幕上的图像传递给MediaCodec。 4.创建一个MediaMuxer对象,用于将编码后的视频数据写入到一个MP4文件中。 5.在循环中,使用MediaProjection获取屏幕上的图像数据,通过Surface将图像传递给MediaCodec进行编码,然后将编码后的数据写入到MediaMuxer中。 6.完成录制后,释放所有资源。 下面是一个简单的示例代码,可以将屏幕录制为MP4文件: ```java public class ScreenRecorder { private static final String TAG = "ScreenRecorder"; private static final String MIME_TYPE = "video/avc"; private static final int FRAME_RATE = 30; private static final int I_FRAME_INTERVAL = 1; private static final int BIT_RATE = 5000000; private MediaProjection mMediaProjection; private MediaCodec mMediaCodec; private MediaMuxer mMediaMuxer; private Surface mInputSurface; private boolean mIsRecording; private int mScreenWidth; private int mScreenHeight; private int mScreenDensity; private int mTrackIndex; private long mStartTime; public ScreenRecorder(int width, int height, int density) { mScreenWidth = width; mScreenHeight = height; mScreenDensity = density; } public void startRecording(Context context, Intent data, String outputPath) { if (mIsRecording) { return; } mMediaProjection = createMediaProjection(context, data); if (mMediaProjection == null) { return; } MediaFormat format = createMediaFormat(); mMediaCodec = createMediaCodec(format); if (mMediaCodec == null) { return; } mMediaMuxer = createMediaMuxer(outputPath); if (mMediaMuxer == null) { return; } mMediaCodec.start(); mIsRecording = true; Thread thread = new Thread(new Runnable() { @Override public void run() { record(); } }); thread.start(); } public void stopRecording() { if (!mIsRecording) { return; } mIsRecording = false; try { mMediaProjection.stop(); } catch (Exception e) { Log.e(TAG, "Failed to stop MediaProjection", e); } releaseMediaCodec(); releaseMediaMuxer(); } private MediaProjection createMediaProjection(Context context, Intent data) { return ((MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE)) .getMediaProjection(Activity.RESULT_OK, data); } private MediaFormat createMediaFormat() { int bitrate = BIT_RATE; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { bitrate = (int) (mScreenWidth * mScreenHeight * FRAME_RATE * 0.1); } MediaFormat format = MediaFormat.createVideoFormat(MIME_TYPE, mScreenWidth, mScreenHeight); format.setInteger(MediaFormat.KEY_BIT_RATE, bitrate); format.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE); format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, I_FRAME_INTERVAL); format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface); return format; } private MediaCodec createMediaCodec(MediaFormat format) { try { MediaCodec codec = MediaCodec.createEncoderByType(MIME_TYPE); codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); mInputSurface = codec.createInputSurface(); return codec; } catch (IOException e) { Log.e(TAG, "Failed to create MediaCodec", e); return null; } } private MediaMuxer createMediaMuxer(String outputPath) { try { return new MediaMuxer(outputPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); } catch (IOException e) { Log.e(TAG, "Failed to create MediaMuxer", e); return null; } } private void record() { mStartTime = System.currentTimeMillis(); MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); while (mIsRecording) { int index = mMediaCodec.dequeueOutputBuffer(bufferInfo, 10000); if (index == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { mTrackIndex = mMediaMuxer.addTrack(mMediaCodec.getOutputFormat()); mMediaMuxer.start(); } else if (index >= 0) { ByteBuffer outputBuffer = mMediaCodec.getOutputBuffer(index); if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0) { bufferInfo.size = 0; } if (bufferInfo.size != 0) { bufferInfo.presentationTimeUs = System.currentTimeMillis() - mStartTime; outputBuffer.position(bufferInfo.offset); outputBuffer.limit(bufferInfo.offset + bufferInfo.size); mMediaMuxer.writeSampleData(mTrackIndex, outputBuffer, bufferInfo); } mMediaCodec.releaseOutputBuffer(index, false); } } } private void releaseMediaCodec() { try { if (mMediaCodec != null) { mMediaCodec.signalEndOfInputStream(); mMediaCodec.stop(); mMediaCodec.release(); } } catch (Exception e) { Log.e(TAG, "Failed to release MediaCodec", e); } if (mInputSurface != null) { mInputSurface.release(); } } private void releaseMediaMuxer() { try { if (mMediaMuxer != null) { mMediaMuxer.stop(); mMediaMuxer.release(); } } catch (Exception e) { Log.e(TAG, "Failed to release MediaMuxer", e); } } } ``` 在Activity中调用startRecording()方法开始录制,stopRecording()方法停止录制。在AndroidManifest.xml中添加下面的权限: ```xml <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> ``` 同时需要在代码中动态申请录音和存储权限。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值