[Libva] [PATCH 2/3] Add multi quality levels encoding support for GEN7
lizhong
zhong.li at intel.com
Wed Jun 4 22:23:38 PDT 2014
On 06/05/2014 01:14 PM, Xiang, Haihao wrote:
> On Thu, 2014-06-05 at 12:54 +0800, lizhong wrote:
>> On 06/05/2014 12:12 PM, Xiang, Haihao wrote:
>>> On Wed, 2014-06-04 at 21:37 +0800, Zhong Li wrote:
>>>> Two encoding quality levels are support on GEN7.
>>>> Default quality level is set to be 1, which has better quality,
>>>> but higher gpu usage and worse performance.
>>>> The second quality level is set to be 2, which has lower gpu usage and
>>>> better performance,but worse quality.
>>>> Other platforms support for multi-quality-level will be added later.
>>>>
>>>> Signed-off-by: Zhong Li <zhong.li at intel.com>
>>>> ---
>>>> src/gen6_mfc.c | 130 ++++++++++++++++++++++++++++++++++++++------------
>>>> src/gen7_vme.c | 84 +++++++++++++++++++++++++++-----
>>>> src/i965_drv_video.c | 12 +++++
>>>> src/i965_drv_video.h | 7 +++
>>>> src/i965_encoder.c | 21 +++++++-
>>>> 5 files changed, 211 insertions(+), 43 deletions(-)
>>>>
>>>> diff --git a/src/gen6_mfc.c b/src/gen6_mfc.c
>>>> index 0a10054..f1cd7ea 100644
>>>> --- a/src/gen6_mfc.c
>>>> +++ b/src/gen6_mfc.c
>>>> @@ -676,8 +676,6 @@ gen6_mfc_stop(VADriverContextP ctx,
>>>> return VA_STATUS_SUCCESS;
>>>> }
>>>>
>>>> -#if __SOFTWARE__
>>>> -
>>>> static int
>>>> gen6_mfc_avc_pak_object_intra(VADriverContextP ctx, int x, int y, int end_mb, int qp,unsigned int *msg,
>>>> struct intel_encoder_context *encoder_context,
>>>> @@ -768,6 +766,58 @@ gen6_mfc_avc_pak_object_inter(VADriverContextP ctx, int x, int y, int end_mb, in
>>>>
>>>> return len_in_dwords;
>>>> }
>>>> +
>>>> +static int
>>>> +gen6_mfc_avc_pak_object_inter2(VADriverContextP ctx, int x, int y, int end_mb, int qp,
>>>> + unsigned int offset,
>>>> + struct intel_encoder_context *encoder_context,
>>>> + struct intel_batchbuffer *batch)
>>>> +{
>>>> + struct gen6_vme_context *vme_context = encoder_context->vme_context;
>>>> + int len_in_dwords = 11;
>>>> +
>>>> + if (batch == NULL)
>>>> + batch = encoder_context->base.batch;
>>>> +
>>>> + BEGIN_BCS_BATCH(batch, len_in_dwords);
>>>> +
>>>> + OUT_BCS_BATCH(batch, MFC_AVC_PAK_OBJECT | (len_in_dwords - 2));
>>>> +
>>>> + OUT_BCS_BATCH(batch, 32); /* 32 MV*/
>>>> + OUT_BCS_BATCH(batch, offset);
>>>> +
>>>> + OUT_BCS_BATCH(batch,
>>>> + (1 << 24) | /* PackedMvNum, Debug*/
>>>> + (4 << 20) | /* 8 MV, SNB don't use it*/
>>>> + (1 << 19) | /* CbpDcY */
>>>> + (1 << 18) | /* CbpDcU */
>>>> + (1 << 17) | /* CbpDcV */
>>>> + (0 << 15) | /* Transform8x8Flag = 0*/
>>>> + (0 << 14) | /* Frame based*/
>>>> + (0 << 13) | /* Inter MB */
>>>> + (1 << 8) | /* MbType = P_L0_16x16 */
>>>> + (0 << 7) | /* MBZ for frame */
>>>> + (0 << 6) | /* MBZ */
>>>> + (2 << 4) | /* MBZ for inter*/
>>>> + (0 << 3) | /* MBZ */
>>>> + (0 << 2) | /* SkipMbFlag */
>>>> + (0 << 0)); /* InterMbMode */
>>>> +
>>>> + OUT_BCS_BATCH(batch, (0xFFFF<<16) | (y << 8) | x); /* Code Block Pattern for Y*/
>>>> + OUT_BCS_BATCH(batch, 0x000F000F); /* Code Block Pattern */
>>>> + OUT_BCS_BATCH(batch, (0 << 27) | (end_mb << 26) | qp); /* Last MB */
>>>> +
>>>> + /*Stuff for Inter MB*/
>>>> + OUT_BCS_BATCH(batch, 0x0);
>>>> + OUT_BCS_BATCH(batch, 0x0);
>>>> + OUT_BCS_BATCH(batch, 0x0);
>>>> +
>>>> + OUT_BCS_BATCH(batch, 0xF0020000); /*MaxSizeInWord and TargetSzieInWord*/
>>>> +
>>>> + ADVANCE_BCS_BATCH(batch);
>>>> +
>>>> + return len_in_dwords;
>>>> +}
>>>>
>>>> static void
>>>> gen6_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
>>>> @@ -791,6 +841,7 @@ gen6_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
>>>> unsigned int tail_data[] = { 0x0, 0x0 };
>>>> int slice_type = intel_avc_enc_slice_type_fixup(pSliceParameter->slice_type);
>>>> int is_intra = slice_type == SLICE_TYPE_I;
>>>> + int is_low_quality = (encode_state->quality_level == ENCODER_LOW_QUALITY);
>>>>
>>>> if (rate_control_mode == VA_RC_CBR) {
>>>> qp = mfc_context->bit_rate_control_context[slice_type].QpPrimeY;
>>>> @@ -818,36 +869,54 @@ gen6_mfc_avc_pipeline_slice_programing(VADriverContextP ctx,
>>>> dri_bo_map(vme_context->vme_output.bo , 1);
>>>> msg = (unsigned int *)vme_context->vme_output.bo->virtual;
>>>>
>>>> - if (is_intra) {
>>>> - msg += pSliceParameter->macroblock_address * INTRA_VME_OUTPUT_IN_DWS;
>>>> - } else {
>>>> - msg += pSliceParameter->macroblock_address * INTER_VME_OUTPUT_IN_DWS;
>>>> - msg += 32; /* the first 32 DWs are MVs */
>>>> - offset = pSliceParameter->macroblock_address * INTER_VME_OUTPUT_IN_BYTES;
>>>> - }
>>>> -
>>>> - for (i = pSliceParameter->macroblock_address;
>>>> - i < pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks; i++) {
>>>> - int last_mb = (i == (pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks - 1) );
>>>> - x = i % width_in_mbs;
>>>> - y = i / width_in_mbs;
>>>> + if (is_low_quality) {
>>>> + for (i = pSliceParameter->macroblock_address;
>>>> + i < pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks; i++) {
>>>> + int last_mb = (i == (pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks - 1) );
>>>> + x = i % width_in_mbs;
>>>> + y = i / width_in_mbs;
>>>>
>>>> + if (is_intra) {
>>>> + assert(msg);
>>>> + gen6_mfc_avc_pak_object_intra(ctx, x, y, last_mb, qp, msg, encoder_context, 0, 0, slice_batch);
>>>> + msg += 4;
>>>> + } else {
>>>> + gen6_mfc_avc_pak_object_inter2(ctx, x, y, last_mb, qp, offset, encoder_context, slice_batch);
>>>> + offset += 64;
>>>> + }
>>>> + }
>>>> + } else {
>>>> if (is_intra) {
>>>> - assert(msg);
>>>> - gen6_mfc_avc_pak_object_intra(ctx, x, y, last_mb, qp, msg, encoder_context, 0, 0, slice_batch);
>>>> - msg += INTRA_VME_OUTPUT_IN_DWS;
>>>> + msg += pSliceParameter->macroblock_address * INTRA_VME_OUTPUT_IN_DWS;
>>>> } else {
>>>> - if (msg[0] & INTRA_MB_FLAG_MASK) {
>>>> + msg += pSliceParameter->macroblock_address * INTER_VME_OUTPUT_IN_DWS;
>>>> + msg += 32; /* the first 32 DWs are MVs */
>>>> + offset = pSliceParameter->macroblock_address * INTER_VME_OUTPUT_IN_BYTES;
>>>> + }
>>>> +
>>>> + for (i = pSliceParameter->macroblock_address;
>>>> + i < pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks; i++) {
>>>> + int last_mb = (i == (pSliceParameter->macroblock_address + pSliceParameter->num_macroblocks - 1) );
>>>> + x = i % width_in_mbs;
>>>> + y = i / width_in_mbs;
>>>> +
>>>> + if (is_intra) {
>>>> + assert(msg);
>>>> gen6_mfc_avc_pak_object_intra(ctx, x, y, last_mb, qp, msg, encoder_context, 0, 0, slice_batch);
>>>> + msg += INTRA_VME_OUTPUT_IN_DWS;
>>>> } else {
>>>> - gen6_mfc_avc_pak_object_inter(ctx, x, y, last_mb, qp, msg, offset, encoder_context, 0, 0, slice_type, slice_batch);
>>>> - }
>>>> + if (msg[0] & INTRA_MB_FLAG_MASK) {
>>>> + gen6_mfc_avc_pak_object_intra(ctx, x, y, last_mb, qp, msg, encoder_context, 0, 0, slice_batch);
>>>> + } else {
>>>> + gen6_mfc_avc_pak_object_inter(ctx, x, y, last_mb, qp, msg, offset, encoder_context, 0, 0, slice_type, slice_batch);
>>>> + }
>>>>
>>>> - msg += INTER_VME_OUTPUT_IN_DWS;
>>>> - offset += INTER_VME_OUTPUT_IN_BYTES;
>>>> + msg += INTER_VME_OUTPUT_IN_DWS;
>>>> + offset += INTER_VME_OUTPUT_IN_BYTES;
>>>> + }
>>>> }
>>>> }
>>>> -
>>>> +
>>>> dri_bo_unmap(vme_context->vme_output.bo);
>>>>
>>>> if ( last_slice ) {
>>>> @@ -896,8 +965,6 @@ gen6_mfc_avc_software_batchbuffer(VADriverContextP ctx,
>>>> return batch_bo;
>>>> }
>>>>
>>>> -#else
>>>> -
>>>> static void
>>>> gen6_mfc_batchbuffer_surfaces_input(VADriverContextP ctx,
>>>> struct encode_state *encode_state,
>>>> @@ -1291,9 +1358,6 @@ gen6_mfc_avc_hardware_batchbuffer(VADriverContextP ctx,
>>>> return mfc_context->mfc_batchbuffer_surface.bo;
>>>> }
>>>>
>>>> -#endif
>>>> -
>>>> -
>>>> static void
>>>> gen6_mfc_avc_pipeline_programing(VADriverContextP ctx,
>>>> struct encode_state *encode_state,
>>>> @@ -1308,11 +1372,15 @@ gen6_mfc_avc_pipeline_programing(VADriverContextP ctx,
>>>> return;
>>>> }
>>>>
>>>> + if (encode_state->quality_level == ENCODER_LOW_QUALITY )
>>>> + slice_batch_bo = gen6_mfc_avc_software_batchbuffer(ctx, encode_state, encoder_context);
>>>> + else {
>>>> #if __SOFTWARE__
>>>> - slice_batch_bo = gen6_mfc_avc_software_batchbuffer(ctx, encode_state, encoder_context);
>>>> + slice_batch_bo = gen6_mfc_avc_software_batchbuffer(ctx, encode_state, encoder_context);
>>>> #else
>>>> - slice_batch_bo = gen6_mfc_avc_hardware_batchbuffer(ctx, encode_state, encoder_context);
>>>> + slice_batch_bo = gen6_mfc_avc_hardware_batchbuffer(ctx, encode_state, encoder_context);
>>>> #endif
>>>> + }
>>>>
>>>> // begin programing
>>>> intel_batchbuffer_start_atomic_bcs(batch, 0x4000);
>>>> diff --git a/src/gen7_vme.c b/src/gen7_vme.c
>>>> index 042fe5d..b45f558 100644
>>>> --- a/src/gen7_vme.c
>>>> +++ b/src/gen7_vme.c
>>>> @@ -63,6 +63,8 @@ enum VIDEO_CODING_TYPE{
>>>> enum AVC_VME_KERNEL_TYPE{
>>>> AVC_VME_INTRA_SHADER = 0,
>>>> AVC_VME_INTER_SHADER,
>>>> + AVC_VME_OLD_INTRA_SHADER,
>>>> + AVC_VME_OLD_INTER_SHADER,
>>>> AVC_VME_BATCHBUFFER,
>>>> AVC_VME_BINTER_SHADER,
>>>> AVC_VME_KERNEL_SUM
>>>> @@ -83,6 +85,14 @@ static const uint32_t gen7_vme_inter_frame[][4] = {
>>>> #include "shaders/vme/inter_frame_ivb.g7b"
>>>> };
>>>>
>>>> +static const uint32_t gen7_vme_old_intra_frame[][4] = {
>>>> +#include "shaders/vme_old/intra_frame.g7b"
>>>> +};
>>>> +
>>>> +static const uint32_t gen7_vme_old_inter_frame[][4] = {
>>>> +#include "shaders/vme_old/inter_frame.g7b"
>>>> +};
>>>> +
>>>> static const uint32_t gen7_vme_batchbuffer[][4] = {
>>>> #include "shaders/vme/batchbuffer.g7b"
>>>> };
>>>> @@ -107,6 +117,20 @@ static struct i965_kernel gen7_vme_kernels[] = {
>>>> NULL
>>>> },
>>>> {
>>>> + "AVC VME Old Intra Frame",
>>>> + AVC_VME_OLD_INTRA_SHADER,
>>>> + gen7_vme_old_intra_frame,
>>>> + sizeof(gen7_vme_old_intra_frame),
>>>> + NULL
>>>> + },
>>>> + {
>>>> + "AVC VME Old Inter Frame",
>>>> + AVC_VME_OLD_INTER_SHADER,
>>>> + gen7_vme_old_inter_frame,
>>>> + sizeof(gen7_vme_old_inter_frame),
>>>> + NULL
>>>> + },
>>>> + {
>>>> "AVC VME BATCHBUFFER",
>>>> AVC_VME_BATCHBUFFER,
>>>> gen7_vme_batchbuffer,
>>>> @@ -359,6 +383,36 @@ static VAStatus gen7_vme_constant_setup(VADriverContextP ctx,
>>>> return VA_STATUS_SUCCESS;
>>>> }
>>>>
>>>> +static VAStatus
>>>> +gen7_vme_vme_state_setup(VADriverContextP ctx,
>>>> + struct encode_state *encode_state,
>>>> + int is_intra,
>>>> + struct intel_encoder_context *encoder_context)
>>>> +{
>>>> + struct gen6_vme_context *vme_context = encoder_context->vme_context;
>>>> + unsigned int *vme_state_message;
>>>> + int i;
>>>> +
>>>> + //building VME state message
>>>> + dri_bo_map(vme_context->vme_state.bo, 1);
>>>> + assert(vme_context->vme_state.bo->virtual);
>>>> + vme_state_message = (unsigned int *)vme_context->vme_state.bo->virtual;
>>>> +
>>>> + vme_state_message[0] = 0x10010101;
>>>> + vme_state_message[1] = 0x100F0F0F;
>>>> + vme_state_message[2] = 0x10010101;
>>>> + vme_state_message[3] = 0x000F0F0F;
>>>> + for(i = 4; i < 14; i++) {
>>>> + vme_state_message[i] = 0x00000000;
>>>> + }
>>>> +
>>>> + for(i = 14; i < 32; i++) {
>>>> + vme_state_message[i] = 0x00000000;
>>>> + }
>>>> +
>>>> + dri_bo_unmap( vme_context->vme_state.bo);
>>>> + return VA_STATUS_SUCCESS;
>>>> +}
>>>>
>>>> static VAStatus gen7_vme_avc_state_setup(VADriverContextP ctx,
>>>> struct encode_state *encode_state,
>>>> @@ -598,25 +652,30 @@ static void gen7_vme_pipeline_programing(VADriverContextP ctx,
>>>> int s;
>>>> bool allow_hwscore = true;
>>>> int kernel_shader;
>>>> -
>>>> - for (s = 0; s < encode_state->num_slice_params_ext; s++) {
>>>> - pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[s]->buffer;
>>>> - if ((pSliceParameter->macroblock_address % width_in_mbs)) {
>>>> - allow_hwscore = false;
>>>> - break;
>>>> - }
>>>> + unsigned int is_low_quality = (encode_state->quality_level == ENCODER_LOW_QUALITY);
>>>> +
>>>> + if (is_low_quality)
>>>> + allow_hwscore = false;
>>>> + else {
>>>> + for (s = 0; s < encode_state->num_slice_params_ext; s++) {
>>>> + pSliceParameter = (VAEncSliceParameterBufferH264 *)encode_state->slice_params_ext[s]->buffer;
>>>> + if ((pSliceParameter->macroblock_address % width_in_mbs)) {
>>>> + allow_hwscore = false;
>>>> + break;
>>>> + }
>>>> + }
>>>> }
>>>>
>>>> if ((pSliceParameter->slice_type == SLICE_TYPE_I) ||
>>>> (pSliceParameter->slice_type == SLICE_TYPE_I)) {
>>>> - kernel_shader = AVC_VME_INTRA_SHADER;
>>>> + kernel_shader = (is_low_quality ? AVC_VME_OLD_INTRA_SHADER : AVC_VME_INTRA_SHADER);
>>>> } else if ((pSliceParameter->slice_type == SLICE_TYPE_P) ||
>>>> (pSliceParameter->slice_type == SLICE_TYPE_SP)) {
>>>> - kernel_shader = AVC_VME_INTER_SHADER;
>>>> + kernel_shader = (is_low_quality ? AVC_VME_OLD_INTER_SHADER : AVC_VME_INTER_SHADER);
>>>> } else {
>>>> kernel_shader = AVC_VME_BINTER_SHADER;
>>>> if (!allow_hwscore)
>>>> - kernel_shader = AVC_VME_INTER_SHADER;
>>>> + kernel_shader = (is_low_quality ? AVC_VME_OLD_INTER_SHADER : AVC_VME_INTER_SHADER);
>>>> }
>>>>
>>>> if (allow_hwscore)
>>>> @@ -668,7 +727,10 @@ static VAStatus gen7_vme_prepare(VADriverContextP ctx,
>>>> gen7_vme_surface_setup(ctx, encode_state, is_intra, encoder_context);
>>>> gen7_vme_interface_setup(ctx, encode_state, encoder_context);
>>>> gen7_vme_constant_setup(ctx, encode_state, encoder_context);
>>>> - gen7_vme_avc_state_setup(ctx, encode_state, is_intra, encoder_context);
>>>> + if (encode_state->quality_level == ENCODER_LOW_QUALITY)
>>>> + gen7_vme_vme_state_setup(ctx, encode_state, is_intra, encoder_context);
>>>> + else
>>>> + gen7_vme_avc_state_setup(ctx, encode_state, is_intra, encoder_context);
>>>>
>>>> /*Programing media pipeline*/
>>>> gen7_vme_pipeline_programing(ctx, encode_state, encoder_context);
>>>> diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
>>>> index fcbab79..6eaf6ca 100755
>>>> --- a/src/i965_drv_video.c
>>>> +++ b/src/i965_drv_video.c
>>>> @@ -621,6 +621,7 @@ i965_GetConfigAttributes(VADriverContextP ctx,
>>>> int num_attribs)
>>>> {
>>>> VAStatus va_status;
>>>> + struct i965_driver_data *i965 = i965_driver_data(ctx);
>>>> int i;
>>>>
>>>> va_status = i965_validate_config(ctx, profile, entrypoint);
>>>> @@ -665,6 +666,15 @@ i965_GetConfigAttributes(VADriverContextP ctx,
>>>> break;
>>>> }
>>>>
>>>> + case VAConfigAttribEncQualityRange:
>>>> + if (entrypoint == VAEntrypointEncSlice) {
>>>> + attrib_list[i].value = 1;
>>>> + if (profile == VAProfileH264ConstrainedBaseline &&
>>>> + IS_GEN7(i965->intel.device_info))
>>> Does the low quality shader support Main Profile ?
>> [Zhong] No, it cann't support B frame, so cann't support Main profile.
>> And it cann't support 8x8 transform(This is high profile feature).
>
> Actually the shader can support B frame with few changes, you can check
> the commit log.
>
[Zhong] Thanks for your remind, I'll check it.
But maybe we can apply these patches, then add more features and reduce
more limitations later.
>>>> + attrib_list[i].value = ENCODER_QUALITY_RANGE;
>>>> + break;
>>>> + }
>>>> +
>>>> default:
>>>> /* Do nothing */
>>>> attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
>>>> @@ -2214,6 +2224,8 @@ i965_BeginPicture(VADriverContextP ctx,
>>>> obj_context->codec_state.encode.num_slice_params_ext = 0;
>>>> obj_context->codec_state.encode.current_render_target = render_target; /*This is input new frame*/
>>>> obj_context->codec_state.encode.last_packed_header_type = 0;
>>>> + obj_context->codec_state.encode.quality_level = ENCODER_DEFAULT_QUALITY;
>>>> +
>>>> memset(obj_context->codec_state.encode.slice_rawdata_index, 0,
>>>> sizeof(int) * obj_context->codec_state.encode.slice_num);
>>>> memset(obj_context->codec_state.encode.slice_rawdata_count, 0,
>>>> diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
>>>> index 418c277..29aa10b 100644
>>>> --- a/src/i965_drv_video.h
>>>> +++ b/src/i965_drv_video.h
>>>> @@ -65,6 +65,11 @@
>>>> #define DEFAULT_HUE 0
>>>> #define DEFAULT_SATURATION 10
>>>>
>>>> +#define ENCODER_QUALITY_RANGE 2
>>>> +#define ENCODER_DEFAULT_QUALITY 1
>>>> +#define ENCODER_HIGH_QUALITY ENCODER_DEFAULT_QUALITY
>>>> +#define ENCODER_LOW_QUALITY 2
>>>> +
>>>> struct i965_surface
>>>> {
>>>> struct object_base *base;
>>>> @@ -172,6 +177,8 @@ struct encode_state
>>>>
>>>> struct buffer_store *misc_param[16];
>>>>
>>>> + unsigned int quality_level;
>>>> +
>>>> VASurfaceID current_render_target;
>>>> struct object_surface *input_yuv_object;
>>>> struct object_surface *reconstructed_object;
>>>> diff --git a/src/i965_encoder.c b/src/i965_encoder.c
>>>> index 14c37bb..bcaa61c 100644
>>>> --- a/src/i965_encoder.c
>>>> +++ b/src/i965_encoder.c
>>>> @@ -124,6 +124,7 @@ intel_encoder_check_yuv_surface(VADriverContextP ctx,
>>>>
>>>> static VAStatus
>>>> intel_encoder_check_avc_parameter(VADriverContextP ctx,
>>>> + VAProfile profile,
>>>> struct encode_state *encode_state,
>>>> struct intel_encoder_context *encoder_context)
>>> This function is used to validate sequence, picture and slice parameters
>>> from user. so it is not suitable to check misc parameter here.
>> [Zhong] This function is used to check parameters before avc encoding.
>> The input of this function is encode_state, not sps/pps/slice parameters.
> Yes, but only for the parameters for the codec. sps/pps/slice
> parameters are passed down by encode_state.
>
>
>> I don't think there is large gap to check quality level in this function.
>>>> {
>>>> @@ -151,6 +152,24 @@ intel_encoder_check_avc_parameter(VADriverContextP ctx,
>>>> if (!obj_buffer || !obj_buffer->buffer_store || !obj_buffer->buffer_store->bo)
>>>> goto error;
>>>>
>>>> + if (encode_state->misc_param[VAEncMiscParameterTypeQualityLevel] &&
>>>> + encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]->buffer) {
>>>> + VAEncMiscParameterBuffer* pMiscParam = (VAEncMiscParameterBuffer*)encode_state->misc_param[VAEncMiscParameterTypeQualityLevel]->buffer;
>>>> + VAEncMiscParameterBufferQualityLevel* param_quality_level = (VAEncMiscParameterBufferQualityLevel*)pMiscParam->data;
>>>> + encode_state->quality_level = param_quality_level->quality_level;
>>>> +
>>>> + if (encode_state->quality_level == 0)
>>>> + encode_state->quality_level = ENCODER_DEFAULT_QUALITY;
>>>> + else if (encode_state->quality_level == ENCODER_LOW_QUALITY &&
>>>> + (profile != VAProfileH264ConstrainedBaseline ||
>>>> + encoder_context->rate_control_mode != VA_RC_CQP)) {
>>>> + /* low quality level mode only support baseline profile and CQP rate control */
>>>> + goto error;
>>> This is the limitation for low quality shader on GEN7, it would be
>>> better to move the code to GEN7 related file(s).
>> I am going to add quality level configurable support on gen6 and gen75.
>> As I know, their old version vme shaders have same limitations.
>>>> + }
>>>> + else if (encode_state->quality_level > ENCODER_QUALITY_RANGE)
>>>> + goto error;
>>>> + }
>>>> +
>>>> encode_state->coded_buf_object = obj_buffer;
>>>>
>>>> for (i = 0; i < 16; i++) {
>>>> @@ -260,7 +279,7 @@ intel_encoder_sanity_check_input(VADriverContextP ctx,
>>>> case VAProfileH264High:
>>>> case VAProfileH264MultiviewHigh:
>>>> case VAProfileH264StereoHigh:
>>>> - vaStatus = intel_encoder_check_avc_parameter(ctx, encode_state, encoder_context);
>>>> + vaStatus = intel_encoder_check_avc_parameter(ctx, profile, encode_state, encoder_context);
>>>> break;
>>>>
>>>> case VAProfileMPEG2Simple:
>>>
>>>
>
>
>
More information about the Libva
mailing list