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