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