pnw_H264.c revision 2c17e69ffe1f253e6827ee4b9cd018f3716ebb87
1/* 2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved. 3 * Copyright (c) Imagination Technologies Limited, UK 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: 26 * Waldo Bastian <waldo.bastian@intel.com> 27 * Li Zeng <li.zeng@intel.com> 28 * 29 */ 30 31#include "pnw_H264.h" 32#include "tng_vld_dec.h" 33#include "psb_def.h" 34#include "psb_drv_debug.h" 35#include "pnw_rotate.h" 36 37#include "hwdefs/reg_io2.h" 38#include "hwdefs/msvdx_offsets.h" 39#include "hwdefs/msvdx_cmds_io2.h" 40#include "hwdefs/msvdx_core_regs_io2.h" 41#include "hwdefs/msvdx_vec_reg_io2.h" 42#include "hwdefs/msvdx_vec_h264_reg_io2.h" 43#include "hwdefs/dxva_fw_ctrl.h" 44#ifdef SLICE_HEADER_PARSING 45#include "hwdefs/dxva_cmdseq_msg.h" 46#include "hwdefs/dxva_msg.h" 47#endif 48#include <stdlib.h> 49#include <stdint.h> 50#include <string.h> 51 52#define BUFFER(id) ((object_buffer_p) object_heap_lookup( &ctx->obj_context->driver_data->buffer_heap, id )) 53 54#define GET_SURFACE_INFO_is_used(psb_surface) ((int) (psb_surface->extra_info[0])) 55#define SET_SURFACE_INFO_is_used(psb_surface, val) psb_surface->extra_info[0] = (uint32_t) val; 56#define GET_SURFACE_INFO_col_pic_params(psb_surface) (psb_surface->extra_info[1]) 57#define SET_SURFACE_INFO_col_pic_params(psb_surface, val) psb_surface->extra_info[1] = val; 58#define GET_SURFACE_INFO_dpb_idx(psb_surface) (psb_surface->extra_info[2]) 59#define SET_SURFACE_INFO_dpb_idx(psb_surface, val) psb_surface->extra_info[2] = val; 60 61#define IS_USED_AS_REFERENCE(pic_flags) ( pic_flags & (VA_PICTURE_H264_SHORT_TERM_REFERENCE | VA_PICTURE_H264_LONG_TERM_REFERENCE) ) 62 63/* Truncates a signed integer to 17 bits */ 64#define SIGNTRUNC( x ) ((( (x) >> 15) & 0x10000) | ( (x) & 0xffff)) 65 66#define MSVDX_VEC_REGS_BASE_MTX 0x0800 67#define MSVDX_COMMANDS_BASE_MTX 0x1000 68#define MSVDX_IQRAM_BASE_MTX 0x700 69 70#define HW_SUPPORTED_MAX_PICTURE_WIDTH_H264 4096 71#define HW_SUPPORTED_MAX_PICTURE_HEIGHT_H264 4096 72 73#define SLICEDATA_BUFFER_TYPE(type) ((type==VASliceDataBufferType)?"VASliceDataBufferType":"VAProtectedSliceDataBufferType") 74 75typedef enum { 76 PICT_NONE, 77 PICT_FRAME, 78 PICT_TOP, 79 PICT_BOTTOM, 80 PICT_PAIR 81} PICTYPE; 82 83typedef enum { 84 H264_BASELINE_PROFILE = 0, 85 H264_MAIN_PROFILE = 1, 86 H264_HIGH_PROFILE = 2 87} PROFILE; 88 89static const char *profile2str[] = { 90 "H264_BASELINE_PROFILE", 91 "H264_MAIN_PROFILE", 92 "H264_HIGH_PROFILE" 93}; 94 95typedef enum { 96 ST_P, 97 ST_B , 98 ST_I , 99 ST_SP , 100 ST_SI 101} SLICE_TYPE; 102 103static IMG_UINT8 aSliceTypeVAtoMsvdx[] = { 1 , 2 , 0, 1, 0 }; 104 105static const char *slice2str[] = { 106 "ST_P", 107 "ST_B", 108 "ST_I", 109 "ST_SP", 110 "ST_SI" 111}; 112 113typedef enum { 114 DEBLOCK_NONE, 115 DEBLOCK_STD, 116 DEBLOCK_INTRA_OOLD 117} DEBLOCK_MODE_2NDPASS; 118 119struct context_H264_s { 120 struct context_DEC_s dec_ctx; 121 object_context_p obj_context; /* back reference */ 122 123 uint32_t profile; // ENTDEC BE_PROFILE & FE_PROFILE 124 uint32_t profile_idc; // BE_PROFILEIDC 125 126 /* Picture parameters */ 127 VAPictureParameterBufferH264 *pic_params; 128 object_surface_p forward_ref_surface; 129 object_surface_p backward_ref_surface; 130 131 uint32_t coded_picture_width; /* in pixels */ 132 uint32_t coded_picture_height; /* in pixels */ 133 134 uint32_t picture_width_mb; /* in macroblocks */ 135 uint32_t picture_height_mb; /* in macroblocks */ 136 uint32_t size_mb; /* in macroblocks */ 137 138 uint32_t first_mb_x; 139 uint32_t first_mb_y; 140 141 uint32_t mb_width_c; /* Chroma macroblock width */ 142 uint32_t mb_height_c; /* Chroma macroblock height */ 143 144 uint32_t bit_depth_l; /* Luma bit depth */ 145 uint32_t qp_bd_offset_l; 146 uint32_t bit_depth_c; /* Chroma bit depth */ 147 uint32_t qp_bd_offset_c; 148 149 uint32_t raw_mb_bits; /* Number of bits per macroblock */ 150 151 uint32_t picture_width_samples_l; 152 uint32_t picture_height_samples_l; 153 uint32_t picture_width_samples_c; 154 uint32_t picture_height_samples_c; 155 156 uint32_t picture_height_map_units; 157 uint32_t picture_size_map_units; 158 159 PICTYPE pic_type; 160 uint32_t field_type; 161 162 uint32_t long_term_frame_flags; 163 uint32_t two_pass_mode; 164 uint32_t deblock_mode; 165 uint32_t slice_count; 166 167 /* Registers */ 168 uint32_t reg_SPS0; 169 uint32_t reg_PPS0; 170 uint32_t reg_PIC0; 171 172 uint32_t slice0_params; 173 uint32_t slice1_params; 174 175 /* VLC packed data */ 176 struct psb_buffer_s vlc_packed_table; 177 178 /* Preload buffer */ 179 struct psb_buffer_s preload_buffer; 180 181 /* Slice Group Map buffer */ 182 psb_buffer_p slice_group_map_buffer; 183 184 /* IQ matrix */ 185 VAIQMatrixBufferH264 *iq_matrix; 186 VASliceParameterBufferH264 *slice_param; 187 188 /* Reference Cache */ 189 struct psb_buffer_s reference_cache; 190}; 191 192typedef struct context_H264_s *context_H264_p; 193 194#define INIT_CONTEXT_H264 context_H264_p ctx = (context_H264_p) obj_context->format_data; 195 196#define SURFACE(id) ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id )) 197 198#define CACHE_REF_OFFSET 72 199#define CACHE_ROW_OFFSET 4 200 201#define REFERENCE_CACHE_SIZE (512 * 1024) 202 203#define MAX_PRELOAD_CMDS (40*2) 204typedef struct { 205 IMG_UINT8 ui8Address[MAX_PRELOAD_CMDS]; /* Address = (ui8Address << 1 | 0x400 ) */ 206 IMG_UINT32 ui32Value[MAX_PRELOAD_CMDS]; 207} ADDRDATA; 208 209typedef struct { 210 IMG_UINT32 ui32ContextId; 211 IMG_UINT32 ui32PreloadBufferSize; 212 ADDRDATA aData; 213} PRELOAD; 214 215 216 217/* **************************************************************************************************************** */ 218/* Prepacked H264 VLC Tables */ 219/* **************************************************************************************************************** */ 220static const IMG_UINT16 ui16H264VLCTableData[] = { 221 0x4000, 0x4205, 0x440a, 0x2204, 0x2206, 0x0208, 0x040b, 0x400f, 222 0x4204, 0x4209, 0x4013, 0x420e, 0x4217, 0x421b, 0x4212, 0x420d, 223 0x4208, 0x2a08, 0x0232, 0x0035, 0x0036, 0x441f, 0x4416, 0x4411, 224 0x440c, 0x0407, 0x040e, 0x0415, 0x041c, 0x0223, 0x4a35, 0x3a00, 225 0x4420, 0x4426, 0x4421, 0x441c, 0x442b, 0x4422, 0x441d, 0x4418, 226 0x4433, 0x442e, 0x4429, 0x4428, 0x442f, 0x442a, 0x4425, 0x4424, 227 0x443b, 0x4436, 0x4431, 0x4430, 0x4437, 0x4432, 0x442d, 0x442c, 228 0x4443, 0x443e, 0x443d, 0x4438, 0x443f, 0x443a, 0x4439, 0x4434, 229 0x4240, 0x4242, 0x4241, 0x423c, 0x4227, 0x421e, 0x4219, 0x4214, 230 0x4023, 0x401a, 0x4015, 0x4010, 0x0410, 0x0249, 0x024c, 0x004f, 231 0x4613, 0x460f, 0x440a, 0x440a, 0x4205, 0x4205, 0x4205, 0x4205, 232 0x4200, 0x4200, 0x4200, 0x4200, 0x2a08, 0x0231, 0x0034, 0x0035, 233 0x4423, 0x4416, 0x4415, 0x440c, 0x0407, 0x040e, 0x0415, 0x121c, 234 0x0222, 0x4a3f, 0x3a00, 0x442f, 0x4426, 0x4425, 0x4420, 0x442b, 235 0x4422, 0x4421, 0x441c, 0x442c, 0x442e, 0x442d, 0x4428, 0x4433, 236 0x442a, 0x4429, 0x4424, 0x443b, 0x4436, 0x4435, 0x4434, 0x4437, 237 0x4432, 0x4431, 0x4430, 0x0203, 0x423a, 0x4238, 0x423d, 0x423c, 238 0x423e, 0x4239, 0x4243, 0x4242, 0x4241, 0x4240, 0x4227, 0x421e, 239 0x421d, 0x4218, 0x4014, 0x401a, 0x4019, 0x4010, 0x421f, 0x4212, 240 0x4211, 0x4208, 0x421b, 0x420e, 0x420d, 0x4204, 0x4017, 0x4009, 241 0x2210, 0x0432, 0x0239, 0x023c, 0x600a, 0x6008, 0x003d, 0x003e, 242 0x461f, 0x461b, 0x4617, 0x4613, 0x460f, 0x460a, 0x4605, 0x4600, 243 0x0403, 0x040a, 0x0611, 0x4433, 0x442e, 0x4429, 0x4424, 0x442f, 244 0x442a, 0x4425, 0x4420, 0x4430, 0x4436, 0x4431, 0x442c, 0x4437, 245 0x4432, 0x442d, 0x4428, 0x3600, 0x4640, 0x4643, 0x4642, 0x4641, 246 0x463c, 0x463f, 0x463e, 0x463d, 0x4638, 0x463b, 0x463a, 0x4639, 247 0x4634, 0x4435, 0x4435, 0x441c, 0x4418, 0x4426, 0x4414, 0x442b, 248 0x4422, 0x4421, 0x4410, 0x420c, 0x421e, 0x421d, 0x4208, 0x4227, 249 0x421a, 0x4219, 0x4204, 0x400d, 0x4023, 0x400e, 0x4009, 0x2208, 250 0x5406, 0x540a, 0x540e, 0x5412, 0x5416, 0x541a, 0x541e, 0x5204, 251 0x0002, 0x5002, 0x3000, 0x4000, 0x4005, 0x4200, 0x440a, 0x0401, 252 0x1208, 0x000a, 0x4410, 0x440c, 0x4408, 0x440f, 0x4409, 0x4404, 253 0x4013, 0x4212, 0x4211, 0x400e, 0x400d, 0x4000, 0x4205, 0x440a, 254 0x0404, 0x480f, 0x4a13, 0x2609, 0x441b, 0x4417, 0x4412, 0x440e, 255 0x440d, 0x4409, 0x4408, 0x4404, 0x0205, 0x0208, 0x020b, 0x020e, 256 0x1411, 0x4216, 0x4211, 0x4210, 0x420c, 0x421f, 0x421a, 0x4215, 257 0x4214, 0x4223, 0x421e, 0x4219, 0x4218, 0x4222, 0x4221, 0x421d, 258 0x421c, 0x3400, 0x3400, 0x3400, 0x4420, 0x4000, 0x0006, 0x0007, 259 0x0008, 0x0009, 0x000a, 0x040b, 0x4002, 0x4001, 0x4004, 0x4003, 260 0x4006, 0x4005, 0x4008, 0x4007, 0x400a, 0x4009, 0x3400, 0x440f, 261 0x440e, 0x440d, 0x420c, 0x420c, 0x420b, 0x420b, 0x1208, 0x000e, 262 0x000f, 0x4404, 0x4403, 0x4402, 0x4401, 0x4400, 0x0203, 0x420a, 263 0x4209, 0x420e, 0x420d, 0x420c, 0x420b, 0x4008, 0x4007, 0x4006, 264 0x4005, 0x0208, 0x000d, 0x000e, 0x4407, 0x4406, 0x4403, 0x4402, 265 0x4401, 0x0004, 0x420c, 0x420a, 0x4209, 0x400d, 0x400b, 0x4008, 266 0x4005, 0x4004, 0x4000, 0x0208, 0x000b, 0x000c, 0x4408, 0x4406, 267 0x4405, 0x4404, 0x4401, 0x420c, 0x420b, 0x420a, 0x4200, 0x4009, 268 0x4007, 0x4003, 0x4002, 0x2208, 0x000a, 0x000b, 0x4407, 0x4406, 269 0x4405, 0x4404, 0x4403, 0x400a, 0x4209, 0x420b, 0x4008, 0x4002, 270 0x4001, 0x4000, 0x2408, 0x4409, 0x4407, 0x4406, 0x4405, 0x4404, 271 0x4403, 0x4402, 0x4008, 0x4201, 0x4400, 0x440a, 0x2408, 0x4408, 272 0x4406, 0x4404, 0x4403, 0x4402, 0x4205, 0x4205, 0x4007, 0x4201, 273 0x4400, 0x4409, 0x2604, 0x0008, 0x4205, 0x4204, 0x4007, 0x4201, 274 0x4402, 0x4600, 0x4608, 0x4006, 0x4003, 0x2604, 0x4206, 0x4204, 275 0x4203, 0x4005, 0x4202, 0x4407, 0x4600, 0x4601, 0x2404, 0x4205, 276 0x4204, 0x4203, 0x4002, 0x4206, 0x4400, 0x4401, 0x4004, 0x0003, 277 0x4402, 0x5000, 0x4003, 0x4005, 0x4003, 0x4202, 0x4404, 0x5000, 278 0x4002, 0x4203, 0x5000, 0x5000, 0x4002, 0x4000, 0x4001, 0x4000, 279 0x4201, 0x4402, 0x4403, 0x4000, 0x4201, 0x4202, 0x4001, 0x4000, 280 0x4001, 0x4000, 0x4000, 0x4201, 0x4202, 0x4203, 0x4202, 0x4201, 281 0x4200, 0x0004, 0x4202, 0x4201, 0x4200, 0x4004, 0x4003, 0x0203, 282 0x4201, 0x4200, 0x4205, 0x4204, 0x4203, 0x4202, 0x4401, 0x4402, 283 0x4404, 0x4403, 0x4406, 0x4405, 0x4200, 0x4200, 0x2a08, 0x4406, 284 0x4405, 0x4404, 0x4403, 0x4402, 0x4401, 0x4400, 0x4007, 0x4208, 285 0x4409, 0x460a, 0x480b, 0x4a0c, 0x2201, 0x400d, 0x420e, 0x3200, 286}; 287 288/* Set bottom field flag in bit 7 and DPB index in bits 0:3 */ 289static uint32_t PICTURE2INDEX(context_H264_p ctx, VAPictureH264 *pic) 290{ 291 uint32_t result = 0xff; /* unused */ 292 object_surface_p ref_surface = SURFACE(pic->picture_id); 293 if (ref_surface) { 294 result = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface); 295 } 296 if (pic->flags & VA_PICTURE_H264_BOTTOM_FIELD) { 297 result |= 0x80; /* Set bit 7 */ 298 } 299 return result; 300} 301 302static void pnw_H264_QueryConfigAttributes( 303 VAProfile profile, 304 VAEntrypoint entrypoint, 305 VAConfigAttrib *attrib_list, 306 int num_attribs) 307{ 308 int i; 309 drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264_QueryConfigAttributes\n"); 310 311 for (i = 0; i < num_attribs; i++) { 312 switch (attrib_list[i].type) { 313 case VAConfigAttribMaxPictureWidth: 314 if ((entrypoint == VAEntrypointVLD) && 315 (profile == VAProfileH264High)) 316 attrib_list[i].value = HW_SUPPORTED_MAX_PICTURE_WIDTH_H264; 317 else 318 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED; 319 break; 320 case VAConfigAttribMaxPictureHeight: 321 if ((entrypoint == VAEntrypointVLD) && 322 (profile == VAProfileH264High)) 323 attrib_list[i].value = HW_SUPPORTED_MAX_PICTURE_HEIGHT_H264; 324 else 325 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED; 326 break; 327 default: 328 break; 329 } 330 } 331 332} 333 334static VAStatus pnw_H264_ValidateConfig( 335 object_config_p obj_config) 336{ 337 int i; 338 /* Check all attributes */ 339 for (i = 0; i < obj_config->attrib_count; i++) { 340 switch (obj_config->attrib_list[i].type) { 341 case VAConfigAttribRTFormat: 342 case VAConfigAttribDecSliceMode: 343 /* Ignore */ 344 break; 345 346 default: 347 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; 348 } 349 } 350 351 return VA_STATUS_SUCCESS; 352} 353 354static VAStatus psb__H264_check_legal_picture(object_context_p obj_context, object_config_p obj_config) 355{ 356 VAStatus vaStatus = VA_STATUS_SUCCESS; 357 358 CHECK_CONTEXT(obj_context); 359 360 CHECK_CONFIG(obj_config); 361 362 /* MSVDX decode capability for H.264: 363 * BP@L3 364 * MP@L4.1 365 * HP@L4.1 366 * 367 * Refer to Table A-6 (Maximum frame rates for some example frame sizes) of ISO/IEC 14496-10:2005 (E). 368 */ 369 switch (obj_config->profile) { 370 case VAProfileH264Baseline: 371 if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 720) 372 || (obj_context->picture_height <= 0) || (obj_context->picture_height > 576)) { 373 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 374 } 375 break; 376 377 case VAProfileH264Main: 378 case VAProfileH264High: 379 case VAProfileH264ConstrainedBaseline: 380 if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 1920) 381 || (obj_context->picture_height <= 0) || (obj_context->picture_height > 1088)) { 382 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 383 } 384 break; 385 386 default: 387 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 388 break; 389 } 390 391 return vaStatus; 392} 393 394static void pnw_H264_DestroyContext(object_context_p obj_context); 395static void psb__H264_process_slice_data(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param); 396static void psb__H264_end_slice(context_DEC_p dec_ctx); 397static void psb__H264_begin_slice(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param); 398static VAStatus pnw_H264_process_buffer(context_DEC_p dec_ctx, object_buffer_p buffer); 399 400static VAStatus pnw_H264_CreateContext( 401 object_context_p obj_context, 402 object_config_p obj_config) 403{ 404 VAStatus vaStatus = VA_STATUS_SUCCESS; 405 context_H264_p ctx; 406 /* Validate flag */ 407 /* Validate picture dimensions */ 408 //vaStatus = psb__H264_check_legal_picture(obj_context, obj_config); 409 CHECK_VASTATUS(); 410 411 ctx = (context_H264_p) calloc(1, sizeof(struct context_H264_s)); 412 CHECK_ALLOCATION(ctx); 413 414 obj_context->format_data = (void*) ctx; 415 ctx->obj_context = obj_context; 416 ctx->pic_params = NULL; 417 418 ctx->dec_ctx.begin_slice = psb__H264_begin_slice; 419 ctx->dec_ctx.process_slice = psb__H264_process_slice_data; 420 ctx->dec_ctx.end_slice = psb__H264_end_slice; 421 ctx->dec_ctx.process_buffer = pnw_H264_process_buffer; 422 423 switch (obj_config->profile) { 424 case VAProfileH264Baseline: 425 ctx->profile = H264_BASELINE_PROFILE; 426 ctx->profile_idc = 0; 427 break; 428 429 case VAProfileH264Main: 430 ctx->profile = H264_MAIN_PROFILE; 431 ctx->profile_idc = 1; 432 break; 433 434 case VAProfileH264High: 435 case VAProfileH264ConstrainedBaseline: 436 ctx->profile = H264_HIGH_PROFILE; 437 ctx->profile_idc = 3; 438 break; 439 440 default: 441 ASSERT(0); 442 vaStatus = VA_STATUS_ERROR_UNKNOWN; 443 } 444 445 // TODO 446 if (vaStatus == VA_STATUS_SUCCESS) { 447 vaStatus = psb_buffer_create(obj_context->driver_data, 448 sizeof(PRELOAD), 449 psb_bt_vpu_only, 450 &ctx->preload_buffer); 451 DEBUG_FAILURE; 452 } 453 ctx->dec_ctx.preload_buffer = &ctx->preload_buffer; 454 455 if (vaStatus == VA_STATUS_SUCCESS) { 456 vaStatus = psb_buffer_create(obj_context->driver_data, 457 REFERENCE_CACHE_SIZE, 458 psb_bt_vpu_only, 459 &ctx->reference_cache); 460 DEBUG_FAILURE; 461 } 462 463 if (vaStatus == VA_STATUS_SUCCESS) { 464 vaStatus = psb_buffer_create(obj_context->driver_data, 465 sizeof(ui16H264VLCTableData), 466 psb_bt_cpu_vpu, 467 &ctx->vlc_packed_table); 468 DEBUG_FAILURE; 469 } 470 if (vaStatus == VA_STATUS_SUCCESS) { 471 unsigned char *vlc_packed_data_address; 472 if (0 == psb_buffer_map(&ctx->vlc_packed_table, &vlc_packed_data_address)) { 473 memcpy(vlc_packed_data_address, ui16H264VLCTableData, sizeof(ui16H264VLCTableData)); 474 psb_buffer_unmap(&ctx->vlc_packed_table); 475 } else { 476 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 477 DEBUG_FAILURE; 478 } 479 } 480 481 if (vaStatus == VA_STATUS_SUCCESS) { 482 vaStatus = vld_dec_CreateContext(&ctx->dec_ctx, obj_context); 483 DEBUG_FAILURE; 484 } 485 486 if (vaStatus != VA_STATUS_SUCCESS) { 487 pnw_H264_DestroyContext(obj_context); 488 } 489 490 return vaStatus; 491} 492 493static void pnw_H264_DestroyContext( 494 object_context_p obj_context) 495{ 496 INIT_CONTEXT_H264 497 int i; 498 499 vld_dec_DestroyContext(&ctx->dec_ctx); 500 501 psb_buffer_destroy(&ctx->reference_cache); 502 psb_buffer_destroy(&ctx->preload_buffer); 503 psb_buffer_destroy(&ctx->vlc_packed_table); 504 505 if (ctx->pic_params) { 506 free(ctx->pic_params); 507 ctx->pic_params = NULL; 508 } 509 if (ctx->iq_matrix) { 510 free(ctx->iq_matrix); 511 ctx->iq_matrix = NULL; 512 } 513 514 free(obj_context->format_data); 515 obj_context->format_data = NULL; 516} 517 518#define P(x) psb__trace_message("PARAMS: " #x "\t= %08x (%d)\n", p->x, p->x) 519static void psb__H264_trace_pic_params(VAPictureParameterBufferH264 *p) 520{ 521 P(CurrPic); 522 P(picture_width_in_mbs_minus1); 523 P(picture_height_in_mbs_minus1); 524 P(bit_depth_luma_minus8); 525 P(bit_depth_chroma_minus8); 526 P(num_ref_frames); 527 P(seq_fields); 528 P(num_slice_groups_minus1); 529 P(slice_group_map_type); 530 P(pic_init_qp_minus26); 531 P(chroma_qp_index_offset); 532 P(second_chroma_qp_index_offset); 533 P(pic_fields); 534 P(frame_num); 535} 536 537static VAStatus psb__H264_process_picture_param(context_H264_p ctx, object_buffer_p obj_buffer) 538{ 539 psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; 540 object_surface_p obj_surface = ctx->obj_context->current_render_target; 541 uint32_t reg_value; 542 VAStatus vaStatus; 543 544 ASSERT(obj_buffer->type == VAPictureParameterBufferType); 545 ASSERT(obj_buffer->num_elements == 1); 546 ASSERT(obj_buffer->size == sizeof(VAPictureParameterBufferH264)); 547 ASSERT(target_surface); 548 549 if ((obj_buffer->num_elements != 1) || 550 (obj_buffer->size != sizeof(VAPictureParameterBufferH264)) || 551 (NULL == target_surface)) { 552 return VA_STATUS_ERROR_UNKNOWN; 553 } 554 555 /* Transfer ownership of VAPictureParameterBufferH264 data */ 556 VAPictureParameterBufferH264 *pic_params = (VAPictureParameterBufferH264 *) obj_buffer->buffer_data; 557 if (ctx->pic_params) { 558 free(ctx->pic_params); 559 } 560 ctx->pic_params = pic_params; 561 obj_buffer->buffer_data = NULL; 562 obj_buffer->size = 0; 563 564 if (psb_video_trace_fp && (psb_video_trace_level & VABUF_TRACE)) 565 psb__H264_trace_pic_params(pic_params); 566 567 /* Table 6-1 */ 568 uint32_t sub_width_c = (pic_params->seq_fields.bits.chroma_format_idc > 2) ? 1 : 2; 569 uint32_t sub_height_c = (pic_params->seq_fields.bits.chroma_format_idc > 1) ? 1 : 2; 570 571 if (pic_params->seq_fields.bits.chroma_format_idc == 0) { 572 ctx->mb_width_c = 0; 573 ctx->mb_height_c = 0; 574 } else { 575 ctx->mb_width_c = 16 / sub_width_c; /* 6-1 */ 576 ctx->mb_height_c = 16 / sub_height_c; /* 6-2 */ 577 } 578 579 ctx->bit_depth_l = 8 + pic_params->bit_depth_luma_minus8; /* (7-1) */ 580 ctx->qp_bd_offset_l = 6 * pic_params->bit_depth_luma_minus8; /* (7-2) */ 581 582 ctx->bit_depth_c = 8 + pic_params->bit_depth_chroma_minus8; /* (7-3) */ 583 ctx->qp_bd_offset_c = 6 * (pic_params->bit_depth_chroma_minus8 + pic_params->seq_fields.bits.residual_colour_transform_flag); /* (7-4) */ 584 585 ctx->picture_width_mb = pic_params->picture_width_in_mbs_minus1 + 1; 586 ctx->picture_height_mb = pic_params->picture_height_in_mbs_minus1 + 1; 587 588 ctx->size_mb = ctx->picture_width_mb * ctx->picture_height_mb; /* (7-25) */ 589 590 //uint32_t colocated_size = (ctx->picture_width_mb + extra_size) * (ctx->picture_height_mb + extra_size) * 192; 591 uint32_t colocated_size = ((ctx->size_mb + 100) * 128 + 0xfff) & ~0xfff; 592 593 vaStatus = vld_dec_allocate_colocated_buffer(&ctx->dec_ctx, ctx->obj_context->current_render_target, colocated_size); 594 CHECK_VASTATUS(); 595 596 ctx->raw_mb_bits = 256 * ctx->bit_depth_l + 2 * ctx->mb_width_c * ctx->mb_height_c * ctx->bit_depth_c; /* (7-5) */ 597 598 ctx->picture_width_samples_l = ctx->picture_width_mb * 16; 599 ctx->picture_width_samples_c = ctx->picture_width_mb * ctx->mb_width_c; 600 601 ctx->picture_height_samples_l = ctx->picture_height_mb * 16; 602 ctx->picture_height_samples_c = ctx->picture_height_mb * ctx->mb_height_c; 603 604 // BECAUSE OF 605 // sps->FrameHeightInMbs = ( 2 - sps->seq_fields.bits.frame_mbs_only_flag ) * sps->PicHeightInMapUnits; /* (7-15) */ 606 ctx->picture_height_map_units = 1 + ctx->picture_height_mb / (2 - pic_params->seq_fields.bits.frame_mbs_only_flag); 607 ctx->picture_size_map_units = ctx->picture_width_mb * ctx->picture_height_map_units;/* (7-14) */ 608 609 pic_params->seq_fields.bits.mb_adaptive_frame_field_flag = (pic_params->seq_fields.bits.mb_adaptive_frame_field_flag && 610 !pic_params->pic_fields.bits.field_pic_flag); 611 /* record just what type of picture we are */ 612 if (pic_params->pic_fields.bits.field_pic_flag) { 613 if (pic_params->CurrPic.flags & VA_PICTURE_H264_BOTTOM_FIELD) { 614 ctx->pic_type = PICT_BOTTOM; 615 ctx->field_type = 1; 616 } else { 617 ctx->pic_type = PICT_TOP; 618 ctx->field_type = 0; 619 } 620 } else { 621 ctx->pic_type = PICT_FRAME; 622 ctx->field_type = pic_params->seq_fields.bits.mb_adaptive_frame_field_flag ? 3 : 2; 623 } 624 625 uint32_t i; 626 ctx->long_term_frame_flags = 0; 627 /* We go from high to low so that we are left with the lowest index */ 628 for (i = pic_params->num_ref_frames; i--;) { 629 if (pic_params->ReferenceFrames[i].flags == VA_PICTURE_H264_INVALID) { 630 continue; 631 } 632 object_surface_p ref_surface = SURFACE(pic_params->ReferenceFrames[i].picture_id); 633 if (pic_params->ReferenceFrames[i].flags & VA_PICTURE_H264_BOTTOM_FIELD) { 634 ctx->long_term_frame_flags |= 0x01 << i; 635 } 636 if (ref_surface) { 637 SET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface, i); 638 } 639 } 640 641 /* If the MB are not guarenteed to be consecutive - we must do a 2pass */ 642 ctx->two_pass_mode = (pic_params->num_slice_groups_minus1 > 0) && (!ctx->pic_params->seq_fields.bits.mb_adaptive_frame_field_flag); 643 644 ctx->reg_SPS0 = 0; 645 REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_SPS0, H264_BE_SPS0_DEFAULT_MATRIX_FLAG, (ctx->profile == H264_BASELINE_PROFILE)); /* Always use suplied matrix non baseline otherwise use default*/ 646 REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_SPS0, H264_BE_SPS0_2PASS_FLAG, ctx->two_pass_mode); /* Always 0 for VA - we cant handle otherwise yet */ 647 /* Assume SGM_8BIT */ 648 REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, H264_FE_SPS0_4BIT_SGM_FLAG, 0); 649 REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_SPS0, BE_PROFILEIDC, ctx->profile_idc); 650 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)); 651 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); 652 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); 653 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); 654 REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0, PICWIDTHINMBSLESS1, ctx->picture_width_mb - 1); 655 656 ctx->reg_PPS0 = 0; 657 REGIO_WRITE_FIELD_LITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_PPS0, TRANSFORM_8X8_MODE_FLAG, pic_params->pic_fields.bits.transform_8x8_mode_flag); 658 REGIO_WRITE_FIELD_LITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_PPS0, CONSTRAINED_INTRA_PRED_FLAG, pic_params->pic_fields.bits.constrained_intra_pred_flag); 659 REGIO_WRITE_FIELD_LITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_PPS0, ENTROPY_CODING_MODE_FLAG, pic_params->pic_fields.bits.entropy_coding_mode_flag); 660 REGIO_WRITE_FIELD_LITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_FE_PPS0, NUM_SLICE_GROUPS_MINUS1, pic_params->num_slice_groups_minus1); 661 REGIO_WRITE_FIELD_LITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_PPS0, BE_WEIGHTED_BIPRED_IDC, pic_params->pic_fields.bits.weighted_bipred_idc); 662 REGIO_WRITE_FIELD_MASKEDLITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_PPS0, BE_CHROMA_QP_INDEX_OFFSET, pic_params->chroma_qp_index_offset); 663 REGIO_WRITE_FIELD_MASKEDLITE(ctx->reg_PPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_PPS0, BE_SECOND_CHROMA_QP_INDEX_OFFSET, pic_params->second_chroma_qp_index_offset); 664 665 uint32_t PicHeightInMbs = ctx->picture_height_mb >> pic_params->pic_fields.bits.field_pic_flag; /* (7-23) */ 666 uint32_t PicSizeInMbs = ctx->picture_width_mb * PicHeightInMbs; /* (7-26) */ 667 668 ctx->reg_PIC0 = 0; 669 REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0, PICSIZEINMBSLESS1, PicSizeInMbs - 1); 670 REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0, PICHEIGHTINMBSLESS1, PicHeightInMbs - 1); 671 /* TODO */ 672 REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_BE_CUR_PIC0, BE_REFERENCE_FLAG, IS_USED_AS_REFERENCE(pic_params->CurrPic.flags) ? 1 : 0); 673 REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0, MBAFFFRAMEFLAG, pic_params->seq_fields.bits.mb_adaptive_frame_field_flag); 674 REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0, FIELD_PIC_FLAG, pic_params->pic_fields.bits.field_pic_flag); 675 REGIO_WRITE_FIELD_LITE(ctx->reg_PIC0, MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0, BOTTOM_FIELD_FLAG, pic_params->CurrPic.flags & VA_PICTURE_H264_BOTTOM_FIELD ? 1 : 0); 676 677 /* Record some info about current picture */ 678 reg_value = 0; 679 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_COL_PIC0, COL_NOTFRAMEFLAG, (PICT_FRAME != ctx->pic_type) ? 1 : 0); 680 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_COL_PIC0, COL_MBAFFFRAMEFLAG, pic_params->seq_fields.bits.mb_adaptive_frame_field_flag); 681 SET_SURFACE_INFO_col_pic_params(target_surface, reg_value); 682 683 if (pic_params->seq_fields.bits.chroma_format_idc == 0) { 684 vaStatus = psb_surface_set_chroma(target_surface, 128); 685 CHECK_VASTATUS(); 686 } 687 688 psb_CheckInterlaceRotate(ctx->obj_context, (unsigned char *)pic_params); 689 690 691#ifdef PSBVIDEO_MSVDX_EC 692 /* tell the driver to save the frame info for Error Concealment */ 693 /* 694 if (driver_data->ec_enabled) { 695 psb_context_get_next_cmdbuf(ctx->obj_context); 696 psb_context_submit_frame_info(ctx->obj_context, &target_surface->buf, 697 target_surface->stride, target_surface->size, 698 ctx->picture_width_mb, ctx->size_mb); 699 } 700 */ 701#endif 702 if ((ctx->picture_width_mb * 16) > 2048) 703 ctx->obj_context->driver_data->ec_enabled = 0; 704 705 return VA_STATUS_SUCCESS; 706} 707 708static VAStatus psb__H264_process_iq_matrix(context_H264_p ctx, object_buffer_p obj_buffer) 709{ 710 ASSERT(obj_buffer->type == VAIQMatrixBufferType); 711 ASSERT(obj_buffer->num_elements == 1); 712 ASSERT(obj_buffer->size == sizeof(VAIQMatrixBufferH264)); 713 714 if ((obj_buffer->num_elements != 1) || 715 (obj_buffer->size != sizeof(VAIQMatrixBufferH264))) { 716 return VA_STATUS_ERROR_UNKNOWN; 717 } 718 719 /* Transfer ownership of VAIQMatrixBufferH264 data */ 720 if (ctx->iq_matrix) { 721 free(ctx->iq_matrix); 722 } 723 ctx->iq_matrix = (VAIQMatrixBufferH264 *) obj_buffer->buffer_data; 724 obj_buffer->buffer_data = NULL; 725 obj_buffer->size = 0; 726 727 return VA_STATUS_SUCCESS; 728} 729 730static VAStatus psb__H264_process_slice_group_map(context_H264_p ctx, object_buffer_p obj_buffer) 731{ 732 ASSERT(obj_buffer->type == VASliceGroupMapBufferType); 733 ASSERT(obj_buffer->num_elements == 1); 734// ASSERT(obj_buffer->size == ...); 735 736 if (obj_buffer->num_elements != 1) { 737 return VA_STATUS_ERROR_UNKNOWN; 738 } 739 740 ctx->slice_group_map_buffer = obj_buffer->psb_buffer; 741 742 return VA_STATUS_SUCCESS; 743} 744 745#ifdef SLICE_HEADER_PARSING 746static VAStatus psb__H264_process_slice_header_group(context_H264_p ctx, object_buffer_p obj_buffer) 747{ 748 ASSERT(obj_buffer->type == VAParsePictureParameterBufferType); 749 object_context_p obj_context = ctx->obj_context; 750 VAStatus vaStatus = VA_STATUS_SUCCESS; 751 /* Transfer ownership of VAPictureParameterBufferH264 data */ 752 VAParsePictureParameterBuffer *pic_param_buf = (VAParsePictureParameterBuffer *) obj_buffer->buffer_data; 753 psb_driver_data_p driver_data = obj_context->driver_data; 754 755 object_buffer_p frame_obj_buffer = BUFFER(pic_param_buf->frame_buf_id); 756 if (NULL == frame_obj_buffer) { 757 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 758 DEBUG_FAILURE; 759 return vaStatus; 760 } 761 762 object_buffer_p slice_header_obj_buffer = BUFFER(pic_param_buf->slice_headers_buf_id); 763 if (NULL == slice_header_obj_buffer) { 764 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 765 DEBUG_FAILURE; 766 return vaStatus; 767 } 768 769 psb_context_get_next_cmdbuf(obj_context); 770 psb_cmdbuf_p cmdbuf = obj_context->cmdbuf; 771 772 uint32_t msg_size = sizeof(struct fw_slice_header_extract_msg); 773 uint32_t *msg = (uint32_t *)cmdbuf->MTX_msg; 774 memset(msg, 0, msg_size); 775 struct fw_slice_header_extract_msg *extract_msg; 776 777 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Send nal parse cmd\n"); 778 if (cmdbuf->cmd_count) { 779 drv_debug_msg(VIDEO_DEBUG_GENERAL, "nal parse cmdbuf has other msgs!\n"); 780 } 781 extract_msg = (struct fw_slice_header_extract_msg *)msg; 782 extract_msg->header.bits.msg_size = sizeof(struct fw_slice_header_extract_msg); 783 extract_msg->header.bits.msg_type = VA_MSGID_SLICE_HEADER_EXTRACT; 784 extract_msg->flags.bits.flags = FW_VA_RENDER_HOST_INT; 785 786 extract_msg->src_size = pic_param_buf->frame_size; 787 extract_msg->dst_size = pic_param_buf->slice_headers_size; 788 extract_msg->flag_bitfield.bits.expected_pps_id = 789 pic_param_buf->expected_pic_parameter_set_id; 790 791 if (obj_context->modular_drm) { 792 extract_msg->flag_bitfield.bits.nalu_header_unit_type = 793 pic_param_buf->nalu_header.bits.nalu_header_unit_type; 794 extract_msg->flag_bitfield.bits.nalu_header_ref_idc = 795 pic_param_buf->nalu_header.bits.nalu_header_ref_idc; 796 extract_msg->header.bits.msg_type = VA_MSGID_MODULAR_SLICE_HEADER_EXTRACT; 797 } 798 799 extract_msg->flag_bitfield.bits.continue_parse_flag = 0; 800 extract_msg->flag_bitfield.bits.frame_mbs_only_flag = 801 pic_param_buf->flags.bits.frame_mbs_only_flag; 802 extract_msg->flag_bitfield.bits.pic_order_present_flag = 803 pic_param_buf->flags.bits.pic_order_present_flag; 804 extract_msg->flag_bitfield.bits.delta_pic_order_always_zero_flag = 805 pic_param_buf->flags.bits.delta_pic_order_always_zero_flag; 806 extract_msg->flag_bitfield.bits.redundant_pic_cnt_present_flag = 807 pic_param_buf->flags.bits.redundant_pic_cnt_present_flag; 808 extract_msg->flag_bitfield.bits.weighted_pred_flag = 809 pic_param_buf->flags.bits.weighted_pred_flag; 810 extract_msg->flag_bitfield.bits.entropy_coding_mode_flag = 811 pic_param_buf->flags.bits.entropy_coding_mode_flag; 812 extract_msg->flag_bitfield.bits.deblocking_filter_control_present_flag = 813 pic_param_buf->flags.bits.deblocking_filter_control_present_flag; 814 extract_msg->flag_bitfield.bits.weighted_bipred_idc = 815 pic_param_buf->flags.bits.weighted_bipred_idc; 816 extract_msg->flag_bitfield.bits.residual_colour_transform_flag = 817 pic_param_buf->residual_colour_transform_flag; 818 extract_msg->flag_bitfield.bits.chroma_format_idc = 819 pic_param_buf->chroma_format_idc; 820 extract_msg->flag_bitfield.bits.idr_flag = 821 pic_param_buf->idr_flag; 822 extract_msg->flag_bitfield.bits.pic_order_cnt_type = 823 pic_param_buf->pic_order_cnt_type; 824 825 extract_msg->pic_param0.bits.num_slice_groups_minus1 = 826 pic_param_buf->num_slice_groups_minus1; 827 extract_msg->pic_param0.bits.slice_group_map_type = 828 pic_param_buf->slice_group_map_type; 829 extract_msg->pic_param0.bits.log2_slice_group_change_cycle = 830 pic_param_buf->log2_slice_group_change_cycle; 831 extract_msg->pic_param0.bits.num_ref_idc_l0_active_minus1 = 832 pic_param_buf->num_ref_idc_l0_active_minus1; 833 834 extract_msg->pic_param0.bits.log2_max_pic_order_cnt_lsb_minus4 = 835 pic_param_buf->log2_max_pic_order_cnt_lsb_minus4; 836 extract_msg->pic_param0.bits.log2_max_frame_num_minus4 = 837 pic_param_buf->log2_max_frame_num_minus4; 838 extract_msg->pic_param0.bits.num_ref_idc_l1_active_minus1 = 839 pic_param_buf->num_ref_idc_l1_active_minus1; 840 extract_msg->pic_param0.bits.slice_header_bit_offset = 841 pic_param_buf->slice_offset; 842 843 844 RELOC_MSG(extract_msg->src, frame_obj_buffer->psb_buffer->buffer_ofs, frame_obj_buffer->psb_buffer); 845 RELOC_MSG(extract_msg->dst, slice_header_obj_buffer->psb_buffer->buffer_ofs, slice_header_obj_buffer->psb_buffer); 846 847 cmdbuf->parse_count++; 848 849 psb__suspend_buffer(driver_data, frame_obj_buffer); 850 psb__suspend_buffer(driver_data, slice_header_obj_buffer); 851 852 if (psb_context_flush_cmdbuf(obj_context)) 853 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_H264: flush parse cmdbuf error\n"); 854 855 return vaStatus; 856} 857#endif 858 859#define SCALING_LIST_4x4_SIZE ((4*4)) 860#define SCALING_LIST_8x8_SIZE ((8*8)) 861 862static void psb__H264_build_SCA_chunk(context_H264_p ctx) 863{ 864 VAIQMatrixBufferH264 dummy_iq_matrix; 865 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 866 867 VAIQMatrixBufferH264 *iq_matrix = ctx->iq_matrix; 868 869 if (!iq_matrix) { 870 drv_debug_msg(VIDEO_DEBUG_GENERAL, "H264: No IQ matrix received for frame. Sending dummy IQ matrix.\n"); 871 iq_matrix = &dummy_iq_matrix; 872 memset(iq_matrix, 0, sizeof(VAIQMatrixBufferH264)); 873 } 874 875 psb_cmdbuf_rendec_start(cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET); 876 877 /* 8x8 Inter Y */ 878 psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList8x8[1], SCALING_LIST_8x8_SIZE); 879 880 /* 8x8 Intra Y */ 881 psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList8x8[0], SCALING_LIST_8x8_SIZE); 882 883 /* 4x4 Intra Y */ 884 psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[0], SCALING_LIST_4x4_SIZE); 885 886 /* 4x4 Inter Y */ 887 psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[3], SCALING_LIST_4x4_SIZE); 888 889 /* 4x4 Inter Cb */ 890 psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[4], SCALING_LIST_4x4_SIZE); 891 892 /* 4x4 Intra Cb */ 893 psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[1], SCALING_LIST_4x4_SIZE); 894 895 /* 4x4 Inter Cr */ 896 psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[5], SCALING_LIST_4x4_SIZE); 897 898 /* 4x4 Intra Cr */ 899 psb_cmdbuf_rendec_write_block(cmdbuf, iq_matrix->ScalingList4x4[2], SCALING_LIST_4x4_SIZE); 900 901 psb_cmdbuf_rendec_end(cmdbuf); 902} 903 904static void psb__H264_build_picture_order_chunk(context_H264_p ctx) 905{ 906 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 907 VAPictureParameterBufferH264 *pic_params = ctx->pic_params; 908 uint32_t reg_value; 909 int i; 910 911 /* CHUNK: POC */ 912 /* send Picture Order Counts (b frame only?) */ 913 /* maybe need a state variable to track if this has already been sent for the frame */ 914 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_FOC0)); 915 916 reg_value = 0; 917 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_FOC0, TOPFIELDORDERCNT_CURR, 918 SIGNTRUNC(pic_params->CurrPic.TopFieldOrderCnt)); 919 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 920 921 reg_value = 0; 922 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_FOC1, BOTTOMFIELDORDERCNT_CURR, 923 SIGNTRUNC(pic_params->CurrPic.BottomFieldOrderCnt)); 924 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 925 926 if (pic_params->num_ref_frames > 16) { 927 drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid reference number %d, set to 16\n", pic_params->num_ref_frames); 928 pic_params->num_ref_frames = 16; 929 } 930 931 for (i = 0; i < pic_params->num_ref_frames; i++) { 932 if (pic_params->ReferenceFrames[i].flags == VA_PICTURE_H264_INVALID) { 933 continue; 934 } 935 reg_value = 0; 936 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_TOP_FOC, TOPFIELDORDERCNT, 937 SIGNTRUNC(pic_params->ReferenceFrames[i].TopFieldOrderCnt)); 938 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 939 940 reg_value = 0; 941 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_BOT_FOC, BOTTOMFIELDORDERCNT, 942 SIGNTRUNC(pic_params->ReferenceFrames[i].BottomFieldOrderCnt)); 943 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 944 } 945 946 psb_cmdbuf_rendec_end(cmdbuf); 947} 948 949static void psb__H264_build_B_slice_chunk(context_H264_p ctx, VASliceParameterBufferH264 *slice_param) 950{ 951 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 952 VAPictureParameterBufferH264 *pic_params = ctx->pic_params; 953 uint32_t reg_value; 954 int i; 955 956 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_COL_PIC0)); 957 958 /* Colocated picture is picture 0 in list 1*/ 959 object_surface_p colocated_surface = SURFACE(slice_param->RefPicList1[0].picture_id); 960 if (colocated_surface) { 961 uint32_t bottom_field_flag; 962 if (pic_params->pic_fields.bits.field_pic_flag) { 963 bottom_field_flag = (slice_param->RefPicList1[0].flags & VA_PICTURE_H264_BOTTOM_FIELD) ? 1 : 0; 964 } else { 965 /* when current pic is a frame col bottom field flag is different */ 966 IMG_INT32 i32Cur; 967 IMG_INT32 i32Top, i32Bot; 968 IMG_INT32 i32TopAbsDiffPoc, i32BotAbsDiffPoc; 969 970 /* current pic */ 971 i32Top = pic_params->CurrPic.TopFieldOrderCnt; 972 i32Bot = pic_params->CurrPic.BottomFieldOrderCnt; 973 i32Cur = (i32Top < i32Bot) ? i32Top : i32Bot; 974 975 /* col pic */ 976 i32Top = slice_param->RefPicList1[0].TopFieldOrderCnt; 977 i32Bot = slice_param->RefPicList1[0].BottomFieldOrderCnt; 978 979 i32TopAbsDiffPoc = (i32Cur < i32Top) ? i32Top - i32Cur : i32Cur - i32Top; 980 i32BotAbsDiffPoc = (i32Cur < i32Bot) ? i32Bot - i32Cur : i32Cur - i32Bot; 981 982 bottom_field_flag = (i32TopAbsDiffPoc < i32BotAbsDiffPoc) ? 0 : 1; 983 } 984 985 reg_value = GET_SURFACE_INFO_col_pic_params(colocated_surface->psb_surface); 986 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_COL_PIC0, COL_BOTTOM_FIELD_FLAG, bottom_field_flag); 987 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 988 989 psb_buffer_p colocated_target_buffer = vld_dec_lookup_colocated_buffer(&ctx->dec_ctx, colocated_surface->psb_surface); 990 ASSERT(colocated_target_buffer); 991 if (colocated_target_buffer) { 992 psb_cmdbuf_rendec_write_address(cmdbuf, colocated_target_buffer, 0); 993 } else { 994 /* This is an error */ 995 psb_cmdbuf_rendec_write(cmdbuf, 0); 996 } 997 } else { 998 /* Need some better error handling here */ 999 psb_cmdbuf_rendec_write(cmdbuf, 0); 1000 psb_cmdbuf_rendec_write(cmdbuf, 0xDEADBEEF); 1001 } 1002 1003 /* Calculate inverse index for reference pictures */ 1004 { 1005 IMG_UINT8 list0_inverse[32]; 1006 memset(list0_inverse, 0xff, 32); /* Unused entries get 0xff */ 1007 1008 if (slice_param->num_ref_idx_l0_active_minus1 + 1 > 32) { 1009 drv_debug_msg(VIDEO_DEBUG_ERROR, "num_ref_idx_l0_active_minus1(%d) is too big. Set it with 31\n", 1010 slice_param->num_ref_idx_l0_active_minus1); 1011 slice_param->num_ref_idx_l0_active_minus1 = 31; 1012 } 1013 1014 if (slice_param->num_ref_idx_l0_active_minus1 > 30) 1015 slice_param->num_ref_idx_l0_active_minus1 = 30; 1016 for (i = slice_param->num_ref_idx_l0_active_minus1 + 1; i--;) { 1017 object_surface_p surface = SURFACE(slice_param->RefPicList0[i].picture_id); 1018 if (surface) { 1019 uint32_t dpb_idx = GET_SURFACE_INFO_dpb_idx(surface->psb_surface); 1020 if (dpb_idx < 16) { 1021 if (slice_param->RefPicList0[i].flags & VA_PICTURE_H264_BOTTOM_FIELD) { 1022 dpb_idx |= 0x10; 1023 } 1024 list0_inverse[dpb_idx] = i; 1025 } 1026 } 1027 } 1028 for (i = 0; i < 32; i += 4) { 1029 reg_value = 0; 1030 reg_value |= list0_inverse[i]; 1031 reg_value |= list0_inverse[i+1] << 8; 1032 reg_value |= list0_inverse[i+2] << 16; 1033 reg_value |= list0_inverse[i+3] << 24; 1034 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1035 } 1036 } 1037 1038 if (slice_param->num_ref_idx_l1_active_minus1 > 28) 1039 slice_param->num_ref_idx_l1_active_minus1 = 28; 1040 1041 /* Write Ref List 1 - but only need the valid ones */ 1042 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i += 4) { 1043 reg_value = 0; 1044 reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList1[i]); 1045 reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList1[i+1]) << 8; 1046 reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList1[i+2]) << 16; 1047 reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList1[i+3]) << 24; 1048 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1049 } 1050 1051 psb_cmdbuf_rendec_end(cmdbuf); 1052} 1053 1054static void psb__H264_build_register(context_H264_p ctx, VASliceParameterBufferH264 *slice_param) 1055{ 1056 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1057 uint32_t reg_value; 1058 1059 psb_cmdbuf_reg_start_block(cmdbuf, 0); 1060 1061 reg_value = 0; 1062 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_PROFILE, ctx->profile); 1063 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_MODE, 1); /* 1 - H.264 */ 1064 1065 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL), reg_value); 1066 1067 /* write the FE registers */ 1068 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_SPS0), ctx->reg_SPS0); 1069 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_PPS0), ctx->reg_PPS0); 1070 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_CUR_PIC0), ctx->reg_PIC0); 1071 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE0), ctx->slice0_params); 1072 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1), ctx->slice1_params); 1073 1074 reg_value = 0; 1075 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE2, FIRST_MB_IN_SLICE, slice_param->first_mb_in_slice); 1076 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE2), reg_value); 1077 1078 if (ctx->pic_params->num_slice_groups_minus1 >= 1) { 1079 ctx->obj_context->driver_data->ec_enabled = 0; 1080 ASSERT(ctx->slice_group_map_buffer); 1081 if (ctx->slice_group_map_buffer) { 1082 psb_cmdbuf_reg_set_address(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_H264, CR_VEC_H264_FE_BASE_ADDR_SGM), 1083 ctx->slice_group_map_buffer, 0); 1084 } 1085 } 1086 psb_cmdbuf_reg_end_block(cmdbuf); 1087} 1088 1089static void psb__H264_build_rendec_params(context_H264_p ctx, VASliceParameterBufferH264 *slice_param) 1090{ 1091 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1092 psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; 1093 VAPictureParameterBufferH264 *pic_params = ctx->pic_params; 1094 uint32_t reg_value; 1095 unsigned int i; 1096 1097 /* psb_cmdbuf_rendec_start_block( cmdbuf ); */ 1098 1099 /* CHUNK: Entdec back-end profile and level */ 1100 { 1101 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL)); 1102 1103 reg_value = 0; 1104 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_PROFILE, ctx->profile); 1105 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_MODE, 1); /* 1 - H.264 */ 1106 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1107 1108 psb_cmdbuf_rendec_end(cmdbuf); 1109 } 1110 1111 /* CHUNK: SEQ Registers */ 1112 /* send Slice Data for every slice */ 1113 /* MUST be the last slice sent */ 1114 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_SPS0)); 1115 1116 psb_cmdbuf_rendec_write(cmdbuf, ctx->reg_SPS0); 1117 psb_cmdbuf_rendec_write(cmdbuf, ctx->reg_PPS0); 1118 psb_cmdbuf_rendec_write(cmdbuf, ctx->reg_PIC0); 1119 psb_cmdbuf_rendec_write(cmdbuf, ctx->slice0_params); 1120 psb_cmdbuf_rendec_write(cmdbuf, ctx->slice1_params); 1121 1122 /* 5.5.75. VEC_H264_BE_BASE_ADDR_CUR_PIC */ 1123 psb_buffer_p colocated_target_buffer = vld_dec_lookup_colocated_buffer(&ctx->dec_ctx, target_surface); 1124 ASSERT(colocated_target_buffer); 1125 if (colocated_target_buffer) { 1126 psb_cmdbuf_rendec_write_address(cmdbuf, colocated_target_buffer, colocated_target_buffer->buffer_ofs); 1127 } else { 1128 /* This is an error */ 1129 psb_cmdbuf_rendec_write(cmdbuf, 0); 1130 } 1131 1132 reg_value = 0; 1133 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_H264, CR_VEC_H264_BE_REF0, BE_LONGTERMFRAMEFLAG, ctx->long_term_frame_flags); 1134 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1135 1136 psb_cmdbuf_rendec_end(cmdbuf); 1137 1138 //#warning "TODO: MUST be done after fe slice1 (which gives MB address) " 1139 /* REGIO_WRITE_REGISTER(0, MSVDX_VEC_H264, CR_VEC_H264_FE_BASE_ADDR_SGM, gui32SliceGroupType6BaseAddressHack); */ 1140 1141 /* CHUNK: SCA */ 1142 /* send Scaling Lists in High Profile for first slice*/ 1143 if (ctx->profile == H264_HIGH_PROFILE) { 1144 psb__H264_build_SCA_chunk(ctx); 1145 } 1146 1147 /* CHUNK: POC */ 1148 /* send Picture Order Counts (b frame only?) */ 1149 /* maybe need a state variable to track if this has already been sent for the frame */ 1150 if (slice_param->slice_type == ST_B) { 1151 psb__H264_build_picture_order_chunk(ctx); 1152 } 1153 1154 /* CHUNK: BIN */ 1155 /* send B-slice information for B-slices */ 1156 if (slice_param->slice_type == ST_B) { 1157 psb__H264_build_B_slice_chunk(ctx, slice_param); 1158 } 1159 1160 /* CHUNK: PIN */ 1161 /* send P+B-slice information for P and B slices */ 1162 if (slice_param->slice_type == ST_B || slice_param->slice_type == ST_P) { 1163 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, H264_CR_VEC_H264_BE_LIST0)); 1164 1165 if (slice_param->num_ref_idx_l0_active_minus1 > 31) { 1166 drv_debug_msg(VIDEO_DEBUG_ERROR, "num_ref_idx_l0_active_minus1(%d) is too big, limit it to 31.\n", 1167 slice_param->num_ref_idx_l0_active_minus1); 1168 slice_param->num_ref_idx_l0_active_minus1 = 28; 1169 } 1170 1171 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i += 4) { 1172 reg_value = 0; 1173 reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i]); 1174 reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i+1]) << 8; 1175 reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i+2]) << 16; 1176 reg_value |= PICTURE2INDEX(ctx, &slice_param->RefPicList0[i+3]) << 24; 1177 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1178 } 1179 1180 psb_cmdbuf_rendec_end(cmdbuf); 1181 } 1182 1183 /* CHUNK: DPB */ 1184 /* send DPB information (for P and B slices?) only needed once per frame */ 1185// if ( sh->slice_type == ST_B || sh->slice_type == ST_P ) 1186 if (pic_params->num_ref_frames > 0 && (slice_param->slice_type == ST_B || slice_param->slice_type == ST_P)) { 1187 IMG_BOOL is_used[16]; 1188 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES)); 1189 1190 /* Mark all surfaces as unused */ 1191 memset(is_used, 0, sizeof(is_used)); 1192 1193 if (slice_param->num_ref_idx_l0_active_minus1 > 31) 1194 slice_param->num_ref_idx_l0_active_minus1 = 31; 1195 /* Mark onlys frame that are actualy used */ 1196 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) { 1197 object_surface_p ref_surface = SURFACE(slice_param->RefPicList0[i].picture_id); 1198 if (ref_surface) { 1199 uint32_t idx = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface); 1200 if (idx < 16) { 1201 is_used[idx] = IMG_TRUE; 1202 } 1203 } 1204 } 1205 1206 if (slice_param->num_ref_idx_l1_active_minus1 > 31) 1207 slice_param->num_ref_idx_l1_active_minus1 = 31; 1208 1209 /* Mark onlys frame that are actualy used */ 1210 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) { 1211 object_surface_p ref_surface = SURFACE(slice_param->RefPicList1[i].picture_id); 1212 if (ref_surface) { 1213 uint32_t idx = GET_SURFACE_INFO_dpb_idx(ref_surface->psb_surface); 1214 if (idx < 16) { 1215 is_used[idx] = IMG_TRUE; 1216 } 1217 } 1218 } 1219 1220 if (pic_params->num_ref_frames > 16) 1221 pic_params->num_ref_frames = 16; 1222 /* Only load used surfaces */ 1223 for (i = 0; i < pic_params->num_ref_frames; i++) { 1224 if (pic_params->ReferenceFrames[i].flags == VA_PICTURE_H264_INVALID) { 1225 continue; 1226 } 1227 object_surface_p ref_surface = SURFACE(pic_params->ReferenceFrames[i].picture_id); 1228 psb_buffer_p buffer; 1229 1230 if (NULL == ref_surface) { 1231 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalide reference surface handle\n", 1232 __FUNCTION__, __LINE__); 1233 return; 1234 } 1235 1236 buffer = ref_surface->psb_surface->ref_buf; 1237 /* 1238 drv_debug_msg(VIDEO_DEBUG_GENERAL, "pic_params->ReferenceFrames[%d] = %08x --> %08x frame_idx:0x%08x flags:%02x TopFieldOrderCnt: 0x%08x BottomFieldOrderCnt: 0x%08x %s\n", 1239 i, 1240 pic_params->ReferenceFrames[i].picture_id, 1241 ref_surface, 1242 pic_params->ReferenceFrames[i].frame_idx, 1243 pic_params->ReferenceFrames[i].flags, 1244 pic_params->ReferenceFrames[i].TopFieldOrderCnt, 1245 pic_params->ReferenceFrames[i].BottomFieldOrderCnt, 1246 is_used[i] ? "used" : ""); 1247 */ 1248 if (ref_surface && is_used[i] && buffer) 1249 // GET_SURFACE_INFO_is_used(ref_surface->psb_surface)) 1250 { 1251 psb_cmdbuf_rendec_write_address(cmdbuf, buffer, 1252 buffer->buffer_ofs); 1253 psb_cmdbuf_rendec_write_address(cmdbuf, buffer, 1254 buffer->buffer_ofs + 1255 ref_surface->psb_surface->chroma_offset); 1256 buffer->unfence_flag = 1; 1257 } else { 1258 psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef); 1259 psb_cmdbuf_rendec_write(cmdbuf, 0xdeadbeef); 1260 } 1261 } 1262 psb_cmdbuf_rendec_end(cmdbuf); 1263 } 1264 1265 /* CHUNK: MVA and MVB */ 1266 /* works as long as weighted factors A and B commands remain the same */ 1267 if ((pic_params->pic_fields.bits.weighted_pred_flag && (slice_param->slice_type == ST_P)) || 1268 ((pic_params->pic_fields.bits.weighted_bipred_idc != 0) && (slice_param->slice_type == ST_B))) { 1269 IMG_UINT32 num_ref_0 = slice_param->num_ref_idx_l0_active_minus1; 1270 1271 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, H264_WEIGHTED_FACTORS_A)); 1272 1273 if (num_ref_0 > 31) 1274 num_ref_0 = 31; 1275 1276 /* weighted factors */ 1277 for (i = 0; i <= num_ref_0; i++) { 1278 reg_value = 0; 1279 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_A, CR_WEIGHT_A, slice_param->chroma_weight_l0[i][1]);/* Cr - 1 */ 1280 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_A, CB_WEIGHT_A, slice_param->chroma_weight_l0[i][0]);/* Cb - 0 */ 1281 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_A, Y_WEIGHT_A, slice_param->luma_weight_l0[i]); 1282 1283 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1284 } 1285 /* pad remainder */ 1286 for (; i < 32; i++) { 1287 psb_cmdbuf_rendec_write(cmdbuf, 0); 1288 } 1289 1290 /* weighted offsets */ 1291 for (i = 0; i <= num_ref_0; i++) { 1292 reg_value = 0; 1293 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_A, CR_OFFSET_A, slice_param->chroma_offset_l0[i][1]);/* Cr - 1 */ 1294 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_A, CB_OFFSET_A, slice_param->chroma_offset_l0[i][0]);/* Cb - 0 */ 1295 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_A, Y_OFFSET_A, slice_param->luma_offset_l0[i]); 1296 1297 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1298 } 1299 /* pad remainder */ 1300 for (; i < 32; i++) { 1301 psb_cmdbuf_rendec_write(cmdbuf, 0); 1302 } 1303 psb_cmdbuf_rendec_end(cmdbuf); 1304 1305 if (slice_param->slice_type == ST_B) { 1306 IMG_UINT32 num_ref_1 = slice_param->num_ref_idx_l1_active_minus1; 1307 1308 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, H264_WEIGHTED_FACTORS_B)); 1309 1310 if (num_ref_1 > 31) { 1311 drv_debug_msg(VIDEO_DEBUG_ERROR, "num_ref_1 shouldn't be larger than 31\n"); 1312 num_ref_1 = 31; 1313 } 1314 1315 /* weighted factors */ 1316 for (i = 0; i <= num_ref_1; i++) { 1317 reg_value = 0; 1318 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_B, CR_WEIGHT_B, slice_param->chroma_weight_l1[i][1]);/* Cr - 1 */ 1319 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_B, CB_WEIGHT_B, slice_param->chroma_weight_l1[i][0]);/* Cb - 0 */ 1320 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTORS_B, Y_WEIGHT_B, slice_param->luma_weight_l1[i]); 1321 1322 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1323 } 1324 /* pad remainder */ 1325 for (; i < 32; i++) { 1326 psb_cmdbuf_rendec_write(cmdbuf, 0); 1327 } 1328 1329 /* weighted offsets */ 1330 for (i = 0; i <= num_ref_1; i++) { 1331 reg_value = 0; 1332 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_B, CR_OFFSET_B, slice_param->chroma_offset_l1[i][1]);/* Cr - 1 */ 1333 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_B, CB_OFFSET_B, slice_param->chroma_offset_l1[i][0]);/* Cb - 0 */ 1334 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_OFFSET_B, Y_OFFSET_B, slice_param->luma_offset_l1[i]); 1335 1336 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1337 } 1338 /* pad remainder */ 1339 for (; i < 32; i++) { 1340 psb_cmdbuf_rendec_write(cmdbuf, 0); 1341 } 1342 psb_cmdbuf_rendec_end(cmdbuf); 1343 } 1344 } 1345 1346 1347 /* CHUNK: SEQ Commands 1 */ 1348 /* send Slice Data for every slice */ 1349 /* MUST be the last slice sent */ 1350 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE)); 1351 1352 reg_value = 0; 1353 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_HEIGHT, (ctx->picture_height_mb * 16) - 1); 1354 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_WIDTH, (ctx->picture_width_mb * 16) - 1); 1355 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1356 1357 reg_value = 0; 1358 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_HEIGHT, (ctx->picture_height_mb * 16) - 1); 1359 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_WIDTH, (ctx->picture_width_mb * 16) - 1); 1360 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1361 1362 reg_value = 0; 1363 // TODO: Must check how these should be set 1364 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CHROMA_INTERLEAVED, 0); 1365 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, ROW_STRIDE, target_surface->stride_mode); 1366 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CODEC_PROFILE, ctx->profile); 1367 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CODEC_MODE, 1); /* H.264 */ 1368 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, (ctx->two_pass_mode && !ctx->pic_params->seq_fields.bits.mb_adaptive_frame_field_flag)); 1369 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, pic_params->seq_fields.bits.chroma_format_idc); 1370 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1371 1372 ctx->obj_context->operating_mode = reg_value; 1373 1374 if ((ctx->deblock_mode == DEBLOCK_INTRA_OOLD) && ctx->two_pass_mode) { /* Need to mark which buf is to be used as ref*/ 1375 /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1376 psb_cmdbuf_rendec_write_address(cmdbuf, target_surface->in_loop_buf, target_surface->in_loop_buf->buffer_ofs); 1377 1378 /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1379 psb_cmdbuf_rendec_write_address(cmdbuf, target_surface->in_loop_buf, target_surface->in_loop_buf->buffer_ofs + target_surface->chroma_offset); 1380 target_surface->ref_buf = target_surface->in_loop_buf; 1381 //target_surface->in_loop_buf->unfence_flag |= 2; 1382 } else { 1383 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs); 1384 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); 1385 target_surface->ref_buf = &target_surface->buf; 1386 //target_surface->buf.unfence_flag = 2; 1387 } 1388 1389 /* Aux Msb Buffer base address: H.264 does not use this command */ 1390 reg_value = 0; 1391 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1392 1393 /* Intra Reference Cache */ 1394 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->reference_cache, 0); 1395 1396 reg_value = 0; 1397 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, MC_CACHE_CONFIGURATION, CONFIG_REF_OFFSET, CACHE_REF_OFFSET); 1398 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, MC_CACHE_CONFIGURATION, CONFIG_ROW_OFFSET, CACHE_ROW_OFFSET); 1399 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1400 1401 /* Vc1 Intensity compensation: H.264 does not use this command */ 1402 reg_value = 0; 1403 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1404 1405 reg_value = 0; 1406 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTOR_DENOMINATOR, C_LOG2_WEIGHT_DENOM, slice_param->chroma_log2_weight_denom); 1407 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, H264_WEIGHTED_FACTOR_DENOMINATOR, Y_LOG2_WEIGHT_DENOM, slice_param->luma_log2_weight_denom); 1408 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1409 1410 psb_cmdbuf_rendec_end(cmdbuf); 1411 1412 /* CHUNK: SEQ Commands 2 */ 1413 /* send Slice Data for every slice */ 1414 /* MUST be the last slice sent */ 1415 { 1416 IMG_UINT32 ui32Mode = pic_params->pic_fields.bits.weighted_pred_flag | (pic_params->pic_fields.bits.weighted_bipred_idc << 1); 1417 1418 psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS)); 1419 1420 reg_value = 0; 1421 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, CONSTRAINED_INTRA_PRED, pic_params->pic_fields.bits.constrained_intra_pred_flag); 1422 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, MODE_CONFIG, ui32Mode); 1423 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, DISABLE_DEBLOCK_FILTER_IDC, slice_param->disable_deblocking_filter_idc); 1424 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_ALPHA_CO_OFFSET_DIV2, slice_param->slice_alpha_c0_offset_div2); 1425 REGIO_WRITE_FIELD_MASKEDLITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_BETA_OFFSET_DIV2, slice_param->slice_beta_offset_div2); 1426 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_FIELD_TYPE, ctx->field_type); 1427 REGIO_WRITE_FIELD_LITE(reg_value, MSVDX_CMDS, SLICE_PARAMS, SLICE_CODE_TYPE, aSliceTypeVAtoMsvdx[slice_param->slice_type % 5]); 1428 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 1429 1430 /* Store slice parameters in header */ 1431 *(ctx->dec_ctx.p_slice_params) = reg_value; 1432 1433 psb_cmdbuf_rendec_end(cmdbuf); 1434 } 1435 1436 /* If this a two pass mode deblock, then we will perform the rotation as part of the 1437 * 2nd pass deblock procedure 1438 */ 1439 if (!ctx->two_pass_mode) 1440 vld_dec_setup_alternative_frame(ctx->obj_context); 1441} 1442 1443static void psb__H264_preprocess_slice(context_H264_p ctx, 1444 VASliceParameterBufferH264 *slice_param) 1445{ 1446 VAPictureParameterBufferH264 *pic_params = ctx->pic_params; 1447 uint32_t slice_qpy; 1448 1449 ctx->first_mb_x = slice_param->first_mb_in_slice % ctx->picture_width_mb; 1450 ctx->first_mb_y = slice_param->first_mb_in_slice / ctx->picture_width_mb; 1451 ctx->slice0_params = 0; 1452 ctx->slice1_params = 0; 1453 1454 ASSERT(pic_params); 1455 if (!pic_params) { 1456 /* This is an error */ 1457 return; 1458 } 1459 1460 if (!pic_params->pic_fields.bits.field_pic_flag && pic_params->seq_fields.bits.mb_adaptive_frame_field_flag) { 1461 /* If in MBAFF mode multiply MB y-address by 2 */ 1462 ctx->first_mb_y *= 2; 1463 } 1464 1465 slice_qpy = 26 + pic_params->pic_init_qp_minus26 + slice_param->slice_qp_delta; /* (7-27) */ 1466 1467 REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_BE_SLICE0, BE_DIRECT_SPATIAL_MV_PRED_FLAG, slice_param->direct_spatial_mv_pred_flag); 1468 REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_BE_SLICE0, H264_BE_SLICE0_DISABLE_DEBLOCK_FILTER_IDC, slice_param->disable_deblocking_filter_idc); 1469 REGIO_WRITE_FIELD_MASKEDLITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_BE_SLICE0, H264_BE_SLICE0_ALPHA_CO_OFFSET_DIV2, slice_param->slice_alpha_c0_offset_div2); 1470 REGIO_WRITE_FIELD_MASKEDLITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_BE_SLICE0, H264_BE_SLICE0_BETA_OFFSET_DIV2, slice_param->slice_beta_offset_div2); 1471 REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_BE_SLICE0, H264_BE_SLICE0_FIELD_TYPE, ctx->field_type); 1472 REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE0, SLICETYPE, aSliceTypeVAtoMsvdx[ slice_param->slice_type % 5]); 1473 REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE0, CABAC_INIT_IDC, slice_param->cabac_init_idc); 1474 REGIO_WRITE_FIELD_LITE(ctx->slice0_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE0, SLICECOUNT, ctx->slice_count); 1475 1476 REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, FIRST_MB_IN_SLICE_X, ctx->first_mb_x); 1477 REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, FIRST_MB_IN_SLICE_Y, ctx->first_mb_y); 1478 REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, SLICEQPY, slice_qpy); 1479 REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, NUM_REF_IDX_L0_ACTIVE_MINUS1, slice_param->num_ref_idx_l0_active_minus1); 1480 REGIO_WRITE_FIELD_LITE(ctx->slice1_params, MSVDX_VEC_H264, CR_VEC_H264_FE_SLICE1, NUM_REF_IDX_L1_ACTIVE_MINUS1, slice_param->num_ref_idx_l1_active_minus1); 1481 1482 IMG_BOOL deblocker_disable = (slice_param->disable_deblocking_filter_idc == 1); 1483 1484 if (deblocker_disable) { 1485 if (ctx->obj_context->is_oold) { 1486 ctx->deblock_mode = DEBLOCK_INTRA_OOLD; 1487 ctx->two_pass_mode = 1; 1488 REGIO_WRITE_FIELD_LITE(ctx->reg_SPS0, MSVDX_VEC_H264, CR_VEC_H264_BE_SPS0, H264_BE_SPS0_2PASS_FLAG, ctx->two_pass_mode); 1489 } else 1490 ctx->deblock_mode = DEBLOCK_STD; 1491 } else { 1492 ctx->deblock_mode = DEBLOCK_STD; 1493 } 1494} 1495 1496/* **************************************************************************************************************** */ 1497/* Prepacked calculates VLC table offsets and reg address */ 1498/* **************************************************************************************************************** */ 1499static const IMG_UINT32 ui32H264VLCTableRegValPair[] = { 1500 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000000), 0x00026000, 1501 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000004), 0x000738a0, 1502 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000008), 0x000828f4, 1503 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x0000000c), 0x000a312d, 1504 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000010), 0x000b5959, 1505 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000014), 0x000c517b, 1506 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000018), 0x000d1196, 1507 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x0000001c), 0x000db1ad, 1508 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000020), 0x000e21be, 1509 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000024), 0x000e59c8, 1510 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000028), 0x000e79cd, 1511 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x0000002c), 0x000eb1d3, 1512 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000030), 0x000ed1d8, 1513 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000034), 0x000f09dd, 1514 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000038), 0x000f71e7, 1515 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x0000003c), 0x000001f6, 1516 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000040), 0x1256a4dd, 1517 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000044), 0x01489292, 1518 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000048), 0x11248050, 1519 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x0000004c), 0x00000002, 1520 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000050), 0x00002a02, 1521 (REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0) + 0x00000054), 0x0108282a, 1522}; 1523 1524 1525static void psb__H264_write_VLC_tables(context_H264_p ctx) 1526{ 1527 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1528 unsigned int i; 1529 1530 psb_cmdbuf_skip_start_block(cmdbuf, SKIP_ON_CONTEXT_SWITCH); 1531 1532 /* VLC Table */ 1533 /* Write a LLDMA Cmd to transfer VLD Table data */ 1534 psb_cmdbuf_dma_write_cmdbuf(cmdbuf, &ctx->vlc_packed_table, 0, 1535 sizeof(ui16H264VLCTableData), 0, 1536 DMA_TYPE_VLC_TABLE); 1537 1538 /* Writes the VLD offsets. mtx need only do this on context switch*/ 1539 psb_cmdbuf_reg_start_block(cmdbuf, 0); 1540 1541 for (i = 0; i < (sizeof(ui32H264VLCTableRegValPair) / sizeof(ui32H264VLCTableRegValPair[0])) ; i += 2) { 1542 psb_cmdbuf_reg_set(cmdbuf, ui32H264VLCTableRegValPair[i] , ui32H264VLCTableRegValPair[i + 1]); 1543 } 1544 1545 psb_cmdbuf_reg_end_block(cmdbuf); 1546 1547 psb_cmdbuf_skip_end_block(cmdbuf); 1548} 1549 1550static void psb__H264_begin_slice(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param) 1551{ 1552 VASliceParameterBufferH264 *slice_param = (VASliceParameterBufferH264 *) vld_slice_param; 1553 context_H264_p ctx = (context_H264_p)dec_ctx; 1554#ifdef SLICE_HEADER_PARSING 1555 if (dec_ctx->parse_enabled == 1) 1556 dec_ctx->parse_key = slice_param->slice_data_bit_offset; 1557#endif 1558 psb__H264_preprocess_slice(ctx, slice_param); 1559 psb__H264_write_VLC_tables(ctx); 1560 1561 dec_ctx->bits_offset = slice_param->slice_data_bit_offset; 1562 1563 /* CMD_SR_VERIFY_STARTCODE, clean this flag to work when no start code in slice data */ 1564#ifdef SLICE_HEADER_PARSING 1565 if (dec_ctx->parse_enabled == 1) 1566 dec_ctx->SR_flags = CMD_ENABLE_RBDU_EXTRACTION | CMD_SR_BITSTR_PARSE_KEY; 1567 else 1568#endif 1569 dec_ctx->SR_flags = CMD_ENABLE_RBDU_EXTRACTION; 1570 ctx->slice_param = slice_param; 1571} 1572 1573static void psb__H264_process_slice_data(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param) 1574{ 1575 VASliceParameterBufferH264 *slice_param = (VASliceParameterBufferH264 *) vld_slice_param; 1576 context_H264_p ctx = (context_H264_p)dec_ctx; 1577 1578 psb__H264_build_register(ctx, slice_param); 1579 psb__H264_build_rendec_params(ctx, slice_param); 1580} 1581 1582static void psb__H264_end_slice(context_DEC_p dec_ctx) 1583{ 1584 context_H264_p ctx = (context_H264_p)dec_ctx; 1585 if (ctx->slice_count == 0) { 1586 ctx->obj_context->flags |= FW_VA_RENDER_IS_FIRST_SLICE; 1587 } 1588 if (ctx->pic_params->seq_fields.bits.mb_adaptive_frame_field_flag) { 1589 ctx->obj_context->flags |= FW_VA_RENDER_IS_H264_MBAFF; 1590 } 1591 if (ctx->two_pass_mode) { 1592 ctx->obj_context->flags |= FW_VA_RENDER_IS_TWO_PASS_DEBLOCK; 1593 } 1594 ctx->obj_context->flags |= FW_VA_RENDER_IS_VLD_NOT_MC; /* FW_ERROR_DETECTION_AND_RECOVERY */ 1595 1596#ifdef PSBVIDEO_MSVDX_EC 1597 if (ctx->obj_context->driver_data->ec_enabled) 1598 ctx->obj_context->flags |= (FW_ERROR_DETECTION_AND_RECOVERY); /* FW_ERROR_DETECTION_AND_RECOVERY */ 1599#endif 1600 1601 ctx->obj_context->first_mb = (ctx->first_mb_y << 8) | ctx->first_mb_x; 1602 ctx->obj_context->last_mb = (((ctx->picture_height_mb >> ctx->pic_params->pic_fields.bits.field_pic_flag) - 1) << 8) | (ctx->picture_width_mb - 1); 1603 *(dec_ctx->slice_first_pic_last) = (ctx->obj_context->first_mb << 16) | (ctx->obj_context->last_mb); 1604 1605 ctx->slice_count++; 1606} 1607 1608#ifdef PSBVIDEO_MSVDX_EC 1609static void psb__H264_choose_ec_frames(context_H264_p ctx) 1610{ 1611 ctx->obj_context->ec_target = NULL; 1612 if (ctx->slice_param == NULL) 1613 return; 1614 /* If reference picture list has a valid entry, this is a P or B frame and we conceal from the frame that is at the top of the list*/ 1615 if (ctx->slice_param->num_ref_idx_l0_active_minus1 >= 0) 1616 { 1617 object_surface_p ref_surface = SURFACE(ctx->slice_param->RefPicList0[0].picture_id); 1618 ctx->obj_context->ec_target = ref_surface; 1619 } 1620 /* Otherwise we conceal from the previous I or P frame*/ 1621 if (!ctx->obj_context->ec_target) 1622 { 1623 ctx->obj_context->ec_target = ctx->obj_context->ec_candidate; 1624 } 1625 1626 if (ctx->slice_param->slice_type != ST_B) 1627 { 1628 ctx->obj_context->ec_candidate = ctx->obj_context->current_render_target; /* in case the next frame is an I frame we will need this */ 1629 } 1630 if (!ctx->obj_context->ec_target) { 1631 ctx->obj_context->ec_target = ctx->obj_context->current_render_target; 1632 } 1633} 1634#endif 1635 1636static VAStatus pnw_H264_BeginPicture( 1637 object_context_p obj_context) 1638{ 1639 INIT_CONTEXT_H264 1640 1641#ifdef SLICE_HEADER_PARSING 1642 obj_context->msvdx_frame_end = 0; 1643#endif 1644 1645 if (ctx->pic_params) { 1646 free(ctx->pic_params); 1647 ctx->pic_params = NULL; 1648 } 1649 if (ctx->iq_matrix) { 1650 free(ctx->iq_matrix); 1651 ctx->iq_matrix = NULL; 1652 } 1653 ctx->slice_count = 0; 1654 ctx->slice_group_map_buffer = NULL; 1655 ctx->deblock_mode = DEBLOCK_NONE; 1656 1657 return VA_STATUS_SUCCESS; 1658} 1659 1660static VAStatus pnw_H264_process_buffer( 1661 context_DEC_p dec_ctx, 1662 object_buffer_p buffer) 1663{ 1664 context_H264_p ctx = (context_H264_p)dec_ctx; 1665 VAStatus vaStatus = VA_STATUS_SUCCESS; 1666 object_buffer_p obj_buffer = buffer; 1667 1668 { 1669 switch (obj_buffer->type) { 1670 case VAPictureParameterBufferType: 1671 vaStatus = psb__H264_process_picture_param(ctx, obj_buffer); 1672 DEBUG_FAILURE; 1673 break; 1674 1675 case VAIQMatrixBufferType: 1676 vaStatus = psb__H264_process_iq_matrix(ctx, obj_buffer); 1677 DEBUG_FAILURE; 1678 break; 1679 1680 case VASliceGroupMapBufferType: 1681 vaStatus = psb__H264_process_slice_group_map(ctx, obj_buffer); 1682 DEBUG_FAILURE; 1683 break; 1684#ifdef SLICE_HEADER_PARSING 1685 case VAParsePictureParameterBufferType: 1686 dec_ctx->parse_enabled = 1; 1687 vaStatus = psb__H264_process_slice_header_group(ctx, obj_buffer); 1688 DEBUG_FAILURE; 1689 break; 1690#endif 1691 default: 1692 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1693 DEBUG_FAILURE; 1694 } 1695 } 1696 1697 return vaStatus; 1698} 1699 1700static VAStatus pnw_H264_EndPicture( 1701 object_context_p obj_context) 1702{ 1703 INIT_CONTEXT_H264 1704 psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; 1705 psb_driver_data_p driver_data = obj_context->driver_data; 1706 VAStatus vaStatus = VA_STATUS_SUCCESS; 1707 1708 if (ctx->two_pass_mode) { 1709 psb_buffer_p colocated_target_buffer = vld_dec_lookup_colocated_buffer(&ctx->dec_ctx, target_surface); 1710 psb_surface_p rotate_surface = ctx->obj_context->current_render_target->out_loop_surface; 1711 uint32_t rotation_flags = 0; 1712 uint32_t ext_stride_a = 0; 1713 1714 drv_debug_msg(VIDEO_DEBUG_GENERAL, "pnw_H264_EndPicture got two pass mode frame\n"); 1715 if (CONTEXT_ROTATE(ctx->obj_context)) { 1716 ASSERT(rotate_surface); 1717 REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ALT_PICTURE_ENABLE, 1); 1718 REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_ROW_STRIDE, rotate_surface->stride_mode); 1719 REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */ 1720 REGIO_WRITE_FIELD_LITE(rotation_flags, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_MODE, GET_SURFACE_INFO_rotate(rotate_surface)); 1721 } 1722 1723 REGIO_WRITE_FIELD_LITE(ext_stride_a, MSVDX_CMDS, EXTENDED_ROW_STRIDE, EXT_ROW_STRIDE, target_surface->stride / 64); 1724 1725 /* Issue two pass deblock cmd, HW can handle deblock instead of host when using DE2.x firmware */ 1726 if (ctx->deblock_mode == DEBLOCK_STD) { 1727 if (psb_context_submit_hw_deblock(ctx->obj_context, 1728 &target_surface->buf, 1729 rotate_surface ? (&rotate_surface->buf) : NULL, 1730 colocated_target_buffer, 1731 ctx->picture_width_mb, 1732 ctx->picture_height_mb, 1733 rotation_flags, 1734 ctx->field_type, 1735 ext_stride_a, 1736 target_surface->chroma_offset + target_surface->buf.buffer_ofs, 1737 rotate_surface ? (rotate_surface->chroma_offset + rotate_surface->buf.buffer_ofs) : 0, 1738 ctx->deblock_mode == DEBLOCK_INTRA_OOLD)) { 1739 return VA_STATUS_ERROR_UNKNOWN; 1740 } 1741 } else if (ctx->deblock_mode == DEBLOCK_INTRA_OOLD) { 1742 psb_buffer_p buffer_dst; 1743 uint32_t chroma_offset_dst; 1744 1745 if (CONTEXT_ROTATE(ctx->obj_context) == 0) { 1746 buffer_dst = &target_surface->buf; 1747 chroma_offset_dst = target_surface->chroma_offset; 1748 } else { 1749 if (!rotate_surface) { 1750 return VA_STATUS_ERROR_UNKNOWN; 1751 } 1752 1753 buffer_dst = &rotate_surface->buf; 1754 chroma_offset_dst = rotate_surface->chroma_offset; 1755 } 1756 1757 if (psb_context_submit_hw_deblock(ctx->obj_context, 1758 target_surface->in_loop_buf, 1759 buffer_dst, 1760 colocated_target_buffer, 1761 ctx->picture_width_mb, 1762 ctx->picture_height_mb, 1763 rotation_flags, 1764 ctx->field_type, 1765 ext_stride_a, 1766 target_surface->chroma_offset + target_surface->buf.buffer_ofs, 1767 chroma_offset_dst, 1768 ctx->deblock_mode == DEBLOCK_INTRA_OOLD)) { 1769 return VA_STATUS_ERROR_UNKNOWN; 1770 } 1771 } 1772 } 1773 1774#ifdef PSBVIDEO_MSVDX_EC 1775 /* Sent the HOST_BE_OPP command to detect slice error */ 1776 if (driver_data->ec_enabled) { 1777 uint32_t rotation_flags = 0; 1778 uint32_t ext_stride_a = 0; 1779 object_surface_p ec_target; 1780 1781 psb__H264_choose_ec_frames(ctx); 1782 ec_target = ctx->obj_context->ec_target; 1783 REGIO_WRITE_FIELD_LITE(ext_stride_a, MSVDX_CMDS, EXTENDED_ROW_STRIDE, EXT_ROW_STRIDE, target_surface->stride / 64); 1784 1785 /* FIXME ec ignor rotate condition */ 1786 if(ec_target) { 1787 if (psb_context_get_next_cmdbuf(ctx->obj_context)) { 1788 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1789 DEBUG_FAILURE; 1790 return vaStatus; 1791 } 1792 1793 if (psb_context_submit_host_be_opp(ctx->obj_context, 1794 &target_surface->buf, 1795 &ec_target->psb_surface->buf, 1796 NULL, 1797 ctx->picture_width_mb, 1798 ctx->picture_height_mb, 1799 rotation_flags, 1800 ctx->field_type, 1801 ext_stride_a, 1802 target_surface->chroma_offset + target_surface->buf.buffer_ofs, 1803 ec_target->psb_surface->chroma_offset + ec_target->psb_surface->buf.buffer_ofs)) { 1804 return VA_STATUS_ERROR_UNKNOWN; 1805 } 1806 } 1807 } 1808#endif 1809#ifdef SLICE_HEADER_PARSING 1810 if (driver_data->protected) 1811 obj_context->msvdx_frame_end = 1; 1812#endif 1813 1814 /* if scaling is enabled, rotate is not performed in 1st pass */ 1815 if (CONTEXT_ROTATE(obj_context) && CONTEXT_SCALING(obj_context)) 1816 { 1817 vld_dec_yuv_rotate(obj_context, 1818 ctx->picture_width_mb * 16, 1819 ctx->picture_height_mb * 16); 1820 ctx->dec_ctx.process_buffer = pnw_H264_process_buffer; 1821 } 1822 1823 if (psb_context_flush_cmdbuf(ctx->obj_context)) { 1824 return VA_STATUS_ERROR_UNKNOWN; 1825 } 1826 1827 if (ctx->pic_params) { 1828 free(ctx->pic_params); 1829 ctx->pic_params = NULL; 1830 } 1831 1832 if (ctx->iq_matrix) { 1833 free(ctx->iq_matrix); 1834 ctx->iq_matrix = NULL; 1835 } 1836 1837 return VA_STATUS_SUCCESS; 1838} 1839 1840struct format_vtable_s pnw_H264_vtable = { 1841queryConfigAttributes: 1842 pnw_H264_QueryConfigAttributes, 1843validateConfig: 1844 pnw_H264_ValidateConfig, 1845createContext: 1846 pnw_H264_CreateContext, 1847destroyContext: 1848 pnw_H264_DestroyContext, 1849beginPicture: 1850 pnw_H264_BeginPicture, 1851renderPicture: 1852 vld_dec_RenderPicture, 1853endPicture: 1854 pnw_H264_EndPicture 1855}; 1856