diff options
author | Pengfei Qu <Pengfei.Qu@intel.com> | 2016-12-28 13:50:27 +0800 |
---|---|---|
committer | Sean V Kelley <seanvk@posteo.de> | 2017-01-10 15:22:36 -0800 |
commit | 091e2582a23ac4cd376a851131c96ff9d3f185e6 (patch) | |
tree | 81869cb06ed332cf9e12a4e916e1a8ca440b53f2 | |
parent | 913e82a3331e36bfaea96b41d475ca7cf4ad7bfc (diff) |
ENC: add Misc parameter check for AVC encoder
Signed-off-by: Pengfei Qu <Pengfei.Qu@intel.com>
Reviewed-by: Sean V Kelley <seanvk@posteo.de>
-rwxr-xr-x | src/gen9_avc_encoder.c | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/src/gen9_avc_encoder.c b/src/gen9_avc_encoder.c index 7f73c95..72a8c00 100755 --- a/src/gen9_avc_encoder.c +++ b/src/gen9_avc_encoder.c @@ -410,6 +410,210 @@ const gen9_avc_frame_brc_update_curbe_data gen9_avc_frame_brc_update_curbe_init_ }, }; + +static void +gen9_avc_update_rate_control_parameters(VADriverContextP ctx, + struct intel_encoder_context *encoder_context, + VAEncMiscParameterRateControl *misc) +{ + struct encoder_vme_mfc_context * vme_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context; + struct generic_enc_codec_state * generic_state = (struct generic_enc_codec_state * )vme_context->generic_enc_state; + + generic_state->max_bit_rate = ALIGN(misc->bits_per_second, 1000) / 1000; + generic_state->window_size = misc->window_size; + + if (generic_state->internal_rate_mode == INTEL_BRC_CBR) { + generic_state->min_bit_rate = generic_state->max_bit_rate; + generic_state->mb_brc_enabled = misc->rc_flags.bits.mb_rate_control; + + if (generic_state->target_bit_rate != generic_state->max_bit_rate) { + generic_state->target_bit_rate = generic_state->max_bit_rate; + generic_state->brc_need_reset = 1; + } + } else if (generic_state->internal_rate_mode == INTEL_BRC_VBR) { + generic_state->min_bit_rate = generic_state->max_bit_rate * (2 * misc->target_percentage - 100) / 100; + generic_state->mb_brc_enabled = misc->rc_flags.bits.mb_rate_control; + + if (generic_state->target_bit_rate != generic_state->max_bit_rate * misc->target_percentage / 100) { + generic_state->target_bit_rate = generic_state->max_bit_rate * misc->target_percentage / 100; + generic_state->brc_need_reset = 1; + } + } +} + +static void +gen9_avc_update_hrd_parameters(VADriverContextP ctx, + struct intel_encoder_context *encoder_context, + VAEncMiscParameterHRD *misc) +{ + struct encoder_vme_mfc_context * vme_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context; + struct generic_enc_codec_state * generic_state = (struct generic_enc_codec_state * )vme_context->generic_enc_state; + + if (generic_state->internal_rate_mode == INTEL_BRC_CQP) + return; + + generic_state->vbv_buffer_size_in_bit = misc->buffer_size; + generic_state->init_vbv_buffer_fullness_in_bit = misc->initial_buffer_fullness; +} + +static void +gen9_avc_update_framerate_parameters(VADriverContextP ctx, + struct intel_encoder_context *encoder_context, + VAEncMiscParameterFrameRate *misc) +{ + struct encoder_vme_mfc_context * vme_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context; + struct generic_enc_codec_state * generic_state = (struct generic_enc_codec_state * )vme_context->generic_enc_state; + + generic_state->frames_per_100s = misc->framerate * 100; /* misc->framerate is multiple of 100 */ + generic_state->frame_rate = misc->framerate ; +} + +static void +gen9_avc_update_roi_parameters(VADriverContextP ctx, + struct intel_encoder_context *encoder_context, + VAEncMiscParameterBufferROI *misc) +{ + struct encoder_vme_mfc_context * vme_context = (struct encoder_vme_mfc_context *)encoder_context->vme_context; + struct generic_enc_codec_state * generic_state = (struct generic_enc_codec_state * )vme_context->generic_enc_state; + int i; + + if (!misc || !misc->roi) { + generic_state->num_roi = 0; + return; + } + + generic_state->num_roi = MIN(misc->num_roi, 3); + generic_state->max_delta_qp = misc->max_delta_qp; + generic_state->min_delta_qp = misc->min_delta_qp; + + for (i = 0; i < generic_state->num_roi; i++) { + generic_state->roi[i].left = misc->roi->roi_rectangle.x; + generic_state->roi[i].right = generic_state->roi[i].left + misc->roi->roi_rectangle.width; + generic_state->roi[i].top = misc->roi->roi_rectangle.y; + generic_state->roi[i].bottom = generic_state->roi[i].top + misc->roi->roi_rectangle.height; + generic_state->roi[i].value = misc->roi->roi_value; + + generic_state->roi[i].left /= 16; + generic_state->roi[i].right /= 16; + generic_state->roi[i].top /= 16; + generic_state->roi[i].bottom /= 16; + } +} + +static void +gen9_avc_update_misc_parameters(VADriverContextP ctx, + struct encode_state *encode_state, + struct intel_encoder_context *encoder_context) +{ + int i,j; + VAEncMiscParameterBuffer *misc_param; + + for (i = 0; i < ARRAY_ELEMS(encode_state->misc_param); i++) { + for (j = 0; j < ARRAY_ELEMS(encode_state->misc_param[0]); j++) { + if (!encode_state->misc_param[i][j] || !encode_state->misc_param[i][j]->buffer) + continue; + + misc_param = (VAEncMiscParameterBuffer *)encode_state->misc_param[i][0]->buffer; + + switch (misc_param->type) { + case VAEncMiscParameterTypeFrameRate: + gen9_avc_update_framerate_parameters(ctx, + encoder_context, + (VAEncMiscParameterFrameRate *)misc_param->data); + break; + + case VAEncMiscParameterTypeRateControl: + gen9_avc_update_rate_control_parameters(ctx, + encoder_context, + (VAEncMiscParameterRateControl *)misc_param->data); + break; + + case VAEncMiscParameterTypeHRD: + gen9_avc_update_hrd_parameters(ctx, + encoder_context, + (VAEncMiscParameterHRD *)misc_param->data); + break; + + case VAEncMiscParameterTypeROI: + gen9_avc_update_roi_parameters(ctx, + encoder_context, + (VAEncMiscParameterBufferROI *)misc_param->data); + break; + + default: + break; + } + } + } +} + +static bool +intel_avc_get_kernel_header_and_size(void *pvbinary, + int binary_size, + INTEL_GENERIC_ENC_OPERATION operation, + int krnstate_idx, + struct i965_kernel *ret_kernel) +{ + typedef uint32_t BIN_PTR[4]; + + char *bin_start; + gen9_avc_encoder_kernel_header *pkh_table; + kernel_header *pcurr_header, *pinvalid_entry, *pnext_header; + int next_krnoffset; + + if (!pvbinary || !ret_kernel) + return false; + + bin_start = (char *)pvbinary; + pkh_table = (gen9_avc_encoder_kernel_header *)pvbinary; + pinvalid_entry = &(pkh_table->static_detection) + 1; + next_krnoffset = binary_size; + + if (operation == INTEL_GENERIC_ENC_SCALING4X) + { + pcurr_header = &pkh_table->ply_dscale_ply; + } + else if (operation == INTEL_GENERIC_ENC_SCALING2X) + { + pcurr_header = &pkh_table->ply_2xdscale_ply; + } + else if (operation == INTEL_GENERIC_ENC_ME) + { + pcurr_header = &pkh_table->me_p; + } + else if (operation == INTEL_GENERIC_ENC_BRC) + { + pcurr_header = &pkh_table->frame_brc_init; + } + else if (operation == INTEL_GENERIC_ENC_MBENC) + { + pcurr_header = &pkh_table->mbenc_quality_I; + } + else if (operation == INTEL_GENERIC_ENC_WP) + { + pcurr_header = &pkh_table->wp; + } + else if (operation == INTEL_GENERIC_ENC_SFD) + { + pcurr_header = &pkh_table->static_detection; + } + else + { + return false; + } + + pcurr_header += krnstate_idx; + ret_kernel->bin = (const BIN_PTR *)(bin_start + (pcurr_header->kernel_start_pointer << 6)); + + pnext_header = (pcurr_header + 1); + if (pnext_header < pinvalid_entry) + { + next_krnoffset = pnext_header->kernel_start_pointer << 6; + } + ret_kernel->size = next_krnoffset - (pcurr_header->kernel_start_pointer << 6); + + return true; +} static void gen9_free_surfaces_avc(void **data) { |