1/*
2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
3 * Copyright (c) Imagination Technologies Limited, UK
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 *    Waldo Bastian <waldo.bastian@intel.com>
27 *
28 */
29
30
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
69typedef 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
80typedef 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
167static 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
178static 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
185static 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
192static 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
203static 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
210static 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
217static 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
224static 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
231static 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
242static 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
248static 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
254static 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
260static 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 */
267extern IMG_UINT16        gaui16vc1VlcTableData[];
268extern const IMG_UINT16    gui16vc1VlcTableSize;
269extern IMG_UINT16        gaui16vc1VlcIndexData[VLC_INDEX_TABLE_SIZE][3];
270extern const IMG_UINT8    gui8vc1VlcIndexSize;
271
272
273static IMG_UINT16       gaui16Inverse[] = {256, 128, 85, 64, 51, 43, 37, 32};    /* figure 66 */
274static IMG_BOOL         gDMVRANGE_ExtHorizontal_RemapTable[] = {0, 1, 0, 1};
275static IMG_BOOL         gDMVRANGE_ExtVertical_RemapTable[] = {0, 0, 1, 1};
276static 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};
277static 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
285static 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
294static 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
314static 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
332static 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
361static 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
414static void psb_VC1_DestroyContext(object_context_p obj_context);
415
416static 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
522static 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
554static 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
578static 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
588static 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)
619static 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
708static 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
1261static 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 */
1282static 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 */
1304static 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 */
1321static 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
1697static 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
1793static 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*/
1803static 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
1835static 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
2309static 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
2344static 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
2444static 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
2464static 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
2492static 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
2589static 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
2638static 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
2652static 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
2703static 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
2742struct format_vtable_s psb_VC1_vtable = {
2743queryConfigAttributes:
2744    psb_VC1_QueryConfigAttributes,
2745validateConfig:
2746    psb_VC1_ValidateConfig,
2747createContext:
2748    psb_VC1_CreateContext,
2749destroyContext:
2750    psb_VC1_DestroyContext,
2751beginPicture:
2752    psb_VC1_BeginPicture,
2753renderPicture:
2754    psb_VC1_RenderPicture,
2755endPicture:
2756    psb_VC1_EndPicture
2757};
2758