aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuanjun Huang <yuanjun.huang@intel.com>2015-01-27 06:22:27 +0800
committerPatrick Tjin <pattjin@google.com>2015-02-09 09:43:34 -0800
commitf4c11867384e8c010264c10f0703e720bf2eefca (patch)
treeffca3c5ceb0cdebd02d10127d4b87b16176f68a0
parent2c781bd1be7b01db4d06224e62b58d84d514eb12 (diff)
downloadpsb_video-f4c11867384e8c010264c10f0703e720bf2eefca.tar.gz
psb_video: Enable MPEG2 in video driver
MPEG2 driver implementation Change-Id: I43933536803788f31445e4eeb00d95e9dfa620c6 Signed-off-by: Yuanjun Huang <yuanjun.huang@intel.com>
-rw-r--r--src/hwdefs/msvdx_vec_mpeg2_reg_io2.h15
-rw-r--r--src/pnw_MPEG2.c87
-rwxr-xr-xsrc/pnw_rotate.c16
-rwxr-xr-xsrc/psb_drv_video.c6
4 files changed, 119 insertions, 5 deletions
diff --git a/src/hwdefs/msvdx_vec_mpeg2_reg_io2.h b/src/hwdefs/msvdx_vec_mpeg2_reg_io2.h
index a272bab..e5c6f5b 100644
--- a/src/hwdefs/msvdx_vec_mpeg2_reg_io2.h
+++ b/src/hwdefs/msvdx_vec_mpeg2_reg_io2.h
@@ -134,6 +134,21 @@ extern "C" {
#define MSVDX_VEC_MPEG2_CR_VEC_MPEG2_FE_SLICE_FE_QUANTISER_SCALE_CODE_LSBMASK (0x0000001F)
#define MSVDX_VEC_MPEG2_CR_VEC_MPEG2_FE_SLICE_FE_QUANTISER_SCALE_CODE_SHIFT (16)
+#define MSVDX_VEC_MPEG2_CR_VEC_MPEG2_FE_SPS0_OFFSET (0x0618)
+
+// MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_SPS0, FE_HORIZONTAL_SIZE_MINUS1
+#define MSVDX_VEC_MPEG2_CR_VEC_MPEG2_FE_SPS0_FE_HORIZONTAL_SIZE_MINUS1_MASK (0x00FF0000)
+#define MSVDX_VEC_MPEG2_CR_VEC_MPEG2_FE_SPS0_FE_HORIZONTAL_SIZE_MINUS1_LSBMASK (0x000000FF)
+#define MSVDX_VEC_MPEG2_CR_VEC_MPEG2_FE_SPS0_FE_HORIZONTAL_SIZE_MINUS1_SHIFT (16)
+
+#define MSVDX_VEC_MPEG2_CR_VEC_MPEG2_FE_MPS0_OFFSET (0x061C)
+
+// MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_MPS0, CR_MACROBLOCK_ADDRESS_INC
+#define MSVDX_VEC_MPEG2_CR_VEC_MPEG2_FE_MPS0_CR_MACROBLOCK_ADDRESS_INC_MASK (0xFFFF0000)
+#define MSVDX_VEC_MPEG2_CR_VEC_MPEG2_FE_MPS0_CR_MACROBLOCK_ADDRESS_INC_LSBMASK (0x0000FFFF)
+#define MSVDX_VEC_MPEG2_CR_VEC_MPEG2_FE_MPS0_CR_MACROBLOCK_ADDRESS_INC_SHIFT (16)
+
+
#define MSVDX_VEC_MPEG2_CR_VEC_MPEG2_BE_SPS0_OFFSET (0x0650)
// MSVDX_VEC_MPEG2 CR_VEC_MPEG2_BE_SPS0 BE_HORIZONTAL_SIZE_MINUS1
diff --git a/src/pnw_MPEG2.c b/src/pnw_MPEG2.c
index f132d23..2b82b3e 100644
--- a/src/pnw_MPEG2.c
+++ b/src/pnw_MPEG2.c
@@ -32,6 +32,7 @@
#include "tng_vld_dec.h"
#include "psb_def.h"
#include "psb_drv_debug.h"
+#include "pnw_rotate.h"
#include "hwdefs/reg_io2.h"
#include "hwdefs/msvdx_offsets.h"
@@ -63,6 +64,15 @@
no End of Block, and a special end_of_macroblock code '1'. PICTURE_CODING_D is not allowed in MPEG2 */
#define PICTURE_CODING_D 0x04
+#define HW_SUPPORTED_MAX_PICTURE_WIDTH_MPEG2_MP 1920
+#define HW_SUPPORTED_MAX_PICTURE_HEIGHT_MPEG2_MP 1088
+
+#define HW_SUPPORTED_MAX_PICTURE_WIDTH_MPEG2_SP 352
+#define HW_SUPPORTED_MAX_PICTURE_HEIGHT_MPEG2_SP 288
+
+#define CACHE_REF_OFFSET 72
+#define CACHE_ROW_OFFSET 4
+
/************************************************************************************/
/* Variable length codes in 'packed' format */
/************************************************************************************/
@@ -501,6 +511,8 @@ struct context_MPEG2_s {
uint32_t FE_PPS0;
uint32_t FE_PPS1;
+ uint32_t slice_count;
+
/* IQ Matrix */
uint32_t qmatrix_data[MAX_QUANT_TABLES][16];
int got_iq_matrix;
@@ -525,7 +537,38 @@ static void pnw_MPEG2_QueryConfigAttributes(
VAConfigAttrib __maybe_unused * attrib_list,
int __maybe_unused num_attribs)
{
- /* No MPEG2 specific attributes */
+ int i;
+ drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_MPEG2_QueryConfigAttributes\n");
+
+ for (i = 0; i < num_attribs; i++) {
+ switch (attrib_list[i].type) {
+ case VAConfigAttribMaxPictureWidth:
+ if (entrypoint == VAEntrypointVLD) {
+ if (profile == VAProfileMPEG2Simple)
+ attrib_list[i].value = HW_SUPPORTED_MAX_PICTURE_WIDTH_MPEG2_SP;
+ else if(profile == VAProfileMPEG2Main)
+ attrib_list[i].value = HW_SUPPORTED_MAX_PICTURE_WIDTH_MPEG2_MP;
+ else
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+ }
+ else
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+ break;
+ case VAConfigAttribMaxPictureHeight:
+ if (entrypoint == VAEntrypointVLD) {
+ if (profile == VAProfileMPEG2Simple)
+ attrib_list[i].value = HW_SUPPORTED_MAX_PICTURE_HEIGHT_MPEG2_SP;
+ else if(profile == VAProfileMPEG2Main)
+ attrib_list[i].value = HW_SUPPORTED_MAX_PICTURE_HEIGHT_MPEG2_MP;
+ }
+ else
+ attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED;
+ break;
+ default:
+ break;
+ }
+ }
+
}
static VAStatus pnw_MPEG2_ValidateConfig(
@@ -803,6 +846,7 @@ static VAStatus psb__MPEG2_process_picture_param(context_MPEG2_p ctx, object_buf
REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 1); /* VDMC only */
REGIO_WRITE_FIELD_LITE(ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, 1);
+ psb_CheckInterlaceRotate(ctx->obj_context, (unsigned char*)ctx->pic_params);
return VA_STATUS_SUCCESS;
}
@@ -880,8 +924,6 @@ static void psb__MPEG2_set_operating_mode(context_MPEG2_p ctx)
psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface;
- vld_dec_setup_alternative_frame(ctx->obj_context);
-
psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE));
psb_cmdbuf_rendec_write(cmdbuf, ctx->display_picture_size);
psb_cmdbuf_rendec_write(cmdbuf, ctx->coded_picture_size);
@@ -894,6 +936,9 @@ static void psb__MPEG2_set_operating_mode(context_MPEG2_p ctx)
psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset);
psb_cmdbuf_rendec_end(cmdbuf);
+
+ vld_dec_setup_alternative_frame(ctx->obj_context);
+
}
static void psb__MPEG2_set_reference_pictures(context_MPEG2_p ctx)
@@ -901,6 +946,9 @@ static void psb__MPEG2_set_reference_pictures(context_MPEG2_p ctx)
psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface;
+ if (ctx->slice_count != 0) {
+ psb_cmdbuf_skip_start_block(cmdbuf, SKIP_ON_CONTEXT_SWITCH);
+ }
psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES));
/* In MPEG2, the registers at N=0 are always used to store the base address of the luma and chroma buffers
@@ -971,6 +1019,10 @@ static void psb__MPEG2_set_reference_pictures(context_MPEG2_p ctx)
}
psb_cmdbuf_rendec_end(cmdbuf);
+
+ if (ctx->slice_count != 0) {
+ psb_cmdbuf_skip_end_block(cmdbuf);
+ }
}
static void psb__MPEG2_set_picture_header(context_MPEG2_p ctx, VASliceParameterBufferMPEG2 *slice_param)
@@ -1010,6 +1062,15 @@ static void psb__MPEG2_set_picture_header(context_MPEG2_p ctx, VASliceParameterB
psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_SLICE) , FE_slice);
+ FE_slice = 0;
+ REGIO_WRITE_FIELD_LITE(FE_slice,
+ MSVDX_VEC_MPEG2,
+ CR_VEC_MPEG2_FE_SPS0,
+ FE_HORIZONTAL_SIZE_MINUS1,
+ ctx->picture_width_mb - 1);
+
+ psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_SPS0) , FE_slice);
+
psb_cmdbuf_reg_end_block(cmdbuf);
@@ -1169,6 +1230,14 @@ static void psb__MPEG2_set_ent_dec(context_MPEG2_p ctx)
psb_cmdbuf_rendec_write(cmdbuf, cmd_data);
psb_cmdbuf_rendec_end(cmdbuf);
+
+ psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, MC_CACHE_CONFIGURATION));
+ cmd_data = 0;
+ REGIO_WRITE_FIELD_LITE(cmd_data, MSVDX_CMDS, MC_CACHE_CONFIGURATION, CONFIG_REF_OFFSET, CACHE_REF_OFFSET);
+ REGIO_WRITE_FIELD_LITE(cmd_data, MSVDX_CMDS, MC_CACHE_CONFIGURATION, CONFIG_ROW_OFFSET, CACHE_ROW_OFFSET);
+ psb_cmdbuf_rendec_write(cmdbuf, cmd_data);
+ psb_cmdbuf_rendec_end(cmdbuf);
+
}
static void psb__MPEG2_begin_slice(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param)
@@ -1176,14 +1245,19 @@ static void psb__MPEG2_begin_slice(context_DEC_p dec_ctx, VASliceParameterBuffer
VASliceParameterBufferMPEG2 *slice_param = (VASliceParameterBufferMPEG2 *) vld_slice_param;
context_MPEG2_p ctx = (context_MPEG2_p)dec_ctx;
+ psb__MPEG2_write_VLC_tables(ctx);
+
dec_ctx->bits_offset = slice_param->macroblock_offset;
- /* dec_ctx->SR_flags = 0; */
+ dec_ctx->SR_flags = CMD_SR_VERIFY_STARTCODE;
}
static void psb__MPEG2_process_slice_data(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param)
{
VASliceParameterBufferMPEG2 *slice_param = (VASliceParameterBufferMPEG2 *) vld_slice_param;
context_MPEG2_p ctx = (context_MPEG2_p)dec_ctx;
+ ctx->obj_context->first_mb = 0;
+ ctx->obj_context->first_mb = slice_param->slice_vertical_position << 8;
+
psb__MPEG2_set_operating_mode(ctx);
psb__MPEG2_set_reference_pictures(ctx);
psb__MPEG2_set_picture_header(ctx, slice_param);
@@ -1203,6 +1277,8 @@ static void psb__MPEG2_end_slice(context_DEC_p dec_ctx)
ctx->obj_context->last_mb = ((ctx->picture_height_mb / 2 - 1) << 8) | (ctx->picture_width_mb - 1);
*(ctx->dec_ctx.slice_first_pic_last) = (ctx->obj_context->first_mb << 16) | (ctx->obj_context->last_mb);
+
+ ctx->slice_count++;
}
static void psb__MEPG2_send_highlevel_cmd(context_MPEG2_p ctx)
@@ -1327,6 +1403,7 @@ static VAStatus pnw_MPEG2_BeginPicture(
ctx->pic_params = NULL;
}
ctx->previous_slice_vertical_position = ~1;
+ ctx->slice_count = 0;
return VA_STATUS_SUCCESS;
}
@@ -1383,6 +1460,8 @@ static VAStatus pnw_MPEG2_EndPicture(
ctx->pic_params = NULL;
}
+ ctx->slice_count = 0;
+
return vaStatus;
}
diff --git a/src/pnw_rotate.c b/src/pnw_rotate.c
index ebec022..5dc1518 100755
--- a/src/pnw_rotate.c
+++ b/src/pnw_rotate.c
@@ -58,6 +58,11 @@
#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id ))
#define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id ))
+/*picture structure*/
+#define TOP_FIELD 1
+#define BOTTOM_FIELD 2
+#define FRAME_PICTURE 3
+
#define CHECK_SURFACE_REALLOC(psb_surface, msvdx_rotate, need) \
do { \
int old_rotate = GET_SURFACE_INFO_rotate(psb_surface); \
@@ -369,8 +374,17 @@ void psb_CheckInterlaceRotate(object_context_p obj_context, unsigned char *pic_p
switch (obj_context->profile) {
case VAProfileMPEG2Simple:
- case VAProfileMPEG2Main:
+ case VAProfileMPEG2Main: {
+ VAPictureParameterBufferMPEG2 *pic_params = (VAPictureParameterBufferMPEG2 *)pic_param_tmp;
+ if ((pic_params->picture_coding_extension.bits.picture_structure == TOP_FIELD) ||
+ (pic_params->picture_coding_extension.bits.picture_structure == BOTTOM_FIELD) ||
+ ((pic_params->picture_coding_extension.bits.picture_structure == FRAME_PICTURE) &&
+ (pic_params->picture_coding_extension.bits.progressive_frame == 0)))
+ obj_context->interlaced_stream = 1;
+ else
+ obj_context->interlaced_stream = 0;
break;
+ }
case VAProfileMPEG4Simple:
case VAProfileMPEG4AdvancedSimple:
case VAProfileMPEG4Main:
diff --git a/src/psb_drv_video.c b/src/psb_drv_video.c
index 930f208..3311f7d 100755
--- a/src/psb_drv_video.c
+++ b/src/psb_drv_video.c
@@ -3336,6 +3336,9 @@ EXPORT VAStatus __vaDriverInit_0_31(VADriverContextP ctx)
driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
+ driver_data->profile2Format[VAProfileMPEG2Simple][VAEntrypointVLD] = &pnw_MPEG2_vtable;
+ driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable;
+
driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;
@@ -3377,6 +3380,9 @@ EXPORT VAStatus __vaDriverInit_0_31(VADriverContextP ctx)
driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable;
+ driver_data->profile2Format[VAProfileMPEG2Simple][VAEntrypointVLD] = &pnw_MPEG2_vtable;
+ driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable;
+
driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointVLD] = &pnw_MPEG4_vtable;
driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable;