Loading media/libstagefright/codec2/include/C2Component.h +3 −3 Original line number Diff line number Diff line Loading @@ -360,6 +360,7 @@ public: C2DomainKind domain; ///< component domain (e.g. audio or video) C2ComponentKind type; ///< component type (e.g. encoder, decoder or filter) C2StringLiteral mediaType; ///< media type supported by the component C2ComponentPriority priority; ///< priority used to determine component ordering /** * name alias(es) for backward compatibility. Loading Loading @@ -569,7 +570,6 @@ public: */ virtual std::shared_ptr<C2ComponentInterface> intf() = 0; protected: virtual ~C2Component() = default; }; Loading Loading @@ -724,11 +724,11 @@ public: /** * Returns the list of components supported by this component store. * * This method may be momentarily blocking, but MUST return within 5ms. * This method MUST return within 500ms. * * \retval vector of component information. */ virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents_sm() const = 0; virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() = 0; // -------------------------------------- UTILITY METHODS -------------------------------------- Loading media/libstagefright/codec2/vndk/C2Store.cpp +402 −5 Original line number Diff line number Diff line Loading @@ -20,12 +20,26 @@ #include <C2Component.h> #include <C2PlatformSupport.h> #define LOG_TAG "C2Store" #define LOG_NDEBUG 0 #include <utils/Log.h> #include <dlfcn.h> #include <map> #include <memory> #include <mutex> namespace android { /** * The platform allocator store provides basic allocator-types for the framework based on ion and * gralloc. Allocators are not meant to be updatable. * * \todo Provide allocator based on ashmem * \todo Move ion allocation into its HIDL or provide some mapping from memory usage to ion flags * \todo Make this allocator store extendable */ class C2PlatformAllocatorStore : public C2AllocatorStore { public: enum : id_t { Loading @@ -37,9 +51,11 @@ public: /* ionmapper */ ); virtual c2_status_t fetchAllocator(id_t id, std::shared_ptr<C2Allocator> *const allocator) override; virtual c2_status_t fetchAllocator( id_t id, std::shared_ptr<C2Allocator> *const allocator) override; virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb() const override { virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb() const override { return std::vector<std::shared_ptr<const C2Allocator::Traits>>(); /// \todo } Loading @@ -48,10 +64,10 @@ public: } private: // returns a shared-singleton ion allocator /// returns a shared-singleton ion allocator std::shared_ptr<C2Allocator> fetchIonAllocator(); // returns a shared-singleton gralloc allocator /// returns a shared-singleton gralloc allocator std::shared_ptr<C2Allocator> fetchGrallocAllocator(); }; Loading Loading @@ -141,4 +157,385 @@ c2_status_t GetCodec2BlockPool( return res; } class C2PlatformComponentStore : public C2ComponentStore { public: virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() override; virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override; virtual C2String getName() const override; virtual c2_status_t querySupportedValues_nb( std::vector<C2FieldSupportedValuesQuery> &fields) const override; virtual c2_status_t querySupportedParams_nb( std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const override; virtual c2_status_t query_sm( const std::vector<C2Param *const> &stackParams, const std::vector<C2Param::Index> &heapParamIndices, std::vector<std::unique_ptr<C2Param>> *const heapParams) const override; virtual c2_status_t createInterface( C2String name, std::shared_ptr<C2ComponentInterface> *const interface) override; virtual c2_status_t createComponent( C2String name, std::shared_ptr<C2Component> *const component) override; virtual c2_status_t copyBuffer( std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) override; virtual c2_status_t config_sm( const std::vector<C2Param *const> ¶ms, std::vector<std::unique_ptr<C2SettingResult>> *const failures) override; virtual c2_status_t commit_sm( const std::vector<C2Param *const> ¶ms, std::vector<std::unique_ptr<C2SettingResult>> *const failures) override; C2PlatformComponentStore(); virtual ~C2PlatformComponentStore() override = default; private: /** * An object encapsulating a loaded component module. * * \todo provide a way to add traits to known components here to avoid loading the .so-s * for listComponents */ struct ComponentModule : public C2ComponentFactory, public std::enable_shared_from_this<ComponentModule> { virtual c2_status_t createComponent( c2_node_id_t id, std::shared_ptr<C2Component> *component, ComponentDeleter deleter = std::default_delete<C2Component>()) override; virtual c2_status_t createInterface( c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface, InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) override; /** * \returns the traits of the component in this module. */ std::shared_ptr<const C2Component::Traits> getTraits(); /** * Creates an uninitialized component module. * * \note Only used by ComponentLoader. */ ComponentModule() : mInit(C2_NO_INIT) {} /** * Initializes a component module with a given library path. Must be called exactly once. * * \note Only used by ComponentLoader. * * \param libPath[in] library path (or name) * * \retval C2_OK the component module has been successfully loaded * \retval C2_NO_MEMORY not enough memory to loading the component module * \retval C2_NOT_FOUND could not locate the component module * \retval C2_CORRUPTED the component module could not be loaded (unexpected) * \retval C2_REFUSED permission denied to load the component module (unexpected) * \retval C2_TIMED_OUT could not load the module within the time limit (unexpected) */ c2_status_t init(std::string libPath); virtual ~ComponentModule() override; protected: std::recursive_mutex mLock; ///< lock protecting mTraits std::shared_ptr<C2Component::Traits> mTraits; ///< cached component traits c2_status_t mInit; ///< initialization result void *mLibHandle; ///< loaded library handle C2ComponentFactory::CreateCodec2FactoryFunc createFactory; ///< loaded create function C2ComponentFactory::DestroyCodec2FactoryFunc destroyFactory; ///< loaded destroy function C2ComponentFactory *mComponentFactory; ///< loaded/created component factory }; /** * An object encapsulating a loadable component module. * * \todo make this also work for enumerations */ struct ComponentLoader { /** * Load the component module. * * This method simply returns the component module if it is already currently loaded, or * attempts to load it if it is not. * * \param module[out] pointer to the shared pointer where the loaded module shall be stored. * This will be nullptr on error. * * \retval C2_OK the component module has been successfully loaded * \retval C2_NO_MEMORY not enough memory to loading the component module * \retval C2_NOT_FOUND could not locate the component module * \retval C2_CORRUPTED the component module could not be loaded * \retval C2_REFUSED permission denied to load the component module */ c2_status_t fetchModule(std::shared_ptr<ComponentModule> *module) { c2_status_t res = C2_OK; std::lock_guard<std::mutex> lock(mMutex); std::shared_ptr<ComponentModule> localModule = mModule.lock(); if (localModule == nullptr) { localModule = std::make_shared<ComponentModule>(); res = localModule->init(mLibPath); if (res == C2_OK) { mModule = localModule; } } *module = localModule; return res; } /** * Creates a component loader for a specific library path (or name). */ ComponentLoader(std::string libPath) : mLibPath(libPath) {} private: std::mutex mMutex; ///< mutex guarding the module std::weak_ptr<ComponentModule> mModule; ///< weak reference to the loaded module std::string mLibPath; ///< library path (or name) }; /** * Retrieves the component loader for a component. * * \return a non-ref-holding pointer to the component loader. * * \retval C2_OK the component loader has been successfully retrieved * \retval C2_NO_MEMORY not enough memory to locate the component loader * \retval C2_NOT_FOUND could not locate the component to be loaded * \retval C2_CORRUPTED the component loader could not be identified due to some modules being * corrupted (this can happen if the name does not refer to an already * identified component but some components could not be loaded due to * bad library) * \retval C2_REFUSED permission denied to find the component loader for the named component * (this can happen if the name does not refer to an already identified * component but some components could not be loaded due to lack of * permissions) */ c2_status_t findComponent(C2String name, ComponentLoader **loader); std::map<C2String, ComponentLoader> mComponents; ///< list of components }; c2_status_t C2PlatformComponentStore::ComponentModule::init(std::string libPath) { ALOGV("in %s", __func__); ALOGV("loading dll"); mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE); if (mLibHandle == nullptr) { // could be access/symbol or simply not being there ALOGD("could not dlopen %s: %s", libPath.c_str(), dlerror()); mInit = C2_CORRUPTED; } else { createFactory = (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory"); destroyFactory = (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory"); mComponentFactory = createFactory(); if (mComponentFactory == nullptr) { ALOGD("could not create factory in %s", libPath.c_str()); mInit = C2_NO_MEMORY; } else { mInit = C2_OK; } } return mInit; } C2PlatformComponentStore::ComponentModule::~ComponentModule() { ALOGV("in %s", __func__); if (destroyFactory && mComponentFactory) { destroyFactory(mComponentFactory); } if (mLibHandle) { ALOGV("unloading dll"); dlclose(mLibHandle); } } c2_status_t C2PlatformComponentStore::ComponentModule::createInterface( c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface, std::function<void(::android::C2ComponentInterface*)> deleter) { interface->reset(); if (mInit != C2_OK) { return mInit; } std::shared_ptr<ComponentModule> module = shared_from_this(); c2_status_t res = mComponentFactory->createInterface( id, interface, [module, deleter](C2ComponentInterface *p) mutable { // capture module so that we ensure we still have it while deleting interface deleter(p); // delete interface first module.reset(); // remove module ref (not technically needed) }); return res; } c2_status_t C2PlatformComponentStore::ComponentModule::createComponent( c2_node_id_t id, std::shared_ptr<C2Component> *component, std::function<void(::android::C2Component*)> deleter) { component->reset(); if (mInit != C2_OK) { return mInit; } std::shared_ptr<ComponentModule> module = shared_from_this(); c2_status_t res = mComponentFactory->createComponent( id, component, [module, deleter](C2Component *p) mutable { // capture module so that we ensure we still have it while deleting component deleter(p); // delete component first module.reset(); // remove module ref (not technically needed) }); return res; } std::shared_ptr<const C2Component::Traits> C2PlatformComponentStore::ComponentModule::getTraits() { std::unique_lock<std::recursive_mutex> lock(mLock); if (!mTraits) { std::shared_ptr<C2ComponentInterface> intf; c2_status_t res = createInterface(0, &intf); if (res != C2_OK) { return nullptr; } std::shared_ptr<C2Component::Traits> traits(new (std::nothrow) C2Component::Traits); if (traits) { // traits->name = intf->getName(); } mTraits = traits; } return mTraits; } C2PlatformComponentStore::C2PlatformComponentStore() { // TODO: move this also into a .so so it can be updated mComponents.emplace("c2.google.avc.decoder", "libstagefright_soft_c2avcdec.so"); } c2_status_t C2PlatformComponentStore::copyBuffer( std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) { (void)src; (void)dst; return C2_OMITTED; } c2_status_t C2PlatformComponentStore::query_sm( const std::vector<C2Param *const> &stackParams, const std::vector<C2Param::Index> &heapParamIndices, std::vector<std::unique_ptr<C2Param>> *const heapParams) const { // there are no supported configs (void)heapParams; return stackParams.empty() && heapParamIndices.empty() ? C2_OK : C2_BAD_INDEX; } c2_status_t C2PlatformComponentStore::config_sm( const std::vector<C2Param *const> ¶ms, std::vector<std::unique_ptr<C2SettingResult>> *const failures) { // there are no supported configs (void)failures; return params.empty() ? C2_OK : C2_BAD_INDEX; } c2_status_t C2PlatformComponentStore::commit_sm( const std::vector<C2Param *const> ¶ms, std::vector<std::unique_ptr<C2SettingResult>> *const failures) { // there are no supported configs (void)failures; return params.empty() ? C2_OK : C2_BAD_INDEX; } std::vector<std::shared_ptr<const C2Component::Traits>> C2PlatformComponentStore::listComponents() { // This method SHALL return within 500ms. std::vector<std::shared_ptr<const C2Component::Traits>> list; for (auto &it : mComponents) { ComponentLoader &loader = it.second; std::shared_ptr<ComponentModule> module; c2_status_t res = loader.fetchModule(&module); if (res == C2_OK) { std::shared_ptr<const C2Component::Traits> traits = module->getTraits(); if (traits) { list.push_back(traits); } } } return list; } c2_status_t C2PlatformComponentStore::findComponent(C2String name, ComponentLoader **loader) { *loader = nullptr; auto pos = mComponents.find(name); // TODO: check aliases if (pos == mComponents.end()) { return C2_NOT_FOUND; } *loader = &pos->second; return C2_OK; } c2_status_t C2PlatformComponentStore::createComponent( C2String name, std::shared_ptr<C2Component> *const component) { // This method SHALL return within 100ms. component->reset(); ComponentLoader *loader; c2_status_t res = findComponent(name, &loader); if (res == C2_OK) { std::shared_ptr<ComponentModule> module; res = loader->fetchModule(&module); if (res == C2_OK) { // TODO: get a unique node ID res = module->createComponent(0, component); } } return res; } c2_status_t C2PlatformComponentStore::createInterface( C2String name, std::shared_ptr<C2ComponentInterface> *const interface) { // This method SHALL return within 100ms. interface->reset(); ComponentLoader *loader; c2_status_t res = findComponent(name, &loader); if (res == C2_OK) { std::shared_ptr<ComponentModule> module; res = loader->fetchModule(&module); if (res == C2_OK) { // TODO: get a unique node ID res = module->createInterface(0, interface); } } return res; } c2_status_t C2PlatformComponentStore::querySupportedParams_nb( std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const { // there are no supported config params (void)params; return C2_OK; } c2_status_t C2PlatformComponentStore::querySupportedValues_nb( std::vector<C2FieldSupportedValuesQuery> &fields) const { // there are no supported config params return fields.empty() ? C2_OK : C2_BAD_INDEX; } C2String C2PlatformComponentStore::getName() const { return "android.componentStore.platform"; } std::shared_ptr<C2ParamReflector> C2PlatformComponentStore::getParamReflector() const { // TODO return nullptr; } 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; } } // namespace android media/libstagefright/codec2/vndk/include/C2PlatformSupport.h +20 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <C2Component.h> #include <functional> #include <memory> namespace android { Loading Loading @@ -64,14 +65,17 @@ c2_status_t GetCodec2BlockPool( */ class C2ComponentFactory { public: typedef std::function<void(::android::C2Component*)> ComponentDeleter; typedef std::function<void(::android::C2ComponentInterface*)> InterfaceDeleter; /** * Creates a component. * * This method SHALL return within 100ms. * * \param id component ID for the created component * \param component shared pointer where the created component is stored. Cleared on * failure and updated on success. * \param id component ID for the created component * * \retval C2_OK the component was created successfully * \retval C2_TIMED_OUT could not create the component within the time limit (unexpected) Loading @@ -80,16 +84,17 @@ public: * \retval C2_NO_MEMORY not enough memory to create the component */ virtual c2_status_t createComponent( std::shared_ptr<C2Component>* const component, c2_node_id_t id) = 0; c2_node_id_t id, std::shared_ptr<C2Component>* const component, ComponentDeleter deleter = std::default_delete<C2Component>()) = 0; /** * Creates a component interface. * * This method SHALL return within 100ms. * * \param id component interface ID for the created interface * \param interface shared pointer where the created interface is stored. Cleared on * failure and updated on success. * \param id component interface ID for the created interface * * \retval C2_OK the component interface was created successfully * \retval C2_TIMED_OUT could not create the component interface within the time limit Loading @@ -100,11 +105,22 @@ public: * \retval C2_NO_MEMORY not enough memory to create the component interface */ virtual c2_status_t createInterface( std::shared_ptr<C2ComponentInterface>* const interface, c2_node_id_t id) = 0; c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface, InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) = 0; virtual ~C2ComponentFactory() = default; typedef ::android::C2ComponentFactory* (*CreateCodec2FactoryFunc)(void); typedef void (*DestroyCodec2FactoryFunc)(::android::C2ComponentFactory*); }; /** * Returns the platform component store. * \retval nullptr if the platform component store could not be obtained */ std::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore(); } // namespace android #endif // STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_ media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp +16 −5 Original line number Diff line number Diff line Loading @@ -261,7 +261,7 @@ C2SoftAvcDecIntf::C2SoftAvcDecIntf(const char *name, c2_node_id_t id) mFrameRate(0u, 0), mBlocksPerSecond(0u, 0), mParamReflector(new ParamReflector) { ALOGV("in %s", __func__); mInputPortMime = C2PortMimeConfig::input::alloc_unique(strlen(CODEC_MIME_TYPE) + 1); strcpy(mInputPortMime->m.mValue, CODEC_MIME_TYPE); mOutputPortMime = C2PortMimeConfig::output::alloc_unique(strlen(MEDIA_MIMETYPE_VIDEO_RAW) + 1); Loading Loading @@ -430,6 +430,10 @@ C2SoftAvcDecIntf::C2SoftAvcDecIntf(const char *name, c2_node_id_t id) false, "_output_block_pools", mOutputBlockPools.get())); } C2SoftAvcDecIntf::~C2SoftAvcDecIntf() { ALOGV("in %s", __func__); } C2String C2SoftAvcDecIntf::getName() const { return mName; } Loading Loading @@ -653,6 +657,7 @@ C2SoftAvcDec::C2SoftAvcDec( mWidth(320), mHeight(240), mInputOffset(0) { ALOGV("in %s", __func__); GETTIME(&mTimeStart, NULL); // If input dump is enabled, then open create an empty file Loading @@ -661,6 +666,7 @@ C2SoftAvcDec::C2SoftAvcDec( } C2SoftAvcDec::~C2SoftAvcDec() { ALOGV("in %s", __func__); CHECK_EQ(deInitDecoder(), (status_t)OK); } Loading Loading @@ -1505,14 +1511,17 @@ status_t C2SoftAvcDec::handleColorAspectsChange() { class C2SoftAvcDecFactory : public C2ComponentFactory { public: virtual c2_status_t createComponent( std::shared_ptr<C2Component>* const component, c2_node_id_t id) override { *component = std::make_shared<C2SoftAvcDec>("avc", id); c2_node_id_t id, std::shared_ptr<C2Component>* const component, std::function<void(::android::C2Component*)> deleter) override { *component = std::shared_ptr<C2Component>(new C2SoftAvcDec("avc", id), deleter); return C2_OK; } virtual c2_status_t createInterface( std::shared_ptr<C2ComponentInterface>* const interface, c2_node_id_t id) override { *interface = std::make_shared<C2SoftAvcDecIntf>("avc", id); c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface, std::function<void(::android::C2ComponentInterface*)> deleter) override { *interface = std::shared_ptr<C2ComponentInterface>(new C2SoftAvcDecIntf("avc", id), deleter); return C2_OK; } Loading @@ -1522,9 +1531,11 @@ public: } // namespace android extern "C" ::android::C2ComponentFactory* CreateCodec2Factory() { ALOGV("in %s", __func__); return new ::android::C2SoftAvcDecFactory(); } extern "C" void DestroyCodec2Factory(::android::C2ComponentFactory* factory) { ALOGV("in %s", __func__); delete factory; } media/libstagefright/codecs/avcdec/C2SoftAvcDec.h +1 −1 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ public: }; C2SoftAvcDecIntf(const char *name, c2_node_id_t id); virtual ~C2SoftAvcDecIntf() = default; virtual ~C2SoftAvcDecIntf() override; // From C2ComponentInterface virtual C2String getName() const override; Loading Loading
media/libstagefright/codec2/include/C2Component.h +3 −3 Original line number Diff line number Diff line Loading @@ -360,6 +360,7 @@ public: C2DomainKind domain; ///< component domain (e.g. audio or video) C2ComponentKind type; ///< component type (e.g. encoder, decoder or filter) C2StringLiteral mediaType; ///< media type supported by the component C2ComponentPriority priority; ///< priority used to determine component ordering /** * name alias(es) for backward compatibility. Loading Loading @@ -569,7 +570,6 @@ public: */ virtual std::shared_ptr<C2ComponentInterface> intf() = 0; protected: virtual ~C2Component() = default; }; Loading Loading @@ -724,11 +724,11 @@ public: /** * Returns the list of components supported by this component store. * * This method may be momentarily blocking, but MUST return within 5ms. * This method MUST return within 500ms. * * \retval vector of component information. */ virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents_sm() const = 0; virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() = 0; // -------------------------------------- UTILITY METHODS -------------------------------------- Loading
media/libstagefright/codec2/vndk/C2Store.cpp +402 −5 Original line number Diff line number Diff line Loading @@ -20,12 +20,26 @@ #include <C2Component.h> #include <C2PlatformSupport.h> #define LOG_TAG "C2Store" #define LOG_NDEBUG 0 #include <utils/Log.h> #include <dlfcn.h> #include <map> #include <memory> #include <mutex> namespace android { /** * The platform allocator store provides basic allocator-types for the framework based on ion and * gralloc. Allocators are not meant to be updatable. * * \todo Provide allocator based on ashmem * \todo Move ion allocation into its HIDL or provide some mapping from memory usage to ion flags * \todo Make this allocator store extendable */ class C2PlatformAllocatorStore : public C2AllocatorStore { public: enum : id_t { Loading @@ -37,9 +51,11 @@ public: /* ionmapper */ ); virtual c2_status_t fetchAllocator(id_t id, std::shared_ptr<C2Allocator> *const allocator) override; virtual c2_status_t fetchAllocator( id_t id, std::shared_ptr<C2Allocator> *const allocator) override; virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb() const override { virtual std::vector<std::shared_ptr<const C2Allocator::Traits>> listAllocators_nb() const override { return std::vector<std::shared_ptr<const C2Allocator::Traits>>(); /// \todo } Loading @@ -48,10 +64,10 @@ public: } private: // returns a shared-singleton ion allocator /// returns a shared-singleton ion allocator std::shared_ptr<C2Allocator> fetchIonAllocator(); // returns a shared-singleton gralloc allocator /// returns a shared-singleton gralloc allocator std::shared_ptr<C2Allocator> fetchGrallocAllocator(); }; Loading Loading @@ -141,4 +157,385 @@ c2_status_t GetCodec2BlockPool( return res; } class C2PlatformComponentStore : public C2ComponentStore { public: virtual std::vector<std::shared_ptr<const C2Component::Traits>> listComponents() override; virtual std::shared_ptr<C2ParamReflector> getParamReflector() const override; virtual C2String getName() const override; virtual c2_status_t querySupportedValues_nb( std::vector<C2FieldSupportedValuesQuery> &fields) const override; virtual c2_status_t querySupportedParams_nb( std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const override; virtual c2_status_t query_sm( const std::vector<C2Param *const> &stackParams, const std::vector<C2Param::Index> &heapParamIndices, std::vector<std::unique_ptr<C2Param>> *const heapParams) const override; virtual c2_status_t createInterface( C2String name, std::shared_ptr<C2ComponentInterface> *const interface) override; virtual c2_status_t createComponent( C2String name, std::shared_ptr<C2Component> *const component) override; virtual c2_status_t copyBuffer( std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) override; virtual c2_status_t config_sm( const std::vector<C2Param *const> ¶ms, std::vector<std::unique_ptr<C2SettingResult>> *const failures) override; virtual c2_status_t commit_sm( const std::vector<C2Param *const> ¶ms, std::vector<std::unique_ptr<C2SettingResult>> *const failures) override; C2PlatformComponentStore(); virtual ~C2PlatformComponentStore() override = default; private: /** * An object encapsulating a loaded component module. * * \todo provide a way to add traits to known components here to avoid loading the .so-s * for listComponents */ struct ComponentModule : public C2ComponentFactory, public std::enable_shared_from_this<ComponentModule> { virtual c2_status_t createComponent( c2_node_id_t id, std::shared_ptr<C2Component> *component, ComponentDeleter deleter = std::default_delete<C2Component>()) override; virtual c2_status_t createInterface( c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface, InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) override; /** * \returns the traits of the component in this module. */ std::shared_ptr<const C2Component::Traits> getTraits(); /** * Creates an uninitialized component module. * * \note Only used by ComponentLoader. */ ComponentModule() : mInit(C2_NO_INIT) {} /** * Initializes a component module with a given library path. Must be called exactly once. * * \note Only used by ComponentLoader. * * \param libPath[in] library path (or name) * * \retval C2_OK the component module has been successfully loaded * \retval C2_NO_MEMORY not enough memory to loading the component module * \retval C2_NOT_FOUND could not locate the component module * \retval C2_CORRUPTED the component module could not be loaded (unexpected) * \retval C2_REFUSED permission denied to load the component module (unexpected) * \retval C2_TIMED_OUT could not load the module within the time limit (unexpected) */ c2_status_t init(std::string libPath); virtual ~ComponentModule() override; protected: std::recursive_mutex mLock; ///< lock protecting mTraits std::shared_ptr<C2Component::Traits> mTraits; ///< cached component traits c2_status_t mInit; ///< initialization result void *mLibHandle; ///< loaded library handle C2ComponentFactory::CreateCodec2FactoryFunc createFactory; ///< loaded create function C2ComponentFactory::DestroyCodec2FactoryFunc destroyFactory; ///< loaded destroy function C2ComponentFactory *mComponentFactory; ///< loaded/created component factory }; /** * An object encapsulating a loadable component module. * * \todo make this also work for enumerations */ struct ComponentLoader { /** * Load the component module. * * This method simply returns the component module if it is already currently loaded, or * attempts to load it if it is not. * * \param module[out] pointer to the shared pointer where the loaded module shall be stored. * This will be nullptr on error. * * \retval C2_OK the component module has been successfully loaded * \retval C2_NO_MEMORY not enough memory to loading the component module * \retval C2_NOT_FOUND could not locate the component module * \retval C2_CORRUPTED the component module could not be loaded * \retval C2_REFUSED permission denied to load the component module */ c2_status_t fetchModule(std::shared_ptr<ComponentModule> *module) { c2_status_t res = C2_OK; std::lock_guard<std::mutex> lock(mMutex); std::shared_ptr<ComponentModule> localModule = mModule.lock(); if (localModule == nullptr) { localModule = std::make_shared<ComponentModule>(); res = localModule->init(mLibPath); if (res == C2_OK) { mModule = localModule; } } *module = localModule; return res; } /** * Creates a component loader for a specific library path (or name). */ ComponentLoader(std::string libPath) : mLibPath(libPath) {} private: std::mutex mMutex; ///< mutex guarding the module std::weak_ptr<ComponentModule> mModule; ///< weak reference to the loaded module std::string mLibPath; ///< library path (or name) }; /** * Retrieves the component loader for a component. * * \return a non-ref-holding pointer to the component loader. * * \retval C2_OK the component loader has been successfully retrieved * \retval C2_NO_MEMORY not enough memory to locate the component loader * \retval C2_NOT_FOUND could not locate the component to be loaded * \retval C2_CORRUPTED the component loader could not be identified due to some modules being * corrupted (this can happen if the name does not refer to an already * identified component but some components could not be loaded due to * bad library) * \retval C2_REFUSED permission denied to find the component loader for the named component * (this can happen if the name does not refer to an already identified * component but some components could not be loaded due to lack of * permissions) */ c2_status_t findComponent(C2String name, ComponentLoader **loader); std::map<C2String, ComponentLoader> mComponents; ///< list of components }; c2_status_t C2PlatformComponentStore::ComponentModule::init(std::string libPath) { ALOGV("in %s", __func__); ALOGV("loading dll"); mLibHandle = dlopen(libPath.c_str(), RTLD_NOW|RTLD_NODELETE); if (mLibHandle == nullptr) { // could be access/symbol or simply not being there ALOGD("could not dlopen %s: %s", libPath.c_str(), dlerror()); mInit = C2_CORRUPTED; } else { createFactory = (C2ComponentFactory::CreateCodec2FactoryFunc)dlsym(mLibHandle, "CreateCodec2Factory"); destroyFactory = (C2ComponentFactory::DestroyCodec2FactoryFunc)dlsym(mLibHandle, "DestroyCodec2Factory"); mComponentFactory = createFactory(); if (mComponentFactory == nullptr) { ALOGD("could not create factory in %s", libPath.c_str()); mInit = C2_NO_MEMORY; } else { mInit = C2_OK; } } return mInit; } C2PlatformComponentStore::ComponentModule::~ComponentModule() { ALOGV("in %s", __func__); if (destroyFactory && mComponentFactory) { destroyFactory(mComponentFactory); } if (mLibHandle) { ALOGV("unloading dll"); dlclose(mLibHandle); } } c2_status_t C2PlatformComponentStore::ComponentModule::createInterface( c2_node_id_t id, std::shared_ptr<C2ComponentInterface> *interface, std::function<void(::android::C2ComponentInterface*)> deleter) { interface->reset(); if (mInit != C2_OK) { return mInit; } std::shared_ptr<ComponentModule> module = shared_from_this(); c2_status_t res = mComponentFactory->createInterface( id, interface, [module, deleter](C2ComponentInterface *p) mutable { // capture module so that we ensure we still have it while deleting interface deleter(p); // delete interface first module.reset(); // remove module ref (not technically needed) }); return res; } c2_status_t C2PlatformComponentStore::ComponentModule::createComponent( c2_node_id_t id, std::shared_ptr<C2Component> *component, std::function<void(::android::C2Component*)> deleter) { component->reset(); if (mInit != C2_OK) { return mInit; } std::shared_ptr<ComponentModule> module = shared_from_this(); c2_status_t res = mComponentFactory->createComponent( id, component, [module, deleter](C2Component *p) mutable { // capture module so that we ensure we still have it while deleting component deleter(p); // delete component first module.reset(); // remove module ref (not technically needed) }); return res; } std::shared_ptr<const C2Component::Traits> C2PlatformComponentStore::ComponentModule::getTraits() { std::unique_lock<std::recursive_mutex> lock(mLock); if (!mTraits) { std::shared_ptr<C2ComponentInterface> intf; c2_status_t res = createInterface(0, &intf); if (res != C2_OK) { return nullptr; } std::shared_ptr<C2Component::Traits> traits(new (std::nothrow) C2Component::Traits); if (traits) { // traits->name = intf->getName(); } mTraits = traits; } return mTraits; } C2PlatformComponentStore::C2PlatformComponentStore() { // TODO: move this also into a .so so it can be updated mComponents.emplace("c2.google.avc.decoder", "libstagefright_soft_c2avcdec.so"); } c2_status_t C2PlatformComponentStore::copyBuffer( std::shared_ptr<C2GraphicBuffer> src, std::shared_ptr<C2GraphicBuffer> dst) { (void)src; (void)dst; return C2_OMITTED; } c2_status_t C2PlatformComponentStore::query_sm( const std::vector<C2Param *const> &stackParams, const std::vector<C2Param::Index> &heapParamIndices, std::vector<std::unique_ptr<C2Param>> *const heapParams) const { // there are no supported configs (void)heapParams; return stackParams.empty() && heapParamIndices.empty() ? C2_OK : C2_BAD_INDEX; } c2_status_t C2PlatformComponentStore::config_sm( const std::vector<C2Param *const> ¶ms, std::vector<std::unique_ptr<C2SettingResult>> *const failures) { // there are no supported configs (void)failures; return params.empty() ? C2_OK : C2_BAD_INDEX; } c2_status_t C2PlatformComponentStore::commit_sm( const std::vector<C2Param *const> ¶ms, std::vector<std::unique_ptr<C2SettingResult>> *const failures) { // there are no supported configs (void)failures; return params.empty() ? C2_OK : C2_BAD_INDEX; } std::vector<std::shared_ptr<const C2Component::Traits>> C2PlatformComponentStore::listComponents() { // This method SHALL return within 500ms. std::vector<std::shared_ptr<const C2Component::Traits>> list; for (auto &it : mComponents) { ComponentLoader &loader = it.second; std::shared_ptr<ComponentModule> module; c2_status_t res = loader.fetchModule(&module); if (res == C2_OK) { std::shared_ptr<const C2Component::Traits> traits = module->getTraits(); if (traits) { list.push_back(traits); } } } return list; } c2_status_t C2PlatformComponentStore::findComponent(C2String name, ComponentLoader **loader) { *loader = nullptr; auto pos = mComponents.find(name); // TODO: check aliases if (pos == mComponents.end()) { return C2_NOT_FOUND; } *loader = &pos->second; return C2_OK; } c2_status_t C2PlatformComponentStore::createComponent( C2String name, std::shared_ptr<C2Component> *const component) { // This method SHALL return within 100ms. component->reset(); ComponentLoader *loader; c2_status_t res = findComponent(name, &loader); if (res == C2_OK) { std::shared_ptr<ComponentModule> module; res = loader->fetchModule(&module); if (res == C2_OK) { // TODO: get a unique node ID res = module->createComponent(0, component); } } return res; } c2_status_t C2PlatformComponentStore::createInterface( C2String name, std::shared_ptr<C2ComponentInterface> *const interface) { // This method SHALL return within 100ms. interface->reset(); ComponentLoader *loader; c2_status_t res = findComponent(name, &loader); if (res == C2_OK) { std::shared_ptr<ComponentModule> module; res = loader->fetchModule(&module); if (res == C2_OK) { // TODO: get a unique node ID res = module->createInterface(0, interface); } } return res; } c2_status_t C2PlatformComponentStore::querySupportedParams_nb( std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const { // there are no supported config params (void)params; return C2_OK; } c2_status_t C2PlatformComponentStore::querySupportedValues_nb( std::vector<C2FieldSupportedValuesQuery> &fields) const { // there are no supported config params return fields.empty() ? C2_OK : C2_BAD_INDEX; } C2String C2PlatformComponentStore::getName() const { return "android.componentStore.platform"; } std::shared_ptr<C2ParamReflector> C2PlatformComponentStore::getParamReflector() const { // TODO return nullptr; } 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; } } // namespace android
media/libstagefright/codec2/vndk/include/C2PlatformSupport.h +20 −4 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ #include <C2Component.h> #include <functional> #include <memory> namespace android { Loading Loading @@ -64,14 +65,17 @@ c2_status_t GetCodec2BlockPool( */ class C2ComponentFactory { public: typedef std::function<void(::android::C2Component*)> ComponentDeleter; typedef std::function<void(::android::C2ComponentInterface*)> InterfaceDeleter; /** * Creates a component. * * This method SHALL return within 100ms. * * \param id component ID for the created component * \param component shared pointer where the created component is stored. Cleared on * failure and updated on success. * \param id component ID for the created component * * \retval C2_OK the component was created successfully * \retval C2_TIMED_OUT could not create the component within the time limit (unexpected) Loading @@ -80,16 +84,17 @@ public: * \retval C2_NO_MEMORY not enough memory to create the component */ virtual c2_status_t createComponent( std::shared_ptr<C2Component>* const component, c2_node_id_t id) = 0; c2_node_id_t id, std::shared_ptr<C2Component>* const component, ComponentDeleter deleter = std::default_delete<C2Component>()) = 0; /** * Creates a component interface. * * This method SHALL return within 100ms. * * \param id component interface ID for the created interface * \param interface shared pointer where the created interface is stored. Cleared on * failure and updated on success. * \param id component interface ID for the created interface * * \retval C2_OK the component interface was created successfully * \retval C2_TIMED_OUT could not create the component interface within the time limit Loading @@ -100,11 +105,22 @@ public: * \retval C2_NO_MEMORY not enough memory to create the component interface */ virtual c2_status_t createInterface( std::shared_ptr<C2ComponentInterface>* const interface, c2_node_id_t id) = 0; c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface, InterfaceDeleter deleter = std::default_delete<C2ComponentInterface>()) = 0; virtual ~C2ComponentFactory() = default; typedef ::android::C2ComponentFactory* (*CreateCodec2FactoryFunc)(void); typedef void (*DestroyCodec2FactoryFunc)(::android::C2ComponentFactory*); }; /** * Returns the platform component store. * \retval nullptr if the platform component store could not be obtained */ std::shared_ptr<C2ComponentStore> GetCodec2PlatformComponentStore(); } // namespace android #endif // STAGEFRIGHT_CODEC2_PLATFORM_SUPPORT_H_
media/libstagefright/codecs/avcdec/C2SoftAvcDec.cpp +16 −5 Original line number Diff line number Diff line Loading @@ -261,7 +261,7 @@ C2SoftAvcDecIntf::C2SoftAvcDecIntf(const char *name, c2_node_id_t id) mFrameRate(0u, 0), mBlocksPerSecond(0u, 0), mParamReflector(new ParamReflector) { ALOGV("in %s", __func__); mInputPortMime = C2PortMimeConfig::input::alloc_unique(strlen(CODEC_MIME_TYPE) + 1); strcpy(mInputPortMime->m.mValue, CODEC_MIME_TYPE); mOutputPortMime = C2PortMimeConfig::output::alloc_unique(strlen(MEDIA_MIMETYPE_VIDEO_RAW) + 1); Loading Loading @@ -430,6 +430,10 @@ C2SoftAvcDecIntf::C2SoftAvcDecIntf(const char *name, c2_node_id_t id) false, "_output_block_pools", mOutputBlockPools.get())); } C2SoftAvcDecIntf::~C2SoftAvcDecIntf() { ALOGV("in %s", __func__); } C2String C2SoftAvcDecIntf::getName() const { return mName; } Loading Loading @@ -653,6 +657,7 @@ C2SoftAvcDec::C2SoftAvcDec( mWidth(320), mHeight(240), mInputOffset(0) { ALOGV("in %s", __func__); GETTIME(&mTimeStart, NULL); // If input dump is enabled, then open create an empty file Loading @@ -661,6 +666,7 @@ C2SoftAvcDec::C2SoftAvcDec( } C2SoftAvcDec::~C2SoftAvcDec() { ALOGV("in %s", __func__); CHECK_EQ(deInitDecoder(), (status_t)OK); } Loading Loading @@ -1505,14 +1511,17 @@ status_t C2SoftAvcDec::handleColorAspectsChange() { class C2SoftAvcDecFactory : public C2ComponentFactory { public: virtual c2_status_t createComponent( std::shared_ptr<C2Component>* const component, c2_node_id_t id) override { *component = std::make_shared<C2SoftAvcDec>("avc", id); c2_node_id_t id, std::shared_ptr<C2Component>* const component, std::function<void(::android::C2Component*)> deleter) override { *component = std::shared_ptr<C2Component>(new C2SoftAvcDec("avc", id), deleter); return C2_OK; } virtual c2_status_t createInterface( std::shared_ptr<C2ComponentInterface>* const interface, c2_node_id_t id) override { *interface = std::make_shared<C2SoftAvcDecIntf>("avc", id); c2_node_id_t id, std::shared_ptr<C2ComponentInterface>* const interface, std::function<void(::android::C2ComponentInterface*)> deleter) override { *interface = std::shared_ptr<C2ComponentInterface>(new C2SoftAvcDecIntf("avc", id), deleter); return C2_OK; } Loading @@ -1522,9 +1531,11 @@ public: } // namespace android extern "C" ::android::C2ComponentFactory* CreateCodec2Factory() { ALOGV("in %s", __func__); return new ::android::C2SoftAvcDecFactory(); } extern "C" void DestroyCodec2Factory(::android::C2ComponentFactory* factory) { ALOGV("in %s", __func__); delete factory; }
media/libstagefright/codecs/avcdec/C2SoftAvcDec.h +1 −1 Original line number Diff line number Diff line Loading @@ -77,7 +77,7 @@ public: }; C2SoftAvcDecIntf(const char *name, c2_node_id_t id); virtual ~C2SoftAvcDecIntf() = default; virtual ~C2SoftAvcDecIntf() override; // From C2ComponentInterface virtual C2String getName() const override; Loading