summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPawin Vongmasa <pawin@google.com>2019-12-16 04:25:41 -0800
committerBruno Martins <bgcngm@gmail.com>2020-06-06 18:17:47 +0200
commit90b9b46cb1ae87b101420efbbaff14d338cb241e (patch)
tree65cc95a1f0f77cc22b3d4a55393f3592440b44bd
parenteb8b20132fdcff88d4a1f2a7db6881eee02e5794 (diff)
downloadframeworks_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.bp1
-rw-r--r--services/mediacodec/registrant/CodecServiceRegistrant.cpp398
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 &params,
+ 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, &params, 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(&paramPointers, 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.";