diff options
Diffstat (limited to 'src/psb_H264.c')
-rwxr-xr-x[-rw-r--r--] | src/psb_H264.c | 88 |
1 files changed, 55 insertions, 33 deletions
diff --git a/src/psb_H264.c b/src/psb_H264.c index 62243c4..1a3889c 100644..100755 --- a/src/psb_H264.c +++ b/src/psb_H264.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2011 Intel Corporation. All Rights Reserved. - * Copyright (c) Imagination Technologies Limited, UK + * Copyright (c) Imagination Technologies Limited, UK * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the @@ -9,11 +9,11 @@ * distribute, sub license, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: - * + * * The above copyright notice and this permission notice (including the * next paragraph) shall be included in all copies or substantial portions * of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. @@ -54,6 +54,8 @@ #define SET_SURFACE_INFO_dpb_idx(psb_surface, val) psb_surface->extra_info[2] = val; #define GET_SURFACE_INFO_colocated_index(psb_surface) ((int) (psb_surface->extra_info[3])) #define SET_SURFACE_INFO_colocated_index(psb_surface, val) psb_surface->extra_info[3] = (uint32_t) val; +#define SET_SURFACE_INFO_rotate(psb_surface, rotate) psb_surface->extra_info[5] = (uint32_t) rotate; +#define GET_SURFACE_INFO_rotate(psb_surface) ((int) psb_surface->extra_info[5]) #define IS_USED_AS_REFERENCE(pic_flags) ( pic_flags & (VA_PICTURE_H264_SHORT_TERM_REFERENCE | VA_PICTURE_H264_LONG_TERM_REFERENCE) ) @@ -468,7 +470,7 @@ static VAStatus psb_H264_CreateContext( DEBUG_FAILURE; } if (vaStatus == VA_STATUS_SUCCESS) { - void *vlc_packed_data_address; + unsigned char *vlc_packed_data_address; if (0 == psb_buffer_map(&ctx->vlc_packed_table, &vlc_packed_data_address)) { memcpy(vlc_packed_data_address, ui16H264VLCTableData, sizeof(ui16H264VLCTableData)); psb_buffer_unmap(&ctx->vlc_packed_table); @@ -555,8 +557,6 @@ static VAStatus psb__H264_allocate_colocated_buffer(context_H264_p ctx, object_s { psb_surface_p surface = obj_surface->psb_surface; - psb__information_message("psb_H264: Allocating colocated buffer for surface %08x size = %08x\n", surface, size); - if (!GET_SURFACE_INFO_colocated_index(surface)) { VAStatus vaStatus; psb_buffer_p buf; @@ -564,6 +564,8 @@ static VAStatus psb__H264_allocate_colocated_buffer(context_H264_p ctx, object_s if (index >= ctx->colocated_buffers_size) { return VA_STATUS_ERROR_UNKNOWN; } + psb__information_message("psb_H264: Allocating colocated buffer for surface %08x size = %08x\n", surface, size); + buf = &(ctx->colocated_buffers[index]); vaStatus = psb_buffer_create(ctx->obj_context->driver_data, size, psb_bt_vpu_only, buf); if (VA_STATUS_SUCCESS != vaStatus) { @@ -577,11 +579,12 @@ static VAStatus psb__H264_allocate_colocated_buffer(context_H264_p ctx, object_s static psb_buffer_p psb__H264_lookup_colocated_buffer(context_H264_p ctx, psb_surface_p surface) { - psb__information_message("psb_H264: Looking up colocated buffer for surface %08x\n", surface); + /* psb__information_message("psb_H264: Looking up colocated buffer for surface %08x\n", surface); */ int index = GET_SURFACE_INFO_colocated_index(surface); if (!index) { return NULL; } + return &(ctx->colocated_buffers[index-1]); /* 0 means unset, index is offset by 1 */ } @@ -621,7 +624,9 @@ static VAStatus psb__H264_process_picture_param(context_H264_p ctx, object_buffe if ((obj_buffer->num_elements != 1) || (obj_buffer->size != sizeof(VAPictureParameterBufferH264)) || - (NULL == target_surface)) { + (NULL == target_surface) || + (NULL == obj_buffer->buffer_data)) { + psb__error_message("picture parameter buffer is not valid.\n"); return VA_STATUS_ERROR_UNKNOWN; } @@ -662,7 +667,10 @@ static VAStatus psb__H264_process_picture_param(context_H264_p ctx, object_buffe ctx->size_mb = ctx->picture_width_mb * ctx->picture_height_mb; /* (7-25) */ //uint32_t colocated_size = (ctx->picture_width_mb + extra_size) * (ctx->picture_height_mb + extra_size) * 192; - uint32_t colocated_size = ((ctx->size_mb + 100) * 128 + 0xfff) & ~0xfff; + /*for resolution change feature, need allocat co-located buffer according the size of surface*/ + uint32_t size_mb = ((ctx->obj_context->current_render_target->width + 15) / 16) * + ((ctx->obj_context->current_render_target->height + 15) / 16); + uint32_t colocated_size = ((size_mb + 100) * 128 + 0xfff) & ~0xfff; vaStatus = psb__H264_allocate_colocated_buffer(ctx, ctx->obj_context->current_render_target, colocated_size); if (VA_STATUS_SUCCESS != vaStatus) { @@ -777,7 +785,9 @@ static VAStatus psb__H264_process_iq_matrix(context_H264_p ctx, object_buffer_p ASSERT(obj_buffer->size == sizeof(VAIQMatrixBufferH264)); if ((obj_buffer->num_elements != 1) || - (obj_buffer->size != sizeof(VAIQMatrixBufferH264))) { + (obj_buffer->size != sizeof(VAIQMatrixBufferH264)) || + (NULL == obj_buffer->buffer_data)) { + psb__error_message("iq matrix buffer is not valid.\n"); return VA_STATUS_ERROR_UNKNOWN; } @@ -798,7 +808,8 @@ static VAStatus psb__H264_process_slice_group_map(context_H264_p ctx, object_buf ASSERT(obj_buffer->num_elements == 1); // ASSERT(obj_buffer->size == ...); - if (obj_buffer->num_elements != 1) { + if ((obj_buffer->num_elements != 1) || + (NULL == obj_buffer->psb_buffer)) { return VA_STATUS_ERROR_UNKNOWN; } @@ -1040,7 +1051,7 @@ static void psb__H264_setup_alternative_frame(context_H264_p ctx) psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate; object_context_p obj_context = ctx->obj_context; - if (rotate_surface->extra_info[5] != obj_context->rotate) + if (GET_SURFACE_INFO_rotate(rotate_surface) != obj_context->msvdx_rotate) psb__error_message("Display rotate mode does not match surface rotate mode!\n"); @@ -1058,7 +1069,7 @@ static void psb__H264_setup_alternative_frame(context_H264_p ctx) REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ALT_PICTURE_ENABLE, 1); REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_ROW_STRIDE, rotate_surface->stride_mode); REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */ - REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_MODE, rotate_surface->extra_info[5]); + REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_MODE, GET_SURFACE_INFO_rotate(rotate_surface)); psb_cmdbuf_rendec_write(cmdbuf, cmd); @@ -1072,7 +1083,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; VAPictureParameterBufferH264 *pic_params = ctx->pic_params; uint32_t reg_value; - int i; + unsigned int i; psb_cmdbuf_rendec_start_block(cmdbuf); @@ -1115,7 +1126,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu psb_cmdbuf_rendec_end_chunk(cmdbuf); -#warning "TODO: MUST be done after fe slice1 (which gives MB address) " + //#warning "TODO: MUST be done after fe slice1 (which gives MB address) " /* REGIO_WRITE_REGISTER(0, MSVDX_VEC_H264, CR_VEC_H264_FE_BASE_ADDR_SGM, gui32SliceGroupType6BaseAddressHack); */ /* CHUNK: SCA */ @@ -1142,8 +1153,8 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu if (slice_param->slice_type == ST_B || slice_param->slice_type == ST_P) { psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_LIST0)); - if (slice_param->num_ref_idx_l0_active_minus1 > (32 - 4)) { - psb__error_message("num_ref_idx_l0_active_minus1(%d) is too big. Set it with 28\n", + if (slice_param->num_ref_idx_l0_active_minus1 > 31) { + psb__error_message("num_ref_idx_l0_active_minus1(%d) is too big, limit it to 31.\n", slice_param->num_ref_idx_l0_active_minus1); slice_param->num_ref_idx_l0_active_minus1 = 28; } @@ -1164,7 +1175,6 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu /* send DPB information (for P and B slices?) only needed once per frame */ // if ( sh->slice_type == ST_B || sh->slice_type == ST_P ) if (pic_params->num_ref_frames > 0) { - int i; IMG_BOOL is_used[16]; psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES)); @@ -1210,7 +1220,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu __FUNCTION__, __LINE__); /* return; */ } - + /* psb__information_message("pic_params->ReferenceFrames[%d] = %08x --> %08x frame_idx:0x%08x flags:%02x TopFieldOrderCnt: 0x%08x BottomFieldOrderCnt: 0x%08x %s\n", i, pic_params->ReferenceFrames[i].picture_id, @@ -1220,8 +1230,8 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu pic_params->ReferenceFrames[i].TopFieldOrderCnt, pic_params->ReferenceFrames[i].BottomFieldOrderCnt, is_used[i] ? "used" : ""); - - if (ref_surface && is_used[i]) + */ + if (ref_surface && is_used[i] && ref_surface->psb_surface->ref_buf) // GET_SURFACE_INFO_is_used(ref_surface->psb_surface)) { buffer = ref_surface->psb_surface->ref_buf; @@ -1322,7 +1332,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu /* If this a two pass mode deblock, then we will perform the rotation as part of the * 2nd pass deblock procedure */ - if (/*!ctx->two_pass_mode &&*/ ctx->obj_context->rotate != VA_ROTATION_NONE) /* FIXME field coded should not issue */ + if (/*!ctx->two_pass_mode &&*/ CONTEXT_ROTATE(ctx->obj_context)) /* FIXME field coded should not issue */ psb__H264_setup_alternative_frame(ctx); /* CHUNK: SEQ Commands 1 */ @@ -1422,7 +1432,7 @@ static VAStatus psb__H264_add_slice_param(context_H264_p ctx, object_buffer_p ob { ASSERT(obj_buffer->type == VASliceParameterBufferType); if (ctx->slice_param_list_idx >= ctx->slice_param_list_size) { - void *new_list; + unsigned char *new_list; ctx->slice_param_list_size += 8; new_list = realloc(ctx->slice_param_list, sizeof(object_buffer_p) * ctx->slice_param_list_size); @@ -1539,7 +1549,7 @@ static const IMG_UINT32 ui32H264VLCTableRegValPair[] = { static void psb__H264_write_VLC_tables(context_H264_p ctx) { psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; - int i; + unsigned int i; psb_cmdbuf_skip_start_block(cmdbuf, SKIP_ON_CONTEXT_SWITCH); @@ -1589,6 +1599,7 @@ static VAStatus psb__H264_process_slice(context_H264_p ctx, ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType)); +#if 0 psb__information_message("H264 process slice %d\n", ctx->slice_count); psb__information_message(" profile = %s\n", profile2str[ctx->profile]); psb__information_message(" size = %08x offset = %08x\n", slice_param->slice_data_size, slice_param->slice_data_offset); @@ -1597,6 +1608,7 @@ static VAStatus psb__H264_process_slice(context_H264_p ctx, psb__information_message(" coded size = %dx%d\n", ctx->picture_width_mb, ctx->picture_height_mb); psb__information_message(" slice type = %s\n", slice2str[(slice_param->slice_type % 5)]); psb__information_message(" weighted_pred_flag = %d weighted_bipred_idc = %d\n", ctx->pic_params->pic_fields.bits.weighted_pred_flag, ctx->pic_params->pic_fields.bits.weighted_bipred_idc); +#endif if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) || (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL)) { @@ -1695,25 +1707,35 @@ static VAStatus psb__H264_process_slice_data(context_H264_p ctx, object_buffer_p VAStatus vaStatus = VA_STATUS_SUCCESS; VASliceParameterBufferH264 *slice_param; int buffer_idx = 0; - int element_idx = 0; + unsigned int element_idx = 0; ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType)); ASSERT(ctx->pic_params); ASSERT(ctx->slice_param_list_idx); - if (!ctx->pic_params) { + if ((!ctx->pic_params) || (!ctx->slice_param_list_idx)) { /* Picture params missing */ + psb__error_message("picture/slice parameter buffer should not be empty.\n"); return VA_STATUS_ERROR_UNKNOWN; } if ((NULL == obj_buffer->psb_buffer) || (0 == obj_buffer->size)) { /* We need to have data in the bitstream buffer */ + psb__error_message("bitstream buffer should not be empty.\n"); return VA_STATUS_ERROR_UNKNOWN; } while (buffer_idx < ctx->slice_param_list_idx) { object_buffer_p slice_buf = ctx->slice_param_list[buffer_idx]; + /*need check whether slice parameter buffer is valid*/ + if ((NULL == slice_buf) || + (NULL == slice_buf->buffer_data) || + (slice_buf->size != sizeof(VASliceParameterBufferH264))) { + psb__error_message("slice parameter buffer is not valid.\n"); + return VA_STATUS_ERROR_UNKNOWN; + } + if (element_idx >= slice_buf->num_elements) { /* Move to next buffer */ element_idx = 0; @@ -1767,32 +1789,32 @@ static VAStatus psb_H264_RenderPicture( switch (obj_buffer->type) { case VAPictureParameterBufferType: - psb__information_message("psb_H264_RenderPicture got VAPictureParameterBuffer\n"); + /* psb__information_message("psb_H264_RenderPicture got VAPictureParameterBuffer\n"); */ vaStatus = psb__H264_process_picture_param(ctx, obj_buffer); DEBUG_FAILURE; break; case VAIQMatrixBufferType: - psb__information_message("psb_H264_RenderPicture got VAIQMatrixBufferType\n"); + /* psb__information_message("psb_H264_RenderPicture got VAIQMatrixBufferType\n"); */ vaStatus = psb__H264_process_iq_matrix(ctx, obj_buffer); DEBUG_FAILURE; break; case VASliceGroupMapBufferType: - psb__information_message("psb_H264_RenderPicture got VASliceGroupMapBufferType\n"); + /* psb__information_message("psb_H264_RenderPicture got VASliceGroupMapBufferType\n"); */ vaStatus = psb__H264_process_slice_group_map(ctx, obj_buffer); DEBUG_FAILURE; break; case VASliceParameterBufferType: - psb__information_message("psb_H264_RenderPicture got VASliceParameterBufferType\n"); + /* psb__information_message("psb_H264_RenderPicture got VASliceParameterBufferType\n"); */ vaStatus = psb__H264_add_slice_param(ctx, obj_buffer); DEBUG_FAILURE; break; case VASliceDataBufferType: case VAProtectedSliceDataBufferType: - psb__information_message("psb_H264_RenderPicture got %s\n", SLICEDATA_BUFFER_TYPE(obj_buffer->type)); + /* psb__information_message("psb_H264_RenderPicture got %s\n", SLICEDATA_BUFFER_TYPE(obj_buffer->type)); */ vaStatus = psb__H264_process_slice_data(ctx, obj_buffer); DEBUG_FAILURE; break; @@ -1855,8 +1877,8 @@ static VAStatus psb_H264_EndPicture( } #endif - if (ctx->two_pass_mode && (ctx->obj_context->rotate == VA_ROTATION_NONE)) { - void *pMbData = NULL; + if (ctx->two_pass_mode && (CONTEXT_ROTATE(ctx->obj_context) == 0)) { + unsigned char *pMbData = NULL; psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; psb_buffer_p colocated_target_buffer = psb__H264_lookup_colocated_buffer(ctx, target_surface); |