summaryrefslogtreecommitdiff
path: root/src/pnw_H264.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pnw_H264.c')
-rw-r--r--src/pnw_H264.c77
1 files changed, 48 insertions, 29 deletions
diff --git a/src/pnw_H264.c b/src/pnw_H264.c
index e2731d6..01bd545 100644
--- a/src/pnw_H264.c
+++ b/src/pnw_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.
@@ -32,6 +32,7 @@
#include "psb_def.h"
#include "psb_surface.h"
#include "psb_cmdbuf.h"
+#include "pnw_rotate.h"
#include "hwdefs/reg_io2.h"
#include "hwdefs/msvdx_offsets.h"
@@ -53,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) )
@@ -483,7 +486,7 @@ static VAStatus pnw_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);
@@ -540,8 +543,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("pnw_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;
@@ -549,6 +550,9 @@ 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("pnw_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) {
@@ -703,7 +707,7 @@ static VAStatus psb__H264_process_picture_param(context_H264_p ctx, object_buffe
/* Assume SGM_8BIT */
REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, H264_FE_SPS0_4BIT_SGM_FLAG, 0);
REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_SPS0, BE_PROFILEIDC, ctx->profile_idc);
- REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, MIN_LUMA_BIPRED_SIZE_8X8, pic_params->seq_fields.bits.MinLumaBiPredSize8x8);
+ REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, MIN_LUMA_BIPRED_SIZE_8X8, (ctx->picture_width_mb > 80));
REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, DIRECT_8X8_INFERENCE_FLAG, pic_params->seq_fields.bits.direct_8x8_inference_flag);
REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, CHROMA_FORMAT_IDC, pic_params->seq_fields.bits.chroma_format_idc);
REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, FRAME_MBS_ONLY_FLAG, pic_params->seq_fields.bits.frame_mbs_only_flag);
@@ -744,6 +748,8 @@ static VAStatus psb__H264_process_picture_param(context_H264_p ctx, object_buffe
}
}
+ psb_CheckInterlaceRotate(ctx->obj_context, (unsigned char *)pic_params);
+
return VA_STATUS_SUCCESS;
}
@@ -1018,7 +1024,12 @@ 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 (rotate_surface == NULL) {
+ psb__information_message("rotate surface is NULL, abort msvdx rotation\n");
+ return;
+ }
+
+ if (GET_SURFACE_INFO_rotate(rotate_surface) != obj_context->msvdx_rotate)
psb__error_message("Display rotate mode does not match surface rotate mode!\n");
@@ -1036,7 +1047,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);
*ctx->alt_output_flags = cmd;
@@ -1057,7 +1068,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 ); */
@@ -1100,7 +1111,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu
psb_cmdbuf_rendec_end(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 */
@@ -1127,8 +1138,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(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;
}
@@ -1149,7 +1160,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(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES));
@@ -1197,6 +1207,7 @@ static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBu
}
buffer = ref_surface->psb_surface->ref_buf;
+ /*
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,
@@ -1206,8 +1217,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] && buffer)
// GET_SURFACE_INFO_is_used(ref_surface->psb_surface))
{
psb_cmdbuf_rendec_write_address(cmdbuf, buffer,
@@ -1394,8 +1405,13 @@ 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__information_message("Setup rotate surface (%d) into command stream\n",
+ ctx->obj_context->msvdx_rotate);
+
psb__H264_setup_alternative_frame(ctx);
+ }
+
/* psb_cmdbuf_rendec_end_block( cmdbuf ); */
}
@@ -1407,7 +1423,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);
@@ -1570,7 +1586,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);
@@ -1600,6 +1616,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);
@@ -1608,6 +1625,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)) {
@@ -1692,7 +1710,7 @@ 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));
@@ -1766,32 +1784,32 @@ static VAStatus pnw_H264_RenderPicture(
switch (obj_buffer->type) {
case VAPictureParameterBufferType:
- psb__information_message("pnw_H264_RenderPicture got VAPictureParameterBuffer\n");
+ /* psb__information_message("pnw_H264_RenderPicture got VAPictureParameterBuffer\n"); */
vaStatus = psb__H264_process_picture_param(ctx, obj_buffer);
DEBUG_FAILURE;
break;
case VAIQMatrixBufferType:
- psb__information_message("pnw_H264_RenderPicture got VAIQMatrixBufferType\n");
+ /* psb__information_message("pnw_H264_RenderPicture got VAIQMatrixBufferType\n"); */
vaStatus = psb__H264_process_iq_matrix(ctx, obj_buffer);
DEBUG_FAILURE;
break;
case VASliceGroupMapBufferType:
- psb__information_message("pnw_H264_RenderPicture got VASliceGroupMapBufferType\n");
+ /* psb__information_message("pnw_H264_RenderPicture got VASliceGroupMapBufferType\n"); */
vaStatus = psb__H264_process_slice_group_map(ctx, obj_buffer);
DEBUG_FAILURE;
break;
case VASliceParameterBufferType:
- psb__information_message("pnw_H264_RenderPicture got VASliceParameterBufferType\n");
+ /* psb__information_message("pnw_H264_RenderPicture got VASliceParameterBufferType\n"); */
vaStatus = psb__H264_add_slice_param(ctx, obj_buffer);
DEBUG_FAILURE;
break;
case VASliceDataBufferType:
case VAProtectedSliceDataBufferType:
- psb__information_message("pnw_H264_RenderPicture got %s\n", SLICEDATA_BUFFER_TYPE(obj_buffer->type));
+ /* psb__information_message("pnw_H264_RenderPicture got %s\n", SLICEDATA_BUFFER_TYPE(obj_buffer->type)); */
vaStatus = psb__H264_process_slice_data(ctx, obj_buffer);
DEBUG_FAILURE;
break;
@@ -1821,12 +1839,12 @@ static VAStatus pnw_H264_EndPicture(
uint32_t ext_stride_a = 0;
psb__information_message("pnw_H264_EndPicture got two pass mode frame\n");
- if (ctx->obj_context->rotate != VA_ROTATION_NONE) {
+ if (CONTEXT_ROTATE(ctx->obj_context)) {
ASSERT(rotate_surface);
REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ALT_PICTURE_ENABLE, 1);
REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_ROW_STRIDE, rotate_surface->stride_mode);
REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */
- REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_MODE, rotate_surface->extra_info[5]);
+ REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_MODE, GET_SURFACE_INFO_rotate(rotate_surface));
}
REGIO_WRITE_FIELD_LITE(ext_stride_a, MSVDX_CMDS, EXTENDED_ROW_STRIDE, EXT_ROW_STRIDE, target_surface->stride / 64);
@@ -1851,12 +1869,13 @@ static VAStatus pnw_H264_EndPicture(
psb_buffer_p buffer_dst;
uint32_t chroma_offset_dst;
- if (ctx->obj_context->rotate == VA_ROTATION_NONE) {
+ if (CONTEXT_ROTATE(ctx->obj_context) == 0) {
buffer_dst = &target_surface->buf;
chroma_offset_dst = target_surface->chroma_offset;
} else {
- if (!rotate_surface)
+ if (!rotate_surface) {
ASSERT(0);
+ }
buffer_dst = &rotate_surface->buf;
chroma_offset_dst = rotate_surface->chroma_offset;