codec2: add util method to fill Traits from C2ComponentInterface
Bug: 160259947
Test: manual
Change-Id: I630138a1ac193848acd4f933bc571a2ceeaa4f6c
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index 13c90f2..c07c09e 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -982,58 +982,10 @@
std::shared_ptr<C2Component::Traits> traits(new (std::nothrow) C2Component::Traits);
if (traits) {
- traits->name = intf->getName();
-
- C2ComponentKindSetting kind;
- C2ComponentDomainSetting domain;
- res = intf->query_vb({ &kind, &domain }, {}, C2_MAY_BLOCK, nullptr);
- bool fixDomain = res != C2_OK;
- if (res == C2_OK) {
- traits->kind = kind.value;
- traits->domain = domain.value;
- } else {
- // TODO: remove this fall-back
- ALOGD("failed to query interface for kind and domain: %d", res);
-
- traits->kind =
- (traits->name.find("encoder") != std::string::npos) ? C2Component::KIND_ENCODER :
- (traits->name.find("decoder") != std::string::npos) ? C2Component::KIND_DECODER :
- C2Component::KIND_OTHER;
- }
-
- uint32_t mediaTypeIndex =
- traits->kind == C2Component::KIND_ENCODER ? C2PortMediaTypeSetting::output::PARAM_TYPE
- : C2PortMediaTypeSetting::input::PARAM_TYPE;
- std::vector<std::unique_ptr<C2Param>> params;
- res = intf->query_vb({}, { mediaTypeIndex }, C2_MAY_BLOCK, ¶ms);
- if (res != C2_OK) {
- ALOGD("failed to query interface: %d", res);
+ if (!C2InterfaceUtils::FillTraitsFromInterface(traits.get(), intf)) {
+ ALOGD("Failed to fill traits from interface");
return mInit;
}
- if (params.size() != 1u) {
- ALOGD("failed to query interface: unexpected vector size: %zu", params.size());
- return mInit;
- }
- C2PortMediaTypeSetting *mediaTypeConfig = C2PortMediaTypeSetting::From(params[0].get());
- if (mediaTypeConfig == nullptr) {
- ALOGD("failed to query media type");
- return mInit;
- }
- traits->mediaType =
- std::string(mediaTypeConfig->m.value,
- strnlen(mediaTypeConfig->m.value, mediaTypeConfig->flexCount()));
-
- if (fixDomain) {
- if (strncmp(traits->mediaType.c_str(), "audio/", 6) == 0) {
- traits->domain = C2Component::DOMAIN_AUDIO;
- } else if (strncmp(traits->mediaType.c_str(), "video/", 6) == 0) {
- traits->domain = C2Component::DOMAIN_VIDEO;
- } else if (strncmp(traits->mediaType.c_str(), "image/", 6) == 0) {
- traits->domain = C2Component::DOMAIN_IMAGE;
- } else {
- traits->domain = C2Component::DOMAIN_OTHER;
- }
- }
// TODO: get this properly from the store during emplace
switch (traits->domain) {
@@ -1043,26 +995,6 @@
default:
traits->rank = 512;
}
-
- params.clear();
- res = intf->query_vb({}, { C2ComponentAliasesSetting::PARAM_TYPE }, C2_MAY_BLOCK, ¶ms);
- if (res == C2_OK && params.size() == 1u) {
- C2ComponentAliasesSetting *aliasesSetting =
- C2ComponentAliasesSetting::From(params[0].get());
- if (aliasesSetting) {
- // Split aliases on ','
- // This looks simpler in plain C and even std::string would still make a copy.
- char *aliases = ::strndup(aliasesSetting->m.value, aliasesSetting->flexCount());
- ALOGD("'%s' has aliases: '%s'", intf->getName().c_str(), aliases);
-
- for (char *tok, *ptr, *str = aliases; (tok = ::strtok_r(str, ",", &ptr));
- str = nullptr) {
- traits->aliases.push_back(tok);
- ALOGD("adding alias: '%s'", tok);
- }
- free(aliases);
- }
- }
}
mTraits = traits;
diff --git a/media/codec2/vndk/include/util/C2InterfaceUtils.h b/media/codec2/vndk/include/util/C2InterfaceUtils.h
index e9037e5..13bdac3 100644
--- a/media/codec2/vndk/include/util/C2InterfaceUtils.h
+++ b/media/codec2/vndk/include/util/C2InterfaceUtils.h
@@ -17,6 +17,7 @@
#ifndef C2UTILS_INTERFACE_UTILS_H_
#define C2UTILS_INTERFACE_UTILS_H_
+#include <C2Component.h>
#include <C2Param.h>
#include <C2Work.h>
@@ -1130,6 +1131,19 @@
};
+/**
+ * Utility class for C2ComponentInterface
+ */
+struct C2InterfaceUtils {
+ /**
+ * Create traits from C2ComponentInterface. Note that rank cannot be queried from interfaces,
+ * so left untouched.
+ */
+ static bool FillTraitsFromInterface(
+ C2Component::Traits *traits,
+ const std::shared_ptr<C2ComponentInterface> &intf);
+};
+
#include <util/C2Debug-interface.h>
#endif // C2UTILS_INTERFACE_UTILS_H_
diff --git a/media/codec2/vndk/util/C2InterfaceUtils.cpp b/media/codec2/vndk/util/C2InterfaceUtils.cpp
index 0c1729b..b5bc691 100644
--- a/media/codec2/vndk/util/C2InterfaceUtils.cpp
+++ b/media/codec2/vndk/util/C2InterfaceUtils.cpp
@@ -21,6 +21,7 @@
#define C2_LOG_VERBOSE
+#include <C2Config.h>
#include <C2Debug.h>
#include <C2Param.h>
#include <C2ParamDef.h>
@@ -30,6 +31,7 @@
#include <cmath>
#include <limits>
#include <map>
+#include <sstream>
#include <type_traits>
#include <android-base/stringprintf.h>
@@ -1304,3 +1306,81 @@
return std::vector<Info>(location.begin(), location.end());
}
+//static
+bool C2InterfaceUtils::FillTraitsFromInterface(
+ C2Component::Traits *traits,
+ const std::shared_ptr<C2ComponentInterface> &intf) {
+ if (!traits) {
+ return false;
+ }
+ traits->name = intf->getName();
+
+ C2ComponentKindSetting kind;
+ C2ComponentDomainSetting domain;
+ c2_status_t res = intf->query_vb({ &kind, &domain }, {}, C2_MAY_BLOCK, nullptr);
+ bool fixDomain = res != C2_OK;
+ if (res == C2_OK) {
+ traits->kind = kind.value;
+ traits->domain = domain.value;
+ } else {
+ // TODO: remove this fall-back
+ C2_LOG(DEBUG) << "failed to query interface for kind and domain: " << res;
+
+ traits->kind =
+ (traits->name.find("encoder") != std::string::npos) ? C2Component::KIND_ENCODER :
+ (traits->name.find("decoder") != std::string::npos) ? C2Component::KIND_DECODER :
+ C2Component::KIND_OTHER;
+ }
+
+ uint32_t mediaTypeIndex = traits->kind == C2Component::KIND_ENCODER
+ ? C2PortMediaTypeSetting::output::PARAM_TYPE
+ : C2PortMediaTypeSetting::input::PARAM_TYPE;
+ std::vector<std::unique_ptr<C2Param>> params;
+ res = intf->query_vb({}, { mediaTypeIndex }, C2_MAY_BLOCK, ¶ms);
+ if (res != C2_OK) {
+ C2_LOG(DEBUG) << "failed to query interface: " << res;
+ return false;
+ }
+ if (params.size() != 1u) {
+ C2_LOG(DEBUG) << "failed to query interface: unexpected vector size: " << params.size();
+ return false;
+ }
+ C2PortMediaTypeSetting *mediaTypeConfig = C2PortMediaTypeSetting::From(params[0].get());
+ if (mediaTypeConfig == nullptr) {
+ C2_LOG(DEBUG) << "failed to query media type";
+ return false;
+ }
+ traits->mediaType =
+ std::string(mediaTypeConfig->m.value,
+ strnlen(mediaTypeConfig->m.value, mediaTypeConfig->flexCount()));
+
+ if (fixDomain) {
+ if (strncmp(traits->mediaType.c_str(), "audio/", 6) == 0) {
+ traits->domain = C2Component::DOMAIN_AUDIO;
+ } else if (strncmp(traits->mediaType.c_str(), "video/", 6) == 0) {
+ traits->domain = C2Component::DOMAIN_VIDEO;
+ } else if (strncmp(traits->mediaType.c_str(), "image/", 6) == 0) {
+ traits->domain = C2Component::DOMAIN_IMAGE;
+ } else {
+ traits->domain = C2Component::DOMAIN_OTHER;
+ }
+ }
+
+ params.clear();
+ res = intf->query_vb({}, { C2ComponentAliasesSetting::PARAM_TYPE }, C2_MAY_BLOCK, ¶ms);
+ if (res == C2_OK && params.size() == 1u) {
+ C2ComponentAliasesSetting *aliasesSetting =
+ C2ComponentAliasesSetting::From(params[0].get());
+ if (aliasesSetting) {
+ std::istringstream iss(
+ std::string(aliasesSetting->m.value, aliasesSetting->flexCount()));
+ C2_LOG(DEBUG) << intf->getName() << " has aliases: " << iss.str();
+
+ for (std::string tok; std::getline(iss, tok, ','); ) {
+ traits->aliases.push_back(tok);
+ C2_LOG(DEBUG) << "adding alias: " << tok;
+ }
+ }
+ }
+ return true;
+}