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

VPC功能及参数说明

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

旧版本中的VPC功能:主要用于处理媒体图像转换,包括缩放、色域转换、降bit数处理、格式转换、区块切割,叠加拼接,CMDLIST。

  • VPC路数无限制,其性能指标如下表。

    VPC性能由于涉及到抠图、缩放等不同的场景,当处理图片过程中的分辨率改变时,性能会对应改变。当处理过程中图像分辨率都没有比原图分辨率大时,典型场景性能指标如下:

    场景

    总帧率

    1080p*32路

    1440fps

    4k*4路

    360fps

    当处理过程中图像分辨率大于原图分辨率时,总帧率计算公式参考如下:

    总帧率=(3840*2160*360)/(W*H) fps

    其中:W和H为VPC处理过程中最大的宽度和高度,例如1080p抠图到960*540,再缩放到3840*2160,此时W为3840,H为2160。

    在处理过程中,缩小比例的增大会导致VPC处理性能有略微下降。

  • VPC输入输出图像宽高限制:
    • 输入图像宽高都需要2对齐(偶数)。
    • 输出图像宽高都需要2对齐(偶数)。

      此处所说的图像宽高是指图片的有效区域,实际上对于送进VPC的内存需要128*16对齐。

  • VPC输入输出图像内存限制:
    • VPC输入内存限制
      • 输入数据地址(os虚拟地址):128字节对齐。
      • 输入图像宽度内存限制:128字节对齐。
      • 输入图像高度内存限制:16字节对齐。

      对于yuv400sp格式图片,需要调用方申请和yuv420sp格式相同大小的空间,即:width_align_128*high_align_16*1.5。

    • VPC输出内存限制
      • 输出数据地址(os虚拟地址):128字节对齐。
      • 输出图像宽内存限制:128字节对齐。
      • 输出图像高内存限制:16字节对齐。

        在使用VPC实现图像裁剪与缩放时,共需要调用两次DvppCtl,第一次调用的输入参数为resize_param_in_msg,输出参数为resize_param_out_msg,第二次调用的输入参数为vpc_in_msg,详细信息请参见入参:resize_param_in_msg~入参:vpc_in_msg

入参:resize_param_in_msg

成员变量

说明

取值范围

int src_width

原图的宽度(2对齐)。

须知:

原图指图片的有效区域,实际上对于送进VPC的内存需要128*16对齐。

最小分辨率:

  • 128(来源VDEC)
  • 16(来源非VDEC)

最大分辨率:

4096

必填

int src_high

原图的高度(2对齐)。

须知:

原图指图片的有效区域,实际上对于送进VPC的内存需要128*16对齐。

最小分辨率:

  • 128(来源VDEC)
  • 16(来源非VDEC)

最大分辨率:

4096

必填

int hmax

与原点在水平方向的最大偏移。

奇数,具体参见入参:vpc_in_msg

int hmin

与原点在水平方向的最小偏移。

偶数,具体参见入参:vpc_in_msg

int vmax

与原点在垂直方向的最大偏移。

奇数,具体参见入参:vpc_in_msg

int vmin

与原点在垂直方向的最小偏移。

偶数,具体参见入参:vpc_in_msg

int dest_width

输出图像宽度。

偶数。

int dest_high

输出图像高度。

偶数。

出参:resize_param_out_msg

成员变量

说明

取值范围

int dest_width_stride

输出图像的宽度对齐值。

128

int dest_high_stride

输出图像的高度对齐值。

16

int hmax

与原点在水平方向的最大偏移。

奇数,具体参见入参:vpc_in_msg

int hmin

与原点在水平方向的最小偏移。

偶数,具体参见入参:vpc_in_msg

int vmax

与原点在垂直方向的最大偏移。

奇数,具体参见入参:vpc_in_msg

int vmin

与原点在垂直方向的最小偏移。

偶数,具体参见入参:vpc_in_msg

double hinc

水平缩放系数。

具体参见入参:vpc_in_msg

double vinc

垂直缩放系数。

具体参见入参:vpc_in_msg

入参:vpc_in_msg

成员变量

说明

取值范围

int format

图像格式,调用方可以自行定义,只要后面的数字对应正确即可。例如:yuv420_semi_plannar对应的是0,调用方声明为yuv420sp,那么也必须对应为0。

yuv420_semi_plannar = 0,//0

yuv400_semi_plannar = 0,//0

yuv422_semi_plannar,//1

yuv444_semi_plannar,//2

yuv422_packed,//3

yuv444_packed,//4

rgb888_packed,//5

xrgb8888_packed,//6

必填

int rank

图像排列方式,调用方可以自行定义,只要后面的数字对应正确即可。

具体参见表1

必填

int bitwidth

位深,默认是8bit。10bit只有在图像格式为YUV/YVU420 Semi-Planar且为HFBC压缩场景下使用。

8或者10

选填

int cvdr_or_rdma

输入图像走CVDR通道还是RDMA,默认走CVDR通道,RDMA通道的输入仅为VDEC输出的HFBC格式数据。

CVDR:1,RDMA:0。

选填

int width

输入原图像宽度,2对齐(偶数)。

须知:

原图指图片的有效区域,实际上对于送进VPC的内存需要128*16对齐。

最小分辨率:

  • 128(来源VDEC)。
  • 16(来源非VDEC)。

最大分辨率:

4096

必填

int high

输入原图像高度,2对齐(偶数)。

须知:

原图指图片的有效区域,实际上对于送进VPC的内存需要128*16对齐。

最小分辨率:

  • 128(来源VDEC)。
  • 16(来源非VDEC)。

最大分辨率:

4096

必填

int stride

图像步长。

须知:

对于不同输入格式,其stride不同。

yuv400sp、yuv420sp、yuv422sp、yuv444sp:width对齐到128。

yuv422packed:width * 2后对齐到128

yuv444packed、rgb888:width * 3后对齐到128

xrgb8888:width * 4后对齐到128

必填

double hinc

水平放大倍数,aicore输出通道配置。

[0.03125, 1) or (1, 4]

缩放系数配置,超出配置范围,VPC会提示出错,如果不要缩放填1。

必填

double vinc

垂直放大倍数,aicore输出通道配置。

[0.03125, 1) or (1, 4]

缩放系数配置,超出配置范围,VPC会提示出错,如果不要缩放填1。

必填

double jpeg_hinc

水平放大倍数,jpege输出通道配置。

[0.03125, 1) or (1, 4]

缩放系数配置,超出配置范围,VPC会提示出错。

选填(目前不适用)

double jpeg_vinc

垂直放大倍数,jpege输出通道配置。

[0.03125, 1) or (1, 4]

缩放系数配置,超出配置范围,VPC会提示出错。

选填(目前不适用)

int hmax

与原点在水平方向的最大偏移。

此值必须为奇数,如果不用裁剪,此值配置成输入宽度-1。

必填

int hmin

与原点在水平方向的最小偏移。

此值必须为偶数。

如果不用裁剪,此值配置成0。

必填

int vmax

与原点在垂直方向的最大偏移。

此值必须为奇数。

如果不用裁剪,此值配置成输入宽度-1。

必填

int vmin

与原点在垂直方向的最小偏移。

此值必须为偶数。

如果不用裁剪,此值配置成0。

int out_width

输出图像宽度。

此值必须为偶数(2对齐)。

当使用智能指针申请输出buffer时,不需要填,当使用自己申请的内存作为输出buffer时,必填。

int out_high

输出图像高度。

此值必须为偶数(2对齐)。

当使用智能指针申请输出buffer时,不需要填,当使用自己申请的内存作为输出buffer时,必填。

int h_stride

图像高度步长,同int:stride描述。此值无需配置。

此值默认为16,即默认输入高度为16对齐。

选填

char* in_buffer

输入buffer。

调用方需保证输入buffer的大小与in message中配置的长度与宽度一致,即:如果输入是yuv420 semi planner nv12格式的图片,其图像大小为:宽*高*1.5,而输入的buffer大小与如上计算结果不符,则会导致VPC调用失败。

必填

int in_buffer_size

输入buffer大小。

此值用来进行输入buffer校验。

必填

shared_ptr<AutoBuffer> auto_out_buffer_1

输出buffer1。

使用VPC基础功能(裁剪,缩放)需要配置此buffer,此buffer为调用方申请智能指针当做参数传入DVPP,由DVPP内部申请输出buffer。用户可读取该buffer获取输出图片。

与下一个参数out_buffer选填一个即可。

char* out_buffer

输出buffer。

使用VPC基础功能(裁剪,缩放)需要配置此buffer,,此buffer为调用方申请的内存,需保证首地址128对齐。用户可读取该buffer获取输出图片。

与上一个参数auto_out_buffer_1选填一个即可。

int out_buffer_1_size

输出buffer1大小。

此值用来进行输出buffer校验。

如果采用shared_ptr<AutoBuffer> auto_out_buffer_1申请输出内存则选填,如果采用 char* out_buffer申请输出内存则必填。

shared_ptr<AutoBuffer> auto_out_buffer_2

此智能指针为vpc双通道的另外一个通道输出,为预留接口

--

int out_buffer_2_size

此buffersize为auto_out_buffer_2智能指针输出buffer2大小,为预留接口

--

int use_flag

使用vpc功能的标志。

  • 0:vpc基础功能。
  • 1:Rawdata8k缩放。
  • 2:Rawdata叠加基础功能,预留功能。
  • 3:Rawdata拼接基础功能,预留功能。

默认为0。

选填

VpcOverLayReverse overlay

叠加结构体,预留。

预留

VpcCollageReverse collage

拼接结构体,预留。

预留

RDMACHANNEL rdma

rdma参数为HFBC数据专用配置结构体。

具体请参见Rdma通道结构体RDMACHANNEL

VpcTurningReverse turningReverse1

Vpc优化预留接口。

具体请参见Vpc内部优化结构体VpcTurningReverse

bool isVpcUseTurning1

标志是否使用Vpc优化,预留接口,此标志与turningReverse1配合使用。

--

VpcTurningReverse turningReverse2

Vpc优化预留接口。

具体请参见Vpc内部优化结构体VpcTurningReverse

bool isVpcUseTurning2

标志是否使用Vpc优化,预留接口,此标志与turningReverse2配合使用。

--

string *yuvscaler_paraset

yuvscaler_paraset指针接收VPC滤波参数集文件的路径和文件名数组。

说明:
  • 参数集须在Device设备上。
  • 请确保传入的文件路径是正确路径。

参数集文件路径为device侧的绝对文件路径+文件名,如{"/home/HwHiAiUser/matrix/YUVScaler_pra.h"}。

unsigned int yuvscaler_paraset_size

yuvscaler_paraset指针指向的string数组元素个数(默认为1)。

yuvscaler_paraset_size<=10

unsigned int index

index变量对应yuvscaler_paraset的数组索引。

0<=index<10

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

输入图片格式

VPC的rank参数配置

输出图片格式

YUV420sp NV12

NV12 = 0

YUV420sp NV21

YUV420sp NV21

NV21 = 1

YUV420sp NV21

YUV420sp NV12

NV12 = 1

YUV420sp NV12

YUV420sp NV21

NV21 = 0

YUV420sp NV12

YUV422sp NV16

NV16 = 1

YUV420sp NV12

YUV422sp NV61

NV61 = 0

YUV420sp NV12

YUV422sp NV16

NV16 = 0

YUV420sp NV21

YUV422sp NV61

NV61 = 1

YUV420sp NV21

YUV444sp 444spUV

444spUV = 1

YUV420sp NV12

YUV444sp 444spVU

444spVU= 0

YUV420sp NV12

YUV444sp 444spUV

444spUV = 0

YUV420sp NV21

YUV444sp 444spVU

444spVU= 1

YUV420sp NV21

YUV422packet YUYV

YUYV = 2

YUV420sp NV12

YUV422packet YVYU

YVYU = 3

YUV420sp NV21

YUV422packet UYVY

UYVY = 4

YUV420sp NV12

YUV444packet YUV

YUV = 5

YUV420sp NV12

RGB888 RGB

RGB = 6

YUV420sp NV12

RGB888 BGR

BGR = 7

YUV420sp NV21

RGB888 RGB

BGR = 7

YUV420sp NV21

RGB888 BGR

RGB = 6

YUV420sp NV12

XRGB8888 RGBA

RGBA = 8

YUV420sp NV12

XRGB8888 RGBA

BGRA = 9

YUV420sp NV21

调用示例

  • VPC基础功能调用示例

    gXxxxx为配置参数,参数配置与VPC调用分为两个阶段。

    Step1:通过DVPP_CTL_TOOL_CASE_GET_RESIZE_PARAM命令字调用DvppCtl,获取配置参数,DvppCtl的入参为resize_paramo_in_msg,出参为resize_param_out_msg。即通过resize_param_in_msg将原始图片的宽高,裁剪区域(hmax,hmin,vamx,vmin),以及输出宽高等参数传给DVPP,DVPP通过计算将重新生成的裁剪区域(hmax,hmin,vamx,vmin)以及缩放比(hinc,vinc)返回给调用方。

    Step2:调用方将第一步返回的参数通过vpc_in_msg结构体传递给DVPP,并将DvppCtl调用命令字改为DVPP_CTL_VPC_PROC执行并获得处理结果。

        dvppapi_ctl_msg dvppApiCtlMsg;
        vpc_in_msg vpcInMsg;
        resize_param_in_msg resize_in_param;
        resize_param_out_msg resize_out_param;
        resize_in_param.src_width = gWidth;
        resize_in_param.src_high = gHigh;
        resize_in_param.hmax = gHmax;
        resize_in_param.hmin = gHmin;
        resize_in_param.vmax = gVmax;
        resize_in_param.vmin = gVmin;
        resize_in_param.dest_width = floor(gHinc * (gHmax - gHmin + 1) + 0.5);
        resize_in_param.dest_high = floor(gVinc * (gVmax - gVmin + 1) + 0.5);
        printf("width  =%d\n", gWidth);
        printf("high   =%d\n", gHigh);
        printf("hmax   =%d\n", gHmax);
        printf("hmin   =%d\n", gHmin);
        printf("vmax   =%d\n", gVmax);
        printf("vmin   =%d\n", gVmin);
        printf("out width   =%d\n", resize_in_param.dest_width);
        printf("out hight   =%d\n", resize_in_param.dest_high );
    
        dvppApiCtlMsg.in = (void *)(&resize_in_param);
        dvppApiCtlMsg.out = (void *)(&resize_out_param);
        IDVPPAPI *pidvppapi = NULL;
        CreateDvppApi(pidvppapi);
        if (DvppCtl(pidvppapi, DVPP_CTL_TOOL_CASE_GET_RESIZE_PARAM, &dvppApiCtlMsg) != 0) {
            printf("call DVPP_CTL_TOOL_CASE_GET_RESIZE_PARAM process faild!\n");
            DestroyDvppApi(pidvppapi);
            return;
        }
    
        int bufferSize        = 0;
        vpcInMsg.format       = gFormat;
        vpcInMsg.cvdr_or_rdma = gcvdr_or_rdma;
        vpcInMsg.bitwidth = gBitwidth;
        vpcInMsg.rank = gRank;
        vpcInMsg.width = gWidth;
        vpcInMsg.high = gHigh;
        vpcInMsg.stride = gStride;
        vpcInMsg.hmax = resize_out_param.hmax;
        vpcInMsg.hmin = resize_out_param.hmin;
        vpcInMsg.vmax = resize_out_param.vmax;
        vpcInMsg.vmin = resize_out_param.vmin;
        vpcInMsg.vinc = resize_out_param.vinc;
        vpcInMsg.hinc = resize_out_param.hinc;
        printf("resize_out_param.hinc = %lf\n", resize_out_param.hinc);
        printf("resize_out_param.vinc = %lf\n", resize_out_param.vinc);
        printf("resize_out_param.hmax = %d\n", resize_out_param.hmax);
        printf("resize_out_param.hmin = %d\n", resize_out_param.hmin);
        printf("resize_out_param.vmax = %d\n", resize_out_param.vmax);
        printf("resize_out_param.vmin = %d\n", resize_out_param.vmin);
    
        printf("format =%d\n", vpcInMsg.format);
        printf("rank   =%d\n", vpcInMsg.rank);
        printf("width  =%d\n", vpcInMsg.width);
        printf("high   =%d\n", vpcInMsg.high);
        printf("stride =%d\n", vpcInMsg.stride);
        printf("hmax   =%d\n", vpcInMsg.hmax);
        printf("hmin   =%d\n", vpcInMsg.hmin);
        printf("vmax   =%d\n", vpcInMsg.vmax);
        printf("vmin   =%d\n", vpcInMsg.vmin);
        printf("vinc   =%F\n", vpcInMsg.vinc);
        printf("hinc   =%F\n", vpcInMsg.hinc);
        if (vpcInMsg.cvdr_or_rdma == 0) {
            printf("rdma channel\n");
            int buffersize ;
            char * payloadY ;
            char * payloadC ;
            char * headY ;
            char * headC ;
            FILE * rdmaimage = fopen(in_file_name, "rb");
    
            if (vpcInMsg.bitwidth == 10) {
                buffersize                        = vpcInMsg.width  * vpcInMsg.high * 2 + 512 * 1024;
                payloadY                          = (char*)memalign(128, buffersize);
                headY                             = payloadY + vpcInMsg.width  * vpcInMsg.high * 2;
                headC                             = headY + 256 * 1024;
                vpcInMsg.rdma.luma_payload_addr   = (long)payloadY;
                vpcInMsg.rdma.chroma_payload_addr = (long)payloadY + 640;
            } else {
                buffersize                        = vpcInMsg.width * vpcInMsg.high * 1.5 + 512 * 1024;
                payloadY                          = (char*)memalign(128, buffersize);
                payloadC                          = payloadY + vpcInMsg.width * vpcInMsg.high;
                headY                             = payloadC + vpcInMsg.width * vpcInMsg.high / 2;
                headC                             = headY + 256 * 1024;
                vpcInMsg.rdma.luma_payload_addr   = (long)payloadY;
                vpcInMsg.rdma.chroma_payload_addr = (long)payloadC;
            }
    
            fread(payloadY, 1, buffersize, rdmaimage);
            vpcInMsg.rdma.luma_head_addr        = (long)headY;
            vpcInMsg.rdma.chroma_head_addr      = (long)headC;
            vpcInMsg.rdma.luma_head_stride      = vpcInMsg.stride;
            vpcInMsg.rdma.chroma_head_stride    = vpcInMsg.stride;
            vpcInMsg.rdma.luma_payload_stride   = gpYStride;
            vpcInMsg.rdma.chroma_payload_stride = gpUVStride;
            fclose(rdmaimage);
            printf("luma payload stride= %d\n", vpcInMsg.rdma.luma_payload_stride );
            printf("chroma payload stride= %d\n", vpcInMsg.rdma.chroma_payload_stride );
        } else {
            alloc_buffer(vpcInMsg.width, vpcInMsg.high, vpcInMsg.stride, bufferSize);
            if (open_image(in_file_name, vpcInMsg.width, vpcInMsg.high, vpcInMsg.stride) != 0) {
                printf("open file failed~\n");
                free(in_buffer);
                return;
            }
            vpcInMsg.in_buffer      = in_buffer;
            vpcInMsg.in_buffer_size = bufferSize;
        }
        //alloc in and out buffer
        shared_ptr<AutoBuffer> auto_out_buffer = make_shared<AutoBuffer>();
        vpcInMsg.auto_out_buffer_1             = auto_out_buffer;
        dvppApiCtlMsg.in                       = (void *)(&vpcInMsg);
        dvppApiCtlMsg.in_size                  = sizeof(vpc_in_msg);
    
        if (pidvppapi != NULL) {
    
            for (int i = 0; i < gLoop; i++) {
                if (DvppCtl(pidvppapi, DVPP_CTL_VPC_PROC, &dvppApiCtlMsg) != 0) {
                    printf("call dvppctl process faild!\n");
                    DestroyDvppApi(pidvppapi);
                    free(in_buffer);
                    return;
                }
            }
    
        } else {
            printf("pidvppapi is null!\n");
        }
    
        free(in_buffer);
    
        FILE *fp = NULL;
        fp = fopen(out_file_name, "wb+");
        if (fp == NULL) {
            printf("open file %s failed~\n", out_file_name);
            free(in_buffer);
            return;
        }
    
        fwrite(vpcInMsg.auto_out_buffer_1->getBuffer(), 1, vpcInMsg.auto_out_buffer_1->getBufferSize(), fp);
        fflush(fp);
        fclose(fp);
        DestroyDvppApi(pidvppapi);
        return;
  • RawData8k基础功能调用示例

    参数配置:

        dvppapi_ctl_msg dvppApiCtlMsg;
        vpc_in_msg vpcInMsg;
        vpcInMsg.width = gWidth;
        vpcInMsg.high = gHigh;
        vpcInMsg.stride = gStride;
        vpcInMsg.out_width = gOutWidth;
        vpcInMsg.out_high = gOutHigh;
        printf("width     =%d\n", vpcInMsg.width);
        printf("high      =%d\n", vpcInMsg.high);
        printf("stride    =%d\n", vpcInMsg.stride);
        printf("out_width =%d\n", vpcInMsg.out_width);
        printf("out_high  =%d\n", vpcInMsg.out_high);
        //alloc in and out buffer
        char *in_buffer = (char *)malloc(vpcInMsg.width * vpcInMsg.high * 1.5);
        if (in_buffer = NULL) {
            printf("malloc fail\n");
            return;
        }
    
        shared_ptr<AutoBuffer> auto_out_buffer = make_shared<AutoBuffer>();
        FILE *yuvimage = fopen(in_file_name, "rb");
        if (yuvimage == NULL) {
            printf("no such file!,file_name=[%s]\n", in_file_name);
            free(in_buffer);
            return;
        } else {
            fread(in_buffer, 1, vpcInMsg.width * vpcInMsg.high * 3 / 2, yuvimage);
        }
    
        vpcInMsg.rank = gRank;
        vpcInMsg.in_buffer = in_buffer;
        vpcInMsg.in_buffer_size = vpcInMsg.width * vpcInMsg.high * 1.5;
        vpcInMsg.auto_out_buffer_1 = auto_out_buffer;
        vpcInMsg.use_flag = 1;
        dvppApiCtlMsg.in = (void *)(&vpcInMsg);
        dvppApiCtlMsg.in_size = sizeof(vpc_in_msg);
        IDVPPAPI *pidvppapi = NULL;
        CreateDvppApi(pidvppapi);
        if (pidvppapi != NULL) {
            if (DvppCtl(pidvppapi, DVPP_CTL_VPC_PROC, &dvppApiCtlMsg) != 0) {
                printf("call dvppctl process faild!\n");
                DestroyDvppApi(pidvppapi);
                free(in_buffer);
                fclose(yuvimage);
                return;
            }
        } else {
            printf("pidvppapi is null!\n");
        }
    
        DestroyDvppApi(pidvppapi);
        FILE *fp = NULL;
        fp = fopen(out_file_name, "wb+");
        if (fp != NULL) {
            fwrite(vpcInMsg.auto_out_buffer_1->getBuffer(), 1, vpcInMsg.auto_out_buffer_1->getBufferSize(), fp);
            fflush(fp);
            fclose(fp);
        } else {
            fclose(yuvimage);
            return;
        }
    
        free(in_buffer);
        fclose(yuvimage);
        return;
  • Rawdata叠加基础功能调用实例
        dvppapi_ctl_msg dvppApiCtlMsg;
        vpc_in_msg vpcInMsg;
        //配置RawData叠加参数
        vpcInMsg.use_flag = 2;
        vpcInMsg.overlay.image_type = 0;
        vpcInMsg.overlay.image_rank_type = 0;
        vpcInMsg.overlay.bit_width = 8;
        vpcInMsg.overlay.in_width_image = 1000;
        vpcInMsg.overlay.in_high_image = 1000;
        vpcInMsg.overlay.in_width_text = 500;
        vpcInMsg.overlay.in_high_text = 390;
        vpcInMsg.overlay.image_width_stride = 2;
        vpcInMsg.overlay.image_high_stride = 2;
        vpcInMsg.overlay.text_width_stride = 2;
        vpcInMsg.overlay.text_high_stride = 2;
        vpcInMsg.overlay.in_buffer_image = NULL;
        vpcInMsg.overlay.in_buffer_text = NULL;
        vpcInMsg.overlay.auto_overlay_out_buffer = make_shared<AutoBuffer>();
        //初始化图像内存
        if(NULL == (vpcInMsg.overlay.in_buffer_image = (char*)malloc(vpcInMsg.overlay.in_width_image*vpcInMsg.overlay.in_high_image*3/2)))    {
            printf("in_buffer_image alloc failed!\n");
            return ;
        }
        //打开图片至申请的内存中
        char image_file[50] = "yuv_data_0";
        FILE * yuvimage = fopen(image_file,"rb");
        if(NULL == yuvimage)    {
            printf("VPC_TEST: yuv image open faild!");
            return ;
        }    else    {
            fread(vpcInMsg.overlay.in_buffer_image, 1,vpcInMsg.overlay.in_width_image*vpcInMsg.overlay.in_high_image*3/2,yuvimage);
            fclose(yuvimage);
            yuvimage = NULL;
    }
    
        //初始化文字内存
        if(NULL == (vpcInMsg.overlay.in_buffer_text = (char*)malloc(vpcInMsg.overlay.in_width_text*vpcInMsg.overlay.in_high_text*3/2)))    {
            printf("in_buffer_text alloc failed!");
            free(vpcInMsg.overlay.in_buffer_image);
            return ;
        }
    
        //打开text图片至申请的内存中
        char text_file[50] = "text_0";
        FILE * yuvtext = fopen(text_file,"rb");
        if(NULL == yuvtext)    {
            printf("VPC_TEST: yuv text image open faild!");
            free(vpcInMsg.overlay.in_buffer_image);
            return ;
        }    else    {
            fread(vpcInMsg.overlay.in_buffer_text, 1,vpcInMsg.overlay.in_width_text*vpcInMsg.overlay.in_high_text*3/2, yuvtext);
            fclose(yuvtext);
            yuvtext = NULL;
        }
    
        dvppApiCtlMsg.in = (void*)(&vpcInMsg);
        dvppApiCtlMsg.in_size = sizeof(vpc_in_msg);
        IDVPPAPI *pidvppapi = NULL;
        CreateDvppApi(pidvppapi);
        if(pidvppapi!=NULL)    {
            if(DvppCtl(pidvppapi,DVPP_CTL_VPC_PROC,&dvppApiCtlMsg)!= 0)        {
                printf("call dvppctl process faild!\n");
                DestroyDvppApi(pidvppapi);
                free(vpcInMsg.overlay.in_buffer_image);
                free(vpcInMsg.overlay.in_buffer_text);
                return ;
            }
            DestroyDvppApi(pidvppapi);
            FILE * fp   = fopen("./out_overlay_image_share","wb+");
            fwrite(vpcInMsg.overlay.auto_overlay_out_buffer->getBuffer(),1,vpcInMsg.overlay.in_width_image*vpcInMsg.overlay.in_high_image*3/2,fp);
            fflush(fp);
            fclose(fp);
            fp=NULL;
            return ;
        }    else    {
            printf("pidvppapi is null!\n");
            return ;
        }
        if(NULL != vpcInMsg.overlay.in_buffer_image)    {
            free(vpcInMsg.overlay.in_buffer_image);
            vpcInMsg.overlay.in_buffer_image = NULL;
        }
        if(NULL != vpcInMsg.overlay.in_buffer_text)    {
            free(vpcInMsg.overlay.in_buffer_text);
            vpcInMsg.overlay.in_buffer_text = NULL;
        }
  • Rawdata拼接基础功能调用实例
        dvppapi_ctl_msg dvppApiCtlMsg;
        vpc_in_msg vpcInMsg;
         //配置RawData拼接参数
        vpcInMsg.use_flag = 3;
        vpcInMsg.collage.image_type = 0;
        vpcInMsg.collage.image_rank_type = 0;
        vpcInMsg.collage.bit_width = 8;
        vpcInMsg.collage.in_width = 1000;
        vpcInMsg.collage.in_high = 1000;
        vpcInMsg.collage.width_stride = 2;
        vpcInMsg.collage.high_stride = 2;
        vpcInMsg.collage.collage_type = 0;
        vpcInMsg.collage.auto_out_buffer = make_shared<AutoBuffer>();
        char image_file[4][50] = {"yuv_data_0","yuv_data_1","yuv_data_2","yuv_data_3"};
        //初始化图像内存without stride************begin************
        for(int i=0; i<4; i++) {
            if(NULL == (vpcInMsg.collage.in_buffer[i] = (char*)malloc(vpcInMsg.collage.in_width*                                        vpcInMsg.collage.in_high*3/2)))
            {
                printf("in_buffer_image alloc failed!\n");
                for(int j=0; j<i; j++) {
                    free(vpcInMsg.collage.in_buffer[j]);
                }
                return ;
            }
            //打开图片至申请的内存中
            FILE * yuvimage = fopen(image_file[i],"rb");
            if(NULL == yuvimage)        {
                printf("PVC_TEST: yuv image open faild!");
                return ;
            }        else        {
                fread(vpcInMsg.collage.in_buffer[i], 1,vpcInMsg.collage.in_width*
                      vpcInMsg.collage.in_high*3/2,yuvimage);
                fclose(yuvimage);
                yuvimage = NULL;
            }
        }
    
        dvppApiCtlMsg.in = (void*)(&vpcInMsg);
        dvppApiCtlMsg.in_size = sizeof(vpc_in_msg);
        IDVPPAPI *pidvppapi = NULL;
        CreateDvppApi(pidvppapi);
        if(pidvppapi!=NULL)    {
            if(DvppCtl(pidvppapi,DVPP_CTL_VPC_PROC,&dvppApiCtlMsg)!= 0)        {
                printf("call dvppctl process faild!\n");
                DestroyDvppApi(pidvppapi);
                for(int i=0; i<4; i++) {
                    free(vpcInMsg.collage.in_buffer[i]);
                }
                return ;
            }
            DestroyDvppApi(pidvppapi);
            FILE * fp   = fopen("./out_collage_image_share","wb+");
            fwrite(vpcInMsg.collage.auto_out_buffer->getBuffer(),1,vpcInMsg.collage.in_width*vpcInMsg.collage.in_high*6,fp);
            fflush(fp);
            fclose(fp);
            fp=NULL;
            return ;
        }    else    {
            printf("pidvppapi is null!\n");
            return ;
        }
        for(int i=0; i<4; i++) {
            if(NULL != vpcInMsg.collage.in_buffer[i])        {
                free(vpcInMsg.collage.in_buffer[i]);
                vpcInMsg.collage.in_buffer[i] = NULL;
            }
        }
  • VPCAPI调用
    IDVPPAPI *pidvppapi = NULL;
    CreateDvppApi(pidvppapi);
    if(pidvppapi!=NULL)
    {
     if(0 != DvppCtl(pidvppapi,DVPP_CTL_VPC_PROC,&dvppApiCtlMsg))
     {
      printf("call dvppctl process faild!\n");
      DestroyDvppApi(pidvppapi);
      return -1;
     }
    }
    else
    printf("pidvppapi is null!\n");
    DestroyDvppApi(pidvppapi);
  • VPC Resize参数配置获取功能调用示例

    gXxxxx为配置参数

    dvppapi_ctl_msg dvppApiCtlMsg;
    vpc_in_msg vpcInMsg;
    resize_param_in_msg resize_in_param;
    resize_param_out_msg resize_out_param;
    resize_in_param.src_width = gWidth;
    resize_in_param.src_high = gHigh;
    resize_in_param.hmax = gHmax;
    resize_in_param.hmin = gHmin;
    resize_in_param.vmax = gVmax;
    resize_in_param.vmin = gVmin;
    resize_in_param.dest_width = floor(gHinc * (gHmax - gHmin + 1) + 0.5);
    resize_in_param.dest_high = floor(gVinc * (gVmax - gVmin + 1) + 0.5);
    dvppApiCtlMsg.in = (void *)(&resize_in_param);
    dvppApiCtlMsg.out = (void *)(&resize_out_param);
    IDVPPAPI *pidvppapi = NULL;
    CreateDvppApi(pidvppapi);
    if (0 != DvppCtl(pidvppapi, DVPP_CTL_TOOL_CASE_GET_RESIZE_PARAM, &dvppApiCtlMsg))
    {
      printf("call dvppctl process faild!\n");
      DestroyDvppApi(pidvppapi);
      return;
    }
    int bufferSize = 0;
    vpcInMsg.format = gFormat;
    vpcInMsg.cvdr_or_rdma = gcvdr_or_rdma;
    vpcInMsg.bitwidth = gBitwidth;
    vpcInMsg.rank = gRank;
    vpcInMsg.width = gWidth;
    vpcInMsg.high = gHigh;
    vpcInMsg.stride = gStride;
    vpcInMsg.hmax = resize_out_param.hmax;
    vpcInMsg.hmin = resize_out_param.hmin;
    vpcInMsg.vmax = resize_out_param.vmax;
    vpcInMsg.vmin = resize_out_param.vmin;
    vpcInMsg.vinc = resize_out_param.vinc;
    vpcInMsg.hinc = resize_out_param.hinc;
分享:

    相关文档

    相关产品