sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
libmpeg.c
1/*
2# _____ ___ ____ ___ ____
3# ____| | ____| | | |____|
4# | ___| |____ ___| ____| | \ PS2DEV Open Source Project.
5#-----------------------------------------------------------------------
6# Copyright (c) 2006-2007 Eugene Plotnikov <e-plotnikov@operamail.com>
7# Licenced under Academic Free License version 2.0
8# Review ps2sdk README & LICENSE files for further details.
9# Based on refernce software of MSSG
10*/
11
12#include <malloc.h>
13#include <stdio.h>
14#include <string.h>
15#include <kernel.h>
16#ifndef _EE
17// for MIN / MAX macros
18#include <sys/param.h>
19#endif
20
21#include "libmpeg.h"
22#include "ee_regs.h"
23#include "libmpeg_internal.h"
24
25static _MPEGContext s_MPEG12Ctx;
26static s64 *s_pCurPTS;
27
28static void (*LumaOp[8])(_MPEGMotion *m, u8 *a2, short *a3, int a4, int var1, int ta, int a7, int a8) = {
29 _MPEG_put_luma, _MPEG_put_luma_X, _MPEG_put_luma_Y, _MPEG_put_luma_XY,
30 _MPEG_avg_luma, _MPEG_avg_luma_X, _MPEG_avg_luma_Y, _MPEG_avg_luma_XY};
31
32static void (*ChromaOp[8])(_MPEGMotion *m, u8 *a2, short *a3, int a4, int var1, int ta, int a7, int a8) = {
33 _MPEG_put_chroma, _MPEG_put_chroma_X, _MPEG_put_chroma_Y, _MPEG_put_chroma_XY,
34 _MPEG_avg_chroma, _MPEG_avg_chroma_X, _MPEG_avg_chroma_Y, _MPEG_avg_chroma_XY};
35
36static void (*PutBlockOp[3])(_MPEGMotions *arg0) = {
37 _MPEG_put_block_il, _MPEG_put_block_fr, _MPEG_put_block_fl};
38
39static void (*AddBlockOp[2][2])(_MPEGMotions *arg0) = {
40 {_MPEG_add_block_frfr, _MPEG_add_block_frfl},
41 {_MPEG_add_block_ilfl, _MPEG_add_block_ilfl}};
42
43static float s_FrameRate[16] = {
44 0.0F, ((23.0F * 1000.0F) / 1001.0F),
45 24.0F, 25.0F, ((30.0F * 1000.0F) / 1001.0F),
46 30.0F, 50.0F, ((60.0F * 1000.0F) / 1001.0F),
47 60.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F, 0.0F};
48
49static void *(*_init_cb)(void *userdata, MPEGSequenceInfo *si);
50static void *s_pInitCBParam;
51
52static void *_init_seq(void);
53static void _destroy_seq(void);
54
55static int _get_hdr(void);
56
57static void _seq_header(void);
58static void _gop_header(void);
59static void _pic_header(void);
60static void _ext_and_ud(void);
61static void _ext_unknown(void);
62static void _ext_seq(void);
63static void _ext_seq_dsp(void);
64static void _ext_qnt_mtx(void);
65static void _ext_cpy_rgt(void);
66static void _ext_seq_scl(void);
67static void _ext_pic_dsp(void);
68static void _ext_pic_cod(void);
69static void _ext_pic_ssc(void);
70static void _ext_pic_tsc(void);
71static void _xtra_bitinf(void);
72
73static int _get_next_picture(void *apData, s64 *apPTS);
74static int _get_first_picture(void *apData, s64 *apPTS);
75
76int (*MPEG_Picture)(void *apData, s64 *apPTS);
77
78static void (*DoMC)(void);
79
80static void _mpeg12_picture_data(void);
81static int _mpeg12_slice(int aMBAMax);
82static int _mpeg12_dec_mb(int *apMBType, int *apMotionType, int aPMV[2][2][2], int aMVFS[2][2], int aDMVector[2]);
83
84void MPEG_Initialize(
85 int (*apDataCB)(void *userdata), void *apDataCBParam,
86 void *(*apInitCB)(void *userdata, MPEGSequenceInfo *si), void *apInitCBParam,
87 s64 *apCurPTS)
88{
89 memset(&s_MPEG12Ctx, 0, sizeof(s_MPEG12Ctx));
90
91 _MPEG_Initialize(&s_MPEG12Ctx, apDataCB, apDataCBParam, &s_MPEG12Ctx.m_SI.m_fEOF);
92
93 _init_cb = apInitCB;
94 s_pInitCBParam = apInitCBParam;
95 s_pCurPTS = apCurPTS;
96
97 s_MPEG12Ctx.m_SI.m_FrameCnt = 0;
98 s_MPEG12Ctx.m_SI.m_fEOF = 0;
99 s_MPEG12Ctx.m_SI.m_Profile = -1;
100 s_MPEG12Ctx.m_SI.m_Level = -1;
101 s_MPEG12Ctx.m_SI.m_ChromaFmt = MPEG_CHROMA_FORMAT_420;
102 s_MPEG12Ctx.m_SI.m_VideoFmt = MPEG_VIDEO_FORMAT_UNSPEC;
103 s_MPEG12Ctx.m_fMPEG2 = 0;
104
105 s_MPEG12Ctx.m_MC[0].m_pSPRBlk = (void *)0x70000000;
106 s_MPEG12Ctx.m_MC[0].m_pSPRRes = (void *)0x70000300;
107 s_MPEG12Ctx.m_MC[0].m_pSPRMC = (void *)0x70000600;
108 s_MPEG12Ctx.m_MC[1].m_pSPRBlk = (void *)0x70001E00;
109 s_MPEG12Ctx.m_MC[1].m_pSPRRes = (void *)0x70002100;
110 s_MPEG12Ctx.m_MC[1].m_pSPRMC = (void *)0x70002400;
111
112 MPEG_Picture = _get_first_picture;
113}
114
115void MPEG_Destroy(void)
116{
117 _destroy_seq();
118 _MPEG_Destroy();
119}
120
121static void *_init_seq(void)
122{
123 int lMBWidth, lMBHeight;
124 char *pA;
125
126 if (!s_MPEG12Ctx.m_fMPEG2) {
127 s_MPEG12Ctx.m_fProgSeq = 1;
128 s_MPEG12Ctx.m_PictStruct = _MPEG_PS_FRAME;
129 s_MPEG12Ctx.m_fFPFrmDCT = 1;
130 }
131
132 lMBWidth = (s_MPEG12Ctx.m_SI.m_Width + 15) / 16;
133 if (s_MPEG12Ctx.m_fMPEG2 && !s_MPEG12Ctx.m_fProgSeq) {
134 lMBHeight = 2 * ((s_MPEG12Ctx.m_SI.m_Height + 31) / 32);
135 } else {
136 lMBHeight = (s_MPEG12Ctx.m_SI.m_Height + 15) / 16;
137 }
138
139 if (lMBWidth != s_MPEG12Ctx.m_MBWidth || lMBHeight != s_MPEG12Ctx.m_MBHeight) {
140 unsigned int lAllocSize;
141 int i, lSize;
142
143 if (s_MPEG12Ctx.m_pFwdFrame)
144 _destroy_seq();
145
146 s_MPEG12Ctx.m_MBWidth = lMBWidth;
147 s_MPEG12Ctx.m_MBHeight = lMBHeight;
148 s_MPEG12Ctx.m_SI.m_Width = lMBWidth << 4;
149 s_MPEG12Ctx.m_SI.m_Height = lMBHeight << 4;
150
151 s_MPEG12Ctx.m_MBStride = lMBWidth * sizeof(_MPEGMacroBlock8);
152
153 lSize = lMBWidth * (lMBHeight + 1) * sizeof(_MPEGMacroBlock8) + sizeof(_MPEGMacroBlock8);
154
155 s_MPEG12Ctx.m_MBCount = s_MPEG12Ctx.m_MBWidth * s_MPEG12Ctx.m_MBHeight;
156
157 lAllocSize = (lSize * 3) + (s_MPEG12Ctx.m_MBCount * sizeof(_MPEGMBXY));
158
159 pA = memalign(64, lAllocSize);
160
161 s_MPEG12Ctx.m_pFrameArena = pA;
162 s_MPEG12Ctx.m_pFwdFrame = (_MPEGMacroBlock8 *)pA;
163 pA += lSize;
164 s_MPEG12Ctx.m_pBckFrame = (_MPEGMacroBlock8 *)pA;
165 pA += lSize;
166 s_MPEG12Ctx.m_pAuxFrame = (_MPEGMacroBlock8 *)pA;
167 pA += lSize;
168 s_MPEG12Ctx.m_pMBXY = (_MPEGMBXY *)pA;
169
170 for (i = 0; i < s_MPEG12Ctx.m_MBCount; ++i) {
171 s_MPEG12Ctx.m_pMBXY[i].m_X = i % lMBWidth;
172 s_MPEG12Ctx.m_pMBXY[i].m_Y = i / lMBWidth;
173 }
174 }
175
176 return _init_cb(s_pInitCBParam, &s_MPEG12Ctx.m_SI);
177}
178
179static void _destroy_seq(void)
180{
181 MPEG_Picture = _get_first_picture;
182
183 if (s_MPEG12Ctx.m_pFrameArena) {
184 free(s_MPEG12Ctx.m_pFrameArena);
185 s_MPEG12Ctx.m_pAuxFrame = NULL;
186 s_MPEG12Ctx.m_pBckFrame = NULL;
187 s_MPEG12Ctx.m_pFwdFrame = NULL;
188 s_MPEG12Ctx.m_pMBXY = NULL;
189 }
190
191 s_MPEG12Ctx.m_MBWidth = 0;
192 s_MPEG12Ctx.m_MBHeight = 0;
193}
194
195/*
196 * decode headers from one input stream
197 * until an End of Sequence or picture start code
198 * is found
199 */
200static int _get_hdr(void)
201{
202 while (1) {
203 unsigned int lCode = _MPEG_NextStartCode();
204 _MPEG_GetBits(32);
205
206 switch (lCode) {
207 case _MPEG_CODE_SEQ_HDR:
208 _seq_header();
209 break;
210 case _MPEG_CODE_GRP_START:
211 _gop_header();
212 break;
213 case _MPEG_CODE_PIC_START:
214 _pic_header();
215 return 1;
216 case _MPEG_CODE_SEQ_END:
217 MPEG_Picture = _get_first_picture;
218 return 0;
219 }
220 }
221}
222
223static void _seq_header(void)
224{
225 s_MPEG12Ctx.m_SI.m_Width = _MPEG_GetBits(12);
226 s_MPEG12Ctx.m_SI.m_Height = _MPEG_GetBits(12);
227
228 _MPEG_GetBits(4); /* aspect_ratio_information */
229 s_MPEG12Ctx.m_SI.m_MSPerFrame = (int)((1000.0F / s_FrameRate[s_MPEG12Ctx.m_FRCode = _MPEG_GetBits(4)]) + 0.5F);
230 _MPEG_GetBits(18); /* bit_rate_value */
231 _MPEG_GetBits(1); /* marker_bit */
232 _MPEG_GetBits(10); /* vbv_buffer_size */
233 _MPEG_GetBits(1); /* constrained_parameters_flag */
234
235 if (_MPEG_GetBits(1))
236 _MPEG_SetQM(0);
237 else
238 _MPEG_SetDefQM(0);
239
240 if (_MPEG_GetBits(1))
241 _MPEG_SetQM(1);
242 else
243 _MPEG_SetDefQM(1);
244
245 _ext_and_ud();
246}
247
248static void _gop_header(void)
249{
250#ifdef _DEBUG
251 _MPEG_GetBits(1); /* drop_flag */
252 _MPEG_GetBits(5); /* hour */
253 _MPEG_GetBits(6); /* minute */
254 _MPEG_GetBits(1); /* marker_bit */
255 _MPEG_GetBits(6); /* sec */
256 _MPEG_GetBits(6); /* frame */
257 _MPEG_GetBits(1); /* closed_gop */
258 _MPEG_GetBits(1); /* broken_link */
259#else
260 _MPEG_GetBits(27);
261#endif /* _DEBUG */
262 _ext_and_ud();
263}
264
265static void _pic_header(void)
266{
267 unsigned int lPicCT;
268
269 _MPEG_GetBits(10); /* temporal_reference */
270 lPicCT = _MPEG_GetBits(3);
271 _MPEG_GetBits(16); /* vbv_delay */
272
273 if (lPicCT == _MPEG_PT_P || lPicCT == _MPEG_PT_B) {
274 s_MPEG12Ctx.m_FPFVector = _MPEG_GetBits(1);
275 s_MPEG12Ctx.m_FwdFCode = _MPEG_GetBits(3);
276 }
277
278 if (lPicCT == _MPEG_PT_B) {
279 s_MPEG12Ctx.m_FPBVector = _MPEG_GetBits(1);
280 s_MPEG12Ctx.m_BckFCode = _MPEG_GetBits(3);
281 }
282
283 _xtra_bitinf();
284 _ext_and_ud();
285
286 _MPEG_SetPCT(s_MPEG12Ctx.m_PictCodingType = lPicCT);
287}
288
289static void _ext_and_ud(void)
290{
291 int lCode, lXID;
292 lCode = _MPEG_NextStartCode();
293
294 while (lCode == _MPEG_CODE_EXTENSION || lCode == _MPEG_CODE_USER_DATA) {
295 if (lCode == _MPEG_CODE_EXTENSION) {
296 _MPEG_GetBits(32);
297 lXID = _MPEG_GetBits(4);
298
299 switch (lXID) {
300 case _MPEG_XID_0:
301 _ext_unknown();
302 break;
303 case _MPEG_XID_SEQUENCE:
304 _ext_seq();
305 break;
306 case _MPEG_XID_DISPLAY:
307 _ext_seq_dsp();
308 break;
309 case _MPEG_XID_QMATRIX:
310 _ext_qnt_mtx();
311 break;
312 case _MPEG_XID_COPYRIGHT:
313 _ext_cpy_rgt();
314 break;
315 case _MPEG_XID_SCALABLE:
316 _ext_seq_scl();
317 break;
318 case _MPEG_XID_6:
319 _ext_unknown();
320 break;
321 case _MPEG_XID_PIC_DSP:
322 _ext_pic_dsp();
323 break;
324 case _MPEG_XID_PIC_COD:
325 _ext_pic_cod();
326 break;
327 case _MPEG_XID_PIC_SSC:
328 _ext_pic_ssc();
329 break;
330 case _MPEG_XID_PIC_TSC:
331 _ext_pic_tsc();
332 break;
333 }
334
335 lCode = _MPEG_NextStartCode();
336 } else {
337 _MPEG_GetBits(32);
338 lCode = _MPEG_NextStartCode();
339 }
340 }
341}
342
343static void _ext_unknown(void) {}
344
345static void _ext_seq(void)
346{
347 int lHSzX;
348 int lVSzX;
349 int lProfLevel;
350 int lFRXn, lFRXd;
351
352 s_MPEG12Ctx.m_fMPEG2 = 1;
353
354 *R_EE_IPU_CTRL &= 0xFF7FFFFF;
355
356 lProfLevel = _MPEG_GetBits(8);
357 s_MPEG12Ctx.m_fProgSeq = _MPEG_GetBits(1);
358 s_MPEG12Ctx.m_SI.m_ChromaFmt = _MPEG_GetBits(2);
359 lHSzX = _MPEG_GetBits(2);
360 lVSzX = _MPEG_GetBits(2);
361#ifdef _DEBUG
362 _MPEG_GetBits(12); /* bit_rate_extension */
363 _MPEG_GetBits(1); /* marker_bit */
364 _MPEG_GetBits(8); /* vbv_buffer_size_extension */
365 _MPEG_GetBits(1); /* low_delay */
366 lFRXn = _MPEG_GetBits(2);
367 lFRXd = _MPEG_GetBits(5);
368#else
369 _MPEG_GetBits(22);
370 lFRXn = _MPEG_GetBits(2);
371 lFRXd = _MPEG_GetBits(5);
372#endif /* _DEBUG */
373 s_MPEG12Ctx.m_SI.m_MSPerFrame = (int)((1000.0F / (s_FrameRate[s_MPEG12Ctx.m_FRCode] * ((lFRXn + 1.0F) / (lFRXd + 1.0F)))) + 0.5F);
374
375 if ((lProfLevel >> 7) & 1) {
376 if ((lProfLevel & 15) == 5) {
377 s_MPEG12Ctx.m_SI.m_Profile = MPEG_PROFILE_422;
378 s_MPEG12Ctx.m_SI.m_Level = MPEG_LEVEL_MAIN;
379 } else {
380 s_MPEG12Ctx.m_SI.m_Profile = s_MPEG12Ctx.m_SI.m_Level = -1;
381 }
382 } else {
383 s_MPEG12Ctx.m_SI.m_Profile = lProfLevel >> 4;
384 s_MPEG12Ctx.m_SI.m_Level = lProfLevel & 0xF;
385 }
386
387 s_MPEG12Ctx.m_SI.m_Width = (lHSzX << 12) | (s_MPEG12Ctx.m_SI.m_Width & 0x0FFF);
388 s_MPEG12Ctx.m_SI.m_Height = (lVSzX << 12) | (s_MPEG12Ctx.m_SI.m_Height & 0x0FFF);
389}
390
391
392static void _ext_seq_dsp(void)
393{
394 s_MPEG12Ctx.m_SI.m_VideoFmt = _MPEG_GetBits(3);
395
396 if (_MPEG_GetBits(1)) { /* color_description */
397#ifdef _DEBUG
398 _MPEG_GetBits(8); /* color_primaries */
399 _MPEG_GetBits(8); /* transfer_characteristics */
400 _MPEG_GetBits(8); /* matrix_coefficients */
401#else
402 _MPEG_GetBits(24);
403#endif /* _DEBUG */
404 }
405#ifdef _DEBUG
406 _MPEG_GetBits(14); /* display_horizontal_size */
407 _MPEG_GetBits(1); /* marker_bit */
408 _MPEG_GetBits(14); /* display_vertical_size */
409#else
410 _MPEG_GetBits(29);
411#endif /* _DEBUG */
412}
413
414static void _ext_qnt_mtx(void)
415{
416 int i;
417
418 if (_MPEG_GetBits(1))
419 _MPEG_SetQM(0);
420
421 if (_MPEG_GetBits(1))
422 _MPEG_SetQM(1);
423
424 if (_MPEG_GetBits(1)) {
425 for (i = 0; i < 16; ++i)
426 _MPEG_GetBits(32);
427 }
428
429 if (_MPEG_GetBits(1)) {
430 for (i = 0; i < 16; ++i)
431 _MPEG_GetBits(32);
432 }
433}
434
435static void _ext_cpy_rgt(void)
436{
437#ifdef _DEBUG
438 _MPEG_GetBits(1); /* copyright_flag */
439 _MPEG_GetBits(8); /* copyright_identifier */
440 _MPEG_GetBits(1); /* original_or_copy */
441 _MPEG_GetBits(7); /* reserved_data */
442 _MPEG_GetBits(1); /* marker_bit */
443 _MPEG_GetBits(20); /* copyright_number_1 */
444 _MPEG_GetBits(1); /* marker_bit */
445 _MPEG_GetBits(22); /* copyright_number_2 */
446 _MPEG_GetBits(1); /* marker_bit */
447 _MPEG_GetBits(22); /* copyright_number_3 */
448#else
449 _MPEG_GetBits(32);
450 _MPEG_GetBits(32);
451 _MPEG_GetBits(20);
452#endif /* _DEBUG */
453}
454
455static void _ext_seq_scl(void) {}
456
457static void _ext_pic_dsp(void)
458{
459 int i;
460 int lnFCO;
461
462 if (s_MPEG12Ctx.m_fProgSeq) {
463 if (s_MPEG12Ctx.m_fRepFF)
464 lnFCO = s_MPEG12Ctx.m_fTopFF ? 3 : 2;
465 else
466 lnFCO = 1;
467 } else {
468 if (s_MPEG12Ctx.m_PictStruct != _MPEG_PS_FRAME)
469 lnFCO = 1;
470 else
471 lnFCO = s_MPEG12Ctx.m_fRepFF ? 3 : 2;
472 }
473
474
475 for (i = 0; i < lnFCO; ++i) {
476 _MPEG_GetBits(16); /* frame_center_horizontal_offset[ i ] */
477 _MPEG_GetBits(1); /* marker_bit */
478 _MPEG_GetBits(16); /* frame_center_vertical_offset [ i ] */
479 _MPEG_GetBits(1); /* marker_bit */
480 }
481}
482
483static void _ext_pic_cod(void)
484{
485
486 s_MPEG12Ctx.m_FCode[0][0] = _MPEG_GetBits(4);
487 s_MPEG12Ctx.m_FCode[0][1] = _MPEG_GetBits(4);
488 s_MPEG12Ctx.m_FCode[1][0] = _MPEG_GetBits(4);
489 s_MPEG12Ctx.m_FCode[1][1] = _MPEG_GetBits(4);
490 _MPEG_SetIDCP();
491 s_MPEG12Ctx.m_PictStruct = _MPEG_GetBits(2);
492 s_MPEG12Ctx.m_fTopFF = _MPEG_GetBits(1);
493 s_MPEG12Ctx.m_fFPFrmDCT = _MPEG_GetBits(1);
494 s_MPEG12Ctx.m_fConsMV = _MPEG_GetBits(1);
495 _MPEG_SetQSTIVFAS();
496 s_MPEG12Ctx.m_fRepFF = _MPEG_GetBits(1);
497#ifdef _DEBUG
498 _MPEG_GetBits(1); /* chroma_420_type */
499 _MPEG_GetBits(1); /* progressive_frame */
500#else
501 _MPEG_GetBits(2);
502#endif /* _DEBUG */
503 if (_MPEG_GetBits(1)) { /* composite_display_flag */
504#ifdef _DEBUG
505 _MPEG_GetBits(1); /* v_axis */
506 _MPEG_GetBits(3); /* field_sequence */
507 _MPEG_GetBits(1); /* sub_carrier */
508 _MPEG_GetBits(7); /* burst_amplitude */
509 _MPEG_GetBits(8); /* sub_carrier_phase */
510#else
511 _MPEG_GetBits(20);
512#endif /* _DEBUG */
513 }
514}
515
516static void _ext_pic_ssc(void) {}
517
518
519static void _ext_pic_tsc(void) {}
520
521static void _xtra_bitinf(void)
522{
523 while (_MPEG_GetBits(1))
524 _MPEG_GetBits(8);
525}
526
527static int _get_first_picture(void *apData, s64 *apPTS)
528{
529 int retVal = _get_hdr();
530
531 if (retVal) {
532 s_MPEG12Ctx.m_SI.m_FrameCnt = 0;
533
534 apData = _init_seq();
535 _mpeg12_picture_data();
536
537 if (s_MPEG12Ctx.m_PictStruct != _MPEG_PS_FRAME)
538 s_MPEG12Ctx.m_fSecField ^= 1;
539
540 MPEG_Picture = _get_next_picture;
541
542 if (!s_MPEG12Ctx.m_fSecField)
543 ++s_MPEG12Ctx.m_SI.m_FrameCnt;
544
545 retVal = _get_next_picture(apData, apPTS);
546 }
547
548 return retVal;
549}
550
551static int _get_next_picture(void *apData, s64 *apPTS)
552{
553 int retVal;
554
555 while (1) {
556 if ((retVal = _get_hdr())) {
557 int lfPic = 0;
558
559 _mpeg12_picture_data();
560
561 if ((s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME || s_MPEG12Ctx.m_fSecField) && s_MPEG12Ctx.m_SI.m_FrameCnt) {
562 void *lpData;
563
564 if (s_MPEG12Ctx.m_PictCodingType == _MPEG_PT_B) {
565 lpData = s_MPEG12Ctx.m_pAuxFrame;
566 *apPTS = s_MPEG12Ctx.m_AuxPTS;
567 } else {
568 lpData = s_MPEG12Ctx.m_pFwdFrame;
569 *apPTS = s_MPEG12Ctx.m_FwdPTS;
570 }
571
572 lfPic = _MPEG_CSCImage(lpData, apData, s_MPEG12Ctx.m_MBCount);
573 }
574
575 if (s_MPEG12Ctx.m_PictStruct != _MPEG_PS_FRAME)
576 s_MPEG12Ctx.m_fSecField ^= 1;
577
578 if (!s_MPEG12Ctx.m_fSecField)
579 ++s_MPEG12Ctx.m_SI.m_FrameCnt;
580
581 if (lfPic)
582 break;
583 } else {
584 break;
585 }
586 }
587
588 return retVal;
589}
590
591static void _mpeg12_do_next_mc(void)
592{
593 _MPEGMotions *lpMotions = &s_MPEG12Ctx.m_MC[!s_MPEG12Ctx.m_CurMC];
594 _MPEGMotion *lpMotion = &lpMotions->m_Motion[0];
595
596 while (lpMotion->MC_Luma) {
597 _MPEG_do_mc(lpMotion);
598 ++lpMotion;
599 }
600
601 lpMotions->BlockOp(lpMotions);
602}
603
604static void _mpeg12_do_first_mc(void)
605{
606 DoMC = _mpeg12_do_next_mc;
607}
608
609/* Decode all macroblocks of the current picture */
610static void _mpeg12_picture_data(void)
611{
612 int lMBAMax = s_MPEG12Ctx.m_MBWidth * s_MPEG12Ctx.m_MBHeight;
613 _MPEGMacroBlock8 *lpMB;
614
615 if (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME && s_MPEG12Ctx.m_fSecField)
616 s_MPEG12Ctx.m_fSecField = 0;
617
618 if (s_MPEG12Ctx.m_PictCodingType == _MPEG_PT_B) {
619 s_MPEG12Ctx.m_pCurFrame = s_MPEG12Ctx.m_pAuxFrame;
620 s_MPEG12Ctx.m_AuxPTS = *s_pCurPTS;
621 } else {
622 s64 lPTS;
623
624 if (!s_MPEG12Ctx.m_fSecField) {
625 lpMB = s_MPEG12Ctx.m_pFwdFrame;
626 lPTS = s_MPEG12Ctx.m_FwdPTS;
627 s_MPEG12Ctx.m_pFwdFrame = s_MPEG12Ctx.m_pBckFrame;
628 s_MPEG12Ctx.m_FwdPTS = s_MPEG12Ctx.m_BckPTS;
629 s_MPEG12Ctx.m_pBckFrame = lpMB;
630 s_MPEG12Ctx.m_BckPTS = lPTS;
631 }
632
633 s_MPEG12Ctx.m_pCurFrame = s_MPEG12Ctx.m_pBckFrame;
634 s_MPEG12Ctx.m_BckPTS = *s_pCurPTS;
635 }
636
637 s_MPEG12Ctx.m_pCurFrameY = (unsigned char *)s_MPEG12Ctx.m_pCurFrame;
638 s_MPEG12Ctx.m_pCurFrameCbCr = (unsigned char *)s_MPEG12Ctx.m_pCurFrame + 256;
639 if (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_BOTTOM_FIELD) {
640 s_MPEG12Ctx.m_pCurFrameY += 16;
641 s_MPEG12Ctx.m_pCurFrameCbCr += 8;
642 }
643
644 if (s_MPEG12Ctx.m_PictStruct != _MPEG_PS_FRAME)
645 lMBAMax >>= 1;
646
647 s_MPEG12Ctx.m_CurMC = 0;
648
649 DoMC = _mpeg12_do_first_mc;
650
651 while (_mpeg12_slice(lMBAMax) >= 0)
652 ;
653
654 _MPEG_WaitBDEC();
655 DoMC();
656}
657
658/* calculate motion vector component */
659/* ISO/IEC 13818-2 section 7.6.3.1: Decoding the motion vectors */
660static void _mpeg12_decode_motion_vector(int *apPred, int aRSize, int aMotionCode,
661 int aMotionResidual, int aFullPelVector)
662{
663 int lLim = 16 << aRSize;
664 int lVec = aFullPelVector ? *apPred >> 1 : *apPred;
665
666 if (aMotionCode > 0) {
667 lVec += ((aMotionCode - 1) << aRSize) + aMotionResidual + 1;
668
669 if (lVec >= lLim)
670 lVec -= lLim + lLim;
671
672 } else if (aMotionCode < 0) {
673 lVec -= ((-aMotionCode - 1) << aRSize) + aMotionResidual + 1;
674
675 if (lVec < -lLim)
676 lVec += lLim + lLim;
677 }
678
679 *apPred = aFullPelVector ? lVec << 1 : lVec;
680}
681
682/* ISO/IEC 13818-2 section 7.6.3.6: Dual prime additional arithmetic */
683static void _mpeg12_dual_prime_vector(int aDMV[][2], const int *apDMVector, int aMVX, int aMVY)
684{
685 if (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME) {
686 if (s_MPEG12Ctx.m_fTopFF) {
687 aDMV[0][0] = ((aMVX + (aMVX > 0)) >> 1) + apDMVector[0];
688 aDMV[0][1] = ((aMVY + (aMVY > 0)) >> 1) + apDMVector[1] - 1;
689
690 aDMV[1][0] = ((3 * aMVX + (aMVX > 0)) >> 1) + apDMVector[0];
691 aDMV[1][1] = ((3 * aMVY + (aMVY > 0)) >> 1) + apDMVector[1] + 1;
692 } else {
693 aDMV[0][0] = ((3 * aMVX + (aMVX > 0)) >> 1) + apDMVector[0];
694 aDMV[0][1] = ((3 * aMVY + (aMVY > 0)) >> 1) + apDMVector[1] - 1;
695
696 aDMV[1][0] = ((aMVX + (aMVX > 0)) >> 1) + apDMVector[0];
697 aDMV[1][1] = ((aMVY + (aMVY > 0)) >> 1) + apDMVector[1] + 1;
698 }
699 } else {
700 aDMV[0][0] = ((aMVX + (aMVX > 0)) >> 1) + apDMVector[0];
701 aDMV[0][1] = ((aMVY + (aMVY > 0)) >> 1) + apDMVector[1];
702
703 if (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_TOP_FIELD)
704 --aDMV[0][1];
705 else
706 ++aDMV[0][1];
707 }
708}
709
710/* get and decode motion vector and differential motion vector
711 for one prediction */
712static void _mpeg12_motion_vector(int *apPMV, int *apDMVector, int aHRSize,
713 int aVRSize, int aDMV, int aMVScale, int aFullPelVector)
714{
715 int lMotionCode;
716 int lMotionResidual;
717
718 /* horizontal component */
719 lMotionCode = _MPEG_GetMotionCode();
720 lMotionResidual = aHRSize && lMotionCode ? _MPEG_GetBits(aHRSize) : 0;
721
722 _mpeg12_decode_motion_vector(&apPMV[0], aHRSize, lMotionCode, lMotionResidual, aFullPelVector);
723
724 if (aDMV)
725 apDMVector[0] = _MPEG_GetDMVector();
726
727 s_MPEG12Ctx.m_fError = lMotionCode == -32768;
728
729 /* vertical component */
730 lMotionCode = _MPEG_GetMotionCode();
731 lMotionResidual = aVRSize && lMotionCode ? _MPEG_GetBits(aVRSize) : 0;
732
733 if (aMVScale)
734 apPMV[1] >>= 1;
735
736 _mpeg12_decode_motion_vector(&apPMV[1], aVRSize, lMotionCode, lMotionResidual, aFullPelVector);
737
738 if (aMVScale)
739 apPMV[1] <<= 1;
740
741 if (aDMV)
742 apDMVector[1] = _MPEG_GetDMVector();
743
744 s_MPEG12Ctx.m_fError = lMotionCode == -32768;
745}
746
747static void _mpeg12_motion_vectors(
748 int aPMV[2][2][2], int aDMVector[2], int aMVFS[2][2], int aS, int anMV,
749 int aMVFmt, int aHRSize, int aVRSize, int aDMV, int aMVScale)
750{
751 if (anMV == 1) {
752 if (aMVFmt == _MPEG_MV_FIELD && !aDMV)
753 aMVFS[1][aS] = aMVFS[0][aS] = _MPEG_GetBits(1);
754
755 _mpeg12_motion_vector(aPMV[0][aS], aDMVector, aHRSize, aVRSize, aDMV, aMVScale, 0);
756
757 aPMV[1][aS][0] = aPMV[0][aS][0];
758 aPMV[1][aS][1] = aPMV[0][aS][1];
759 } else {
760 aMVFS[0][aS] = _MPEG_GetBits(1);
761 _mpeg12_motion_vector(aPMV[0][aS], aDMVector, aHRSize, aVRSize, aDMV, aMVScale, 0);
762
763 aMVFS[1][aS] = _MPEG_GetBits(1);
764 _mpeg12_motion_vector(aPMV[1][aS], aDMVector, aHRSize, aVRSize, aDMV, aMVScale, 0);
765 }
766}
767
768static int _mpeg12_dec_mb(
769 int *apMBType, int *apMotionType,
770 int aPMV[2][2][2], int aMVFS[2][2], int aDMVector[2])
771{
772
773 int lMBType;
774 int lDMV;
775 int lMVScale;
776 int lnMV;
777 int lMVFmt;
778 int lDCType;
779 int lMotionType;
780 int lfIntra;
781
782 lMotionType = 0;
783 lMBType = _MPEG_GetMBType();
784
785 if (!lMBType)
786 return 0;
787
788 lfIntra = lMBType & _MPEG_MBT_INTRA;
789
790 if (lMBType & (_MPEG_MBT_MOTION_FORWARD | _MPEG_MBT_MOTION_BACKWARD)) {
791
792 if (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME)
793 lMotionType = s_MPEG12Ctx.m_fFPFrmDCT ? _MPEG_MC_FRAME : _MPEG_GetBits(2);
794 else
795 lMotionType = _MPEG_GetBits(2);
796
797 } else if (lfIntra && s_MPEG12Ctx.m_fConsMV)
798 lMotionType = (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME) ? _MPEG_MC_FRAME : _MPEG_MC_FIELD;
799
800 if (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME) {
801 lnMV = lMotionType == _MPEG_MC_FIELD ? 2 : 1;
802 lMVFmt = lMotionType == _MPEG_MC_FRAME ? _MPEG_MV_FRAME : _MPEG_MV_FIELD;
803 } else {
804 lnMV = (lMotionType == _MPEG_MC_16X8) ? 2 : 1;
805 lMVFmt = _MPEG_MV_FIELD;
806 }
807
808 lDMV = lMotionType == _MPEG_MC_DMV;
809 lMVScale = lMVFmt == _MPEG_MV_FIELD && s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME;
810 lDCType = s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME && !s_MPEG12Ctx.m_fFPFrmDCT && lMBType & (_MPEG_MBT_PATTERN | _MPEG_MBT_INTRA) ? _MPEG_GetBits(1) : 0;
811
812 if (lMBType & _MPEG_MBT_QUANT)
813 s_MPEG12Ctx.m_QScale = _MPEG_GetBits(5);
814
815 if ((lMBType & _MPEG_MBT_MOTION_FORWARD) || (lfIntra && s_MPEG12Ctx.m_fConsMV)) {
816 if (s_MPEG12Ctx.m_fMPEG2)
817 _mpeg12_motion_vectors(aPMV, aDMVector, aMVFS, 0, lnMV, lMVFmt, s_MPEG12Ctx.m_FCode[0][0] - 1, s_MPEG12Ctx.m_FCode[0][1] - 1, lDMV, lMVScale);
818 else
819 _mpeg12_motion_vector(aPMV[0][0], aDMVector, s_MPEG12Ctx.m_FwdFCode - 1, s_MPEG12Ctx.m_FwdFCode - 1, 0, 0, s_MPEG12Ctx.m_FPFVector);
820 }
821
822 if (s_MPEG12Ctx.m_fError)
823 return 0;
824
825 if (lMBType & _MPEG_MBT_MOTION_BACKWARD) {
826 if (s_MPEG12Ctx.m_fMPEG2)
827 _mpeg12_motion_vectors(aPMV, aDMVector, aMVFS, 1, lnMV, lMVFmt, s_MPEG12Ctx.m_FCode[1][0] - 1, s_MPEG12Ctx.m_FCode[1][1] - 1, 0, lMVScale);
828 else
829 _mpeg12_motion_vector(aPMV[0][1], aDMVector, s_MPEG12Ctx.m_BckFCode - 1, s_MPEG12Ctx.m_BckFCode - 1, 0, 0, s_MPEG12Ctx.m_FPBVector);
830 }
831
832 if (s_MPEG12Ctx.m_fError)
833 return 0;
834
835 if (lfIntra && s_MPEG12Ctx.m_fConsMV)
836 _MPEG_GetBits(1);
837
838 if (lMBType & (_MPEG_MBT_INTRA | _MPEG_MBT_PATTERN))
839 _MPEG_BDEC(lfIntra, s_MPEG12Ctx.m_fDCRst, lDCType, s_MPEG12Ctx.m_QScale, s_MPEG12Ctx.m_pCurMotions->m_pSPRBlk);
840
841 s_MPEG12Ctx.m_fDCRst = !lfIntra;
842
843 if (lfIntra && !s_MPEG12Ctx.m_fConsMV) {
844 aPMV[0][0][0] = 0;
845 aPMV[0][0][1] = 0;
846 aPMV[1][0][0] = 0;
847 aPMV[1][0][1] = 0;
848 aPMV[0][1][0] = 0;
849 aPMV[0][1][1] = 0;
850 aPMV[1][1][0] = 0;
851 aPMV[1][1][1] = 0;
852 }
853
854 if ((s_MPEG12Ctx.m_PictCodingType == _MPEG_PT_P) && !(lMBType & (_MPEG_MBT_MOTION_FORWARD | _MPEG_MBT_INTRA))) {
855 aPMV[0][0][0] = 0;
856 aPMV[0][0][1] = 0;
857 aPMV[1][0][0] = 0;
858 aPMV[1][0][1] = 0;
859
860 if (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME) {
861 lMotionType = _MPEG_MC_FRAME;
862 } else {
863 lMotionType = _MPEG_MC_FIELD;
864 aMVFS[0][0] = s_MPEG12Ctx.m_PictStruct == _MPEG_PS_BOTTOM_FIELD;
865 }
866 }
867
868 *apMBType = lMBType;
869 *apMotionType = lMotionType;
870
871 return 1;
872}
873
874static void _mpeg12_get_ref(_MPEGMacroBlock8 *apMBSrc, int aX, int anY,
875 int aDX, int aDY, int aH, int aFSrc, int aFDst, int afAvg)
876{
877
878 int lfInt = (aH & 8) >> 3;
879 int lDXY = ((aDY & 1) << 1) | (aDX & 1);
880 int lUVXY = ((aDX & 2) >> 1) | (aDY & 2);
881 int lSrcX = aX + (aDX >> 1);
882 int lSrcY = ((anY + (aDY >> 1)) << lfInt) + aFSrc;
883 int lMBX = lSrcX >> 4;
884 int lMBY = lSrcY >> 4;
885 _MPEGMotion *lpMotion = &s_MPEG12Ctx.m_pCurMotions->m_Motion[s_MPEG12Ctx.m_pCurMotions->m_nMotions++];
886
887 afAvg <<= 2;
888
889#ifdef _EE
890 __asm__ __volatile__(
891 "pnor $v1, $zero, $zero \n"
892 "ld $v0, %4 \n"
893 "pextlw %0, %3, %2 \n"
894 "paddw $v0, $v0, $v1 \n"
895 "pmaxw %0, %0, $zero \n"
896 "pminw %0, %0, $v0 \n"
897 "dsrl32 %1, %0, 0 \n"
898 "sll %0, %0, 0 \n"
899 : "=r"(lMBX), "=r"(lMBY) : "r"(lMBX), "r"(lMBY), "m"(s_MPEG12Ctx.m_MBWidth)
900 : "v0", "v1");
901#else
902 lMBX = MIN(MAX(lMBX, 0), s_MPEG12Ctx.m_MBWidth - 1);
903 lMBY = MIN(MAX(lMBY, 0), s_MPEG12Ctx.m_MBWidth - 1);
904#endif
905
906 lpMotion->m_pSrc = (unsigned char *)(apMBSrc + lMBX + lMBY * s_MPEG12Ctx.m_MBWidth);
907 lpMotion->m_pDstY = (short *)(s_MPEG12Ctx.m_pCurMotions->m_pSPRRes + (aFDst << 5));
908 lpMotion->m_pDstCbCr = (short *)(s_MPEG12Ctx.m_pCurMotions->m_pSPRRes + 512 + (aFDst << 3));
909 lpMotion->m_X = lSrcX & 0xF;
910 lpMotion->m_Y = lSrcY & 0xF;
911 lpMotion->m_H = aH;
912 lpMotion->m_fInt = lfInt;
913 lpMotion->m_Field = aFSrc;
914 lpMotion->MC_Luma = LumaOp[lDXY + afAvg];
915 lpMotion->MC_Chroma = ChromaOp[lUVXY + afAvg];
916}
917
918static void _mpeg12_get_refs(int aBX, int aBY, int aMBType, int aMotionType, int aPMV[2][2][2],
919 int aMVFS[2][2], int aDMVector[2])
920{
921 int lfAdd = 0;
922
923 s_MPEG12Ctx.m_pCurMotions->m_nMotions = 0;
924
925 if ((aMBType & _MPEG_MBT_MOTION_FORWARD) ||
926 (s_MPEG12Ctx.m_PictCodingType == _MPEG_PT_P)) {
927
928 int lDMV[2][2];
929
930 if (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME) {
931
932 if ((aMotionType == _MPEG_MC_FRAME) || !(aMBType & _MPEG_MBT_MOTION_FORWARD)) {
933 _mpeg12_get_ref(s_MPEG12Ctx.m_pFwdFrame, aBX, aBY, aPMV[0][0][0], aPMV[0][0][1],
934 16, 0, 0, 0);
935 } else if (aMotionType == _MPEG_MC_FIELD) {
936 _mpeg12_get_ref(s_MPEG12Ctx.m_pFwdFrame, aBX, aBY >> 1, aPMV[0][0][0], aPMV[0][0][1] >> 1,
937 8, aMVFS[0][0], 0, 0);
938 _mpeg12_get_ref(s_MPEG12Ctx.m_pFwdFrame, aBX, aBY >> 1, aPMV[1][0][0], aPMV[1][0][1] >> 1,
939 8, aMVFS[1][0], 8, 0);
940 } else if (aMotionType == _MPEG_MC_DMV) {
941
942 _mpeg12_dual_prime_vector(lDMV, aDMVector, aPMV[0][0][0], aPMV[0][0][1] >> 1);
943 _mpeg12_get_ref(s_MPEG12Ctx.m_pFwdFrame, aBX, aBY >> 1, aPMV[0][0][0], aPMV[0][0][1] >> 1,
944 8, 0, 0, 0);
945 _mpeg12_get_ref(s_MPEG12Ctx.m_pFwdFrame, aBX, aBY >> 1, lDMV[0][0], lDMV[0][1],
946 8, 1, 0, 1);
947 _mpeg12_get_ref(s_MPEG12Ctx.m_pFwdFrame, aBX, aBY >> 1, aPMV[0][0][0], aPMV[0][0][1] >> 1,
948 8, 1, 8, 0);
949 _mpeg12_get_ref(s_MPEG12Ctx.m_pFwdFrame, aBX, aBY >> 1, lDMV[1][0], lDMV[1][1],
950 8, 0, 8, 1);
951 }
952 } else {
953 int lCurField;
954 _MPEGMacroBlock8 *lpMBSrc;
955
956 lCurField = (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_BOTTOM_FIELD);
957 lpMBSrc = (s_MPEG12Ctx.m_PictCodingType == _MPEG_PT_P) && s_MPEG12Ctx.m_fSecField && (lCurField != aMVFS[0][0]) ? s_MPEG12Ctx.m_pBckFrame : s_MPEG12Ctx.m_pFwdFrame;
958
959 if ((aMotionType == _MPEG_MC_FIELD) || !(aMBType & _MPEG_MBT_MOTION_FORWARD)) {
960 _mpeg12_get_ref(lpMBSrc, aBX, aBY, aPMV[0][0][0], aPMV[0][0][1], 8,
961 aMVFS[0][0], 0, 0);
962 _mpeg12_get_ref(lpMBSrc, aBX, aBY + 8, aPMV[0][0][0], aPMV[0][0][1], 8,
963 aMVFS[0][0], 8, 0);
964 } else if (aMotionType == _MPEG_MC_16X8) {
965 _mpeg12_get_ref(lpMBSrc, aBX, aBY, aPMV[0][0][0], aPMV[0][0][1], 8,
966 aMVFS[0][0], 0, 0);
967
968 lpMBSrc = (s_MPEG12Ctx.m_PictCodingType == _MPEG_PT_P) &&
969 s_MPEG12Ctx.m_fSecField &&
970 (lCurField != aMVFS[1][0]) ?
971 s_MPEG12Ctx.m_pBckFrame :
972 s_MPEG12Ctx.m_pFwdFrame;
973 _mpeg12_get_ref(lpMBSrc, aBX, aBY + 8, aPMV[1][0][0], aPMV[1][0][1], 8,
974 aMVFS[1][0], 8, 0);
975 } else if (aMotionType == _MPEG_MC_DMV) {
976 lpMBSrc = s_MPEG12Ctx.m_fSecField ? s_MPEG12Ctx.m_pBckFrame : s_MPEG12Ctx.m_pFwdFrame;
977 _mpeg12_dual_prime_vector(lDMV, aDMVector, aPMV[0][0][0], aPMV[0][0][1]);
978 _mpeg12_get_ref(s_MPEG12Ctx.m_pFwdFrame, aBX, aBY, aPMV[0][0][0], aPMV[0][0][1], 16,
979 lCurField, 0, 0);
980 _mpeg12_get_ref(lpMBSrc, aBX, aBY, lDMV[0][0], lDMV[0][1], 16, !lCurField, 1, 1);
981 }
982 }
983
984 lfAdd = 1;
985 }
986
987 if (aMBType & _MPEG_MBT_MOTION_BACKWARD) {
988 if (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME) {
989 if (aMotionType == _MPEG_MC_FRAME) {
990 _mpeg12_get_ref(s_MPEG12Ctx.m_pBckFrame, aBX, aBY, aPMV[0][1][0], aPMV[0][1][1],
991 16, 0, 0, lfAdd);
992 } else {
993 _mpeg12_get_ref(s_MPEG12Ctx.m_pBckFrame, aBX, aBY >> 1, aPMV[0][1][0], aPMV[0][1][1] >> 1,
994 8, aMVFS[0][1], 0, lfAdd);
995 _mpeg12_get_ref(s_MPEG12Ctx.m_pBckFrame, aBX, aBY >> 1, aPMV[1][1][0], aPMV[1][1][1] >> 1,
996 8, aMVFS[1][1], 8, lfAdd);
997 }
998 } else {
999 if (aMotionType == _MPEG_MC_FIELD) {
1000 _mpeg12_get_ref(s_MPEG12Ctx.m_pBckFrame, aBX, aBY, aPMV[0][1][0], aPMV[0][1][1], 8,
1001 aMVFS[0][1], 0, lfAdd);
1002 _mpeg12_get_ref(s_MPEG12Ctx.m_pBckFrame, aBX, aBY + 8, aPMV[0][1][0], aPMV[0][1][1], 8,
1003 aMVFS[0][1], 8, lfAdd);
1004 } else if (aMotionType == _MPEG_MC_16X8) {
1005 _mpeg12_get_ref(s_MPEG12Ctx.m_pBckFrame, aBX, aBY, aPMV[0][1][0], aPMV[0][1][1],
1006 8, aMVFS[0][1], 0, lfAdd);
1007 _mpeg12_get_ref(s_MPEG12Ctx.m_pBckFrame, aBX, aBY + 8, aPMV[1][1][0], aPMV[1][1][1],
1008 8, aMVFS[1][1], 8, lfAdd);
1009 }
1010 }
1011 }
1012
1013 _MPEG_dma_ref_image((_MPEGMacroBlock8 *)s_MPEG12Ctx.m_pCurMotions->m_pSPRMC,
1014 &s_MPEG12Ctx.m_pCurMotions->m_Motion[0],
1015 s_MPEG12Ctx.m_pCurMotions->m_nMotions, s_MPEG12Ctx.m_MBWidth);
1016}
1017
1018/* Motion compensation */
1019static void _mpeg2_mc(int aMBA, int aMBType, int aMotionType,
1020 int aPMV[2][2][2], int aMVFS[2][2],
1021 int aDMVector[2], int aMBAI)
1022{
1023 /* block x,y */
1024 int lBX, lBY;
1025 int lfField;
1026 int lfIntra;
1027 int lOffset;
1028 int lfNoSkip;
1029 int lfFiledMV;
1030
1031 lBX = s_MPEG12Ctx.m_pMBXY[aMBA].m_X;
1032 lBY = s_MPEG12Ctx.m_pMBXY[aMBA].m_Y;
1033 lfField = s_MPEG12Ctx.m_PictStruct != _MPEG_PS_FRAME;
1034 lOffset = (lBY * (s_MPEG12Ctx.m_MBWidth << lfField) + lBX) * sizeof(_MPEGMacroBlock8);
1035 lfIntra = aMBType & _MPEG_MBT_INTRA;
1036 lfNoSkip = aMBAI == 1;
1037 lfFiledMV = aMotionType & _MPEG_MC_FIELD;
1038
1039 s_MPEG12Ctx.m_pCurMotions->m_Stride = s_MPEG12Ctx.m_MBStride;
1040 s_MPEG12Ctx.m_pCurMotions->m_pMBDstY = UNCACHED_SEG(s_MPEG12Ctx.m_pCurFrameY + lOffset);
1041 s_MPEG12Ctx.m_pCurMotions->m_pMBDstCbCr = UNCACHED_SEG(s_MPEG12Ctx.m_pCurFrameCbCr + lOffset);
1042
1043 lBX <<= 4;
1044 lBY <<= 4;
1045
1046 if (!lfIntra) {
1047 _mpeg12_get_refs(lBX, lBY, aMBType, aMotionType, aPMV, aMVFS, aDMVector);
1048 if (lfNoSkip && (aMBType & _MPEG_MBT_PATTERN))
1049 s_MPEG12Ctx.m_pCurMotions->BlockOp = AddBlockOp[lfField][lfFiledMV];
1050 else {
1051 s_MPEG12Ctx.m_pCurMotions->m_pSrc = s_MPEG12Ctx.m_pCurMotions->m_pSPRRes;
1052 s_MPEG12Ctx.m_pCurMotions->BlockOp = PutBlockOp[!lfField + (lfNoSkip && lfFiledMV && !lfField)];
1053 }
1054 } else {
1055 s_MPEG12Ctx.m_pCurMotions->m_Motion[0].MC_Luma = NULL;
1056 s_MPEG12Ctx.m_pCurMotions->m_pSrc = s_MPEG12Ctx.m_pCurMotions->m_pSPRBlk;
1057 s_MPEG12Ctx.m_pCurMotions->BlockOp = PutBlockOp[!lfField];
1058 }
1059}
1060
1061/* decode all macroblocks of the current picture */
1062static int _mpeg12_slice(int aMBAMax)
1063{
1064 int lPMV[2][2][2];
1065 int lMVFS[2][2];
1066 int lDMVector[2];
1067 int lMBA, lMBAI, lMBType, lMotionType;
1068 int retVal;
1069
1070 s_MPEG12Ctx.m_fError = 0;
1071 lMBType = _MPEG_NextStartCode();
1072
1073 /* only slice headers are allowed in picture_data */
1074 if (lMBType < _MPEG_CODE_SLICE_MIN || lMBType > _MPEG_CODE_SLICE_MAX)
1075 return -1;
1076
1077 _MPEG_GetBits(32);
1078
1079 s_MPEG12Ctx.m_QScale = _MPEG_GetBits(5);
1080
1081 if (_MPEG_GetBits(1)) {
1082 _MPEG_GetBits(8);
1083 _xtra_bitinf();
1084 }
1085
1086 lMBAI = _MPEG_GetMBAI();
1087
1088 if (lMBAI) {
1089 lMBA = ((lMBType & 255) - 1) * s_MPEG12Ctx.m_MBWidth + lMBAI - 1;
1090
1091 lMBAI = s_MPEG12Ctx.m_fDCRst = 1;
1092
1093 lPMV[0][0][0] = lPMV[0][0][1] = lPMV[1][0][0] = lPMV[1][0][1] = 0;
1094 lPMV[0][1][0] = lPMV[0][1][1] = lPMV[1][1][0] = lPMV[1][1][1] = 0;
1095 } else {
1096 return 0;
1097 }
1098
1099 while (1) {
1100 s_MPEG12Ctx.m_pCurMotions = &s_MPEG12Ctx.m_MC[s_MPEG12Ctx.m_CurMC];
1101
1102 if (lMBA >= aMBAMax || !_MPEG_WaitBDEC())
1103 return -1;
1104
1105 if (!lMBAI) {
1106 if (!_MPEG_ShowBits(23) || s_MPEG12Ctx.m_fError) {
1107 resync:
1108 s_MPEG12Ctx.m_fError = 0;
1109 return 0;
1110 } else {
1111 lMBAI = _MPEG_GetMBAI();
1112
1113 if (!lMBAI)
1114 goto resync;
1115 }
1116 }
1117
1118 if (lMBA >= aMBAMax)
1119 return -1;
1120
1121 if (lMBAI == 1) {
1122 retVal = _mpeg12_dec_mb(&lMBType, &lMotionType, lPMV, lMVFS, lDMVector);
1123
1124 if (retVal < 0)
1125 return retVal;
1126
1127 if (!retVal)
1128 goto resync;
1129 } else {
1130 /* skipped macroblock */
1131 s_MPEG12Ctx.m_fDCRst = 1;
1132
1133 if (s_MPEG12Ctx.m_PictCodingType == _MPEG_PT_P) {
1134 lPMV[0][0][0] = 0;
1135 lPMV[0][0][1] = 0;
1136 lPMV[1][0][0] = 0;
1137 lPMV[1][0][1] = 0;
1138 }
1139
1140 if (s_MPEG12Ctx.m_PictStruct == _MPEG_PS_FRAME) {
1141 lMotionType = _MPEG_MC_FRAME;
1142 } else {
1143 lMotionType = _MPEG_MC_FIELD;
1144 lMVFS[0][0] = s_MPEG12Ctx.m_PictStruct == _MPEG_PS_BOTTOM_FIELD;
1145 lMVFS[0][1] = s_MPEG12Ctx.m_PictStruct == _MPEG_PS_BOTTOM_FIELD;
1146 }
1147
1148 lMBType &= ~_MPEG_MBT_INTRA;
1149 }
1150
1151 _mpeg2_mc(lMBA, lMBType, lMotionType, lPMV, lMVFS, lDMVector, lMBAI);
1152
1153 DoMC();
1154
1155 ++lMBA;
1156 --lMBAI;
1157
1158 s_MPEG12Ctx.m_CurMC ^= 1;
1159
1160 if (lMBA >= aMBAMax)
1161 return -1;
1162 }
1163}
#define R_EE_IPU_CTRL
Definition ee_regs.h:241