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