Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added 1DLUT filter sample code and template. #325

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions videoprocess/process_1dlut_3dlut.cfg.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Configuration information for video process test case.
# This application will firstly load yuv frames to one type of surface(P010)
# you require. After video processing, the processed content (NV12 surface)
# will be stored to frames(nv12 format in file).
# Supported features include scaling and implicit format conversion(P010<->RGB<->NV12).
# you can modify this configuration file to set the corresponding parameters.

#1.Source YUV file information
SRC_FILE_NAME: ./Flower.p010
SRC_FRAME_WIDTH: 1920
SRC_FRAME_HEIGHT: 1080
SRC_FRAME_FORMAT: P010
SRC_FILE_FORMAT: P010

#2.Destination YUV(RGB) file information
DST_FILE_NAME: ./out_1920x1080.p010
DST_FRAME_WIDTH: 1920
DST_FRAME_HEIGHT: 1080
DST_FRAME_FORMAT: P010
DST_FILE_FORMAT: P010

#3.How many frames to be processed
FRAME_SUM: 1

#4.3DLUT configuration file
3DLUT_FILE_NAME: ./3dlut_65cubic.dat
3DLUT_SEG_SIZE: 65
3DLUT_MUL_SIZE: 128
3DLUT_CHANNEL_MAPPING: 1

#5.1DLUT configuration file
1DLUT_FILE_NAME: ./1dlut_256.dat
1DLUT_SEG_SIZE: 256

#5. pipeline(3DLUT->Scaling: 1, Scaling->3DLUT: 0, Scaling only: 2, 1DLUT_3DLUT: 3)
PIPELINE: 3

4 changes: 2 additions & 2 deletions videoprocess/process_3dlut.cfg.template
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,6 @@ FRAME_SUM: 1
3DLUT_MUL_SIZE: 128
3DLUT_CHANNEL_MAPPING: 1

#5. 3DLUT Scaling pipeline(3DLUT->Scaling: 1, Scaling->3DLUT: 0, Scaling only: 2)
3DLUT_SCALING: 1
#5. Pipeline Configuration(3DLUT->Scaling: 1, Scaling->3DLUT: 0, Scaling only: 2)
PIPELINE: 1

209 changes: 202 additions & 7 deletions videoprocess/vpp3dlut.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
/* indicate the pipleine is 3dlut -> scaling, by default in one call */
#define VA_3DLUT_SCALING 1
#define VA_SCALING_ONLY 2
#define VA_1DLUT_3DLUT 3

static VADisplay va_dpy = NULL;
static VAContextID context_id = 0;
Expand Down Expand Up @@ -90,6 +91,13 @@ static uint16_t g_3dlut_seg_size = 65;
static uint16_t g_3dlut_mul_size = 128;
static uint32_t g_3dlut_channel_mapping = 1;

static char g_1dlut_file_name[MAX_LEN];
static uint16_t g_1dlut_seg_size = 256;
static uint8_t* g_1dlut_buffer = NULL;
static uint8_t g_1dlut_bit_depth = 16;
static uint8_t g_1dlut_channel_num = 4;
static uint32_t g_1dlut_buffer_size = g_1dlut_seg_size * (g_1dlut_bit_depth / 8) * g_1dlut_channel_num;

#if VA_CHECK_VERSION(1, 12, 0)

static int8_t
Expand Down Expand Up @@ -989,6 +997,45 @@ store_yuv_surface_to_file(FILE *fp,
}
}

static VAStatus
upload_data_to_1dlut(FILE *fp)
{
VAStatus va_status;
uint32_t real_size = 0;
uint16_t *p1dlut_buffer = NULL;

if (g_1dlut_buffer == NULL) {
g_1dlut_buffer = (unsigned char*)malloc(g_1dlut_seg_size * g_1dlut_bit_depth / 8 * g_1dlut_channel_num);
assert(g_1dlut_buffer);
}

p1dlut_buffer = (uint16_t*)g_1dlut_buffer;

if (0 /*fp*/) {
fseek(fp, 0L, SEEK_END);
real_size = ftell(fp);
rewind(fp);

if (real_size != g_1dlut_buffer_size) {
printf("1DLUT file size error!\n");
}

if (fread(g_1dlut_buffer, real_size, 1, fp) != 0) {
printf("upload_data_to_1dlut %d\n");
va_status = VA_STATUS_SUCCESS;
}
} else { // default test 1dlut
for (uint32_t index = 0; index < g_1dlut_seg_size; index++) {
p1dlut_buffer[index *4 + 0] = index * 257;
p1dlut_buffer[index *4 + 1] = index * 257;
p1dlut_buffer[index *4 + 2] = index * 257;
p1dlut_buffer[index *4 + 3] = index * 257;
}
}

return va_status;
}

static VAStatus
upload_data_to_3dlut(FILE *fp,
VASurfaceID &surface_id)
Expand All @@ -1007,12 +1054,12 @@ upload_data_to_3dlut(FILE *fp,
va_status = vaMapBuffer(va_dpy, surface_image.buf, &surface_p);
CHECK_VASTATUS(va_status, "vaMapBuffer");

if (surface_image.format.fourcc == VA_FOURCC_RGBA && fp) {
/* 3DLUT surface is allocated to 32 bit RGB */
frame_size = surface_image.width * surface_image.height * 4;
newImageBuffer = (unsigned char*)malloc(frame_size);
assert(newImageBuffer);
/* 3DLUT surface is allocated to 32 bit RGB */
frame_size = surface_image.width * surface_image.height * 4;
newImageBuffer = (unsigned char*)malloc(frame_size);
assert(newImageBuffer);

if (0 /*surface_image.format.fourcc == VA_FOURCC_RGBA && fp*/) {
fseek(fp, 0L, SEEK_END);
lut3d_size = ftell(fp);
rewind(fp);
Expand All @@ -1024,6 +1071,10 @@ upload_data_to_3dlut(FILE *fp,
printf("upload_data_to_3dlut: 3DLUT surface width %d, height %d, pitch %d, frame size %d, 3dlut file size: %d\n", surface_image.width, surface_image.height, surface_image.pitches[0], frame_size, lut3d_size);
}
}
else { // default 3dlut
memset(newImageBuffer, 0xff, frame_size);
memcpy(surface_p, newImageBuffer, frame_size);
}

if (newImageBuffer) {
free(newImageBuffer);
Expand Down Expand Up @@ -1059,6 +1110,50 @@ create_surface(VASurfaceID * p_surface_id,
return va_status;
}

static VAStatus
lut1D_filter_init(VABufferID &filter_param_buf_id)
{
VAStatus va_status;
VAProcFilterParameterBuffer1DLUT lut1d_param;
VABufferID lut1d_param_buf_id;
uint32_t num_caps = 10;
bool bSupported = false;

VAProcFilterCap1DLUT caps[num_caps];
memset(&caps, 0, sizeof(VAProcFilterCap1DLUT)*num_caps);
va_status = vaQueryVideoProcFilterCaps(va_dpy, context_id,
VAProcFilter1DLUT,
(void *)caps, &num_caps);
CHECK_VASTATUS(va_status, "vaQueryVideoProcFilterCaps");
printf("vaQueryVideoProcFilterCaps num_caps %d\n", num_caps);

/* check if the input parameters are supported */
for (uint32_t index = 0; index < num_caps; index++) {
// check lut_size and lut_stride
if (caps[index].lut_size == g_1dlut_seg_size) {
bSupported = true;
}
}

if (bSupported) {
lut1d_param.type = VAProcFilter1DLUT;
lut1d_param.buffer_size = g_1dlut_buffer_size;
lut1d_param.lut_buffer = g_1dlut_buffer;
lut1d_param.lut_size = g_1dlut_seg_size;
lut1d_param.bit_depth = g_1dlut_bit_depth;
lut1d_param.num_channel = g_1dlut_channel_num;

/* create 3dlut fitler buffer */
va_status = vaCreateBuffer(va_dpy, context_id,
VAProcFilterParameterBufferType, sizeof(lut1d_param), 1,
&lut1d_param, &lut1d_param_buf_id);

filter_param_buf_id = lut1d_param_buf_id;
}

return va_status;
}

static VAStatus
lut3D_filter_init(VABufferID &filter_param_buf_id)
{
Expand All @@ -1079,7 +1174,7 @@ lut3D_filter_init(VABufferID &filter_param_buf_id)
/* check if the input parameters are supported */
for (uint32_t index = 0; index < num_caps; index++) {
// check lut_size and lut_stride
if ((caps[index].lut_size = g_3dlut_seg_size) &&
if ((caps[index].lut_size == g_3dlut_seg_size) &&
(caps[index].lut_stride[0] == g_3dlut_seg_size) &&
(caps[index].lut_stride[1] == g_3dlut_seg_size) &&
(caps[index].lut_stride[2] == g_3dlut_mul_size)) {
Expand Down Expand Up @@ -1109,6 +1204,83 @@ lut3D_filter_init(VABufferID &filter_param_buf_id)
return va_status;
}

static VAStatus
video_frame_process_1dlut_3dlut(
VASurfaceID in_surface_id,
VASurfaceID out_surface_id)

{
VAStatus va_status;
VAProcPipelineParameterBuffer pipeline_param;
VARectangle surface_region, output_region;
VABufferID pipeline_param_buf_id = VA_INVALID_ID;
VABufferID filter_param_buf_id[2];

/*Create 1DLUT Filter*/
lut1D_filter_init(filter_param_buf_id[0]);

/*Create 3DLUT Filter*/
lut3D_filter_init(filter_param_buf_id[1]);

/* Fill pipeline buffer */
surface_region.x = 0;
surface_region.y = 0;
surface_region.width = g_in_pic_width;
surface_region.height = g_in_pic_height;
output_region.x = 0;
output_region.y = 0;
output_region.width = g_out_pic_width;
output_region.height = g_out_pic_height;

memset(&pipeline_param, 0, sizeof(pipeline_param));
pipeline_param.surface = in_surface_id;
pipeline_param.surface_region = &surface_region;
pipeline_param.output_region = &output_region;
pipeline_param.filter_flags = 0;
pipeline_param.filters = filter_param_buf_id;
pipeline_param.num_filters = 2;
/* input is bt2020 */
pipeline_param.surface_color_standard = VAProcColorStandardBT2020;
pipeline_param.output_color_standard = VAProcColorStandardBT2020;

va_status = vaCreateBuffer(va_dpy,
context_id,
VAProcPipelineParameterBufferType,
sizeof(pipeline_param),
1,
&pipeline_param,
&pipeline_param_buf_id);
CHECK_VASTATUS(va_status, "vaCreateBuffer");

va_status = vaBeginPicture(va_dpy,
context_id,
out_surface_id);
CHECK_VASTATUS(va_status, "vaBeginPicture");

va_status = vaRenderPicture(va_dpy,
context_id,
&pipeline_param_buf_id,
1);
CHECK_VASTATUS(va_status, "vaRenderPicture");

va_status = vaEndPicture(va_dpy, context_id);
CHECK_VASTATUS(va_status, "vaEndPicture");

if (pipeline_param_buf_id != VA_INVALID_ID) {
vaDestroyBuffer(va_dpy, pipeline_param_buf_id);
}

if (filter_param_buf_id[0] != VA_INVALID_ID) {
vaDestroyBuffer(va_dpy, filter_param_buf_id[0]);
}

if (filter_param_buf_id[1] != VA_INVALID_ID) {
vaDestroyBuffer(va_dpy, filter_param_buf_id[1]);
}

return va_status;
}

static VAStatus
video_frame_process_3dlut(VASurfaceID in_surface_id,
VASurfaceID out_surface_id)
Expand Down Expand Up @@ -1322,6 +1494,12 @@ vpp_context_create()
}
}

if (g_pipeline_sequence == VA_1DLUT_3DLUT) {
FILE *lut1d_file = NULL;
lut1d_file = fopen(g_1dlut_file_name, "rb");
upload_data_to_1dlut(lut1d_file);
}

va_status = vaCreateConfig(va_dpy,
VAProfileNone,
VAEntrypointVideoProc,
Expand Down Expand Up @@ -1438,7 +1616,9 @@ parse_basic_parameters()

read_value_uint32(g_config_file_fd, "FRAME_SUM", &g_frame_count);

read_value_uint32(g_config_file_fd, "3DLUT_SCALING", &g_pipeline_sequence);
if (read_value_uint32(g_config_file_fd, "PIPELINE", &g_pipeline_sequence)) {
printf("Read Pipeline Oonfiguration failed, exit.");
}

if (read_value_string(g_config_file_fd, "3DLUT_FILE_NAME", g_3dlut_file_name)) {
printf("Read 3DLUT file failed, exit.");
Expand All @@ -1456,6 +1636,14 @@ parse_basic_parameters()
printf("Read channel_mapping failed, exit.");
}

if (read_value_string(g_config_file_fd, "1DLUT_FILE_NAME", g_1dlut_file_name)) {
printf("Read 1DLUT file failed, exit.");
}

if (read_value_uint16(g_config_file_fd, "1DLUT_SEG_SIZE", &g_1dlut_seg_size)) {
printf("Read segment_size failed, exit.");
}

if (g_in_pic_width != g_out_pic_width ||
g_in_pic_height != g_out_pic_height)
printf("Scaling will be done : from %4d x %4d to %4d x %4d \n",
Expand Down Expand Up @@ -1534,6 +1722,8 @@ int32_t main(int32_t argc, char *argv[])
} else if (g_pipeline_sequence == VA_SCALING_ONLY) {
printf("process frame #%d in VA_SCALING_ONLY\n", i);
video_frame_process_scaling(g_in_surface_id, g_out_surface_id);
} else if (g_pipeline_sequence == VA_1DLUT_3DLUT) {
video_frame_process_1dlut_3dlut(g_in_surface_id, g_out_surface_id);
} else {
printf("Unknown pipeline sequence, default is 3DLUT->scaling!\n");
}
Expand All @@ -1549,6 +1739,11 @@ int32_t main(int32_t argc, char *argv[])
if (g_config_file_fd)
fclose(g_config_file_fd);

if (g_1dlut_buffer) {
free(g_1dlut_buffer);
g_1dlut_buffer = NULL;
}

vpp_context_destroy();

return 0;
Expand Down