From 85ea7684cc3e4e6caee7c20f8e2a21ddd089ff9d Mon Sep 17 00:00:00 2001 From: "Xiang, Haihao" Date: Tue, 6 Apr 2010 15:06:45 +0800 Subject: [PATCH] i965_drv_video: multiple slices in a picture for H.264 --- i965_drv_video/i965_avc_bsd.c | 54 ++++++++++++++++---------------- i965_drv_video/i965_drv_video.c | 65 +++++++++++++++++++++++++++++++-------- i965_drv_video/i965_drv_video.h | 12 ++++++-- i965_drv_video/i965_media_h264.c | 8 ++--- i965_drv_video/i965_media_mpeg2.c | 47 +++++++++++++++------------- 5 files changed, 118 insertions(+), 68 deletions(-) diff --git a/i965_drv_video/i965_avc_bsd.c b/i965_drv_video/i965_avc_bsd.c index d9a45b7..80d26d4 100644 --- a/i965_drv_video/i965_avc_bsd.c +++ b/i965_drv_video/i965_avc_bsd.c @@ -85,9 +85,9 @@ i965_avc_bsd_initialize_private_surface_data(VADriverContextP ctx, struct object } static void -i965_bsd_ind_obj_base_address(VADriverContextP ctx, struct decode_state *decode_state) +i965_bsd_ind_obj_base_address(VADriverContextP ctx, struct decode_state *decode_state, int slice) { - dri_bo *ind_bo = decode_state->slice_data->bo; + dri_bo *ind_bo = decode_state->slice_datas[slice]->bo; BEGIN_BCS_BATCH(ctx, 3); OUT_BCS_BATCH(ctx, CMD_BSD_IND_OBJ_BASE_ADDR | (3 - 2)); @@ -401,21 +401,19 @@ i965_avc_bsd_slice_state(VADriverContextP ctx, } static void -i965_avc_bsd_buf_base_state(VADriverContextP ctx, struct decode_state *decode_state) +i965_avc_bsd_buf_base_state(VADriverContextP ctx, + VAPictureParameterBufferH264 *pic_param, + VASliceParameterBufferH264 *slice_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_avc_bsd_context *i965_avc_bsd_context; int i; - VAPictureParameterBufferH264 *pic_param; VAPictureH264 *va_pic; struct object_surface *obj_surface; struct i965_avc_bsd_surface *avc_bsd_surface; - assert(decode_state->pic_param && decode_state->pic_param->buffer); - pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer; - assert(media_state->private_context); i965_h264_context = (struct i965_h264_context *)media_state->private_context; i965_avc_bsd_context = &i965_h264_context->i965_avc_bsd_context; @@ -770,34 +768,36 @@ i965_avc_bsd_phantom_slice(VADriverContextP ctx, void i965_avc_bsd_pipeline(VADriverContextP ctx, struct decode_state *decode_state) { - int i; + int i, j; VAPictureParameterBufferH264 *pic_param; VASliceParameterBufferH264 *slice_param; assert(decode_state->pic_param && decode_state->pic_param->buffer); pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer; - assert(decode_state->slice_param && decode_state->slice_param->buffer); - slice_param = (VASliceParameterBufferH264 *)decode_state->slice_param->buffer; - intel_batchbuffer_start_atomic_bcs(ctx, 0x1000); - i965_bsd_ind_obj_base_address(ctx, decode_state); - - assert(decode_state->num_slices == 1); /* FIXME: */ - for (i = 0; i < decode_state->num_slices; i++) { - assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL); - assert((slice_param->slice_type == SLICE_TYPE_I) || - (slice_param->slice_type == SLICE_TYPE_P) || - (slice_param->slice_type == SLICE_TYPE_B)); /* hardware requirement */ - - if (i == 0) { - i965_avc_bsd_img_state(ctx, decode_state); - i965_avc_bsd_qm_state(ctx, decode_state); + + i965_avc_bsd_img_state(ctx, decode_state); + i965_avc_bsd_qm_state(ctx, decode_state); + + for (j = 0; j < decode_state->num_slice_params; j++) { + assert(decode_state->slice_params && decode_state->slice_params[j]->buffer); + slice_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j]->buffer; + + i965_bsd_ind_obj_base_address(ctx, decode_state, j); + + assert(decode_state->slice_params[j]->num_elements == 1); /* FIXME */ + for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) { + assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL); + assert((slice_param->slice_type == SLICE_TYPE_I) || + (slice_param->slice_type == SLICE_TYPE_P) || + (slice_param->slice_type == SLICE_TYPE_B)); /* hardware requirement */ + + i965_avc_bsd_slice_state(ctx, pic_param, slice_param); + i965_avc_bsd_buf_base_state(ctx, pic_param, slice_param); + i965_avc_bsd_object(ctx, decode_state, pic_param, slice_param); + slice_param++; } - i965_avc_bsd_slice_state(ctx, pic_param, slice_param); - i965_avc_bsd_buf_base_state(ctx, decode_state); - i965_avc_bsd_object(ctx, decode_state, pic_param, slice_param); - slice_param++; } i965_avc_bsd_phantom_slice(ctx, decode_state, pic_param); diff --git a/i965_drv_video/i965_drv_video.c b/i965_drv_video/i965_drv_video.c index e0b5ee4..c902834 100644 --- a/i965_drv_video/i965_drv_video.c +++ b/i965_drv_video/i965_drv_video.c @@ -632,12 +632,23 @@ static void i965_destroy_context(struct object_heap *heap, struct object_base *obj) { struct object_context *obj_context = (struct object_context *)obj; + int i; + + assert(obj_context->decode_state.num_slice_params <= obj_context->decode_state.max_slice_params); + assert(obj_context->decode_state.num_slice_datas <= obj_context->decode_state.max_slice_datas); i965_release_buffer_store(&obj_context->decode_state.pic_param); - i965_release_buffer_store(&obj_context->decode_state.slice_param); i965_release_buffer_store(&obj_context->decode_state.iq_matrix); i965_release_buffer_store(&obj_context->decode_state.bit_plane); - i965_release_buffer_store(&obj_context->decode_state.slice_data); + + for (i = 0; i < obj_context->decode_state.num_slice_params; i++) + i965_release_buffer_store(&obj_context->decode_state.slice_params[i]); + + for (i = 0; i < obj_context->decode_state.num_slice_datas; i++) + i965_release_buffer_store(&obj_context->decode_state.slice_datas[i]); + + free(obj_context->decode_state.slice_params); + free(obj_context->decode_state.slice_datas); free(obj_context->render_targets); object_heap_free(heap, obj); } @@ -678,6 +689,12 @@ i965_CreateContext(VADriverContextP ctx, *context = contextID; memset(&obj_context->decode_state, 0, sizeof(obj_context->decode_state)); obj_context->decode_state.current_render_target = -1; + obj_context->decode_state.max_slice_params = NUM_SLICES; + obj_context->decode_state.max_slice_datas = NUM_SLICES; + obj_context->decode_state.slice_params = calloc(obj_context->decode_state.max_slice_params, + sizeof(*obj_context->decode_state.slice_params)); + obj_context->decode_state.slice_datas = calloc(obj_context->decode_state.max_slice_datas, + sizeof(*obj_context->decode_state.slice_datas)); obj_context->config_id = config_id; obj_context->picture_width = picture_width; obj_context->picture_height = picture_height; @@ -791,6 +808,7 @@ i965_CreateBuffer(VADriverContextP ctx, memcpy(buffer_store->buffer, data, size * num_elements); } + buffer_store->num_elements = obj_buffer->num_elements; i965_reference_buffer_store(&obj_buffer->buffer_store, buffer_store); i965_release_buffer_store(&buffer_store); *buf_id = bufferID; @@ -971,10 +989,18 @@ i965_render_slice_parameter_buffer(VADriverContextP ctx, { assert(obj_buffer->buffer_store->bo == NULL); assert(obj_buffer->buffer_store->buffer); - i965_release_buffer_store(&obj_context->decode_state.slice_param); - i965_reference_buffer_store(&obj_context->decode_state.slice_param, + + if (obj_context->decode_state.num_slice_params == obj_context->decode_state.max_slice_params) { + obj_context->decode_state.slice_params = realloc(obj_context->decode_state.slice_params, + (obj_context->decode_state.max_slice_params + NUM_SLICES) * sizeof(*obj_context->decode_state.slice_params)); + memset(obj_context->decode_state.slice_params + obj_context->decode_state.max_slice_params, 0, NUM_SLICES * sizeof(*obj_context->decode_state.slice_params)); + obj_context->decode_state.max_slice_params += NUM_SLICES; + } + + i965_release_buffer_store(&obj_context->decode_state.slice_params[obj_context->decode_state.num_slice_params]); + i965_reference_buffer_store(&obj_context->decode_state.slice_params[obj_context->decode_state.num_slice_params], obj_buffer->buffer_store); - obj_context->decode_state.num_slices = obj_buffer->num_elements; + obj_context->decode_state.num_slice_params++; return VA_STATUS_SUCCESS; } @@ -986,9 +1012,18 @@ i965_render_slice_data_buffer(VADriverContextP ctx, { assert(obj_buffer->buffer_store->buffer == NULL); assert(obj_buffer->buffer_store->bo); - i965_release_buffer_store(&obj_context->decode_state.slice_data); - i965_reference_buffer_store(&obj_context->decode_state.slice_data, + + if (obj_context->decode_state.num_slice_datas == obj_context->decode_state.max_slice_datas) { + obj_context->decode_state.slice_datas = realloc(obj_context->decode_state.slice_datas, + (obj_context->decode_state.max_slice_datas + NUM_SLICES) * sizeof(*obj_context->decode_state.slice_datas)); + memset(obj_context->decode_state.slice_datas + obj_context->decode_state.max_slice_datas, 0, NUM_SLICES * sizeof(*obj_context->decode_state.slice_datas)); + obj_context->decode_state.max_slice_datas += NUM_SLICES; + } + + i965_release_buffer_store(&obj_context->decode_state.slice_datas[obj_context->decode_state.num_slice_datas]); + i965_reference_buffer_store(&obj_context->decode_state.slice_datas[obj_context->decode_state.num_slice_datas], obj_buffer->buffer_store); + obj_context->decode_state.num_slice_datas++; return VA_STATUS_SUCCESS; } @@ -1048,11 +1083,13 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context) struct object_context *obj_context = CONTEXT(context); struct object_config *obj_config; VAContextID config; + int i; assert(obj_context); assert(obj_context->decode_state.pic_param); - assert(obj_context->decode_state.slice_param); - assert(obj_context->decode_state.slice_data); + assert(obj_context->decode_state.num_slice_params >= 1); + assert(obj_context->decode_state.num_slice_datas >= 1); + assert(obj_context->decode_state.num_slice_params == obj_context->decode_state.num_slice_datas); config = obj_context->config_id; obj_config = CONFIG(config); @@ -1071,12 +1108,16 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context) i965_media_decode_picture(ctx, obj_config->profile, &obj_context->decode_state); obj_context->decode_state.current_render_target = -1; - obj_context->decode_state.num_slices = 0; + obj_context->decode_state.num_slice_params = 0; + obj_context->decode_state.num_slice_datas = 0; i965_release_buffer_store(&obj_context->decode_state.pic_param); - i965_release_buffer_store(&obj_context->decode_state.slice_param); i965_release_buffer_store(&obj_context->decode_state.iq_matrix); i965_release_buffer_store(&obj_context->decode_state.bit_plane); - i965_release_buffer_store(&obj_context->decode_state.slice_data); + + for (i = 0; i < obj_context->decode_state.num_slice_params; i++) { + i965_release_buffer_store(&obj_context->decode_state.slice_params[i]); + i965_release_buffer_store(&obj_context->decode_state.slice_datas[i]); + } return VA_STATUS_SUCCESS; } diff --git a/i965_drv_video/i965_drv_video.h b/i965_drv_video/i965_drv_video.h index b7e02a5..33b46f3 100644 --- a/i965_drv_video/i965_drv_video.h +++ b/i965_drv_video/i965_drv_video.h @@ -53,6 +53,7 @@ struct buffer_store unsigned char *buffer; dri_bo *bo; int ref_count; + int num_elements; }; struct object_config @@ -64,15 +65,20 @@ struct object_config int num_attribs; }; +#define NUM_SLICES 10 + struct decode_state { struct buffer_store *pic_param; - struct buffer_store *slice_param; + struct buffer_store **slice_params; struct buffer_store *iq_matrix; struct buffer_store *bit_plane; - struct buffer_store *slice_data; + struct buffer_store **slice_datas; VASurfaceID current_render_target; - int num_slices; + int max_slice_params; + int max_slice_datas; + int num_slice_params; + int num_slice_datas; }; struct object_context diff --git a/i965_drv_video/i965_media_h264.c b/i965_drv_video/i965_media_h264.c index c1b5626..841b777 100644 --- a/i965_drv_video/i965_media_h264.c +++ b/i965_drv_video/i965_media_h264.c @@ -517,8 +517,8 @@ i965_media_h264_vfe_state_extension(VADriverContextP ctx, assert(decode_state->pic_param && decode_state->pic_param->buffer); pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer; - assert(decode_state->slice_param && decode_state->slice_param->buffer); - slice_param = (VASliceParameterBufferH264 *)decode_state->slice_param->buffer; + assert(decode_state->slice_params[0] && decode_state->slice_params[0]->buffer); + slice_param = (VASliceParameterBufferH264 *)decode_state->slice_params[0]->buffer; mbaff_frame_flag = (pic_param->seq_fields.bits.mb_adaptive_frame_field_flag && !pic_param->pic_fields.bits.field_pic_flag); @@ -651,8 +651,8 @@ i965_media_h264_upload_constants(VADriverContextP ctx, struct decode_state *deco assert(media_state->private_context); i965_h264_context = (struct i965_h264_context *)media_state->private_context; - assert(decode_state->slice_param && decode_state->slice_param->buffer); - slice_param = (VASliceParameterBufferH264 *)decode_state->slice_param->buffer; + assert(decode_state->slice_params[0] && decode_state->slice_params[0]->buffer); + slice_param = (VASliceParameterBufferH264 *)decode_state->slice_params[0]->buffer; dri_bo_map(media_state->curbe.bo, 1); assert(media_state->curbe.bo->virtual); diff --git a/i965_drv_video/i965_media_mpeg2.c b/i965_drv_video/i965_media_mpeg2.c index eaed1e9..c966904 100644 --- a/i965_drv_video/i965_media_mpeg2.c +++ b/i965_drv_video/i965_media_mpeg2.c @@ -851,30 +851,33 @@ i965_media_mpeg2_states_setup(VADriverContextP ctx, struct decode_state *decode_ static void i965_media_mpeg2_objects(VADriverContextP ctx, struct decode_state *decode_state) { - int i; + int i, j; VASliceParameterBufferMPEG2 *slice_param; - assert(decode_state->slice_param && decode_state->slice_param->buffer); - slice_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_param->buffer; - - for (i = 0; i < decode_state->num_slices; i++) { - assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL); - - BEGIN_BATCH(ctx, 6); - OUT_BATCH(ctx, CMD_MEDIA_OBJECT | 4); - OUT_BATCH(ctx, 0); - OUT_BATCH(ctx, slice_param->slice_data_size - (slice_param->macroblock_offset >> 3)); - OUT_RELOC(ctx, decode_state->slice_data->bo, - I915_GEM_DOMAIN_SAMPLER, 0, - slice_param->slice_data_offset + (slice_param->macroblock_offset >> 3)); - OUT_BATCH(ctx, - ((slice_param->slice_horizontal_position << 24) | - (slice_param->slice_vertical_position << 16) | - (127 << 8) | - (slice_param->macroblock_offset & 0x7))); - OUT_BATCH(ctx, slice_param->quantiser_scale_code << 24); - ADVANCE_BATCH(ctx); - slice_param++; + for (j = 0; j < decode_state->num_slice_params; j++) { + assert(decode_state->slice_params[j] && decode_state->slice_params[j]->buffer); + assert(decode_state->slice_datas[j] && decode_state->slice_datas[j]->bo); + slice_param = (VASliceParameterBufferMPEG2 *)decode_state->slice_params[j]->buffer; + + for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) { + assert(slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL); + + BEGIN_BATCH(ctx, 6); + OUT_BATCH(ctx, CMD_MEDIA_OBJECT | 4); + OUT_BATCH(ctx, 0); + OUT_BATCH(ctx, slice_param->slice_data_size - (slice_param->macroblock_offset >> 3)); + OUT_RELOC(ctx, decode_state->slice_datas[j]->bo, + I915_GEM_DOMAIN_SAMPLER, 0, + slice_param->slice_data_offset + (slice_param->macroblock_offset >> 3)); + OUT_BATCH(ctx, + ((slice_param->slice_horizontal_position << 24) | + (slice_param->slice_vertical_position << 16) | + (127 << 8) | + (slice_param->macroblock_offset & 0x7))); + OUT_BATCH(ctx, slice_param->quantiser_scale_code << 24); + ADVANCE_BATCH(ctx); + slice_param++; + } } } -- 2.7.4