在上一篇文章中,我们详细梳理了HIDL层组件的创建过程。在这一篇文章中,我们将以C2SoftMpeg2Dec为例简单了解SW C2Component的实现架构。
1、C2SoftMpeg2DecFactory
C2ComponentStore通过调用组件实现的C2ComponentFactory完成组件的创建,C2SoftMpeg2Dec实现的factory名为C2SoftMpeg2DecFactory:
class C2SoftMpeg2DecFactory : public C2ComponentFactory {
public:
C2SoftMpeg2DecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>(
GetCodec2PlatformComponentStore()->getParamReflector())) {
}
virtual c2_status_t createComponent(
c2_node_id_t id,
std::shared_ptr<C2Component>* const component,
std::function<void(C2Component*)> deleter) override {
*component = std::shared_ptr<C2Component>(
new C2SoftMpeg2Dec(COMPONENT_NAME,
id,
std::make_shared<C2SoftMpeg2Dec::IntfImpl>(mHelper)),
deleter);
return C2_OK;
}
// ...
private:
std::shared_ptr<C2ReflectorHelper> mHelper;
};
C2SoftMpeg2DecFactory的构造函数会获取C2ComponentStore的C2ReflectorHelper,在创建C2SoftMpeg2Dec实例时,会将C2ReflectorHelper对象作为参数传入C2SoftMpeg2Dec::IntfImpl的构造函数。
C2SoftMpeg2Dec的构造函数有三个参数:
- name:组件名称;
- id:组件在ComponentStore中的id,此id暂时没有用,都为0;
- IntfImpl:组件配置接口,以独立实例的形式与组件实例相互绑定;
2、C2SoftMpeg2Dec::IntfImpl
C2SoftMpeg2Dec::IntfImpl继承于SimpleInterface::BaseParams:
class C2SoftMpeg2Dec::IntfImpl : public SimpleInterface<void>::BaseParams {
public:
explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper)
: SimpleInterface<void>::BaseParams(
helper,
COMPONENT_NAME,
C2Component::KIND_DECODER,
C2Component::DOMAIN_VIDEO,
MEDIA_MIMETYPE_VIDEO_MPEG2) {
// ...
addParameter(
DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY)
.withConstValue(new C2PortActualDelayTuning::output(3u))
.build());
// ...
}
}
SimpleInterface是一个模板类,普通模板版本继承于C2ComponentInterface:
template <typename T>
class SimpleC2Interface : public C2ComponentInterface {
public:
SimpleC2Interface(const char *name, c2_node_id_t id, const std::shared_ptr<T> &impl)
: mName(name),
mId(id),
mImpl(impl) {
}
}
除此之外还有一个模板参数为void的特化版本:
template<>
class SimpleC2Interface<void> {
public:
/**
* Base Codec 2.0 parameters required for all components.
*/
struct BaseParams : C2InterfaceHelper {
explicit BaseParams(
const std::shared_ptr<C2ReflectorHelper> &helper,
C2String name,
C2Component::kind_t kind,
C2Component::domain_t domain,
C2String mediaType,
std::vector<C2String> aliases = std::vector<C2String>());
//...
std::shared_ptr<C2PortActualDelayTuning::input> mActualInputDelay;
std::shared_ptr<C2PortActualDelayTuning::output> mActualOutputDelay;
std::shared_ptr<C2ActualPipelineDelayTuning> mActualPipelineDelay;
//...
};
};
SimpleC2Interface有一个内部类BaseParams,它定义了所有Codec2组件必要的参数,并提供了一些默认参数值的设置方法。BaseParams继承于C2InterfaceHelper,因此参数定义使用的是addParameter。
从BaseParams的构造函数可以看到,组件名称、组件domain、kind、mediaType都是在这里设定的,组件的别名默认是空。
C2SoftMpeg2Dec::IntfImpl继承于BaseParams,需要实例化BaseParams定义的参数,也可以修改BaseParams已经实例化的参数,也可以自定义参数。
3、C2SoftMpeg2Dec
C2SoftMpeg2Dec继承于SimpleC2Component:
struct C2SoftMpeg2Dec : public SimpleC2Component {
C2SoftMpeg2Dec(const char* name, c2_node_id_t id,
const std::shared_ptr<IntfImpl>& intfImpl);
private:
std::shared_ptr<IntfImpl> mIntf;
}
我们先看C2SoftMpeg2Dec的构造函数:
C2SoftMpeg2Dec::C2SoftMpeg2Dec(
const char *name,
c2_node_id_t id,
const std::shared_ptr<IntfImpl> &intfImpl)
: SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)),
mIntf(intfImpl),
mDecHandle(nullptr),
mMemRecords(nullptr),
mOutBufferDrain(nullptr),
mIvColorformat(IV_YUV_420P),
mWidth(320),
mHeight(240),
mOutIndex(0u) {
// If input dump is enabled, then open create an empty file
GENERATE_FILE_NAMES();
CREATE_DUMP_FILE(mInFile);
}
上一节创建的IntfImpl会被封装为普通的SimpleInterface传给SimpleC2Component,同时C2SoftMpeg2Dec本身也会持有一个引用。
template <typename T>
class SimpleC2Interface : public C2ComponentInterface {
public:
SimpleC2Interface(const char *name, c2_node_id_t id, const std::shared_ptr<T> &impl)
: mName(name),
mId(id),
mImpl(impl) {
}
}
C2SoftMpeg2Dec提供了两个宏GENERATE_FILE_NAMES和CREATE_DUMP_FILE,用于dump input bs,这里是可以参考借鉴的。