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。
- VPC输入内存限制
入参:resize_param_in_msg
成员变量 |
说明 |
取值范围 |
---|---|---|
int src_width |
原图的宽度(2对齐)。
须知:
原图指图片的有效区域,实际上对于送进VPC的内存需要128*16对齐。 |
最小分辨率:
最大分辨率: 4096 必填 |
int src_high |
原图的高度(2对齐)。
须知:
原图指图片的有效区域,实际上对于送进VPC的内存需要128*16对齐。 |
最小分辨率:
最大分辨率: 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对齐。 |
最小分辨率:
最大分辨率: 4096 必填 |
int high |
输入原图像高度,2对齐(偶数)。
须知:
原图指图片的有效区域,实际上对于送进VPC的内存需要128*16对齐。 |
最小分辨率:
最大分辨率: 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。 选填 |
VpcOverLayReverse overlay |
叠加结构体,预留。 |
预留 |
VpcCollageReverse collage |
拼接结构体,预留。 |
预留 |
RDMACHANNEL rdma |
rdma参数为HFBC数据专用配置结构体。 |
具体请参见Rdma通道结构体RDMACHANNEL。 |
VpcTurningReverse turningReverse1 |
Vpc优化预留接口。 |
|
bool isVpcUseTurning1 |
标志是否使用Vpc优化,预留接口,此标志与turningReverse1配合使用。 |
-- |
VpcTurningReverse turningReverse2 |
Vpc优化预留接口。 |
|
bool isVpcUseTurning2 |
标志是否使用Vpc优化,预留接口,此标志与turningReverse2配合使用。 |
-- |
string *yuvscaler_paraset |
yuvscaler_paraset指针接收VPC滤波参数集文件的路径和文件名数组。
说明:
|
参数集文件路径为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 |
输入图片格式 |
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;