av_cp(协处理器侧AV)
简介
在嵌入式IoT领域,编解码等功能主频需求较大,单核嵌入式硬件平台已经难以满足复杂的计算需求。而异构多核处理器在音视频编解码运算上具有强大的优势。所以需要将这部分功能置于其他核或带有DSP功能的核上运行。
av_cp是一个轻量级的多核异构核间多媒体AV库,用于协处理器侧(此处称为DSP侧)的固件开发。其与AV组件中的核间处理接口(运行在应用程序处理器侧,此处称为主控侧)配合使用,如核间解码。该库屏蔽了底层核间通信(IPC)的细节,开发人员可直接基于该库使用芯片的多核异构解码、重采样、fft等运算能力。这样可以有效提高音视频播放等功能的实时性、降低产品成本、充分利用硬件资源。
该组件的使用是硬件相关的,当前仅支持pangu芯片。对于其他多核芯片,用户可基于此扩展实现。
核间处理机制
系统上电后,可通过bootloader或在主控侧应用程序初始时先加载DSP固件到指定位置运行。DSP固件启动后,即通过核间通信机制开启监听服务,如核间解码服务。当主控侧调用核间封装的解码器接口时,底层会通过核间通信机制向DSP侧发起核间解码请求。DSP侧核间解码服务接收到该核间请求后,如果资源满足则正确响应该请求,否则返回失败。
核间解码器
核间解码器内部通信机制设计
服务ID
主控侧向DSP侧发起核间解码请求时,需要携带内部定义的核间解码服务ID才能找到DSP侧对应的服务。该服务ID定义如下:
#define AD_ICORE_IPC_SERIVCE_ID 0x10
注意事项:
DSP侧的IPC服务ID不能冲突,否则核间通信创建失败
命令字及内部核间通信消息
解码器通常的操作有打开、解码、重置、关闭等。主控侧在发起核间解码请求时,需要在核间通信消息中携带相应的命令字。命令字定义如下:
enum {
ICORE_CMD_AD_INVALID,
ICORE_CMD_AD_OPEN,
ICORE_CMD_AD_DECODE,
ICORE_CMD_AD_RESET,
ICORE_CMD_AD_CLOSE,
};
打开解码器
ad_icore_t* ad_icore_open(avcodec_id_t id, const adi_conf_t *adi_cnf);
此函数为ICORE_CMD_AD_OPEN对应的内部处理函数。打开解码器内部核间通信消息具体定义如下:
typedef struct {
avcodec_id_t id; ///< 解码器类型
adi_conf_t adi_cnf; ///< 解码器配置信息,某些解码器可能需要
void *ad; ///< DSP侧内部打开的解码器句柄
sf_t sf; ///< 打开解码器后的音频采样格式(可能与解复用出来的格式不一致)
} ad_icore_open_t;
返回值:
调用成功时返回0,否则返回-1。
解码器解码
int ad_icore_decode(ad_icore_t *hdl, avframe_t *frame, int *got_frame, const avpacket_t *pkt);
此函数为ICORE_CMD_AD_DECODE对应的内部处理函数。内部核间通信消息具体定义如下:
typedef struct {
void *ad; ///< DSP侧内部打开的解码器句柄
uint8_t *es_data; ///< 音频编码帧
int32_t es_len; ///< 音频编码帧大小
avframe_t frame; ///< 音频解码后的pcm
int got_frame;///< 本次是否解码一帧标志
} ad_icore_decode_t;
返回值:
调用失败时,返回-1,大于0表示解码一帧消耗的原始编码帧字节数
重置解码器
int ad_icore_reset(ad_icore_t *hdl);
此函数为ICORE_CMD_AD_RESET对应的内部处理函数。内部核间通信消息具体定义如下:
typedef struct {
void *ad; ///< DSP侧内部打开的解码器句柄
} ad_icore_reset_t;
返回值:
调用成功时返回0,否则返回-1。
关闭解码器
int ad_icore_close(ad_icore_t *hdl);
此函数为ICORE_CMD_AD_CLOSE对应的内部处理函数。内部核间通信消息具体定义如下:
typedef struct {
void *ad; ///< DSP侧内部打开的解码器句柄
} ad_icore_close_t;
返回值:
调用成功时返回0,否则返回-1。
DSP侧核间解码器接口及使用
核间解码器初始化
int ad_icore_cp_init();
初始化DSP侧核间解码器模块(一次即可)。该接口成功调用后,DSP侧便成功通过核间通信机制开启监听。主控侧的核间解码功能需要搭配此接口使用。
返回值:
调用成功时返回0,否则返回-1
核间解码器使用
开发者可基于solution/pangu_804demo开发DSP固件。默认demo中提供pangu芯片的mp3核间解码。
用户可修改解决方案下package.yaml中的CONFIG_DECODER_XXX等配置项。如solutions/pangu_804demo/package.yaml中,以下配置项默认可将mp3解码器(pvmp3)注册进去
CONFIG_DECODER_PCM: 1
CONFIG_DECODER_PVMP3: 1
CONFIG_DECODER_FLAC: 0
CONFIG_DECODER_FDK: 0
CONFIG_DECODER_ADPCM_MS: 0
CONFIG_DECODER_AMRNB: 0
CONFIG_DECODER_AMRWB: 0
CONFIG_DECODER_IPC: 0
注意事项:
- 解决方案下package.yaml中的CONFIG_DECODER_IPC配置项不能开启。此选项仅用于主控侧
- 若核间解码支持了mp3,则没有必要在主控侧也注册mp3解码支持。否则会根据对应解码注册的先后顺序使用
- 因对于pangu芯片,DSP侧(cpu1)中链接文件gcc_eflash.ld.S中配置的内存仅1M。若需要加入多个核间解码支持时,需要分配好每个核的内存使用。以防止内存不足导致核间解码异常。
- 编译好的DSP固件存放在generated/data/prim。对于盘古芯片,可将此固件重命名为cpu1。并和主控侧程序一起打包生成对应镜像文件。