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