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