1 /* 2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved. 3 * Copyright (c) Imagination Technologies Limited, UK 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sub license, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial portions 15 * of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: 26 * Waldo Bastian <waldo.bastian (at) intel.com> 27 * 28 */ 29 30 31 #include "psb_VC1.h" 32 #include "psb_def.h" 33 #include "psb_surface.h" 34 #include "psb_cmdbuf.h" 35 #include "psb_drv_debug.h" 36 37 #include "vc1_header.h" 38 #include "vc1_defs.h" 39 40 #include "hwdefs/reg_io2.h" 41 #include "hwdefs/msvdx_offsets.h" 42 #include "hwdefs/msvdx_cmds_io2.h" 43 #include "hwdefs/msvdx_vec_reg_io2.h" 44 #include "hwdefs/msvdx_vec_vc1_reg_io2.h" 45 #include "hwdefs/msvdx_rendec_vc1_reg_io2.h" 46 #include "hwdefs/dxva_fw_ctrl.h" 47 48 #include <stdlib.h> 49 #include <stdint.h> 50 #include <string.h> 51 52 #define GET_SURFACE_INFO_is_defined(psb_surface) ((int) (psb_surface->extra_info[0])) 53 #define SET_SURFACE_INFO_is_defined(psb_surface, val) psb_surface->extra_info[0] = (uint32_t) val; 54 #define GET_SURFACE_INFO_picture_structure(psb_surface) (psb_surface->extra_info[1]) 55 #define SET_SURFACE_INFO_picture_structure(psb_surface, val) psb_surface->extra_info[1] = val; 56 #define GET_SURFACE_INFO_picture_coding_type(psb_surface) ((int) (psb_surface->extra_info[2])) 57 #define SET_SURFACE_INFO_picture_coding_type(psb_surface, val) psb_surface->extra_info[2] = (uint32_t) val; 58 #define GET_SURFACE_INFO_colocated_index(psb_surface) ((int) (psb_surface->extra_info[3])) 59 #define SET_SURFACE_INFO_colocated_index(psb_surface, val) psb_surface->extra_info[3] = (uint32_t) val; 60 61 #define SLICEDATA_BUFFER_TYPE(type) ((type==VASliceDataBufferType)?"VASliceDataBufferType":"VAProtectedSliceDataBufferType") 62 63 #define PIXELS_TO_MB(x) ((x + 15) / 16) 64 65 #define PRELOAD_BUFFER_SIZE (4*1024) 66 #define AUXMSB_BUFFER_SIZE (1024*1024) 67 68 69 typedef struct { 70 IMG_UINT32 ui32ContextId; 71 IMG_UINT32 ui32SliceParams; 72 IMG_UINT32 ui32MacroblockNumber; 73 } VC1PRELOAD; 74 75 /*! 76 ****************************************************************************** 77 @LUTs VLC table selection Look-up Tables 78 ******************************************************************************/ 79 80 typedef enum { 81 VC1_VLC_Code_3x2_2x3_tiles = 0x0, 82 VC1_VLC_FourMV_Pattern_0, 83 VC1_VLC_FourMV_Pattern_1, 84 VC1_VLC_FourMV_Pattern_2, 85 VC1_VLC_FourMV_Pattern_3, 86 VC1_VLC_High_Mot_Chroma_DC_Diff_VLC, 87 VC1_VLC_High_Mot_Inter_VLC, 88 VC1_VLC_High_Mot_Intra_VLC, 89 VC1_VLC_High_Mot_Luminance_DC_Diff_VLC, 90 VC1_VLC_High_Rate_Inter_VLC, 91 VC1_VLC_High_Rate_Intra_VLC, 92 VC1_VLC_High_Rate_SUBBLKPAT, 93 VC1_VLC_High_Rate_TTBLK, 94 VC1_VLC_High_Rate_TTMB, 95 VC1_VLC_I_Picture_CBPCY_VLC, 96 VC1_VLC_Interlace_2_MVP_Pattern_0, 97 VC1_VLC_Interlace_2_MVP_Pattern_1, 98 VC1_VLC_Interlace_2_MVP_Pattern_2, 99 VC1_VLC_Interlace_2_MVP_Pattern_3, 100 VC1_VLC_Interlace_4MV_MB_0, 101 VC1_VLC_Interlace_4MV_MB_1, 102 VC1_VLC_Interlace_4MV_MB_2, 103 VC1_VLC_Interlace_4MV_MB_3, 104 VC1_VLC_Interlace_Non_4MV_MB_0, 105 VC1_VLC_Interlace_Non_4MV_MB_1, 106 VC1_VLC_Interlace_Non_4MV_MB_2, 107 VC1_VLC_Interlace_Non_4MV_MB_3, 108 VC1_VLC_Interlaced_CBPCY_0, 109 VC1_VLC_Interlaced_CBPCY_1, 110 VC1_VLC_Interlaced_CBPCY_2, 111 VC1_VLC_Interlaced_CBPCY_3, 112 VC1_VLC_Interlaced_CBPCY_4, 113 VC1_VLC_Interlaced_CBPCY_5, 114 VC1_VLC_Interlaced_CBPCY_6, 115 VC1_VLC_Interlaced_CBPCY_7, 116 VC1_VLC_Low_Mot_Chroma_DC_Diff_VLC, 117 VC1_VLC_Low_Mot_Inter_VLC, 118 VC1_VLC_Low_Mot_Intra_VLC, 119 VC1_VLC_Low_Mot_Luminance_DC_Diff_VLC, 120 VC1_VLC_Low_Rate_SUBBLKPAT, 121 VC1_VLC_Low_Rate_TTBLK, 122 VC1_VLC_Low_Rate_TTMB, 123 VC1_VLC_Medium_Rate_SUBBLKPAT, 124 VC1_VLC_Medium_Rate_TTBLK, 125 VC1_VLC_Medium_Rate_TTMB, 126 VC1_VLC_Mid_Rate_Inter_VLC, 127 VC1_VLC_Mid_Rate_Intra_VLC, 128 VC1_VLC_Mixed_MV_MB_0, 129 VC1_VLC_Mixed_MV_MB_1, 130 VC1_VLC_Mixed_MV_MB_2, 131 VC1_VLC_Mixed_MV_MB_3, 132 VC1_VLC_Mixed_MV_MB_4, 133 VC1_VLC_Mixed_MV_MB_5, 134 VC1_VLC_Mixed_MV_MB_6, 135 VC1_VLC_Mixed_MV_MB_7, 136 VC1_VLC_Mot_Vector_Diff_VLC_0, 137 VC1_VLC_Mot_Vector_Diff_VLC_1, 138 VC1_VLC_Mot_Vector_Diff_VLC_2, 139 VC1_VLC_Mot_Vector_Diff_VLC_3, 140 VC1_VLC_One_Field_Ref_Ilace_MV_0, 141 VC1_VLC_One_Field_Ref_Ilace_MV_1, 142 VC1_VLC_One_Field_Ref_Ilace_MV_2, 143 VC1_VLC_One_Field_Ref_Ilace_MV_3, 144 VC1_VLC_One_MV_MB_0, 145 VC1_VLC_One_MV_MB_1, 146 VC1_VLC_One_MV_MB_2, 147 VC1_VLC_One_MV_MB_3, 148 VC1_VLC_One_MV_MB_4, 149 VC1_VLC_One_MV_MB_5, 150 VC1_VLC_One_MV_MB_6, 151 VC1_VLC_One_MV_MB_7, 152 VC1_VLC_P_Picture_CBPCY_VLC_0, 153 VC1_VLC_P_Picture_CBPCY_VLC_1, 154 VC1_VLC_P_Picture_CBPCY_VLC_2, 155 VC1_VLC_P_Picture_CBPCY_VLC_3, 156 VC1_VLC_Two_Field_Ref_Ilace_MV_0, 157 VC1_VLC_Two_Field_Ref_Ilace_MV_1, 158 VC1_VLC_Two_Field_Ref_Ilace_MV_2, 159 VC1_VLC_Two_Field_Ref_Ilace_MV_3, 160 VC1_VLC_Two_Field_Ref_Ilace_MV_4, 161 VC1_VLC_Two_Field_Ref_Ilace_MV_5, 162 VC1_VLC_Two_Field_Ref_Ilace_MV_6, 163 VC1_VLC_Two_Field_Ref_Ilace_MV_7, 164 165 } VC1_eVLCTables; 166 167 static IMG_UINT8 MBMODETableFLDI[][2] = { 168 {VC1_VLC_One_MV_MB_0, VC1_VLC_Mixed_MV_MB_0}, 169 {VC1_VLC_One_MV_MB_1, VC1_VLC_Mixed_MV_MB_1}, 170 {VC1_VLC_One_MV_MB_2, VC1_VLC_Mixed_MV_MB_2}, 171 {VC1_VLC_One_MV_MB_3, VC1_VLC_Mixed_MV_MB_3}, 172 {VC1_VLC_One_MV_MB_4, VC1_VLC_Mixed_MV_MB_4}, 173 {VC1_VLC_One_MV_MB_5, VC1_VLC_Mixed_MV_MB_5}, 174 {VC1_VLC_One_MV_MB_6, VC1_VLC_Mixed_MV_MB_6}, 175 {VC1_VLC_One_MV_MB_7, VC1_VLC_Mixed_MV_MB_7}, 176 }; 177 178 static IMG_UINT8 MBMODETableFRMI[][2] = { 179 {VC1_VLC_Interlace_4MV_MB_0, VC1_VLC_Interlace_Non_4MV_MB_0}, 180 {VC1_VLC_Interlace_4MV_MB_1, VC1_VLC_Interlace_Non_4MV_MB_1}, 181 {VC1_VLC_Interlace_4MV_MB_2, VC1_VLC_Interlace_Non_4MV_MB_2}, 182 {VC1_VLC_Interlace_4MV_MB_3, VC1_VLC_Interlace_Non_4MV_MB_3}, 183 }; 184 185 static IMG_UINT8 CBPCYTableProg[] = { 186 VC1_VLC_P_Picture_CBPCY_VLC_0, 187 VC1_VLC_P_Picture_CBPCY_VLC_1, 188 VC1_VLC_P_Picture_CBPCY_VLC_2, 189 VC1_VLC_P_Picture_CBPCY_VLC_3, 190 }; 191 192 static IMG_UINT8 CBPCYTableInterlaced[] = { 193 VC1_VLC_Interlaced_CBPCY_0, 194 VC1_VLC_Interlaced_CBPCY_1, 195 VC1_VLC_Interlaced_CBPCY_2, 196 VC1_VLC_Interlaced_CBPCY_3, 197 VC1_VLC_Interlaced_CBPCY_4, 198 VC1_VLC_Interlaced_CBPCY_5, 199 VC1_VLC_Interlaced_CBPCY_6, 200 VC1_VLC_Interlaced_CBPCY_7, 201 }; 202 203 static IMG_UINT8 FourMVTable[] = { 204 VC1_VLC_FourMV_Pattern_0, 205 VC1_VLC_FourMV_Pattern_1, 206 VC1_VLC_FourMV_Pattern_2, 207 VC1_VLC_FourMV_Pattern_3, 208 }; 209 210 static IMG_UINT8 Interlace2MVTable[] = { 211 VC1_VLC_Interlace_2_MVP_Pattern_0, 212 VC1_VLC_Interlace_2_MVP_Pattern_1, 213 VC1_VLC_Interlace_2_MVP_Pattern_2, 214 VC1_VLC_Interlace_2_MVP_Pattern_3, 215 }; 216 217 static IMG_UINT8 ProgressiveMVTable[] = { 218 VC1_VLC_Mot_Vector_Diff_VLC_0, 219 VC1_VLC_Mot_Vector_Diff_VLC_1, 220 VC1_VLC_Mot_Vector_Diff_VLC_2, 221 VC1_VLC_Mot_Vector_Diff_VLC_3, 222 }; 223 224 static IMG_UINT8 Interlaced1RefMVTable[] = { 225 VC1_VLC_One_Field_Ref_Ilace_MV_0, 226 VC1_VLC_One_Field_Ref_Ilace_MV_1, 227 VC1_VLC_One_Field_Ref_Ilace_MV_2, 228 VC1_VLC_One_Field_Ref_Ilace_MV_3, 229 }; 230 231 static IMG_UINT8 MVTable2RefIlace[] = { 232 VC1_VLC_Two_Field_Ref_Ilace_MV_0, 233 VC1_VLC_Two_Field_Ref_Ilace_MV_1, 234 VC1_VLC_Two_Field_Ref_Ilace_MV_2, 235 VC1_VLC_Two_Field_Ref_Ilace_MV_3, 236 VC1_VLC_Two_Field_Ref_Ilace_MV_4, 237 VC1_VLC_Two_Field_Ref_Ilace_MV_5, 238 VC1_VLC_Two_Field_Ref_Ilace_MV_6, 239 VC1_VLC_Two_Field_Ref_Ilace_MV_7, 240 }; 241 242 static IMG_UINT8 IntraTablePQIndexLT9[] = { 243 VC1_VLC_High_Rate_Intra_VLC, 244 VC1_VLC_High_Mot_Intra_VLC, 245 VC1_VLC_Mid_Rate_Intra_VLC, 246 }; 247 248 static IMG_UINT8 InterTablePQIndexLT9[] = { 249 VC1_VLC_High_Rate_Inter_VLC, 250 VC1_VLC_High_Mot_Inter_VLC, 251 VC1_VLC_Mid_Rate_Inter_VLC, 252 }; 253 254 static IMG_UINT8 IntraTablePQIndexGT8[] = { 255 VC1_VLC_Low_Mot_Intra_VLC, 256 VC1_VLC_High_Mot_Intra_VLC, 257 VC1_VLC_Mid_Rate_Intra_VLC, 258 }; 259 260 static IMG_UINT8 InterTablePQIndexGT8[] = { 261 VC1_VLC_Low_Mot_Inter_VLC, 262 VC1_VLC_High_Mot_Inter_VLC, 263 VC1_VLC_Mid_Rate_Inter_VLC, 264 }; 265 266 /* TODO: Make tables const, don't polute namespace */ 267 extern IMG_UINT16 gaui16vc1VlcTableData[]; 268 extern const IMG_UINT16 gui16vc1VlcTableSize; 269 extern IMG_UINT16 gaui16vc1VlcIndexData[VLC_INDEX_TABLE_SIZE][3]; 270 extern const IMG_UINT8 gui8vc1VlcIndexSize; 271 272 273 static IMG_UINT16 gaui16Inverse[] = {256, 128, 85, 64, 51, 43, 37, 32}; /* figure 66 */ 274 static IMG_BOOL gDMVRANGE_ExtHorizontal_RemapTable[] = {0, 1, 0, 1}; 275 static IMG_BOOL gDMVRANGE_ExtVertical_RemapTable[] = {0, 0, 1, 1}; 276 static IMG_BYTE gBFRACTION_DenRemapTable[] = {2, 3, 3, 4, 4, 5, 5, 5, 5, 6, 6, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 255, 255}; 277 static IMG_BYTE gBFRACTION_NumRemapTable[] = {1, 1, 2, 1, 3, 1, 2, 3, 4, 1, 5, 1, 2, 3, 4, 5, 6, 1, 3, 5, 7, 255, 255}; 278 279 280 #define INIT_CONTEXT_VC1 context_VC1_p ctx = (context_VC1_p) obj_context->format_data; 281 282 #define SURFACE(id) ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id )) 283 284 285 static void psb_VC1_QueryConfigAttributes( 286 VAProfile profile, 287 VAEntrypoint entrypoint, 288 VAConfigAttrib *attrib_list, 289 int num_attribs) 290 { 291 /* No VC1 specific attributes */ 292 } 293 294 static VAStatus psb_VC1_ValidateConfig( 295 object_config_p obj_config) 296 { 297 int i; 298 /* Check all attributes */ 299 for (i = 0; i < obj_config->attrib_count; i++) { 300 switch (obj_config->attrib_list[i].type) { 301 case VAConfigAttribRTFormat: 302 /* Ignore */ 303 break; 304 305 default: 306 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; 307 } 308 } 309 310 return VA_STATUS_SUCCESS; 311 } 312 313 314 static void psb__VC1_pack_vlc_tables(uint16_t *vlc_packed_data, 315 uint16_t *gaui16vc1VlcTableData, 316 int gui16vc1VlcTableSize) 317 { 318 int i, j; 319 /************************************************************************************/ 320 /* Pack the VLC tables into 32-bit format ready for DMA into 15-bit wide RAM. */ 321 /************************************************************************************/ 322 for (i = 0; i < gui16vc1VlcTableSize; i++) { 323 j = i * 3; 324 325 /* opcode 14:12 *//* width 11:9 *//* symbol 8:0 */ 326 vlc_packed_data[i] = ((gaui16vc1VlcTableData[j + 0]) << 12) | 327 ((gaui16vc1VlcTableData[j + 1]) << 9) | 328 (gaui16vc1VlcTableData[j + 2]); 329 } 330 } 331 332 static void psb__VC1_pack_index_table_info(uint32_t *packed_index_table, 333 uint16_t index_data[VLC_INDEX_TABLE_SIZE][3]) 334 { 335 uint32_t start = 0, end = 0, length = 0, opcode = 0, width = 0; 336 int i; 337 338 for (i = 0; i < VLC_INDEX_TABLE_SIZE; i++) { 339 start = index_data[i][2]; 340 if (i < (VLC_INDEX_TABLE_SIZE - 1)) { //Make sure we don't exceed the bound 341 end = index_data[i+1][2]; 342 } else { 343 end = start + 500; 344 } 345 length = end - start; 346 width = index_data[i][1]; 347 opcode = index_data[i][0]; 348 349 drv_debug_msg(VIDEO_DEBUG_GENERAL, "packed_index_table[%02d]->start = %08x length = %08x (%d)\n", i, start * 2, length * 2, length * 2); 350 351 packed_index_table[i] = opcode; 352 packed_index_table[i] <<= 3; 353 packed_index_table[i] |= width; 354 packed_index_table[i] <<= 9; 355 packed_index_table[i] |= length; 356 packed_index_table[i] <<= 16; 357 packed_index_table[i] |= start; 358 } 359 } 360 361 static VAStatus psb__VC1_check_legal_picture(object_context_p obj_context, object_config_p obj_config) 362 { 363 VAStatus vaStatus = VA_STATUS_SUCCESS; 364 365 if (NULL == obj_context) { 366 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 367 DEBUG_FAILURE; 368 return vaStatus; 369 } 370 371 if (NULL == obj_config) { 372 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 373 DEBUG_FAILURE; 374 return vaStatus; 375 } 376 377 /* MSVDX decode capability for VC-1: 378 * SP@ML 379 * MP@HL 380 * AP@L3 381 * 382 * Refer to Table 253 (Limitations of profiles and levels) of SMPTE-421M 383 */ 384 switch (obj_config->profile) { 385 case VAProfileVC1Simple: 386 if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 352) 387 || (obj_context->picture_height <= 0) || (obj_context->picture_height > 288)) { 388 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 389 } 390 break; 391 392 case VAProfileVC1Main: 393 if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 1920) 394 || (obj_context->picture_height <= 0) || (obj_context->picture_height > 1088)) { 395 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 396 } 397 break; 398 399 case VAProfileVC1Advanced: 400 if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 2048) 401 || (obj_context->picture_height <= 0) || (obj_context->picture_height > 2048)) { 402 vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 403 } 404 break; 405 406 default: 407 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 408 break; 409 } 410 411 return vaStatus; 412 } 413 414 static void psb_VC1_DestroyContext(object_context_p obj_context); 415 416 static VAStatus psb_VC1_CreateContext( 417 object_context_p obj_context, 418 object_config_p obj_config) 419 { 420 VAStatus vaStatus = VA_STATUS_SUCCESS; 421 context_VC1_p ctx; 422 /* Validate flag */ 423 /* Validate picture dimensions */ 424 vaStatus = psb__VC1_check_legal_picture(obj_context, obj_config); 425 if (VA_STATUS_SUCCESS != vaStatus) { 426 DEBUG_FAILURE; 427 return vaStatus; 428 } 429 430 ctx = (context_VC1_p) calloc(1, sizeof(struct context_VC1_s)); 431 if (NULL == ctx) { 432 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 433 DEBUG_FAILURE; 434 return vaStatus; 435 } 436 437 obj_context->format_data = (void*) ctx; 438 ctx->obj_context = obj_context; 439 ctx->pic_params = NULL; 440 441 ctx->split_buffer_pending = FALSE; 442 443 ctx->slice_param_list_size = 8; 444 ctx->slice_param_list = (object_buffer_p*) calloc(1, sizeof(object_buffer_p) * ctx->slice_param_list_size); 445 ctx->slice_param_list_idx = 0; 446 447 if (NULL == ctx->slice_param_list) { 448 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 449 DEBUG_FAILURE; 450 } 451 452 ctx->colocated_buffers_size = obj_context->num_render_targets; 453 ctx->colocated_buffers_idx = 0; 454 ctx->colocated_buffers = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s) * ctx->colocated_buffers_size); 455 if (NULL == ctx->colocated_buffers) { 456 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 457 DEBUG_FAILURE; 458 } 459 460 switch (obj_config->profile) { 461 case VAProfileVC1Simple: 462 ctx->profile = WMF_PROFILE_SIMPLE; 463 break; 464 465 case VAProfileVC1Main: 466 ctx->profile = WMF_PROFILE_MAIN; 467 break; 468 469 case VAProfileVC1Advanced: 470 ctx->profile = WMF_PROFILE_ADVANCED; 471 break; 472 473 default: 474 ASSERT(0 == 1); 475 vaStatus = VA_STATUS_ERROR_UNKNOWN; 476 } 477 478 // TODO 479 480 if (vaStatus == VA_STATUS_SUCCESS) { 481 vaStatus = psb_buffer_create(obj_context->driver_data, 482 PRELOAD_BUFFER_SIZE, 483 psb_bt_vpu_only, 484 &ctx->preload_buffer); 485 DEBUG_FAILURE; 486 } 487 488 if (vaStatus == VA_STATUS_SUCCESS) { 489 vaStatus = psb_buffer_create(obj_context->driver_data, 490 AUXMSB_BUFFER_SIZE, 491 psb_bt_vpu_only, 492 &ctx->aux_msb_buffer); 493 DEBUG_FAILURE; 494 } 495 496 if (vaStatus == VA_STATUS_SUCCESS) { 497 vaStatus = psb_buffer_create(obj_context->driver_data, 498 gui16vc1VlcTableSize * sizeof(IMG_UINT16), 499 psb_bt_cpu_vpu, 500 &ctx->vlc_packed_table); 501 DEBUG_FAILURE; 502 } 503 if (vaStatus == VA_STATUS_SUCCESS) { 504 void *vlc_packed_data_address; 505 if (0 == psb_buffer_map(&ctx->vlc_packed_table, (unsigned char **)&vlc_packed_data_address)) { 506 psb__VC1_pack_vlc_tables((unsigned short *)vlc_packed_data_address, gaui16vc1VlcTableData, gui16vc1VlcTableSize); 507 psb_buffer_unmap(&ctx->vlc_packed_table); 508 psb__VC1_pack_index_table_info(ctx->vlc_packed_index_table, gaui16vc1VlcIndexData); 509 } else { 510 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 511 DEBUG_FAILURE; 512 } 513 } 514 515 if (vaStatus != VA_STATUS_SUCCESS) { 516 psb_VC1_DestroyContext(obj_context); 517 } 518 519 return vaStatus; 520 } 521 522 static void psb_VC1_DestroyContext( 523 object_context_p obj_context) 524 { 525 INIT_CONTEXT_VC1 526 int i; 527 528 psb_buffer_destroy(&ctx->vlc_packed_table); 529 psb_buffer_destroy(&ctx->aux_msb_buffer); 530 psb_buffer_destroy(&ctx->preload_buffer); 531 532 if (ctx->pic_params) { 533 free(ctx->pic_params); 534 ctx->pic_params = 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 554 static VAStatus psb__VC1_allocate_colocated_buffer(context_VC1_p ctx, object_surface_p obj_surface, uint32_t size) 555 { 556 psb_surface_p surface = obj_surface->psb_surface; 557 558 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_VC1: Allocationg colocated buffer for surface %08x\n", surface); 559 560 if (!GET_SURFACE_INFO_colocated_index(surface)) { 561 VAStatus vaStatus; 562 psb_buffer_p buf; 563 int index = ctx->colocated_buffers_idx; 564 if (index >= ctx->colocated_buffers_size) { 565 return VA_STATUS_ERROR_UNKNOWN; 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 578 static psb_buffer_p psb__VC1_lookup_colocated_buffer(context_VC1_p ctx, psb_surface_p surface) 579 { 580 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_VC1: 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 return &(ctx->colocated_buffers[index-1]); /* 0 means unset, index is offset by 1 */ 586 } 587 588 static uint32_t psb__vc1_get_izz_scan_index(context_VC1_p ctx) 589 { 590 if (ctx->pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI) { 591 // P_PICTURE_ADV_FRAME_INTERLACE 592 return 3; 593 } 594 if (PIC_TYPE_IS_INTRA(ctx->pic_params->picture_fields.bits.picture_type)) { 595 // I-picture tables 596 return 4; 597 } else { 598 /* Assume P frame */ 599 if ((ctx->profile == WMF_PROFILE_SIMPLE) || 600 (ctx->profile == WMF_PROFILE_MAIN)) { 601 // P-picture Simple/Main tables 602 return 0; 603 } else { /* Advanced profile */ 604 if (ctx->pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_P) { 605 // P-picture Advanced Progressive tables 606 return 1; 607 } else { /* Interlaced Field */ 608 // P-picture Advanced Field Interlaced tables 609 return 2; 610 } 611 } 612 } 613 } 614 615 616 //#define psb__trace_message(...) 617 618 #define P(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->x) 619 static void psb__VC1_trace_pic_params(VAPictureParameterBufferVC1 *p) 620 { 621 #define P0(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->sequence_fields.bits.x) 622 P0(interlace); 623 P0(syncmarker); 624 P0(overlap); 625 626 P(coded_width); 627 P(coded_height); 628 629 #define P2(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->picture_fields.bits.x) 630 /* picture_fields */ 631 P2(picture_type); 632 P2(frame_coding_mode); 633 P2(top_field_first); 634 P2(is_first_field); 635 P2(intensity_compensation); 636 637 #define P4(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->entrypoint_fields.bits.x) 638 P4(closed_entry); 639 P4(broken_link); 640 P4(loopfilter); 641 642 P(conditional_overlap_flag); 643 P(fast_uvmc_flag); 644 645 #define P3(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->range_mapping_fields.bits.x) 646 /* range_mapping_fields */ 647 P3(luma_flag); 648 P3(luma); 649 P3(chroma_flag); 650 P3(chroma); 651 652 P(b_picture_fraction); 653 P(cbp_table); 654 P(mb_mode_table); 655 P(range_reduction_frame); 656 P(rounding_control); 657 P(post_processing); 658 P(picture_resolution_index); 659 P(luma_scale); 660 P(luma_shift); 661 662 P(raw_coding.value); 663 P(bitplane_present.value); 664 665 #define P4(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->reference_fields.bits.x) 666 P4(reference_distance_flag); 667 P4(reference_distance); 668 P4(num_reference_pictures); 669 P4(reference_field_pic_indicator); 670 671 #define P5(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->mv_fields.bits.x) 672 P5(mv_mode); 673 P5(mv_mode2); 674 675 P5(mv_table); 676 P5(two_mv_block_pattern_table); 677 P5(four_mv_switch); 678 P5(four_mv_block_pattern_table); 679 P5(extended_mv_flag); 680 P5(extended_mv_range); 681 P5(extended_dmv_flag); 682 P5(extended_dmv_range); 683 684 #define P6(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->pic_quantizer_fields.bits.x) 685 686 P6(dquant); 687 P6(quantizer); 688 P6(half_qp); 689 P6(pic_quantizer_scale); 690 P6(pic_quantizer_type); 691 P6(dq_frame); 692 P6(dq_profile); 693 P6(dq_sb_edge); 694 P6(dq_db_edge); 695 P6(dq_binary_level); 696 P6(alt_pic_quantizer); 697 698 #define P7(x) psb__trace_message("PARAMS: " #x "\t= %d\n", p->transform_fields.bits.x) 699 700 P7(variable_sized_transform_flag); 701 P7(mb_level_transform_type_flag); 702 P7(frame_level_transform_type); 703 P7(transform_ac_codingset_idx1); 704 P7(transform_ac_codingset_idx2); 705 P7(intra_transform_dc_table); 706 } 707 708 static VAStatus psb__VC1_process_picture_param(context_VC1_p ctx, object_buffer_p obj_buffer) 709 { 710 VAStatus vaStatus; 711 VAPictureParameterBufferVC1 *pic_params; 712 IMG_UINT8 ui8LumaScale1 = 0, ui8LumaShift1 = 0, ui8LumaScale2 = 0, ui8LumaShift2 = 0; 713 714 ASSERT(obj_buffer->type == VAPictureParameterBufferType); 715 ASSERT(obj_buffer->num_elements == 1); 716 ASSERT(obj_buffer->size == sizeof(VAPictureParameterBufferVC1)); 717 718 if ((obj_buffer->num_elements != 1) || 719 (obj_buffer->size != sizeof(VAPictureParameterBufferVC1))) { 720 vaStatus = VA_STATUS_ERROR_UNKNOWN; 721 DEBUG_FAILURE; 722 return vaStatus; 723 } 724 725 /* Transfer ownership of VAPictureParameterBufferVC1 data */ 726 pic_params = (VAPictureParameterBufferVC1 *) obj_buffer->buffer_data; 727 if (ctx->pic_params) { 728 free(ctx->pic_params); 729 } 730 ctx->pic_params = pic_params; 731 obj_buffer->buffer_data = NULL; 732 obj_buffer->size = 0; 733 734 if (psb_video_trace_fp && (psb_video_trace_level & VABUF_TRACE)) 735 psb__VC1_trace_pic_params(pic_params); 736 737 if (pic_params->pic_quantizer_fields.bits.quantizer == 0) { 738 /* Non uniform quantizer indicates PQINDEX > 8 */ 739 ctx->pqindex_gt8 = (pic_params->pic_quantizer_fields.bits.pic_quantizer_type == 0); 740 } else { 741 /* PQUANT (pic_quantizer_scale) == PQINDEX */ 742 ctx->pqindex_gt8 = (pic_params->pic_quantizer_fields.bits.pic_quantizer_scale > 8); 743 } 744 745 /* 746 * We decode to ctx->decoded_surface 747 * the out of loop decoded picture is stored in ctx->obj_context->current_render_target 748 */ 749 if (pic_params->inloop_decoded_picture == VA_INVALID_SURFACE) { 750 /* No out of loop deblocking */ 751 ctx->decoded_surface = ctx->obj_context->current_render_target; 752 } else { 753 ctx->decoded_surface = SURFACE(pic_params->inloop_decoded_picture); 754 if (NULL == ctx->decoded_surface) { 755 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 756 DEBUG_FAILURE; 757 return vaStatus; 758 } 759 } 760 /* Lookup surfaces for backward/forward references */ 761 ctx->forward_ref_surface = NULL; 762 ctx->backward_ref_surface = NULL; 763 if (pic_params->forward_reference_picture != VA_INVALID_SURFACE) { 764 ctx->forward_ref_surface = SURFACE(pic_params->forward_reference_picture); 765 } 766 if (pic_params->backward_reference_picture != VA_INVALID_SURFACE) { 767 ctx->backward_ref_surface = SURFACE(pic_params->backward_reference_picture); 768 } 769 770 #if 0 771 if (NULL == ctx->forward_ref_surface) { 772 /* for mmu fault protection */ 773 ctx->forward_ref_surface = ctx->decoded_surface; 774 } 775 if (NULL == ctx->backward_ref_surface) { 776 /* for mmu fault protection */ 777 ctx->backward_ref_surface = ctx->decoded_surface; 778 } 779 #endif 780 781 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Target ref = %08x ID = %08x\n", ctx->obj_context->current_render_target->psb_surface, ctx->obj_context->current_render_target->surface_id); 782 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Decoded ref = %08x ID = %08x\n", ctx->decoded_surface->psb_surface, pic_params->inloop_decoded_picture); 783 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Forward ref = %08x ID = %08x\n", ctx->forward_ref_surface ? ctx->forward_ref_surface->psb_surface : 0, pic_params->forward_reference_picture); 784 drv_debug_msg(VIDEO_DEBUG_GENERAL, "Backwrd ref = %08x ID = %08x\n", ctx->backward_ref_surface ? ctx->backward_ref_surface->psb_surface : 0, pic_params->backward_reference_picture); 785 786 // NOTE: coded_width and coded_height do not have to be an exact multiple of MBs 787 788 ctx->display_picture_width = pic_params->coded_width; 789 ctx->display_picture_height = pic_params->coded_height; 790 ctx->picture_width_mb = PIXELS_TO_MB(ctx->display_picture_width); 791 ctx->picture_height_mb = PIXELS_TO_MB(ctx->display_picture_height); 792 ctx->coded_picture_width = ctx->picture_width_mb * 16; 793 ctx->coded_picture_height = ctx->picture_height_mb * 16; 794 if ((WMF_PROFILE_ADVANCED == ctx->profile) && (VC1_FCM_FLDI == pic_params->picture_fields.bits.frame_coding_mode)) { 795 ctx->picture_height_mb /= 2; 796 ctx->coded_picture_height = ctx->picture_height_mb * 16 * 2; 797 } 798 799 ctx->size_mb = ctx->picture_width_mb * ctx->picture_height_mb; 800 801 uint32_t colocated_size = (ctx->size_mb + 1) * 2 * VC1_MB_PARAM_STRIDE + 0x2000; 802 803 vaStatus = psb__VC1_allocate_colocated_buffer(ctx, ctx->decoded_surface, colocated_size); 804 vaStatus = psb__VC1_allocate_colocated_buffer(ctx, ctx->obj_context->current_render_target, colocated_size); 805 806 if (VA_STATUS_SUCCESS != vaStatus) { 807 DEBUG_FAILURE; 808 return vaStatus; 809 } 810 811 /* TODO: Store top_field_first and frame_coding_mode (or even all of pic_params) for the current frame 812 * so that it can be referenced when the same frame is used as reference frame 813 */ 814 815 if (ctx->profile != WMF_PROFILE_ADVANCED) { 816 /* Simple and Main profiles always use progressive pictures*/ 817 pic_params->picture_fields.bits.frame_coding_mode = VC1_FCM_P; 818 } 819 820 if ((pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_P) || (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI)) { 821 pic_params->picture_fields.bits.top_field_first = 1; 822 } 823 824 ctx->bitplane_present = 0; 825 switch (pic_params->picture_fields.bits.picture_type) { 826 case WMF_PTYPE_I: 827 case WMF_PTYPE_BI: 828 ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_overflags && !pic_params->raw_coding.flags.overflags) ? 0x04 : 0; 829 ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_ac_pred && !pic_params->raw_coding.flags.ac_pred) ? 0x02 : 0; 830 ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_field_tx && !pic_params->raw_coding.flags.field_tx) ? 0x01 : 0; 831 break; 832 833 case WMF_PTYPE_P: 834 ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_mv_type_mb && !pic_params->raw_coding.flags.mv_type_mb) ? 0x04 : 0; 835 ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_skip_mb && !pic_params->raw_coding.flags.skip_mb) ? 0x02 : 0; 836 break; 837 838 case WMF_PTYPE_B: /* B picture */ 839 ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_forward_mb && !pic_params->raw_coding.flags.forward_mb) ? 0x04 : 0; 840 ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_skip_mb && !pic_params->raw_coding.flags.skip_mb) ? 0x02 : 0; 841 ctx->bitplane_present |= (pic_params->bitplane_present.flags.bp_direct_mb && !pic_params->raw_coding.flags.direct_mb) ? 0x01 : 0; 842 break; 843 844 default: 845 break; 846 } 847 drv_debug_msg(VIDEO_DEBUG_GENERAL, "bitplane_present_flag = %02x raw_coding_flag = %02x bitplane_present = %02x\n", 848 pic_params->bitplane_present.value, pic_params->raw_coding.value, ctx->bitplane_present); 849 850 if (pic_params->reference_fields.bits.reference_distance_flag == 0) { 851 pic_params->reference_fields.bits.reference_distance = 0; 852 } 853 854 /* conditional_overlap_flag is not always defined, but MSVDX expects it to be set in those cases anyway */ 855 if (ctx->profile == WMF_PROFILE_ADVANCED) { 856 if (pic_params->sequence_fields.bits.overlap == FALSE) { 857 ctx->condover = 0; /* No overlap smoothing */ 858 } else if (pic_params->pic_quantizer_fields.bits.pic_quantizer_scale < 9) { 859 ctx->condover = pic_params->conditional_overlap_flag; 860 } else { 861 ctx->condover = 2; 862 } 863 } else { 864 if ((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) || (pic_params->sequence_fields.bits.overlap == FALSE) || (pic_params->pic_quantizer_fields.bits.pic_quantizer_scale < 9)) { 865 ctx->condover = 0; /* No overlap smoothing */ 866 } else { 867 ctx->condover = 2; 868 } 869 } 870 871 /************************** Calculate the IZZ scan index ****************************/ 872 ctx->scan_index = psb__vc1_get_izz_scan_index(ctx); 873 /************************************************************************************/ 874 875 /**************************** Calculate MVMODE and MVMODE2 **************************/ 876 ctx->mv_mode = pic_params->mv_fields.bits.mv_mode; 877 if (ctx->mv_mode == WMF_MVMODE_INTENSITY_COMPENSATION) { 878 ctx->mv_mode = pic_params->mv_fields.bits.mv_mode2; 879 } 880 881 /* Neither MVMODE nor MVMODE2 are signaled at the picture level for interlaced frame pictures, 882 but MVMODE can be determine for P pictures depending on the value of MV4SWITCH, and for B 883 pictures it is by default 1MV mode. */ 884 if ((pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI) && PIC_TYPE_IS_INTER(pic_params->picture_fields.bits.picture_type)) { 885 if ((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) && (pic_params->mv_fields.bits.four_mv_switch == 1)) { 886 ctx->mv_mode = WMF_MVMODE_MIXED_MV; 887 pic_params->mv_fields.bits.mv_mode = WMF_MVMODE_MIXED_MV; 888 } else { 889 ctx->mv_mode = WMF_MVMODE_1MV; 890 pic_params->mv_fields.bits.mv_mode = WMF_MVMODE_1MV; 891 } 892 } 893 /************************************************************************************/ 894 895 896 /******************************** Calculate HALFPEL *********************************/ 897 if ((ctx->mv_mode == WMF_MVMODE_1MV) || (ctx->mv_mode == WMF_MVMODE_MIXED_MV)) { 898 ctx->half_pel = 0; 899 } else { 900 ctx->half_pel = 1; 901 } 902 /************************************************************************************/ 903 904 /* TODO: Are we using the correct size for this ? */ 905 ctx->pull_back_x = COMPUTE_PULLBACK(pic_params->coded_width); 906 ctx->pull_back_y = COMPUTE_PULLBACK(pic_params->coded_height); 907 908 if (pic_params->mv_fields.bits.extended_dmv_flag == 1) { 909 ctx->extend_x = gDMVRANGE_ExtHorizontal_RemapTable[pic_params->mv_fields.bits.extended_dmv_range]; 910 ctx->extend_y = gDMVRANGE_ExtVertical_RemapTable[pic_params->mv_fields.bits.extended_dmv_range]; 911 } else { 912 ctx->extend_x = IMG_FALSE; 913 ctx->extend_y = IMG_FALSE; 914 } 915 916 /* B interlaced field picture and ...?? */ 917 ctx->ui32ScaleFactor = 0; 918 ctx->i8FwrdRefFrmDist = 0; 919 ctx->i8BckwrdRefFrmDist = 0; 920 if (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) { 921 IMG_UINT32 ui32BFractionDen; 922 IMG_UINT32 ui32BFractionNum; 923 924 IMG_UINT32 ui32FrameReciprocal; 925 926 if (pic_params->b_picture_fraction > (sizeof(gBFRACTION_DenRemapTable) / sizeof(IMG_BYTE) - 1)) 927 pic_params->b_picture_fraction = sizeof(gBFRACTION_DenRemapTable) / sizeof(IMG_BYTE) - 1; 928 929 ui32BFractionDen = gBFRACTION_DenRemapTable[pic_params->b_picture_fraction]; 930 ui32BFractionNum = gBFRACTION_NumRemapTable[pic_params->b_picture_fraction]; 931 932 if (ui32BFractionDen > (sizeof(gaui16Inverse) / sizeof(IMG_UINT16))) 933 ui32BFractionDen = sizeof(gaui16Inverse) / sizeof(IMG_UINT16); 934 935 if (ui32BFractionDen == 0) { 936 drv_debug_msg(VIDEO_DEBUG_ERROR, "Invalid ui32BFractionDen value %d\n", ui32BFractionDen); 937 ui32BFractionDen = 1; 938 } 939 940 ui32FrameReciprocal = gaui16Inverse[ui32BFractionDen - 1]; 941 ctx->ui32ScaleFactor = ui32BFractionNum * ui32FrameReciprocal; 942 943 if (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) { 944 ctx->i8FwrdRefFrmDist = (IMG_INT8)((ctx->ui32ScaleFactor * pic_params->reference_fields.bits.reference_distance) >> 8); /* 10.4.6.2 */ 945 ctx->i8BckwrdRefFrmDist = pic_params->reference_fields.bits.reference_distance - ctx->i8FwrdRefFrmDist - 1; 946 947 if (ctx->i8BckwrdRefFrmDist < 0) { 948 ctx->i8BckwrdRefFrmDist = 0; 949 } 950 } 951 } 952 953 /* Compute the mode config parameter */ 954 /* 955 MODE_CONFIG[1:0] = 956 VC-1 intensity compensation flag, derived from MVMODE = Intensity compensation, and INTCOMPFIELD 957 00 No intensity compensation 958 01 Intensity compensation for top field 959 10 Intensity compensation for bottom field 960 11 Intensity compensation for the frame 961 962 MODE_CONFIG[3:2] = 963 VC-1 reference range scaling, derived from RANGERED, RANGEREDFRM for current frame and reference frame. 964 00 No scaling 965 01 Scale down 966 10 Scale up 967 11 No scaling 968 */ 969 970 /****************************** INTENSITY COMPENSATION ******************************/ 971 /* For each NEW reference frame, rotate IC history */ 972 if (PIC_TYPE_IS_REF(pic_params->picture_fields.bits.picture_type) && 973 pic_params->picture_fields.bits.is_first_field && 974 (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI)) { 975 /* 976 This is the first field picture of a new frame, so move the IC params for both field 977 pictures of the last frame (from position [1][0] for the first field and position [1][1] for 978 the second field to positions [0][0] and [0][1] respectevely). 979 */ 980 memcpy(&ctx->sICparams[0][0], &ctx->sICparams[1][0], sizeof(IC_PARAM)); 981 memcpy(&ctx->sICparams[0][1], &ctx->sICparams[1][1], sizeof(IC_PARAM)); 982 983 memset(&ctx->sICparams[1][0], 0, sizeof(IC_PARAM)); 984 memset(&ctx->sICparams[1][1], 0, sizeof(IC_PARAM)); 985 } 986 987 if (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) { 988 ctx->ui8CurrLumaScale1 = 0; 989 ctx->ui8CurrLumaShift1 = 0; 990 ctx->ui8CurrLumaScale2 = 0; 991 ctx->ui8CurrLumaShift2 = 0; 992 993 if (pic_params->picture_fields.bits.frame_coding_mode != VC1_FCM_FRMI) { 994 if (pic_params->picture_fields.bits.intensity_compensation) { 995 /* Intensity compensation of reference */ 996 if (pic_params->picture_fields.bits.frame_coding_mode != VC1_FCM_FLDI) { // progressive picture 997 ctx->mode_config = 0x3; 998 999 ui8LumaScale1 = pic_params->luma_scale & 0x3F; 1000 ui8LumaShift1 = pic_params->luma_shift & 0x3F; 1001 1002 if (ui8LumaScale1 != 0 || ui8LumaShift1 != 0) { 1003 ctx->ui8CurrLumaScale1 = ui8LumaScale1; 1004 ctx->ui8CurrLumaShift1 = ui8LumaShift1; 1005 } 1006 } else { // field interlaced picture 1007 // top field 1008 ui8LumaScale1 = pic_params->luma_scale & 0x3F; 1009 ui8LumaShift1 = pic_params->luma_shift & 0x3F; 1010 1011 // bottom field 1012 ui8LumaScale2 = ui8LumaScale1; /* TODO: How to keep track of top/bottom field intensity comp? */ 1013 ui8LumaShift2 = ui8LumaShift1; /* TODO: How to keep track of top/bottom field intensity comp? */ 1014 1015 /* Check what fields undergo intensity compensation */ 1016 ctx->ui8IntCompField = 0; 1017 if (ui8LumaScale1 != 0 || ui8LumaShift1 != 0) { 1018 ctx->ui8IntCompField = 1; 1019 } 1020 if (ui8LumaScale2 != 0 || ui8LumaShift2 != 0) { 1021 ctx->ui8IntCompField |= 2; 1022 } 1023 1024 switch (ctx->ui8IntCompField) { 1025 case 0: /* none */ 1026 ctx->mode_config = 0x0; 1027 break; 1028 1029 case 1: /* top */ 1030 ctx->mode_config = 0x1; 1031 1032 // IC parameters for top field 1033 ctx->ui8CurrLumaScale1 = ui8LumaScale1; 1034 ctx->ui8CurrLumaShift1 = ui8LumaShift1; 1035 break; 1036 1037 case 2: /* bottom */ 1038 ctx->mode_config = 0x2; 1039 1040 // IC parameters for bottom field 1041 ctx->ui8CurrLumaScale2 = ui8LumaScale2; 1042 ctx->ui8CurrLumaShift2 = ui8LumaShift2; 1043 break; 1044 1045 case 3: /* both */ 1046 ctx->mode_config = 0x3; 1047 1048 // IC parameters for top field 1049 ctx->ui8CurrLumaScale1 = ui8LumaScale1; 1050 ctx->ui8CurrLumaShift1 = ui8LumaShift1; 1051 1052 // IC parameters for bottom field 1053 ctx->ui8CurrLumaScale2 = ui8LumaScale2; 1054 ctx->ui8CurrLumaShift2 = ui8LumaShift2; 1055 break; 1056 } 1057 } 1058 } else { 1059 ctx->mode_config = 0; 1060 } 1061 } else { // interlaced frame P picture 1062 if (pic_params->picture_fields.bits.intensity_compensation) { /* iINSO */ 1063 ctx->mode_config = 0x3; // intensity compensate whole frame 1064 } else { 1065 ctx->mode_config = 0; 1066 } 1067 } 1068 } else if (PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type)) { 1069 ctx->mode_config = 0; 1070 } 1071 1072 /* 1073 10.3.8 Intensity Compensation: 1074 If intensity compensation is performed on a reference field, then after decoding the field, 1075 the post-compensated pixel values shall be retained and shall be used when decoding the next 1076 field. If the next field indicates that the field that was intensity compensated by the 1077 previous field is to have intensity compensation performed again then the post-compensated 1078 field shall be used. Therefore, when a reference field has intensity compensation performed 1079 twice, the result of the first intensity compensation operation shall be used as input 1080 for the second intensity compensation. 1081 */ 1082 /* 1083 Don't forget point 9.1.1.4 in VC1 Spec: 1084 1085 If the current frame, coded as two interlace field pictures, contains at least one P or B 1086 field, and if this P or B field uses one or both field in another frame as a reference, where 1087 the reference frame was also coded as a interlace field pictue, then the TFF of the current 1088 frame and reference frame shall be the same. 1089 */ 1090 if ((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) && (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI)) { 1091 if (pic_params->picture_fields.bits.top_field_first) { // top field first 1092 if (!pic_params->picture_fields.bits.is_first_field) { // this is the second field picture (and bottom) 1093 if (ctx->ui8IntCompField & 0x1) { 1094 /* The second and bottom field picture of the current frame 1095 intensity compensates the top field of the current frame. */ 1096 ctx->sICparams[1][0].ui8LumaScale1 = ui8LumaScale1; 1097 ctx->sICparams[1][0].ui8LumaShift1 = ui8LumaShift1; 1098 ctx->sICparams[1][0].ui8IC1 = 1; 1099 } 1100 if (ctx->ui8IntCompField & 0x2) { 1101 /* The second and bottom field picture of the current frame 1102 intensity compensates the bottom field of the previous frame. */ 1103 ctx->sICparams[0][1].ui8LumaScale2 = ui8LumaScale2; 1104 ctx->sICparams[0][1].ui8LumaShift2 = ui8LumaShift2; 1105 ctx->sICparams[0][1].ui8IC2 = 2; 1106 } 1107 } else { // first field picture (and top) 1108 if (ctx->ui8IntCompField & 0x1) { 1109 /* The first and top field picture of the current frame 1110 intensity compensates the top field of the previous frame. */ 1111 ctx->sICparams[0][0].ui8LumaScale2 = ui8LumaScale1; 1112 ctx->sICparams[0][0].ui8LumaShift2 = ui8LumaShift1; 1113 ctx->sICparams[0][0].ui8IC2 = 1; 1114 } 1115 if (ctx->ui8IntCompField & 0x2) { 1116 /* The first and top field picture of the current frame 1117 intensity compensates the bottom field of the previous frame. */ 1118 ctx->sICparams[0][1].ui8LumaScale1 = ui8LumaScale2; 1119 ctx->sICparams[0][1].ui8LumaShift1 = ui8LumaShift2; 1120 ctx->sICparams[0][1].ui8IC1 = 2; 1121 } 1122 } 1123 } else { // bottom field first 1124 if (!pic_params->picture_fields.bits.is_first_field) { // this is the second field picture (and top) 1125 if (ctx->ui8IntCompField & 0x2) { 1126 /* The second and top field picture of the current frame 1127 intensity compensates the bottom field of the current frame. */ 1128 ctx->sICparams[1][1].ui8LumaScale1 = ui8LumaScale2; 1129 ctx->sICparams[1][1].ui8LumaShift1 = ui8LumaShift2; 1130 ctx->sICparams[1][1].ui8IC1 = 2; 1131 } 1132 if (ctx->ui8IntCompField & 0x1) { 1133 /* The second and top field picture of the current frame 1134 intensity compensates the top field of the previous frame. */ 1135 ctx->sICparams[0][0].ui8LumaScale2 = ui8LumaScale1; 1136 ctx->sICparams[0][0].ui8LumaShift2 = ui8LumaShift1; 1137 ctx->sICparams[0][0].ui8IC2 = 1; 1138 } 1139 } else { // first field picture (and bottom) 1140 if (ctx->ui8IntCompField & 0x1) { 1141 /* The first and bottom field picture of the current frame 1142 intensity compensates the top field of the previous frame. */ 1143 ctx->sICparams[0][0].ui8LumaScale1 = ui8LumaScale1; 1144 ctx->sICparams[0][0].ui8LumaShift1 = ui8LumaShift1; 1145 ctx->sICparams[0][0].ui8IC1 = 1; 1146 } 1147 if (ctx->ui8IntCompField & 0x2) { 1148 /* The first and bottom field picture of the current frame 1149 intensity compensates the bottom field of the previous frame. */ 1150 ctx->sICparams[0][1].ui8LumaScale2 = ui8LumaScale2; 1151 ctx->sICparams[0][1].ui8LumaShift2 = ui8LumaShift2; 1152 ctx->sICparams[0][1].ui8IC2 = 2; 1153 } 1154 } 1155 } 1156 } 1157 /************************************************************************************/ 1158 1159 /********************************* RANGE REDUCTION **********************************/ 1160 /* Determine the difference between the range reduction of current and reference picture */ 1161 if (ctx->profile == WMF_PROFILE_MAIN) { 1162 /* Range Reduction is only enabled for Main Profile */ 1163 /* The RANGEREDFRM values from the reference pictures are; 1164 psVLDContext->bRef0RangeRed 1165 psVLDContext->bRef1RangeRed */ 1166 1167 switch (pic_params->picture_fields.bits.picture_type) { 1168 case WMF_PTYPE_I: 1169 case WMF_PTYPE_BI: 1170 /* no reference picture scaling */ 1171 break; 1172 1173 case WMF_PTYPE_P: /* P picture */ 1174 /* 1175 8.3.4.11 also need to scale the previously reconstructed anchor frame prior to using it for MC if: 1176 - RANGEREDFRM == 1 and ref RANGEREDFRM flag is not signalled scale down previous reconstructed frame. 1177 - RANGEREDFRM == 0 and ref RANGEREDFRM flag is set scale up previous reconstructed frame. 1178 */ 1179 if (ctx->pic_params->range_reduction_frame && !ctx->bRef0RangeRed) { 1180 ctx->mode_config |= (0x1 << 2); // scale down previous reconstructed frame 1181 } else if (!ctx->pic_params->range_reduction_frame && ctx->bRef0RangeRed) { 1182 ctx->mode_config |= (0x2 << 2); // scale up previous reconstructed frame 1183 } else { /* neither or both are set */ 1184 ctx->mode_config |= (0x0 << 2); // no scaling of reference 1185 } 1186 break; 1187 1188 case WMF_PTYPE_B: /* B picture */ 1189 /* 1190 8.4.4.14 RANGEREDFRM shall be the same as for the temporally subsequent anchor frame (display order) 1191 If this is set then the current decoded frame shall be scalled up similar to P frame. 1192 Scaling for the temporally (display order) preceeding frame will be applied as for P frames 1193 */ 1194 if (ctx->bRef0RangeRed && !ctx->bRef1RangeRed) { 1195 ctx->mode_config |= (0x1 << 2); 1196 } else if (!ctx->bRef0RangeRed && ctx->bRef1RangeRed) { 1197 ctx->mode_config |= (0x2 << 2); 1198 } else { /* neither or both are set */ 1199 ctx->mode_config |= (0x0 << 2); // no scaling of reference 1200 } 1201 break; 1202 1203 default: 1204 break; 1205 } 1206 } else { 1207 ctx->mode_config |= (0x0 << 2); 1208 } 1209 /************************************************************************************/ 1210 1211 /********************************** Slice structure *********************************/ 1212 if (VC1_FCM_FLDI == pic_params->picture_fields.bits.frame_coding_mode) { 1213 if ((pic_params->picture_fields.bits.top_field_first && pic_params->picture_fields.bits.is_first_field) || 1214 (!pic_params->picture_fields.bits.top_field_first && !pic_params->picture_fields.bits.is_first_field)) { 1215 // Top field 1216 ctx->slice_field_type = 0; 1217 ctx->bottom_field = 0; 1218 } else { 1219 // Bottom field 1220 ctx->slice_field_type = 1; 1221 ctx->bottom_field = 1; 1222 } 1223 } else { 1224 // progressive or interlaced frame 1225 ctx->slice_field_type = 2; 1226 ctx->bottom_field = 1; 1227 } 1228 /************************************************************************************/ 1229 1230 /************************* FCM for the reference pictures ***************************/ 1231 if (PIC_TYPE_IS_REF(pic_params->picture_fields.bits.picture_type) || 1232 ((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) && /* The second B field picture in an */ 1233 (ctx->pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) && /* interlaced field coded frame shall */ 1234 !pic_params->picture_fields.bits.is_first_field)) { /* reference the first field picture. */ 1235 if (ctx->pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI && !pic_params->picture_fields.bits.is_first_field) { 1236 /* The current picture is the second field of the frame, then the previous field picture 1237 is in the same frame. Therefore the FCM of the first field is the same as the FCM of the 1238 current field and the first field will be reference 0. */ 1239 ctx->ui8FCM_Ref0Pic = ctx->pic_params->picture_fields.bits.frame_coding_mode; 1240 } else if (ctx->pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI && pic_params->picture_fields.bits.is_first_field) { 1241 /* The current picture is the first field of the frame, then the previous field picture 1242 is in a different frame and will be reference 1. */ 1243 ctx->ui8FCM_Ref1Pic = ctx->ui8FCM_Ref2Pic; 1244 } else { // progresive or interlaced frame picture 1245 ctx->ui8FCM_Ref1Pic = ctx->ui8FCM_Ref2Pic; 1246 } 1247 } 1248 /************************************************************************************/ 1249 1250 /************************* TFF for the reference pictures ***************************/ 1251 if (PIC_TYPE_IS_REF(pic_params->picture_fields.bits.picture_type) && 1252 ((ctx->pic_params->picture_fields.bits.frame_coding_mode != VC1_FCM_FLDI) || 1253 pic_params->picture_fields.bits.is_first_field)) { 1254 ctx->bTFF_FwRefFrm = ctx->bTFF_BwRefFrm; 1255 } 1256 /************************************************************************************/ 1257 1258 return VA_STATUS_SUCCESS; 1259 } 1260 1261 static VAStatus psb__VC1_process_bitplane(context_VC1_p ctx, object_buffer_p obj_buffer) 1262 { 1263 VAStatus vaStatus = VA_STATUS_SUCCESS; 1264 ASSERT(obj_buffer->type == VABitPlaneBufferType); 1265 ASSERT(ctx->pic_params); 1266 1267 if ((NULL == obj_buffer->psb_buffer) || 1268 (0 == obj_buffer->size)) { 1269 /* We need to have data in the bitplane buffer */ 1270 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1271 return vaStatus; 1272 } 1273 1274 ctx->bitplane_buffer = obj_buffer->psb_buffer; 1275 ctx->has_bitplane = TRUE; 1276 return vaStatus; 1277 } 1278 1279 /* 1280 * Adds a VASliceParameterBuffer to the list of slice params 1281 */ 1282 static VAStatus psb__VC1_add_slice_param(context_VC1_p ctx, object_buffer_p obj_buffer) 1283 { 1284 ASSERT(obj_buffer->type == VASliceParameterBufferType); 1285 if (ctx->slice_param_list_idx >= ctx->slice_param_list_size) { 1286 unsigned char *new_list; 1287 ctx->slice_param_list_size += 8; 1288 new_list = realloc(ctx->slice_param_list, 1289 sizeof(object_buffer_p) * ctx->slice_param_list_size); 1290 if (NULL == new_list) { 1291 return VA_STATUS_ERROR_ALLOCATION_FAILED; 1292 } 1293 ctx->slice_param_list = (object_buffer_p*) new_list; 1294 } 1295 ctx->slice_param_list[ctx->slice_param_list_idx] = obj_buffer; 1296 ctx->slice_param_list_idx++; 1297 return VA_STATUS_SUCCESS; 1298 } 1299 1300 1301 /* 1302 * This function extracts the information about a given table from the index of VLC tables. 1303 */ 1304 static void psb__VC1_extract_table_info(context_VC1_p ctx, sTableData *psInfo, int idx) 1305 { 1306 IMG_UINT32 tmp; 1307 1308 if (idx >= VLC_INDEX_TABLE_SIZE) 1309 idx = VLC_INDEX_TABLE_SIZE - 1; 1310 1311 tmp = ctx->vlc_packed_index_table[idx]; 1312 psInfo->aui16StartLocation = (IMG_UINT16)(tmp & 0xffff); 1313 psInfo->aui16VLCTableLength = (IMG_UINT16)((tmp >> 16) & 0x1ff); 1314 psInfo->aui16InitialWidth = (IMG_UINT16)((tmp >> 25) & 0x7); 1315 psInfo->aui16InitialOpcode = (IMG_UINT16)((tmp >> 28) & 0x3); 1316 } 1317 1318 /* 1319 * This function selects the VLD tables from the picture layer parameters. 1320 */ 1321 static void psb__VC1_write_VLC_tables(context_VC1_p ctx) 1322 { 1323 VAPictureParameterBufferVC1 *pic_params = ctx->pic_params; 1324 IMG_UINT16 ui16Table = 0, ui16IntraTable = 0, ui16InterTable = 0, aui16Table[3]; 1325 IMG_UINT32 i, ui32TableNum = 0; 1326 1327 /* select the required table from the n different types 1328 A - vc1DEC_I_Picture_CBPCY_VLC (1) 1329 B - vc1DEC_P_Picture_CBPCY_VLC_N (4) | 1330 C - vc1DEC_Interlaced_CBPCY_N (8) | 1331 D - vc1DEC_FourMV_Pattern_N (4) | 1332 E - vc1DEC_INTERLACE_2_MVP_Pattern_N (4) | 1333 F - vc1DEC_Mot_Vector_Diff_VLC_N (4) | MB Layer 1334 G - vc1DEC_One_Field_Ref_Ilace_MV_N (4) | 1335 H - vc1DEC_Two_Field_Ref_Ilace_MV_N (8) | 1336 I - vc1DEC_Mixed_MV_MB_N (8) | 1337 J - vc1DEC_One_MV_MB_N (8) | 1338 K - vc1DEC_INTERLACE_4MV_MB_N (4) | 1339 L - vc1DEC_INTERLACE_Non_4MV_MB_N (4) | 1340 M - vc1DEC_X_Rate_TTMB (3) - 1341 N - vc1DEC_X_Rate_TTBLK (3) 1342 O - vc1DEC_X_Rate_SUBBLKPAT (3) | 1343 P - vc1DEC_X_X_Inter_VLC (4) | Block Layer 1344 Q - vc1DEC_X_X_Intra_VLC (4) | 1345 R - vc1DEC_X_Mot_Luminance_DC_Diff_VLC (2) | 1346 S - vc1DEC_X_Mot_Chroma_DC_Diff_VLC (2) - 1347 1348 X - vc1DEC_Code_3x2_2x3_tiles (1) NOT USED */ 1349 1350 /*! 1351 *********************************************************************************** 1352 @ Table A,B,C VLC CBPCY Tables 1353 1354 [VC1] 7.1.3.1 Coded Block Pattern (CBPCY) (Variable size)[I, P,B] 1355 1356 CBPCY is a variable-sized syntax element that shall be present in all 1357 I and BI picture macroblocks, and may be present in P and B picture 1358 macroblocks. In P and B pictures, CBPCY shall be decoded using 1359 the VLC table specified by the CBPTAB syntax element as described in 1360 section 7.1.1.39. The CBP tables for P and B pictures are listed in 1361 section 11.6. 1362 1363 1364 [VC1] 9.1.3.2 Coded Block Pattern (CBPCY) (Variable size)[I, P,B] 1365 1366 Table 102: ICBPTAB code-table 1367 1368 A vc1DEC_I_Picture_CBPCY_VLC (1) 1369 B vc1DEC_P_Picture_CBPCY_VLC_N (4) 1370 C vc1DEC_Interlaced_CBPCY_N (8) 1371 1372 ***********************************************************************************/ 1373 1374 if ((!pic_params->sequence_fields.bits.interlace) || (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_P)) { 1375 if (PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type)) { 1376 ui16Table = VC1_VLC_I_Picture_CBPCY_VLC; 1377 } else if (PIC_TYPE_IS_INTER(pic_params->picture_fields.bits.picture_type)) { 1378 psb__bounds_check(pic_params->cbp_table, 4); 1379 ui16Table = CBPCYTableProg[pic_params->cbp_table]; 1380 } 1381 } else { /* Interlaced */ 1382 if (PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type)) { 1383 ui16Table = VC1_VLC_I_Picture_CBPCY_VLC; 1384 } else { 1385 psb__bounds_check(pic_params->cbp_table, 8); 1386 ui16Table = CBPCYTableInterlaced[pic_params->cbp_table]; /* LUT */ 1387 } 1388 } 1389 1390 psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16Table); 1391 ui32TableNum++; 1392 1393 /*! 1394 ************************************************************ 1395 @ Table D VLC 4MV Pattern 1396 1397 [VC1] Table 104: 4MVBP code-table 1398 1399 Tables 116-119 1400 1401 D vc1DEC_FourMV_Pattern_N (4) 1402 ************************************************************/ 1403 psb__bounds_check(pic_params->mv_fields.bits.four_mv_block_pattern_table, 4); 1404 ui16Table = FourMVTable[pic_params->mv_fields.bits.four_mv_block_pattern_table]; 1405 1406 psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16Table); 1407 ui32TableNum++; 1408 1409 /*! 1410 ************************************************************************************ 1411 @ Table E VLC 2MVBP Tables 1412 1413 1414 Table 103: 2MVBP code-table 1415 1416 for Tables 120-123 1417 1418 E vc1DEC_INTERLACE_2_MVP_Pattern_N (4) 1419 ***********************************************************************************/ 1420 psb__bounds_check(pic_params->mv_fields.bits.two_mv_block_pattern_table, 4); 1421 ui16Table = Interlace2MVTable[pic_params->mv_fields.bits.two_mv_block_pattern_table]; 1422 1423 psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16Table); 1424 ui32TableNum++; 1425 1426 /*! 1427 ************************************************************************************ 1428 @ Table F,G,H VLC MV Tables 1429 1430 [VC1] MVDATA Variable size vlclbf 7.1.3.8 1431 1432 7.1.3.8 Motion Vector Data (MVDATA)(Variable size)[P] 1433 1434 MVDATA is a variable sized syntax element that may be present in P picture 1435 macroblocks. This syntax element decodes to the motion vector(s) for the 1436 macroblock. The table used to decode this syntax element is specified by the 1437 MVTAB syntax element in the picture layer as specified in section 7.1.1.38. 1438 1439 F vc1DEC_Mot_Vector_Diff_VLC_N (4) 1440 1441 [VC1] 9.1.1.34 INTERLACE Motion Vector Table (IMVTAB) (2 or 3 bits) 1442 1443 Table 100: IMVTAB code-table for P INTERLACE field picture with NUMREF = 0, 1444 and for P/B INTERLACE frame pictures 1445 1446 IMVTAB Motion Vector Table 1447 00 1-Reference Table 0 1448 01 1-Reference Table 1 1449 10 1-Reference Table 2 1450 11 1-Reference Table 3 1451 1452 Table 101: IMVTAB code-table for P INTERLACE field pictures with NUMREF = 1, 1453 and for B INTERLACE field pictures 1454 1455 IMVTAB Motion Vector Table 1456 000 2-Reference Table 0 1457 001 2-Reference Table 1 1458 010 2-Reference Table 2 1459 011 2-Reference Table 3 1460 100 2-Reference Table 4 1461 101 2-Reference Table 5 1462 110 2-Reference Table 6 1463 111 2-Reference Table 7 1464 1465 G vc1DEC_One_Field_Ref_Ilace_MV_N (4) 1466 H vc1DEC_Two_Field_Ref_Ilace_MV_N (8) 1467 1468 ***********************************************************************************/ 1469 if ((!pic_params->sequence_fields.bits.interlace) || (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_P)) { 1470 psb__bounds_check(pic_params->mv_fields.bits.mv_table, 4); 1471 ui16Table = ProgressiveMVTable[pic_params->mv_fields.bits.mv_table]; 1472 } else { 1473 if ( 1474 ( 1475 PIC_TYPE_IS_INTER(pic_params->picture_fields.bits.picture_type) && 1476 (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI) 1477 ) 1478 || 1479 ( 1480 (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) && 1481 (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) && 1482 (pic_params->reference_fields.bits.num_reference_pictures == 0) 1483 ) 1484 ) { 1485 /* One field */ 1486 psb__bounds_check(pic_params->mv_fields.bits.mv_table, 4); 1487 ui16Table = Interlaced1RefMVTable[pic_params->mv_fields.bits.mv_table]; 1488 } else { /*if (((FCM == VC1_FCM_FLDI) && (NUMREF == 0) && (PTYPE == WMF_PTYPE_P)) || ((PTYPE == WMF_PTYPE_B) && (FCM == VC1_FCM_FLDI))) */ 1489 /* two field */ 1490 psb__bounds_check(pic_params->mv_fields.bits.mv_table, 8); 1491 ui16Table = MVTable2RefIlace[pic_params->mv_fields.bits.mv_table]; /* LUT */ 1492 } 1493 } 1494 1495 psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16Table); 1496 ui32TableNum++; 1497 1498 /*! 1499 ************************************************************************************ 1500 @ Table I,J,K,L VLC MBMODE Tables 1501 1502 I vc1DEC_Mixed_MV_MB_N (8) 1503 J vc1DEC_One_MV_MB_N (8) 1504 K vc1DEC_INTERLACE_4MV_MB_N (4) 1505 L vc1DEC_INTERLACE_Non_4MV_MB_N (4) 1506 ***********************************************************************************/ 1507 ui16Table = 0; 1508 if (pic_params->sequence_fields.bits.interlace && (pic_params->picture_fields.bits.frame_coding_mode > VC1_FCM_P)) { 1509 if (PIC_TYPE_IS_INTER(pic_params->picture_fields.bits.picture_type)) { 1510 if (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) { 1511 psb__bounds_check(pic_params->mb_mode_table, 8); 1512 /* 9.1.1.33 use MBMODETAB and MVMODE to select field interlaced tables */ 1513 ui16Table = MBMODETableFLDI[pic_params->mb_mode_table][(pic_params->mv_fields.bits.mv_mode == WMF_MVMODE_MIXED_MV) ? 1 : 0]; 1514 } else if (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI) { 1515 psb__bounds_check(pic_params->mb_mode_table, 4); 1516 /* 9.1.1.33 use MBMODETAB and MV4SWITCH to select frame interlaced tables */ 1517 ui16Table = MBMODETableFRMI[pic_params->mb_mode_table][(pic_params->mv_fields.bits.four_mv_switch) ? 0 : 1]; 1518 } 1519 } 1520 } 1521 1522 psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16Table); 1523 ui32TableNum++; 1524 1525 /*! 1526 ************************************************************************************ 1527 @ Table M,N,O VLC PQUANT Tables 1528 1529 [WMV9] 3.2.2.10 MB-level Transform Type (TTMB)(Variable size)[P,B] 1530 [WMV9] 3.2.3.15 Block-level Transform Type (TTBLK)(Variable size)[inter] 1531 1532 [WMV9] 3.2.3.16 Transform sub-block pattern (SUBBLKPAT)(Variable size)[inter] 1533 1534 M vc1DEC_X_Rate_TTMB (3) 1535 N vc1DEC_X_Rate_TTBLK (3) 1536 O vc1DEC_X_Rate_SUBBLKPAT (3) 1537 1538 TTBLK and TTMB P and B Pictures only 1539 1540 ***********************************************************************************/ 1541 aui16Table[0] = 0; 1542 aui16Table[1] = 0; 1543 aui16Table[2] = 0; 1544 1545 if (pic_params->pic_quantizer_fields.bits.pic_quantizer_scale <= 4) { /* high rate */ 1546 aui16Table[2] = VC1_VLC_High_Rate_SUBBLKPAT; 1547 aui16Table[1] = VC1_VLC_High_Rate_TTBLK; 1548 aui16Table[0] = VC1_VLC_High_Rate_TTMB; 1549 } else if (pic_params->pic_quantizer_fields.bits.pic_quantizer_scale <= 12) { /* med rate */ 1550 aui16Table[2] = VC1_VLC_Medium_Rate_SUBBLKPAT; 1551 aui16Table[1] = VC1_VLC_Medium_Rate_TTBLK; 1552 aui16Table[0] = VC1_VLC_Medium_Rate_TTMB; 1553 } else { /* low rate */ 1554 aui16Table[2] = VC1_VLC_Low_Rate_SUBBLKPAT; 1555 aui16Table[1] = VC1_VLC_Low_Rate_TTBLK; 1556 aui16Table[0] = VC1_VLC_Low_Rate_TTMB; 1557 } 1558 1559 for (i = ui32TableNum; i < ui32TableNum + 3; i++) { 1560 psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[i], aui16Table[i-ui32TableNum]); 1561 } 1562 1563 ui32TableNum = ui32TableNum + 3; 1564 1565 { 1566 /*! 1567 *********************************************************************************************** 1568 Inter Coded Blocks 1569 1570 Table 54: Index/Coding Set Correspondence for PQINDEX <= 7 1571 Y, Cb and Cr blocks 1572 1573 Index Table 1574 0 High Rate Inter 1575 1 High Motion Inter 1576 2 Mid Rate Inter 1577 1578 Table 55: Index/Coding Set Correspondence for PQINDEX > 7 1579 Y, Cb and Cr blocks 1580 1581 Index Table 1582 0 Low Motion Inter 1583 1 High Motion Inter 1584 2 Mid Rate Inter 1585 1586 ---------------------------------------------------------------------------------- 1587 Intra Blocks 1588 1589 8 AC Coeff Coding Sets: 1590 4 x INTRA, 4 x INTER 1591 1592 Y use Intra, CrCb use Inter 1593 1594 Table 38: Coding Set Correspondence for PQINDEX <= 7 1595 1596 Y blocks Cb and Cr blocks 1597 Index Table Index Table 1598 0 High Rate Intra 0 High Rate Inter 1599 1 High Motion Intra 1 High Motion Inter 1600 2 Mid Rate Intra 2 Mid Rate Inter 1601 1602 Table 39: Coding Set Correspondence for PQINDEX > 7 1603 1604 Y blocks Cb and Cr blocks 1605 Index Table Index Table 1606 0 Low Motion Intra 0 Low Motion Inter 1607 1 High Motion Intra 1 High Motion Inter 1608 2 Mid Rate Intra 2 Mid Rate Inter 1609 1610 The value decoded from the DCTACFRM2 syntax element shall be used 1611 as the coding set index for Y blocks and the value decoded from the 1612 DCTACFRM syntax element shall be used as the coding set 1613 index for Cb and Cr blocks. 1614 1615 P vc1DEC_X_X_Inter_VLC 1616 Q vc1DEC_X_X_Intra_VLC 1617 1618 1619 for I pictures TRANSACFRM specifies the Inter Coding set 1620 TRANSACFRM2 specifies the Intra Coding set 1621 1622 for P pictures TRANSACFRM specifies Inter and Intra Coding set 1623 1624 1625 ***************************************************************************************************/ 1626 IMG_UINT32 ui32IntraCodingSetIndex = PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type) 1627 ? pic_params->transform_fields.bits.transform_ac_codingset_idx2 1628 : pic_params->transform_fields.bits.transform_ac_codingset_idx1; 1629 1630 IMG_UINT32 ui32InterCodingSetIndex = pic_params->transform_fields.bits.transform_ac_codingset_idx1; 1631 1632 /* For PQINDEX < 9 the uniform quantizer should be used, as indicated by PQUANTIZER == 1 */ 1633 if (!ctx->pqindex_gt8) { 1634 ui16IntraTable = IntraTablePQIndexLT9[ui32IntraCodingSetIndex]; 1635 ui16InterTable = InterTablePQIndexLT9[ui32InterCodingSetIndex]; 1636 } else { 1637 ui16IntraTable = IntraTablePQIndexGT8[ui32IntraCodingSetIndex]; 1638 ui16InterTable = InterTablePQIndexGT8[ui32InterCodingSetIndex]; 1639 } 1640 1641 psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16IntraTable); 1642 ui32TableNum++; 1643 1644 psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16InterTable); 1645 ui32TableNum++; 1646 } 1647 1648 /*! 1649 ************************************************************************************ 1650 @ Table R & S VLC TRANSDCTAB Tables 1651 1652 R vc1DEC_X_Mot_Luminance_DC_Diff_VLC (2) 1653 S vc1DEC_X_Mot_Chroma_DC_Diff_VLC (2) 1654 1655 [VC1] 8.1.1.2 Intra Transform DC Table 1656 TRANSDCTAB is a one-bit syntax element that shall specify which of two 1657 tables is used to decode the Transform DC coefficients in intra-coded blocks. 1658 If TRANSDCTAB = 0, then the low motion table of Section 11.7 shall be used. 1659 If TRANSDCTAB = 1, then the high motion table of Section 11.7 shall be used. 1660 1661 [VC1] 8.1.1.2 Intra Transform DC Table 1662 TRANSDCTAB is a one-bit syntax element that shall specify which of two 1663 tables is used to decode the Transform DC coefficients in intra-coded blocks. 1664 If TRANSDCTAB = 0, then the low motion table of Section 11.7 shall be used. 1665 If TRANSDCTAB = 1, then the high motion table of Section 11.7 shall be used. 1666 1667 ***********************************************************************************/ 1668 if (pic_params->transform_fields.bits.intra_transform_dc_table == 0) { 1669 /* low motion */ 1670 1671 /* VC1_VLC_Low_Mot_Luminance_DC_Diff_VLC */ 1672 ui16IntraTable = VC1_VLC_Low_Mot_Luminance_DC_Diff_VLC; 1673 1674 /* VC1_VLC_Low_Mot_Chroma_DC_Diff_VLC */ 1675 ui16InterTable = VC1_VLC_Low_Mot_Chroma_DC_Diff_VLC; 1676 } else { /* TRANSDCTAB == 1 */ 1677 /* high motion */ 1678 /* VC1_VLC_High_Mot_Luminance_DC_Diff_VLC */ 1679 ui16IntraTable = VC1_VLC_High_Mot_Luminance_DC_Diff_VLC; 1680 1681 /* VC1_VLC_High_Mot_Chroma_DC_Diff_VLC */ 1682 ui16InterTable = VC1_VLC_High_Mot_Chroma_DC_Diff_VLC; 1683 } 1684 1685 psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16IntraTable); 1686 ui32TableNum++; 1687 1688 psb__VC1_extract_table_info(ctx, &ctx->sTableInfo[ui32TableNum], ui16InterTable); 1689 ui32TableNum++; 1690 1691 /* at the end determine how many tables have been chosen 1692 this should be constant and equal 12 */ 1693 ctx->ui32NumTables = ui32TableNum; 1694 ASSERT(ctx->ui32NumTables == 12); 1695 } 1696 1697 static void psb__VC1_build_VLC_tables(context_VC1_p ctx) 1698 { 1699 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1700 unsigned int i; 1701 uint16_t RAM_location = 0; 1702 uint32_t reg_value; 1703 1704 for (i = 0; i < ctx->ui32NumTables; i++) { 1705 if (RAM_location & 0x03) { 1706 /* Align */ 1707 RAM_location += 4 - (RAM_location & 0x03); 1708 } 1709 ctx->sTableInfo[i].aui16RAMLocation = RAM_location; 1710 1711 /* VLC Table */ 1712 /* Write a LLDMA Cmd to transfer VLD Table data */ 1713 1714 psb_cmdbuf_lldma_write_cmdbuf(cmdbuf, &ctx->vlc_packed_table, 1715 ctx->sTableInfo[i].aui16StartLocation * sizeof(IMG_UINT16), /* origin */ 1716 ctx->sTableInfo[i].aui16VLCTableLength * sizeof(IMG_UINT16), /* size */ 1717 RAM_location * sizeof(IMG_UINT32), /* destination */ 1718 LLDMA_TYPE_VLC_TABLE); 1719 drv_debug_msg(VIDEO_DEBUG_GENERAL, "table[%02d] start_loc = %08x RAM_location = %08x | %08x\n", i, ctx->sTableInfo[i].aui16StartLocation * sizeof(IMG_UINT16), RAM_location, RAM_location * sizeof(IMG_UINT32)); 1720 RAM_location += ctx->sTableInfo[i].aui16VLCTableLength; 1721 } 1722 1723 /* Write the vec registers with the index data for each of the tables */ 1724 psb_cmdbuf_reg_start_block(cmdbuf, 0); 1725 1726 reg_value = 0; 1727 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0, VLC_TABLE_ADDR0, ctx->sTableInfo[0].aui16RAMLocation); 1728 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0, VLC_TABLE_ADDR1, ctx->sTableInfo[1].aui16RAMLocation); 1729 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0), reg_value); 1730 1731 reg_value = 0; 1732 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR1, VLC_TABLE_ADDR2, ctx->sTableInfo[2].aui16RAMLocation); 1733 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR1, VLC_TABLE_ADDR3, ctx->sTableInfo[3].aui16RAMLocation); 1734 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR1), reg_value); 1735 1736 reg_value = 0; 1737 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2, VLC_TABLE_ADDR4, ctx->sTableInfo[4].aui16RAMLocation); 1738 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2, VLC_TABLE_ADDR5, ctx->sTableInfo[5].aui16RAMLocation); 1739 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2), reg_value); 1740 1741 reg_value = 0; 1742 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR3, VLC_TABLE_ADDR6, ctx->sTableInfo[6].aui16RAMLocation); 1743 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR3, VLC_TABLE_ADDR7, ctx->sTableInfo[7].aui16RAMLocation); 1744 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR3), reg_value); 1745 1746 reg_value = 0; 1747 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR4, VLC_TABLE_ADDR8, ctx->sTableInfo[8].aui16RAMLocation); 1748 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR4, VLC_TABLE_ADDR9, ctx->sTableInfo[9].aui16RAMLocation); 1749 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR4), reg_value); 1750 1751 reg_value = 0; 1752 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR5, VLC_TABLE_ADDR10, ctx->sTableInfo[10].aui16RAMLocation); 1753 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR5, VLC_TABLE_ADDR11, ctx->sTableInfo[11].aui16RAMLocation); 1754 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR5), reg_value); 1755 1756 reg_value = 0; 1757 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH0, ctx->sTableInfo[0].aui16InitialWidth); 1758 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH1, ctx->sTableInfo[1].aui16InitialWidth); 1759 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH2, ctx->sTableInfo[2].aui16InitialWidth); 1760 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH3, ctx->sTableInfo[3].aui16InitialWidth); 1761 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH4, ctx->sTableInfo[4].aui16InitialWidth); 1762 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH5, ctx->sTableInfo[5].aui16InitialWidth); 1763 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH6, ctx->sTableInfo[6].aui16InitialWidth); 1764 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH7, ctx->sTableInfo[7].aui16InitialWidth); 1765 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH8, ctx->sTableInfo[8].aui16InitialWidth); 1766 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0, VLC_TABLE_INITIAL_WIDTH9, ctx->sTableInfo[9].aui16InitialWidth); 1767 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0), reg_value); 1768 1769 reg_value = 0; 1770 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH1, VLC_TABLE_INITIAL_WIDTH10, ctx->sTableInfo[10].aui16InitialWidth); 1771 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH1, VLC_TABLE_INITIAL_WIDTH11, ctx->sTableInfo[11].aui16InitialWidth); 1772 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH1), reg_value); 1773 1774 reg_value = 0; 1775 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE0, ctx->sTableInfo[0].aui16InitialOpcode); 1776 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE1, ctx->sTableInfo[1].aui16InitialOpcode); 1777 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE2, ctx->sTableInfo[2].aui16InitialOpcode); 1778 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE3, ctx->sTableInfo[3].aui16InitialOpcode); 1779 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE4, ctx->sTableInfo[4].aui16InitialOpcode); 1780 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE5, ctx->sTableInfo[5].aui16InitialOpcode); 1781 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE6, ctx->sTableInfo[6].aui16InitialOpcode); 1782 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE7, ctx->sTableInfo[7].aui16InitialOpcode); 1783 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE8, ctx->sTableInfo[8].aui16InitialOpcode); 1784 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE9, ctx->sTableInfo[9].aui16InitialOpcode); 1785 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE10, ctx->sTableInfo[10].aui16InitialOpcode); 1786 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0, VLC_TABLE_INITIAL_OPCODE11, ctx->sTableInfo[11].aui16InitialOpcode); 1787 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0), reg_value); 1788 1789 psb_cmdbuf_reg_end_block(cmdbuf); 1790 } 1791 1792 1793 static void psb__VC1_write_kick(context_VC1_p ctx, VASliceParameterBufferVC1 *slice_param) 1794 { 1795 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1796 1797 (void) slice_param; /* Unused for now */ 1798 1799 *cmdbuf->cmd_idx++ = CMD_COMPLETION; 1800 } 1801 1802 /* Programme the Alt output if there is a rotation*/ 1803 static void psb__VC1_setup_alternative_frame(context_VC1_p ctx) 1804 { 1805 uint32_t cmd; 1806 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1807 psb_surface_p rotate_surface = ctx->obj_context->current_render_target->out_loop_surface; 1808 object_context_p obj_context = ctx->obj_context; 1809 1810 if (GET_SURFACE_INFO_rotate(rotate_surface) != obj_context->msvdx_rotate) 1811 drv_debug_msg(VIDEO_DEBUG_ERROR, "Display rotate mode does not match surface rotate mode!\n"); 1812 1813 1814 /* CRendecBlock RendecBlk( mCtrlAlloc , RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); */ 1815 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS)); 1816 1817 psb_cmdbuf_rendec_write_address(cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs); 1818 psb_cmdbuf_rendec_write_address(cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset); 1819 1820 psb_cmdbuf_rendec_end_chunk(cmdbuf); 1821 1822 /* Set the rotation registers */ 1823 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION)); 1824 cmd = 0; 1825 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ALT_PICTURE_ENABLE, 1); 1826 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_ROW_STRIDE, rotate_surface->stride_mode); 1827 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */ 1828 REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_MODE, GET_SURFACE_INFO_rotate(rotate_surface)); 1829 1830 psb_cmdbuf_rendec_write(cmdbuf, cmd); 1831 1832 psb_cmdbuf_rendec_end_chunk(cmdbuf); 1833 } 1834 1835 static void psb__VC1_send_rendec_params(context_VC1_p ctx, VASliceParameterBufferVC1 *slice_param) 1836 { 1837 VAPictureParameterBufferVC1 *pic_params = ctx->pic_params; 1838 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 1839 psb_surface_p deblock_surface = ctx->decoded_surface->psb_surface; 1840 psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface; 1841 1842 uint32_t cmd; 1843 IMG_UINT32 ui32MBParamMemOffset; 1844 IMG_UINT8 ui8PrevLumaScale = 0, ui8PrevLumaShift = 0; 1845 IMG_UINT8 ui8BackLumaScale = 0, ui8BackLumaShift = 0; 1846 IMG_UINT8 ui8PrevBotLumaShift = 0, ui8PrevBotLumaScale = 0; 1847 IMG_UINT8 ui8PrevIC = 0, ui8BackIC = 0, ui8PrevBotIC = 0; 1848 1849 /* Align MB Parameter memory */ 1850 ui32MBParamMemOffset = ((pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) && (!pic_params->picture_fields.bits.is_first_field)) ? 1851 (ctx->size_mb * VC1_MB_PARAM_STRIDE) : 0; 1852 ui32MBParamMemOffset += 0x00000fff; 1853 ui32MBParamMemOffset &= 0xfffff000; 1854 1855 /****************************** INTENSITY COMPENSATION ******************************/ 1856 if (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI) { 1857 if (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) { 1858 if (pic_params->picture_fields.bits.top_field_first) { // top field first 1859 if (!pic_params->picture_fields.bits.is_first_field) { // this is the second field picture (and bottom) 1860 if (ctx->sICparams[0][1].ui8IC1 == 2) { 1861 /* The first and top field picture of the current frame 1862 intensity compensates the bottom field of the previous frame. */ 1863 ui8PrevLumaScale = ctx->sICparams[0][1].ui8LumaScale1; 1864 ui8PrevLumaShift = ctx->sICparams[0][1].ui8LumaShift1; 1865 ui8PrevIC = 2; 1866 } 1867 } else { // first field picture (and top) 1868 if (ctx->sICparams[0][0].ui8IC1 == 1) { 1869 /* The second and bottom field picture of the previous frame 1870 intensity compensates the top field of the previous frame. */ 1871 ui8PrevLumaScale = ctx->sICparams[0][0].ui8LumaScale1; 1872 ui8PrevLumaShift = ctx->sICparams[0][0].ui8LumaShift1; 1873 ui8PrevIC = 1; 1874 } 1875 } 1876 } else { // botom field first 1877 if (!pic_params->picture_fields.bits.is_first_field) { // this is the second field picture (and top) 1878 if (ctx->sICparams[0][0].ui8IC1 == 1) { 1879 /* The first and bottom field picture of the current frame 1880 intensity compensates the top field of the previous frame. */ 1881 ui8PrevLumaScale = ctx->sICparams[0][0].ui8LumaScale1; 1882 ui8PrevLumaShift = ctx->sICparams[0][0].ui8LumaShift1; 1883 ui8PrevIC = 1; 1884 } 1885 } else { // first field picture (and bottom) 1886 if (ctx->sICparams[0][1].ui8IC1 == 2) { 1887 /* The second and top field picture of the previous frame 1888 intensity compensates the bottom field of the previous frame. */ 1889 ui8PrevLumaScale = ctx->sICparams[0][1].ui8LumaScale1; 1890 ui8PrevLumaShift = ctx->sICparams[0][1].ui8LumaShift1; 1891 ui8PrevIC = 2; 1892 } 1893 } 1894 } 1895 } else if (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) { 1896 /* 1897 First frame - second temporally closest reference frame to the B frame 1898 Second frame - first temporally closest reference frame to the B frame 1899 */ 1900 if (pic_params->picture_fields.bits.top_field_first) { // top field first 1901 if (ctx->sICparams[0][0].ui8IC1 == 1) { 1902 /* The second and bottom field of the first reference frame intensity 1903 compensates the first and top field of the first reference frame. */ 1904 ui8PrevLumaScale = ctx->sICparams[0][0].ui8LumaScale1; 1905 ui8PrevLumaShift = ctx->sICparams[0][0].ui8LumaShift1; 1906 ui8PrevIC = 1; 1907 } 1908 if (ctx->sICparams[0][0].ui8IC2 == 1) { 1909 /* The first and top field of the second reference frame intensity 1910 compensates the first and top field of the first reference frame. */ 1911 ui8BackLumaScale = ctx->sICparams[0][0].ui8LumaScale2; 1912 ui8BackLumaShift = ctx->sICparams[0][0].ui8LumaShift2; 1913 ui8BackIC = 1; 1914 } 1915 if (ctx->sICparams[0][1].ui8IC2 == 2) { 1916 /* The first and top field of the second reference frame intensity 1917 compensates the second and bottom field of the first reference frame. */ 1918 ui8PrevBotLumaScale = ctx->sICparams[0][1].ui8LumaScale2; 1919 ui8PrevBotLumaShift = ctx->sICparams[0][1].ui8LumaShift2; 1920 ui8PrevBotIC = 2; 1921 } 1922 } else { // botom field first 1923 if (ctx->sICparams[0][1].ui8IC1 == 2) { 1924 /* The second and top field of the first reference frame intensity 1925 compensates the first and bottom field of the first reference frame. */ 1926 ui8BackLumaScale = ctx->sICparams[0][1].ui8LumaScale1; 1927 ui8BackLumaShift = ctx->sICparams[0][1].ui8LumaShift1; 1928 ui8BackIC = 2; 1929 } 1930 if (ctx->sICparams[0][1].ui8IC2 == 2) { 1931 /* The first and bottom field of the second reference frame intensity 1932 compensates the first and bottom field of the first reference frame. */ 1933 ui8PrevBotLumaScale = ctx->sICparams[0][1].ui8LumaScale2; 1934 ui8PrevBotLumaShift = ctx->sICparams[0][1].ui8LumaShift2; 1935 ui8PrevBotIC = 2; 1936 } 1937 if (ctx->sICparams[0][0].ui8IC1 == 1) { 1938 /* The first and bottom field of the second reference frame intensity 1939 compensates the second and top field of the first reference frame. */ 1940 ui8PrevLumaScale = ctx->sICparams[0][0].ui8LumaScale1; 1941 ui8PrevLumaShift = ctx->sICparams[0][0].ui8LumaShift1; 1942 ui8PrevIC = 1; 1943 } 1944 } 1945 } 1946 } 1947 /************************************************************************************/ 1948 1949 psb_cmdbuf_rendec_start_block(cmdbuf); 1950 1951 if (CONTEXT_ROTATE(ctx->obj_context)) /* FIXME field coded should not issue */ 1952 psb__VC1_setup_alternative_frame(ctx); 1953 1954 /* CHUNK: 1 - VC1SEQUENCE00 */ 1955 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE)); 1956 1957 /* VC1SEQUENCE00 Command: Display Picture Size (sequence) */ 1958 cmd = 0; 1959 /* TODO: Can "display size" and "coded size" be different? */ 1960 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE00, PICTURE_HEIGHT, (ctx->display_picture_height - 1)); /* display picture size - 1 */ 1961 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE00, PICTURE_WIDTH, (ctx->display_picture_width - 1)); 1962 psb_cmdbuf_rendec_write(cmdbuf, cmd); 1963 1964 /* VC1SEQUENCE00 Command: Coded Picture Size (sequence) */ 1965 cmd = 0; 1966 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE00, PICTURE_HEIGHT, (ctx->coded_picture_height - 1)); /* coded picture size - 1 */ 1967 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE00, PICTURE_WIDTH, (ctx->coded_picture_width - 1)); 1968 psb_cmdbuf_rendec_write(cmdbuf, cmd); 1969 1970 /* VC1SEQUENCE01 Command: Operating Mode (sequence) */ 1971 cmd = 0; 1972 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, CHROMA_INTERLEAVED, 0); /* 0 = CbCr - MSVDX default */ 1973 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, ROW_STRIDE, target_surface->stride_mode); 1974 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, CODEC_MODE, 2); /* MODE_VC1 */ 1975 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, CODEC_PROFILE, ctx->profile); 1976 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, ASYNC_MODE, 0/*((pPicParams->bPicDeblocked & 0x02) ? 0:1)*/); // @TODO: async mode should be synchronous or pre-load for VC1 1977 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, CHROMA_FORMAT, 1); 1978 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, INTERLACED, ((pic_params->picture_fields.bits.frame_coding_mode & 0x02) >> 1)); /* if progressive, INTERLACE is always 0 */ 1979 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, VC1_OVERLAP, pic_params->sequence_fields.bits.overlap); 1980 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, PIC_CONDOVER, ctx->condover); 1981 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SEQUENCE01, PIC_QUANT, pic_params->pic_quantizer_fields.bits.pic_quantizer_scale); 1982 ctx->obj_context->operating_mode = cmd; 1983 psb_cmdbuf_rendec_write(cmdbuf, cmd); 1984 1985 /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1986 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs); 1987 1988 /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */ 1989 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); 1990 1991 /* Aux MSB buffer */ 1992 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->aux_msb_buffer, 0); 1993 1994 psb_cmdbuf_rendec_end_chunk(cmdbuf); 1995 1996 /* CHUNK: 2 - VC1SLICE00 */ 1997 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, MC_CACHE_CONFIGURATION)); 1998 1999 /* VC1SLICE00 Command: Cache Configuration (picture?) */ 2000 cmd = 0; 2001 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE00, CONFIG_REF_OFFSET, 72); 2002 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE00, CONFIG_ROW_OFFSET, 4); 2003 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2004 2005 /* VC1SLICE01 Command: VC1 Intensity Compensation Parameter (picture or slice) */ 2006 cmd = 0; 2007 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE01, VC1_LUMSHIFT2, ctx->ui8CurrLumaShift2); /* INTERLACE field P pictures */ 2008 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE01, VC1_LUMSCALE2, ctx->ui8CurrLumaScale2); /* INTERLACE field P pictures */ 2009 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE01, VC1_LUMSHIFT1, ctx->ui8CurrLumaShift1); 2010 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE01, VC1_LUMSCALE1, ctx->ui8CurrLumaScale1); 2011 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2012 2013 psb_cmdbuf_rendec_end_chunk(cmdbuf); 2014 2015 /* CHUNK: 3 */ 2016 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS)); 2017 2018 /* VC1 Luma Range Mapping Base Address */ 2019 psb_cmdbuf_rendec_write_address(cmdbuf, &deblock_surface->buf, deblock_surface->buf.buffer_ofs); 2020 2021 /* VC1 Chroma Range Mapping Base Address */ 2022 psb_cmdbuf_rendec_write_address(cmdbuf, &deblock_surface->buf, deblock_surface->chroma_offset + deblock_surface->buf.buffer_ofs); 2023 2024 /* VC1SLICE03 Range Map Control (current picture) */ 2025 cmd = 0; 2026 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE03, RANGE_MAPUV_FLAG, pic_params->range_mapping_fields.bits.chroma_flag /*RANGE_MAPUV_FLAG*/); 2027 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE03, RANGE_MAPUV, pic_params->range_mapping_fields.bits.chroma); 2028 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE03, RANGE_MAPY_FLAG, pic_params->range_mapping_fields.bits.luma_flag /*RANGE_MAPY_FLAG*/); 2029 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE03, RANGE_MAPY, pic_params->range_mapping_fields.bits.luma); 2030 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2031 2032 /* Store VC1SLICE03 bits in lower bits of Range Mapping Base Address */ 2033 /* VC1 Luma Range Mapping Base Address */ 2034 RELOC(*ctx->p_range_mapping_base, cmd + deblock_surface->buf.buffer_ofs, &deblock_surface->buf); 2035 2036 /* VC1 Intensity Compensation Backward/Previous */ 2037 /* 2038 3.3.10 VC1 Intensity Compensation Backward/Previous: 2039 The parameters applied in VC1 Intensity Compensation Parameters are the Intensity Compensation 2040 applied to forward prediction. In the case of Interlaced P field pictures, the second field can 2041 be Intensity Compensated relative to the first P field picture. If this is done, when decoding 2042 B pictures the first field backward MV reference to P picture needs to be Intensity Compensated 2043 with VC1_LUMSCALE_BACK and VC1_LUMSHIFT_BACK. (The command should contain the Intensity 2044 Compensation parameters that were used for opposite parity field when decoding 2nd P field picture). 2045 2046 The parameters will only be used if VC1_BACK_INT_COMP in Slice Params command indicates 2047 Backward Intensity Compensation is used. 2048 */ 2049 cmd = 0; 2050 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE04, VC1_LUMSHIFT_PREV, ui8PrevLumaShift); 2051 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE04, VC1_LUMSCALE_PREV, ui8PrevLumaScale); 2052 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE04, VC1_LUMSHIFT_BACK, ui8BackLumaShift); 2053 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE04, VC1_LUMSCALE_BACK, ui8BackLumaScale); 2054 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2055 2056 #if 0 2057 /* VC1 Intensity Compensation Previous Bottom */ 2058 if (ui8PrevBotIC) { 2059 /* 2060 The VDMC dynamically applies intensity compensation when generating reference predicted data 2061 for P/B fields/frames. In the case of Interlaced B field pictures, both the top field and 2062 bottom field could be Intensity Compensated twice (if all previous P field pictures applied 2063 separate top and bottom Intensity Compensation). If this is the case, the VC1 previous field 2064 defined in 3.3.10 should apply to top field, whilst the parameters defined in this register 2065 apply to the bottom field. The VC1_PREV_BOT_INT_COMP field of Slice Params command indicates 2066 if the fields in this register are used. 2067 */ 2068 cmd = 0; 2069 REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, VC1_INTENSITY_COMPENSATION_, VC1_LUMSHIFT_PREV_BOT, ui8PrevBotLumaShift); 2070 REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, VC1_INTENSITY_COMPENSATION_, VC1_LUMSCALE_PREV_BOT, ui8PrevBotLumaScale); 2071 pcmdBuffer[i++] = REGISTER_OFFSET(MSVDX_CMDS, VC1_INTENSITY_COMPENSATION_); 2072 pcmdBuffer[i++] = cmd; 2073 } 2074 #endif 2075 psb_cmdbuf_rendec_end_chunk(cmdbuf); 2076 2077 /* 2078 Reference Picture Base Addresses 2079 2080 The reference picture pointers always include the current picture at first location (0) and 2081 the oldest reference in the next location (1). For B pictures the subsequent reference 2082 frame (display order) is 2. 2083 */ 2084 if ((pic_params->picture_fields.bits.picture_type != WMF_PTYPE_I) && (pic_params->picture_fields.bits.picture_type != WMF_PTYPE_BI)) { 2085 /* CHUNK: 4 */ 2086 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES)); 2087 2088 /********************** CURRENT PICTURE **********************/ 2089 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs); 2090 psb_cmdbuf_rendec_write_address(cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset); 2091 2092 /*************** FORWARD REFERENCE *****************/ 2093 if (ctx->forward_ref_surface) { 2094 /* 2095 In VC1, if a P field picture references both top field and bottom field, but the two fields 2096 are stored in different frame stores, then the most recently decoded field will use reference 2097 index 0, and the other field will use reference index 1. 2098 2099 Progressive P pictures use always reference index 1. 2100 */ 2101 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs); 2102 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->\ 2103 buf.buffer_ofs + ctx->forward_ref_surface->psb_surface->chroma_offset); 2104 } 2105 2106 /*************** BACKWARD REFERENCE *****************/ 2107 if (ctx->backward_ref_surface) { 2108 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->backward_ref_surface->psb_surface->buf, ctx->backward_ref_surface->psb_surface->buf.buffer_ofs); 2109 psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->backward_ref_surface->psb_surface->buf, ctx->backward_ref_surface->psb_surface\ 2110 ->buf.buffer_ofs + ctx->backward_ref_surface->psb_surface->chroma_offset); 2111 } 2112 psb_cmdbuf_rendec_end_chunk(cmdbuf); 2113 } 2114 2115 /* CHUNK: 5 - VC1SLICE02 */ 2116 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS)); 2117 2118 /* VC1SLICE02 Command: Slice Params (picture or slice) */ 2119 cmd = 0; 2120 2121 //REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, SLICE_PARAMS, VC1_PREV_BOT_INT_COMP, ui8PrevBotIC); 2122 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, VC1_PREV_INT_COMP, ui8PrevIC); 2123 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, VC1_BACK_INT_COMP, ui8BackIC); 2124 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, RND_CTRL_BIT, pic_params->rounding_control); 2125 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, MODE_CONFIG, ctx->mode_config); 2126 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, SUBPEL_FILTER_MODE, ((ctx->mv_mode == WMF_MVMODE_1MV_HALF_PEL_BILINEAR) && !(pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FRMI)) ? 0 : 1); 2127 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, VC1_FASTUVMC, pic_params->fast_uvmc_flag); 2128 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, VC1_LOOPFILTER, pic_params->entrypoint_fields.bits.loopfilter); 2129 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, SLICE_FIELD_TYPE, ctx->slice_field_type); 2130 REGIO_WRITE_FIELD(cmd, VC1_RENDEC_CMD, VC1SLICE02, SLICE_CODE_TYPE, (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_BI) ? 0 : (pic_params->picture_fields.bits.picture_type & 0x3)); /* BI is sent as I */ 2131 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2132 2133 psb_cmdbuf_rendec_end_chunk(cmdbuf); 2134 2135 *ctx->p_slice_params = cmd; 2136 2137 /* ------------------------------- Back-End Registers --------------------------------- */ 2138 2139 /* CHUNK: 6 (Back-end registers) */ 2140 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, VC1_CR_VEC_VC1_BE_SPS0)); 2141 2142 /* CR_VEC_VC1_BE_SPS0 */ 2143 cmd = 0; 2144 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS0, VC1_BE_EXTENDED_DMV, pic_params->mv_fields.bits.extended_dmv_flag); 2145 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS0, VC1_BE_EXTENDED_MV, pic_params->mv_fields.bits.extended_mv_flag); 2146 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS0, VC1_BE_FASTUVMC, pic_params->fast_uvmc_flag); 2147 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS0, VC1_BE_INTERLACE, pic_params->sequence_fields.bits.interlace); 2148 //REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS0, VC1_BE_PROFILE, ctx->profile); 2149 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2150 2151 /* CR_VEC_VC1_BE_SPS1 */ 2152 cmd = 0; 2153 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS1, VC1_BE_PIC_HEIGHT_IN_MBS_LESS1, ctx->picture_height_mb - 1); 2154 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2155 2156 /* CR_VEC_VC1_BE_SPS2 */ 2157 cmd = 0; 2158 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_SPS2, VC1_BE_PIC_WIDTH_IN_MBS_LESS1, ctx->picture_width_mb - 1); 2159 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2160 2161 psb_cmdbuf_rendec_end_chunk(cmdbuf); 2162 2163 /* CHUNK: 6b (Back-end registers) */ 2164 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, VC1_CR_VEC_VC1_BE_PPS2)); 2165 2166 /* CR_VEC_VC1_BE_PPS2 */ 2167 cmd = 0; 2168 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS2, VC1_BE_FCM_REF2, ctx->ui8FCM_Ref2Pic); 2169 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS2, VC1_BE_FCM_REF1, ctx->ui8FCM_Ref1Pic); 2170 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS2, VC1_BE_FCM_REF0, ctx->ui8FCM_Ref0Pic); 2171 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS2, VC1_BE_COLLOCATED_SKIPPED, 0); // @TODO: Really need this? 2172 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2173 2174 /* CR_VEC_VC1_BE_PPS0 */ 2175 cmd = 0; 2176 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_IQ_OVERLAP, ((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) || (ctx->condover == 0)) ? 0 : 1); 2177 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_UNIFORM_QUANTIZER, pic_params->pic_quantizer_fields.bits.pic_quantizer_type); 2178 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_TFF_FWD, ctx->bTFF_FwRefFrm); 2179 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_TFF_BWD, ctx->bTFF_BwRefFrm); 2180 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_TFF, pic_params->picture_fields.bits.top_field_first); 2181 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_SECOND_FIELD, !pic_params->picture_fields.bits.is_first_field); 2182 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_HALFQP, pic_params->pic_quantizer_fields.bits.half_qp); 2183 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_BFRACTION, pic_params->b_picture_fraction); 2184 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_FCM, pic_params->picture_fields.bits.frame_coding_mode); 2185 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS0, VC1_BE_RNDCTRL, pic_params->rounding_control); 2186 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2187 2188 /* CR_VEC_VC1_BE_PPS1 */ 2189 cmd = 0; 2190 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_EXTEND_Y, ctx->extend_y); 2191 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_EXTEND_X, ctx->extend_x); 2192 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_QUANTIZER, (pic_params->pic_quantizer_fields.bits.pic_quantizer_type ? 0x03 /* uniform */ : 0x02 /* non-uniform */)); 2193 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_PQUANT, pic_params->pic_quantizer_fields.bits.pic_quantizer_scale); 2194 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_MVMODE, pic_params->mv_fields.bits.mv_mode); 2195 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_MVMODE2, pic_params->mv_fields.bits.mv_mode2); 2196 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_PPS1, VC1_BE_PTYPE, pic_params->picture_fields.bits.picture_type); 2197 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2198 2199 /* CR_VEC_VC1_BE_MVD0 */ 2200 cmd = 0; 2201 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD0, VC1_BE_BRPD, ctx->i8BckwrdRefFrmDist); /* 10.4.6.2 */ 2202 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD0, VC1_BE_FRPD, ctx->i8FwrdRefFrmDist); 2203 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2204 2205 /* CR_VEC_VC1_BE_MVD1 */ 2206 cmd = 0; 2207 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD1, VC1_BE_SCALEFACTOR, ctx->ui32ScaleFactor); /* figure 66 */ 2208 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2209 2210 /* CR_VEC_VC1_BE_MVD2 */ 2211 cmd = 0; 2212 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD2, VC1_BE_PULLBACK_X, ctx->pull_back_x); 2213 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2214 2215 /* CR_VEC_VC1_BE_MVD3 */ 2216 cmd = 0; 2217 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD3, VC1_BE_PULLBACK_Y, ctx->pull_back_y); 2218 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2219 2220 /* CR_VEC_VC1_BE_MVD4 */ 2221 cmd = 0; 2222 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD4, VC1_BE_FIRST_MB_IN_SLICE_Y, slice_param->slice_vertical_position); 2223 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2224 2225 /* CR_VEC_VC1_BE_MVD5 */ 2226 cmd = 0; 2227 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_REFDIST, pic_params->reference_fields.bits.reference_distance); 2228 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_NUMREF, pic_params->reference_fields.bits.num_reference_pictures); 2229 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_REFFIELD, pic_params->reference_fields.bits.reference_field_pic_indicator); 2230 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_MVRANGE, pic_params->mv_fields.bits.extended_mv_range); 2231 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_HALFPEL_FLAG, ctx->half_pel); 2232 //REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_FRAME_CODING_MODE, pic_params->picture_fields.bits.frame_coding_mode); 2233 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_BOTTOM_FIELD_FLAG, ctx->bottom_field); 2234 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_ADVANCED_PROFILE, (ctx->profile == WMF_PROFILE_ADVANCED) ? 1 : 0); 2235 REGIO_WRITE_FIELD(cmd, MSVDX_VEC_VC1, CR_VEC_VC1_BE_MVD5, VC1_BE_SCAN_INDEX, ctx->scan_index); 2236 psb_cmdbuf_rendec_write(cmdbuf, cmd); 2237 2238 psb_cmdbuf_rendec_end_chunk(cmdbuf); 2239 2240 /* CHUNK: 6c (Back-end registers) */ 2241 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, VC1_CR_VEC_VC1_BE_PARAM_BASE_ADDR)); 2242 2243 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_VC1: picture_type = %d\n", pic_params->picture_fields.bits.picture_type); 2244 2245 if (PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type) || (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P)) { 2246 psb_buffer_p colocated_target_buffer = psb__VC1_lookup_colocated_buffer(ctx, target_surface); 2247 ASSERT(colocated_target_buffer); 2248 if (colocated_target_buffer) { 2249 psb_cmdbuf_rendec_write_address(cmdbuf, colocated_target_buffer, ui32MBParamMemOffset); 2250 } else { 2251 /* This is an error */ 2252 psb_cmdbuf_rendec_write(cmdbuf, 0); 2253 } 2254 } else if (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) { 2255 ASSERT(ctx->forward_ref_surface); 2256 psb_buffer_p colocated_forward_ref_buffer = ctx->forward_ref_surface ? psb__VC1_lookup_colocated_buffer(ctx, ctx->forward_ref_surface->psb_surface) : 0; 2257 ASSERT(colocated_forward_ref_buffer); 2258 if (colocated_forward_ref_buffer) { 2259 psb_cmdbuf_rendec_write_address(cmdbuf, colocated_forward_ref_buffer, ui32MBParamMemOffset); 2260 } else { 2261 /* This is an error */ 2262 psb_cmdbuf_rendec_write(cmdbuf, 0); 2263 } 2264 } 2265 psb_cmdbuf_rendec_end_chunk(cmdbuf); 2266 2267 if (!PIC_TYPE_IS_INTRA(pic_params->picture_fields.bits.picture_type)) { 2268 /* CHUNK: 6d (Back-end registers) */ 2269 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, VC1_CR_VEC_VC1_BE_COLPARAM_BASE_ADDR)); 2270 2271 if (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) { 2272 /* CR_VEC_VC1_BE_COLPARAM_BASE_ADDR */ 2273 ASSERT(ctx->forward_ref_surface); 2274 psb_buffer_p colocated_forward_ref_buffer = ctx->forward_ref_surface ? psb__VC1_lookup_colocated_buffer(ctx, ctx->forward_ref_surface->psb_surface) : NULL; 2275 ASSERT(colocated_forward_ref_buffer); 2276 if (colocated_forward_ref_buffer) { 2277 psb_cmdbuf_rendec_write_address(cmdbuf, colocated_forward_ref_buffer, ui32MBParamMemOffset); 2278 } else { 2279 /* This is an error */ 2280 psb_cmdbuf_rendec_write(cmdbuf, 0); 2281 } 2282 } else if (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) { 2283 /* CR_VEC_VC1_BE_COLPARAM_BASE_ADDR */ 2284 ASSERT(ctx->backward_ref_surface); 2285 psb_buffer_p colocated_backward_ref_buffer; 2286 2287 if (NULL == ctx->backward_ref_surface) { 2288 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s L%d Invalid backward_ref_surface handle\n", __FUNCTION__, __LINE__); 2289 return; 2290 } 2291 2292 colocated_backward_ref_buffer = ctx->backward_ref_surface->psb_surface ? psb__VC1_lookup_colocated_buffer(ctx, ctx->backward_ref_surface->psb_surface) : NULL; 2293 ASSERT(colocated_backward_ref_buffer); 2294 if (colocated_backward_ref_buffer) { 2295 psb_cmdbuf_rendec_write_address(cmdbuf, colocated_backward_ref_buffer, ui32MBParamMemOffset); 2296 } else { 2297 /* This is an error */ 2298 psb_cmdbuf_rendec_write(cmdbuf, 0); 2299 } 2300 } 2301 2302 psb_cmdbuf_rendec_end_chunk(cmdbuf); 2303 } 2304 2305 psb_cmdbuf_rendec_end_block(cmdbuf); 2306 } 2307 2308 2309 static void psb__VC1_load_sequence_registers(context_VC1_p ctx) 2310 { 2311 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 2312 uint32_t reg_value; 2313 2314 psb_cmdbuf_reg_start_block(cmdbuf, 0); 2315 2316 /* FE_CONTROL */ 2317 reg_value = 0; 2318 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_PROFILE, ctx->profile); 2319 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL, ENTDEC_FE_MODE, 2); /* 2 - VC1 */ 2320 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL), reg_value); 2321 2322 /* FE_SPS0 */ 2323 reg_value = 0; 2324 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_SPS0, VC1_FE_SYNCMARKER, ctx->pic_params->sequence_fields.bits.syncmarker); 2325 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_SPS0, VC1_FE_VSTRANSFORM, ctx->pic_params->transform_fields.bits.variable_sized_transform_flag); 2326 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_SPS0, VC1_FE_INTERLACE, ctx->pic_params->sequence_fields.bits.interlace); 2327 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_SPS0), reg_value); 2328 2329 psb_cmdbuf_reg_end_block(cmdbuf); 2330 2331 psb_cmdbuf_rendec_start_block(cmdbuf); 2332 /* CHUNK: Entdec back-end profile and level */ 2333 psb_cmdbuf_rendec_start_chunk(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL)); 2334 2335 reg_value = 0; 2336 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_PROFILE, ctx->profile); 2337 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL, ENTDEC_BE_MODE, 2); /* 2 - VC1 */ 2338 2339 psb_cmdbuf_rendec_write(cmdbuf, reg_value); 2340 psb_cmdbuf_rendec_end_chunk(cmdbuf); 2341 psb_cmdbuf_rendec_end_block(cmdbuf); 2342 } 2343 2344 static void psb__VC1_load_picture_registers(context_VC1_p ctx, VASliceParameterBufferVC1 *slice_param) 2345 { 2346 VAPictureParameterBufferVC1 *pic_params = ctx->pic_params; 2347 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 2348 uint32_t reg_value; 2349 int bEnableMVDLite = FALSE; 2350 psb_cmdbuf_reg_start_block(cmdbuf, 0); 2351 2352 /* Enable MVD lite for Progressive or FLDI P */ 2353 if ( 2354 ( 2355 (pic_params->sequence_fields.bits.interlace && (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_FLDI)) || 2356 (!pic_params->sequence_fields.bits.interlace) || 2357 (pic_params->sequence_fields.bits.interlace && (pic_params->picture_fields.bits.frame_coding_mode == VC1_FCM_P)) 2358 ) && 2359 (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P) 2360 ) { 2361 bEnableMVDLite = TRUE; 2362 } 2363 2364 /* FE_PPS0 */ 2365 reg_value = 0; 2366 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0, VC1_FE_PIC_WIDTH_IN_MBS_LESS1, ctx->picture_width_mb - 1); 2367 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0, VC1_FE_PIC_HEIGHT_IN_MBS_LESS1, ctx->picture_height_mb - 1); 2368 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0, VC1_FE_FIRST_MB_IN_SLICE_Y, slice_param->slice_vertical_position); 2369 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0, VC1_FE_PTYPE, pic_params->picture_fields.bits.picture_type); 2370 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0, VC1_FE_FCM, pic_params->picture_fields.bits.frame_coding_mode); 2371 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS0), reg_value); 2372 2373 /* FE_PPS1 */ 2374 reg_value = 0; 2375 #if VC1_INTERLEAVED_BITPLANE 2376 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_BP_FORMAT, IMG_FALSE); // interleaved format 2377 #else 2378 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_BP_FORMAT, IMG_TRUE); // non-interleaved format 2379 #endif 2380 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_BP_PRESENT, ctx->bitplane_present); 2381 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_RAWCODINGFLAG, (pic_params->raw_coding.value & 0x7F)); /* 7-bits */ 2382 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_MVMODE, pic_params->mv_fields.bits.mv_mode); 2383 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_MVMODE2, pic_params->mv_fields.bits.mv_mode2); 2384 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_TTMBF, pic_params->transform_fields.bits.mb_level_transform_type_flag); 2385 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_TTFRM, pic_params->transform_fields.bits.frame_level_transform_type); 2386 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_BFRACTION, pic_params->b_picture_fraction); 2387 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_CONDOVER, ctx->condover); 2388 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_EXTEND_X, ctx->extend_x); 2389 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1, VC1_FE_EXTEND_Y, ctx->extend_y); 2390 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS1), reg_value); 2391 2392 /* FE_PPS2 */ 2393 reg_value = 0; 2394 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQXBEDGE, (pic_params->pic_quantizer_fields.bits.dq_profile == 1) ? pic_params->pic_quantizer_fields.bits.dq_db_edge : pic_params->pic_quantizer_fields.bits.dq_sb_edge); 2395 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQUANT, pic_params->pic_quantizer_fields.bits.dquant); 2396 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_PQUANT, pic_params->pic_quantizer_fields.bits.pic_quantizer_scale); 2397 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_HALFQP, pic_params->pic_quantizer_fields.bits.half_qp); 2398 /* Is this correct? */ 2399 // Write to the VC1_FE_VOPDQUANT_PRESENT register according to PowerVR decoder's implementation. 2400 if (((ctx->profile == WMF_PROFILE_ADVANCED) && (pic_params->pic_quantizer_fields.bits.dquant != 0)) 2401 || (((ctx->profile != WMF_PROFILE_ADVANCED) && ((pic_params->picture_fields.bits.picture_type == WMF_PTYPE_B) || (pic_params->picture_fields.bits.picture_type == WMF_PTYPE_P))) && (pic_params->pic_quantizer_fields.bits.dquant != 0))) { 2402 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_VOPDQUANT_PRESENT, 1); 2403 } else { 2404 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_VOPDQUANT_PRESENT, 0); 2405 } 2406 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQUANTFRM, pic_params->pic_quantizer_fields.bits.dq_frame); 2407 { 2408 IMG_BOOL DQUANT_INFRAME = (pic_params->pic_quantizer_fields.bits.dquant == 2) || 2409 ((pic_params->pic_quantizer_fields.bits.dquant == 1) && pic_params->pic_quantizer_fields.bits.dq_frame) || 2410 ((pic_params->pic_quantizer_fields.bits.dquant == 3) && pic_params->pic_quantizer_fields.bits.dq_frame); 2411 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQUANT_INFRAME, DQUANT_INFRAME); 2412 } 2413 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_ALTPQUANT, pic_params->pic_quantizer_fields.bits.alt_pic_quantizer); 2414 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQPROFILE, pic_params->pic_quantizer_fields.bits.dq_profile); 2415 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_DQBILEVEL, pic_params->pic_quantizer_fields.bits.dq_binary_level); 2416 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_PQINDEX_GT8, ctx->pqindex_gt8); 2417 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_TRANSACFRM, pic_params->transform_fields.bits.transform_ac_codingset_idx1); 2418 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2, VC1_FE_TRANSACFRM2, pic_params->transform_fields.bits.transform_ac_codingset_idx2); 2419 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_PPS2), reg_value); 2420 2421 /* MVD_LITE0 */ 2422 reg_value = 0; 2423 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE0, VC1_FE_MVD_LITE_ENABLE, bEnableMVDLite); 2424 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE0, VC1_FE_PULLBACK_X, ctx->pull_back_x); 2425 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE0, VC1_FE_PULLBACK_Y, ctx->pull_back_y); 2426 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE0), reg_value); 2427 2428 /* MVD_LITE1 */ 2429 reg_value = 0; 2430 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_TFF, pic_params->picture_fields.bits.top_field_first); 2431 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_REFDIST, pic_params->reference_fields.bits.reference_distance); 2432 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_NUMREF, pic_params->reference_fields.bits.num_reference_pictures); 2433 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_REFFIELD, pic_params->reference_fields.bits.reference_field_pic_indicator); 2434 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_MVRANGE, pic_params->mv_fields.bits.extended_mv_range); 2435 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_HALFPEL_FLAG, ctx->half_pel); 2436 //REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_FRAME_CODING_MODE, pic_params->picture_fields.bits.frame_coding_mode); 2437 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_BOTTOM_FIELD_FLAG, ctx->bottom_field); 2438 REGIO_WRITE_FIELD(reg_value, MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1, VC1_FE_ADVANCED_PROFILE, (ctx->profile == WMF_PROFILE_ADVANCED) ? 1 : 0); 2439 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_MVD_LITE1), reg_value); 2440 2441 psb_cmdbuf_reg_end_block(cmdbuf); 2442 } 2443 2444 static void psb__VC1_setup_bitplane(context_VC1_p ctx) 2445 { 2446 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 2447 2448 psb_cmdbuf_reg_start_block(cmdbuf, 0); 2449 2450 /* Bitplanes Data Buffer Base Address */ 2451 if (ctx->bitplane_present) { 2452 ASSERT(ctx->has_bitplane); 2453 psb_cmdbuf_reg_set_address(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_BITPLANES_BASE_ADDR0), 2454 ctx->bitplane_buffer, 0); 2455 //if (psb_video_trace_fp && (psb_video_trace_level & AUXBUF_TRACE)) 2456 //psb__debug_schedule_hexdump("Bitplane buffer", ctx->bitplane_buffer, 0, (ctx->size_mb + 1) / 2); 2457 } else { 2458 psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET(MSVDX_VEC_VC1, CR_VEC_VC1_FE_BITPLANES_BASE_ADDR0), 0); 2459 } 2460 2461 psb_cmdbuf_reg_end_block(cmdbuf); 2462 } 2463 2464 static void psb__VC1_FE_state(context_VC1_p ctx) 2465 { 2466 uint32_t lldma_record_offset; 2467 psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf; 2468 psb_surface_p deblock_surface = ctx->decoded_surface->psb_surface; 2469 2470 /* See RENDER_BUFFER_HEADER */ 2471 *cmdbuf->cmd_idx++ = CMD_HEADER_VC1; 2472 2473 ctx->p_range_mapping_base = cmdbuf->cmd_idx++; /* Fill Luma Range Mapping Base later */ 2474 2475 /* VC1 Chroma Range Mapping Base Address */ 2476 RELOC(*cmdbuf->cmd_idx++, deblock_surface->buf.buffer_ofs + deblock_surface->chroma_offset, &deblock_surface->buf); 2477 2478 ctx->p_slice_params = cmdbuf->cmd_idx; 2479 *cmdbuf->cmd_idx++ = 0; /* ui32SliceParams */ 2480 2481 lldma_record_offset = psb_cmdbuf_lldma_create(cmdbuf, &ctx->preload_buffer, 0, 2482 sizeof(VC1PRELOAD), 0, LLDMA_TYPE_VC1_PRELOAD_SAVE); 2483 RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); 2484 cmdbuf->cmd_idx++; 2485 2486 lldma_record_offset = psb_cmdbuf_lldma_create(cmdbuf, &ctx->preload_buffer, 0, 2487 sizeof(VC1PRELOAD), 0, LLDMA_TYPE_VC1_PRELOAD_RESTORE); 2488 RELOC(*cmdbuf->cmd_idx, lldma_record_offset, &(cmdbuf->buf)); 2489 cmdbuf->cmd_idx++; 2490 } 2491 2492 static VAStatus psb__VC1_process_slice(context_VC1_p ctx, 2493 VASliceParameterBufferVC1 *slice_param, 2494 object_buffer_p obj_buffer) 2495 { 2496 VAStatus vaStatus = VA_STATUS_SUCCESS; 2497 2498 ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType)); 2499 2500 drv_debug_msg(VIDEO_DEBUG_GENERAL, "VC1 process slice\n"); 2501 drv_debug_msg(VIDEO_DEBUG_GENERAL, " size = %08x offset = %08x\n", slice_param->slice_data_size, slice_param->slice_data_offset); 2502 drv_debug_msg(VIDEO_DEBUG_GENERAL, " vertical pos = %d offset = %d\n", slice_param->slice_vertical_position, slice_param->macroblock_offset); 2503 drv_debug_msg(VIDEO_DEBUG_GENERAL, " slice_data_flag = %d\n", slice_param->slice_data_flag); 2504 2505 if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) || 2506 (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL)) { 2507 if (0 == slice_param->slice_data_size) { 2508 vaStatus = VA_STATUS_ERROR_UNKNOWN; 2509 DEBUG_FAILURE; 2510 return vaStatus; 2511 } 2512 ASSERT(!ctx->split_buffer_pending); 2513 2514 /* Initialise the command buffer */ 2515 /* TODO: Reuse current command buffer until full */ 2516 psb_context_get_next_cmdbuf(ctx->obj_context); 2517 2518 psb__VC1_FE_state(ctx); 2519 2520 /* TODO: Optimize? */ 2521 psb__VC1_write_VLC_tables(ctx); 2522 2523 psb__VC1_build_VLC_tables(ctx); 2524 2525 psb_cmdbuf_lldma_write_bitstream(ctx->obj_context->cmdbuf, 2526 obj_buffer->psb_buffer, 2527 obj_buffer->psb_buffer->buffer_ofs + slice_param->slice_data_offset, 2528 slice_param->slice_data_size, 2529 slice_param->macroblock_offset, 2530 (ctx->profile == WMF_PROFILE_ADVANCED) ? CMD_ENABLE_RBDU_EXTRACTION : 0); 2531 2532 if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) { 2533 ctx->split_buffer_pending = TRUE; 2534 } 2535 } else { 2536 ASSERT(ctx->split_buffer_pending); 2537 ASSERT(0 == slice_param->slice_data_offset); 2538 /* Create LLDMA chain to continue buffer */ 2539 if (slice_param->slice_data_size) { 2540 psb_cmdbuf_lldma_write_bitstream_chained(ctx->obj_context->cmdbuf, 2541 obj_buffer->psb_buffer, 2542 slice_param->slice_data_size); 2543 } 2544 } 2545 2546 if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL) || 2547 (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END)) { 2548 if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END) { 2549 ASSERT(ctx->split_buffer_pending); 2550 } 2551 2552 psb__VC1_load_sequence_registers(ctx); 2553 2554 psb__VC1_load_picture_registers(ctx, slice_param); 2555 2556 psb__VC1_setup_bitplane(ctx); 2557 2558 psb__VC1_send_rendec_params(ctx, slice_param); 2559 2560 psb__VC1_write_kick(ctx, slice_param); 2561 2562 ctx->split_buffer_pending = FALSE; 2563 ctx->obj_context->video_op = psb_video_vld; 2564 ctx->obj_context->first_mb = 0; 2565 ctx->obj_context->flags = 0; 2566 if (ctx->is_first_slice) { 2567 ctx->obj_context->flags |= FW_VA_RENDER_IS_FIRST_SLICE; 2568 } 2569 if (ctx->bitplane_present) { 2570 ctx->obj_context->flags |= FW_VA_RENDER_VC1_BITPLANE_PRESENT; 2571 } 2572 ctx->obj_context->last_mb = ((ctx->picture_height_mb - 1) << 8) | (ctx->picture_width_mb - 1); 2573 2574 if (psb_video_trace_fp && (psb_video_trace_level & AUXBUF_TRACE)) { 2575 psb__debug_schedule_hexdump("Preload buffer", &ctx->preload_buffer, 0, PRELOAD_BUFFER_SIZE); 2576 psb__debug_schedule_hexdump("AUXMSB buffer", &ctx->aux_msb_buffer, 0, 0x8000 /* AUXMSB_BUFFER_SIZE */); 2577 psb__debug_schedule_hexdump("VLC Table", &ctx->vlc_packed_table, 0, gui16vc1VlcTableSize * sizeof(IMG_UINT16)); 2578 } 2579 2580 if (psb_context_submit_cmdbuf(ctx->obj_context)) { 2581 vaStatus = VA_STATUS_ERROR_UNKNOWN; 2582 } 2583 2584 ctx->is_first_slice = FALSE; /* Reset */ 2585 } 2586 return vaStatus; 2587 } 2588 2589 static VAStatus psb__VC1_process_slice_data(context_VC1_p ctx, object_buffer_p obj_buffer) 2590 { 2591 VAStatus vaStatus = VA_STATUS_SUCCESS; 2592 VASliceParameterBufferVC1 *slice_param; 2593 int buffer_idx = 0; 2594 unsigned int element_idx = 0; 2595 2596 ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType)); 2597 2598 ASSERT(ctx->pic_params); 2599 ASSERT(ctx->slice_param_list_idx); 2600 2601 if (!ctx->pic_params) { 2602 /* Picture params missing */ 2603 vaStatus = VA_STATUS_ERROR_UNKNOWN; 2604 DEBUG_FAILURE; 2605 return vaStatus; 2606 } 2607 if ((NULL == obj_buffer->psb_buffer) || 2608 (0 == obj_buffer->size)) { 2609 /* We need to have data in the bitstream buffer */ 2610 vaStatus = VA_STATUS_ERROR_UNKNOWN; 2611 DEBUG_FAILURE; 2612 return vaStatus; 2613 } 2614 2615 while (buffer_idx < ctx->slice_param_list_idx) { 2616 object_buffer_p slice_buf = ctx->slice_param_list[buffer_idx]; 2617 if (element_idx >= slice_buf->num_elements) { 2618 /* Move to next buffer */ 2619 element_idx = 0; 2620 buffer_idx++; 2621 continue; 2622 } 2623 2624 slice_param = (VASliceParameterBufferVC1 *) slice_buf->buffer_data; 2625 slice_param += element_idx; 2626 element_idx++; 2627 vaStatus = psb__VC1_process_slice(ctx, slice_param, obj_buffer); 2628 if (vaStatus != VA_STATUS_SUCCESS) { 2629 DEBUG_FAILURE; 2630 break; 2631 } 2632 } 2633 ctx->slice_param_list_idx = 0; 2634 2635 return vaStatus; 2636 } 2637 2638 static VAStatus psb_VC1_BeginPicture( 2639 object_context_p obj_context) 2640 { 2641 INIT_CONTEXT_VC1 2642 2643 if (ctx->pic_params) { 2644 free(ctx->pic_params); 2645 ctx->pic_params = NULL; 2646 } 2647 ctx->is_first_slice = TRUE; 2648 2649 return VA_STATUS_SUCCESS; 2650 } 2651 2652 static VAStatus psb_VC1_RenderPicture( 2653 object_context_p obj_context, 2654 object_buffer_p *buffers, 2655 int num_buffers) 2656 { 2657 int i; 2658 INIT_CONTEXT_VC1 2659 VAStatus vaStatus = VA_STATUS_SUCCESS; 2660 2661 for (i = 0; i < num_buffers; i++) { 2662 object_buffer_p obj_buffer = buffers[i]; 2663 2664 switch (obj_buffer->type) { 2665 case VAPictureParameterBufferType: 2666 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_VC1_RenderPicture got VAPictureParameterBuffer\n"); 2667 vaStatus = psb__VC1_process_picture_param(ctx, obj_buffer); 2668 DEBUG_FAILURE; 2669 break; 2670 2671 case VABitPlaneBufferType: 2672 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_VC1_RenderPicture got VABitPlaneBuffer\n"); 2673 vaStatus = psb__VC1_process_bitplane(ctx, obj_buffer); 2674 DEBUG_FAILURE; 2675 break; 2676 2677 case VASliceParameterBufferType: 2678 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_VC1_RenderPicture got VASliceParameterBufferType\n"); 2679 vaStatus = psb__VC1_add_slice_param(ctx, obj_buffer); 2680 DEBUG_FAILURE; 2681 break; 2682 2683 case VASliceDataBufferType: 2684 case VAProtectedSliceDataBufferType: 2685 2686 drv_debug_msg(VIDEO_DEBUG_GENERAL, "psb_VC1_RenderPicture got %s\n", SLICEDATA_BUFFER_TYPE(obj_buffer->type)); 2687 vaStatus = psb__VC1_process_slice_data(ctx, obj_buffer); 2688 DEBUG_FAILURE; 2689 break; 2690 2691 default: 2692 vaStatus = VA_STATUS_ERROR_UNKNOWN; 2693 DEBUG_FAILURE; 2694 } 2695 if (vaStatus != VA_STATUS_SUCCESS) { 2696 break; 2697 } 2698 } 2699 2700 return vaStatus; 2701 } 2702 2703 static VAStatus psb_VC1_EndPicture( 2704 object_context_p obj_context) 2705 { 2706 INIT_CONTEXT_VC1 2707 2708 if (psb_context_flush_cmdbuf(ctx->obj_context)) { 2709 return VA_STATUS_ERROR_UNKNOWN; 2710 } 2711 2712 ASSERT(ctx->pic_params); 2713 if (!ctx->pic_params) { 2714 return VA_STATUS_ERROR_UNKNOWN; 2715 } 2716 2717 /********* Keep some picture parameters of the previously decoded picture ***********/ 2718 if (PIC_TYPE_IS_REF(ctx->pic_params->picture_fields.bits.picture_type)) { // I or P 2719 /* Assume that the picture that we just decoded (the picture previous to the one that 2720 is about to be decoded) is the backward reference picture for a B picture. */ 2721 /* TODO: Make this more robust */ 2722 ctx->ui8FCM_Ref2Pic = ctx->pic_params->picture_fields.bits.frame_coding_mode; 2723 2724 /* For interlaced field pictures only */ 2725 if ((ctx->pic_params->picture_fields.bits.frame_coding_mode != VC1_FCM_FLDI) || !ctx->pic_params->picture_fields.bits.is_first_field) { 2726 ctx->bTFF_BwRefFrm = ctx->pic_params->picture_fields.bits.top_field_first; 2727 } 2728 } 2729 2730 ctx->bRef1RangeRed = ctx->bRef0RangeRed; 2731 if (PIC_TYPE_IS_REF(ctx->pic_params->picture_fields.bits.picture_type)) { 2732 ctx->bRef0RangeRed = ctx->pic_params->range_reduction_frame; 2733 } 2734 /***********************************************************************************/ 2735 2736 free(ctx->pic_params); 2737 ctx->pic_params = NULL; 2738 2739 return VA_STATUS_SUCCESS; 2740 } 2741 2742 struct format_vtable_s psb_VC1_vtable = { 2743 queryConfigAttributes: 2744 psb_VC1_QueryConfigAttributes, 2745 validateConfig: 2746 psb_VC1_ValidateConfig, 2747 createContext: 2748 psb_VC1_CreateContext, 2749 destroyContext: 2750 psb_VC1_DestroyContext, 2751 beginPicture: 2752 psb_VC1_BeginPicture, 2753 renderPicture: 2754 psb_VC1_RenderPicture, 2755 endPicture: 2756 psb_VC1_EndPicture 2757 }; 2758