diff options
author | Yuanjun Huang <yuanjun.huang@intel.com> | 2015-01-27 06:22:27 +0800 |
---|---|---|
committer | Patrick Tjin <pattjin@google.com> | 2015-02-09 09:43:34 -0800 |
commit | f4c11867384e8c010264c10f0703e720bf2eefca (patch) | |
tree | ffca3c5ceb0cdebd02d10127d4b87b16176f68a0 | |
parent | 2c781bd1be7b01db4d06224e62b58d84d514eb12 (diff) | |
download | psb_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.h | 15 | ||||
-rw-r--r-- | src/pnw_MPEG2.c | 87 | ||||
-rwxr-xr-x | src/pnw_rotate.c | 16 | ||||
-rwxr-xr-x | src/psb_drv_video.c | 6 |
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; |