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