图形视频模块开发
按场景展开模块开发
在完成前述最小送显闭环后,按业务场景继续开发:图层绘制、混合和格式转换依次使用 VAU 与 DPU;图片预览在 JPEG 解码后将输出 Surface 交给 VAU/DPU;屏幕适配先完成 LCD 初始化;视频采集、编码、解码分别进入 VICAP、VENC、VDEC 分支。以下内容保留各场景的功能限制、参数表、流程图和代码示例,阅读时应只选择当前链路需要的分支。
VAU
接口参考:/src/middleware/utils/common_headers/gpu/external/soc_vau_api.h。
VAU 概述
矢量加速单元VAU(Vector Acceleration Unit)主要包含矢量绘制、矩阵变换、2.5D、多层混合叠加、低功耗、高性能(60@fps)、低内存等功能。
VAU 功能描述
VAU模块提供如表1所示接口。
表 1 VAU模块接口
接口 |
描述 |
|---|---|
uapi_vau_create |
返回对应任务的句柄。 |
uapi_vau_cancel |
取消对应任务。 |
uapi_vau_destroy |
销毁对应任务 |
uapi_vau_fill |
快速填充颜色,对surface填充的颜色为color值,color的格式支持:ARGB8888、RGB888。 |
uapi_vau_render |
矢量图形绘制,主要用于绘制矢量基本图形。 |
uapi_vau_compose |
多图层叠加,可支持叠加、仿射变换、ColorKey、ROP等操作(多个操作一次性提交)。 |
uapi_vau_submit |
提交任务。 |
uapi_vau_parse_cmp_header |
解析压缩文件头。 |
uapi_vau_wait_for_done |
等待任务完成。 |
-
矩形填充
用某种颜色填充表面的某一矩形区域,矩形填充支持Alpha混和。
-
数据搬移
数据搬移过程中可以完成像素格式转换、Alpha混和、ColorKey、ROP等,也可进行缩放、旋转、镜像变换。
-
像素格式转换
Blit模块支持以下像素格式转换:
- 源位图像素格式:ARGB8888、RGB888、RGB565、ARGB1555、ARGB4444、A1、A8。
- 目标位图像素格式:ARGB8888、RGB888、RGB565、ARGB1555、ARGB4444。
-
Alpha混和
将多个位图的像素值按照Alpha值进行加权求和,得到一个Alpha混和后的位图。Alpha可来源于源位图、目标位图和全局Alpha。
-
ColorKey
- 对源位图进行ColorKey,则把位图从源地址搬移到输出地址,在此过程中,颜色为关键色的位图像素使用目标位图数据替换。
- 对目标位图进行ColorKey,则把位图从目标地址搬移到输出地址,在此过程中,颜色为与关键色不相同的位图像素用源位图数据替换。
-
ROP
对源位图和目标位图的颜色值进行布尔运算。
VAU 开发指引
以使用VAU两层叠加为例,surface1作为背景通过VAU纯色填充,surface2作为前景,surface1与surface2进行叠加。
-
设置surface1和surface2的属性配置:
#define TEST_VAU_W 454 #define TEST_VAU_H 454 #define TEST_VAU_PSRAM_OFFSET 0x6C200000 #define TEST_VAU_MAX_BUF_SIZE 0x10000000 ext_vau_surface src_surface[2] = {0}; ext_vau_surface dst_surface = {0}; ext_vau_surface_list surface_list = {0}; ext_vau_blit_opt opt = {0}; /* src_surface[0] backgroud fill color red */ src_surface[0].width = TEST_VAU_W; src_surface[0].height = TEST_VAU_H; src_surface[0].phy_addr = TEST_VAU_PSRAM_OFFSET + 0xD0000; src_surface[0].color_fmt = EXT_GFX_FMT_ARGB8888; src_surface[0].compress_mode = EXT_GFX_COMPRESS_NONE; src_surface[0].argb_order = EXT_GFX_FMT_ORDER_ARGB; src_surface[0].rect.x = 100; src_surface[0].rect.y = 100; src_surface[0].rect.width = 256; /* 256:index */ src_surface[0].rect.height = 256; /* 256:index */ src_surface[0].stride = 1816; /* 454 * 32 / 8 = 1816 */ src_surface[0].is_color_surface = TD_TRUE; src_surface[0].color = 0xffff0000; memset_s((void *)src_surface[0].phy_addr, TEST_VAU_MAX_BUF_SIZE, 0xff, src_surface[0].stride * src_surface[0].height); /* src_surface[1] foreground white */ src_surface[1].width = 256; /* 256:index */ src_surface[1].height = 256; /* 256:index */ src_surface[1].phy_addr = TEST_VAU_PSRAM_OFFSET; src_surface[1].color_fmt = EXT_GFX_FMT_RGB565; src_surface[1].argb_order = EXT_GFX_FMT_ORDER_ARGB; src_surface[1].compress_mode = EXT_GFX_COMPRESS_NONE; src_surface[1].rect.x = 0; src_surface[1].rect.y = 0; src_surface[1].rect.width = src_surface[1].width; src_surface[1].rect.height = src_surface[1].height; src_surface[1].stride = 912; /* 454 * 16 / 8 = 908, 8字节对齐得912 */ memset_s((void *)src_surface[1].phy_addr, TEST_VAU_MAX_BUF_SIZE, 0x0, src_surface[1].stride * src_surface[1].height); src_surface[1].alpha_info.global_alpha_en = TD_TRUE; src_surface[1].alpha_info.global_alpha = 0x50; src_surface[1].alpha_info.pixel_alpha_en = TD_TRUE; src_surface[1].alpha_info.premult_en = TD_TRUE; -
设置dst surface的属性:
/* dst surface */ dst_surface.width = TEST_VAU_W; dst_surface.height = TEST_VAU_H; dst_surface.phy_addr = TEST_VAU_PSRAM_OFFSET + 0xD0000; dst_surface.color_fmt = EXT_GFX_FMT_ARGB8888; dst_surface.compress_mode = EXT_GFX_COMPRESS_NONE; dst_surface.argb_order = EXT_GFX_FMT_ORDER_ARGB; dst_surface.rect.x = src_surface[0].rect.x; dst_surface.rect.y = src_surface[0].rect.y; dst_surface.rect.width = src_surface[0].rect.width; dst_surface.rect.height = src_surface[0].rect.height; dst_surface.stride = 1816; /* 454 * 32 / 8 = 1816 */ opt.blend_opt.blend_enable = TD_TRUE; opt.blend_opt.blend_cmd = EXT_VAU_BLENDCMD_SRCOVER; /* 正常绘制显示,上下层绘制叠加 */ opt.blend_opt.out_alpha_mode = EXT_VAU_OUTALPHA_FROM_FOREGROUND; /* alpha来自前景 */ surface_list.src_surface_cnt = 2; /* 2:index */ surface_list.src_surface = src_surface; surface_list.dst_surface = &dst_surface; surface_list.opt = &opt; -
执行一次blit操作:
td_s32 ret; td_handle handle; handle = uapi_vau_create(); if (handle <= 0) { printf("uapi_vau_create failed\n"); return EXT_FAILURE; } ret = uapi_vau_compose(handle, &surface_list); if (ret != EXT_SUCCESS) { printf("uapi_vau_compose failed\n"); uapi_vau_destroy(handle); return ret; } ret = uapi_vau_submit(handle, TD_TRUE, 1000); /* 1000 ms timeout */ if (ret != EXT_SUCCESS) { uapi_vau_cancel(handle); printf("uapi_vau_submit failed\n"); uapi_vau_destroy(handle); return ret; } uapi_vau_destroy(handle);
DPU
接口参考:/src/middleware/utils/common_headers/gpu/external/soc_dpu_api.h。
DPU 概述
显示处理单元DPU(Display Processing Unit)主要对图形显示通路的处理,包含多层叠加、自研压缩数据解压、局部刷新、低功耗等功能。
DPU 功能描述
- 支持两层在线叠加。
- 支持RTOS操作系统。
- 支持SRAM存储访问。
- 支持PSRAM存储访问。
- 支持低功耗。
- 支持输入分辨率可设。
- 支持CMD模式刷新显示。
- 支持对接MIPI接口实现图形显示。
- 支持对接QSPI接口实现图形显示。
- 支持DFX。
- 支持低Flash下DPU运行。
- 支持低内存下DPU运行。
- 支持图层ColorKey。
- 申请地址16Byte对齐。
- 输入stride要求16Byte对齐。
- G0/G1支持的颜色格式:RGB888/RGB565。
表 1 DPU模块接口
接口 |
说明 |
|---|---|
uapi_dpu_create_layer |
创建图层。 |
uapi_dpu_destroy_layer |
销毁图层。 |
uapi_dpu_set_layer_alpha |
设置图层全局Alpha。 |
uapi_dpu_get_layer_alpha |
获取图层全局Alpha。 |
uapi_dpu_set_layer_pos |
设置图层在屏上的显示位置。 |
uapi_dpu_get_layer_pos |
获取图层在屏上的显示位置。 |
uapi_dpu_set_layer_zorder |
设置图层Z序。 |
uapi_dpu_get_layer_zorder |
获取图层Z序。 |
uapi_dpu_show_layer |
显示图层。 |
uapi_dpu_hide_layer |
隐藏图层。 |
uapi_dpu_set_layer_info |
设置图层信息。 |
uapi_dpu_get_layer_info |
获取图层信息。 |
uapi_dpu_set_layer_colorkey |
设置图层的ColorKey。 |
uapi_dpu_get_layer_colorkey |
获取图层的ColorKey。 |
uapi_dpu_refresh_layers |
刷新显示。 |
uapi_dpu_wait_layer_vsync |
等待显示完成。 |
uapi_dpu_set_layer_vblank |
设置等待标记。 |
uapi_dpu_get_layer_vblank |
获取等待标记。 |
uapi_dpu_query_layer_state |
查询图层的显示完成状态。 |
uapi_dpu_set_output_info |
配置输出参数。 |
DPU 开发指引
-
通过接口uapi_dpu_create_layer创建显示图层,并返回图层句柄:
td_s32 ret; td_handle dpu_handle; ext_dpu_surface dpu_canvas = { 0 }; ext_dpu_layer_info layer_info = { 0 }; /* dst_surface vau的输出surface */ layer_info.width = dst_surface->width; layer_info.height = dst_surface->height; layer_info.layer_id = EXT_DPU_LAYER_ID1; layer_info.layer_fmt = dst_surface->color_fmt; layer_info.compress_mode = dst_surface->compress_mode; /* NORMAL模式(双canvas送显模式) */ layer_info.buf_mode = EXT_DPU_BUFFER_MODE_NORMAL; ret = uapi_dpu_create_layer(&layer_info, &dpu_handle); if (ret != EXT_SUCCESS) { printf("call uapi_dpu_create_layer fail, ret:0x%x\n", ret); return ret; } -
通过接口uapi_dpu_set_layer_info设置图层显示信息:
dpu_canvas.width = dst_surface->width; dpu_canvas.height = dst_surface->height; dpu_canvas.stride = dst_surface->stride; dpu_canvas.size = dpu_canvas.height * dpu_canvas.stride; dpu_canvas.phy_addr = dst_surface->phy_addr; dpu_canvas.vir_addr = dst_surface->vir_addr; dpu_canvas.update_rect = TD_NULL; dpu_canvas.color_fmt = dst_surface->color_fmt; dpu_canvas.compress_mode = dst_surface->compress_mode; ret = uapi_dpu_set_layer_info(dpu_handle, &dpu_canvas); if (ret != EXT_SUCCESS) { printf("call uapi_dpu_set_layer_info fail, ret:0x%x\n", ret); return ret; } -
调用接口uapi_dpu_refresh_layers刷新显示内容:
JPEG
接口参考:/src/middleware/utils/common_headers/gpu/external/soc_jpeg_api.h。
JPEG 概述
穿戴手表对体验的需求越来越高,如视频预览(手表控制手机拍照,在手表端可看到要拍照的内容)、本地视频播放(如视频表盘),而这些应用需要支持JPEG解码的功能。

JPEG 功能描述
- 支持文件方式输入。
- 支持内存方式输入。
- 支持解码输出yuv420 semi-planer格式的数据。
- 支持解码缩小1倍、2倍、4倍、8倍。
- 支持获取缩略图。
JPEG 开发指引
JPEG提供的接口说明请参考API说明,后续章节通过demo来指导应用如何使用。
获取缩略图
void demo_get_exif_data(char *file_name)
{
int ret;
static int cnt = 0;
FILE *in_file = NULL;
FILE *ou_file = NULL;
struct jpeg_decompress_struct dinfo = { 0 };
struct jpeg_source_struct src = { 0 };
in_file = fopen(file_name, "rb");
if (in_file == NULL) {
return;
}
/* 设置输入流信息 */
src.infile = in_file;
/* 缩略图操作使能 */
dinfo.thumbnail_en = TD_TRUE;
/* 创建解码器,该函数包含对文件头的解析处理 */
ret = uapi_jpeg_decomress_create(&dinfo, &src, TD_FALSE);
if (ret != 0) {
fclose(in_file);
return;
}
/* 缩略图要写入的文件路径和文件名 */
snprintf(file_name, SAMPLE_JPEG_EXIF_FILE_PATH_LEN, "%s/out_%d.jpg", SAMPLE_JPEG_EXIF_FILE_DIR, cnt++);
/* 将缩略图数据写到文件中 */
ou_file = fopen(file_name, "wb");
fwrite(dinfo.thumbnail.buffer, 1, dinfo.thumbnail.size, ou_file);
fclose(ou_file);
/* 销毁解码器 */
uapi_jpeg_decompress_destroy(&dinfo);
fclose(in_file);
return;
}
解码后数据输出 yuv420 semi-planar
void demo_decompress_to_yuvsp(char *file_name)
{
int ret;
FILE *in_file = NULL;
struct jpeg_decompress_struct dinfo = { 0 };
struct jpeg_source_struct src = { 0 };
struct jpeg_dst_struct dst = { 0 };
in_file = fopen(file_name, "rb");
if (in_file == NULL) {
return;
}
/* 设置输入流信息 */
src.infile = in_file;
/* 缩小1倍 */
dinfo.scale = JPEG_SCALE_1;
/* 解码输出格式和图片格式保持一致 */
dinfo.output_yuv420sp = TD_TRUE;
/* 创建解码器 */
ret = uapi_jpeg_decomress_create(&dinfo, &src, TD_FALSE);
if (ret != 0) {
fclose(in_file);
return;
}
/* 根据图片信息分配内存 */
dst.stride = dinfo.output.stride[0];
dst.uv_stride = dinfo.output.stride[1];
dst.size = dinfo.output.size[0] + dinfo.output.size[1];
dst.uv_offset = dinfo.output.size[0];
/* 内存分配 */
dst.phy_buf = mpi_mmz_new(dst.size, 64, NULL, "JPEG");
if (dst.phy_buf == 0) {
fclose(in_file);
return;
}
dst.vir_buf = (td_char *)mpi_mmz_map(dst.phy_buf, 0);
if (dst.vir_buf == NULL) {
mpi_mmz_delete(dst.phy_buf);
fclose(in_file);
return;
}
/* 启动解码 */
uapi_jpeg_decompress_start(&dinfo, &dst);
/* 销毁解码器 */
uapi_jpeg_decompress_destroy(&dinfo);
/* 释放资源 */
mpi_mmz_unmap(dst.phy_buf);
mpi_mmz_delete(dst.phy_buf);
fclose(in_file);
return;
}
JPEG 注意事项
只支持baseline,数据精度为8的JPEG图片。
LCD
接口参考:/src/drivers/drivers/driver/lcd/include/soc_lcd_api.h。
LCD 概述
LCD为屏端控制驱动提供显示、进出睡眠、进出IDLE、读写屏端控制寄存器、设置获取屏幕亮度等功能。
LCD 功能描述
LCD模块提供以下接口:
表 1 LCD提供的接口
接口 |
描述 |
|---|---|
uapi_lcd_info_register |
屏幕信息注册,包括屏幕分辨率、帧率、通信串口类型及指令集等。 |
uapi_lcd_init |
LCD驱动初始化。 |
uapi_lcd_deinit |
LCD驱动去初始化。 |
uapi_lcd_get_status |
获取屏幕当前状态。 |
uapi_lcd_enter_sleep_mode |
使屏端进入睡眠模式。 |
uapi_lcd_exit_sleep_mode |
使屏端退出睡眠模式。 |
uapi_lcd_enter_idle_mode |
使屏端进入IDLE模式。 |
uapi_lcd_exit_idle_mode |
使屏端退出IDLE模式。 |
uapi_lcd_te_on |
使能te信号。 |
uapi_lcd_te_off |
关闭te信号。 |
uapi_lcd_set_brightness |
设置屏幕亮度。 |
uapi_lcd_get_brightness |
获取当前屏幕亮度。 |
uapi_lcd_write_reg |
将数据写入屏端寄存器。 |
uapi_lcd_read_reg |
从屏端寄存器读取数据。 |
uapi_lcd_init接口支持屏端复位、串口初始化、屏端初始化、送显使能等配置,主要配置流程如图1所示。

驱动内部支持两种串口协议:QSPI协议与MIPI协议。完成硬件环境搭建后,通过uapi_lcd_info_register接口注册屏幕信息,屏蔽了底层协议的差异。
LCD 开发指引
-
LCD信息注册:
信息注册的参数结构:
typedef struct { lcd_bus_type bus_type; combo_dev_cfg_t *bus_cfg; uint16_t x_start; uint16_t y_start; uint32_t fps; uint32_t lcd_id; uint32_t ddic_id; lcd_cmds_sequ *display_on_cmds; lcd_cmds_sequ *display_off_cmds; lcd_cmds_sequ *enter_idle_cmds; lcd_cmds_sequ *exit_idle_cmds; lcd_cmds_sequ *te_on_cmds; lcd_cmds_sequ *te_off_cmds; lcd_cmds_sequ *set_brightnes_cmds; lcd_cmds_sequ *sleep_in_cmds; lcd_cmds_sequ *sleep_out_cmds; ext_lcd_read_info lcd_id_info; } lcd_drv_cfg;combo_dev_cfg_t结构体定义:
typedef struct { uint32_t devno; short lane_id[LANE_MAX_NUM]; out_mode_t out_mode; video_mode_t video_mode; out_format_t out_format; sync_info_t sync_info; pck_en_t pck_en; uint32_t phy_data_rate; uint32_t pixel_clk; } combo_dev_cfg_t;sync_info_t 结构体定义:
typedef struct { uint16_t hsa_pixels; uint16_t hbp_pixels; uint16_t hact_pixels; uint16_t hfp_pixels; uint16_t vsa_lines; uint16_t vbp_lines; uint16_t vact_lines; uint16_t vfp_lines; } sync_info_t;指令集结构体定义:
typedef struct lcd_cmd_sequ { uint8_t dcs_flag; /* 当前数据是否通过DCS协议命令下发,为0表示不是DCS命令 */ uint8_t data_len; /* payload length, 小于等于64 */ uint8_t data[MAX_DATA_LENGTH]; /* data内包含cmd和参数,有效数据最短为1(例如0x11),最长为128 */ uint16_t delay_ms; /* 发送命令后等待时间,单位:ms */ } lcd_cmd_sequ; typedef struct lcd_cmds_sequ { lcd_cmd_sequ *cmd; /* dsi命令数组 */ uint16_t cmd_cnt; /* dsi命令个数 */ } lcd_cmds_sequ;LCD信息注册示例代码:
BUS配置信息
/* MIPI配置参数,根据实际屏幕信息修改 */ combo_dev_cfg_t g_mipi_config = { .devno = 0, .lane_id = {0, -1}, .out_mode = OUT_MODE_DSI_CMD, .out_format = OUT_FORMAT_RGB_24BIT, .sync_info = { .hsa_pixels = 10, // hsa 10 pixels .hbp_pixels = 10, // hbp 10 pixels .hact_pixels = 454, // hact 454 pixels .hfp_pixels = 10, // hfp 10 pixels .vsa_lines = 4, // vsa 4 lines .vbp_lines = 12, // vbp 12 lines .vact_lines = 454, // vact 454 lines .vfp_lines = 10, // vfp 10 lines }, .phy_data_rate = 480, // 480Mbps .pixel_clk = 20000, // 20000KHz }; /*QSPI屏幕配置与MIP屏幕一致*/指令集
/* display off sequence for common lcd */ lcd_cmd_sequ g_common_cmd_display_off[] = { {1, 2, {0xfe, 0x00}, 0}, /* select default cmd page */ {1, 1, {0x28}, 0}, /* display off */ {1, 1, {0x10}, 120}, /* sleep in */ }; /* sleep in sequence for common lcd */ const lcd_cmd_sequ g_common_cmd_sleep_in[] = { {1, 2, {0xfe, 0x00}, 0}, /* select default cmd page */ {1, 1, {0x28}, 0}, /* display off */ {1, 1, {0x10}, 120}, /* sleep in */ }; /* sleep out sequence */ const lcd_cmd_sequ g_common_cmd_sleep_out[] = { {1, 2, {0xfe, 0x00}, 0}, /* select default cmd page */ {1, 1, {0x11}, 120}, /* sleep out */ {1, 1, {0x29}, 0}, /* display on */ }; /* idle in sequence */ lcd_cmd_sequ g_common_cmd_idle_in[] = { {1, 2, {0xfe, 0x00}, 0}, {1, 1, {0x39}, 0}, }; /* idle out sequence */ lcd_cmd_sequ g_common_cmd_idle_out[] = { {1, 2, {0xfe, 0x00}, 0}, {1, 1, {0x38}, 0}, }; /* te on sequence */ lcd_cmd_sequ g_common_cmd_te_on[] = { {1, 2, {0xfe, 0x00}, 0}, {1, 1, {0x35}, 0}, }; /* te off sequence */ lcd_cmd_sequ g_common_cmd_te_off[] = { {1, 2, {0xfe, 0x00}, 0}, {1, 1, {0x34}, 0}, }; /* set brightness sequence */ lcd_cmd_sequ g_common_cmd_brightness[] = { {1, 2, {0xfe, 0x00}, 0}, {1, 2, {0x51, 0xff}, 0}, }; /* init sequence, 根据屏端提供的手册输入 */ lcd_cmd_sequ g_screen_init[] = { {1, 2, {0xfe, 0x01}, 0}, {1, 2, {0x30, 0x43}, 0}, /* set LCD frequency to 15HZ */ {1, 2, {0xfe, 0x00}, 0}, {1, 2, {0x3a, 0x77}, 0}, {1, 2, {0x53, 0x20}, 0}, {1, 2, {0x51, 0xff}, 0}, {0, 5, {0x2a, 0x00, 0x0e, 0x01, 0xd3}, 0}, {0, 5, {0x2b, 0x00, 0x00, 0x01, 0xc5}, 0}, {1, 2, {0x35, 0x00}, 0}, {1, 1, {0x11}, 120}, {1, 1, {0x29}, 0}, };信息注册
lcd_drv_cfg g_lcd_info = { .bus_type = BUS_DISPLAY_MIPI, /* BUS_DISPLAY_QSPI */ .bus_cfg = &g_mipi_config, /* g_qspi_config */ .x_start = 0xe, .y_start = 0, .fps = 60, .lcd_id = 0xf00, .display_on_cmds = &g_screen_init, .display_off_cmds = &g_display_off_cmds, .enter_idle_cmds = &g_idle_in_cmds, .exit_idle_cmds = &g_idle_out_cmds, .te_on_cmds = &g_te_on_cmds, .te_off_cmds = &g_te_off_cmds, .set_brightnes_cmds = &g_brightness_cmds, .sleep_in_cmds = &g_sleep_in_cmds, .sleep_out_cmds = &g_sleep_out_cmds, .lcd_id_info.reg_addr = 0x04, .lcd_id_info.read_len = 3, }; ext_errno ret = uapi_lcd_info_register(&g_lcd_info); if (ret != EXT_ERR_SUCCESS) { ... } -
LCD初始化:
-
送显。参考VAU及DPU接口说明,本章不做说明。
-
设置亮度或其他控制功能,以设置亮度为例:
-
读写其他控制寄存器。
-
写操作:
-
读操作:
-
VENC
接口参考:/src/middleware/utils/common_headers/venc/external/soc_venc_api.h。
VENC 概述
视频编码器VENC(Video Encoder)主要对输入图像或图像序列进行编码,并输出二进制码流,支持多路、多协议、高性能、低功耗等功能。
当前Hi3322V100HiDiTingV100版本VENC支持JPEG、MJPEG协议编码。
VENC 功能描述
VENC模块具有以下功能特点:
- 支持JPEG、MJPEG协议编码。
- 支持最大分辨率1280×720、最小120×120。
- 支持8bit YUV semi-planar 420。
- 支持最多2个编码通道,不区分协议。
- 支持输出码流缓存大小设置。
- 支持用户主动送图和前级绑定送图。
- 支持编码通道状态查询。
- 支持编码私有用户数据。
- 支持输入输出帧率设置。
- 支持码率控制RC参数设置。
- 支持设置序列码率过冲策略。
- 支持设置单帧码率过冲策略。
-
支持JPEG支持Baseline编码。
- JPEG支持FixQP码控模式。
- JPEG支持ECS MCU个数设置。
- JPEG支持量化表设置。
-
支持MJPEG编码,由JPEG Baseline构成。
- MJPEG支持FixQP、CBR、VBR码控模式。
- MJPEG支持ECS MCU个数设置,中断使能。
- MJPEG支持量化表参数设置。
VENC模块提供如表1所示接口。
表 1 VENC模块接口
接口 |
描述 |
|---|---|
uapi_venc_module_init |
编码模块初始化。 |
uapi_venc_module_exit |
编码模块去初始化。 |
uapi_venc_is_standard_support |
判断编码器是否支持给定协议。 |
uapi_venc_get_default_attr |
获取编码器默认配置值。 |
uapi_venc_create |
创建编码通道。 |
uapi_venc_destroy |
销毁编码通道。 |
uapi_venc_reset |
复位编码通道。 |
uapi_venc_start |
开启编码通道接收图像。 |
uapi_venc_stop |
停止编码通道接收图像。 |
uapi_venc_get_status |
获取编码通道状态。 |
uapi_venc_send_frame |
用户发送图像。 |
uapi_venc_send_userdata |
发送用户数据。 |
uapi_venc_get_stream |
获取编码码流。 |
uapi_venc_put_stream |
释放码流缓存。 |
uapi_venc_get_attr |
获取编码属性。 |
uapi_venc_set_attr |
设置编码通道属性。 |
uapi_venc_get_rc_param |
获取码控参数。 |
uapi_venc_set_rc_param |
设置码控参数。 |
uapi_venc_get_bit_rate_overshoot |
获取序列码率过冲应对策略设置。 |
uapi_venc_set_bit_rate_overshoot |
设置序列码率过冲应对策略设置。 |
uapi_venc_get_frame_bits_overshoot |
获取单帧码率过冲应对策略设置。 |
uapi_venc_set_frame_bits_overshoot |
设置单帧码率过冲应对策略设置。 |
uapi_venc_get_jpeg_ecs |
获取JPEG/MJPEG协议编码通道ecs参数。 |
uapi_venc_set_jpeg_ecs |
设置JPEG/MJPEG协议编码通道ecs参数。 |
uapi_venc_get_jpeg_qt |
获取JPEG/MJPEG协议编码量化表。 |
uapi_venc_set_jpeg_qt |
设置JPEG/MJPEG协议编码量化表。 |
VENC 开发指引

VDEC
接口参考:/src/middleware/utils/common_headers/vdec/external/soc_vdec_api.h。
VDEC 概述
VDEC(Video Decoder)即视频解码器,主要是对压缩数据例如H.264、MJPGE码流进行解码出YUV的功能。
VDEC 功能描述
VDEC模块具有以下功能特点:
- 支持H.264解码,最高支持2个参考帧,参考帧类型为P帧/B帧。
- 支持MJPEG解码。
- 支持分辨率最大600×600分辨率。
- 支持semi-planar420的输出。
- 支持PTS纠正。
- 支持帧率计算。
- 解码性能:500×500@60fps(YUV420格式)。
硬件约束:
- 首地址16Byte对齐。
- stride16Byte对齐。
VDEC提供如表1所示接口。
表 1 VDEC接口说明
接口 |
说明 |
|---|---|
uapi_vdec_module_init |
初始化VDEC模块。 |
uapi_vdec_module_exit |
去初始化VDEC模块。 |
uapi_vdec_suspend |
VDEC模块待机。 |
uapi_vdec_resume |
VDEC模块唤醒。 |
uapi_vdec_create |
创建解码器实例。 |
uapi_vdec_destroy |
销毁解码器实例。 |
uapi_vdec_start |
启动解码器。 |
uapi_vdec_stop |
暂停解码器。 |
uapi_vdec_reset |
复位解码器。 |
uapi_vdec_flush |
刷新解码器。 |
uapi_vdec_decode |
单帧解码(I帧)。 |
uapi_vdec_get_attr |
获取实例属性。 |
uapi_vdec_set_attr |
设置实例属性。 |
uapi_vdec_get_param |
获取实例参数。 |
uapi_vdec_set_param |
设置实例参数。 |
uapi_vdec_get_feature |
获取实例特性。 |
uapi_vdec_get_status |
获取实例状态。 |
uapi_vdec_get_stream |
获取空闲的码流缓冲。 |
uapi_vdec_put_stream |
发送码流缓冲。 |
uapi_vdec_acquire_frame |
获取解码帧存。 |
uapi_vdec_release_frame |
释放解码帧存。 |
uapi_vdec_register_event |
注册事件。 |
uapi_vdec_listen_event |
监测解码事件。 |
uapi_vdec_send_eos |
发送码流结束标志。 |
uapi_vdec_bind_frame_buffer |
绑定解码帧存。 |
表 2 VDEC静态实例属性表
属性名称 |
描述 |
|---|---|
standard |
解码协议。 |
decode_mode |
解码模式(IPB/IP/I)。 |
output_order |
输出顺序,默认显示序输出。 |
frame_layout |
帧存YUV布局方式。 |
max_stream_size |
最大码流缓冲大小。 |
max_stream_num |
最大码流缓冲个数。 |
extra_frame_num |
额外解码缓冲帧数,不包含解码所需的最少帧存数。 |
error_threshold |
错误阈值[0,100],当一帧的error_ratio大于错误阈值时此帧会被解码丢弃,小于等于错误阈值的帧输出,0:所有有错误的帧都会被丢弃;100:所有帧全部输出。 |
表 3 VDEC监测事件表
事件类型 |
作用 |
备注 |
|---|---|---|
EXT_VDEC_EVT_NEW_FRAME |
新帧事件。 |
监测是否解码出帧。 |
EXT_VDEC_EVT_FREE_STREAM |
码流空闲事件。 |
监测是否码流缓冲可用。 |
EXT_VDEC_EVT_EOS |
码流结束事件。 |
监测是否码流解码结束。 |
EXT_VDEC_EVT_ERR_UNSUPPORT |
不支持事件。 |
监测是否有不支持规格。 |
EXT_VDEC_EVT_ERR_FRAME |
错误帧事件。 |
监测是否错误帧。 |
EXT_VDEC_EVT_ERR_DECODE |
解码报错事件。 |
监测是否出现解码报错。 |
EXT_VDEC_EVT_ALL |
所有事件。 |
监测以上所有事件。 |
VDEC 开发指引

VICAP
VICAP 概述
VICAP(Video Input Capture)为视频输入捕获模块,模块主要功能是接收不同接口、不同时序的视频数据,将捕获的图像写入PARAM。
VICAP 功能描述
VICAP模块具有以下功能特性:
- 支持1路视频输入接口(PT0 DC时序),YUV422输入。
- 支持1路CH写出 ,YUV422/YUV444写出。
- 支持自建时序写出。
VICAP 开发指引

注意事项
- VAU、DPU 和 LCD 使用同一帧缓冲区时,
width、height、stride、像素格式和压缩模式必须一致;任一项不匹配都可能造成花屏、颜色异常或刷新失败。 - Surface 的物理地址必须位于硬件可访问的显存范围,并满足对应格式、压缩方式和硬件的地址对齐要求。VAU 任务未完成、DPU 仍在显示时不得复用或释放该缓冲区。
- 屏幕时序、MIPI/QSPI 参数、初始化命令集和亮度命令必须来自实际屏幕规格书。示例中的分辨率、时钟和命令字节不能直接用于不同屏幕。
- JPEG 仅支持 baseline、数据精度为 8 bit 的图片;解码输出的 YUV420SP stride、UV 偏移和缓冲区大小应使用解码器返回的值计算。
- VENC、VDEC 与 VICAP 的编码规格、帧格式、缓冲区数量和事件处理要求以各自模块章节的表格、默认参数和流程图为准。
常见编译错误
| 现象 | 排查方法 |
|---|---|
找不到 soc_vau_api.h、soc_dpu_api.h 或 soc_jpeg_api.h |
检查组件私有头文件目录是否包含对应的 /src/middleware/utils/common_headers/gpu/external 路径,并确认目标启用了图形显示配置。 |
gpu_at 未参与构建或 AT 中没有 GPU 命令 |
检查 /src/build/config/target_config/3322/target_config.py 的组件清单,以及 at_gpu_cmd/CMakeLists.txt 的 AT_COMMAND_GPU 定义。 |
uapi_dpu_create_layer 参数类型不匹配 |
使用 ext_dpu_layer_info 和 ext_dpu_surface,并以 /src/middleware/utils/common_headers/gpu/external/soc_dpu_type.h 的定义为准。 |
| 命令执行后无显示或显示异常 | 检查 LCD 初始化、面板连接、Surface 地址、颜色格式、stride、压缩模式以及 DPU/VAU DFX 输出。 |