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