更新时间:2021-03-18 GMT+08:00
分享

CMDLIST功能及参数说明

不推荐使用CMDLIST功能,后续版本会删除。旧版本中的VPC功能和CMDLIST功能均迁移到VPC功能,请参见VPC参数说明处的参数说明进行开发。

CMDLIST是VPC的一个扩展功能,其概念为将原来需要多次启动VPC执行的功能,合并到一次的“启动”与“完成中断返回”间完成。简单来说,CMDLIST适用于对时延要求不高,处理的图片分辨率低,数量多的场景。

入参

CMDLIST输入为结构体,详细参数如图1表1所示。

图1 CMDLIST结构体

详细信息以及取值范围请参见表1

表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相同,

详见Rdma通道结构体 RDMACHANNEL

ROI_CONFIG:roi_config

输出参数配置结构体。

详见ROI_CONFIG结构体

IMAGE_CONFIG*:next

下一个IMAGE_CONFIG结构体指针。多图时配置,单图时配置为NULL。

--

结构体详细定义请见DDK包下include/inc/dvpp/dvpp_config.h。

可以通过图2所示,直观了解输入参数信息。

图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个框。

出参

暂无,其中输出图片在sum_out中的out_buffer中,用户可读取该内存获取图片。

输入图片格式与输出图片格式对应rank配置表请参见表1

调用示例

/************************************************************************************************/
/*****用例说明:**********************************************************************************
此用例以一张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;    
}
分享:

    相关文档

    相关产品