decoder: h264: fix frame store logic for MVC.
[platform/upstream/libva-intel-driver.git] / src / i965_avc_bsd.c
index 8921275..ebeb2a6 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"
@@ -54,6 +51,7 @@ i965_avc_bsd_init_avc_bsd_surface(VADriverContextP ctx,
 
     if (!avc_bsd_surface) {
         avc_bsd_surface = calloc(sizeof(GenAvcSurface), 1);
+        avc_bsd_surface->frame_store_id = -1;
         assert((obj_surface->size & 0x3f) == 0);
         obj_surface->private_data = avc_bsd_surface;
     }
@@ -118,8 +116,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)
@@ -376,14 +372,14 @@ i965_avc_bsd_slice_state(VADriverContextP ctx,
 
 static void
 i965_avc_bsd_buf_base_state(VADriverContextP ctx,
+                            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;
     GenAvcSurface *avc_bsd_surface;
@@ -413,45 +409,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;
+        obj_surface = i965_h264_context->fsid_list[i].obj_surface;
+        if (obj_surface && obj_surface->private_data) {
+            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);
-                }
-            } 
+            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);
@@ -459,12 +432,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;
 
@@ -483,26 +467,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);
@@ -516,35 +490,6 @@ 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, 
                    struct decode_state *decode_state,
@@ -563,11 +508,10 @@ 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? */
 
@@ -577,12 +521,12 @@ g4x_avc_bsd_object(VADriverContextP ctx,
         } 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)
@@ -652,7 +596,7 @@ g4x_avc_bsd_object(VADriverContextP ctx,
                       (slice_hor_pos << 16) | 
                       (first_mb_in_slice << 0));
         OUT_BCS_BATCH(batch, 
-                      (0 << 7) | /* FIXME: ??? */
+                      (1 << 7) |
                       ((0x7 - (slice_data_bit_offset & 0x7)) << 0));
 
         if (encrypted) {
@@ -692,11 +636,10 @@ 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? */
 
@@ -705,12 +648,11 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
         } 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)
@@ -782,7 +724,7 @@ ironlake_avc_bsd_object(VADriverContextP ctx,
                       (slice_hor_pos << 16) | 
                       (first_mb_in_slice << 0));
         OUT_BCS_BATCH(batch, 
-                      (0 << 7) | /* FIXME: ??? */
+                      (1 << 7) |
                       ((0x7 - (slice_data_bit_offset & 0x7)) << 0));
         OUT_BCS_BATCH(batch, counter_value);
         
@@ -828,7 +770,7 @@ 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);
@@ -843,120 +785,6 @@ 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 
 i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state, void *h264_context)
 {
@@ -968,7 +796,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;
@@ -1019,7 +848,7 @@ i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state, v
                 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++;
         }