OSDN Git Service

Add vdenc common commands for CNL
[android-x86/hardware-intel-common-vaapi.git] / src / i965_avc_bsd.c
index 612d0ee..d422382 100644 (file)
  *    Xiang Haihao <haihao.xiang@intel.com>
  *
  */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
+#include "sysdeps.h"
 
 #include "intel_batchbuffer.h"
 #include "intel_driver.h"
 #include "i965_media_h264.h"
 #include "i965_media.h"
 #include "i965_decoder_utils.h"
-
-static void 
-i965_avc_bsd_free_avc_bsd_surface(void **data)
-{
-    struct i965_avc_bsd_surface *avc_bsd_surface = *data;
-
-    if (!avc_bsd_surface)
-        return;
-
-    dri_bo_unreference(avc_bsd_surface->dmv_top);
-    avc_bsd_surface->dmv_top = NULL;
-    dri_bo_unreference(avc_bsd_surface->dmv_bottom);
-    avc_bsd_surface->dmv_bottom = NULL;
-
-    free(avc_bsd_surface);
-    *data = NULL;
-}
+#include "intel_media.h"
 
 static void
-i965_avc_bsd_init_avc_bsd_surface(VADriverContextP ctx, 
+i965_avc_bsd_init_avc_bsd_surface(VADriverContextP ctx,
                                   struct object_surface *obj_surface,
                                   VAPictureParameterBufferH264 *pic_param,
                                   struct i965_h264_context *i965_h264_context)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
-    struct i965_avc_bsd_context *i965_avc_bsd_context = &i965_h264_context->i965_avc_bsd_context;
-    struct i965_avc_bsd_surface *avc_bsd_surface = obj_surface->private_data;
+    GenAvcSurface *avc_bsd_surface = obj_surface->private_data;
 
-    obj_surface->free_private_data = i965_avc_bsd_free_avc_bsd_surface;
+    obj_surface->free_private_data = gen_free_avc_surface;
 
     if (!avc_bsd_surface) {
-        avc_bsd_surface = calloc(sizeof(struct i965_avc_bsd_surface), 1);
+        avc_bsd_surface = calloc(sizeof(GenAvcSurface), 1);
+        assert(avc_bsd_surface);
+        avc_bsd_surface->base.frame_store_id = -1;
         assert((obj_surface->size & 0x3f) == 0);
         obj_surface->private_data = avc_bsd_surface;
     }
 
-    avc_bsd_surface->ctx = i965_avc_bsd_context;
     avc_bsd_surface->dmv_bottom_flag = (pic_param->pic_fields.bits.field_pic_flag &&
                                         !pic_param->seq_fields.bits.direct_8x8_inference_flag);
 
@@ -100,7 +81,7 @@ i965_bsd_ind_obj_base_address(VADriverContextP ctx,
                               struct decode_state *decode_state,
                               int slice,
                               struct i965_h264_context *i965_h264_context)
-                              
+
 {
     struct intel_batchbuffer *batch = i965_h264_context->batch;
 
@@ -136,8 +117,6 @@ i965_avc_bsd_img_state(VADriverContextP ctx,
     assert(decode_state->pic_param && decode_state->pic_param->buffer);
     pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
 
-    assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID));
-
     if (pic_param->CurrPic.flags & VA_PICTURE_H264_TOP_FIELD)
         img_struct = 1;
     else if (pic_param->CurrPic.flags & VA_PICTURE_H264_BOTTOM_FIELD)
@@ -163,7 +142,7 @@ i965_avc_bsd_img_state(VADriverContextP ctx,
 
     width_in_mbs = ((pic_param->picture_width_in_mbs_minus1 + 1) & 0xff);
     height_in_mbs = ((pic_param->picture_height_in_mbs_minus1 + 1) & 0xff); /* frame height */
-                                                                               
+
     assert(!((width_in_mbs * height_in_mbs) & 0x8000)); /* hardware requirement */
 
     /* BSD unit doesn't support 4:2:2 and 4:4:4 picture */
@@ -175,14 +154,14 @@ i965_avc_bsd_img_state(VADriverContextP ctx,
 
     BEGIN_BCS_BATCH(batch, 6);
     OUT_BCS_BATCH(batch, CMD_AVC_BSD_IMG_STATE | (6 - 2));
-    OUT_BCS_BATCH(batch, 
+    OUT_BCS_BATCH(batch,
                   ((width_in_mbs * height_in_mbs) & 0x7fff));
-    OUT_BCS_BATCH(batch, 
-                  (height_in_mbs << 16) | 
+    OUT_BCS_BATCH(batch,
+                  (height_in_mbs << 16) |
                   (width_in_mbs << 0));
-    OUT_BCS_BATCH(batch, 
+    OUT_BCS_BATCH(batch,
                   ((pic_param->second_chroma_qp_index_offset & 0x1f) << 24) |
-                  ((pic_param->chroma_qp_index_offset & 0x1f) << 16) | 
+                  ((pic_param->chroma_qp_index_offset & 0x1f) << 16) |
                   (SCAN_RASTER_ORDER << 15) | /* AVC ILDB Data */
                   (SCAN_SPECIAL_ORDER << 14) | /* AVC IT Command */
                   (SCAN_RASTER_ORDER << 13) | /* AVC IT Data */
@@ -236,11 +215,11 @@ i965_avc_bsd_qm_state(VADriverContextP ctx,
     OUT_BCS_BATCH(batch, CMD_AVC_BSD_QM_STATE | (cmd_len - 2));
 
     if (pic_param->pic_fields.bits.transform_8x8_mode_flag)
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (0x0  << 8) | /* don't use default built-in matrices */
                       (0xff << 0)); /* six 4x4 and two 8x8 scaling matrices */
     else
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (0x0  << 8) | /* don't use default built-in matrices */
                       (0x3f << 0)); /* six 4x4 scaling matrices */
 
@@ -253,8 +232,8 @@ i965_avc_bsd_qm_state(VADriverContextP ctx,
 }
 
 static void
-i965_avc_bsd_slice_state(VADriverContextP ctx, 
-                         VAPictureParameterBufferH264 *pic_param, 
+i965_avc_bsd_slice_state(VADriverContextP ctx,
+                         VAPictureParameterBufferH264 *pic_param,
                          VASliceParameterBufferH264 *slice_param,
                          struct i965_h264_context *i965_h264_context)
 {
@@ -274,13 +253,13 @@ i965_avc_bsd_slice_state(VADriverContextP ctx,
         slice_param->slice_type == SLICE_TYPE_SP) {
         present_flag = PRESENT_REF_LIST0;
         cmd_len += 8;
-    } else { 
+    } else {
         present_flag = PRESENT_REF_LIST0 | PRESENT_REF_LIST1;
         cmd_len += 16;
     }
 
     if ((slice_param->slice_type == SLICE_TYPE_P ||
-         slice_param->slice_type == SLICE_TYPE_SP) && 
+         slice_param->slice_type == SLICE_TYPE_SP) &&
         (pic_param->pic_fields.bits.weighted_pred_flag == 1)) {
         present_flag |= PRESENT_WEIGHT_OFFSET_L0;
         cmd_len += 48;
@@ -317,7 +296,7 @@ i965_avc_bsd_slice_state(VADriverContextP ctx,
             ref_idx_state,
             va_pic, num_va_pics,
             i965_h264_context->fsid_list
-        );            
+        );
         intel_batchbuffer_data(batch, ref_idx_state, sizeof(ref_idx_state));
     }
 
@@ -394,17 +373,17 @@ i965_avc_bsd_slice_state(VADriverContextP ctx,
 
 static void
 i965_avc_bsd_buf_base_state(VADriverContextP ctx,
-                            VAPictureParameterBufferH264 *pic_param, 
+                            struct decode_state *decode_state,
+                            VAPictureParameterBufferH264 *pic_param,
                             VASliceParameterBufferH264 *slice_param,
                             struct i965_h264_context *i965_h264_context)
 {
-    struct i965_driver_data *i965 = i965_driver_data(ctx);
     struct intel_batchbuffer *batch = i965_h264_context->batch;
     struct i965_avc_bsd_context *i965_avc_bsd_context;
-    int i, j;
+    int i;
     VAPictureH264 *va_pic;
     struct object_surface *obj_surface;
-    struct i965_avc_bsd_surface *avc_bsd_surface;
+    GenAvcSurface *avc_bsd_surface;
 
     i965_avc_bsd_context = &i965_h264_context->i965_avc_bsd_context;
 
@@ -431,45 +410,22 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
         OUT_BCS_BATCH(batch, 0);
 
     for (i = 0; i < ARRAY_ELEMS(i965_h264_context->fsid_list); i++) {
-        if (i965_h264_context->fsid_list[i].surface_id != VA_INVALID_ID) {
-            int found = 0;
-            for (j = 0; j < ARRAY_ELEMS(pic_param->ReferenceFrames); j++) {
-                va_pic = &pic_param->ReferenceFrames[j];
-                
-                if (va_pic->flags & VA_PICTURE_H264_INVALID)
-                    continue;
-
-                if (va_pic->picture_id == i965_h264_context->fsid_list[i].surface_id) {
-                    found = 1;
-                    break;
-                }
-            }
-
-            assert(found == 1);
-
-            if (!(va_pic->flags & VA_PICTURE_H264_INVALID)) {
-                obj_surface = SURFACE(va_pic->picture_id);
-                assert(obj_surface);
-                avc_bsd_surface = obj_surface->private_data;
-            
-                if (avc_bsd_surface == NULL) {
-                    OUT_BCS_BATCH(batch, 0);
-                    OUT_BCS_BATCH(batch, 0);
-                } else {
-                    OUT_BCS_RELOC(batch, avc_bsd_surface->dmv_top,
-                                  I915_GEM_DOMAIN_INSTRUCTION, 0,
-                                  0);
-
-                    if (avc_bsd_surface->dmv_bottom_flag == 1)
-                        OUT_BCS_RELOC(batch, avc_bsd_surface->dmv_bottom,
-                                      I915_GEM_DOMAIN_INSTRUCTION, 0,
-                                      0);
-                    else
-                        OUT_BCS_RELOC(batch, avc_bsd_surface->dmv_top,
-                                      I915_GEM_DOMAIN_INSTRUCTION, 0,
-                                      0);
-                }
-            } 
+        obj_surface = i965_h264_context->fsid_list[i].obj_surface;
+        if (obj_surface && obj_surface->private_data) {
+            avc_bsd_surface = obj_surface->private_data;
+
+            OUT_BCS_RELOC(batch, avc_bsd_surface->dmv_top,
+                          I915_GEM_DOMAIN_INSTRUCTION, 0,
+                          0);
+
+            if (avc_bsd_surface->dmv_bottom_flag == 1)
+                OUT_BCS_RELOC(batch, avc_bsd_surface->dmv_bottom,
+                              I915_GEM_DOMAIN_INSTRUCTION, 0,
+                              0);
+            else
+                OUT_BCS_RELOC(batch, avc_bsd_surface->dmv_top,
+                              I915_GEM_DOMAIN_INSTRUCTION, 0,
+                              0);
         } else {
             OUT_BCS_BATCH(batch, 0);
             OUT_BCS_BATCH(batch, 0);
@@ -477,12 +433,23 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
     }
 
     va_pic = &pic_param->CurrPic;
-    assert(!(va_pic->flags & VA_PICTURE_H264_INVALID));
-    obj_surface = SURFACE(va_pic->picture_id);
-    assert(obj_surface);
-    obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
-    obj_surface->flags |= (pic_param->pic_fields.bits.reference_pic_flag ? SURFACE_REFERENCED : 0);
-    i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
+    obj_surface = decode_state->render_object;
+    if (pic_param->pic_fields.bits.reference_pic_flag)
+        obj_surface->flags |= SURFACE_REFERENCED;
+    else
+        obj_surface->flags &= ~SURFACE_REFERENCED;
+    i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
+
+    /* initial uv component for YUV400 case */
+    if (pic_param->seq_fields.bits.chroma_format_idc == 0) {
+        unsigned int uv_offset = obj_surface->width * obj_surface->height;
+        unsigned int uv_size   = obj_surface->width * obj_surface->height / 2;
+
+        dri_bo_map(obj_surface->bo, 1);
+        memset(obj_surface->bo->virtual + uv_offset, 0x80, uv_size);
+        dri_bo_unmap(obj_surface->bo);
+    }
+
     i965_avc_bsd_init_avc_bsd_surface(ctx, obj_surface, pic_param, i965_h264_context);
     avc_bsd_surface = obj_surface->private_data;
 
@@ -501,26 +468,16 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
 
     /* POC List */
     for (i = 0; i < ARRAY_ELEMS(i965_h264_context->fsid_list); i++) {
-        if (i965_h264_context->fsid_list[i].surface_id != VA_INVALID_ID) {
-            int found = 0;
-            for (j = 0; j < ARRAY_ELEMS(pic_param->ReferenceFrames); j++) {
-                va_pic = &pic_param->ReferenceFrames[j];
-                
-                if (va_pic->flags & VA_PICTURE_H264_INVALID)
-                    continue;
-
-                if (va_pic->picture_id == i965_h264_context->fsid_list[i].surface_id) {
-                    found = 1;
-                    break;
-                }
-            }
+        obj_surface = i965_h264_context->fsid_list[i].obj_surface;
 
-            assert(found == 1);
+        if (obj_surface) {
+            const VAPictureH264 * const va_pic = avc_find_picture(
+                                                     obj_surface->base.id, pic_param->ReferenceFrames,
+                                                     ARRAY_ELEMS(pic_param->ReferenceFrames));
 
-            if (!(va_pic->flags & VA_PICTURE_H264_INVALID)) {
-                OUT_BCS_BATCH(batch, va_pic->TopFieldOrderCnt);
-                OUT_BCS_BATCH(batch, va_pic->BottomFieldOrderCnt);
-            } 
+            assert(va_pic != NULL);
+            OUT_BCS_BATCH(batch, va_pic->TopFieldOrderCnt);
+            OUT_BCS_BATCH(batch, va_pic->BottomFieldOrderCnt);
         } else {
             OUT_BCS_BATCH(batch, 0);
             OUT_BCS_BATCH(batch, 0);
@@ -534,37 +491,8 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
     ADVANCE_BCS_BATCH(batch);
 }
 
-/*
- * Return the bit offset to the first bit of the slice data
- *
- * VASliceParameterBufferH264.slice_data_bit_offset will point into the part
- * of slice header if there are some escaped bytes in the slice header. The offset 
- * to slice data is needed for BSD unit so that BSD unit can fetch right slice data
- * for processing. This fixes conformance case BASQP1_Sony_C.jsv
- */
-static int
-i965_avc_bsd_get_slice_bit_offset(uint8_t *buf, int mode_flag, int in_slice_data_bit_offset)
-{
-    int out_slice_data_bit_offset;
-    int slice_header_size = in_slice_data_bit_offset / 8;
-    int i, j;
-
-    for (i = 0, j = 0; i < slice_header_size; i++, j++) {
-        if (!buf[j] && !buf[j + 1] && buf[j + 2] == 3) {
-            i++, j += 2;
-        }
-    }
-
-    out_slice_data_bit_offset = 8 * j + in_slice_data_bit_offset % 8;
-
-    if (mode_flag == ENTROPY_CABAC)
-        out_slice_data_bit_offset = ALIGN(out_slice_data_bit_offset, 0x8);
-
-    return out_slice_data_bit_offset;
-}
-
 static void
-g4x_avc_bsd_object(VADriverContextP ctx, 
+g4x_avc_bsd_object(VADriverContextP ctx,
                    struct decode_state *decode_state,
                    VAPictureParameterBufferH264 *pic_param,
                    VASliceParameterBufferH264 *slice_param,
@@ -581,26 +509,25 @@ g4x_avc_bsd_object(VADriverContextP ctx,
         int num_ref_idx_l0, num_ref_idx_l1;
         int mbaff_picture = (!pic_param->pic_fields.bits.field_pic_flag &&
                              pic_param->seq_fields.bits.mb_adaptive_frame_field_flag);
-        int slice_data_bit_offset;
+        unsigned int slice_data_bit_offset;
         int weighted_pred_idc = 0;
         int first_mb_in_slice = 0;
         int slice_type;
-        uint8_t *slice_data = NULL;
 
         encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */
 
         if (encrypted) {
             cmd_len = 9;
             counter_value = 0; /* FIXME: ??? */
-        } else 
+        } else
             cmd_len = 8;
 
-        dri_bo_map(decode_state->slice_datas[slice_index]->bo, 0);
-        slice_data = (uint8_t *)(decode_state->slice_datas[slice_index]->bo->virtual + slice_param->slice_data_offset);
-        slice_data_bit_offset = i965_avc_bsd_get_slice_bit_offset(slice_data,
-                                                                  pic_param->pic_fields.bits.entropy_coding_mode_flag,
-                                                                  slice_param->slice_data_bit_offset);
-        dri_bo_unmap(decode_state->slice_datas[slice_index]->bo);
+
+        slice_data_bit_offset = avc_get_first_mb_bit_offset_with_epb(
+                                    decode_state->slice_datas[slice_index]->bo,
+                                    slice_param,
+                                    pic_param->pic_fields.bits.entropy_coding_mode_flag
+                                );
 
         if (slice_param->slice_type == SLICE_TYPE_I ||
             slice_param->slice_type == SLICE_TYPE_SI)
@@ -633,18 +560,18 @@ g4x_avc_bsd_object(VADriverContextP ctx,
             weighted_pred_idc = pic_param->pic_fields.bits.weighted_bipred_idc;
 
         first_mb_in_slice = slice_param->first_mb_in_slice << mbaff_picture;
-        slice_hor_pos = first_mb_in_slice % width_in_mbs; 
+        slice_hor_pos = first_mb_in_slice % width_in_mbs;
         slice_ver_pos = first_mb_in_slice / width_in_mbs;
 
         BEGIN_BCS_BATCH(batch, cmd_len);
         OUT_BCS_BATCH(batch, CMD_AVC_BSD_OBJECT | (cmd_len - 2));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (encrypted << 31) |
                       ((slice_param->slice_data_size - (slice_data_bit_offset >> 3)) << 0));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (slice_param->slice_data_offset +
                        (slice_data_bit_offset >> 3)));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (0 << 31) | /* concealment mode: 0->intra 16x16 prediction, 1->inter P Copy */
                       (0 << 14) | /* ignore BSDPrematureComplete Error handling */
                       (0 << 13) | /* FIXME: ??? */
@@ -652,12 +579,12 @@ g4x_avc_bsd_object(VADriverContextP ctx,
                       (0 << 10) | /* ignore Entropy Error handling */
                       (0 << 8)  | /* ignore MB Header Error handling */
                       (slice_type << 0));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (num_ref_idx_l1 << 24) |
                       (num_ref_idx_l0 << 16) |
                       (slice_param->chroma_log2_weight_denom << 8) |
                       (slice_param->luma_log2_weight_denom << 0));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (weighted_pred_idc << 30) |
                       (slice_param->direct_spatial_mv_pred_flag << 29) |
                       (slice_param->disable_deblocking_filter_idc << 27) |
@@ -665,21 +592,21 @@ g4x_avc_bsd_object(VADriverContextP ctx,
                       ((pic_param->pic_init_qp_minus26 + 26 + slice_param->slice_qp_delta) << 16) |
                       ((slice_param->slice_beta_offset_div2 & 0xf) << 8) |
                       ((slice_param->slice_alpha_c0_offset_div2 & 0xf) << 0));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (slice_ver_pos << 24) |
-                      (slice_hor_pos << 16) | 
+                      (slice_hor_pos << 16) |
                       (first_mb_in_slice << 0));
-        OUT_BCS_BATCH(batch, 
-                      (0 << 7) | /* FIXME: ??? */
+        OUT_BCS_BATCH(batch,
+                      (1 << 7) |
                       ((0x7 - (slice_data_bit_offset & 0x7)) << 0));
 
         if (encrypted) {
             OUT_BCS_BATCH(batch, counter_value);
         }
 
-        ADVANCE_BCS_BATCH(batch); 
+        ADVANCE_BCS_BATCH(batch);
     } else {
-        BEGIN_BCS_BATCH(batch, 8); 
+        BEGIN_BCS_BATCH(batch, 8);
         OUT_BCS_BATCH(batch, CMD_AVC_BSD_OBJECT | (8 - 2));
         OUT_BCS_BATCH(batch, 0); /* indirect data length for phantom slice is 0 */
         OUT_BCS_BATCH(batch, 0); /* indirect data start address for phantom slice is 0 */
@@ -693,7 +620,7 @@ g4x_avc_bsd_object(VADriverContextP ctx,
 }
 
 static void
-ironlake_avc_bsd_object(VADriverContextP ctx, 
+ironlake_avc_bsd_object(VADriverContextP ctx,
                         struct decode_state *decode_state,
                         VAPictureParameterBufferH264 *pic_param,
                         VASliceParameterBufferH264 *slice_param,
@@ -710,25 +637,23 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
         int num_ref_idx_l0, num_ref_idx_l1;
         int mbaff_picture = (!pic_param->pic_fields.bits.field_pic_flag &&
                              pic_param->seq_fields.bits.mb_adaptive_frame_field_flag);
-        int slice_data_bit_offset;
+        unsigned int slice_data_bit_offset;
         int weighted_pred_idc = 0;
         int first_mb_in_slice;
         int slice_type;
-        uint8_t *slice_data = NULL;
 
         encrypted = 0; /* FIXME: which flag in VAAPI is used for encryption? */
 
         if (encrypted) {
             counter_value = 0; /* FIXME: ??? */
-        } else 
+        } else
             counter_value = 0;
 
-        dri_bo_map(decode_state->slice_datas[slice_index]->bo, 0);
-        slice_data = (uint8_t *)(decode_state->slice_datas[slice_index]->bo->virtual + slice_param->slice_data_offset);
-        slice_data_bit_offset = i965_avc_bsd_get_slice_bit_offset(slice_data,
-                                                                  pic_param->pic_fields.bits.entropy_coding_mode_flag,
-                                                                  slice_param->slice_data_bit_offset);
-        dri_bo_unmap(decode_state->slice_datas[slice_index]->bo);
+        slice_data_bit_offset = avc_get_first_mb_bit_offset_with_epb(
+                                    decode_state->slice_datas[slice_index]->bo,
+                                    slice_param,
+                                    pic_param->pic_fields.bits.entropy_coding_mode_flag
+                                );
 
         if (slice_param->slice_type == SLICE_TYPE_I ||
             slice_param->slice_type == SLICE_TYPE_SI)
@@ -761,20 +686,20 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
             weighted_pred_idc = pic_param->pic_fields.bits.weighted_bipred_idc;
 
         first_mb_in_slice = slice_param->first_mb_in_slice << mbaff_picture;
-        slice_hor_pos = first_mb_in_slice % width_in_mbs; 
+        slice_hor_pos = first_mb_in_slice % width_in_mbs;
         slice_ver_pos = first_mb_in_slice / width_in_mbs;
 
         BEGIN_BCS_BATCH(batch, 16);
         OUT_BCS_BATCH(batch, CMD_AVC_BSD_OBJECT | (16 - 2));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (encrypted << 31) |
                       (0 << 30) | /* FIXME: packet based bit stream */
                       (0 << 29) | /* FIXME: packet format */
                       ((slice_param->slice_data_size - (slice_data_bit_offset >> 3)) << 0));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (slice_param->slice_data_offset +
                        (slice_data_bit_offset >> 3)));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (0 << 31) | /* concealment mode: 0->intra 16x16 prediction, 1->inter P Copy */
                       (0 << 14) | /* ignore BSDPrematureComplete Error handling */
                       (0 << 13) | /* FIXME: ??? */
@@ -782,12 +707,12 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
                       (0 << 10) | /* ignore Entropy Error handling */
                       (0 << 8)  | /* ignore MB Header Error handling */
                       (slice_type << 0));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (num_ref_idx_l1 << 24) |
                       (num_ref_idx_l0 << 16) |
                       (slice_param->chroma_log2_weight_denom << 8) |
                       (slice_param->luma_log2_weight_denom << 0));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (weighted_pred_idc << 30) |
                       (slice_param->direct_spatial_mv_pred_flag << 29) |
                       (slice_param->disable_deblocking_filter_idc << 27) |
@@ -795,15 +720,15 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
                       ((pic_param->pic_init_qp_minus26 + 26 + slice_param->slice_qp_delta) << 16) |
                       ((slice_param->slice_beta_offset_div2 & 0xf) << 8) |
                       ((slice_param->slice_alpha_c0_offset_div2 & 0xf) << 0));
-        OUT_BCS_BATCH(batch, 
+        OUT_BCS_BATCH(batch,
                       (slice_ver_pos << 24) |
-                      (slice_hor_pos << 16) | 
+                      (slice_hor_pos << 16) |
                       (first_mb_in_slice << 0));
-        OUT_BCS_BATCH(batch, 
-                      (0 << 7) | /* FIXME: ??? */
+        OUT_BCS_BATCH(batch,
+                      (1 << 7) |
                       ((0x7 - (slice_data_bit_offset & 0x7)) << 0));
         OUT_BCS_BATCH(batch, counter_value);
-        
+
         /* FIXME: dw9-dw11 */
         OUT_BCS_BATCH(batch, 0);
         OUT_BCS_BATCH(batch, 0);
@@ -813,7 +738,7 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
         OUT_BCS_BATCH(batch, i965_h264_context->weight128_chroma_l0);
         OUT_BCS_BATCH(batch, i965_h264_context->weight128_chroma_l1);
 
-        ADVANCE_BCS_BATCH(batch); 
+        ADVANCE_BCS_BATCH(batch);
     } else {
         BEGIN_BCS_BATCH(batch, 16);
         OUT_BCS_BATCH(batch, CMD_AVC_BSD_OBJECT | (16 - 2));
@@ -837,7 +762,7 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
 }
 
 static void
-i965_avc_bsd_object(VADriverContextP ctx, 
+i965_avc_bsd_object(VADriverContextP ctx,
                     struct decode_state *decode_state,
                     VAPictureParameterBufferH264 *pic_param,
                     VASliceParameterBufferH264 *slice_param,
@@ -846,14 +771,14 @@ i965_avc_bsd_object(VADriverContextP ctx,
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
 
-    if (IS_IRONLAKE(i965->intel.device_id))
+    if (IS_IRONLAKE(i965->intel.device_info))
         ironlake_avc_bsd_object(ctx, decode_state, pic_param, slice_param, slice_index, i965_h264_context);
     else
         g4x_avc_bsd_object(ctx, decode_state, pic_param, slice_param, slice_index, i965_h264_context);
 }
 
 static void
-i965_avc_bsd_phantom_slice(VADriverContextP ctx, 
+i965_avc_bsd_phantom_slice(VADriverContextP ctx,
                            struct decode_state *decode_state,
                            VAPictureParameterBufferH264 *pic_param,
                            struct i965_h264_context *i965_h264_context)
@@ -861,121 +786,7 @@ i965_avc_bsd_phantom_slice(VADriverContextP ctx,
     i965_avc_bsd_object(ctx, decode_state, pic_param, NULL, 0, i965_h264_context);
 }
 
-static void
-i965_avc_bsd_frame_store_index(VADriverContextP ctx,
-                               VAPictureParameterBufferH264 *pic_param,
-                               struct i965_h264_context *i965_h264_context)
-{
-    struct i965_driver_data *i965 = i965_driver_data(ctx);
-    int i, j;
-
-    assert(ARRAY_ELEMS(i965_h264_context->fsid_list) == ARRAY_ELEMS(pic_param->ReferenceFrames));
-
-    for (i = 0; i < ARRAY_ELEMS(i965_h264_context->fsid_list); i++) {
-        int found = 0;
-
-        if (i965_h264_context->fsid_list[i].surface_id == VA_INVALID_ID)
-            continue;
-
-        for (j = 0; j < ARRAY_ELEMS(pic_param->ReferenceFrames); j++) {
-            VAPictureH264 *ref_pic = &pic_param->ReferenceFrames[j];
-            if (ref_pic->flags & VA_PICTURE_H264_INVALID)
-                continue;
-
-            if (i965_h264_context->fsid_list[i].surface_id == ref_pic->picture_id) {
-                found = 1;
-                break;
-            }
-        }
-
-        if (!found) {
-            struct object_surface *obj_surface = SURFACE(i965_h264_context->fsid_list[i].surface_id);
-            obj_surface->flags &= ~SURFACE_REFERENCED;
-
-            if ((obj_surface->flags & SURFACE_ALL_MASK) == SURFACE_DISPLAYED) {
-                dri_bo_unreference(obj_surface->bo);
-                obj_surface->bo = NULL;
-                obj_surface->flags &= ~SURFACE_REF_DIS_MASK;
-            }
-
-            if (obj_surface->free_private_data)
-                obj_surface->free_private_data(&obj_surface->private_data);
-
-            i965_h264_context->fsid_list[i].surface_id = VA_INVALID_ID;
-            i965_h264_context->fsid_list[i].frame_store_id = -1;
-        }
-    }
-
-    for (i = 0; i < ARRAY_ELEMS(pic_param->ReferenceFrames); i++) {
-        VAPictureH264 *ref_pic = &pic_param->ReferenceFrames[i];
-        int found = 0;
-
-        if (ref_pic->flags & VA_PICTURE_H264_INVALID)
-            continue;
-
-        for (j = 0; j < ARRAY_ELEMS(i965_h264_context->fsid_list); j++) {
-            if (i965_h264_context->fsid_list[j].surface_id == VA_INVALID_ID)
-                continue;
-            
-            if (i965_h264_context->fsid_list[j].surface_id == ref_pic->picture_id) {
-                found = 1;
-                break;
-            }
-        }
-
-        if (!found) {
-            int frame_idx;
-            struct object_surface *obj_surface = SURFACE(ref_pic->picture_id);
-            assert(obj_surface);
-            i965_check_alloc_surface_bo(ctx, obj_surface, 0, VA_FOURCC('N','V','1','2'), SUBSAMPLE_YUV420);
-            
-            for (frame_idx = 0; frame_idx < ARRAY_ELEMS(i965_h264_context->fsid_list); frame_idx++) {
-                for (j = 0; j < ARRAY_ELEMS(i965_h264_context->fsid_list); j++) {
-                    if (i965_h264_context->fsid_list[j].surface_id == VA_INVALID_ID)
-                        continue;
-
-                    if (i965_h264_context->fsid_list[j].frame_store_id == frame_idx)
-                        break;
-                }
-
-                if (j == ARRAY_ELEMS(i965_h264_context->fsid_list))
-                    break;
-            }
-
-            assert(frame_idx < ARRAY_ELEMS(i965_h264_context->fsid_list));
-
-            for (j = 0; j < ARRAY_ELEMS(i965_h264_context->fsid_list); j++) {
-                if (i965_h264_context->fsid_list[j].surface_id == VA_INVALID_ID) {
-                    i965_h264_context->fsid_list[j].surface_id = ref_pic->picture_id;
-                    i965_h264_context->fsid_list[j].frame_store_id = frame_idx;
-                    break;
-                }
-            }
-        }
-    }
-
-    for (i = 0; i < ARRAY_ELEMS(i965_h264_context->fsid_list) - 1; i++) {
-        if (i965_h264_context->fsid_list[i].surface_id != VA_INVALID_ID &&
-            i965_h264_context->fsid_list[i].frame_store_id == i)
-            continue;
-
-        for (j = i + 1; j < ARRAY_ELEMS(i965_h264_context->fsid_list); j++) {
-            if (i965_h264_context->fsid_list[j].surface_id != VA_INVALID_ID &&
-                i965_h264_context->fsid_list[j].frame_store_id == i) {
-                VASurfaceID id = i965_h264_context->fsid_list[i].surface_id;
-                int frame_idx = i965_h264_context->fsid_list[i].frame_store_id;
-
-                i965_h264_context->fsid_list[i].surface_id = i965_h264_context->fsid_list[j].surface_id;
-                i965_h264_context->fsid_list[i].frame_store_id = i965_h264_context->fsid_list[j].frame_store_id;
-                i965_h264_context->fsid_list[j].surface_id = id;
-                i965_h264_context->fsid_list[j].frame_store_id = frame_idx;
-                break;
-            }
-        }
-    }
-}
-
-void 
+void
 i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state, void *h264_context)
 {
     struct i965_h264_context *i965_h264_context = (struct i965_h264_context *)h264_context;
@@ -986,7 +797,8 @@ i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state, v
 
     assert(decode_state->pic_param && decode_state->pic_param->buffer);
     pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
-    i965_avc_bsd_frame_store_index(ctx, pic_param, i965_h264_context);
+    intel_update_avc_frame_store_index(ctx, decode_state, pic_param,
+                                       i965_h264_context->fsid_list, &i965_h264_context->fs_ctx);
 
     i965_h264_context->enable_avc_ildb = 0;
     i965_h264_context->picture.i_flag = 1;
@@ -1031,13 +843,13 @@ i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state, v
                    (slice_param->slice_type == SLICE_TYPE_SP) ||
                    (slice_param->slice_type == SLICE_TYPE_B));
 
-            if (i965_h264_context->picture.i_flag && 
-                (slice_param->slice_type != SLICE_TYPE_I ||
+            if (i965_h264_context->picture.i_flag &&
+                (slice_param->slice_type != SLICE_TYPE_I &&
                  slice_param->slice_type != SLICE_TYPE_SI))
                 i965_h264_context->picture.i_flag = 0;
 
             i965_avc_bsd_slice_state(ctx, pic_param, slice_param, i965_h264_context);
-            i965_avc_bsd_buf_base_state(ctx, pic_param, slice_param, i965_h264_context);
+            i965_avc_bsd_buf_base_state(ctx, decode_state, pic_param, slice_param, i965_h264_context);
             i965_avc_bsd_object(ctx, decode_state, pic_param, slice_param, j, i965_h264_context);
             slice_param++;
         }
@@ -1049,7 +861,7 @@ i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state, v
     intel_batchbuffer_flush(batch);
 }
 
-void 
+void
 i965_avc_bsd_decode_init(VADriverContextP ctx, void *h264_context)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);
@@ -1077,7 +889,7 @@ i965_avc_bsd_decode_init(VADriverContextP ctx, void *h264_context)
     i965_avc_bsd_context->mpr_row_store.bo = bo;
 }
 
-Bool 
+Bool
 i965_avc_bsd_ternimate(struct i965_avc_bsd_context *i965_avc_bsd_context)
 {
     dri_bo_unreference(i965_avc_bsd_context->bsd_raw_store.bo);