OSDN Git Service

test: use the new H264 encoding and VPP interfaces
authorXiang, Haihao <haihao.xiang@intel.com>
Thu, 16 Feb 2012 03:03:20 +0000 (11:03 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Tue, 28 May 2013 08:46:48 +0000 (16:46 +0800)
Signed-off-by: Xiang, Haihao <haihao.xiang@intel.com>
test/encode/avcenc.c

index 3e05753..a8772c9 100644 (file)
@@ -45,6 +45,7 @@
 #include <pthread.h>
 
 #include <va/va.h>
+#include <va/va_enc_h264.h>
 #include "va_display.h"
 
 #define NAL_REF_IDC_NONE        0
@@ -87,10 +88,6 @@ static int intra_period = 30;
 static int pb_period = 5;
 static int frame_bit_rate = -1;
 
-#define BR_CBR          0
-#define BR_VBR          1
-#define BR_CQP          2
-
 #define MAX_SLICES      32
 
 static int
@@ -108,26 +105,28 @@ struct upload_thread_param
 static void 
 upload_yuv_to_surface(FILE *yuv_fp, VASurfaceID surface_id);
 
-struct {
+static struct {
+    VAProfile profile;
     VAEncSequenceParameterBufferH264 seq_param;
     VAEncPictureParameterBufferH264 pic_param;
     VAEncSliceParameterBufferH264 slice_param[MAX_SLICES];
-    VAEncH264DecRefPicMarkingBuffer dec_ref_pic_marking;
     VAContextID context_id;
     VAConfigID config_id;
     VABufferID seq_param_buf_id;                /* Sequence level parameter */
     VABufferID pic_param_buf_id;                /* Picture level parameter */
     VABufferID slice_param_buf_id[MAX_SLICES];  /* Slice level parameter, multil slices */
-    VABufferID dec_ref_pic_marking_buf_id;
     VABufferID codedbuf_buf_id;                 /* Output buffer, compressed data */
     VABufferID packed_seq_header_param_buf_id;
     VABufferID packed_seq_buf_id;
     VABufferID packed_pic_header_param_buf_id;
     VABufferID packed_pic_buf_id;
+    VABufferID misc_parameter_hrd_buf_id;
+
     int num_slices;
     int codedbuf_i_size;
     int codedbuf_pb_size;
     int current_input_surface;
+    int rate_control_method;
     struct upload_thread_param upload_thread_param;
     pthread_t upload_thread_id;
     int upload_thread_value;
@@ -145,7 +144,7 @@ static void create_encode_pipe()
     va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
     CHECK_VASTATUS(va_status, "vaInitialize");
 
-    vaQueryConfigEntrypoints(va_dpy, VAProfileH264Baseline, entrypoints, 
+    vaQueryConfigEntrypoints(va_dpy, avcenc_context.profile, entrypoints, 
                              &num_entrypoints);
 
     for        (slice_entrypoint = 0; slice_entrypoint < num_entrypoints; slice_entrypoint++) {
@@ -161,7 +160,7 @@ 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;
-    vaGetConfigAttributes(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice,
+    vaGetConfigAttributes(va_dpy, avcenc_context.profile, VAEntrypointEncSlice,
                           &attrib[0], 2);
 
     if ((attrib[0].value & VA_RT_FORMAT_YUV420) == 0) {
@@ -169,16 +168,16 @@ static void create_encode_pipe()
         assert(0);
     }
 
-    if ((attrib[1].value & VA_RC_VBR) == 0) {
+    if ((attrib[1].value & avcenc_context.rate_control_method) == 0) {
         /* Can't find matched RC mode */
-        printf("VBR mode doesn't found, exit\n");
+        printf("Can't find the desired RC mode, exit\n");
         assert(0);
     }
 
     attrib[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */
-    attrib[1].value = VA_RC_VBR; /* set to desired RC mode */
+    attrib[1].value = avcenc_context.rate_control_method; /* set to desired RC mode */
 
-    va_status = vaCreateConfig(va_dpy, VAProfileH264Baseline, VAEntrypointEncSlice,
+    va_status = vaCreateConfig(va_dpy, avcenc_context.profile, VAEntrypointEncSlice,
                                &attrib[0], 2,&avcenc_context.config_id);
     CHECK_VASTATUS(va_status, "vaCreateConfig");
 
@@ -270,7 +269,7 @@ static void avcenc_update_picture_parameter(int slice_type, int frame_num, int d
     pic_param->ReferenceFrames[1].picture_id = surface_ids[SID_REFERENCE_PICTURE_L1];
     pic_param->ReferenceFrames[2].picture_id = VA_INVALID_ID;
     assert(avcenc_context.codedbuf_buf_id != VA_INVALID_ID);
-    pic_param->CodedBuf = avcenc_context.codedbuf_buf_id;
+    pic_param->coded_buf = avcenc_context.codedbuf_buf_id;
     pic_param->frame_num = frame_num;
     pic_param->pic_fields.bits.idr_pic_flag = !!is_idr;
     pic_param->pic_fields.bits.reference_pic_flag = (slice_type != SLICE_TYPE_B);
@@ -366,8 +365,8 @@ static void avcenc_update_slice_parameter(int slice_type)
     // Slice level
     i = 0;
     slice_param = &avcenc_context.slice_param[i];
-    slice_param->starting_macroblock_address = 0;
-    slice_param->number_of_mbs = picture_height_in_mbs * picture_width_in_mbs; 
+    slice_param->macroblock_address = 0;
+    slice_param->num_macroblocks = picture_height_in_mbs * picture_width_in_mbs; 
     slice_param->pic_parameter_set_id = 0;
     slice_param->slice_type = slice_type;
     slice_param->direct_spatial_mv_pred_flag = 0;
@@ -380,9 +379,6 @@ static void avcenc_update_slice_parameter(int slice_type)
     slice_param->slice_beta_offset_div2 = 2;
     slice_param->idr_pic_id = 0;
 
-    /* ref_pic_list_modification() */
-    slice_param->ref_pic_list_modification_flag_l0 = 0;
-    slice_param->ref_pic_list_modification_flag_l1 = 0;
     /* FIXME: fill other fields */
 
     va_status = vaCreateBuffer(va_dpy,
@@ -395,8 +391,8 @@ static void avcenc_update_slice_parameter(int slice_type)
 
 #if 0
     slice_param = &avcenc_context.slice_param[i];
-    slice_param->starting_macroblock_address = picture_height_in_mbs * picture_width_in_mbs / 2;
-    slice_param->number_of_mbs = picture_height_in_mbs * picture_width_in_mbs / 2;
+    slice_param->macroblock_address = picture_height_in_mbs * picture_width_in_mbs / 2;
+    slice_param->num_macroblocks = picture_height_in_mbs * picture_width_in_mbs / 2;
     slice_param->pic_parameter_set_id = 0;
     slice_param->slice_type = slice_type;
     slice_param->direct_spatial_mv_pred_flag = 0;
@@ -409,9 +405,6 @@ static void avcenc_update_slice_parameter(int slice_type)
     slice_param->slice_beta_offset_div2 = 2;
     slice_param->idr_pic_id = 0;
 
-    /* ref_pic_list_modification() */
-    slice_param->ref_pic_list_modification_flag_l0 = 0;
-    slice_param->ref_pic_list_modification_flag_l1 = 0;
     /* FIXME: fill other fields */
 
     va_status = vaCreateBuffer(va_dpy,
@@ -452,12 +445,9 @@ static int begin_picture(FILE *yuv_fp, int frame_num, int display_num, int slice
         assert(slice_type == SLICE_TYPE_I);
         length_in_bits = build_packed_seq_buffer(&packed_seq_buffer);
         offset_in_bytes = 0;
-        packed_header_param_buffer.type = VAEncPackedHeaderSPS;
-        packed_header_param_buffer.insert_emulation_bytes = 1;
-        packed_header_param_buffer.skip_emulation_check_count = 5; /* ignore start code & nal type for emulation prevetion check */
-        packed_header_param_buffer.num_headers = 1;
-        packed_header_param_buffer.length_in_bits = &length_in_bits;
-        packed_header_param_buffer.offset_in_bytes = &offset_in_bytes;
+        packed_header_param_buffer.type = VAEncPackedHeaderSequence;
+        packed_header_param_buffer.bit_length = length_in_bits;
+        packed_header_param_buffer.has_emulation_bytes = 0;
         va_status = vaCreateBuffer(va_dpy,
                                    avcenc_context.context_id,
                                    VAEncPackedHeaderParameterBufferType,
@@ -474,12 +464,9 @@ static int begin_picture(FILE *yuv_fp, int frame_num, int display_num, int slice
 
         length_in_bits = build_packed_pic_buffer(&packed_pic_buffer);
         offset_in_bytes = 0;
-        packed_header_param_buffer.type = VAEncPackedHeaderPPS;
-        packed_header_param_buffer.insert_emulation_bytes = 1;
-        packed_header_param_buffer.skip_emulation_check_count = 5; /* ignore start code & nal type for emulation prevetion check */
-        packed_header_param_buffer.num_headers = 1;
-        packed_header_param_buffer.length_in_bits = &length_in_bits;
-        packed_header_param_buffer.offset_in_bytes = &offset_in_bytes;
+        packed_header_param_buffer.type = VAEncPackedHeaderPicture;
+        packed_header_param_buffer.bit_length = length_in_bits;
+        packed_header_param_buffer.has_emulation_bytes = 0;
 
         va_status = vaCreateBuffer(va_dpy,
                                    avcenc_context.context_id,
@@ -506,7 +493,36 @@ static int begin_picture(FILE *yuv_fp, int frame_num, int display_num, int slice
                                VAEncSequenceParameterBufferType,
                                sizeof(*seq_param), 1, seq_param,
                                &avcenc_context.seq_param_buf_id);
-    CHECK_VASTATUS(va_status,"vaCreateBuffer");;
+    CHECK_VASTATUS(va_status,"vaCreateBuffer");
+
+
+    /* hrd parameter */
+    VAEncMiscParameterBuffer *misc_param;
+    VAEncMiscParameterHRD *misc_hrd_param;
+    vaCreateBuffer(va_dpy,
+                   avcenc_context.context_id,
+                   VAEncMiscParameterBufferType,
+                   sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterRateControl),
+                   1,
+                   NULL, 
+                   &avcenc_context.misc_parameter_hrd_buf_id);
+    CHECK_VASTATUS(va_status, "vaCreateBuffer");
+
+    vaMapBuffer(va_dpy,
+                avcenc_context.misc_parameter_hrd_buf_id,
+                (void **)&misc_param);
+    misc_param->type = VAEncMiscParameterTypeHRD;
+    misc_hrd_param = (VAEncMiscParameterHRD *)misc_param->data;
+
+    if (frame_bit_rate > 0) {
+        misc_hrd_param->initial_buffer_fullness = frame_bit_rate * 1024 * 4;
+        misc_hrd_param->buffer_size = frame_bit_rate * 1024 * 8;
+    } else {
+        misc_hrd_param->initial_buffer_fullness = 0;
+        misc_hrd_param->buffer_size = 0;
+    }
+
+    vaUnmapBuffer(va_dpy, avcenc_context.misc_parameter_hrd_buf_id);
 
     /* slice parameter */
     avcenc_update_slice_parameter(slice_type);
@@ -524,9 +540,6 @@ int avcenc_render_picture()
     va_buffers[num_va_buffers++] = avcenc_context.seq_param_buf_id;
     va_buffers[num_va_buffers++] = avcenc_context.pic_param_buf_id;
 
-    if (avcenc_context.dec_ref_pic_marking_buf_id != VA_INVALID_ID)
-        va_buffers[num_va_buffers++] = avcenc_context.dec_ref_pic_marking_buf_id;
-
     if (avcenc_context.packed_seq_header_param_buf_id != VA_INVALID_ID)
         va_buffers[num_va_buffers++] = avcenc_context.packed_seq_header_param_buf_id;
 
@@ -539,6 +552,9 @@ int avcenc_render_picture()
     if (avcenc_context.packed_pic_buf_id != VA_INVALID_ID)
         va_buffers[num_va_buffers++] = avcenc_context.packed_pic_buf_id;
 
+    if (avcenc_context.misc_parameter_hrd_buf_id != VA_INVALID_ID)
+        va_buffers[num_va_buffers++] =  avcenc_context.misc_parameter_hrd_buf_id;
+
     va_status = vaBeginPicture(va_dpy,
                                avcenc_context.context_id,
                                surface_ids[avcenc_context.current_input_surface]);
@@ -605,13 +621,14 @@ static void end_picture(int slice_type, int next_is_bpic)
 
     avcenc_destroy_buffers(&avcenc_context.seq_param_buf_id, 1);
     avcenc_destroy_buffers(&avcenc_context.pic_param_buf_id, 1);
-    avcenc_destroy_buffers(&avcenc_context.dec_ref_pic_marking_buf_id, 1);
     avcenc_destroy_buffers(&avcenc_context.packed_seq_header_param_buf_id, 1);
     avcenc_destroy_buffers(&avcenc_context.packed_seq_buf_id, 1);
     avcenc_destroy_buffers(&avcenc_context.packed_pic_header_param_buf_id, 1);
     avcenc_destroy_buffers(&avcenc_context.packed_pic_buf_id, 1);
     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);
+
     memset(avcenc_context.slice_param, 0, sizeof(avcenc_context.slice_param));
     avcenc_context.num_slices = 0;
 }
@@ -773,8 +790,14 @@ static void nal_header(bitstream *bs, int nal_ref_idc, int nal_unit_type)
 static void sps_rbsp(bitstream *bs)
 {
     VAEncSequenceParameterBufferH264 *seq_param = &avcenc_context.seq_param;
+    int profile_idc = PROFILE_IDC_BASELINE;
+
+    if (avcenc_context.profile == VAProfileH264High)
+        profile_idc = PROFILE_IDC_HIGH;
+    else if (avcenc_context.profile == VAProfileH264Main)
+        profile_idc = PROFILE_IDC_MAIN;
 
-    bitstream_put_ui(bs, seq_param->profile_idc, 8);    /* profile_idc */
+    bitstream_put_ui(bs, profile_idc, 8);               /* profile_idc */
     bitstream_put_ui(bs, 0, 1);                         /* constraint_set0_flag */
     bitstream_put_ui(bs, 1, 1);                         /* constraint_set1_flag */
     bitstream_put_ui(bs, 0, 1);                         /* constraint_set2_flag */
@@ -783,16 +806,11 @@ static void sps_rbsp(bitstream *bs)
     bitstream_put_ui(bs, seq_param->level_idc, 8);      /* level_idc */
     bitstream_put_ue(bs, seq_param->seq_parameter_set_id);      /* seq_parameter_set_id */
 
-    if (seq_param->profile_idc >= PROFILE_IDC_HIGH) {
-        /* FIXME: fix for high profile */
-        assert(0);
-    }
+    bitstream_put_ue(bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4); /* log2_max_frame_num_minus4 */
+    bitstream_put_ue(bs, seq_param->seq_fields.bits.pic_order_cnt_type);        /* pic_order_cnt_type */
 
-    bitstream_put_ue(bs, seq_param->log2_max_frame_num_minus4); /* log2_max_frame_num_minus4 */
-    bitstream_put_ue(bs, seq_param->pic_order_cnt_type);        /* pic_order_cnt_type */
-
-    if (seq_param->pic_order_cnt_type == 0)
-        bitstream_put_ue(bs, seq_param->log2_max_pic_order_cnt_lsb_minus4);     /* log2_max_pic_order_cnt_lsb_minus4 */
+    if (seq_param->seq_fields.bits.pic_order_cnt_type == 0)
+        bitstream_put_ue(bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);     /* log2_max_pic_order_cnt_lsb_minus4 */
     else {
         assert(0);
     }
@@ -802,13 +820,13 @@ static void sps_rbsp(bitstream *bs)
 
     bitstream_put_ue(bs, seq_param->picture_width_in_mbs - 1);  /* pic_width_in_mbs_minus1 */
     bitstream_put_ue(bs, seq_param->picture_height_in_mbs - 1); /* pic_height_in_map_units_minus1 */
-    bitstream_put_ui(bs, seq_param->frame_mbs_only_flag, 1);    /* frame_mbs_only_flag */
+    bitstream_put_ui(bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1);    /* frame_mbs_only_flag */
 
-    if (!seq_param->frame_mbs_only_flag) {
+    if (!seq_param->seq_fields.bits.frame_mbs_only_flag) {
         assert(0);
     }
 
-    bitstream_put_ui(bs, seq_param->direct_8x8_inference_flag, 1);      /* direct_8x8_inference_flag */
+    bitstream_put_ui(bs, seq_param->seq_fields.bits.direct_8x8_inference_flag, 1);      /* direct_8x8_inference_flag */
     bitstream_put_ui(bs, seq_param->frame_cropping_flag, 1);            /* frame_cropping_flag */
 
     if (seq_param->frame_cropping_flag) {
@@ -968,10 +986,10 @@ slice_header(bitstream *bs, int frame_num, int display_frame, int slice_type, in
     bitstream_put_ue(bs, 0);                   /* first_mb_in_slice: 0 */
     bitstream_put_ue(bs, slice_type);          /* slice_type */
     bitstream_put_ue(bs, 0);                   /* pic_parameter_set_id: 0 */
-    bitstream_put_ui(bs, frame_num & 0x0F, seq_param->log2_max_frame_num_minus4 + 4);    /* frame_num */
+    bitstream_put_ui(bs, frame_num & 0x0F, seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 4);    /* frame_num */
 
     /* frame_mbs_only_flag == 1 */
-    if (!seq_param->frame_mbs_only_flag) {
+    if (!seq_param->seq_fields.bits.frame_mbs_only_flag) {
         /* FIXME: */
         assert(0);
     }
@@ -979,8 +997,8 @@ slice_header(bitstream *bs, int frame_num, int display_frame, int slice_type, in
     if (is_idr)
         bitstream_put_ue(bs, 0);               /* idr_pic_id: 0 */
 
-    if (seq_param->pic_order_cnt_type == 0) {
-        bitstream_put_ui(bs, (display_frame*2) & 0x3F, seq_param->log2_max_pic_order_cnt_lsb_minus4 + 4);
+    if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) {
+        bitstream_put_ui(bs, (display_frame*2) & 0x3F, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4);
         /* only support frame */
     } else {
         /* FIXME: */
@@ -1224,50 +1242,26 @@ static void avcenc_context_seq_param_init(VAEncSequenceParameterBufferH264 *seq_
     int frame_crop_bottom_offset = 0;
 
     seq_param->seq_parameter_set_id = 0;
-    seq_param->profile_idc = PROFILE_IDC_MAIN;
     seq_param->level_idc = 41;
     seq_param->intra_period = intra_period;
     seq_param->ip_period = 0;   /* FIXME: ??? */
     seq_param->max_num_ref_frames = 4;
     seq_param->picture_width_in_mbs = width_in_mbs;
     seq_param->picture_height_in_mbs = height_in_mbs;
-    seq_param->frame_mbs_only_flag = 1;
-    seq_param->target_usage = 1;
+    seq_param->seq_fields.bits.frame_mbs_only_flag = 1;
     
-    /* 0:CBR, 1:VBR, 2:Constant QP */
-    if (qp_value == -1)
-        seq_param->rate_control_method = BR_CBR;
-    else if (qp_value == -2)
-        seq_param->rate_control_method = BR_VBR;
-    else {
-        assert(qp_value >= 0 && qp_value <= 51);
-        seq_param->rate_control_method = BR_CQP;
-    }
-
     if (frame_bit_rate > 0)
         seq_param->bits_per_second = 1024 * frame_bit_rate; /* use kbps as input */
     else
         seq_param->bits_per_second = 0;
-
-    if (seq_param->rate_control_method == BR_VBR) {
-        seq_param->max_bits_per_second = 0;     /* FIXME: set it later */
-        seq_param->min_bits_per_second = 0;
-    }
-
-       if ( frame_bit_rate > 0) {
-               seq_param->initial_hrd_buffer_fullness = frame_bit_rate * 1024 * 4;
-               seq_param->hrd_buffer_size = frame_bit_rate * 1024 * 8;
-       } else {
-               seq_param->initial_hrd_buffer_fullness = 0; 
-               seq_param->hrd_buffer_size = 0;             
-       }
+    
     seq_param->time_scale = 900;
     seq_param->num_units_in_tick = 15;                 /* Tc = num_units_in_tick / time_sacle */
 
     if (height_in_mbs * 16 - height) {
         frame_cropping_flag = 1;
         frame_crop_bottom_offset = 
-            (height_in_mbs * 16 - height) / (2 * (!seq_param->frame_mbs_only_flag + 1));
+            (height_in_mbs * 16 - height) / (2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1));
     }
 
     seq_param->frame_cropping_flag = frame_cropping_flag;
@@ -1276,16 +1270,16 @@ static void avcenc_context_seq_param_init(VAEncSequenceParameterBufferH264 *seq_
     seq_param->frame_crop_top_offset = 0;
     seq_param->frame_crop_bottom_offset = frame_crop_bottom_offset;
 
-    seq_param->pic_order_cnt_type = 0;
-    seq_param->direct_8x8_inference_flag = 0;
+    seq_param->seq_fields.bits.pic_order_cnt_type = 0;
+    seq_param->seq_fields.bits.direct_8x8_inference_flag = 0;
     
-    seq_param->log2_max_frame_num_minus4 = 0;
-    seq_param->log2_max_pic_order_cnt_lsb_minus4 = 2;
+    seq_param->seq_fields.bits.log2_max_frame_num_minus4 = 0;
+    seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = 2;
        
-       if ( frame_bit_rate > 0)
-               seq_param->vui_flag = 1;        //HRD info located in vui
-       else
-               seq_param->vui_flag = 0;
+    if (frame_bit_rate > 0)
+        seq_param->vui_parameters_present_flag = 1;    //HRD info located in vui
+    else
+        seq_param->vui_parameters_present_flag = 0;
 }
 
 static void avcenc_context_pic_param_init(VAEncPictureParameterBufferH264 *pic_param)
@@ -1295,7 +1289,6 @@ static void avcenc_context_pic_param_init(VAEncPictureParameterBufferH264 *pic_p
 
     pic_param->last_picture = 0;
     pic_param->frame_num = 0;
-    pic_param->coding_type = 0;
     
     pic_param->pic_init_qp = (qp_value >= 0 ?  qp_value : 26);
     pic_param->num_ref_idx_l0_active_minus1 = 0;
@@ -1314,19 +1307,29 @@ static void avcenc_context_init(int width, int height)
 {
     int i;
     memset(&avcenc_context, 0, sizeof(avcenc_context));
+    avcenc_context.profile = VAProfileH264Main;
     avcenc_context.seq_param_buf_id = VA_INVALID_ID;
     avcenc_context.pic_param_buf_id = VA_INVALID_ID;
-    avcenc_context.dec_ref_pic_marking_buf_id = VA_INVALID_ID;
     avcenc_context.packed_seq_header_param_buf_id = VA_INVALID_ID;
     avcenc_context.packed_seq_buf_id = VA_INVALID_ID;
     avcenc_context.packed_pic_header_param_buf_id = VA_INVALID_ID;
     avcenc_context.packed_pic_buf_id = VA_INVALID_ID;
     avcenc_context.codedbuf_buf_id = VA_INVALID_ID;
+    avcenc_context.misc_parameter_hrd_buf_id = VA_INVALID_ID;
     avcenc_context.codedbuf_i_size = width * height;
     avcenc_context.codedbuf_pb_size = 0;
     avcenc_context.current_input_surface = SID_INPUT_PICTURE_0;
     avcenc_context.upload_thread_value = -1;
 
+    if (qp_value == -1)
+        avcenc_context.rate_control_method = VA_RC_CBR;
+    else if (qp_value == -2)
+        avcenc_context.rate_control_method = VA_RC_VBR;
+    else {
+        assert(qp_value >= 0 && qp_value <= 51);
+        avcenc_context.rate_control_method = VA_RC_CQP;
+    }
+
     for (i = 0; i < MAX_SLICES; i++) {
         avcenc_context.slice_param_buf_id[i] = VA_INVALID_ID;
     }