pnw_MPEG2.c revision 4b5b72d7dd3fe944d75029ff0ca6db1e74600e59
1/*
2 * INTEL CONFIDENTIAL
3 * Copyright 2007 Intel Corporation. All Rights Reserved.
4 * Copyright 2005-2007 Imagination Technologies Limited. All Rights Reserved.
5 *
6 * The source code contained or described herein and all documents related to
7 * the source code ("Material") are owned by Intel Corporation or its suppliers
8 * or licensors. Title to the Material remains with Intel Corporation or its
9 * suppliers and licensors. The Material may contain trade secrets and
10 * proprietary and confidential information of Intel Corporation and its
11 * suppliers and licensors, and is protected by worldwide copyright and trade
12 * secret laws and treaty provisions. No part of the Material may be used,
13 * copied, reproduced, modified, published, uploaded, posted, transmitted,
14 * distributed, or disclosed in any way without Intel's prior express written
15 * permission.
16 *
17 * No license under any patent, copyright, trade secret or other intellectual
18 * property right is granted to or conferred upon you by disclosure or delivery
19 * of the Materials, either expressly, by implication, inducement, estoppel or
20 * otherwise. Any license under such intellectual property rights must be
21 * express and approved by Intel in writing.
22 */
23
24
25#include "pnw_MPEG2.h"
26#include "psb_def.h"
27#include "psb_surface.h"
28#include "psb_cmdbuf.h"
29
30#include "hwdefs/reg_io2.h"
31#include "hwdefs/msvdx_offsets.h"
32#include "hwdefs/msvdx_cmds_io2.h"
33#include "hwdefs/msvdx_vec_reg_io2.h"
34#include "hwdefs/msvdx_vec_mpeg2_reg_io2.h"
35#include "hwdefs/dxva_fw_ctrl.h"
36
37#include <stdlib.h>
38#include <stdint.h>
39#include <string.h>
40
41#define GET_SURFACE_INFO_is_defined(psb_surface) ((int) (psb_surface->extra_info[0]))
42#define SET_SURFACE_INFO_is_defined(psb_surface, val) psb_surface->extra_info[0] = (uint32_t) val;
43#define GET_SURFACE_INFO_picture_structure(psb_surface) (psb_surface->extra_info[1])
44#define SET_SURFACE_INFO_picture_structure(psb_surface, val) psb_surface->extra_info[1] = val;
45#define GET_SURFACE_INFO_picture_coding_type(psb_surface) ((int) (psb_surface->extra_info[2]))
46#define SET_SURFACE_INFO_picture_coding_type(psb_surface, val) psb_surface->extra_info[2] = (uint32_t) val;
47
48
49#define SLICEDATA_BUFFER_TYPE(type) ((type==VASliceDataBufferType)?"VASliceDataBufferType":"VAProtectedSliceDataBufferType")
50
51/*
52 * Frame types - format dependant!
53 */
54#define PICTURE_CODING_I    0x01
55#define PICTURE_CODING_P    0x02
56#define PICTURE_CODING_B    0x03
57/* A special syntax is defined for D-pictures (picture_coding_type = 4). D-pictures are like I-pictures with only Intra-DC coefficients,
58   no End of Block, and a special end_of_macroblock code '1'. PICTURE_CODING_D is not allowed in MPEG2 */
59#define PICTURE_CODING_D    0x04
60
61/************************************************************************************/
62/*                Variable length codes in 'packed' format                            */
63/************************************************************************************/
64
65/* Format is: opcode, width, symbol. All VLC tables are concatenated. Index            */
66/* infomation is stored in gui16mpeg2VlcIndexData[]                                    */
67#define VLC_PACK(a,b,c)         ( ( (a) << 12 ) | ( (b) << 9  ) | (c) )
68const static IMG_UINT16 gaui16mpeg2VlcTableDataPacked[] =
69{
70    VLC_PACK( 6 , 0 , 0 ) ,
71    VLC_PACK( 0 , 0 , 6 ) ,
72    VLC_PACK( 4 , 2 , 4 ) ,
73    VLC_PACK( 4 , 3 , 5 ) ,
74    VLC_PACK( 4 , 4 , 6 ) ,
75    VLC_PACK( 4 , 5 , 7 ) ,
76    VLC_PACK( 1 , 1 , 3 ) ,
77    VLC_PACK( 4 , 0 , 0 ) ,
78    VLC_PACK( 4 , 0 , 3 ) ,
79    VLC_PACK( 4 , 0 , 8 ) ,
80    VLC_PACK( 4 , 1 , 9 ) ,
81    VLC_PACK( 5 , 0 , 5 ) ,
82    VLC_PACK( 5 , 0 , 0 ) ,
83    VLC_PACK( 4 , 1 , 2 ) ,
84    VLC_PACK( 4 , 2 , 3 ) ,
85    VLC_PACK( 4 , 3 , 4 ) ,
86    VLC_PACK( 4 , 4 , 5 ) ,
87    VLC_PACK( 4 , 5 , 6 ) ,
88    VLC_PACK( 1 , 2 , 1 ) ,
89    VLC_PACK( 4 , 0 , 7 ) ,
90    VLC_PACK( 4 , 1 , 8 ) ,
91    VLC_PACK( 4 , 2 , 9 ) ,
92    VLC_PACK( 5 , 0 , 5 ) ,
93    VLC_PACK( 0 , 2 , 16 ) ,
94    VLC_PACK( 0 , 1 , 87 ) ,
95    VLC_PACK( 2 , 3 , 90 ) ,
96    VLC_PACK( 0 , 0 , 98 ) ,
97    VLC_PACK( 5 , 0 , 253 ) ,
98    VLC_PACK( 5 , 0 , 366 ) ,
99    VLC_PACK( 4 , 3 , 380 ) ,
100    VLC_PACK( 4 , 3 , 381 ) ,
101    VLC_PACK( 4 , 1 , 508 ) ,
102    VLC_PACK( 4 , 1 , 508 ) ,
103    VLC_PACK( 4 , 1 , 508 ) ,
104    VLC_PACK( 4 , 1 , 508 ) ,
105    VLC_PACK( 4 , 1 , 509 ) ,
106    VLC_PACK( 4 , 1 , 509 ) ,
107    VLC_PACK( 4 , 1 , 509 ) ,
108    VLC_PACK( 4 , 1 , 509 ) ,
109    VLC_PACK( 0 , 4 , 8 ) ,
110    VLC_PACK( 0 , 2 , 63 ) ,
111    VLC_PACK( 4 , 1 , 255 ) ,
112    VLC_PACK( 4 , 1 , 255 ) ,
113    VLC_PACK( 5 , 0 , 365 ) ,
114    VLC_PACK( 5 , 0 , 470 ) ,
115    VLC_PACK( 5 , 0 , 251 ) ,
116    VLC_PACK( 5 , 0 , 471 ) ,
117    VLC_PACK( 3 , 4 , 0 ) ,
118    VLC_PACK( 0 , 1 , 31 ) ,
119    VLC_PACK( 0 , 0 , 40 ) ,
120    VLC_PACK( 2 , 2 , 41 ) ,
121    VLC_PACK( 5 , 2 , 224 ) ,
122    VLC_PACK( 5 , 2 , 228 ) ,
123    VLC_PACK( 5 , 2 , 232 ) ,
124    VLC_PACK( 5 , 2 , 236 ) ,
125    VLC_PACK( 5 , 1 , 437 ) ,
126    VLC_PACK( 0 , 0 , 39 ) ,
127    VLC_PACK( 0 , 0 , 40 ) ,
128    VLC_PACK( 0 , 0 , 41 ) ,
129    VLC_PACK( 5 , 1 , 241 ) ,
130    VLC_PACK( 0 , 0 , 41 ) ,
131    VLC_PACK( 5 , 1 , 454 ) ,
132    VLC_PACK( 5 , 1 , 456 ) ,
133    VLC_PACK( 5 , 0 , 244 ) ,
134    VLC_PACK( 5 , 0 , 439 ) ,
135    VLC_PACK( 5 , 0 , 348 ) ,
136    VLC_PACK( 5 , 0 , 245 ) ,
137    VLC_PACK( 5 , 0 , 363 ) ,
138    VLC_PACK( 5 , 0 , 325 ) ,
139    VLC_PACK( 5 , 0 , 458 ) ,
140    VLC_PACK( 5 , 0 , 459 ) ,
141    VLC_PACK( 5 , 0 , 246 ) ,
142    VLC_PACK( 5 , 0 , 460 ) ,
143    VLC_PACK( 5 , 0 , 461 ) ,
144    VLC_PACK( 5 , 0 , 186 ) ,
145    VLC_PACK( 5 , 0 , 356 ) ,
146    VLC_PACK( 5 , 0 , 247 ) ,
147    VLC_PACK( 5 , 0 , 333 ) ,
148    VLC_PACK( 5 , 0 , 462 ) ,
149    VLC_PACK( 5 , 2 , 173 ) ,
150    VLC_PACK( 2 , 1 , 3 ) ,
151    VLC_PACK( 1 , 1 , 5 ) ,
152    VLC_PACK( 5 , 2 , 449 ) ,
153    VLC_PACK( 5 , 1 , 432 ) ,
154    VLC_PACK( 5 , 0 , 431 ) ,
155    VLC_PACK( 5 , 0 , 332 ) ,
156    VLC_PACK( 5 , 1 , 434 ) ,
157    VLC_PACK( 5 , 0 , 436 ) ,
158    VLC_PACK( 5 , 0 , 448 ) ,
159    VLC_PACK( 5 , 2 , 215 ) ,
160    VLC_PACK( 5 , 2 , 219 ) ,
161    VLC_PACK( 5 , 2 , 180 ) ,
162    VLC_PACK( 5 , 1 , 178 ) ,
163    VLC_PACK( 5 , 0 , 177 ) ,
164    VLC_PACK( 5 , 0 , 223 ) ,
165    VLC_PACK( 5 , 0 , 340 ) ,
166    VLC_PACK( 5 , 0 , 355 ) ,
167    VLC_PACK( 5 , 0 , 362 ) ,
168    VLC_PACK( 5 , 0 , 184 ) ,
169    VLC_PACK( 5 , 0 , 185 ) ,
170    VLC_PACK( 5 , 0 , 240 ) ,
171    VLC_PACK( 5 , 0 , 243 ) ,
172    VLC_PACK( 5 , 0 , 453 ) ,
173    VLC_PACK( 5 , 0 , 463 ) ,
174    VLC_PACK( 5 , 0 , 341 ) ,
175    VLC_PACK( 5 , 0 , 248 ) ,
176    VLC_PACK( 5 , 0 , 364 ) ,
177    VLC_PACK( 5 , 0 , 187 ) ,
178    VLC_PACK( 5 , 0 , 464 ) ,
179    VLC_PACK( 5 , 0 , 465 ) ,
180    VLC_PACK( 5 , 0 , 349 ) ,
181    VLC_PACK( 5 , 0 , 326 ) ,
182    VLC_PACK( 5 , 0 , 334 ) ,
183    VLC_PACK( 5 , 0 , 189 ) ,
184    VLC_PACK( 5 , 0 , 342 ) ,
185    VLC_PACK( 5 , 0 , 252 ) ,
186    VLC_PACK( 0 , 1 , 4 ) ,
187    VLC_PACK( 5 , 1 , 467 ) ,
188    VLC_PACK( 5 , 0 , 249 ) ,
189    VLC_PACK( 5 , 0 , 466 ) ,
190    VLC_PACK( 5 , 0 , 357 ) ,
191    VLC_PACK( 5 , 0 , 188 ) ,
192    VLC_PACK( 5 , 0 , 250 ) ,
193    VLC_PACK( 5 , 0 , 469 ) ,
194    VLC_PACK( 5 , 0 , 350 ) ,
195    VLC_PACK( 5 , 0 , 358 ) ,
196    VLC_PACK( 0 , 2 , 16 ) ,
197    VLC_PACK( 0 , 1 , 87 ) ,
198    VLC_PACK( 2 , 3 , 90 ) ,
199    VLC_PACK( 0 , 0 , 98 ) ,
200    VLC_PACK( 5 , 0 , 253 ) ,
201    VLC_PACK( 5 , 0 , 366 ) ,
202    VLC_PACK( 4 , 3 , 380 ) ,
203    VLC_PACK( 4 , 3 , 381 ) ,
204    VLC_PACK( 4 , 1 , 254 ) ,
205    VLC_PACK( 4 , 1 , 254 ) ,
206    VLC_PACK( 4 , 1 , 254 ) ,
207    VLC_PACK( 4 , 1 , 254 ) ,
208    VLC_PACK( 4 , 2 , 508 ) ,
209    VLC_PACK( 4 , 2 , 508 ) ,
210    VLC_PACK( 4 , 2 , 509 ) ,
211    VLC_PACK( 4 , 2 , 509 ) ,
212    VLC_PACK( 0 , 4 , 8 ) ,
213    VLC_PACK( 0 , 2 , 63 ) ,
214    VLC_PACK( 4 , 1 , 255 ) ,
215    VLC_PACK( 4 , 1 , 255 ) ,
216    VLC_PACK( 5 , 0 , 365 ) ,
217    VLC_PACK( 5 , 0 , 470 ) ,
218    VLC_PACK( 5 , 0 , 251 ) ,
219    VLC_PACK( 5 , 0 , 471 ) ,
220    VLC_PACK( 3 , 4 , 0 ) ,
221    VLC_PACK( 0 , 1 , 31 ) ,
222    VLC_PACK( 0 , 0 , 40 ) ,
223    VLC_PACK( 2 , 2 , 41 ) ,
224    VLC_PACK( 5 , 2 , 224 ) ,
225    VLC_PACK( 5 , 2 , 228 ) ,
226    VLC_PACK( 5 , 2 , 232 ) ,
227    VLC_PACK( 5 , 2 , 236 ) ,
228    VLC_PACK( 5 , 1 , 437 ) ,
229    VLC_PACK( 0 , 0 , 39 ) ,
230    VLC_PACK( 0 , 0 , 40 ) ,
231    VLC_PACK( 0 , 0 , 41 ) ,
232    VLC_PACK( 5 , 1 , 241 ) ,
233    VLC_PACK( 0 , 0 , 41 ) ,
234    VLC_PACK( 5 , 1 , 454 ) ,
235    VLC_PACK( 5 , 1 , 456 ) ,
236    VLC_PACK( 5 , 0 , 244 ) ,
237    VLC_PACK( 5 , 0 , 439 ) ,
238    VLC_PACK( 5 , 0 , 348 ) ,
239    VLC_PACK( 5 , 0 , 245 ) ,
240    VLC_PACK( 5 , 0 , 363 ) ,
241    VLC_PACK( 5 , 0 , 325 ) ,
242    VLC_PACK( 5 , 0 , 458 ) ,
243    VLC_PACK( 5 , 0 , 459 ) ,
244    VLC_PACK( 5 , 0 , 246 ) ,
245    VLC_PACK( 5 , 0 , 460 ) ,
246    VLC_PACK( 5 , 0 , 461 ) ,
247    VLC_PACK( 5 , 0 , 186 ) ,
248    VLC_PACK( 5 , 0 , 356 ) ,
249    VLC_PACK( 5 , 0 , 247 ) ,
250    VLC_PACK( 5 , 0 , 333 ) ,
251    VLC_PACK( 5 , 0 , 462 ) ,
252    VLC_PACK( 5 , 2 , 173 ) ,
253    VLC_PACK( 2 , 1 , 3 ) ,
254    VLC_PACK( 1 , 1 , 5 ) ,
255    VLC_PACK( 5 , 2 , 449 ) ,
256    VLC_PACK( 5 , 1 , 432 ) ,
257    VLC_PACK( 5 , 0 , 431 ) ,
258    VLC_PACK( 5 , 0 , 332 ) ,
259    VLC_PACK( 5 , 1 , 434 ) ,
260    VLC_PACK( 5 , 0 , 436 ) ,
261    VLC_PACK( 5 , 0 , 448 ) ,
262    VLC_PACK( 5 , 2 , 215 ) ,
263    VLC_PACK( 5 , 2 , 219 ) ,
264    VLC_PACK( 5 , 2 , 180 ) ,
265    VLC_PACK( 5 , 1 , 178 ) ,
266    VLC_PACK( 5 , 0 , 177 ) ,
267    VLC_PACK( 5 , 0 , 223 ) ,
268    VLC_PACK( 5 , 0 , 340 ) ,
269    VLC_PACK( 5 , 0 , 355 ) ,
270    VLC_PACK( 5 , 0 , 362 ) ,
271    VLC_PACK( 5 , 0 , 184 ) ,
272    VLC_PACK( 5 , 0 , 185 ) ,
273    VLC_PACK( 5 , 0 , 240 ) ,
274    VLC_PACK( 5 , 0 , 243 ) ,
275    VLC_PACK( 5 , 0 , 453 ) ,
276    VLC_PACK( 5 , 0 , 463 ) ,
277    VLC_PACK( 5 , 0 , 341 ) ,
278    VLC_PACK( 5 , 0 , 248 ) ,
279    VLC_PACK( 5 , 0 , 364 ) ,
280    VLC_PACK( 5 , 0 , 187 ) ,
281    VLC_PACK( 5 , 0 , 464 ) ,
282    VLC_PACK( 5 , 0 , 465 ) ,
283    VLC_PACK( 5 , 0 , 349 ) ,
284    VLC_PACK( 5 , 0 , 326 ) ,
285    VLC_PACK( 5 , 0 , 334 ) ,
286    VLC_PACK( 5 , 0 , 189 ) ,
287    VLC_PACK( 5 , 0 , 342 ) ,
288    VLC_PACK( 5 , 0 , 252 ) ,
289    VLC_PACK( 0 , 1 , 4 ) ,
290    VLC_PACK( 5 , 1 , 467 ) ,
291    VLC_PACK( 5 , 0 , 249 ) ,
292    VLC_PACK( 5 , 0 , 466 ) ,
293    VLC_PACK( 5 , 0 , 357 ) ,
294    VLC_PACK( 5 , 0 , 188 ) ,
295    VLC_PACK( 5 , 0 , 250 ) ,
296    VLC_PACK( 5 , 0 , 469 ) ,
297    VLC_PACK( 5 , 0 , 350 ) ,
298    VLC_PACK( 5 , 0 , 358 ) ,
299    VLC_PACK( 2 , 2 , 32 ) ,
300    VLC_PACK( 0 , 1 , 87 ) ,
301    VLC_PACK( 5 , 1 , 248 ) ,
302    VLC_PACK( 0 , 0 , 89 ) ,
303    VLC_PACK( 1 , 2 , 90 ) ,
304    VLC_PACK( 5 , 0 , 366 ) ,
305    VLC_PACK( 5 , 0 , 189 ) ,
306    VLC_PACK( 5 , 0 , 358 ) ,
307    VLC_PACK( 4 , 3 , 380 ) ,
308    VLC_PACK( 4 , 3 , 380 ) ,
309    VLC_PACK( 4 , 3 , 381 ) ,
310    VLC_PACK( 4 , 3 , 381 ) ,
311    VLC_PACK( 4 , 3 , 254 ) ,
312    VLC_PACK( 4 , 3 , 254 ) ,
313    VLC_PACK( 4 , 4 , 504 ) ,
314    VLC_PACK( 4 , 4 , 505 ) ,
315    VLC_PACK( 4 , 2 , 508 ) ,
316    VLC_PACK( 4 , 2 , 508 ) ,
317    VLC_PACK( 4 , 2 , 508 ) ,
318    VLC_PACK( 4 , 2 , 508 ) ,
319    VLC_PACK( 4 , 2 , 509 ) ,
320    VLC_PACK( 4 , 2 , 509 ) ,
321    VLC_PACK( 4 , 2 , 509 ) ,
322    VLC_PACK( 4 , 2 , 509 ) ,
323    VLC_PACK( 4 , 3 , 506 ) ,
324    VLC_PACK( 4 , 3 , 506 ) ,
325    VLC_PACK( 4 , 3 , 507 ) ,
326    VLC_PACK( 4 , 3 , 507 ) ,
327    VLC_PACK( 5 , 0 , 251 ) ,
328    VLC_PACK( 5 , 0 , 250 ) ,
329    VLC_PACK( 0 , 1 , 71 ) ,
330    VLC_PACK( 0 , 2 , 74 ) ,
331    VLC_PACK( 4 , 0 , 255 ) ,
332    VLC_PACK( 0 , 1 , 3 ) ,
333    VLC_PACK( 0 , 2 , 8 ) ,
334    VLC_PACK( 0 , 3 , 17 ) ,
335    VLC_PACK( 5 , 0 , 341 ) ,
336    VLC_PACK( 5 , 0 , 465 ) ,
337    VLC_PACK( 0 , 0 , 2 ) ,
338    VLC_PACK( 5 , 0 , 464 ) ,
339    VLC_PACK( 5 , 0 , 363 ) ,
340    VLC_PACK( 5 , 0 , 463 ) ,
341    VLC_PACK( 5 , 1 , 438 ) ,
342    VLC_PACK( 5 , 1 , 348 ) ,
343    VLC_PACK( 5 , 1 , 324 ) ,
344    VLC_PACK( 5 , 1 , 458 ) ,
345    VLC_PACK( 5 , 1 , 459 ) ,
346    VLC_PACK( 5 , 1 , 461 ) ,
347    VLC_PACK( 5 , 1 , 356 ) ,
348    VLC_PACK( 0 , 0 , 1 ) ,
349    VLC_PACK( 5 , 0 , 333 ) ,
350    VLC_PACK( 5 , 0 , 462 ) ,
351    VLC_PACK( 3 , 3 , 0 ) ,
352    VLC_PACK( 0 , 1 , 15 ) ,
353    VLC_PACK( 0 , 0 , 24 ) ,
354    VLC_PACK( 2 , 2 , 25 ) ,
355    VLC_PACK( 5 , 2 , 224 ) ,
356    VLC_PACK( 5 , 2 , 228 ) ,
357    VLC_PACK( 5 , 2 , 232 ) ,
358    VLC_PACK( 5 , 2 , 236 ) ,
359    VLC_PACK( 5 , 1 , 437 ) ,
360    VLC_PACK( 0 , 0 , 23 ) ,
361    VLC_PACK( 0 , 0 , 24 ) ,
362    VLC_PACK( 5 , 1 , 185 ) ,
363    VLC_PACK( 3 , 3 , 0 ) ,
364    VLC_PACK( 5 , 1 , 452 ) ,
365    VLC_PACK( 5 , 1 , 454 ) ,
366    VLC_PACK( 5 , 1 , 456 ) ,
367    VLC_PACK( 5 , 2 , 173 ) ,
368    VLC_PACK( 2 , 1 , 3 ) ,
369    VLC_PACK( 1 , 1 , 5 ) ,
370    VLC_PACK( 5 , 2 , 449 ) ,
371    VLC_PACK( 5 , 1 , 432 ) ,
372    VLC_PACK( 5 , 0 , 431 ) ,
373    VLC_PACK( 5 , 0 , 332 ) ,
374    VLC_PACK( 5 , 1 , 434 ) ,
375    VLC_PACK( 5 , 0 , 436 ) ,
376    VLC_PACK( 5 , 0 , 448 ) ,
377    VLC_PACK( 5 , 2 , 215 ) ,
378    VLC_PACK( 5 , 2 , 219 ) ,
379    VLC_PACK( 5 , 2 , 180 ) ,
380    VLC_PACK( 5 , 1 , 178 ) ,
381    VLC_PACK( 5 , 0 , 177 ) ,
382    VLC_PACK( 5 , 0 , 223 ) ,
383    VLC_PACK( 5 , 0 , 340 ) ,
384    VLC_PACK( 5 , 0 , 355 ) ,
385    VLC_PACK( 5 , 0 , 362 ) ,
386    VLC_PACK( 5 , 0 , 184 ) ,
387    VLC_PACK( 5 , 0 , 326 ) ,
388    VLC_PACK( 5 , 0 , 471 ) ,
389    VLC_PACK( 5 , 0 , 334 ) ,
390    VLC_PACK( 5 , 0 , 365 ) ,
391    VLC_PACK( 5 , 0 , 350 ) ,
392    VLC_PACK( 5 , 0 , 342 ) ,
393    VLC_PACK( 2 , 1 , 4 ) ,
394    VLC_PACK( 5 , 1 , 466 ) ,
395    VLC_PACK( 5 , 0 , 357 ) ,
396    VLC_PACK( 5 , 0 , 187 ) ,
397    VLC_PACK( 5 , 1 , 244 ) ,
398    VLC_PACK( 5 , 0 , 468 ) ,
399    VLC_PACK( 5 , 0 , 186 ) ,
400    VLC_PACK( 5 , 0 , 470 ) ,
401    VLC_PACK( 5 , 0 , 188 ) ,
402    VLC_PACK( 5 , 0 , 469 ) ,
403    VLC_PACK( 5 , 0 , 247 ) ,
404    VLC_PACK( 4 , 2 , 492 ) ,
405    VLC_PACK( 4 , 2 , 493 ) ,
406    VLC_PACK( 5 , 0 , 243 ) ,
407    VLC_PACK( 5 , 0 , 242 ) ,
408    VLC_PACK( 5 , 0 , 364 ) ,
409    VLC_PACK( 5 , 0 , 349 ) ,
410    VLC_PACK( 5 , 0 , 241 ) ,
411    VLC_PACK( 5 , 0 , 240 ) ,
412    VLC_PACK( 4 , 0 , 30 ) ,
413    VLC_PACK( 5 , 0 , 14 ) ,
414    VLC_PACK( 5 , 0 , 13 ) ,
415    VLC_PACK( 5 , 0 , 12 ) ,
416    VLC_PACK( 0 , 0 , 3 ) ,
417    VLC_PACK( 2 , 2 , 4 ) ,
418    VLC_PACK( 0 , 1 , 7 ) ,
419    VLC_PACK( 5 , 1 , 9 ) ,
420    VLC_PACK( 5 , 0 , 11 ) ,
421    VLC_PACK( 5 , 0 , 8 ) ,
422    VLC_PACK( 5 , 1 , 6 ) ,
423    VLC_PACK( 5 , 0 , 5 ) ,
424    VLC_PACK( 5 , 1 , 3 ) ,
425    VLC_PACK( 3 , 1 , 0 ) ,
426    VLC_PACK( 2 , 2 , 3 ) ,
427    VLC_PACK( 3 , 1 , 0 ) ,
428    VLC_PACK( 2 , 1 , 5 ) ,
429    VLC_PACK( 3 , 2 , 0 ) ,
430    VLC_PACK( 3 , 2 , 0 ) ,
431    VLC_PACK( 3 , 2 , 0 ) ,
432    VLC_PACK( 4 , 2 , 226 ) ,
433    VLC_PACK( 5 , 1 , 1 ) ,
434    VLC_PACK( 5 , 0 , 0 ) ,
435    VLC_PACK( 5 , 0 , 31 ) ,
436    VLC_PACK( 4 , 0 , 62 ) ,
437    VLC_PACK( 5 , 0 , 30 ) ,
438    VLC_PACK( 5 , 0 , 29 ) ,
439    VLC_PACK( 5 , 0 , 28 ) ,
440    VLC_PACK( 0 , 0 , 3 ) ,
441    VLC_PACK( 2 , 2 , 4 ) ,
442    VLC_PACK( 1 , 1 , 7 ) ,
443    VLC_PACK( 5 , 1 , 25 ) ,
444    VLC_PACK( 5 , 0 , 27 ) ,
445    VLC_PACK( 5 , 0 , 24 ) ,
446    VLC_PACK( 5 , 1 , 22 ) ,
447    VLC_PACK( 5 , 0 , 21 ) ,
448    VLC_PACK( 5 , 1 , 19 ) ,
449    VLC_PACK( 3 , 1 , 0 ) ,
450    VLC_PACK( 3 , 1 , 0 ) ,
451    VLC_PACK( 5 , 2 , 15 )
452};
453
454#define MAX_QUANT_TABLES    (2) /* only 2 tables for 4:2:0 decode */
455
456static int scan0[64] = // spec, fig 7-2
457{/*u 0  .....                   7*/
458    0,  1,  5,  6,  14, 15, 27, 28,  /* v = 0 */
459    2,  4,  7,  13, 16, 26, 29, 42,
460    3,  8,  12, 17, 25, 30, 41, 43,
461    9,  11, 18, 24, 31, 40, 44, 53,
462    10, 19, 23, 32, 39, 45, 52, 54,
463    20, 22, 33, 38, 46, 51, 55, 60,
464    21, 34, 37, 47, 50, 56, 59, 61,
465    35, 36, 48, 49, 57, 58, 62, 63  /* v = 7 */
466};
467
468typedef enum
469{
470    NONINTRA_LUMA_Q = 0,
471    INTRA_LUMA_Q = 1
472} QUANT_IDX;
473
474struct context_MPEG2_s {
475    object_context_p obj_context; /* back reference */
476
477    /* Picture parameters */
478    VAPictureParameterBufferMPEG2 *pic_params;
479    object_surface_p forward_ref_surface;
480    object_surface_p backward_ref_surface;
481
482    uint32_t coded_picture_width;    /* in pixels */
483    uint32_t coded_picture_height;    /* in pixels */
484
485    uint32_t picture_width_mb;        /* in macroblocks */
486    uint32_t picture_height_mb;        /* in macroblocks */
487    uint32_t size_mb;                /* in macroblocks */
488
489    uint32_t coded_picture_size;    /* MSVDX format */
490    uint32_t display_picture_size;    /* MSVDX format */
491
492    uint32_t BE_PPS0;
493    uint32_t BE_PPS1;
494    uint32_t BE_PPS2;
495    uint32_t BE_SPS0;
496    uint32_t BE_SPS1;
497    uint32_t FE_PPS0;
498    uint32_t FE_PPS1;
499
500    /* IQ Matrix */
501    uint32_t qmatrix_data[MAX_QUANT_TABLES][16];
502    int got_iq_matrix;
503
504    /* Split buffers */
505    int split_buffer_pending;
506
507    /* List of VASliceParameterBuffers */
508    object_buffer_p *slice_param_list;
509    int slice_param_list_size;
510    int slice_param_list_idx;
511
512    /* VLC packed data */
513    struct psb_buffer_s vlc_packed_table;
514
515    /* Misc */
516    unsigned int previous_slice_vertical_position;
517
518    uint32_t *p_range_mapping_base0;
519    uint32_t *p_range_mapping_base1;
520    uint32_t *p_slice_params; /* pointer to ui32SliceParams in CMD_HEADER */
521    uint32_t *slice_first_pic_last;
522};
523
524typedef struct context_MPEG2_s *context_MPEG2_p;
525
526#define INIT_CONTEXT_MPEG2    context_MPEG2_p ctx = (context_MPEG2_p) obj_context->format_data;
527
528#define SURFACE(id)    ((object_surface_p) object_heap_lookup( &ctx->obj_context->driver_data->surface_heap, id ))
529
530
531static void pnw_MPEG2_QueryConfigAttributes(
532            VAProfile profile,
533            VAEntrypoint entrypoint,
534            VAConfigAttrib *attrib_list,
535            int num_attribs )
536{
537    /* No MPEG2 specific attributes */
538}
539
540static VAStatus pnw_MPEG2_ValidateConfig(
541            object_config_p obj_config )
542{
543    int i;
544    /* Check all attributes */
545    for(i = 0; i < obj_config->attrib_count; i++)
546    {
547        switch (obj_config->attrib_list[i].type)
548        {
549          case VAConfigAttribRTFormat:
550                  /* Ignore */
551                  break;
552
553          default:
554                  return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED;
555        }
556    }
557
558    return VA_STATUS_SUCCESS;
559}
560
561static VAStatus psb__MPEG2_check_legal_picture(object_context_p obj_context, object_config_p obj_config)
562{
563    VAStatus vaStatus = VA_STATUS_SUCCESS;
564
565    if (NULL == obj_context)
566    {
567        vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT;
568        DEBUG_FAILURE;
569        return vaStatus;
570    }
571
572    if (NULL == obj_config)
573    {
574        vaStatus = VA_STATUS_ERROR_INVALID_CONFIG;
575        DEBUG_FAILURE;
576        return vaStatus;
577    }
578
579    /* MSVDX decode capability for MPEG2:
580     *     MP@HL
581     *
582     * Refer to Table 8-11 (Upper bounds for luminance sample rate) of ISO/IEC 13818-2: 1995(E),
583     * and the "MSVDX MPEG2 decode capability" table of "Poulsbo Media Software Overview"
584     */
585
586    switch (obj_config->profile)
587    {
588        case VAProfileMPEG2Simple:
589            if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 352)
590                || (obj_context->picture_height <= 0) || (obj_context->picture_height > 288))
591            {
592                vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
593            }
594            break;
595
596        case VAProfileMPEG2Main:
597            if ((obj_context->picture_width <= 0) || (obj_context->picture_width > 1920)
598                || (obj_context->picture_height <= 0) || (obj_context->picture_height > 1088))
599            {
600                vaStatus = VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED;
601            }
602            break;
603
604        default:
605            vaStatus = VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
606            break;
607    }
608
609    return vaStatus;
610}
611
612static void pnw_MPEG2_DestroyContext(object_context_p obj_context);
613
614static VAStatus pnw_MPEG2_CreateContext(
615            object_context_p obj_context,
616            object_config_p obj_config )
617{
618    VAStatus vaStatus = VA_STATUS_SUCCESS;
619    context_MPEG2_p ctx;
620    /* Validate flag */
621    /* Validate picture dimensions */
622    vaStatus = psb__MPEG2_check_legal_picture(obj_context, obj_config);
623    if (VA_STATUS_SUCCESS != vaStatus)
624    {
625        DEBUG_FAILURE;
626        return vaStatus;
627    }
628
629    if (obj_context->num_render_targets < 1)
630    {
631        vaStatus = VA_STATUS_ERROR_UNKNOWN;
632        DEBUG_FAILURE;
633        return vaStatus;
634    }
635    ctx = (context_MPEG2_p) calloc(1, sizeof(struct context_MPEG2_s));
636    if (NULL == ctx)
637    {
638        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
639        DEBUG_FAILURE;
640        return vaStatus;
641    }
642
643    obj_context->format_data = (void*) ctx;
644    ctx->obj_context = obj_context;
645    ctx->pic_params = NULL;
646    ctx->got_iq_matrix = FALSE;
647    ctx->previous_slice_vertical_position = ~1;
648
649    ctx->split_buffer_pending = FALSE;
650
651    ctx->slice_param_list_size = 8;
652    ctx->slice_param_list = (object_buffer_p*) calloc(1, sizeof(object_buffer_p)*ctx->slice_param_list_size);
653    ctx->slice_param_list_idx = 0;
654
655    if (NULL == ctx->slice_param_list)
656    {
657        vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
658        DEBUG_FAILURE;
659    }
660
661    if (vaStatus == VA_STATUS_SUCCESS)
662    {
663        vaStatus = psb_buffer_create( obj_context->driver_data,
664                           sizeof(gaui16mpeg2VlcTableDataPacked),
665                           psb_bt_cpu_vpu,
666                           &ctx->vlc_packed_table );
667        DEBUG_FAILURE;
668    }
669    if (vaStatus == VA_STATUS_SUCCESS)
670    {
671        void *vlc_packed_data_address;
672        if (0 ==  psb_buffer_map( &ctx->vlc_packed_table, &vlc_packed_data_address ))
673        {
674            memcpy( vlc_packed_data_address, gaui16mpeg2VlcTableDataPacked, sizeof(gaui16mpeg2VlcTableDataPacked));
675            psb_buffer_unmap( &ctx->vlc_packed_table );
676        }
677        else
678        {
679            vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
680            DEBUG_FAILURE;
681        }
682    }
683
684    if (vaStatus != VA_STATUS_SUCCESS)
685    {
686        pnw_MPEG2_DestroyContext(obj_context);
687    }
688
689    return vaStatus;
690}
691
692static void pnw_MPEG2_DestroyContext(
693            object_context_p obj_context)
694{
695    INIT_CONTEXT_MPEG2
696
697    psb_buffer_destroy( &ctx->vlc_packed_table );
698
699    if (ctx->pic_params)
700    {
701        free(ctx->pic_params);
702        ctx->pic_params = NULL;
703    }
704
705    if (ctx->slice_param_list)
706    {
707        free(ctx->slice_param_list);
708        ctx->slice_param_list = NULL;
709    }
710
711    free(obj_context->format_data);
712    obj_context->format_data = NULL;
713}
714
715static VAStatus psb__MPEG2_process_picture_param(context_MPEG2_p ctx, object_buffer_p obj_buffer)
716{
717    ASSERT(obj_buffer->type == VAPictureParameterBufferType);
718    ASSERT(obj_buffer->num_elements == 1);
719    ASSERT(obj_buffer->size == sizeof(VAPictureParameterBufferMPEG2));
720
721    if ((obj_buffer->num_elements != 1) ||
722        (obj_buffer->size != sizeof(VAPictureParameterBufferMPEG2)))
723    {
724        return VA_STATUS_ERROR_UNKNOWN;
725    }
726
727    /* Transfer ownership of VAPictureParameterBufferMPEG2 data */
728    if (ctx->pic_params)
729    {
730        free(ctx->pic_params);
731    }
732    ctx->pic_params = (VAPictureParameterBufferMPEG2 *) obj_buffer->buffer_data;
733    obj_buffer->buffer_data = NULL;
734    obj_buffer->size = 0;
735
736    /* Lookup surfaces for backward/forward references */
737    switch (ctx->pic_params->picture_coding_type)
738    {
739      case PICTURE_CODING_I:
740          ctx->forward_ref_surface = NULL;
741          ctx->backward_ref_surface = NULL;
742          break;
743
744      case PICTURE_CODING_P:
745          ctx->forward_ref_surface = SURFACE(ctx->pic_params->forward_reference_picture);
746          ctx->backward_ref_surface = NULL;
747          if (NULL == ctx->forward_ref_surface)
748          {
749              return VA_STATUS_ERROR_INVALID_SURFACE;
750          }
751          break;
752
753      case PICTURE_CODING_B:
754          ctx->forward_ref_surface = SURFACE(ctx->pic_params->forward_reference_picture);
755          ctx->backward_ref_surface = SURFACE(ctx->pic_params->backward_reference_picture);
756          if ((NULL == ctx->forward_ref_surface) ||
757              (NULL == ctx->backward_ref_surface))
758          {
759              return VA_STATUS_ERROR_INVALID_SURFACE;
760          }
761          break;
762
763      default:
764          return VA_STATUS_ERROR_UNKNOWN;
765    }
766
767    ctx->picture_width_mb = (ctx->pic_params->horizontal_size + 15) / 16;
768    if (ctx->obj_context->va_flags & VA_PROGRESSIVE)
769    {
770        ctx->picture_height_mb = (ctx->pic_params->vertical_size + 15) / 16;
771    }
772    else
773    {
774        ctx->picture_height_mb = (ctx->pic_params->vertical_size + 31) / 32;
775        ctx->picture_height_mb *= 2;
776    }
777    ctx->coded_picture_width = ctx->picture_width_mb * 16;
778    ctx->coded_picture_height = ctx->picture_height_mb * 16;
779
780    ctx->size_mb = ctx->picture_width_mb * ctx->picture_height_mb;
781
782    /* Display picture size                                                            */
783    ctx->display_picture_size = 0;
784/*
785 * coded_picture_width/height is aligned to the size of a macroblock..
786 * Both coded_picture_height or vertical_size can be used for DISPLAY_SIZE and both give correct results,
787 * however Vista driver / test app uses the aligned value that's in coded_picture_height so we do too.
788 * See e.g. low4.m2v for an example clip where vertical_size will differ from coded_picture_height
789 */
790#if 0
791    REGIO_WRITE_FIELD_LITE (ctx->display_picture_size, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_HEIGHT, ctx->pic_params->vertical_size - 1);
792    REGIO_WRITE_FIELD_LITE (ctx->display_picture_size, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_WIDTH, ctx->pic_params->horizontal_size - 1);
793#else
794    REGIO_WRITE_FIELD_LITE (ctx->display_picture_size, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_HEIGHT, ctx->coded_picture_height - 1);
795    REGIO_WRITE_FIELD_LITE (ctx->display_picture_size, MSVDX_CMDS, DISPLAY_PICTURE_SIZE, DISPLAY_PICTURE_WIDTH, ctx->coded_picture_width - 1);
796#endif
797
798    /* Coded picture size                                                            */
799    ctx->coded_picture_size = 0;
800    REGIO_WRITE_FIELD_LITE (ctx->coded_picture_size, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_HEIGHT, ctx->coded_picture_height - 1);
801    REGIO_WRITE_FIELD_LITE (ctx->coded_picture_size, MSVDX_CMDS, CODED_PICTURE_SIZE, CODED_PICTURE_WIDTH, ctx->coded_picture_width - 1);
802
803    ctx->BE_SPS0 = 0;
804    REGIO_WRITE_FIELD_LITE (ctx->BE_SPS0,MSVDX_VEC_MPEG2,CR_VEC_MPEG2_BE_SPS0,BE_HORIZONTAL_SIZE_MINUS1, ctx->picture_width_mb - 1);
805
806    ctx->BE_SPS1 = 0;
807    REGIO_WRITE_FIELD_LITE (ctx->BE_SPS1,MSVDX_VEC_MPEG2,CR_VEC_MPEG2_BE_SPS1,BE_VERTICAL_SIZE_MINUS1, ctx->picture_height_mb);
808
809    ctx->FE_PPS0 = 0;
810    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_ALTERNATE_SCAN,                 !!(ctx->pic_params->picture_coding_extension.bits.alternate_scan));
811    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_Q_SCALE_TYPE,                 !!(ctx->pic_params->picture_coding_extension.bits.q_scale_type));
812    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_INTRA_DC_PRECISION,                ctx->pic_params->picture_coding_extension.bits.intra_dc_precision);
813    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_TOP_FIELD_FIRST,             !!(ctx->pic_params->picture_coding_extension.bits.top_field_first));
814    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_CONCEALMENT_MOTION_VECTORS,  !!(ctx->pic_params->picture_coding_extension.bits.concealment_motion_vectors));
815    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_FRAME_PRED_FRAME_DCT,         !!(ctx->pic_params->picture_coding_extension.bits.frame_pred_frame_dct));
816    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_PICTURE_STRUCTURE,                ctx->pic_params->picture_coding_extension.bits.picture_structure);
817    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0, FE_INTRA_VLC_FORMAT,             !!(ctx->pic_params->picture_coding_extension.bits.intra_vlc_format));
818
819    ctx->FE_PPS1 = 0;
820    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1, FE_PICTURE_CODING_TYPE, ctx->pic_params->picture_coding_type);
821    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1, FE_F_CODE00,             (ctx->pic_params->f_code >> 12) & 0x0F);
822    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1, FE_F_CODE01,             (ctx->pic_params->f_code >>  8) & 0x0F);
823    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1, FE_F_CODE10,             (ctx->pic_params->f_code >>  4) & 0x0F);
824    REGIO_WRITE_FIELD_LITE (ctx->FE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1, FE_F_CODE11,             (ctx->pic_params->f_code >>  0) & 0x0F);
825
826    /* VEC Control register: Back-End MPEG2 PPS0                                    */
827    ctx->BE_PPS0 = 0;
828    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS0, BE_FRAME_PRED_FRAME_DCT,    !!(ctx->pic_params->picture_coding_extension.bits.frame_pred_frame_dct));
829    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS0, BE_INTRA_DC_PRECISION,           ctx->pic_params->picture_coding_extension.bits.intra_dc_precision);
830    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS0, BE_Q_SCALE_TYPE,            !!(ctx->pic_params->picture_coding_extension.bits.q_scale_type));
831    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS0, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS0, BE_ALTERNATE_SCAN,            !!(ctx->pic_params->picture_coding_extension.bits.alternate_scan));
832
833    ctx->BE_PPS1 = 0;
834    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS1, BE_F_CODE00, (ctx->pic_params->f_code >> 12) & 0x0F);
835    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS1, BE_F_CODE01, (ctx->pic_params->f_code >>  8) & 0x0F);
836    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS1, BE_F_CODE10, (ctx->pic_params->f_code >>  4) & 0x0F);
837    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS1, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS1, BE_F_CODE11, (ctx->pic_params->f_code >>  0) & 0x0F);
838
839    /* VEC Control register: Back-End MPEG2 PPS2                                    */
840    ctx->BE_PPS2 = 0;
841    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS2, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS2, BE_PICTURE_CODING_TYPE,           ctx->pic_params->picture_coding_type);
842    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS2, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS2, BE_TOP_FIELD_FIRST,            !!(ctx->pic_params->picture_coding_extension.bits.top_field_first));
843    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS2, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS2, BE_CONCEALMENT_MOTION_VECTORS, !!(ctx->pic_params->picture_coding_extension.bits.concealment_motion_vectors));
844    REGIO_WRITE_FIELD_LITE (ctx->BE_PPS2, MSVDX_VEC_MPEG2, CR_VEC_MPEG2_BE_PPS2, BE_PICTURE_STRUCTURE,               ctx->pic_params->picture_coding_extension.bits.picture_structure);
845
846    ctx->obj_context->operating_mode = 0;
847    REGIO_WRITE_FIELD_LITE (ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, CHROMA_INTERLEAVED, 0);
848    REGIO_WRITE_FIELD_LITE (ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, ROW_STRIDE, ctx->obj_context->current_render_target->psb_surface->stride_mode);
849    REGIO_WRITE_FIELD_LITE (ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, CODEC_PROFILE, 1);                                /* MPEG2 profile            */
850    REGIO_WRITE_FIELD_LITE (ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, CODEC_MODE, 3);                                /* MPEG2 mode                */
851    REGIO_WRITE_FIELD_LITE (ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 1);                                /* VDMC only                */
852    REGIO_WRITE_FIELD_LITE (ctx->obj_context->operating_mode, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, 1);
853
854    return VA_STATUS_SUCCESS;
855}
856
857static void psb__MPEG2_convert_iq_matrix(uint32_t *dest32, unsigned char *src)
858{
859    int i;
860    int *idx = scan0;
861    uint8_t *dest8 = (uint8_t*) dest32;
862
863    for (i = 0; i < 64; i++)
864    {
865        *dest8++ = src[*idx++];
866    }
867}
868
869static VAStatus psb__MPEG2_process_iq_matrix(context_MPEG2_p ctx, object_buffer_p obj_buffer)
870{
871    VAIQMatrixBufferMPEG2 *iq_matrix = (VAIQMatrixBufferMPEG2 *) obj_buffer->buffer_data;
872    ASSERT(obj_buffer->type == VAIQMatrixBufferType);
873    ASSERT(obj_buffer->num_elements == 1);
874    ASSERT(obj_buffer->size == sizeof(VAIQMatrixBufferMPEG2));
875
876    if ((obj_buffer->num_elements != 1) ||
877        (obj_buffer->size != sizeof(VAIQMatrixBufferMPEG2)))
878    {
879        return VA_STATUS_ERROR_UNKNOWN;
880    }
881
882    /* Only update the qmatrix data if the load flag is set */
883    if (iq_matrix->load_non_intra_quantiser_matrix)
884    {
885        psb__MPEG2_convert_iq_matrix( ctx->qmatrix_data[NONINTRA_LUMA_Q], iq_matrix->non_intra_quantiser_matrix );
886    }
887    if (iq_matrix->load_intra_quantiser_matrix)
888    {
889        psb__MPEG2_convert_iq_matrix( ctx->qmatrix_data[INTRA_LUMA_Q], iq_matrix->intra_quantiser_matrix );
890    }
891    /* We ignore the Chroma tables because those are not supported with VA_RT_FORMAT_YUV420 */
892    ctx->got_iq_matrix = TRUE;
893
894    return VA_STATUS_SUCCESS;
895}
896
897/*
898 * Adds a VASliceParameterBuffer to the list of slice params
899 */
900static VAStatus psb__MPEG2_add_slice_param(context_MPEG2_p ctx, object_buffer_p obj_buffer)
901{
902    ASSERT(obj_buffer->type == VASliceParameterBufferType);
903    if (ctx->slice_param_list_idx >= ctx->slice_param_list_size)
904    {
905        void *new_list;
906        ctx->slice_param_list_size += 8;
907        new_list = realloc(ctx->slice_param_list,
908                                    sizeof(object_buffer_p)*ctx->slice_param_list_size);
909        if (NULL == new_list)
910        {
911            return VA_STATUS_ERROR_ALLOCATION_FAILED;
912        }
913        ctx->slice_param_list = (object_buffer_p*) new_list;
914    }
915    ctx->slice_param_list[ctx->slice_param_list_idx] = obj_buffer;
916    ctx->slice_param_list_idx++;
917    return VA_STATUS_SUCCESS;
918}
919
920/* Precalculated values */
921#define ADDR0       (0x00006000)
922#define ADDR1       (0x0003f017)
923#define ADDR2       (0x000ab0e5)
924#define ADDR3       (0x0000016e)
925#define WIDTH0      (0x0016c6ed)
926#define OPCODE0     (0x00002805)
927
928static void psb__MPEG2_write_VLC_tables(context_MPEG2_p ctx)
929{
930    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
931
932    psb_cmdbuf_skip_start_block( cmdbuf, SKIP_ON_CONTEXT_SWITCH );
933    /* VLC Table */
934    /* Write a LLDMA Cmd to transfer VLD Table data */
935    psb_cmdbuf_lldma_write_cmdbuf( cmdbuf, &ctx->vlc_packed_table, 0,
936                                sizeof(gaui16mpeg2VlcTableDataPacked),
937                                0, LLDMA_TYPE_VLC_TABLE );
938
939    /* Write the vec registers with the index data for each of the tables and then write    */
940    /* the actual table data.                                                                */
941    psb_cmdbuf_reg_start_block( cmdbuf );
942    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR0),            ADDR0    );
943    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR1),            ADDR1    );
944    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR2),            ADDR2    );
945    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_ADDR3),            ADDR3    );
946    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_WIDTH0),    WIDTH0    );
947    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_VLC_TABLE_INITIAL_OPCODE0),OPCODE0    );
948    psb_cmdbuf_reg_end_block( cmdbuf );
949
950    psb_cmdbuf_skip_end_block( cmdbuf );
951}
952
953/* Programme the Alt output if there is a rotation*/
954static void psb__MPEG2_setup_alternative_frame( context_MPEG2_p ctx, IMG_BOOL write_reg )
955{
956    uint32_t cmd;
957    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
958    psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate;
959    object_context_p obj_context = ctx->obj_context;
960
961    if(rotate_surface->extra_info[5] != obj_context->rotate)
962        psb__error_message("Display rotate mode does not match surface rotate mode!\n");
963
964
965    /* CRendecBlock    RendecBlk( mCtrlAlloc , RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); */
966    psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS)  );
967
968    psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs);
969    psb_cmdbuf_rendec_write_address( cmdbuf, &rotate_surface->buf, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset);
970
971    RELOC(*ctx->p_range_mapping_base0, rotate_surface->buf.buffer_ofs, &rotate_surface->buf);
972    RELOC(*ctx->p_range_mapping_base1, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset, &rotate_surface->buf);
973
974    psb_cmdbuf_rendec_end( cmdbuf );
975
976    if(write_reg) {
977        /* Set the rotation registers */
978        psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION)  );
979        cmd = 0;
980        REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ALT_PICTURE_ENABLE,1 );
981        REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_ROW_STRIDE, rotate_surface->stride_mode);
982        REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,RECON_WRITE_DISABLE, 0); /* FIXME Always has Rec */
983        REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_MODE, rotate_surface->extra_info[5]);
984
985        psb_cmdbuf_rendec_write( cmdbuf, cmd );
986
987        psb_cmdbuf_rendec_end( cmdbuf );
988    }
989}
990
991static void psb__MPEG2_set_operating_mode(context_MPEG2_p ctx)
992{
993    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
994    psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface;
995
996    if(ctx->obj_context->rotate != VA_ROTATION_NONE)
997        psb__MPEG2_setup_alternative_frame( ctx, ctx->pic_params->picture_coding_extension.bits.progressive_frame);
998
999    psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE) );
1000    psb_cmdbuf_rendec_write( cmdbuf, ctx->display_picture_size );
1001    psb_cmdbuf_rendec_write( cmdbuf, ctx->coded_picture_size );
1002    psb_cmdbuf_rendec_write( cmdbuf, ctx->obj_context->operating_mode );
1003
1004    /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES                                    */
1005    psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs);
1006
1007    /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES                                    */
1008    psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset);
1009
1010    psb_cmdbuf_rendec_end( cmdbuf );
1011}
1012
1013static void psb__MPEG2_set_reference_pictures(context_MPEG2_p ctx)
1014{
1015    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1016    psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface;
1017
1018    psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) );
1019
1020    /* In MPEG2, the registers at N=0 are always used to store the base address of the luma and chroma buffers
1021        of the most recently decoded reference picture. The registers at N=1 are used to store the base address
1022        of the luma and chroma buffers of the older reference picture, if more than one reference picture is used.
1023        This means that when decoding a P picture the forward reference picture�s address is at index 0.
1024        When decoding a B-picture the backward reference picture�s address is at index 0 and the address of the
1025        forward reference picture � which was decoded earlier than the backward reference � is at index 1.
1026    */
1027
1028    switch (ctx->pic_params->picture_coding_type)
1029    {
1030      case PICTURE_CODING_I:
1031          psb__information_message("    I-Frame\n");
1032          /* No reference pictures */
1033          psb_cmdbuf_rendec_write( cmdbuf, 0 );
1034          psb_cmdbuf_rendec_write( cmdbuf, 0 );
1035          psb_cmdbuf_rendec_write( cmdbuf, 0 );
1036          psb_cmdbuf_rendec_write( cmdbuf, 0 );
1037          break;
1038
1039      case PICTURE_CODING_P:
1040          psb__information_message("    P-Frame\n");
1041          if (ctx->pic_params->picture_coding_extension.bits.is_first_field)
1042          {
1043              /* forward reference picture */
1044              /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */
1045              psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs);
1046
1047              /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES */
1048              psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->forward_ref_surface->psb_surface->buf,  ctx->forward_ref_surface->psb_surface\
1049                                               ->buf.buffer_ofs + ctx->forward_ref_surface->psb_surface->chroma_offset);
1050
1051              /* No backward reference picture */
1052              psb_cmdbuf_rendec_write( cmdbuf, 0 );
1053              psb_cmdbuf_rendec_write( cmdbuf, 0 );
1054          }
1055          else
1056          {
1057              /* backward reference picture */
1058              /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES                                    */
1059              psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs);
1060
1061              /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES                                    */
1062              psb_cmdbuf_rendec_write_address( cmdbuf, &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset);
1063
1064              /* forward reference picture */
1065              /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES                                    */
1066              psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs);
1067
1068              /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES                                    */
1069              psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs + ctx->forward_ref_surface->psb_surface->chroma_offset);
1070          }
1071          break;
1072
1073      case PICTURE_CODING_B:
1074          psb__information_message("    B-Frame\n");
1075          /* backward reference picture */
1076          /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES                                    */
1077          psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->backward_ref_surface->psb_surface->buf, ctx->backward_ref_surface->psb_surface->buf.buffer_ofs);
1078
1079          /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES                                    */
1080          psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->backward_ref_surface->psb_surface->buf, ctx->backward_ref_surface->psb_surface->buf.buffer_ofs + ctx->backward_ref_surface->psb_surface->chroma_offset);
1081
1082          /* forward reference picture */
1083          /* LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES                                    */
1084          psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs);
1085
1086          /* CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES                                    */
1087          psb_cmdbuf_rendec_write_address( cmdbuf, &ctx->forward_ref_surface->psb_surface->buf, ctx->forward_ref_surface->psb_surface->buf.buffer_ofs + ctx->forward_ref_surface->psb_surface->chroma_offset);
1088          break;
1089    }
1090
1091    psb_cmdbuf_rendec_end( cmdbuf );
1092}
1093
1094static void psb__MPEG2_set_picture_header(context_MPEG2_p ctx, VASliceParameterBufferMPEG2 *slice_param)
1095{
1096    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1097    psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface;
1098    uint32_t FE_slice;
1099    uint32_t BE_slice;
1100
1101    psb_cmdbuf_reg_start_block( cmdbuf );
1102
1103    /* VEC Control register: Front-End MPEG2 PPS0 */
1104    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS0) , ctx->FE_PPS0 );
1105
1106    /* VEC Control register: Front-End MPEG2 PPS1 */
1107    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_PPS1) , ctx->FE_PPS1 );
1108
1109    /* Slice level */
1110    FE_slice = 0;
1111    REGIO_WRITE_FIELD (FE_slice,
1112                    MSVDX_VEC_MPEG2,
1113                    CR_VEC_MPEG2_FE_SLICE,
1114                    FE_FIRST_IN_ROW,
1115                    (ctx->previous_slice_vertical_position != slice_param->slice_vertical_position));
1116
1117    REGIO_WRITE_FIELD (FE_slice,
1118                    MSVDX_VEC_MPEG2,
1119                    CR_VEC_MPEG2_FE_SLICE,
1120                    FE_SLICE_VERTICAL_POSITION_MINUS1,
1121                    slice_param->slice_vertical_position);
1122
1123    REGIO_WRITE_FIELD (FE_slice,
1124                    MSVDX_VEC_MPEG2,
1125                    CR_VEC_MPEG2_FE_SLICE,
1126                    FE_QUANTISER_SCALE_CODE,
1127                    slice_param->quantiser_scale_code);
1128
1129    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC_MPEG2, CR_VEC_MPEG2_FE_SLICE) , FE_slice );
1130
1131    psb_cmdbuf_reg_end_block( cmdbuf );
1132
1133
1134    /* BE Section */
1135    psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, MPEG2_CR_VEC_MPEG2_BE_SPS0) );
1136
1137    psb_cmdbuf_rendec_write( cmdbuf, ctx->BE_SPS0 );
1138    psb_cmdbuf_rendec_write( cmdbuf, ctx->BE_SPS1 );
1139    psb_cmdbuf_rendec_write( cmdbuf, ctx->BE_PPS0 ); /* VEC Control register: Back-End MPEG2 PPS0 */
1140    psb_cmdbuf_rendec_write( cmdbuf, ctx->BE_PPS1 ); /* VEC Control register: Back-End MPEG2 PPS1 */
1141    psb_cmdbuf_rendec_write( cmdbuf, ctx->BE_PPS2 ); /* VEC Control register: Back-End MPEG2 PPS2 */
1142
1143    BE_slice = 0;
1144    if( !ctx->pic_params->picture_coding_extension.bits.is_first_field )
1145    {
1146        /*
1147            BE_IP_PAIR_FLAG is 1 if the current picture_data is a P-coded field which is the 2nd field of a frame,
1148                        and which uses the first field of the frame (which was I-coded) as a reference. 0 otherwise.
1149            BE_IP_PAIR_FLAG will only be 1 if BE_SECOND_FIELD_FLAG is 1, and the condition
1150                of "this is a P-field which uses the accompanying I-field as a reference" is met.
1151        */
1152        if( ctx->pic_params->picture_coding_type == PICTURE_CODING_P  )
1153        {
1154            if( GET_SURFACE_INFO_picture_coding_type(target_surface) == PICTURE_CODING_I )            {
1155                REGIO_WRITE_FIELD_LITE (BE_slice,
1156                        MSVDX_VEC_MPEG2,
1157                        CR_VEC_MPEG2_BE_SLICE,
1158                        BE_IP_PAIR_FLAG, 1    );
1159            }
1160        }
1161
1162        REGIO_WRITE_FIELD_LITE(BE_slice,
1163                            MSVDX_VEC_MPEG2,
1164                            CR_VEC_MPEG2_BE_SLICE,
1165                            BE_SECOND_FIELD_FLAG,     1 );
1166
1167    }
1168    else
1169    {
1170        // BE_IP_PAIR_FLAG = 0;
1171        // BE_SECOND_FIELD_FLAG = 0;
1172
1173        /*  Update with current settings first field */
1174        SET_SURFACE_INFO_is_defined(target_surface, TRUE);
1175        SET_SURFACE_INFO_picture_structure(target_surface, ctx->pic_params->picture_coding_extension.bits.picture_structure );
1176        SET_SURFACE_INFO_picture_coding_type(target_surface, ctx->pic_params->picture_coding_type );
1177    }
1178
1179    REGIO_WRITE_FIELD_LITE (BE_slice,
1180                       MSVDX_VEC_MPEG2,
1181                       CR_VEC_MPEG2_BE_SLICE,
1182                       BE_FIRST_IN_ROW,
1183                       (ctx->previous_slice_vertical_position != slice_param->slice_vertical_position));
1184
1185    REGIO_WRITE_FIELD_LITE (BE_slice,
1186                       MSVDX_VEC_MPEG2,
1187                       CR_VEC_MPEG2_BE_SLICE,
1188                       BE_SLICE_VERTICAL_POSITION_MINUS1,
1189                       slice_param->slice_vertical_position);
1190
1191    REGIO_WRITE_FIELD_LITE (BE_slice,
1192                       MSVDX_VEC_MPEG2,
1193                       CR_VEC_MPEG2_BE_SLICE,
1194                       BE_QUANTISER_SCALE_CODE,
1195                       slice_param->quantiser_scale_code);
1196
1197psb__information_message("BE_slice = %08x first_field = %d\n", BE_slice, ctx->pic_params->picture_coding_extension.bits.is_first_field);
1198
1199    psb_cmdbuf_rendec_write( cmdbuf, BE_slice );
1200
1201    psb_cmdbuf_rendec_end( cmdbuf );
1202
1203    ctx->previous_slice_vertical_position = slice_param->slice_vertical_position;
1204}
1205
1206static void psb__MPEG2_set_slice_params(context_MPEG2_p ctx)
1207{
1208    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1209
1210    uint32_t cmd_data;
1211
1212    psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, SLICE_PARAMS)  );
1213
1214    cmd_data = 0;    /* Build slice parameters */
1215    REGIO_WRITE_FIELD (cmd_data,
1216                       MSVDX_CMDS,
1217                       SLICE_PARAMS,
1218                       SLICE_FIELD_TYPE,
1219                       ctx->pic_params->picture_coding_extension.bits.picture_structure - 1);
1220
1221    REGIO_WRITE_FIELD (cmd_data,
1222                       MSVDX_CMDS,
1223                       SLICE_PARAMS,
1224                       SLICE_CODE_TYPE,
1225                       PICTURE_CODING_D == ctx->pic_params->picture_coding_type ? 0 : ctx->pic_params->picture_coding_type - 1);
1226
1227    psb_cmdbuf_rendec_write( cmdbuf, cmd_data );
1228
1229    *ctx->p_slice_params = cmd_data;
1230
1231    psb_cmdbuf_rendec_end( cmdbuf );
1232}
1233
1234static void psb__MPEG2_write_qmatrices(context_MPEG2_p ctx)
1235{
1236    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1237    int i;
1238
1239    /* Since we only decode 4:2:0 We only need to the Intra tables.
1240    Chroma quant tables are only used in Mpeg 4:2:2 and 4:4:4.
1241    The hardware wants non-intra followed by intra */
1242    psb_cmdbuf_rendec_start( cmdbuf, REG_MSVDX_VEC_IQRAM_OFFSET );
1243
1244    /* todo : optimisation here is to only load the need table */
1245
1246    /*  NONINTRA_LUMA_Q --> REG_MSVDX_VEC_IQRAM_OFFSET + 0 */
1247    for (i = 0; i < 16; i++)
1248    {
1249        psb_cmdbuf_rendec_write( cmdbuf, ctx->qmatrix_data[NONINTRA_LUMA_Q][i] );
1250// psb__information_message("NONINTRA_LUMA_Q[i] = %08x\n", ctx->qmatrix_data[NONINTRA_LUMA_Q][i]);
1251    }
1252    /*  INTRA_LUMA_Q --> REG_MSVDX_VEC_IQRAM_OFFSET + (16*4) */
1253    for (i = 0; i < 16; i++)
1254    {
1255        psb_cmdbuf_rendec_write( cmdbuf, ctx->qmatrix_data[INTRA_LUMA_Q][i] );
1256// psb__information_message("INTRA_LUMA_Q[i] = %08x\n", ctx->qmatrix_data[INTRA_LUMA_Q][i]);
1257    }
1258
1259    psb_cmdbuf_rendec_end( cmdbuf );
1260}
1261
1262static void psb__MPEG2_set_ent_dec(context_MPEG2_p ctx)
1263{
1264    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1265
1266    uint32_t cmd_data;
1267
1268    psb_cmdbuf_reg_start_block( cmdbuf );
1269
1270    cmd_data = 0;     /* Entdec Front-End controls    */
1271    REGIO_WRITE_FIELD_LITE(cmd_data, MSVDX_VEC,  CR_VEC_ENTDEC_FE_CONTROL,  ENTDEC_FE_PROFILE, 1); /* MPEG2 Main Profile */
1272    REGIO_WRITE_FIELD_LITE(cmd_data, MSVDX_VEC,  CR_VEC_ENTDEC_FE_CONTROL,  ENTDEC_FE_MODE,       3); /* Set MPEG2 mode */
1273
1274    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET (MSVDX_VEC, CR_VEC_ENTDEC_FE_CONTROL), cmd_data);
1275
1276    psb_cmdbuf_reg_end_block( cmdbuf );
1277
1278    psb_cmdbuf_rendec_start( cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_VEC, CR_VEC_ENTDEC_BE_CONTROL) );
1279
1280    cmd_data = 0;     /* Entdec Back-End controls    */
1281    REGIO_WRITE_FIELD (cmd_data,
1282                       MSVDX_VEC,
1283                       CR_VEC_ENTDEC_BE_CONTROL,
1284                       ENTDEC_BE_PROFILE,
1285                       1);                                /* MPEG2 Main Profile        */
1286
1287    REGIO_WRITE_FIELD (cmd_data,
1288                       MSVDX_VEC,
1289                       CR_VEC_ENTDEC_BE_CONTROL,
1290                       ENTDEC_BE_MODE,
1291                       3);                                /* Set MPEG2 mode            */
1292
1293    psb_cmdbuf_rendec_write( cmdbuf, cmd_data );
1294
1295    psb_cmdbuf_rendec_end( cmdbuf );
1296}
1297
1298static void psb__MPEG2_write_kick(context_MPEG2_p ctx, VASliceParameterBufferMPEG2 *slice_param)
1299{
1300    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1301
1302    (void) slice_param; /* Unused for now */
1303
1304    *cmdbuf->cmd_idx++ = CMD_COMPLETION;
1305}
1306
1307static void psb__MPEG2_FE_state(context_MPEG2_p ctx)
1308{
1309    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1310
1311    /* See RENDER_BUFFER_HEADER */
1312    *cmdbuf->cmd_idx++ = CMD_HEADER_VC1;
1313
1314    ctx->p_range_mapping_base0 = cmdbuf->cmd_idx++;
1315    ctx->p_range_mapping_base1 = cmdbuf->cmd_idx++;
1316
1317    *ctx->p_range_mapping_base0 = 0;
1318    *ctx->p_range_mapping_base1 = 0;
1319
1320    ctx->p_slice_params = cmdbuf->cmd_idx;
1321    *cmdbuf->cmd_idx++ = 0; /* ui32SliceParams */
1322
1323    *cmdbuf->cmd_idx++ = 0; /* skip two lldma addr field */
1324
1325    *cmdbuf->cmd_idx++  = 0;
1326    ctx->slice_first_pic_last = cmdbuf->cmd_idx++;
1327}
1328
1329static VAStatus psb__MPEG2_process_slice(context_MPEG2_p ctx,
1330                                         VASliceParameterBufferMPEG2 *slice_param,
1331                                         object_buffer_p obj_buffer)
1332{
1333    VAStatus vaStatus = VA_STATUS_SUCCESS;
1334
1335    ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType));
1336
1337    psb__information_message("MPEG2 process slice\n");
1338    psb__information_message("    size = %08x offset = %08x\n", slice_param->slice_data_size, slice_param->slice_data_offset);
1339    psb__information_message("    vertical pos = %d\n", slice_param->slice_vertical_position);
1340    psb__information_message("    slice_data_flag = %d\n", slice_param->slice_data_flag);
1341    psb__information_message("    coded size = %dx%d\n", ctx->picture_width_mb, ctx->picture_height_mb);
1342
1343    if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) ||
1344        (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL))
1345    {
1346        if (0 == slice_param->slice_data_size)
1347        {
1348            vaStatus = VA_STATUS_ERROR_UNKNOWN;
1349            DEBUG_FAILURE;
1350            return vaStatus;
1351        }
1352
1353        ASSERT( !ctx->split_buffer_pending );
1354
1355        /* Initialise the command buffer */
1356        psb_context_get_next_cmdbuf(ctx->obj_context);
1357
1358        psb__MPEG2_FE_state(ctx);
1359        psb__MPEG2_write_VLC_tables(ctx);
1360
1361        psb_cmdbuf_lldma_write_bitstream(ctx->obj_context->cmdbuf,
1362                                         obj_buffer->psb_buffer,
1363                                         obj_buffer->psb_buffer->buffer_ofs + slice_param->slice_data_offset,
1364                                         slice_param->slice_data_size,
1365                                         slice_param->macroblock_offset,
1366                                         0);
1367
1368        if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN)
1369        {
1370            ctx->split_buffer_pending = TRUE;
1371        }
1372    }
1373    else
1374    {
1375        ASSERT( ctx->split_buffer_pending );
1376        ASSERT(0 == slice_param->slice_data_offset);
1377        /* Create LLDMA chain to continue buffer */
1378        if (slice_param->slice_data_size)
1379        {
1380            psb_cmdbuf_lldma_write_bitstream_chained(ctx->obj_context->cmdbuf,
1381                                                     obj_buffer->psb_buffer,
1382                                                     slice_param->slice_data_size);
1383        }
1384    }
1385
1386    if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL) ||
1387        (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END))
1388    {
1389        if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END)
1390        {
1391            ASSERT( ctx->split_buffer_pending );
1392        }
1393
1394        psb__MPEG2_set_operating_mode(ctx);
1395
1396        psb__MPEG2_set_reference_pictures(ctx);
1397
1398        psb__MPEG2_set_picture_header(ctx, slice_param);
1399
1400        psb__MPEG2_set_slice_params(ctx);
1401
1402        psb__MPEG2_write_qmatrices(ctx);
1403
1404        psb__MPEG2_set_ent_dec(ctx);
1405
1406        psb__MPEG2_write_kick(ctx, slice_param);
1407
1408        ctx->split_buffer_pending = FALSE;
1409        ctx->obj_context->video_op = psb_video_vld;
1410        ctx->obj_context->flags = FW_DXVA_RENDER_IS_VLD_NOT_MC;
1411        ctx->obj_context->first_mb = 0;
1412
1413        if(ctx->pic_params->picture_coding_extension.bits.progressive_frame)
1414            ctx->obj_context->last_mb =  ((ctx->picture_height_mb - 1) << 8) | (ctx->picture_width_mb - 1);
1415        else
1416            ctx->obj_context->last_mb =  ((ctx->picture_height_mb/2 - 1 ) << 8) | (ctx->picture_width_mb - 1);
1417
1418        *ctx->slice_first_pic_last = (ctx->obj_context->first_mb << 16) | (ctx->obj_context->last_mb);
1419
1420        if (psb_context_submit_cmdbuf(ctx->obj_context))
1421        {
1422            vaStatus = VA_STATUS_ERROR_UNKNOWN;
1423        }
1424    }
1425    return vaStatus;
1426}
1427
1428static VAStatus psb__MPEG2_process_slice_data(context_MPEG2_p ctx, object_buffer_p obj_buffer)
1429{
1430    VAStatus vaStatus = VA_STATUS_SUCCESS;
1431    VASliceParameterBufferMPEG2 *slice_param;
1432    int buffer_idx = 0;
1433    int element_idx = 0;
1434
1435    ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType));
1436
1437    ASSERT(ctx->got_iq_matrix);
1438    ASSERT(ctx->pic_params);
1439    ASSERT(ctx->slice_param_list_idx);
1440
1441    if (!ctx->got_iq_matrix || !ctx->pic_params)
1442    {
1443        /* IQ matrix or Picture params missing */
1444        return VA_STATUS_ERROR_UNKNOWN;
1445    }
1446    if ((NULL == obj_buffer->psb_buffer) ||
1447        (0 == obj_buffer->size))
1448    {
1449        /* We need to have data in the bitstream buffer */
1450        return VA_STATUS_ERROR_UNKNOWN;
1451    }
1452
1453    while(buffer_idx < ctx->slice_param_list_idx)
1454    {
1455        object_buffer_p slice_buf = ctx->slice_param_list[buffer_idx];
1456        if (element_idx >= slice_buf->num_elements)
1457        {
1458            /* Move to next buffer */
1459            element_idx = 0;
1460            buffer_idx++;
1461            continue;
1462        }
1463
1464        slice_param = (VASliceParameterBufferMPEG2 *) slice_buf->buffer_data;
1465        slice_param += element_idx;
1466        element_idx++;
1467        vaStatus = psb__MPEG2_process_slice(ctx, slice_param, obj_buffer);
1468        if (vaStatus != VA_STATUS_SUCCESS)
1469        {            DEBUG_FAILURE;
1470            break;
1471        }
1472    }
1473    ctx->slice_param_list_idx = 0;
1474
1475    return vaStatus;
1476}
1477
1478static void psb__MEPG2_send_highlevel_cmd(context_MPEG2_p ctx)
1479{
1480    uint32_t cmd;
1481    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1482    psb_surface_p target_surface = ctx->obj_context->current_render_target->psb_surface;
1483    psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate;
1484    object_context_p obj_context = ctx->obj_context;
1485
1486    psb_cmdbuf_reg_start_block( cmdbuf );
1487    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, DISPLAY_PICTURE_SIZE), ctx->display_picture_size);
1488    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, CODED_PICTURE_SIZE), ctx->coded_picture_size);
1489
1490    cmd = 0;
1491    REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, CHROMA_FORMAT, 1);
1492    REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, ASYNC_MODE, 1); // 0 = VDMC and VDEB active.  1 = VDEB pass-thru.
1493    REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, CODEC_MODE, 3);        // MPEG2
1494    REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, CODEC_PROFILE, 1); // MAIN
1495    REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, OPERATING_MODE, ROW_STRIDE, target_surface->stride_mode );
1496    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, OPERATING_MODE), cmd);
1497
1498    psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, LUMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES),
1499                             &target_surface->buf, target_surface->buf.buffer_ofs);
1500
1501    psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, CHROMA_RECONSTRUCTED_PICTURE_BASE_ADDRESSES),
1502                              &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset);
1503
1504    psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + (0 * 8),
1505                             &target_surface->buf, target_surface->buf.buffer_ofs);
1506
1507    psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + 4 + (0 * 8),
1508                              &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset);
1509
1510    psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + (1 * 8),
1511                             &target_surface->buf, target_surface->buf.buffer_ofs);
1512
1513    psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, REFERENCE_PICTURE_BASE_ADDRESSES) + 4 + (1 * 8),
1514                              &target_surface->buf, target_surface->buf.buffer_ofs + target_surface->chroma_offset);
1515
1516    cmd = 0;
1517    REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_FIELD_TYPE,   2); /* FRAME PICTURE -- ui8SliceFldType */
1518    REGIO_WRITE_FIELD(cmd, MSVDX_CMDS, SLICE_PARAMS, SLICE_CODE_TYPE,    1); /* P PICTURE -- (ui8PicType == WMF_PTYPE_BI) ? WMF_PTYPE_I : (ui8PicType & 0x3) */
1519    psb_cmdbuf_reg_set(cmdbuf, REGISTER_OFFSET (MSVDX_CMDS, SLICE_PARAMS), cmd );
1520    *ctx->p_slice_params = cmd;
1521    psb_cmdbuf_reg_end_block( cmdbuf );
1522
1523
1524    psb_cmdbuf_reg_start_block( cmdbuf );
1525    psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS),
1526                             &rotate_surface->buf, rotate_surface->buf.buffer_ofs);
1527
1528    psb_cmdbuf_reg_set_RELOC(cmdbuf, REGISTER_OFFSET (MSVDX_CMDS, VC1_CHROMA_RANGE_MAPPING_BASE_ADDRESS),
1529                              &rotate_surface->buf, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset);
1530    psb_cmdbuf_reg_end_block( cmdbuf );
1531
1532    RELOC(*ctx->p_range_mapping_base0, rotate_surface->buf.buffer_ofs, &rotate_surface->buf);
1533    RELOC(*ctx->p_range_mapping_base1, rotate_surface->buf.buffer_ofs + rotate_surface->chroma_offset, &rotate_surface->buf);
1534}
1535
1536static void psb__MEPG2_send_blit_cmd(context_MPEG2_p ctx)
1537{
1538    uint32_t cmd;
1539    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1540    psb_surface_p rotate_surface = ctx->obj_context->current_render_target->psb_surface_rotate;
1541    object_context_p obj_context = ctx->obj_context;
1542
1543    psb_cmdbuf_reg_start_block( cmdbuf );
1544    cmd = 0;
1545    REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ALT_PICTURE_ENABLE,1 );
1546    REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_ROW_STRIDE, rotate_surface->stride_mode);
1547    REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,RECON_WRITE_DISABLE, 0);
1548    REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION ,ROTATION_MODE, rotate_surface->extra_info[5]);
1549    psb_cmdbuf_reg_set( cmdbuf, REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION), cmd);
1550    psb_cmdbuf_reg_end_block( cmdbuf );
1551
1552    *cmdbuf->cmd_idx++ = 0x40000000; /* CMD_BLIT_CMD */
1553    *cmdbuf->cmd_idx++ = ctx->picture_width_mb;
1554    *cmdbuf->cmd_idx++ = ctx->picture_height_mb; /* FIXME */
1555    *cmdbuf->cmd_idx++ = CMD_COMPLETION;
1556}
1557
1558static void psb__MPEG2_insert_blit_cmd_to_rotate( context_MPEG2_p ctx )
1559{
1560    psb_cmdbuf_p cmdbuf = ctx->obj_context->cmdbuf;
1561
1562    /* See RENDER_BUFFER_HEADER */
1563    *cmdbuf->cmd_idx++ = CMD_HEADER_VC1;
1564
1565    ctx->p_range_mapping_base0 = cmdbuf->cmd_idx++;
1566    ctx->p_range_mapping_base1 = cmdbuf->cmd_idx++;
1567
1568    *ctx->p_range_mapping_base0 = 0;
1569    *ctx->p_range_mapping_base1 = 0;
1570
1571    ctx->p_slice_params = cmdbuf->cmd_idx;
1572    *cmdbuf->cmd_idx++ = 0; /* ui32SliceParams */
1573
1574    *cmdbuf->cmd_idx++ = 0; /* skip two lldma addr field */
1575    *cmdbuf->cmd_idx++ = 0;
1576
1577    ctx->slice_first_pic_last = cmdbuf->cmd_idx++;
1578    *ctx->slice_first_pic_last = 0;
1579
1580    psb__MEPG2_send_highlevel_cmd(ctx);
1581    psb__MEPG2_send_blit_cmd(ctx);
1582
1583    ctx->obj_context->video_op = psb_video_mc;
1584    ctx->obj_context->flags = FW_DXVA_RENDER_IS_LAST_SLICE;
1585
1586    if (psb_context_submit_cmdbuf(ctx->obj_context))
1587    {
1588       ASSERT(0);
1589    }
1590}
1591
1592static VAStatus pnw_MPEG2_BeginPicture(
1593            object_context_p obj_context)
1594{
1595    INIT_CONTEXT_MPEG2
1596
1597    psb__information_message("pnw_MPEG2_BeginPicture\n");
1598    if (ctx->pic_params)
1599    {
1600        free(ctx->pic_params);
1601        ctx->pic_params = NULL;
1602    }
1603    ctx->previous_slice_vertical_position = ~1;
1604
1605    return VA_STATUS_SUCCESS;
1606}
1607
1608static VAStatus pnw_MPEG2_RenderPicture(
1609            object_context_p obj_context,
1610            object_buffer_p *buffers,
1611            int num_buffers)
1612{
1613    int i;
1614    INIT_CONTEXT_MPEG2
1615    VAStatus vaStatus = VA_STATUS_SUCCESS;
1616
1617    for(i = 0; i < num_buffers; i++)
1618    {
1619        object_buffer_p obj_buffer = buffers[i];
1620
1621        switch( obj_buffer->type)
1622        {
1623          case VAPictureParameterBufferType:
1624              psb__information_message("pnw_MPEG2_RenderPicture got VAPictureParameterBuffer\n");
1625              vaStatus = psb__MPEG2_process_picture_param(ctx, obj_buffer);
1626              DEBUG_FAILURE;
1627              break;
1628
1629          case VAIQMatrixBufferType:
1630              psb__information_message("pnw_MPEG2_RenderPicture got VAIQMatrixBufferType\n");
1631              vaStatus = psb__MPEG2_process_iq_matrix(ctx, obj_buffer);
1632              DEBUG_FAILURE;
1633              break;
1634
1635          case VASliceParameterBufferType:
1636              psb__information_message("pnw_MPEG2_RenderPicture got VASliceParameterBufferType\n");
1637              vaStatus = psb__MPEG2_add_slice_param(ctx, obj_buffer);
1638              DEBUG_FAILURE;
1639              break;
1640
1641          case VASliceDataBufferType:
1642          case VAProtectedSliceDataBufferType:
1643
1644              psb__information_message("pnw_MPEG2_RenderPicture got %s\n", SLICEDATA_BUFFER_TYPE(obj_buffer->type));
1645              vaStatus = psb__MPEG2_process_slice_data(ctx, obj_buffer);
1646              DEBUG_FAILURE;
1647              break;
1648
1649          default:
1650              vaStatus = VA_STATUS_ERROR_UNKNOWN;
1651              DEBUG_FAILURE;
1652        }
1653        if (vaStatus != VA_STATUS_SUCCESS)
1654        {
1655            break;
1656        }
1657    }
1658
1659    return vaStatus;
1660}
1661
1662static VAStatus pnw_MPEG2_EndPicture(
1663            object_context_p obj_context)
1664{
1665    VAStatus vaStatus = VA_STATUS_SUCCESS;
1666    INIT_CONTEXT_MPEG2
1667
1668    psb__information_message("pnw_MPEG2_EndPicture\n");
1669
1670    if(ctx->obj_context->rotate != VA_ROTATION_NONE)
1671    {
1672        if( !(ctx->pic_params->picture_coding_extension.bits.progressive_frame) &&
1673            !(ctx->pic_params->picture_coding_extension.bits.is_first_field))
1674            psb__MPEG2_insert_blit_cmd_to_rotate(ctx);
1675    }
1676
1677    if (psb_context_flush_cmdbuf(ctx->obj_context))
1678    {
1679        vaStatus = VA_STATUS_ERROR_UNKNOWN;
1680    }
1681
1682    if (ctx->pic_params)
1683    {
1684        free(ctx->pic_params);
1685        ctx->pic_params = NULL;
1686    }
1687
1688    return vaStatus;
1689}
1690
1691struct format_vtable_s pnw_MPEG2_vtable = {
1692    queryConfigAttributes: pnw_MPEG2_QueryConfigAttributes,
1693    validateConfig: pnw_MPEG2_ValidateConfig,
1694    createContext: pnw_MPEG2_CreateContext,
1695    destroyContext: pnw_MPEG2_DestroyContext,
1696    beginPicture: pnw_MPEG2_BeginPicture,
1697    renderPicture: pnw_MPEG2_RenderPicture,
1698    endPicture: pnw_MPEG2_EndPicture
1699};
1700