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