这一节我们将对Codec2的跨进程数据传输相关的内容做简单了解。
1、C2Work
Codec2把数据传输(数据处理)抽象为work,一次数据传输可以看作为一个work,一个work包含需要传输的数据,以及数据携带的信息。Code2声明了类C2Work来封装数据与信息,UML类图如下:
C2Work存在一些过度设计,有些字段并未使用,有些结构体的实际使用场景和设计意图有很大出入,如果只看C2Work.h中的注释来理解这部分很容易被带偏。
C2Work的定义如下:
struct C2Work {
std::shared_ptr<C2WorkChainInfo> chainInfo;
C2FrameData input;
std::list<std::unique_ptr<C2Worklet>> worklets;
uint32_t workletsProcessed;
c2_status_t result;
};
- chainInfo:暂未使用,无需了解。
- input:输入数据,以C2FrameData的形式封装,该字段由上层应用填充;
- worklet:输出数据,同样以C2FrameData的形式封装,虽然该字段是一个list类型,但是实际使用中一个C2Work只会装载一块output数据,该字段由组件填充;
- workletsProcessed:标识当前work是否被成功处理,该字段由组件填充;
- result:标识当前work是否被成功处理,该字段由组件填充;该字段含义和workletsProcessed相互重合。
C2FrameData用于封装数据、标志位以及一些需要更新的参数,它的定义如下:
struct C2FrameData {
flags_t flags;
C2WorkOrdinalStruct ordinal;
std::vector<std::shared_ptr<C2Buffer>> buffers;
std::vector<std::unique_ptr<C2Param>> configUpdate;
std::vector<C2InfoBuffer> infoBuffers;
};
- flags:标志位
- FLAG_DROP_FRAME:输入,丢弃此输入帧;
- FLAG_END_OF_STREAM:输入输出,表示当前流已经结束;
- FLAG_DISCARD_FRAME:输出,丢弃此输出帧;
- FLAG_INCOMPLETE:输出,一帧input可能会产出多帧output,此flag用于标记当前输出不是输入产出的最后一帧;
- FLAG_CORRECTED:暂不了解;
- FLAG_CORRUPT:输入输出,如果由输入设定表示当前帧不能被处理,如果由输出设定表示输出帧不可用;
- FLAG_CODEC_CONFIG:当前帧包含csd数据
- ordinal:数据携带的序列信息
- buffers:数据,以C2Buffer的形式存储,虽然字段类型是数组但是实际使用只会存储一块buffer;
- configUpdate:数据携带的配置更新信息,可以由输入设定给组件,组件会用新的配置进行编解码;也可由输出设定,表示组件回传的新的配置更新;
- infoBuffers:信息数据,该字段只有在播放加密流时用到,暂不展开。
C2WorkOrdinalStruct存储的是数据的序列信息,总共有三种信息:
struct C2WorkOrdinalStruct {
c2_cntr64_t timestamp;
c2_cntr64_t frameIndex;
c2_cntr64_t customOrdinal;
};
- timestamp:输入时间戳,由上层应用填充;
- frameIndex:当前数据的序列号,每输入一个数据序号都会加一;
- customOrdinal:组件端设定的序列,一般是reorder之后的时间戳;
C2Worklet有4个成员字段,我们要了解的只有output,它和input相对应,用于存储输出数据:
struct C2Worklet {
c2_node_id_t component;
std::vector<std::unique_ptr<C2Tuning>> tunings;
std::vector<std::unique_ptr<C2SettingResult>> failures;
C2FrameData output;
};
2、WorkBundle
我们已经了解如何把输入数据组织为C2Work,接下来我们一起了解如何跨进程传输C2Work。Android为C2Work、C2FrameData、C2Worklet等结构都定义了对应的hal类型,我们可以在 hardware/interfaces/media/c2/1.0/types.hal 查看相关定义。
跨进程传输时,数据会被组织为WorkBundle:
struct WorkBundle {
vec<Work> works;
vec<BaseBlock> baseBlocks;
};
WorkBundle中有Work和BaseBlock,Work对应C2Work,BaseBlock对应什么呢?先往下看。Work的定义如下:
3、objcpy
4、BufferPoolSender
原文阅读:
Android Codec2(二六)C2Work
扫描下方二维码,关注公众号《青山渺渺》阅读音视频开发内容。