On 12/04/2015 02:14 AM, Xiang, Haihao wrote:
From: Pengfei Qu<pengfei...@intel.com>

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...@intel.com>
Signed-off-by: Sirisha Muppavarapu<sirisha.muppavar...@intel.com>
Signed-off-by: peng.chen<peng.c.c...@intel.com>

This looks good to me.

Thanks

---
  src/gen9_mfd.c | 944 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
  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 44b343f..5bad278 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) {                                                   \
@@ -205,7 +206,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);

@@ -970,6 +971,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,
@@ -992,6 +1902,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!! */
@@ -1017,6 +1930,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);
@@ -1029,6 +1946,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)
  {
@@ -1054,6 +1990,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;
@@ -1066,7 +2005,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 */

_______________________________________________
Libva mailing list
Libva@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libva

Reply via email to