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