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