diff options
author | Pengfei Qu <Pengfei.Qu@intel.com> | 2015-10-22 04:51:38 -0400 |
---|---|---|
committer | Xiang, Haihao <haihao.xiang@intel.com> | 2015-12-07 13:31:29 +0800 |
commit | 823d9bbe2baf915b7d8ee0fc86fb774126a9148c (patch) | |
tree | fed291e858f9991ae43c6263574c6762dd0267b3 | |
parent | 1fcb5d1851f59ec492b97069339d6df083fbdcc8 (diff) |
VP9 HWDec: add VP9 HW decoding pipeline
v2: fix sengment feature in inter frame
v3: update the prob buffer logic
v4: fix intra-only feature issue
Signed-off-by: Pengfei Qu <Pengfei.Qu@intel.com>
Signed-off-by: Sirisha Muppavarapu <sirisha.muppavarapu@intel.com>
Signed-off-by: peng.chen <peng.c.chen@intel.com>
Reviewed-by: Zhao Yakui <yakui.zhao@intel.com>
(cherry picked from commit 8f1e1015a4cc8c08dd685f80829ca1555ae1cab1)
-rw-r--r-- | src/gen9_mfd.c | 944 | ||||
-rw-r--r-- | src/gen9_mfd.h | 26 |
2 files changed, 968 insertions, 2 deletions
diff --git a/src/gen9_mfd.c b/src/gen9_mfd.c index dab4213..d9ca3be 100644 --- a/src/gen9_mfd.c +++ b/src/gen9_mfd.c @@ -39,6 +39,7 @@ #include "gen9_mfd.h" #include "intel_media.h" +#include "vp9_probs.h" #define OUT_BUFFER(buf_bo, is_target, ma) do { \ if (buf_bo) { \ @@ -190,7 +191,7 @@ gen9_hcpd_pipe_mode_select(VADriverContextP ctx, { struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch; - assert(codec == HCP_CODEC_HEVC); + assert((codec == HCP_CODEC_HEVC) || (codec == HCP_CODEC_VP9)); BEGIN_BCS_BATCH(batch, 4); @@ -955,6 +956,915 @@ out: return vaStatus; } +/*********************************************************/ +/* VP9 Code */ +/*********************************************************/ + + +#define VP9_PROB_BUFFER_FIRST_PART_SIZE 2010 +#define VP9_PROB_BUFFER_SECOND_PART_SIZE 10 +#define VP9_PROB_BUFFER_KEY_INTER_OFFSET 1667 +#define VP9_PROB_BUFFER_KEY_INTER_SIZE 343 + +#define VP9_PROB_BUFFER_UPDATE_NO 0 +#define VP9_PROB_BUFFER_UPDATE_SECNE_1 1 +#define VP9_PROB_BUFFER_UPDATE_SECNE_2 2 +#define VP9_PROB_BUFFER_UPDATE_SECNE_3 3 +#define VP9_PROB_BUFFER_UPDATE_SECNE_4 4 +#define VP9_PROB_BUFFER_UPDATE_SECNE_5 5 + +#define VP9_PROB_BUFFER_SAVED_NO 0 +#define VP9_PROB_BUFFER_SAVED_SECNE_1 1 +#define VP9_PROB_BUFFER_SAVED_SECNE_2 2 + +#define VP9_PROB_BUFFER_RESTORED_NO 0 +#define VP9_PROB_BUFFER_RESTORED_SECNE_1 1 +#define VP9_PROB_BUFFER_RESTORED_SECNE_2 2 +#define VP9_PROB_BUFFER_RESTORED_SECNE_MAX (VP9_PROB_BUFFER_RESTORED_SECNE_2 + 1) + +static void vp9_update_segmentId_buffer(VADriverContextP ctx, + struct decode_state *decode_state, + struct gen9_hcpd_context *gen9_hcpd_context, uint8_t isScaling) +{ + VADecPictureParameterBufferVP9 *pic_param; + + assert(decode_state->pic_param && decode_state->pic_param->buffer); + pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer; + + int size = 0; + + if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) || + pic_param->pic_fields.bits.error_resilient_mode || + pic_param->pic_fields.bits.intra_only || isScaling) { + + size = (gen9_hcpd_context->picture_width_in_min_cb_minus1+2)*(gen9_hcpd_context->picture_height_in_min_cb_minus1 + 2) * 1; + size<<=6; + //VP9 Segment ID buffer needs to be zero + dri_bo_map(gen9_hcpd_context->vp9_segment_id_buffer.bo,1); + memset((unsigned char *)gen9_hcpd_context->vp9_segment_id_buffer.bo->virtual,0, size); + dri_bo_unmap(gen9_hcpd_context->vp9_segment_id_buffer.bo); + } +} + +static void +vp9_gen_default_probabilities(VADriverContextP ctx, struct gen9_hcpd_context *gen9_hcpd_context) +{ + int i = 0; + uint32_t size = 0; + + size = sizeof(FRAME_CONTEXT); + memset(&gen9_hcpd_context->vp9_fc_key_default,0,size); + memset(&gen9_hcpd_context->vp9_fc_inter_default,0,size); + memset(&gen9_hcpd_context->vp9_frame_ctx,0,size*FRAME_CONTEXTS); + //more code to come here below + + //1. key default + gen9_hcpd_context->vp9_fc_key_default.tx_probs = default_tx_probs; + //dummy 52 + vp9_copy(gen9_hcpd_context->vp9_fc_key_default.coeff_probs4x4, default_coef_probs_4x4); + vp9_copy(gen9_hcpd_context->vp9_fc_key_default.coeff_probs8x8, default_coef_probs_8x8); + vp9_copy(gen9_hcpd_context->vp9_fc_key_default.coeff_probs16x16, default_coef_probs_16x16); + vp9_copy(gen9_hcpd_context->vp9_fc_key_default.coeff_probs32x32, default_coef_probs_32x32); + //dummy 16 + vp9_copy(gen9_hcpd_context->vp9_fc_key_default.skip_probs, default_skip_probs); + vp9_copy(gen9_hcpd_context->vp9_fc_key_default.partition_prob, vp9_kf_partition_probs); + //dummy 47 + vp9_copy(gen9_hcpd_context->vp9_fc_key_default.uv_mode_prob, vp9_kf_uv_mode_prob); + vp9_copy(gen9_hcpd_context->vp9_fc_key_default.seg_tree_probs, default_seg_tree_probs); + vp9_copy(gen9_hcpd_context->vp9_fc_key_default.seg_pred_probs, default_seg_pred_probs); + + //2. inter default + gen9_hcpd_context->vp9_fc_inter_default.tx_probs = default_tx_probs; + //dummy 52 + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.coeff_probs4x4, default_coef_probs_4x4); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.coeff_probs8x8, default_coef_probs_8x8); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.coeff_probs16x16, default_coef_probs_16x16); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.coeff_probs32x32, default_coef_probs_32x32); + //dummy 16 + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.skip_probs, default_skip_probs); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.inter_mode_probs, default_inter_mode_probs); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.switchable_interp_prob, default_switchable_interp_prob); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.intra_inter_prob, default_intra_inter_p); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.comp_inter_prob, default_comp_inter_p); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.single_ref_prob, default_single_ref_p); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.comp_ref_prob, default_comp_ref_p); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.y_mode_prob, default_if_y_probs); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.partition_prob, default_partition_probs); + gen9_hcpd_context->vp9_fc_inter_default.nmvc = default_nmv_context; + //dummy 47 + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.uv_mode_prob, default_if_uv_probs); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.seg_tree_probs, default_seg_tree_probs); + vp9_copy(gen9_hcpd_context->vp9_fc_inter_default.seg_pred_probs, default_seg_pred_probs); + + for(i = 0; i < FRAME_CONTEXTS; i++) + { + gen9_hcpd_context->vp9_frame_ctx[i] = gen9_hcpd_context->vp9_fc_inter_default; + } + gen9_hcpd_context->vp9_fc = gen9_hcpd_context->vp9_fc_inter_default; + +} + +static void +vp9_update_probabilities(VADriverContextP ctx, + struct decode_state *decode_state, + struct gen9_hcpd_context *gen9_hcpd_context) +{ + VADecPictureParameterBufferVP9 *pic_param; + int i = 0; + uint8_t is_saved = VP9_PROB_BUFFER_SAVED_NO; + uint8_t is_restored = VP9_PROB_BUFFER_RESTORED_NO; + + uint8_t last_frame_type = gen9_hcpd_context->last_frame.frame_type; + uint8_t temp_frame_ctx_id; + + assert(decode_state->pic_param && decode_state->pic_param->buffer); + pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer; + temp_frame_ctx_id = pic_param->pic_fields.bits.frame_context_idx; + + if(pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) + { + gen9_hcpd_context->vp9_fc = gen9_hcpd_context->vp9_fc_key_default; + gen9_hcpd_context->last_frame.prob_buffer_saved_flag = VP9_PROB_BUFFER_SAVED_NO; + gen9_hcpd_context->last_frame.prob_buffer_restored_flag = VP9_PROB_BUFFER_RESTORED_NO; + + }else + { + gen9_hcpd_context->vp9_fc = gen9_hcpd_context->vp9_fc_inter_default; + } + + // restore? + if(gen9_hcpd_context->last_frame.prob_buffer_saved_flag == VP9_PROB_BUFFER_SAVED_SECNE_1) + { + if((pic_param->pic_fields.bits.frame_type == HCP_VP9_INTER_FRAME)) + { + //save the inter frame values for the 343 bytes + //Update the 343 bytes of the buffer with Intra values + is_restored = VP9_PROB_BUFFER_RESTORED_SECNE_1; + } + }else if(gen9_hcpd_context->last_frame.prob_buffer_saved_flag == VP9_PROB_BUFFER_SAVED_SECNE_2) + { + if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) ||pic_param->pic_fields.bits.intra_only|pic_param->pic_fields.bits.error_resilient_mode) + { + temp_frame_ctx_id = 0; + } + + if((pic_param->pic_fields.bits.frame_type == HCP_VP9_INTER_FRAME) && + (temp_frame_ctx_id == 0)) + { + + is_restored = VP9_PROB_BUFFER_RESTORED_SECNE_2; + } + } + + if(is_restored > VP9_PROB_BUFFER_RESTORED_NO && is_restored < VP9_PROB_BUFFER_RESTORED_SECNE_MAX) + { + memcpy(gen9_hcpd_context->vp9_frame_ctx[gen9_hcpd_context->last_frame.frame_context_idx].inter_mode_probs,gen9_hcpd_context->vp9_saved_fc.inter_mode_probs,VP9_PROB_BUFFER_KEY_INTER_SIZE); + } + + if((gen9_hcpd_context->last_frame.prob_buffer_restored_flag == VP9_PROB_BUFFER_RESTORED_SECNE_MAX) || + (gen9_hcpd_context->last_frame.refresh_frame_context && last_frame_type == HCP_VP9_KEY_FRAME && (pic_param->pic_fields.bits.frame_type == HCP_VP9_INTER_FRAME))) + { + if(pic_param->pic_fields.bits.frame_type == HCP_VP9_INTER_FRAME) + { + memcpy(gen9_hcpd_context->vp9_frame_ctx[gen9_hcpd_context->last_frame.frame_context_idx].inter_mode_probs,gen9_hcpd_context->vp9_fc_inter_default.inter_mode_probs,VP9_PROB_BUFFER_KEY_INTER_SIZE); + } + } + //first part buffer update: Case 1)Reset all 4 probablity buffers + if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) ||pic_param->pic_fields.bits.intra_only|pic_param->pic_fields.bits.error_resilient_mode) + { + if((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) || + (pic_param->pic_fields.bits.reset_frame_context == 3)|| + pic_param->pic_fields.bits.error_resilient_mode) + { + //perform full buffer update + for(i = 0; i < FRAME_CONTEXTS; i++) + { + memcpy(&gen9_hcpd_context->vp9_frame_ctx[i],&gen9_hcpd_context->vp9_fc_inter_default,VP9_PROB_BUFFER_FIRST_PART_SIZE); + } + }else if(pic_param->pic_fields.bits.reset_frame_context == 2&&pic_param->pic_fields.bits.intra_only) + { + memcpy(&gen9_hcpd_context->vp9_frame_ctx[pic_param->pic_fields.bits.frame_context_idx],&gen9_hcpd_context->vp9_fc_inter_default,VP9_PROB_BUFFER_FIRST_PART_SIZE); + } + pic_param->pic_fields.bits.frame_context_idx = 0; + } + + //Full buffer update: Case 2.2)Reset only segmentation prob buffer + if(pic_param->pic_fields.bits.segmentation_enabled && + pic_param->pic_fields.bits.segmentation_update_map) + { + for(i = 0; i < FRAME_CONTEXTS; i++) + { + //Reset only the segementation probability buffers + vp9_copy(gen9_hcpd_context->vp9_frame_ctx[i].seg_tree_probs, default_seg_tree_probs); + vp9_copy(gen9_hcpd_context->vp9_frame_ctx[i].seg_pred_probs, default_seg_pred_probs); + } + } + + //update vp9_fc according to frame_context_id + { + gen9_hcpd_context->vp9_fc = gen9_hcpd_context->vp9_frame_ctx[pic_param->pic_fields.bits.frame_context_idx]; + } + //Partial Buffer Update + //Case 1) Update top 3 probabilities only + if(pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) + { + memcpy(gen9_hcpd_context->vp9_fc.inter_mode_probs,gen9_hcpd_context->vp9_fc_key_default.inter_mode_probs,VP9_PROB_BUFFER_KEY_INTER_SIZE); + if((!pic_param->pic_fields.bits.segmentation_enabled || + !pic_param->pic_fields.bits.segmentation_update_map)) { + //Update with key frame default probability values for only + //tx_probs, coef_probs, and the next 343 bytes + memcpy(&gen9_hcpd_context->vp9_fc,&gen9_hcpd_context->vp9_fc_key_default,VP9_PROB_BUFFER_FIRST_PART_SIZE); + } + } + //Case 2) Update 343 bytes for first inter following key frame + if( last_frame_type == HCP_VP9_KEY_FRAME && + (pic_param->pic_fields.bits.frame_type == HCP_VP9_INTER_FRAME)) { + //Update with inter frame default values for the 343 bytes + memcpy(gen9_hcpd_context->vp9_fc.inter_mode_probs,gen9_hcpd_context->vp9_fc_inter_default.inter_mode_probs,VP9_PROB_BUFFER_KEY_INTER_SIZE); + } + //Case 2.1) Update 343 bytes for first intra-inly frame following key frame + if( last_frame_type == HCP_VP9_KEY_FRAME && + pic_param->pic_fields.bits.intra_only) { + //Update with inter frame default values for the 343 bytes + memcpy(gen9_hcpd_context->vp9_fc.inter_mode_probs,gen9_hcpd_context->vp9_fc_key_default.inter_mode_probs,VP9_PROB_BUFFER_KEY_INTER_SIZE); + } + //Case 3) Update only segment probabilities + if((pic_param->pic_fields.bits.segmentation_enabled && + pic_param->pic_fields.bits.segmentation_update_map)) + { + //Update seg_tree_probs and seg_pred_probs accordingly + for (i=0; i<SEG_TREE_PROBS; i++) + { + gen9_hcpd_context->vp9_fc.seg_tree_probs[i] = pic_param->mb_segment_tree_probs[i]; + } + for (i=0; i<PREDICTION_PROBS; i++) + { + gen9_hcpd_context->vp9_fc.seg_pred_probs[i] = pic_param->segment_pred_probs[i]; + } + } + + //Case 4) Considering Intra only frame in the middle of Inter frames + if((pic_param->pic_fields.bits.intra_only && + (pic_param->pic_fields.bits.frame_type == HCP_VP9_INTER_FRAME)&& + (pic_param->pic_fields.bits.reset_frame_context==0 || + pic_param->pic_fields.bits.reset_frame_context==1|| + pic_param->pic_fields.bits.reset_frame_context==2|| + pic_param->pic_fields.bits.reset_frame_context==3)) && + (last_frame_type == HCP_VP9_INTER_FRAME)) + { + //save the inter frame values for the 343 bytes + //Update the 343 bytes of the buffer with Intra values + is_saved = VP9_PROB_BUFFER_SAVED_SECNE_1; + } + //Case 5) Considering Intra only frame among 3 Inter frames + if((pic_param->pic_fields.bits.intra_only && + (pic_param->pic_fields.bits.frame_type == HCP_VP9_INTER_FRAME)&& + (pic_param->pic_fields.bits.reset_frame_context==2 || + pic_param->pic_fields.bits.frame_context_idx==1)) && + ((last_frame_type == HCP_VP9_INTER_FRAME) && + (gen9_hcpd_context->last_frame.frame_context_idx==0))) + { + //save the inter frame values for the 343 bytes + //Update the 343 bytes of the buffer with Intra values + is_saved = VP9_PROB_BUFFER_SAVED_SECNE_2; + } + + if(is_saved > VP9_PROB_BUFFER_SAVED_NO) + { + gen9_hcpd_context->vp9_saved_fc = gen9_hcpd_context->vp9_fc; + memcpy(gen9_hcpd_context->vp9_fc.inter_mode_probs,gen9_hcpd_context->vp9_fc_key_default.inter_mode_probs,VP9_PROB_BUFFER_KEY_INTER_SIZE); + }else if(pic_param->pic_fields.bits.intra_only) + { + is_restored = VP9_PROB_BUFFER_RESTORED_SECNE_MAX; + + } + + // update after the restored + if(gen9_hcpd_context->last_frame.prob_buffer_restored_flag == VP9_PROB_BUFFER_RESTORED_SECNE_2) + { + if((pic_param->pic_fields.bits.frame_type == HCP_VP9_INTER_FRAME) && + pic_param->pic_fields.bits.frame_context_idx==1) + { + memcpy(&gen9_hcpd_context->vp9_fc,&gen9_hcpd_context->vp9_fc_inter_default,VP9_PROB_BUFFER_FIRST_PART_SIZE); + } + } + + { + dri_bo_map(gen9_hcpd_context->vp9_probability_buffer.bo,1); + memcpy((unsigned char *)gen9_hcpd_context->vp9_probability_buffer.bo->virtual,&gen9_hcpd_context->vp9_fc,2048); + dri_bo_unmap(gen9_hcpd_context->vp9_probability_buffer.bo); + } + // save the flag in order to restore or update prob buffer + gen9_hcpd_context->last_frame.prob_buffer_saved_flag = is_saved; + gen9_hcpd_context->last_frame.prob_buffer_restored_flag = is_restored; +} + +static void +gen9_hcpd_init_vp9_surface(VADriverContextP ctx, + VADecPictureParameterBufferVP9 *pic_param, + struct object_surface *obj_surface, + struct gen9_hcpd_context *gen9_hcpd_context) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + GenVP9Surface *gen9_vp9_surface; + uint32_t size=0; + + if (!obj_surface) + return; + + obj_surface->free_private_data = gen_free_vp9_surface; + gen9_vp9_surface = obj_surface->private_data; + + if (!gen9_vp9_surface) { + gen9_vp9_surface = calloc(sizeof(GenVP9Surface), 1); + gen9_vp9_surface->base.frame_store_id = -1; + obj_surface->private_data = gen9_vp9_surface; + } + + //Super block size in VP9 is 64x64, size in SBs + size = gen9_hcpd_context->picture_width_in_ctbs * gen9_hcpd_context->picture_height_in_ctbs * 9 ; + size<<=6; //CL aligned + + if (gen9_vp9_surface->motion_vector_temporal_bo == NULL) { + gen9_vp9_surface->motion_vector_temporal_bo = dri_bo_alloc(i965->intel.bufmgr, + "current motion vector temporal buffer", + size, + 0x1000); + } + gen9_vp9_surface->frame_width = pic_param->frame_width; + gen9_vp9_surface->frame_height = pic_param->frame_height; + +} + +static VAStatus +gen9_hcpd_vp9_decode_init(VADriverContextP ctx, + struct decode_state *decode_state, + struct gen9_hcpd_context *gen9_hcpd_context) +{ + struct i965_driver_data *i965 = i965_driver_data(ctx); + VADecPictureParameterBufferVP9 *pic_param; + struct object_surface *obj_surface; + uint32_t size; + int width_in_mbs=0, height_in_mbs=0; + + assert(decode_state->pic_param && decode_state->pic_param->buffer); + pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer; + + width_in_mbs = (pic_param->frame_width + 15) / 16; + height_in_mbs = (pic_param->frame_height + 15) / 16; + + //For BXT, we support only till 4K + assert(width_in_mbs > 0 && width_in_mbs <= 256); /* 4K */ + assert(height_in_mbs > 0 && height_in_mbs <= 256); + + //Update the frame store buffers with the reference frames information + intel_update_vp9_frame_store_index(ctx, + decode_state, + pic_param, + gen9_hcpd_context->reference_surfaces); + + /* Current decoded picture */ + obj_surface = decode_state->render_object; + //Ensure there is a tiled render surface in NV12 format. If not, create one. + vp9_ensure_surface_bo(ctx, decode_state, obj_surface, pic_param); + + + //Super block in VP9 is 64x64 + gen9_hcpd_context->ctb_size = 64; + gen9_hcpd_context->min_cb_size = 8; //Min block size is 4 or 8? + + //If picture width/height is not multiple of 64, needs to upsize it to the next 64 pixels + //before calculation below. + gen9_hcpd_context->picture_width_in_ctbs = ALIGN(pic_param->frame_width, gen9_hcpd_context->ctb_size) / gen9_hcpd_context->ctb_size; + gen9_hcpd_context->picture_height_in_ctbs = ALIGN(pic_param->frame_height, gen9_hcpd_context->ctb_size) / gen9_hcpd_context->ctb_size; + + gen9_hcpd_context->picture_width_in_min_cb_minus1 = ALIGN(pic_param->frame_width, gen9_hcpd_context->min_cb_size) / gen9_hcpd_context->min_cb_size - 1; + gen9_hcpd_context->picture_height_in_min_cb_minus1 = ALIGN(pic_param->frame_height, gen9_hcpd_context->min_cb_size) / gen9_hcpd_context->min_cb_size - 1; + + gen9_hcpd_context->picture_width_in_pixels = (gen9_hcpd_context->picture_width_in_min_cb_minus1 + 1) * gen9_hcpd_context->min_cb_size ; + gen9_hcpd_context->picture_height_in_pixels = (gen9_hcpd_context->picture_height_in_min_cb_minus1 + 1) * gen9_hcpd_context->min_cb_size ; + + gen9_hcpd_init_vp9_surface(ctx, pic_param, obj_surface, gen9_hcpd_context); + + size = gen9_hcpd_context->picture_width_in_ctbs*18; //num_width_in_SB * 18 + size<<=6; + ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_line_buffer), "line buffer", size); + ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_line_buffer), "tile line buffer", size); + + size = gen9_hcpd_context->picture_height_in_ctbs*17; //num_height_in_SB * 17 + size<<=6; + ALLOC_GEN_BUFFER((&gen9_hcpd_context->deblocking_filter_tile_column_buffer), "tile column buffer", size); + + size = gen9_hcpd_context->picture_width_in_ctbs*5; //num_width_in_SB * 5 + size<<=6; + ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_line_buffer), "metadata line buffer", size); + ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_line_buffer), "metadata tile line buffer", size); + + size = gen9_hcpd_context->picture_height_in_ctbs*5; //num_height_in_SB * 5 + size<<=6; + ALLOC_GEN_BUFFER((&gen9_hcpd_context->metadata_tile_column_buffer), "metadata tile column buffer", size); + + size =gen9_hcpd_context->picture_width_in_ctbs*1; //num_width_in_SB * 1 + size<<=6; + ALLOC_GEN_BUFFER((&gen9_hcpd_context->hvd_line_rowstore_buffer), "hvd line rowstore buffer", size); + ALLOC_GEN_BUFFER((&gen9_hcpd_context->hvd_tile_rowstore_buffer), "hvd tile rowstore buffer", size); + + size = 32; + size<<=6; + ALLOC_GEN_BUFFER((&gen9_hcpd_context->vp9_probability_buffer), "vp9 probability buffer", size); + + size = (gen9_hcpd_context->picture_width_in_min_cb_minus1+2)*(gen9_hcpd_context->picture_height_in_min_cb_minus1 + 2) * 1; + size<<=6; + ALLOC_GEN_BUFFER((&gen9_hcpd_context->vp9_segment_id_buffer), "vp9 segment id buffer", size); + + gen9_hcpd_context->first_inter_slice_collocated_ref_idx = 0; + gen9_hcpd_context->first_inter_slice_collocated_from_l0_flag = 0; + gen9_hcpd_context->first_inter_slice_valid = 0; + + return VA_STATUS_SUCCESS; +} + +static void +gen9_hcpd_vp9_surface_state(VADriverContextP ctx, + struct decode_state *decode_state, + struct gen9_hcpd_context *gen9_hcpd_context) +{ + struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch; + struct object_surface *obj_surface = decode_state->render_object; + struct object_surface *tmp_obj_surface = NULL; + unsigned int y_cb_offset; + int i = 0; + + assert(obj_surface); + + y_cb_offset = obj_surface->y_cb_offset; + + BEGIN_BCS_BATCH(batch, 3); + + OUT_BCS_BATCH(batch, HCP_SURFACE_STATE | (3 - 2)); + OUT_BCS_BATCH(batch, + (0 << 28) | /* surface id */ + (obj_surface->width - 1)); /* pitch - 1 */ + OUT_BCS_BATCH(batch, + (SURFACE_FORMAT_PLANAR_420_8 << 28) | + y_cb_offset); + ADVANCE_BCS_BATCH(batch); + + tmp_obj_surface = obj_surface; + + for(i = 0; i < 3; i++) + { + obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface; + if (obj_surface && obj_surface->private_data) + { + BEGIN_BCS_BATCH(batch, 3); + + OUT_BCS_BATCH(batch, HCP_SURFACE_STATE | (3 - 2)); + OUT_BCS_BATCH(batch, + ((i + 2) << 28) | /* surface id */ + (obj_surface->width - 1)); /* pitch - 1 */ + OUT_BCS_BATCH(batch, + (SURFACE_FORMAT_PLANAR_420_8 << 28) | + obj_surface->y_cb_offset); + ADVANCE_BCS_BATCH(batch); + }else + { + BEGIN_BCS_BATCH(batch, 3); + + OUT_BCS_BATCH(batch, HCP_SURFACE_STATE | (3 - 2)); + OUT_BCS_BATCH(batch, + ((i + 2) << 28) | /* surface id */ + (tmp_obj_surface->width - 1)); /* pitch - 1 */ + OUT_BCS_BATCH(batch, + (SURFACE_FORMAT_PLANAR_420_8 << 28) | + tmp_obj_surface->y_cb_offset); + ADVANCE_BCS_BATCH(batch); + } + } +} + +static void +gen9_hcpd_vp9_pipe_buf_addr_state(VADriverContextP ctx, + struct decode_state *decode_state, + struct gen9_hcpd_context *gen9_hcpd_context) +{ + struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch; + struct object_surface *obj_surface; + GenVP9Surface *gen9_vp9_surface; + int i=0; + + BEGIN_BCS_BATCH(batch, 95); + + OUT_BCS_BATCH(batch, HCP_PIPE_BUF_ADDR_STATE | (95 - 2)); + + obj_surface = decode_state->render_object; + assert(obj_surface && obj_surface->bo); + gen9_vp9_surface = obj_surface->private_data; + assert(gen9_vp9_surface && gen9_vp9_surface->motion_vector_temporal_bo); + + OUT_BUFFER_MA_TARGET(obj_surface->bo); /* DW 1..3 */ + OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_line_buffer.bo);/* DW 4..6 */ + OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_tile_line_buffer.bo); /* DW 7..9 */ + OUT_BUFFER_MA_TARGET(gen9_hcpd_context->deblocking_filter_tile_column_buffer.bo); /* DW 10..12 */ + OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_line_buffer.bo); /* DW 13..15 */ + OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_tile_line_buffer.bo); /* DW 16..18 */ + OUT_BUFFER_MA_TARGET(gen9_hcpd_context->metadata_tile_column_buffer.bo); /* DW 19..21 */ + OUT_BUFFER_MA_TARGET(NULL); /* DW 22..24, ignore for VP9 */ + OUT_BUFFER_MA_TARGET(NULL); /* DW 25..27, ignore for VP9 */ + OUT_BUFFER_MA_TARGET(NULL); /* DW 28..30, ignore for VP9 */ + OUT_BUFFER_MA_TARGET(gen9_vp9_surface->motion_vector_temporal_bo); /* DW 31..33 */ + + OUT_BUFFER_MA_TARGET(NULL); /* DW 34..36, reserved */ + + /* DW 37..52 - Reference picture address */ + for (i = 0; i < 3; i++) + { + obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface; + + if (obj_surface) + { + OUT_BUFFER_NMA_REFERENCE(obj_surface->bo); + } + else + OUT_BUFFER_NMA_REFERENCE(NULL); + } + for (; i < ARRAY_ELEMS(gen9_hcpd_context->reference_surfaces); i++) + { + OUT_BUFFER_NMA_REFERENCE(NULL); + } + OUT_BCS_BATCH(batch, 0); /* DW 53, memory address attributes */ + + OUT_BUFFER_MA_REFERENCE(NULL); /* DW 54..56, ignore for decoding mode */ + OUT_BUFFER_MA_TARGET(NULL); /* DW 57..59, StreamOutEnable - used for transcoding */ + OUT_BUFFER_MA_TARGET(NULL); /* DW 60..62, DecodedPictureStatusError, ignored */ + OUT_BUFFER_MA_TARGET(NULL); /* DW 63..65, Ignored */ + + /* DW 66..81 - for 8 Collocated motion vectors */ + for (i = 0; i < 1; i++) + { + OUT_BUFFER_NMA_REFERENCE(gen9_hcpd_context->last_frame.mv_temporal_buffer_bo); + } + for (; i < ARRAY_ELEMS(gen9_hcpd_context->reference_surfaces); i++) + { + OUT_BUFFER_NMA_REFERENCE(NULL); + } + + OUT_BCS_BATCH(batch, 0); /* DW 82, memory address attributes */ + + OUT_BUFFER_MA_TARGET(gen9_hcpd_context->vp9_probability_buffer.bo); /* DW 83..85, VP9 Probability bufffer */ + OUT_BUFFER_MA_TARGET(gen9_hcpd_context->vp9_segment_id_buffer.bo); /* DW 86..88, VP9 Segment ID buffer */ + OUT_BUFFER_MA_TARGET(gen9_hcpd_context->hvd_line_rowstore_buffer.bo);/* DW 89..91, VP9 HVD Line Rowstore buffer */ + OUT_BUFFER_MA_TARGET(gen9_hcpd_context->hvd_tile_rowstore_buffer.bo);/* DW 92..94, VP9 HVD Tile Rowstore buffer */ + + ADVANCE_BCS_BATCH(batch); + gen9_hcpd_context->last_frame.mv_temporal_buffer_bo = gen9_vp9_surface->motion_vector_temporal_bo; +} + +static inline int +gen9_hcpd_vp9_valid_ref_frame_size(int ref_width, int ref_height, + int cur_width, int cur_height) { + return 2 * cur_width >= ref_width && + 2 * cur_height >= ref_height && + cur_width <= 16 * ref_width && + cur_height <= 16 * ref_height; +} +static void +gen9_hcpd_vp9_pic_state(VADriverContextP ctx, + struct decode_state *decode_state, + struct gen9_hcpd_context *gen9_hcpd_context) +{ + struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch; + VADecPictureParameterBufferVP9 *pic_param; + struct object_surface *obj_surface; + GenVP9Surface *gen9_vp9_surface; + uint16_t scale_h = 0; + uint16_t scale_w = 0; + uint16_t frame_width_in_pixel = 0; + uint16_t frame_height_in_pixel = 0; + uint16_t fwidth = 64; + uint16_t fheight = 64; + int i; +#define LEN_COMMAND_OWN 12 + assert(decode_state->pic_param && decode_state->pic_param->buffer); + pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer; + + uint8_t segmentIDStreamInEnable = 0; + uint8_t segmentIDStreamOutEnable = (pic_param->pic_fields.bits.segmentation_enabled && pic_param->pic_fields.bits.segmentation_update_map); + + // For KEY_FRAME or INTRA_ONLY frame, this bit should be set to "0". + uint8_t segmentation_temporal_update = + ((pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME) || (pic_param->pic_fields.bits.intra_only)) ? 0 : pic_param->pic_fields.bits.segmentation_temporal_update; + + + if(pic_param->pic_fields.bits.intra_only || (pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME)) + { + segmentIDStreamInEnable = 1; + }else if(pic_param->pic_fields.bits.segmentation_enabled) + { + if(!pic_param->pic_fields.bits.segmentation_update_map) + { + segmentIDStreamInEnable = 1; + + }else if( pic_param->pic_fields.bits.segmentation_temporal_update) + { + segmentIDStreamInEnable = 1; + } + } + + if(pic_param->pic_fields.bits.error_resilient_mode) + { + segmentIDStreamInEnable = 1; + } + + //frame type of previous frame (Key or Non-Key Frame). + uint8_t last_frame_type = gen9_hcpd_context->last_frame.frame_type; + + uint8_t use_pre_frame_mvs = 0; + use_pre_frame_mvs = !((pic_param->pic_fields.bits.error_resilient_mode) || + (pic_param->frame_width != gen9_hcpd_context->last_frame.frame_width) || + (pic_param->frame_height != gen9_hcpd_context->last_frame.frame_height) || + (pic_param->pic_fields.bits.intra_only) || + (pic_param->pic_fields.bits.frame_type == HCP_VP9_KEY_FRAME)|| + (gen9_hcpd_context->last_frame.intra_only)|| + (last_frame_type == HCP_VP9_KEY_FRAME) || + (!gen9_hcpd_context->last_frame.show_frame)); + + uint8_t adapt_probabilities_flag = 0; + if((pic_param->pic_fields.bits.error_resilient_mode || pic_param->pic_fields.bits.frame_parallel_decoding_mode)) + adapt_probabilities_flag = 0; //0: Do not adapt (error resilient or frame_parallel_mode are set) + else if(!(pic_param->pic_fields.bits.error_resilient_mode) && !(pic_param->pic_fields.bits.frame_parallel_decoding_mode)) + adapt_probabilities_flag = 1; //1: Adapt (not error resilient and not frame_ parallel_mode) + + frame_width_in_pixel = (gen9_hcpd_context->picture_width_in_min_cb_minus1 + 1) * gen9_hcpd_context->min_cb_size ; + frame_height_in_pixel = (gen9_hcpd_context->picture_height_in_min_cb_minus1 + 1) * gen9_hcpd_context->min_cb_size ; + + fwidth = (fwidth > frame_width_in_pixel)?frame_width_in_pixel:fwidth; + fheight = (fheight > frame_height_in_pixel)?frame_height_in_pixel:fheight; + + BEGIN_BCS_BATCH(batch, LEN_COMMAND_OWN); + + OUT_BCS_BATCH(batch, HCP_VP9_PIC_STATE | (LEN_COMMAND_OWN - 2)); + + OUT_BCS_BATCH(batch, + (frame_height_in_pixel - 1) << 16 | + (frame_width_in_pixel - 1)); /* DW 1 */ + OUT_BCS_BATCH(batch, + segmentIDStreamInEnable << 31 | + segmentIDStreamOutEnable << 30 | + pic_param->pic_fields.bits.lossless_flag << 29 | + segmentation_temporal_update << 28 | + pic_param->pic_fields.bits.segmentation_update_map << 27 | + pic_param->pic_fields.bits.segmentation_enabled << 26 | + pic_param->sharpness_level << 23 | + pic_param->filter_level << 17 | + pic_param->pic_fields.bits.frame_parallel_decoding_mode << 16 | + pic_param->pic_fields.bits.error_resilient_mode << 15 | + pic_param->pic_fields.bits.refresh_frame_context << 14 | + last_frame_type << 13 | + 0 << 12 | /* tx select mode */ + 0 << 11 | /* Hybrid Prediction Mode */ + use_pre_frame_mvs << 10 | + pic_param->pic_fields.bits.alt_ref_frame_sign_bias << 9 | + pic_param->pic_fields.bits.golden_ref_frame_sign_bias << 8 | + pic_param->pic_fields.bits.last_ref_frame_sign_bias << 7 | + pic_param->pic_fields.bits.mcomp_filter_type << 4 | + pic_param->pic_fields.bits.allow_high_precision_mv << 3 | + pic_param->pic_fields.bits.intra_only <<2 | + adapt_probabilities_flag << 1 | + pic_param->pic_fields.bits.frame_type <<0); /* DW 2 */ + OUT_BCS_BATCH(batch, + HCP_VP9_PROFILE0 << 28 | /* Profile 0 only supports 8 bit 420 only */ + pic_param->log2_tile_rows << 8 | + pic_param->log2_tile_columns <<0); /* DW 3 */ + // resolution change case + + // DW4-DW6 + for(i = 0; i < 3; i++) + { + obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface; + gen9_vp9_surface = NULL; + scale_w = 0; + scale_h = 0; + if (obj_surface && obj_surface->private_data) + { + gen9_vp9_surface = obj_surface->private_data; + if(!gen9_hcpd_vp9_valid_ref_frame_size(gen9_vp9_surface->frame_width,gen9_vp9_surface->frame_height,pic_param->frame_width,pic_param->frame_height)) + { + scale_w = -1; + scale_h = -1; + }else + { + scale_w = (gen9_vp9_surface->frame_width << 14) /pic_param->frame_width ; + scale_h = (gen9_vp9_surface->frame_height << 14) /pic_param->frame_height ; + } + OUT_BCS_BATCH(batch, + scale_w<<16 | + scale_h); + }else + { + OUT_BCS_BATCH(batch, 0); + } + } + + // DW7-DW9 + for(i = 0; i < 3; i++) + { + obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface; + gen9_vp9_surface = NULL; + + if (obj_surface && obj_surface->private_data) + { + gen9_vp9_surface = obj_surface->private_data; + OUT_BCS_BATCH(batch, + ((gen9_vp9_surface->frame_height- 1)&0x3fff)<<16 | + ((gen9_vp9_surface->frame_width - 1)&0x3fff)); + }else + { + OUT_BCS_BATCH(batch, 0); + } + } + + OUT_BCS_BATCH(batch, + pic_param->first_partition_size << 16 | + pic_param->frame_header_length_in_bytes <<0); /* DW 10 */ + OUT_BCS_BATCH(batch, + (0 << 3) | + (0 << 2) | + (1 << 1) | + (0 << 0)); /* DW 11, ignored */ + //Rest of the DWs are not valid for BXT + for(i = 12; i < LEN_COMMAND_OWN; i++) + { + OUT_BCS_BATCH(batch, 0); + } + + ADVANCE_BCS_BATCH(batch); + +} + +static void +gen9_hcpd_vp9_segment_state(VADriverContextP ctx, + VADecPictureParameterBufferVP9 *pic_param, + VASegmentParameterVP9 *seg_param, uint8_t seg_id, + struct gen9_hcpd_context *gen9_hcpd_context) +{ + struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch; + + BEGIN_BCS_BATCH(batch, 7); + + OUT_BCS_BATCH(batch, HCP_VP9_SEGMENT_STATE | (7 - 2)); + OUT_BCS_BATCH(batch, seg_id << 0); /* DW 1 - SegmentID */ + OUT_BCS_BATCH(batch, + seg_param->segment_flags.fields.segment_reference_enabled << 3 | + seg_param->segment_flags.fields.segment_reference << 1 | + seg_param->segment_flags.fields.segment_reference_skipped <<0 ); /* DW 2 */ + OUT_BCS_BATCH(batch, + seg_param->filter_level[1][1] << 24 | //FilterLevelRef1Mode1 + seg_param->filter_level[1][0] << 16 | //FilterLevelRef1Mode0 + seg_param->filter_level[0][1] << 8 | //FilterLevelRef0Mode1 + seg_param->filter_level[0][0] << 0 ); //FilterLevelRef0Mode0 /* DW 3 */ + OUT_BCS_BATCH(batch, + seg_param->filter_level[3][1] << 24 | //FilterLevelRef3Mode1 + seg_param->filter_level[3][0] << 16 | //FilterLevelRef3Mode0 + seg_param->filter_level[2][1] << 8 | //FilterLevelRef2Mode1 + seg_param->filter_level[2][0] << 0 ); //FilterLevelRef2Mode0 /* DW 4 */ + OUT_BCS_BATCH(batch, + seg_param->luma_ac_quant_scale << 16 | + seg_param->luma_dc_quant_scale << 0 ); /* DW 5 */ + OUT_BCS_BATCH(batch, + seg_param->chroma_ac_quant_scale << 16 | + seg_param->chroma_dc_quant_scale << 0 ); /* DW 6 */ + + ADVANCE_BCS_BATCH(batch); + +} + +static void +gen9_hcpd_vp9_bsd_object(VADriverContextP ctx, + VADecPictureParameterBufferVP9 *pic_param, + VASliceParameterBufferVP9 *slice_param, + struct gen9_hcpd_context *gen9_hcpd_context) +{ + struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch; + int slice_data_size = slice_param->slice_data_size - pic_param->frame_header_length_in_bytes; + int slice_data_offset = slice_param->slice_data_offset + pic_param->frame_header_length_in_bytes; + + BEGIN_BCS_BATCH(batch, 3); + + OUT_BCS_BATCH(batch, HCP_BSD_OBJECT | (3 - 2)); + + OUT_BCS_BATCH(batch, slice_data_size ); + OUT_BCS_BATCH(batch, slice_data_offset); + + ADVANCE_BCS_BATCH(batch); + +} + +static VAStatus +gen9_hcpd_vp9_decode_picture(VADriverContextP ctx, + struct decode_state *decode_state, + struct gen9_hcpd_context *gen9_hcpd_context) +{ + VAStatus vaStatus; + struct i965_driver_data *i965 = i965_driver_data(ctx); + struct intel_batchbuffer *batch = gen9_hcpd_context->base.batch; + VADecPictureParameterBufferVP9 *pic_param; + VASliceParameterBufferVP9 *slice_param; + dri_bo *slice_data_bo; + int i = 0, num_segments=0, isScaling=0; + struct object_surface *obj_surface; + GenVP9Surface *gen9_vp9_surface; + vaStatus = gen9_hcpd_vp9_decode_init(ctx, decode_state, gen9_hcpd_context); + + if (vaStatus != VA_STATUS_SUCCESS) + goto out; + + assert(decode_state->pic_param && decode_state->pic_param->buffer); + pic_param = (VADecPictureParameterBufferVP9 *)decode_state->pic_param->buffer; + + //****And set the isScaling value accordingly****** + isScaling = 0; + for(i = 0; i < 3; i++) + { + obj_surface = gen9_hcpd_context->reference_surfaces[i].obj_surface; + gen9_vp9_surface = NULL; + if (obj_surface && obj_surface->private_data) + { + gen9_vp9_surface = obj_surface->private_data; + isScaling |= (gen9_vp9_surface->frame_width == pic_param->frame_width && + gen9_vp9_surface->frame_height == pic_param->frame_height)? 0:1; + } + } + + //Update segment id buffer if needed + vp9_update_segmentId_buffer(ctx, decode_state, gen9_hcpd_context, isScaling); + //Update probability buffer if needed + vp9_update_probabilities(ctx, decode_state, gen9_hcpd_context); + + if (i965->intel.has_bsd2) + intel_batchbuffer_start_atomic_bcs_override(batch, 0x1000, BSD_RING0); + else + intel_batchbuffer_start_atomic_bcs(batch, 0x1000); + intel_batchbuffer_emit_mi_flush(batch); + + gen9_hcpd_pipe_mode_select(ctx, decode_state, HCP_CODEC_VP9, gen9_hcpd_context); + //Not sure what the surface id value should be: Gold? ALtRef? PrevRef? or Just RefPic? + gen9_hcpd_vp9_surface_state(ctx, decode_state, gen9_hcpd_context); + + //Only one VASliceParameterBufferVP9 should be sent per frame + assert(decode_state->slice_params && decode_state->slice_params[0]->buffer); + slice_param = (VASliceParameterBufferVP9 *)decode_state->slice_params[0]->buffer; + slice_data_bo = decode_state->slice_datas[0]->bo; + + gen9_hcpd_ind_obj_base_addr_state(ctx, slice_data_bo, gen9_hcpd_context); + + gen9_hcpd_vp9_pipe_buf_addr_state(ctx, decode_state, gen9_hcpd_context); + //If segmentation is disabled, only SegParam[0] is valid, + //all others should be populated with 0 + if(!pic_param->pic_fields.bits.segmentation_enabled) + num_segments = 1; + else //If segmentation is enabled, all 8 entries should be valid. + num_segments = 8; + + for(i=0; i<num_segments; i++) { + VASegmentParameterVP9 seg_param = slice_param->seg_param[i]; + gen9_hcpd_vp9_segment_state(ctx, pic_param, &seg_param, i, gen9_hcpd_context); + } + + gen9_hcpd_vp9_pic_state(ctx, decode_state, gen9_hcpd_context); + + gen9_hcpd_vp9_bsd_object(ctx, pic_param, slice_param, gen9_hcpd_context); + + // keep track of the last frame status + gen9_hcpd_context->last_frame.frame_width = pic_param->frame_width; + gen9_hcpd_context->last_frame.frame_height = pic_param->frame_height; + gen9_hcpd_context->last_frame.show_frame = pic_param->pic_fields.bits.show_frame; + gen9_hcpd_context->last_frame.frame_type = pic_param->pic_fields.bits.frame_type; + gen9_hcpd_context->last_frame.refresh_frame_context = pic_param->pic_fields.bits.refresh_frame_context; + gen9_hcpd_context->last_frame.frame_context_idx = pic_param->pic_fields.bits.frame_context_idx; + gen9_hcpd_context->last_frame.intra_only = pic_param->pic_fields.bits.intra_only; + + // update prob buffer to vp9_fc; + + intel_batchbuffer_end_atomic(batch); + intel_batchbuffer_flush(batch); + + //update vp9_frame_ctx according to frame_context_id + if (pic_param->pic_fields.bits.refresh_frame_context) + { + //update vp9_fc to frame_context + dri_bo_map(gen9_hcpd_context->vp9_probability_buffer.bo,1); + memcpy(&gen9_hcpd_context->vp9_fc,(unsigned char *)gen9_hcpd_context->vp9_probability_buffer.bo->virtual,2048); + dri_bo_unmap(gen9_hcpd_context->vp9_probability_buffer.bo); + gen9_hcpd_context->vp9_frame_ctx[pic_param->pic_fields.bits.frame_context_idx] = gen9_hcpd_context->vp9_fc; + + } + +out: + return vaStatus; +} + + static VAStatus gen9_hcpd_decode_picture(VADriverContextP ctx, VAProfile profile, @@ -977,6 +1887,9 @@ gen9_hcpd_decode_picture(VADriverContextP ctx, case VAProfileHEVCMain10: vaStatus = gen9_hcpd_hevc_decode_picture(ctx, decode_state, gen9_hcpd_context); break; + case VAProfileVP9Profile0: + vaStatus = gen9_hcpd_vp9_decode_picture(ctx, decode_state, gen9_hcpd_context); + break; default: /* should never get here 1!! */ @@ -1002,6 +1915,10 @@ gen9_hcpd_context_destroy(void *hw_context) FREE_GEN_BUFFER((&gen9_hcpd_context->sao_line_buffer)); FREE_GEN_BUFFER((&gen9_hcpd_context->sao_tile_line_buffer)); FREE_GEN_BUFFER((&gen9_hcpd_context->sao_tile_column_buffer)); + FREE_GEN_BUFFER((&gen9_hcpd_context->hvd_line_rowstore_buffer)); + FREE_GEN_BUFFER((&gen9_hcpd_context->hvd_tile_rowstore_buffer)); + FREE_GEN_BUFFER((&gen9_hcpd_context->vp9_probability_buffer)); + FREE_GEN_BUFFER((&gen9_hcpd_context->vp9_segment_id_buffer)); intel_batchbuffer_free(gen9_hcpd_context->base.batch); free(gen9_hcpd_context); @@ -1014,6 +1931,25 @@ gen9_hcpd_hevc_context_init(VADriverContextP ctx, hevc_gen_default_iq_matrix(&gen9_hcpd_context->iq_matrix_hevc); } +static void +gen9_hcpd_vp9_context_init(VADriverContextP ctx, + struct gen9_hcpd_context *gen9_hcpd_context) +{ + int default_value = 255; + + gen9_hcpd_context->last_frame.frame_height = 0; + gen9_hcpd_context->last_frame.show_frame = 0; + gen9_hcpd_context->last_frame.frame_type = 0; + gen9_hcpd_context->last_frame.refresh_frame_context = default_value; + gen9_hcpd_context->last_frame.frame_context_idx = default_value; + gen9_hcpd_context->last_frame.intra_only = 0; + gen9_hcpd_context->last_frame.prob_buffer_saved_flag = 0; + gen9_hcpd_context->last_frame.prob_buffer_restored_flag = 0; + gen9_hcpd_context->last_frame.mv_temporal_buffer_bo = NULL; + + vp9_gen_default_probabilities(ctx, gen9_hcpd_context); +} + static struct hw_context * gen9_hcpd_context_init(VADriverContextP ctx, struct object_config *object_config) { @@ -1039,6 +1975,9 @@ gen9_hcpd_context_init(VADriverContextP ctx, struct object_config *object_config case VAProfileHEVCMain10: gen9_hcpd_hevc_context_init(ctx, gen9_hcpd_context); break; + case VAProfileVP9Profile0: + gen9_hcpd_vp9_context_init(ctx, gen9_hcpd_context); + break; default: break; @@ -1051,7 +1990,8 @@ struct hw_context * gen9_dec_hw_context_init(VADriverContextP ctx, struct object_config *obj_config) { if (obj_config->profile == VAProfileHEVCMain || - obj_config->profile == VAProfileHEVCMain10) { + obj_config->profile == VAProfileHEVCMain10 || + obj_config->profile == VAProfileVP9Profile0) { return gen9_hcpd_context_init(ctx, obj_config); } else { return gen8_dec_hw_context_init(ctx, obj_config); diff --git a/src/gen9_mfd.h b/src/gen9_mfd.h index 6e9fa5d..c266dd4 100644 --- a/src/gen9_mfd.h +++ b/src/gen9_mfd.h @@ -34,9 +34,24 @@ #include <i915_drm.h> #include <intel_bufmgr.h> #include "i965_decoder.h" +#include "vp9_probs.h" struct hw_context; +typedef struct vp9_frame_status +{ + uint16_t frame_width; + uint16_t frame_height; + uint8_t frame_type; + uint8_t show_frame; + uint8_t refresh_frame_context; + uint8_t frame_context_idx; + uint8_t intra_only; + uint8_t prob_buffer_saved_flag; + uint8_t prob_buffer_restored_flag; + dri_bo * mv_temporal_buffer_bo; +}vp9_last_frame_status; + struct gen9_hcpd_context { struct hw_context base; @@ -65,10 +80,21 @@ struct gen9_hcpd_context GenBuffer sao_line_buffer; GenBuffer sao_tile_line_buffer; GenBuffer sao_tile_column_buffer; + GenBuffer hvd_line_rowstore_buffer; + GenBuffer hvd_tile_rowstore_buffer; + GenBuffer vp9_probability_buffer; + GenBuffer vp9_segment_id_buffer; unsigned short first_inter_slice_collocated_ref_idx; unsigned short first_inter_slice_collocated_from_l0_flag; int first_inter_slice_valid; + + vp9_last_frame_status last_frame; + FRAME_CONTEXT vp9_frame_ctx[FRAME_CONTEXTS]; + FRAME_CONTEXT vp9_fc_inter_default; + FRAME_CONTEXT vp9_fc_key_default; + FRAME_CONTEXT vp9_fc; + FRAME_CONTEXT vp9_saved_fc; }; #endif /* GEN9_MFD_H */ |