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