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