bmcv_image_vpp_convert¶
该 API 将输入图像格式转化为输出图像格式,并支持 crop + resize 功能,支持从 1 张输入中 crop 多张输出并 resize 到输出图片大小。
bm_status_t bmcv_image_vpp_convert( bm_handle_t handle, int output_num, bm_image input, bm_image *output, bmcv_rect_t *crop_rect, bmcv_resize_algorithm algorithm = BMCV_INTER_LINEAR );
传入参数说明:
bm_handle_t handle
输入参数。设备环境句柄,通过调用 bm_dev_request 获取
int output_num
输出参数。输出 bm_image 数量,和src image的crop 数量相等,一个src crop 输出一个dst bm_image
bm_image input
输入参数。输入 bm_image 对象
bm_image* output
输出参数。输出 bm_image 对象指针
bmcv_rect_t * crop_rect
输入参数。具体格式定义如下:
typedef struct bmcv_rect { int start_x; int start_y; int crop_w; int crop_h; } bmcv_rect_t;
每个输出 bm_image 对象所对应的在输入图像上 crop 的参数,包括起始点x坐标、起始点y坐标、crop图像的宽度以及crop图像的高度。
bmcv_resize_algorithm algorithm = BMCV_INTER_LINEAR
输入参数。resize 算法选择,包括 BMCV_INTER_NEAREST 、 BMCV_INTER_LINEAR 和 BMCV_INTER_BICUBIC 三种,默认情况下是双线性差值。
返回值说明:
BM_SUCCESS: 成功
其他:失败
注意事项:
该 API 所需要满足的格式以及部分要求与 bmcv_image_vpp_basic 中的表格相同。
输入输出的寬高(src.width, src.height, dst.widht, dst.height)限制在 16 ~ 4096 之间。
输入必须关联 device memory,否则返回失败。
FORMAT_COMPRESSED 是 VPU 解码后内置的一种压缩格式,它包括4个部分:Y compressed table、Y compressed data、CbCr compressed table 以及 CbCr compressed data。请注意 bm_image 中这四部分存储的顺序与 FFMPEG 中 AVFrame 稍有不同,如果需要 attach AVFrame 中 device memory 数据到 bm_image 中时,对应关系如下,关于 AVFrame 详细内容请参考 VPU 的用户手册。
bm_device_mem_t src_plane_device[4]; src_plane_device[0] = bm_mem_from_device((u64)avframe->data[6], avframe->linesize[6]); src_plane_device[1] = bm_mem_from_device((u64)avframe->data[4], avframe->linesize[4] * avframe->h); src_plane_device[2] = bm_mem_from_device((u64)avframe->data[7], avframe->linesize[7]); src_plane_device[3] = bm_mem_from_device((u64)avframe->data[5], avframe->linesize[4] * avframe->h / 2); bm_image_attach(*compressed_image, src_plane_device);
代码示例:
#include <iostream> #include <vector> #include "bmcv_api_ext.h" #include "bmlib_utils.h" #include "common.h" #include <memory> #include "stdio.h" #include "stdlib.h" #include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { bm_handle_t handle; int image_h = 1080; int image_w = 1920; bm_image src, dst[4]; bm_dev_request(&handle, 0); bm_image_create(handle, image_h, image_w, FORMAT_NV12, DATA_TYPE_EXT_1N_BYTE, &src); bm_image_alloc_dev_mem(src, 1); for (int i = 0; i < 4; i++) { bm_image_create(handle, image_h / 2, image_w / 2, FORMAT_BGR_PACKED, DATA_TYPE_EXT_1N_BYTE, dst + i); bm_image_alloc_dev_mem(dst[i]); } std::unique_ptr<u8 []> y_ptr(new u8[image_h * image_w]); std::unique_ptr<u8 []> uv_ptr(new u8[image_h * image_w / 2]); memset((void *)(y_ptr.get()), 148, image_h * image_w); memset((void *)(uv_ptr.get()), 158, image_h * image_w / 2); u8 *host_ptr[] = {y_ptr.get(), uv_ptr.get()}; bm_image_copy_host_to_device(src, (void **)host_ptr); bmcv_rect_t rect[] = {{0, 0, image_w / 2, image_h / 2}, {0, image_h / 2, image_w / 2, image_h / 2}, {image_w / 2, 0, image_w / 2, image_h / 2}, {image_w / 2, image_h / 2, image_w / 2, image_h / 2}}; bmcv_image_vpp_convert(handle, 4, src, dst, rect); for (int i = 0; i < 4; i++) { bm_image_destroy(dst[i]); } bm_image_destroy(src); bm_dev_free(handle); return 0; }