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