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