Android CCodec Codec2 (九)组件实现分析

在上一篇文章中,我们详细梳理了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,这里是可以参考借鉴的。

4、SimpleC2Component

关注公众号《青山渺渺》订阅合集阅读完整内容

Android CCodec Codec2 (九)组件实现分析_第1张图片

你可能感兴趣的:(Android,Media框架剖析,android,CCodec,Android,Codec2,音视频)