diff options
author | Pawin Vongmasa <pawin@google.com> | 2019-12-16 04:25:41 -0800 |
---|---|---|
committer | Bruno Martins <bgcngm@gmail.com> | 2020-06-06 18:17:47 +0200 |
commit | 90b9b46cb1ae87b101420efbbaff14d338cb241e (patch) | |
tree | 65cc95a1f0f77cc22b3d4a55393f3592440b44bd | |
parent | eb8b20132fdcff88d4a1f2a7db6881eee02e5794 (diff) | |
download | frameworks_av-90b9b46cb1ae87b101420efbbaff14d338cb241e.tar.gz frameworks_av-90b9b46cb1ae87b101420efbbaff14d338cb241e.tar.bz2 frameworks_av-90b9b46cb1ae87b101420efbbaff14d338cb241e.zip |
mediaswcodec: Set "default" as preferred service
Usage mapper will be retrieved from the preferred service if system
properties for mediaswcodec's ION usage are not set.
Test: Define system property "ro.com.android.media.swcodec.ion.heapmask"
and check the log during the startup of mediaswcodec.
Test: Manually log the mapper activity; test if gets invoked from
mediaswcodec and CCodec.
Test: atest CtsMediaTestCases -- \
--module-arg CtsMediaTestCases:size:small
Bug: 144995284
Change-Id: Iebcd89bfa38de3c10b79f878462ba2af347ad332
Merged-In: Iebcd89bfa38de3c10b79f878462ba2af347ad332
(cherry picked from commit 235d6c703672db8923c707eab718233c7d79f4ed)
-rw-r--r-- | services/mediacodec/registrant/Android.bp | 1 | ||||
-rw-r--r-- | services/mediacodec/registrant/CodecServiceRegistrant.cpp | 398 |
2 files changed, 395 insertions, 4 deletions
diff --git a/services/mediacodec/registrant/Android.bp b/services/mediacodec/registrant/Android.bp index fa5bc4a15a..765ac99d2a 100644 --- a/services/mediacodec/registrant/Android.bp +++ b/services/mediacodec/registrant/Android.bp @@ -14,6 +14,7 @@ cc_library_shared { "libbase", "libcodec2_hidl@1.0", "libcodec2_vndk", + "libhidlbase", "libutils", ], diff --git a/services/mediacodec/registrant/CodecServiceRegistrant.cpp b/services/mediacodec/registrant/CodecServiceRegistrant.cpp index 706ebee13a..7f7cecaa1a 100644 --- a/services/mediacodec/registrant/CodecServiceRegistrant.cpp +++ b/services/mediacodec/registrant/CodecServiceRegistrant.cpp @@ -18,21 +18,411 @@ #define LOG_TAG "CodecServiceRegistrant" #include <android-base/logging.h> +#include <android-base/properties.h> +#include <C2Component.h> #include <C2PlatformSupport.h> #include <codec2/hidl/1.0/ComponentStore.h> +#include <codec2/hidl/1.0/Configurable.h> +#include <codec2/hidl/1.0/types.h> +#include <hidl/HidlSupport.h> #include <media/CodecServiceRegistrant.h> +namespace /* unnamed */ { + +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::sp; +using namespace ::android::hardware::media::c2::V1_0; +using namespace ::android::hardware::media::c2::V1_0::utils; + +constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED; + +// Converter from IComponentStore to C2ComponentStore. +class H2C2ComponentStore : public C2ComponentStore { +protected: + sp<IComponentStore> mStore; + sp<IConfigurable> mConfigurable; +public: + explicit H2C2ComponentStore(sp<IComponentStore> const& store) + : mStore{store}, + mConfigurable{[store]() -> sp<IConfigurable>{ + if (!store) { + return nullptr; + } + Return<sp<IConfigurable>> transResult = + store->getConfigurable(); + return transResult.isOk() ? + static_cast<sp<IConfigurable>>(transResult) : + nullptr; + }()} { + if (!mConfigurable) { + LOG(ERROR) << "Preferred store is corrupted."; + } + } + + virtual ~H2C2ComponentStore() override = default; + + virtual c2_status_t config_sm( + std::vector<C2Param*> const ¶ms, + std::vector<std::unique_ptr<C2SettingResult>>* const failures + ) override { + Params hidlParams; + if (!createParamsBlob(&hidlParams, params)) { + LOG(ERROR) << "config -- bad input."; + return C2_TRANSACTION_FAILED; + } + c2_status_t status{}; + Return<void> transResult = mConfigurable->config( + hidlParams, + true, + [&status, ¶ms, failures]( + Status s, + const hidl_vec<SettingResult> f, + const Params& o) { + status = static_cast<c2_status_t>(s); + if (status != C2_OK && status != C2_BAD_INDEX) { + LOG(DEBUG) << "config -- call failed: " + << status << "."; + } + size_t i = failures->size(); + failures->resize(i + f.size()); + for (const SettingResult& sf : f) { + if (!objcpy(&(*failures)[i++], sf)) { + LOG(ERROR) << "config -- " + << "invalid SettingResult returned."; + return; + } + } + if (!updateParamsFromBlob(params, o)) { + LOG(ERROR) << "config -- " + << "failed to parse returned params."; + status = C2_CORRUPTED; + } + }); + if (!transResult.isOk()) { + LOG(ERROR) << "config -- transaction failed."; + return C2_TRANSACTION_FAILED; + } + return status; + }; + + virtual c2_status_t copyBuffer( + std::shared_ptr<C2GraphicBuffer>, + std::shared_ptr<C2GraphicBuffer>) override { + LOG(ERROR) << "copyBuffer -- not supported."; + return C2_OMITTED; + } + + virtual c2_status_t createComponent( + C2String, std::shared_ptr<C2Component> *const component) override { + component->reset(); + LOG(ERROR) << "createComponent -- not supported."; + return C2_OMITTED; + } + + virtual c2_status_t createInterface( + C2String, std::shared_ptr<C2ComponentInterface> *const interface) { + interface->reset(); + LOG(ERROR) << "createInterface -- not supported."; + return C2_OMITTED; + } + + virtual c2_status_t query_sm( + const std::vector<C2Param *> &stackParams, + const std::vector<C2Param::Index> &heapParamIndices, + std::vector<std::unique_ptr<C2Param>> *const heapParams) const + override { + hidl_vec<ParamIndex> indices( + stackParams.size() + heapParamIndices.size()); + size_t numIndices = 0; + for (C2Param* const& stackParam : stackParams) { + if (!stackParam) { + LOG(WARNING) << "query -- null stack param encountered."; + continue; + } + indices[numIndices++] = static_cast<ParamIndex>(stackParam->index()); + } + size_t numStackIndices = numIndices; + for (const C2Param::Index& index : heapParamIndices) { + indices[numIndices++] = + static_cast<ParamIndex>(static_cast<uint32_t>(index)); + } + indices.resize(numIndices); + if (heapParams) { + heapParams->reserve(heapParams->size() + numIndices); + } + c2_status_t status; + Return<void> transResult = mConfigurable->query( + indices, + true, + [&status, &numStackIndices, &stackParams, heapParams]( + Status s, const Params& p) { + status = static_cast<c2_status_t>(s); + if (status != C2_OK && status != C2_BAD_INDEX) { + LOG(DEBUG) << "query -- call failed: " + << status << "."; + return; + } + std::vector<C2Param*> paramPointers; + if (!parseParamsBlob(¶mPointers, p)) { + LOG(ERROR) << "query -- error while parsing params."; + status = C2_CORRUPTED; + return; + } + size_t i = 0; + for (auto it = paramPointers.begin(); + it != paramPointers.end(); ) { + C2Param* paramPointer = *it; + if (numStackIndices > 0) { + --numStackIndices; + if (!paramPointer) { + LOG(WARNING) << "query -- null stack param."; + ++it; + continue; + } + for (; i < stackParams.size() && !stackParams[i]; ) { + ++i; + } + if (i >= stackParams.size()) { + LOG(ERROR) << "query -- unexpected error."; + status = C2_CORRUPTED; + return; + } + if (stackParams[i]->index() != paramPointer->index()) { + LOG(WARNING) << "query -- param skipped: " + "index = " + << stackParams[i]->index() << "."; + stackParams[i++]->invalidate(); + continue; + } + if (!stackParams[i++]->updateFrom(*paramPointer)) { + LOG(WARNING) << "query -- param update failed: " + "index = " + << paramPointer->index() << "."; + } + } else { + if (!paramPointer) { + LOG(WARNING) << "query -- null heap param."; + ++it; + continue; + } + if (!heapParams) { + LOG(WARNING) << "query -- " + "unexpected extra stack param."; + } else { + heapParams->emplace_back( + C2Param::Copy(*paramPointer)); + } + } + ++it; + } + }); + if (!transResult.isOk()) { + LOG(ERROR) << "query -- transaction failed."; + return C2_TRANSACTION_FAILED; + } + return status; + } + + virtual c2_status_t querySupportedParams_nb( + std::vector<std::shared_ptr<C2ParamDescriptor>> *const params) const { + c2_status_t status; + Return<void> transResult = mConfigurable->querySupportedParams( + std::numeric_limits<uint32_t>::min(), + std::numeric_limits<uint32_t>::max(), + [&status, params]( + Status s, + const hidl_vec<ParamDescriptor>& p) { + status = static_cast<c2_status_t>(s); + if (status != C2_OK) { + LOG(DEBUG) << "querySupportedParams -- call failed: " + << status << "."; + return; + } + size_t i = params->size(); + params->resize(i + p.size()); + for (const ParamDescriptor& sp : p) { + if (!objcpy(&(*params)[i++], sp)) { + LOG(ERROR) << "querySupportedParams -- " + << "invalid returned ParamDescriptor."; + return; + } + } + }); + if (!transResult.isOk()) { + LOG(ERROR) << "querySupportedParams -- transaction failed."; + return C2_TRANSACTION_FAILED; + } + return status; + } + + virtual c2_status_t querySupportedValues_sm( + std::vector<C2FieldSupportedValuesQuery> &fields) const { + hidl_vec<FieldSupportedValuesQuery> inFields(fields.size()); + for (size_t i = 0; i < fields.size(); ++i) { + if (!objcpy(&inFields[i], fields[i])) { + LOG(ERROR) << "querySupportedValues -- bad input"; + return C2_TRANSACTION_FAILED; + } + } + + c2_status_t status; + Return<void> transResult = mConfigurable->querySupportedValues( + inFields, + true, + [&status, &inFields, &fields]( + Status s, + const hidl_vec<FieldSupportedValuesQueryResult>& r) { + status = static_cast<c2_status_t>(s); + if (status != C2_OK) { + LOG(DEBUG) << "querySupportedValues -- call failed: " + << status << "."; + return; + } + if (r.size() != fields.size()) { + LOG(ERROR) << "querySupportedValues -- " + "input and output lists " + "have different sizes."; + status = C2_CORRUPTED; + return; + } + for (size_t i = 0; i < fields.size(); ++i) { + if (!objcpy(&fields[i], inFields[i], r[i])) { + LOG(ERROR) << "querySupportedValues -- " + "invalid returned value."; + status = C2_CORRUPTED; + return; + } + } + }); + if (!transResult.isOk()) { + LOG(ERROR) << "querySupportedValues -- transaction failed."; + return C2_TRANSACTION_FAILED; + } + return status; + } + + virtual C2String getName() const { + C2String outName; + Return<void> transResult = mConfigurable->getName( + [&outName](const hidl_string& name) { + outName = name.c_str(); + }); + if (!transResult.isOk()) { + LOG(ERROR) << "getName -- transaction failed."; + } + return outName; + } + + virtual std::shared_ptr<C2ParamReflector> getParamReflector() const + override { + struct SimpleParamReflector : public C2ParamReflector { + virtual std::unique_ptr<C2StructDescriptor> describe( + C2Param::CoreIndex coreIndex) const { + hidl_vec<ParamIndex> indices(1); + indices[0] = static_cast<ParamIndex>(coreIndex.coreIndex()); + std::unique_ptr<C2StructDescriptor> descriptor; + Return<void> transResult = mBase->getStructDescriptors( + indices, + [&descriptor]( + Status s, + const hidl_vec<StructDescriptor>& sd) { + c2_status_t status = static_cast<c2_status_t>(s); + if (status != C2_OK) { + LOG(DEBUG) << "SimpleParamReflector -- " + "getStructDescriptors() failed: " + << status << "."; + descriptor.reset(); + return; + } + if (sd.size() != 1) { + LOG(DEBUG) << "SimpleParamReflector -- " + "getStructDescriptors() " + "returned vector of size " + << sd.size() << ". " + "It should be 1."; + descriptor.reset(); + return; + } + if (!objcpy(&descriptor, sd[0])) { + LOG(DEBUG) << "SimpleParamReflector -- " + "getStructDescriptors() returned " + "corrupted data."; + descriptor.reset(); + return; + } + }); + return descriptor; + } + + explicit SimpleParamReflector(sp<IComponentStore> base) + : mBase(base) { } + + sp<IComponentStore> mBase; + }; + + return std::make_shared<SimpleParamReflector>(mStore); + } + + virtual std::vector<std::shared_ptr<const C2Component::Traits>> + listComponents() override { + LOG(ERROR) << "listComponents -- not supported."; + return {}; + } +}; + +bool ionPropertiesDefined() { + using namespace ::android::base; + std::string heapMask = + GetProperty("ro.com.android.media.swcodec.ion.heapmask", "undefined"); + std::string flags = + GetProperty("ro.com.android.media.swcodec.ion.flags", "undefined"); + std::string align = + GetProperty("ro.com.android.media.swcodec.ion.align", "undefined"); + if (heapMask != "undefined" || + flags != "undefined" || + align != "undefined") { + LOG(INFO) + << "Some system properties for mediaswcodec ION usage are set: " + << "heapmask = " << heapMask << ", " + << "flags = " << flags << ", " + << "align = " << align << ". " + << "Preferred Codec2 store is defaulted to \"software\"."; + return true; + } + return false; +} + +} // unnamed namespace + extern "C" void RegisterCodecServices() { - using namespace ::android::hardware::media::c2::V1_0; + using ComponentStore = ::android::hardware::media::c2::V1_0::utils:: + ComponentStore; LOG(INFO) << "Creating software Codec2 service..."; - android::sp<IComponentStore> store = - new utils::ComponentStore( - android::GetCodec2PlatformComponentStore()); + sp<ComponentStore> store = + new ComponentStore(::android::GetCodec2PlatformComponentStore()); if (store == nullptr) { LOG(ERROR) << "Cannot create software Codec2 service."; } else { + if (!ionPropertiesDefined()) { + std::string preferredStoreName = "default"; + sp<IComponentStore> preferredStore = + IComponentStore::getService(preferredStoreName.c_str()); + if (preferredStore) { + ::android::SetPreferredCodec2ComponentStore( + std::make_shared<H2C2ComponentStore>(preferredStore)); + LOG(INFO) << + "Preferred Codec2 store is set to \"" << + preferredStoreName << "\"."; + } else { + LOG(INFO) << + "Preferred Codec2 store is defaulted to \"software\"."; + } + } if (store->registerAsService("software") != android::OK) { LOG(ERROR) << "Cannot register software Codec2 service."; |