CMDLIST功能及参数说明
不推荐使用CMDLIST功能,后续版本会删除。旧版本中的VPC功能和CMDLIST功能均迁移到VPC功能,请参见VPC参数说明处的参数说明进行开发。
CMDLIST是VPC的一个扩展功能,其概念为将原来需要多次启动VPC执行的功能,合并到一次的“启动”与“完成中断返回”间完成。简单来说,CMDLIST适用于对时延要求不高,处理的图片分辨率低,数量多的场景。
详细信息以及取值范围请参见表1。
成员变量 |
说明 |
取值范围 |
---|---|---|
unsigned int:format |
输入图像类型。 |
typedef enum { yuv420_semi_plannar =0,//0 yuv422_semi_plannar,//1 yuv444_semi_plannar,//2 yuv422_packed,//3 yuv444_packed,//4 rgb888_packed,//5 xrgb8888_packed,//6 yuv400_semi_plannar,//7 invalid_image_type,//20 }Imge_Type; |
unsigned int:rank |
输出图像格式(NV12或NV21)。 |
详见表1。 |
unsigned int:bitwidth |
位深,通常为8bit。10bit只有在图像格式为YUV/YVU420 Semi-Planar且为HFBC压缩场景下使用。 |
8:8bit 10:10bit |
int:is_hfbc_image |
输入图像通道,通常设置为1,走CVDR通道,仅当VDEC输出的HFBC格式数据作为输入时走RDMA通道。 |
0:RDMA 1:CVDR |
unsigned int:in_width |
输入图像宽度,必须128对齐。 |
128~4096 |
unsigned int:in_height |
输入图像高度,必须16对齐。 |
16~4096 |
unsigned int:width_step |
图像步长。 |
yuv400sp、yuv420sp、yuv422sp、yuv444sp:width对齐到128。 yuv422packed:width * 2后对齐到128。 yuv444packed、rgb888:width * 3后对齐到128。 xrgb8888:width * 4后对齐到128。 |
unsigned int:need_debug |
内部调试预留值,通常设置为0。 |
0:普通模式。 1:debug模式。 |
CMDLIST_IN_BUFFER:in_buffer |
输入图像内存地址指针,是一个联合体,普通非压缩图像选择bare_buffer,需要128对齐。HFBC压缩图像地址选择hfbc_buffer。 |
union CMDLIST_IN_BUFFER { char* bare_buffer; RDMACHANNEL* hfbc_buffer; }; 与vpc_in_msg中RDMACHANNEL相同, |
ROI_CONFIG:roi_config |
输出参数配置结构体。 |
|
IMAGE_CONFIG*:next |
下一个IMAGE_CONFIG结构体指针。多图时配置,单图时配置为NULL。 |
-- |
结构体详细定义请见DDK包下include/inc/dvpp/dvpp_config.h。
可以通过图2所示,直观了解输入参数信息。
此图将crop和resize操作归一化到一个图中,理解如下。
- 只做crop时,相当于resize系数为1。
- 只做resize时,相当于crop大小为原图。
- 输入图片的宽128对齐,高16对齐,且输入输出图片最大分辨率为4K。
- 内存地址对齐,需要用到如下接口。
输入输出图片内存地址128对齐,需要用HIAI_DVPP_DMalloc的申请大页内存。
申请接口:HIAI_DVPP_DMalloc(size)。
- 根据输出图片比上crop后图片计算缩放系数,需要在[0.03125,4]范围内。
- 输出内存大小需要根据输出宽128对齐,高16对齐后的分辨率计算。
- 调用一次cmdlist接口,最多支持32张图,每图最多支持256个框。
调用示例
/************************************************************************************************/ /*****用例说明:********************************************************************************** 此用例以一张1920x1088 yuv420 nv12图片作为输入 输入图片文件名: "file1_1920x1088_nv12.yuv" 对输入图片的操作:抠出5张子图,均缩放到224x224; ************************************************************************************************ ************************************************************************************************/ int main() { int ret = 0; //读取输入文件 char image_file[128] = "file1_1920x1088_nv12.yuv"; ifstream in_stream(image_file); if (!in_stream.is_open()) { printf("can not open %s.\n", image_file); return -1; } in_stream.seekg(0, ios::end); int file_len = in_stream.tellg(); char* in_buffer = (char *)HIAI_DVPP_DMalloc(file_len); in_stream.seekg(0, ios::beg); in_stream.read(in_buffer, file_len); in_stream.close(); //开始添加第一个image的配置 IMAGE_CONFIG* image_config = (IMAGE_CONFIG*)malloc(sizeof(IMAGE_CONFIG)); image_config->in_buffer.bare_buffer = in_buffer; //目前用到的都是非压缩图 image_config->format = 0; image_config->rank = 1;//输入nv12输出也为nv12,rank填1 image_config->bitwidth = 8;//目前用到的都是8bit一个单位的 image_config->in_width = 1920; image_config->in_height = 1088; image_config->width_step = 1920;//这个值同宽 //开始添加第一个抠图的配置,该例子抠图区域:(0,0),(511,511)围成的区域 ROI_CONFIG* roi_config = &image_config->roi_config; //开始配置crop参数 roi_config->crop_config.enable = 1; //注:当只要resize的时候,crop参数只要这个配置为0 roi_config->crop_config.hmin = 0; roi_config->crop_config.hmax = 511; roi_config->crop_config.vmin = 0; roi_config->crop_config.vmax = 511; //开始配置输出通道参数 roi_config->sum_out.enable = 1; //开启第一通道输出 roi_config->sum_out.out_width = 224; roi_config->sum_out.out_height = 224; int out_buffer_size = AlignUp(224,128)*AlignUp(224,16)*3/2; roi_config->sum_out.out_buffer = (char*)HIAI_DVPP_DMalloc(out_buffer_size); ROI_CONFIG* last_roi = roi_config; //开始添加第2到第5个抠图的配置 for (int i = 0 ; i < 4; i++) { ROI_CONFIG* roi_config = (ROI_CONFIG*)malloc(sizeof(ROI_CONFIG)); //开始配置crop参数 roi_config->crop_config.enable = 1; roi_config->crop_config.hmin = 100*i; roi_config->crop_config.hmax = 299 + 100*i; roi_config->crop_config.vmin = 100*i; roi_config->crop_config.vmax = 299 + 100*i; //开始配置输出通道参数 roi_config->sum_out.enable = 1; roi_config->sum_out.out_width = 224; roi_config->sum_out.out_height = 224; out_buffer_size = AlignUp(224,128)*AlignUp(224,16)*3/2; roi_config->sum_out.out_buffer = (char*)HIAI_DVPP_DMalloc(out_buffer_size); roi_config->next = nullptr; last_roi->next = roi_config; last_roi = roi_config; } //开始调用dvpp的cmdlist接口 IDVPPAPI *pidvppapi = NULL; //无论后面调用多少次,createdvppapi只要一次调用就好 ret = CreateDvppApi(pidvppapi); if (ret != 0) { printf("creat dvpp api faild!\n"); return -1; } dvppapi_ctl_msg dvppApiCtlMsg; dvppApiCtlMsg.in = (void *)(image_config); dvppApiCtlMsg.in_size = sizeof(IMAGE_CONFIG); ret = DvppCtl(pidvppapi, DVPP_CTL_CMDLIST_PROC, &dvppApiCtlMsg); if (0 != ret) { printf("call cmdlist dvppctl process faild!\n"); } else { printf("cmdlist success.\n"); } ret += DestroyDvppApi(pidvppapi); roi_config = image_config->roi_config.next; while (roi_config != nullptr) { ROI_CONFIG* next_roi = roi_config->next; UNMAP(roi_config->sum_out.out_buffer, out_buffer_size); free(roi_config); roi_config = next_roi; } UNMAP(image_config->roi_config.sum_out.out_buffer, out_buffer_size); free(image_config); UNMAP(in_buffer, file_len); return ret; }