i965_drv_video: [H.264] track frame store index
authorXiang, Haihao <haihao.xiang@intel.com>
Wed, 14 Apr 2010 07:14:50 +0000 (15:14 +0800)
committerXiang, Haihao <haihao.xiang@intel.com>
Wed, 14 Apr 2010 07:14:50 +0000 (15:14 +0800)
i965_avc_bsd.c
i965_media_h264.c
i965_media_h264.h
intel_driver.h

index 1c8da31..3017bb2 100644 (file)
@@ -306,16 +306,15 @@ i965_avc_bsd_slice_state(VADriverContextP ctx,
             } else {
                 int frame_idx;
                 
-                for (frame_idx = 0; frame_idx < 16; frame_idx++) {
-                    VAPictureH264 *ref_pic = &pic_param->ReferenceFrames[frame_idx];
-                    
-                    if (!(ref_pic->flags & VA_PICTURE_H264_INVALID)) {
-                        if (ref_pic->picture_id == va_pic->picture_id)
-                            break;
-                    }       
+                for (frame_idx = 0; frame_idx < ARRAY_ELEMS(i965_h264_context->fsid_list); frame_idx++) {
+                    if (i965_h264_context->fsid_list[frame_idx].surface_id != VA_INVALID_ID &&
+                        va_pic->picture_id == i965_h264_context->fsid_list[frame_idx].surface_id) {
+                        assert(frame_idx == i965_h264_context->fsid_list[frame_idx].frame_store_id);
+                        break;
+                    }
                 }
-                
-                assert(frame_idx < 16);
+
+                assert(frame_idx < ARRAY_ELEMS(i965_h264_context->fsid_list));
                 
                 refs[j].non_exist = 0;
                 refs[j].long_term = !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE);
@@ -411,7 +410,7 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
     struct i965_media_state *media_state = &i965->media_state;
     struct i965_h264_context *i965_h264_context;
     struct i965_avc_bsd_context *i965_avc_bsd_context;
-    int i;
+    int i, j;
     VAPictureH264 *va_pic;
     struct object_surface *obj_surface;
     struct i965_avc_bsd_surface *avc_bsd_surface;
@@ -438,33 +437,48 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
                   I915_GEM_DOMAIN_INSTRUCTION, I915_GEM_DOMAIN_INSTRUCTION,
                   0);
 
-    for (i = 0; i < 16; i++) {
-        va_pic = &pic_param->ReferenceFrames[i];
+    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->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(ctx, 0);
-                OUT_BCS_BATCH(ctx, 0);
-            } else {
-                assert(avc_bsd_surface->direct_mv_flag != -1);
+                if (va_pic->picture_id == i965_h264_context->fsid_list[i].surface_id) {
+                    found = 1;
+                    break;
+                }
+            }
 
-                OUT_BCS_RELOC(ctx, avc_bsd_surface->direct_mv_wr_top_bo,
-                              I915_GEM_DOMAIN_INSTRUCTION, 0,
-                              0);
+            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(ctx, 0);
+                    OUT_BCS_BATCH(ctx, 0);
+                } else {
+                    assert(avc_bsd_surface->direct_mv_flag != -1);
 
-                if (avc_bsd_surface->direct_mv_flag == 1)
-                    OUT_BCS_RELOC(ctx, avc_bsd_surface->direct_mv_wr_bottom_bo,
-                                  I915_GEM_DOMAIN_INSTRUCTION, 0,
-                                  0);
-                else
                     OUT_BCS_RELOC(ctx, avc_bsd_surface->direct_mv_wr_top_bo,
                                   I915_GEM_DOMAIN_INSTRUCTION, 0,
                                   0);
-            }
+
+                    if (avc_bsd_surface->direct_mv_flag == 1)
+                        OUT_BCS_RELOC(ctx, avc_bsd_surface->direct_mv_wr_bottom_bo,
+                                      I915_GEM_DOMAIN_INSTRUCTION, 0,
+                                      0);
+                    else
+                        OUT_BCS_RELOC(ctx, avc_bsd_surface->direct_mv_wr_top_bo,
+                                      I915_GEM_DOMAIN_INSTRUCTION, 0,
+                                      0);
+                }
+            } 
         } else {
             OUT_BCS_BATCH(ctx, 0);
             OUT_BCS_BATCH(ctx, 0);
@@ -494,11 +508,27 @@ i965_avc_bsd_buf_base_state(VADriverContextP ctx,
                       0);
 
     /* POC List */
-    for (i = 0; i < 16; i++) {
-        va_pic = &pic_param->ReferenceFrames[i];
-        if (!(va_pic->flags & VA_PICTURE_H264_INVALID)) {
-            OUT_BCS_BATCH(ctx, va_pic->TopFieldOrderCnt);
-            OUT_BCS_BATCH(ctx, va_pic->BottomFieldOrderCnt);
+    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)) {
+                OUT_BCS_BATCH(ctx, va_pic->TopFieldOrderCnt);
+                OUT_BCS_BATCH(ctx, va_pic->BottomFieldOrderCnt);
+            } 
         } else {
             OUT_BCS_BATCH(ctx, 0);
             OUT_BCS_BATCH(ctx, 0);
@@ -801,6 +831,106 @@ i965_avc_bsd_phantom_slice(VADriverContextP ctx,
     i965_avc_bsd_object(ctx, decode_state, pic_param, NULL);
 }
 
+static void
+i965_avc_bsd_frame_store_index(VADriverContextP ctx,
+                               VAPictureParameterBufferH264 *pic_param)
+{
+    struct i965_driver_data *i965 = i965_driver_data(ctx);
+    struct i965_media_state *media_state = &i965->media_state;
+    struct i965_h264_context *i965_h264_context = (struct i965_h264_context *)media_state->private_context;
+    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) {
+            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;
+            
+            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)
 {
@@ -810,6 +940,7 @@ i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state)
 
     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);
     intel_batchbuffer_start_atomic_bcs(ctx, 0x1000);
 
     i965_avc_bsd_img_state(ctx, decode_state);
index 24c43fd..fe8c219 100644 (file)
@@ -344,12 +344,17 @@ i965_media_h264_surfaces_setup(VADriverContextP ctx,
                                struct decode_state *decode_state)
 {
     struct i965_driver_data *i965 = i965_driver_data(ctx);  
+    struct i965_media_state *media_state = &i965->media_state;
+    struct i965_h264_context *i965_h264_context;
     struct object_surface *obj_surface;
     VAPictureParameterBufferH264 *pic_param;
     VAPictureH264 *va_pic;
-    int i, w, h;
+    int i, j, w, h;
     int field_picture;
 
+    assert(media_state->private_context);
+    i965_h264_context = (struct i965_h264_context *)media_state->private_context;
+
     assert(decode_state->pic_param && decode_state->pic_param->buffer);
     pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer;
 
@@ -375,10 +380,23 @@ i965_media_h264_surfaces_setup(VADriverContextP ctx,
                                   I965_SURFACEFORMAT_R8G8_SINT);  /* INTERLEAVED U/V */
 
     /* Reference Pictures */
-    for (i = 0; i < 16; i++) {
-        va_pic = &pic_param->ReferenceFrames[i];
+    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);
             w = obj_surface->width;
@@ -851,6 +869,11 @@ i965_media_h264_init(VADriverContextP ctx)
         dri_bo_subdata(kernel->bo, 0, kernel->size, kernel->bin);
     }
 
+    for (i = 0; i < 16; i++) {
+        i965_h264_context->fsid_list[i].surface_id = VA_INVALID_ID;
+        i965_h264_context->fsid_list[i].frame_store_id = -1;
+    }
+
     media_state->private_context = i965_h264_context;
     return True;
 }
index 3001b2e..4df37a4 100644 (file)
@@ -43,6 +43,10 @@ struct i965_h264_context
 
     struct i965_avc_bsd_context i965_avc_bsd_context;
     struct i965_avc_hw_scoreboard_context avc_hw_scoreboard_context;
+    struct {
+        VASurfaceID surface_id;
+        int frame_store_id;
+    } fsid_list[16];
 };
 
 Bool i965_media_h264_init(VADriverContextP ctx);
index 7fcb760..e7cbaaa 100644 (file)
@@ -45,6 +45,7 @@ struct intel_batchbuffer;
 #define ALIGN(i, n)    (((i) + (n) - 1) & ~((n) - 1))
 #define MIN(a, b) ((a) < (b) ? (a) : (b))
 #define MAX(a, b) ((a) > (b) ? (a) : (b))
+#define ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
 
 #define SET_BLOCKED_SIGSET()   do {     \
         sigset_t bl_mask;               \