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