1.add p010->nv12 before VME 2.add CBR support Signed-off-by: Pengfei Qu <pengfei...@intel.com> --- src/gen6_mfc_common.c | 13 +++++ src/gen9_mfc_hevc.c | 105 ++++++++++++++---------------------- src/gen9_vme.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 198 insertions(+), 66 deletions(-)
diff --git a/src/gen6_mfc_common.c b/src/gen6_mfc_common.c index 9f041d8..faabbe7 100644 --- a/src/gen6_mfc_common.c +++ b/src/gen6_mfc_common.c @@ -2089,12 +2089,19 @@ intel_hevc_vme_reference_state(VADriverContextP ctx, struct object_surface *obj_surface = NULL; struct i965_driver_data *i965 = i965_driver_data(ctx); VASurfaceID ref_surface_id; + VAEncSequenceParameterBufferHEVC *pSequenceParameter = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer; VAEncPictureParameterBufferHEVC *pic_param = (VAEncPictureParameterBufferHEVC *)encode_state->pic_param_ext->buffer; VAEncSliceParameterBufferHEVC *slice_param = (VAEncSliceParameterBufferHEVC *)encode_state->slice_params_ext[0]->buffer; int max_num_references; VAPictureHEVC *curr_pic; VAPictureHEVC *ref_list; int ref_idx; + unsigned int is_hevc10 = 0; + GenHevcSurface *hevc_encoder_surface = NULL; + + if((pSequenceParameter->seq_fields.bits.bit_depth_luma_minus8 > 0) + || (pSequenceParameter->seq_fields.bits.bit_depth_chroma_minus8 > 0)) + is_hevc10 = 1; if (list_index == 0) { max_num_references = pic_param->num_ref_idx_l0_default_active_minus1 + 1; @@ -2141,6 +2148,12 @@ intel_hevc_vme_reference_state(VADriverContextP ctx, obj_surface->bo) { assert(ref_idx >= 0); vme_context->used_reference_objects[list_index] = obj_surface; + + if(is_hevc10){ + hevc_encoder_surface = (GenHevcSurface *) obj_surface->private_data; + assert(hevc_encoder_surface); + obj_surface = hevc_encoder_surface->nv12_surface_obj; + } vme_source_surface_state(ctx, surface_index, obj_surface, encoder_context); vme_context->ref_index_in_mb[list_index] = (ref_idx << 24 | ref_idx << 16 | diff --git a/src/gen9_mfc_hevc.c b/src/gen9_mfc_hevc.c index b3ee327..9aaf4e9 100644 --- a/src/gen9_mfc_hevc.c +++ b/src/gen9_mfc_hevc.c @@ -193,12 +193,21 @@ gen9_hcpe_surface_state(VADriverContextP ctx, struct encode_state *encode_state, struct intel_batchbuffer *batch = encoder_context->base.batch; struct object_surface *obj_surface = encode_state->reconstructed_object; struct gen9_hcpe_context *mfc_context = encoder_context->mfc_context; + VAEncSequenceParameterBufferHEVC *pSequenceParameter = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer; + unsigned int surface_format = SURFACE_FORMAT_PLANAR_420_8; /* to do */ unsigned int y_cb_offset; assert(obj_surface); + if((pSequenceParameter->seq_fields.bits.bit_depth_luma_minus8 > 0) + || (pSequenceParameter->seq_fields.bits.bit_depth_chroma_minus8 > 0)) + { + assert(obj_surface->fourcc == VA_FOURCC_P010); + surface_format = SURFACE_FORMAT_P010; + } + y_cb_offset = obj_surface->y_cb_offset; BEGIN_BCS_BATCH(batch, 3); @@ -207,7 +216,7 @@ gen9_hcpe_surface_state(VADriverContextP ctx, struct encode_state *encode_state, (1 << 28) | /* surface id */ (mfc_context->surface_state.w_pitch - 1)); /* pitch - 1 */ OUT_BCS_BATCH(batch, - (SURFACE_FORMAT_PLANAR_420_8 << 28) | + surface_format << 28 | y_cb_offset); ADVANCE_BCS_BATCH(batch); @@ -217,7 +226,7 @@ gen9_hcpe_surface_state(VADriverContextP ctx, struct encode_state *encode_state, (0 << 28) | /* surface id */ (mfc_context->surface_state.w_pitch - 1)); /* pitch - 1 */ OUT_BCS_BATCH(batch, - (SURFACE_FORMAT_PLANAR_420_8 << 28) | + surface_format << 28 | y_cb_offset); ADVANCE_BCS_BATCH(batch); } @@ -588,8 +597,8 @@ gen9_hcpe_hevc_pic_state(VADriverContextP ctx, struct encode_state *encode_state seq_param->seq_fields.bits.sample_adaptive_offset_enabled_flag << 3 | /* 0 for encoder */ 0); OUT_BCS_BATCH(batch, - 0 << 27 | /* 8 bit only for encoder */ - 0 << 24 | /* 8 bit only for encoder */ + seq_param->seq_fields.bits.bit_depth_luma_minus8 << 27 | /* 10 bit for KBL+*/ + seq_param->seq_fields.bits.bit_depth_chroma_minus8 << 24 | /* 10 bit for KBL+ */ pcm_sample_bit_depth_luma_minus1 << 20 | pcm_sample_bit_depth_chroma_minus1 << 16 | seq_param->max_transform_hierarchy_depth_inter << 13 | /* for encoder */ @@ -913,6 +922,11 @@ static void gen9_hcpe_init(VADriverContextP ctx, int height_in_mb = ALIGN(pSequenceParameter->pic_height_in_luma_samples, 16) / 16; int num_cu_record = 64; + int size_shift = 3; + + if((pSequenceParameter->seq_fields.bits.bit_depth_luma_minus8 > 0) + || (pSequenceParameter->seq_fields.bits.bit_depth_chroma_minus8 > 0)) + size_shift = 2; if (log2_ctb_size == 5) num_cu_record = 16; else if (log2_ctb_size == 4) num_cu_record = 4; @@ -991,12 +1005,12 @@ static void gen9_hcpe_init(VADriverContextP ctx, /* Current internal buffer for HCP */ - size = ALIGN(pSequenceParameter->pic_width_in_luma_samples, 32) >> 3; + size = ALIGN(pSequenceParameter->pic_width_in_luma_samples, 32) >> size_shift; size <<= 6; ALLOC_ENCODER_BUFFER((&mfc_context->deblocking_filter_line_buffer), "line buffer", size); ALLOC_ENCODER_BUFFER((&mfc_context->deblocking_filter_tile_line_buffer), "tile line buffer", size); - size = ALIGN(pSequenceParameter->pic_height_in_luma_samples + 6 * width_in_ctb, 32) >> 3; + size = ALIGN(pSequenceParameter->pic_height_in_luma_samples + 6 * width_in_ctb, 32) >> size_shift; size <<= 6; ALLOC_ENCODER_BUFFER((&mfc_context->deblocking_filter_tile_column_buffer), "tile column buffer", size); @@ -1026,15 +1040,15 @@ static void gen9_hcpe_init(VADriverContextP ctx, ALLOC_ENCODER_BUFFER((&mfc_context->metadata_tile_column_buffer), "metadata tile column buffer", size); } - size = ALIGN(((pSequenceParameter->pic_width_in_luma_samples >> 1) + 3 * width_in_ctb), 16) >> 3; + size = ALIGN(((pSequenceParameter->pic_width_in_luma_samples >> 1) + 3 * width_in_ctb), 16) >> size_shift; size <<= 6; ALLOC_ENCODER_BUFFER((&mfc_context->sao_line_buffer), "sao line buffer", size); - size = ALIGN(((pSequenceParameter->pic_width_in_luma_samples >> 1) + 6 * width_in_ctb), 16) >> 3; + size = ALIGN(((pSequenceParameter->pic_width_in_luma_samples >> 1) + 6 * width_in_ctb), 16) >> size_shift; size <<= 6; ALLOC_ENCODER_BUFFER((&mfc_context->sao_tile_line_buffer), "sao tile line buffer", size); - size = ALIGN(((pSequenceParameter->pic_height_in_luma_samples >> 1) + 6 * height_in_ctb), 16) >> 3; + size = ALIGN(((pSequenceParameter->pic_height_in_luma_samples >> 1) + 6 * height_in_ctb), 16) >> size_shift; size <<= 6; ALLOC_ENCODER_BUFFER((&mfc_context->sao_tile_column_buffer), "sao tile column buffer", size); @@ -1707,8 +1721,8 @@ gen9_hcpe_hevc_pipeline_slice_programing(VADriverContextP ctx, } /* only support for 8-bit pixel bit-depth */ - assert(pSequenceParameter->seq_fields.bits.bit_depth_luma_minus8 == 0); - assert(pSequenceParameter->seq_fields.bits.bit_depth_chroma_minus8 == 0); + assert(pSequenceParameter->seq_fields.bits.bit_depth_luma_minus8 >= 0 && pSequenceParameter->seq_fields.bits.bit_depth_luma_minus8 <= 2); + assert(pSequenceParameter->seq_fields.bits.bit_depth_chroma_minus8 >= 0 && pSequenceParameter->seq_fields.bits.bit_depth_chroma_minus8 <= 2); assert(pPicParameter->pic_init_qp >= 0 && pPicParameter->pic_init_qp < 52); assert(qp >= 0 && qp < 52); @@ -2073,7 +2087,6 @@ VAStatus intel_hcpe_hevc_prepare(VADriverContextP ctx, struct encode_state *encode_state, struct intel_encoder_context *encoder_context) { - struct i965_driver_data *i965 = i965_driver_data(ctx); struct gen9_hcpe_context *mfc_context = encoder_context->mfc_context; struct object_surface *obj_surface; struct object_buffer *obj_buffer; @@ -2081,45 +2094,20 @@ VAStatus intel_hcpe_hevc_prepare(VADriverContextP ctx, dri_bo *bo; VAStatus vaStatus = VA_STATUS_SUCCESS; int i; - struct i965_coded_buffer_segment *coded_buffer_segment; - VAEncSequenceParameterBufferHEVC *pSequenceParameter = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer; + struct i965_coded_buffer_segment *coded_buffer_segment; /*Setup all the input&output object*/ /* Setup current frame and current direct mv buffer*/ obj_surface = encode_state->reconstructed_object; - i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420); - - if (obj_surface->private_data == NULL) { - uint32_t size; - - if (mfc_context->pic_size.ctb_size == 16) - size = ((pSequenceParameter->pic_width_in_luma_samples + 63) >> 6) * - ((pSequenceParameter->pic_height_in_luma_samples + 15) >> 4); - else - size = ((pSequenceParameter->pic_width_in_luma_samples + 31) >> 5) * - ((pSequenceParameter->pic_height_in_luma_samples + 31) >> 5); - size <<= 6; /* in unit of 64bytes */ - - hevc_encoder_surface = calloc(sizeof(GenHevcSurface), 1); - assert(hevc_encoder_surface); - hevc_encoder_surface->motion_vector_temporal_bo = - dri_bo_alloc(i965->intel.bufmgr, - "motion vector temporal buffer", - size, - 0x1000); - assert(hevc_encoder_surface->motion_vector_temporal_bo); - - obj_surface->private_data = (void *)hevc_encoder_surface; - obj_surface->free_private_data = (void *)gen_free_hevc_surface; - } hevc_encoder_surface = (GenHevcSurface *) obj_surface->private_data; + assert(hevc_encoder_surface); if (hevc_encoder_surface) { + hevc_encoder_surface->has_p010_to_nv12_done=0; hevc_encoder_surface->base.frame_store_id = -1; mfc_context->current_collocated_mv_temporal_buffer[NUM_HCP_CURRENT_COLLOCATED_MV_TEMPORAL_BUFFERS - 1].bo = hevc_encoder_surface->motion_vector_temporal_bo; - dri_bo_reference(hevc_encoder_surface->motion_vector_temporal_bo); } @@ -2137,33 +2125,8 @@ VAStatus intel_hcpe_hevc_prepare(VADriverContextP ctx, dri_bo_reference(obj_surface->bo); /* Check MV temporal buffer */ - if (obj_surface->private_data == NULL) { - uint32_t size; - - if (mfc_context->pic_size.ctb_size == 16) - size = ((pSequenceParameter->pic_width_in_luma_samples + 63) >> 6) * - ((pSequenceParameter->pic_height_in_luma_samples + 15) >> 4); - else - size = ((pSequenceParameter->pic_width_in_luma_samples + 31) >> 5) * - ((pSequenceParameter->pic_height_in_luma_samples + 31) >> 5); - size <<= 6; /* in unit of 64bytes */ - - hevc_encoder_surface = calloc(sizeof(GenHevcSurface), 1); - - if (hevc_encoder_surface) { - hevc_encoder_surface->motion_vector_temporal_bo = - dri_bo_alloc(i965->intel.bufmgr, - "motion vector temporal buffer", - size, - 0x1000); - assert(hevc_encoder_surface->motion_vector_temporal_bo); - } - - obj_surface->private_data = (void *)hevc_encoder_surface; - obj_surface->free_private_data = (void *)gen_free_hevc_surface; - } - hevc_encoder_surface = (GenHevcSurface *) obj_surface->private_data; + assert(hevc_encoder_surface); if (hevc_encoder_surface) { hevc_encoder_surface->base.frame_store_id = -1; @@ -2176,6 +2139,7 @@ VAStatus intel_hcpe_hevc_prepare(VADriverContextP ctx, } } + mfc_context->uncompressed_picture_source.bo = encode_state->input_yuv_object->bo; dri_bo_reference(mfc_context->uncompressed_picture_source.bo); @@ -2265,6 +2229,14 @@ static void intel_hcpe_brc_init(struct encode_state *encode_state, int ratio_max = 32; int ratio = 8; double buffer_size = 0; + int bpp = 1; + + if((pSequenceParameter->seq_fields.bits.bit_depth_luma_minus8 > 0) || + (pSequenceParameter->seq_fields.bits.bit_depth_chroma_minus8 > 0)) + bpp = 2; + + qp1_size = qp1_size * bpp; + qp51_size = qp51_size * bpp; if (!encode_state->misc_param[VAEncMiscParameterTypeHRD] || !encode_state->misc_param[VAEncMiscParameterTypeHRD]->buffer) return; @@ -2733,6 +2705,7 @@ VAStatus gen9_hcpe_pipeline(VADriverContextP ctx, switch (profile) { case VAProfileHEVCMain: + case VAProfileHEVCMain10: vaStatus = gen9_hcpe_hevc_encode_picture(ctx, encode_state, encoder_context); break; diff --git a/src/gen9_vme.c b/src/gen9_vme.c index 1625c2b..9e66275 100644 --- a/src/gen9_vme.c +++ b/src/gen9_vme.c @@ -40,6 +40,8 @@ #include "i965_encoder.h" #include "gen6_vme.h" #include "gen6_mfc.h" +#include "gen9_mfc.h" +#include "intel_media.h" #ifdef SURFACE_STATE_PADDED_SIZE #undef SURFACE_STATE_PADDED_SIZE @@ -334,6 +336,7 @@ gen9_vme_surface_setup(VADriverContextP ctx, /*Setup surfaces state*/ /* current picture for encoding */ obj_surface = encode_state->input_yuv_object; + assert(obj_surface); gen9_vme_source_surface_state(ctx, 0, obj_surface, encoder_context); gen9_vme_media_source_surface_state(ctx, 4, obj_surface, encoder_context); gen9_vme_media_chroma_source_surface_state(ctx, 6, obj_surface, encoder_context); @@ -1418,10 +1421,19 @@ gen9_vme_hevc_surface_setup(VADriverContextP ctx, struct intel_encoder_context *encoder_context) { struct object_surface *obj_surface; + VAEncSequenceParameterBufferHEVC *pSequenceParameter = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer; + GenHevcSurface *hevc_encoder_surface = NULL; /*Setup surfaces state*/ /* current picture for encoding */ obj_surface = encode_state->input_yuv_object; + + if((pSequenceParameter->seq_fields.bits.bit_depth_luma_minus8 > 0) + || (pSequenceParameter->seq_fields.bits.bit_depth_chroma_minus8 > 0)) { + hevc_encoder_surface = (GenHevcSurface *) obj_surface->private_data; + assert(hevc_encoder_surface); + obj_surface = hevc_encoder_surface->nv12_surface_obj; + } gen9_vme_source_surface_state(ctx, 0, obj_surface, encoder_context); gen9_vme_media_source_surface_state(ctx, 4, obj_surface, encoder_context); gen9_vme_media_chroma_source_surface_state(ctx, 6, obj_surface, encoder_context); @@ -1735,6 +1747,137 @@ static void gen9_vme_hevc_pipeline_programing(VADriverContextP ctx, intel_batchbuffer_end_atomic(batch); } +static VAStatus gen9_intel_init_hevc_surface(VADriverContextP ctx, + struct intel_encoder_context *encoder_context, + struct encode_state *encode_state, + struct object_surface *input_obj_surface) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct gen9_hcpe_context *mfc_context = encoder_context->mfc_context; + VAEncSequenceParameterBufferHEVC *pSequenceParameter = (VAEncSequenceParameterBufferHEVC *)encode_state->seq_param_ext->buffer; + GenHevcSurface *hevc_encoder_surface; + struct i965_surface src_surface, dst_surface; + struct object_surface *obj_surface; + VARectangle rect; + VAStatus status; + + uint32_t size; + + obj_surface = input_obj_surface; + assert(obj_surface && obj_surface->bo); + + if (obj_surface->private_data == NULL) { + + if (mfc_context->pic_size.ctb_size == 16) + size = ((pSequenceParameter->pic_width_in_luma_samples + 63) >> 6) * + ((pSequenceParameter->pic_height_in_luma_samples + 15) >> 4); + else + size = ((pSequenceParameter->pic_width_in_luma_samples + 31) >> 5) * + ((pSequenceParameter->pic_height_in_luma_samples + 31) >> 5); + size <<= 6; /* in unit of 64bytes */ + + hevc_encoder_surface = calloc(sizeof(GenHevcSurface), 1); + + assert(hevc_encoder_surface); + hevc_encoder_surface->motion_vector_temporal_bo = + dri_bo_alloc(i965->intel.bufmgr, + "motion vector temporal buffer", + size, + 0x1000); + assert(hevc_encoder_surface->motion_vector_temporal_bo); + + hevc_encoder_surface->ctx = ctx; + hevc_encoder_surface->nv12_surface_obj = NULL; + hevc_encoder_surface->nv12_surface_id = VA_INVALID_SURFACE; + hevc_encoder_surface->has_p010_to_nv12_done = 0; + + obj_surface->private_data = (void *)hevc_encoder_surface; + obj_surface->free_private_data = (void *)gen_free_hevc_surface; + } + + hevc_encoder_surface = (GenHevcSurface *) obj_surface->private_data; + + if(!hevc_encoder_surface->has_p010_to_nv12_done && obj_surface->fourcc == VA_FOURCC_P010) + { + // convert input + rect.x = 0; + rect.y = 0; + rect.width = obj_surface->orig_width; + rect.height = obj_surface->orig_height; + + src_surface.base = (struct object_base *)obj_surface; + src_surface.type = I965_SURFACE_TYPE_SURFACE; + src_surface.flags = I965_SURFACE_FLAG_FRAME; + + if(SURFACE(hevc_encoder_surface->nv12_surface_id) == NULL) + { + status = i965_CreateSurfaces(ctx, + obj_surface->orig_width, + obj_surface->orig_height, + VA_RT_FORMAT_YUV420, + 1, + &hevc_encoder_surface->nv12_surface_id); + assert(status == VA_STATUS_SUCCESS); + + if (status != VA_STATUS_SUCCESS) + return status; + } + + obj_surface = SURFACE(hevc_encoder_surface->nv12_surface_id); + hevc_encoder_surface->nv12_surface_obj = obj_surface; + assert(obj_surface); + i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420); + + dst_surface.base = (struct object_base *)obj_surface; + dst_surface.type = I965_SURFACE_TYPE_SURFACE; + dst_surface.flags = I965_SURFACE_FLAG_FRAME; + + status = i965_image_processing(ctx, + &src_surface, + &rect, + &dst_surface, + &rect); + assert(status == VA_STATUS_SUCCESS); + hevc_encoder_surface->has_p010_to_nv12_done = 1; + } + return VA_STATUS_SUCCESS; +} + +static VAStatus gen9_intel_hevc_input_check(VADriverContextP ctx, + struct encode_state *encode_state, + struct intel_encoder_context *encoder_context) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct gen9_hcpe_context *mfc_context = encoder_context->mfc_context; + struct object_surface *obj_surface; + int i; + + obj_surface = SURFACE(encode_state->current_render_target); + assert(obj_surface && obj_surface->bo); + + gen9_intel_init_hevc_surface(ctx,encoder_context,encode_state,obj_surface); + + /* Setup current frame and current direct mv buffer*/ + obj_surface = encode_state->reconstructed_object; + gen9_intel_init_hevc_surface(ctx,encoder_context,encode_state,obj_surface); + + /* Setup reference frames and direct mv buffers*/ + for (i = 0; i < MAX_HCP_REFERENCE_SURFACES; i++) { + obj_surface = encode_state->reference_objects[i]; + + if (obj_surface && obj_surface->bo) { + mfc_context->reference_surfaces[i].bo = obj_surface->bo; + dri_bo_reference(obj_surface->bo); + + gen9_intel_init_hevc_surface(ctx,encoder_context,encode_state,obj_surface); + } else { + break; + } + } + + return VA_STATUS_SUCCESS; +} + static VAStatus gen9_vme_hevc_prepare(VADriverContextP ctx, struct encode_state *encode_state, struct intel_encoder_context *encoder_context) @@ -1751,6 +1894,9 @@ static VAStatus gen9_vme_hevc_prepare(VADriverContextP ctx, vme_context->hevc_level = pSequenceParameter->general_level_idc; } + //internal input check for main10 + gen9_intel_hevc_input_check(ctx,encode_state,encoder_context); + intel_vme_hevc_update_mbmv_cost(ctx, encode_state, encoder_context); /*Setup all the memory object*/ -- 2.7.4 _______________________________________________ Libva mailing list Libva@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libva