通过之前的介绍我们了解到,Codec2模块的功能实现与配置实现是相互分离的,Codec2框架设计了一组API用于获取与模块关联的配置对象。
Codec2给ComponentStore设计了名为getConfigurable的API,用于获取Store中的参数对象:
struct ComponentStore : public IComponentStore {
virtual Return<sp<IConfigurable>> getConfigurable() override;
}
给Component设计的API是getInterface:
struct Component : public IComponent {
virtual Return<sp<IComponentInterface>> getInterface() override;
}
两个API看似不一样,实则是一样的。IComponentInterface内部有一个接口getConfigurable:
struct ComponentInterface : public IComponentInterface {
virtual Return<sp<IConfigurable>> getConfigurable() override;
}
所以,调用组件的getInterface方法拿到IComponentInterface对象后,还要再调用一次getConfigurable才能拿到与组件相关联的参数配置。
IConfigurable有四个与参数配置相关的接口:
virtual Return<void> query(
const hidl_vec<uint32_t>& indices,
bool mayBlock,
query_cb _hidl_cb) override;
virtual Return<void> config(
const hidl_vec<uint8_t>& inParams,
bool mayBlock,
config_cb _hidl_cb) override;
virtual Return<void> querySupportedParams(
uint32_t start,
uint32_t count,
querySupportedParams_cb _hidl_cb) override;
virtual Return<void> querySupportedValues(
const hidl_vec<FieldSupportedValuesQuery>& inFields,
bool mayBlock,
querySupportedValues_cb _hidl_cb) override;
后续用的最多的是query和config方法,接下来我们将以C2Store为例,对他俩的调用流程进行梳理。为了能将调用流程看得更清楚,这里要再贴一遍C2Store的UML类图:
Return<void> CachedConfigurable::query(
const hidl_vec<uint32_t>& indices,
bool mayBlock,
query_cb _hidl_cb) {
typedef C2Param::Index Index;
std::vector<Index> c2heapParamIndices(
(Index*)indices.data(),
(Index*)indices.data() + indices.size());
std::vector<std::unique_ptr<C2Param>> c2heapParams;
c2_status_t c2res = mIntf->query(
c2heapParamIndices,
mayBlock ? C2_MAY_BLOCK : C2_DONT_BLOCK,
&c2heapParams);
hidl_vec<uint8_t> params;
if (!createParamsBlob(¶ms, c2heapParams)) {
LOG(WARNING) << "query -- invalid output params.";
}
_hidl_cb(static_cast<Status>(c2res), params);
return Void();
}
query方法传入参数是一个hidl_vec,可以一次请求一个参数的值,也可以一次请求多个参数的值。hidl_vec元素类型为uint32_t。
struct StoreIntf : public ConfigurableC2Intf {
virtual c2_status_t query(
const std::vector<C2Param::Index> &indices,
c2_blocking_t mayBlock,
std::vector<std::unique_ptr<C2Param>> *const params) const override {
if (mayBlock == C2_DONT_BLOCK && indices.size() != 0) {
return C2_BLOCKING;
}
return mStore->query_sm({}, indices, params);
}
}
c2_status_t C2PlatformComponentStore::query_sm(
const std::vector<C2Param*> &stackParams,
const std::vector<C2Param::Index> &heapParamIndices,
std::vector<std::unique_ptr<C2Param>> *const heapParams) const {
return mInterface.query(stackParams, heapParamIndices, C2_MAY_BLOCK, heapParams);
}
通过上一节的学习我们可以知道,mInterface是继承于C2InterfaceHelper的,因此最终调用的是C2InterfaceHelper的query方法。
c2_status_t C2InterfaceHelper::query(
const std::vector<C2Param*> &stackParams,
const std::vector<C2Param::Index> &heapParamIndices,
c2_blocking_t mayBlock __unused /* TODO */,
std::vector<std::unique_ptr<C2Param>>* const heapParams) const {
std::lock_guard<std::mutex> lock(mMutex);
bool paramWasInvalid = false;
bool paramNotFound = false;
bool paramDidNotFit = false;
bool paramNoMemory = false;
// ...
// 遍历要获取参数的索引
for (const C2Param::Index ix : heapParamIndices) {
// 调用Factory的getParamValue方法
std::shared_ptr<C2Param> value = _mFactory->getParamValue(ix);
if (value) {
// 如果value不为null,则拷贝一份C2Param
std::unique_ptr<C2Param> p = C2Param::Copy(*value);
if (p != nullptr) {
heapParams->push_back(std::move(p));
} else {
heapParams->push_back(nullptr);
paramNoMemory = true;
}
} else {
heapParams->push_back(nullptr);
paramNotFound = true;
}
}
return paramNoMemory ? C2_NO_MEMORY :
paramNotFound ? C2_BAD_INDEX :
// the following errors are not marked in the return value
paramDidNotFit ? C2_OK :
paramWasInvalid ? C2_OK : C2_OK;
}
原文阅读:
扫描下方二维码,关注公众号《青山渺渺》阅读音视频开发内容。
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- hzar.cn 版权所有 赣ICP备2024042791号-5
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务