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) )
83 static 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 
470 static 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 
482 typedef enum {
483     NONINTRA_LUMA_Q = 0,
484     INTRA_LUMA_Q = 1
485 } QUANT_IDX;
486 
487 struct 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 
527 typedef 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 
pnw_MPEG2_QueryConfigAttributes(VAProfile __maybe_unused profile,VAEntrypoint __maybe_unused entrypoint,VAConfigAttrib __maybe_unused * attrib_list,int __maybe_unused num_attribs)534 static 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 
pnw_MPEG2_ValidateConfig(object_config_p obj_config)574 static 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 
psb__MPEG2_check_legal_picture(object_context_p obj_context,object_config_p obj_config)593 static 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 
630 static void pnw_MPEG2_DestroyContext(object_context_p obj_context);
631 static void psb__MPEG2_process_slice_data(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param);
632 static void psb__MPEG2_end_slice(context_DEC_p dec_ctx);
633 static void psb__MPEG2_begin_slice(context_DEC_p dec_ctx, VASliceParameterBufferBase *vld_slice_param);
634 static VAStatus pnw_MPEG2_process_buffer(context_DEC_p dec_ctx, object_buffer_p buffer);
635 
pnw_MPEG2_CreateContext(object_context_p obj_context,object_config_p obj_config)636 static 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 
pnw_MPEG2_DestroyContext(object_context_p obj_context)694 static 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 
psb__MPEG2_process_picture_param(context_MPEG2_p ctx,object_buffer_p obj_buffer)712 static 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 
psb__MPEG2_convert_iq_matrix(uint32_t * dest32,unsigned char * src)853 static 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 
psb__MPEG2_process_iq_matrix(context_MPEG2_p ctx,object_buffer_p obj_buffer)864 static 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 
psb__MPEG2_write_VLC_tables(context_MPEG2_p ctx)897 static 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 
psb__MPEG2_set_operating_mode(context_MPEG2_p ctx)922 static 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 
psb__MPEG2_set_reference_pictures(context_MPEG2_p ctx)944 static 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 
psb__MPEG2_set_picture_header(context_MPEG2_p ctx,VASliceParameterBufferMPEG2 * slice_param)1028 static 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 
psb__MPEG2_set_slice_params(context_MPEG2_p ctx)1145 static 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 
psb__MPEG2_write_qmatrices(context_MPEG2_p ctx)1173 static 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 
psb__MPEG2_set_ent_dec(context_MPEG2_p ctx)1199 static 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 
psb__MPEG2_begin_slice(context_DEC_p dec_ctx,VASliceParameterBufferBase * vld_slice_param)1243 static 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 }
psb__MPEG2_process_slice_data(context_DEC_p dec_ctx,VASliceParameterBufferBase * vld_slice_param)1253 static 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 
psb__MPEG2_end_slice(context_DEC_p dec_ctx)1269 static 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 
psb__MEPG2_send_highlevel_cmd(context_MPEG2_p ctx)1284 static 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 
psb__MEPG2_send_blit_cmd(context_MPEG2_p ctx)1341 static 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 
psb__MPEG2_insert_blit_cmd_to_rotate(context_MPEG2_p ctx)1362 static 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 
pnw_MPEG2_BeginPicture(object_context_p obj_context)1395 static 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 
pnw_MPEG2_process_buffer(context_DEC_p dec_ctx,object_buffer_p buffer)1411 static 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 
pnw_MPEG2_EndPicture(object_context_p obj_context)1440 static 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 
1468 struct format_vtable_s pnw_MPEG2_vtable = {
1469 queryConfigAttributes:
1470     pnw_MPEG2_QueryConfigAttributes,
1471 validateConfig:
1472     pnw_MPEG2_ValidateConfig,
1473 createContext:
1474     pnw_MPEG2_CreateContext,
1475 destroyContext:
1476     pnw_MPEG2_DestroyContext,
1477 beginPicture:
1478     pnw_MPEG2_BeginPicture,
1479 renderPicture:
1480     vld_dec_RenderPicture,
1481 endPicture:
1482     pnw_MPEG2_EndPicture
1483 };
1484