[Libva] [PATCH 2/3] Encoding: Add ROI example
Xiang, Haihao
haihao.xiang at intel.com
Fri Aug 5 07:55:48 UTC 2016
> From: Zhao Yakui <yakui.zhao at intel.com>
>
> v1:
> add --roi-test for test only for ROI. default only one
> region(0,0,120,120) has been test.
> v2:
> add ROI region size check to ensure region width/height <
> frame_width/4 or frame_height/4
> add ROI attrib check
>
> Signed-off-by: Zhao Yakui <yakui.zhao at intel.com>
> Signed-off-by: ceciliapeng <cecilia.peng at intel.com>
> Signed-off-by: Pengfei Qu <Pengfei.Qu at intel.com>
> ---
> test/encode/avcenc.c | 92
> +++++++++++++++++++++++++++++++++++++++++++++++++---
> 1 file changed, 87 insertions(+), 5 deletions(-)
>
> diff --git a/test/encode/avcenc.c b/test/encode/avcenc.c
> index 74729fb..549625f 100644
> --- a/test/encode/avcenc.c
> +++ b/test/encode/avcenc.c
> @@ -91,6 +91,7 @@ static int intra_period = 30;
> static int frame_bit_rate = -1;
> static int frame_rate = 30;
> static int ip_period = 1;
> +static int roi_test_enable = 0;
>
> static VAEntrypoint select_entrypoint = VAEntrypointEncSlice;
>
> @@ -106,6 +107,7 @@ static const struct option longopts[] = {
> {"fb", required_argument, 0, 2},
> {"mode", required_argument, 0, 3},
> {"low-power", no_argument, 0, 4},
> + {"roi-test", no_argument, 0, 5},
> { NULL, 0, NULL, 0}
> };
>
> @@ -154,6 +156,7 @@ static struct {
> VABufferID packed_sei_header_param_buf_id; /* the SEI buffer
> */
> VABufferID packed_sei_buf_id;
> VABufferID misc_parameter_hrd_buf_id;
> + VABufferID misc_parameter_roi_buf_id;
>
> int num_slices;
> int codedbuf_i_size;
> @@ -185,7 +188,7 @@ static void create_encode_pipe()
> {
> VAEntrypoint entrypoints[5];
> int num_entrypoints,slice_entrypoint;
> - VAConfigAttrib attrib[2];
> + VAConfigAttrib attrib[3];
> int major_ver, minor_ver;
> VAStatus va_status;
>
> @@ -209,8 +212,11 @@ static void create_encode_pipe()
> /* find out the format for the render target, and rate control
> mode */
> attrib[0].type = VAConfigAttribRTFormat;
> attrib[1].type = VAConfigAttribRateControl;
> +
> + /* This is to query whether the ROI is supported */
> + attrib[2].type = VAConfigAttribEncROI;
> vaGetConfigAttributes(va_dpy, avcenc_context.profile,
> select_entrypoint,
> - &attrib[0], 2);
> + &attrib[0], 3);
>
> if ((attrib[0].value & VA_RT_FORMAT_YUV420) == 0) {
> /* not find desired YUV420 RT format */
> @@ -223,11 +229,24 @@ static void create_encode_pipe()
> assert(0);
> }
>
> + if (roi_test_enable){
> + VAConfigAttribValEncROI *roi_config =
> (VAConfigAttribValEncROI *)&(attrib[2].value);
> + if(roi_config->bits.num_roi_regions == 0) {
> + printf("WARNING: No find roi entry point! \n");
ROI is an attribute, not entry point.
It would be better to force roi_test_enable to 0 here. If so, the case
doesn't pass ROI related parameters to libva.
> + }
> + }
> +
> attrib[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT
> format */
> attrib[1].value = avcenc_context.rate_control_method; /* set to
> desired RC mode */
> + /* This is to create one context with ROI supported
> + * Only when it is supported, it is possible to pass ROI buffer
> on-the fly
> + * so that it can use the given ROI config for one frame.
> + * If ROI buffer is not passed, it will continue the original
> encoding mode.
> + */
> + attrib[2].value = 0x0101;
As Sree pointed out, VAConfigAttribEncROI is read-only attribute, so do
not set the value here when call vaCreateConfig(). Instead you should
set the corresponding flags in VAEncMiscParameterBufferROI.
On the other side, do not include VAConfigAttribEncROI in the attribute
list here if VAConfigAttribEncROI is not supported or user doesn't
specify --roi-test in the command line. You can't
assume vaCreateConfig() will return VA_STATUS_SUCCESS with ignoring
unsupported attribute.
>
> va_status = vaCreateConfig(va_dpy, avcenc_context.profile,
> select_entrypoint,
> - &attrib[0],
> 2,&avcenc_context.config_id);
> + &attrib[0],
> 3,&avcenc_context.config_id);
> CHECK_VASTATUS(va_status, "vaCreateConfig");
>
> /* Create a context for this decode pipe */
> @@ -814,16 +833,70 @@ static int begin_picture(FILE *yuv_fp, int
> frame_num, int display_num, int slice
>
> vaUnmapBuffer(va_dpy, avcenc_context.misc_parameter_hrd_buf_id);
>
> + /* ROI parameter: hard code for test on inly one region
> (0,0,120,120) with qp_delta=4 */
Please update the comment because the region size is not fixed any more
for small frame.
> + if(roi_test_enable)
> + {
> + VAEncMiscParameterBufferROI *misc_roi_param;
> +
> + int roi_num = 1;
> + vaCreateBuffer(va_dpy,
> + avcenc_context.context_id,
> + VAEncMiscParameterBufferType,
> + sizeof(VAEncMiscParameterBuffer) +
> sizeof(VAEncMiscParameterBufferROI) + roi_num * sizeof(VAEncROI),
> + 1,
> + NULL,
> + &avcenc_context.misc_parameter_roi_buf_id);
> + vaMapBuffer(va_dpy,
> + avcenc_context.misc_parameter_roi_buf_id,
> + (void **)&misc_param);
> + misc_param->type = VAEncMiscParameterTypeROI;
> + misc_roi_param = (VAEncMiscParameterBufferROI *)misc_param-
> >data;
> +
> + {
> + /*
> + * Max/Min delta_qp is only used in CBR mode. It is
> ingored under CQP mode.
> + * max_delta_qp means the allowed upper bound of qp
> delta. (qp + X)
> + * min_delta_qp means the allowed lower bound of qp
> delta. (qp -X)
> + * So it will be better that it is positive. Otherwise
> the driver will
> + * use the default bound setting.
> + */
> + misc_roi_param->max_delta_qp = 3;
> + misc_roi_param->min_delta_qp = 3;
> + /* one example of ROI region conf.
> + * please change it on the fly.
> + */
> + VAEncROI *region_roi =(VAEncROI *)((char *)misc_param +
> sizeof(VAEncMiscParameterBuffer) +
> + sizeof(VAEncMiscParameterBufferROI));
> +
> + /*
> + * Under CQP mode roi_value specifies the qp_delta that
> is added to frame qp
> + * Under CBR mode roi_value specifies the important level
> (positive means that
> + * it is important. negative means that it is less
> important).
> + */
> + region_roi->roi_value = 4;
> + region_roi->roi_rectangle.x = 0;
> + region_roi->roi_rectangle.y = 0;
> + region_roi->roi_rectangle.width = (120 <
> picture_width/4)? 120:picture_width/4;
> + region_roi->roi_rectangle.height = (120 <
> picture_height/4)? 120:picture_height/4;
> +
> + misc_roi_param->roi = region_roi;
> + misc_roi_param->num_roi = 1;
> + }
> +
> + vaUnmapBuffer(va_dpy,
> avcenc_context.misc_parameter_roi_buf_id);
> + }
> return 0;
> }
>
> int avcenc_render_picture()
> {
> VAStatus va_status;
> - VABufferID va_buffers[10];
> + VABufferID va_buffers[20];
> unsigned int num_va_buffers = 0;
> int i;
>
> + memset(&va_buffers, 0xff, sizeof(va_buffers));
> +
> va_buffers[num_va_buffers++] = avcenc_context.seq_param_buf_id;
> va_buffers[num_va_buffers++] = avcenc_context.pic_param_buf_id;
>
> @@ -848,6 +921,9 @@ int avcenc_render_picture()
> if (avcenc_context.misc_parameter_hrd_buf_id != VA_INVALID_ID)
> va_buffers[num_va_buffers++]
> = avcenc_context.misc_parameter_hrd_buf_id;
>
> + if (avcenc_context.misc_parameter_roi_buf_id != VA_INVALID_ID)
> + va_buffers[num_va_buffers++]
> = avcenc_context.misc_parameter_roi_buf_id;
> +
> va_status = vaBeginPicture(va_dpy,
> avcenc_context.context_id,
> surface_ids[avcenc_context.current_in
> put_surface]);
> @@ -904,6 +980,7 @@ static void end_picture()
> avcenc_destroy_buffers(&avcenc_context.slice_param_buf_id[0],
> avcenc_context.num_slices);
> avcenc_destroy_buffers(&avcenc_context.codedbuf_buf_id, 1);
> avcenc_destroy_buffers(&avcenc_context.misc_parameter_hrd_buf_id
> , 1);
> + avcenc_destroy_buffers(&avcenc_context.misc_parameter_roi_buf_id
> , 1);
>
> memset(avcenc_context.slice_param, 0,
> sizeof(avcenc_context.slice_param));
> avcenc_context.num_slices = 0;
> @@ -1691,7 +1768,7 @@ encode_picture(FILE *yuv_fp, FILE *avc_fp,
>
> static void show_help()
> {
> - printf("Usage: avnenc <width> <height> <input_yuvfile>
> <output_avcfile> [--qp=qpvalue|--fb=framebitrate] [--mode=0(I frames
> only)/1(I and P frames)/2(I, P and B frames)] [--low-power]\n");
> + printf("Usage: avnenc <width> <height> <input_yuvfile>
> <output_avcfile> [--qp=qpvalue|--fb=framebitrate] [--mode=0(I frames
> only)/1(I and P frames)/2(I, P and B frames)] [--low-power] [--roi-
> test]\n");
> }
>
> static void
> avcenc_context_seq_param_init(VAEncSequenceParameterBufferH264
> *seq_param,
> @@ -1831,6 +1908,7 @@ static void avcenc_context_init(int width, int
> height)
> avcenc_context.upload_thread_value = -1;
> avcenc_context.packed_sei_header_param_buf_id = VA_INVALID_ID;
> avcenc_context.packed_sei_buf_id = VA_INVALID_ID;
> + avcenc_context.misc_parameter_roi_buf_id = VA_INVALID_ID;
>
> if (qp_value == -1)
> avcenc_context.rate_control_method = VA_RC_CBR;
> @@ -1926,6 +2004,10 @@ int main(int argc, char *argv[])
> select_entrypoint = VAEntrypointEncSliceLP;
> break;
>
> + case 5: // roi-test enable/disable
> + roi_test_enable = 1;
> + break;
> +
> default:
> show_help();
> return -1;
More information about the Libva
mailing list