在Codec2框架中,对组件的配置(Setting)、微调(Tuning)以及组件回传的信息(Info)都是通过参数的形式进行传递的。无论是简单参数(只包含一个值)还是复杂参数(包含多个字段),都是以结构体的形式被定义的。Codec2框架提供了全新的参数反射机制,该机制可以在不修改Framework的情况下,将厂商扩展暴露给上层APP使用。要使用这个机制,需要按照Codec2标准来定义参数。
1、参数类型划分
Codec2将参数划分为两大类:一类是与组件配置相关的参数,另一类是与码流数据相关的参数。其中,与组件配置相关的参数又根据使用时机进一步细分为静态配置参数和动态配置参数。
- Setting:只能在Stopped状态下设定;
- Tuning:可以在任何状态下设定此类型的参数;
- Info:与已被处理的数据相关的信息,简单来说就是output携带的信息,该参数也是动态的。
2、参数设计
从整体来看Codec2参数由三部分组成,分别为index、size和data。
- index:参数索引,是唯一的id,记录有参数的类型
- size:整个参数结构体的大小;
- data:参数结构体存储数据的部分。
在Codec2中,大部分的参数只有一个字段,它们的结构参考data1。为了实现复杂功能,不可避免地需要传递包含多个字段的参数,结构参考data2。
data3中包含一个灵活数组成员(Flexible Array Member, FAM),灵活数组在结构体中只能放在结构体的最后。包含灵活数组的结构体比较特殊,因为数组元素不确定,size无法计算。
Blob(Binary Large Object)表示二进制大型对象,通常指的是一块可以存储任意类型数据的二进制数据块。Codec2可能用参数结构体传递一些比较大的数据,该功能使用灵活数组实现。
在Codec2实现中,参数会被划分为Header和Data两部分。Header包含index和size两部分,data可以是一个字段也可以是一个结构体(包含多个字段),用于存储被传递数据。
3、参数结构体字段类型
理论上参数结构体的字段可以是任意类型的,但是为了反射实现更简单,Codec2框架推荐参数字段使用基本数据类型。可用的原始数据类型如下:
- uint64_t
- int64_t
- c2_cntr64_t
- uint32_t
- int32_t
- c2_cntr32_t
- float
我们不熟悉的是c2_cntr32_t和c2_cntr64_t,它们是由Codec2框架定义的用于计数的类型,以c2_cntr32_t为例简单看下它们是怎么使用的。
c2_cntr32_t定义在C2.h中,它是一个模板参数是uint32_t的模板类型:
typedef c2_cntr_t<uint32_t> c2_cntr32_t;
template<typename T, typename B=typename std::enable_if<std::is_integral<T>::value && std::is_unsigned<T>::value>::type>
class C2_HIDE c2_cntr_t {
T mValue;
public:
inline constexpr c2_cntr_t() : mValue(T(0)) {}
template<typename U>
inline constexpr c2_cntr_t(const U &value) : mValue(compat::get(value)) {}
inline constexpr typename std::make_signed<T>::type peek() const {
return static_cast<typename std::make_signed<T>::type>(mValue);
}
inline constexpr typename std::make_signed<T>::type peek() const {
return static_cast<typename std::make_signed<T>::type>(mValue);
}
inline constexpr T peeku() const {
return mValue;
}
inline constexpr long long peekll() const {
return (long long)mValue;
}
inline constexpr unsigned long long peekull() const {
return (unsigned long long)mValue;
}
}
创建c2_cntr32_t和c2_cntr64_t时和普通的数据类型一样,只不过读取数据的时候需要选择合适的方法,用peeku还是peekull。
如果需要传递字符串,可以使用char[],数组长度可以是固定的,也可以是变长的。
4、复杂参数定义
Codec2框架在C2Config.h中预先定义了很多参数,接下来我们用几个例子来看看参数是如何定义的,以便我们能够根据需求自定义新的参数。