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