From 9ce46e9daf04e237dc4d2e367f2a9f8167784b4b Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Wed, 14 Apr 2010 15:14:50 +0800 Subject: [PATCH] i965_drv_video: [H.264] track frame store index --- i965_drv_video/i965_avc_bsd.c | 203 ++++++++++++++++++++++++++++++++------- i965_drv_video/i965_media_h264.c | 31 +++++- i965_drv_video/i965_media_h264.h | 4 + i965_drv_video/intel_driver.h | 1 + 4 files changed, 199 insertions(+), 40 deletions(-) diff --git a/i965_drv_video/i965_avc_bsd.c b/i965_drv_video/i965_avc_bsd.c index 1c8da31..3017bb2 100644 --- a/i965_drv_video/i965_avc_bsd.c +++ b/i965_drv_video/i965_avc_bsd.c @@ -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); diff --git a/i965_drv_video/i965_media_h264.c b/i965_drv_video/i965_media_h264.c index 24c43fd..fe8c219 100644 --- a/i965_drv_video/i965_media_h264.c +++ b/i965_drv_video/i965_media_h264.c @@ -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; } diff --git a/i965_drv_video/i965_media_h264.h b/i965_drv_video/i965_media_h264.h index 3001b2e..4df37a4 100644 --- a/i965_drv_video/i965_media_h264.h +++ b/i965_drv_video/i965_media_h264.h @@ -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); diff --git a/i965_drv_video/intel_driver.h b/i965_drv_video/intel_driver.h index 7fcb760..e7cbaaa 100644 --- a/i965_drv_video/intel_driver.h +++ b/i965_drv_video/intel_driver.h @@ -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; \ -- 2.7.4