1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "audio/audiostream.h"
24 #include "audio/decoders/raw.h"
25 #include "audio/decoders/ac3.h"
26 #include "audio/decoders/mp3.h"
27 #include "common/debug.h"
28 #include "common/endian.h"
29 #include "common/stream.h"
30 #include "common/memstream.h"
31 #include "common/system.h"
32 #include "common/textconsole.h"
33 
34 #include "video/mpegps_decoder.h"
35 #include "image/codecs/mpeg.h"
36 
37 // The demuxing code is based on libav's demuxing code
38 
39 namespace Video {
40 
41 // --------------------------------------------------------------------------
42 // Decoder - This is the part that takes a packet and figures out what to do
43 // with it.
44 // --------------------------------------------------------------------------
45 
46 enum {
47 	kStartCodePack = 0x1BA,
48 	kStartCodeSystemHeader = 0x1BB,
49 	kStartCodeProgramStreamMap = 0x1BC,
50 	kStartCodePrivateStream1 = 0x1BD,
51 	kStartCodePaddingStream = 0x1BE,
52 	kStartCodePrivateStream2 = 0x1BF
53 };
54 
MPEGPSDecoder(double decibel)55 MPEGPSDecoder::MPEGPSDecoder(double decibel) {
56 	_decibel = decibel;
57 	_demuxer = new MPEGPSDemuxer();
58 }
59 
~MPEGPSDecoder()60 MPEGPSDecoder::~MPEGPSDecoder() {
61 	close();
62 	delete _demuxer;
63 }
64 
loadStream(Common::SeekableReadStream * stream)65 bool MPEGPSDecoder::loadStream(Common::SeekableReadStream *stream) {
66 	close();
67 
68 	if (!_demuxer->loadStream(stream)) {
69 		close();
70 		return false;
71 	}
72 
73 	if (!addFirstVideoTrack()) {
74 		close();
75 		return false;
76 	}
77 
78 	return true;
79 }
80 
close()81 void MPEGPSDecoder::close() {
82 	VideoDecoder::close();
83 	_demuxer->close();
84 	_streamMap.clear();
85 }
86 
getStream(uint32 startCode,Common::SeekableReadStream * packet)87 MPEGPSDecoder::MPEGStream *MPEGPSDecoder::getStream(uint32 startCode, Common::SeekableReadStream *packet) {
88 	MPEGStream *stream = 0;
89 
90 	if (_streamMap.contains(startCode)) {
91 		// We already found the stream
92 		stream = _streamMap[startCode];
93 	} else {
94 		// We haven't seen this before
95 
96 		if (startCode == kStartCodePrivateStream1) {
97 			PrivateStreamType streamType = detectPrivateStreamType(packet);
98 			packet->seek(0);
99 
100 			// TODO: Handling of these types (as needed)
101 			bool handled = false;
102 			const char *typeName;
103 
104 			switch (streamType) {
105 			case kPrivateStreamAC3: {
106 				typeName = "AC-3";
107 
108 #ifdef USE_A52
109 				handled = true;
110 				AC3AudioTrack *ac3Track = new AC3AudioTrack(*packet, _decibel, getSoundType());
111 				stream = ac3Track;
112 				_streamMap[startCode] = ac3Track;
113 				addTrack(ac3Track);
114 #endif
115 				break;
116 			}
117 			case kPrivateStreamDTS:
118 				typeName = "DTS";
119 				break;
120 			case kPrivateStreamDVDPCM:
121 				typeName = "DVD PCM";
122 				break;
123 			case kPrivateStreamPS2Audio: {
124 				typeName = "PS2 Audio";
125 				handled = true;
126 				PS2AudioTrack *audioTrack = new PS2AudioTrack(packet, getSoundType());
127 				stream = audioTrack;
128 				_streamMap[startCode] = audioTrack;
129 				addTrack(audioTrack);
130 				break;
131 			}
132 			default:
133 				typeName = "Unknown";
134 				break;
135 			}
136 
137 			if (!handled) {
138 				warning("Unhandled DVD private stream: %s", typeName);
139 
140 				// Make it 0 so we don't get the warning twice
141 				_streamMap[startCode] = 0;
142 			}
143 		} else if (startCode >= 0x1E0 && startCode <= 0x1EF) {
144 			// Video stream
145 			// TODO: Multiple video streams
146 			warning("Found extra video stream 0x%04X", startCode);
147 			_streamMap[startCode] = 0;
148 		} else if (startCode >= 0x1C0 && startCode <= 0x1DF) {
149 #ifdef USE_MAD
150 			// MPEG Audio stream
151 			MPEGAudioTrack *audioTrack = new MPEGAudioTrack(*packet, getSoundType());
152 			stream = audioTrack;
153 			_streamMap[startCode] = audioTrack;
154 			addTrack(audioTrack);
155 #else
156 			warning("Found audio stream 0x%04X, but no MAD support compiled in", startCode);
157 			_streamMap[startCode] = 0;
158 #endif
159 		} else {
160 			// Probably not relevant
161 			debug(0, "Found unhandled MPEG-PS stream type 0x%04x", startCode);
162 			_streamMap[startCode] = 0;
163 		}
164 	}
165 
166 	return stream;
167 }
168 
readNextPacket()169 void MPEGPSDecoder::readNextPacket() {
170 	for (;;) {
171 		int32 startCode;
172 		uint32 pts, dts;
173 		Common::SeekableReadStream *packet = _demuxer->getNextPacket(getTime(), startCode, pts, dts);
174 
175 		if (!packet) {
176 			// End of stream
177 			for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++)
178 				if ((*it)->getTrackType() == Track::kTrackTypeVideo)
179 					((MPEGVideoTrack *)*it)->setEndOfTrack();
180 			return;
181 		}
182 
183 		MPEGStream *stream = getStream(startCode, packet);
184 
185 		if (stream) {
186 			packet->seek(0);
187 
188 			bool done = stream->sendPacket(packet, pts, dts);
189 
190 			if (done && stream->getStreamType() == MPEGStream::kStreamTypeVideo)
191 				return;
192 		} else {
193 			delete packet;
194 		}
195 	}
196 }
197 
addFirstVideoTrack()198 bool MPEGPSDecoder::addFirstVideoTrack() {
199 	int32 startCode;
200 	uint32 pts, dts;
201 	Common::SeekableReadStream *packet = _demuxer->getFirstVideoPacket(startCode, pts, dts);
202 
203 	if (!packet)
204 		return false;
205 
206 	// Video stream
207 	// Can be MPEG-1/2 or MPEG-4/h.264. We'll assume the former and
208 	// I hope we never need the latter.
209 	MPEGVideoTrack *track = new MPEGVideoTrack(packet, getDefaultHighColorFormat());
210 	addTrack(track);
211 	_streamMap[startCode] = track;
212 
213 	return true;
214 }
215 
detectPrivateStreamType(Common::SeekableReadStream * packet)216 MPEGPSDecoder::PrivateStreamType MPEGPSDecoder::detectPrivateStreamType(Common::SeekableReadStream *packet) {
217 	uint32 dvdCode = packet->readUint32LE();
218 	if (packet->eos())
219 		return kPrivateStreamUnknown;
220 
221 	uint32 ps2Header = packet->readUint32BE();
222 	if (!packet->eos() && ps2Header == MKTAG('S', 'S', 'h', 'd'))
223 		return kPrivateStreamPS2Audio;
224 
225 	switch (dvdCode & 0xE0) {
226 	case 0x80:
227 		if ((dvdCode & 0xF8) == 0x88)
228 			return kPrivateStreamDTS;
229 
230 		return kPrivateStreamAC3;
231 	case 0xA0:
232 		return kPrivateStreamDVDPCM;
233 	default:
234 		break;
235 	}
236 
237 	return kPrivateStreamUnknown;
238 }
239 
240 // --------------------------------------------------------------------------
241 // Demuxer - This is the part that reads packets from the stream and delivers
242 // them to the decoder.
243 //
244 // It will buffer a number of packets in advance, because otherwise it may
245 // not encounter any audio packets until it's far too late to decode them.
246 // Before I added this, there would be 9 or 10 frames of video before the
247 // first audio packet, even though the timestamp indicated that the audio
248 // should start slightly before the video.
249 // --------------------------------------------------------------------------
250 
251 #define PREBUFFERED_PACKETS 150
252 #define AUDIO_THRESHOLD     100
253 
MPEGPSDemuxer()254 MPEGPSDecoder::MPEGPSDemuxer::MPEGPSDemuxer() {
255 	_stream = 0;
256 }
257 
~MPEGPSDemuxer()258 MPEGPSDecoder::MPEGPSDemuxer::~MPEGPSDemuxer() {
259 	close();
260 }
261 
loadStream(Common::SeekableReadStream * stream)262 bool MPEGPSDecoder::MPEGPSDemuxer::loadStream(Common::SeekableReadStream *stream) {
263 	close();
264 
265 	_stream = stream;
266 
267 	int queuedPackets = 0;
268 	while (queueNextPacket() && queuedPackets < PREBUFFERED_PACKETS) {
269 		queuedPackets++;
270 	}
271 
272 	return true;
273 }
274 
close()275 void MPEGPSDecoder::MPEGPSDemuxer::close() {
276 	delete _stream;
277 	_stream = 0;
278 
279 	while (!_audioQueue.empty()) {
280 		Packet packet = _audioQueue.pop();
281 		delete packet._stream;
282 	}
283 
284 	while (!_videoQueue.empty()) {
285 		Packet packet = _videoQueue.pop();
286 		delete packet._stream;
287 	}
288 }
289 
getFirstVideoPacket(int32 & startCode,uint32 & pts,uint32 & dts)290 Common::SeekableReadStream *MPEGPSDecoder::MPEGPSDemuxer::getFirstVideoPacket(int32 &startCode, uint32 &pts, uint32 &dts) {
291 	if (_videoQueue.empty())
292 		return nullptr;
293 	Packet packet = _videoQueue.front();
294 	startCode = packet._startCode;
295 	pts = packet._pts;
296 	dts = packet._dts;
297 	return packet._stream;
298 }
299 
getNextPacket(uint32 currentTime,int32 & startCode,uint32 & pts,uint32 & dts)300 Common::SeekableReadStream *MPEGPSDecoder::MPEGPSDemuxer::getNextPacket(uint32 currentTime, int32 &startCode, uint32 &pts, uint32 &dts) {
301 	queueNextPacket();
302 
303 	// The idea here is to prioritize the delivery of audio packets,
304 	// because when the decoder wants a frame it will keep asking until it
305 	// gets a frame. There is nothing like that in the decoder to ensure
306 	// speedy delivery of audio.
307 
308 	if (!_audioQueue.empty()) {
309 		Packet packet = _audioQueue.front();
310 		bool usePacket = false;
311 
312 		if (packet._pts == 0xFFFFFFFF) {
313 			// No timestamp? Use it just in case. This could be a
314 			// bad idea, but in my tests all audio packets have a
315 			// time stamp.
316 			usePacket = true;
317 		} else {
318 			uint32 packetTime = packet._pts / 90;
319 			if (packetTime <= currentTime || packetTime - currentTime < AUDIO_THRESHOLD || _videoQueue.empty()) {
320 				// The packet is overdue, or will be soon.
321 				//
322 				// TODO: We should pad or trim the first audio
323 				// packet based on the timestamp to get the
324 				// audio to start at the exact desired time.
325 				// But for some reason it seems to work well
326 				// enough anyway. For now.
327 				usePacket = true;
328 			}
329 		}
330 
331 		if (usePacket) {
332 			_audioQueue.pop();
333 			startCode = packet._startCode;
334 			pts = packet._pts;
335 			dts = packet._dts;
336 			return packet._stream;
337 		}
338 	}
339 
340 	if (!_videoQueue.empty()) {
341 		Packet packet = _videoQueue.pop();
342 		startCode = packet._startCode;
343 		pts = packet._pts;
344 		dts = packet._dts;
345 		return packet._stream;
346 	}
347 
348 	return nullptr;
349 }
350 
queueNextPacket()351 bool MPEGPSDecoder::MPEGPSDemuxer::queueNextPacket() {
352 	if (_stream->eos())
353 		return false;
354 
355 	for (;;) {
356 		int32 startCode;
357 		uint32 pts, dts;
358 		int size = readNextPacketHeader(startCode, pts, dts);
359 
360 		if (size < 0) {
361 			// End of stream
362 			return false;
363 		}
364 
365 		Common::SeekableReadStream *stream = _stream->readStream(size);
366 
367 		if (startCode == kStartCodePrivateStream1 || (startCode >= 0x1C0 && startCode <= 0x1DF)) {
368 			// Audio packet
369 			_audioQueue.push(Packet(stream, startCode, pts, dts));
370 			return true;
371 		}
372 
373 		if (startCode >= 0x1E0 && startCode <= 0x1EF) {
374 			// Video packet
375 			_videoQueue.push(Packet(stream, startCode, pts, dts));
376 			return true;
377 		}
378 
379 		delete stream;
380 	}
381 }
382 
readNextPacketHeader(int32 & startCode,uint32 & pts,uint32 & dts)383 int MPEGPSDecoder::MPEGPSDemuxer::readNextPacketHeader(int32 &startCode, uint32 &pts, uint32 &dts) {
384 	for (;;) {
385 		uint32 size;
386 		startCode = findNextStartCode(size);
387 
388 		if (_stream->eos())
389 			return -1;
390 
391 		if (startCode < 0)
392 			continue;
393 
394 		uint32 lastSync = _stream->pos();
395 
396 		if (startCode == kStartCodePack || startCode == kStartCodeSystemHeader)
397 			continue;
398 
399 		int length = _stream->readUint16BE();
400 
401 		if (startCode == kStartCodePaddingStream || startCode == kStartCodePrivateStream2) {
402 			_stream->skip(length);
403 			continue;
404 		}
405 
406 		if (startCode == kStartCodeProgramStreamMap) {
407 			parseProgramStreamMap(length);
408 			continue;
409 		}
410 
411 		// Find matching stream
412 		if (!((startCode >= 0x1C0 && startCode <= 0x1DF) ||
413 				(startCode >= 0x1E0 && startCode <= 0x1EF) ||
414 				startCode == kStartCodePrivateStream1 || startCode == 0x1FD))
415 			continue;
416 
417 		// Stuffing
418 		byte c;
419 		for (;;) {
420 			if (length < 1) {
421 				_stream->seek(lastSync);
422 				continue;
423 			}
424 
425 			c = _stream->readByte();
426 			length--;
427 
428 			// XXX: for mpeg1, should test only bit 7
429 			if (c != 0xFF)
430 				break;
431 		}
432 
433 		if ((c & 0xC0) == 0x40) {
434 			// Buffer scale and size
435 			_stream->readByte();
436 			c = _stream->readByte();
437 			length -= 2;
438 		}
439 
440 		pts = 0xFFFFFFFF;
441 		dts = 0xFFFFFFFF;
442 
443 		if ((c & 0xE0) == 0x20) {
444 			dts = pts = readPTS(c);
445 			length -= 4;
446 
447 			if (c & 0x10) {
448 				dts = readPTS(-1);
449 				length -= 5;
450 			}
451 		} else if ((c & 0xC0) == 0x80) {
452 			// MPEG-2 PES
453 			byte flags = _stream->readByte();
454 			int headerLength = _stream->readByte();
455 			length -= 2;
456 
457 			if (headerLength > length) {
458 				_stream->seek(lastSync);
459 				continue;
460 			}
461 
462 			length -= headerLength;
463 
464 			if (flags & 0x80) {
465 				dts = pts = readPTS(-1);
466 				headerLength -= 5;
467 
468 				if (flags & 0x40) {
469 					dts = readPTS(-1);
470 					headerLength -= 5;
471 				}
472 			}
473 
474 			if (flags & 0x3F && headerLength == 0) {
475 				flags &= 0xC0;
476 				warning("Further flags set but no bytes left");
477 			}
478 
479 			if (flags & 0x01) { // PES extension
480 				byte pesExt =_stream->readByte();
481 				headerLength--;
482 
483 				// Skip PES private data, program packet sequence
484 				int skip = (pesExt >> 4) & 0xB;
485 				skip += skip & 0x9;
486 
487 				if (pesExt & 0x40 || skip > headerLength) {
488 					warning("pesExt %x is invalid", pesExt);
489 					pesExt = skip = 0;
490 				} else {
491 					_stream->skip(skip);
492 					headerLength -= skip;
493 				}
494 
495 				if (pesExt & 0x01) { // PES extension 2
496 					byte ext2Length = _stream->readByte();
497 					headerLength--;
498 
499 					if ((ext2Length & 0x7F) != 0) {
500 						byte idExt = _stream->readByte();
501 
502 						if ((idExt & 0x80) == 0)
503 							startCode = (startCode & 0xFF) << 8;
504 
505 						headerLength--;
506 					}
507 				}
508 			}
509 
510 			if (headerLength < 0) {
511 				_stream->seek(lastSync);
512 				continue;
513 			}
514 
515 			_stream->skip(headerLength);
516 		} else if (c != 0xF) {
517 			continue;
518 		}
519 
520 		if (length < 0) {
521 			_stream->seek(lastSync);
522 			continue;
523 		}
524 
525 		return length;
526 	}
527 }
528 
529 #define MAX_SYNC_SIZE 100000
530 
findNextStartCode(uint32 & size)531 int MPEGPSDecoder::MPEGPSDemuxer::findNextStartCode(uint32 &size) {
532 	size = MAX_SYNC_SIZE;
533 	int32 state = 0xFF;
534 
535 	while (size > 0) {
536 		byte v = _stream->readByte();
537 
538 		if (_stream->eos())
539 			return -1;
540 
541 		size--;
542 
543 		if (state == 0x1)
544 			return ((state << 8) | v) & 0xFFFFFF;
545 
546 		state = ((state << 8) | v) & 0xFFFFFF;
547 	}
548 
549 	return -1;
550 }
551 
readPTS(int c)552 uint32 MPEGPSDecoder::MPEGPSDemuxer::readPTS(int c) {
553 	byte buf[5];
554 
555 	buf[0] = (c < 0) ? _stream->readByte() : c;
556 	_stream->read(buf + 1, 4);
557 
558 	return ((buf[0] & 0x0E) << 29) | ((READ_BE_UINT16(buf + 1) >> 1) << 15) | (READ_BE_UINT16(buf + 3) >> 1);
559 }
560 
parseProgramStreamMap(int length)561 void MPEGPSDecoder::MPEGPSDemuxer::parseProgramStreamMap(int length) {
562 	_stream->readByte();
563 	_stream->readByte();
564 
565 	// skip program stream info
566 	_stream->skip(_stream->readUint16BE());
567 
568 	int esMapLength = _stream->readUint16BE();
569 
570 	while (esMapLength >= 4) {
571 		_stream->readByte(); // type
572 		_stream->readByte(); // esID
573 		uint16 esInfoLength = _stream->readUint16BE();
574 
575 		// Skip program stream info
576 		_stream->skip(esInfoLength);
577 
578 		esMapLength -= 4 + esInfoLength;
579 	}
580 
581 	_stream->readUint32BE(); // CRC32
582 }
583 
584 // --------------------------------------------------------------------------
585 // Video track
586 // --------------------------------------------------------------------------
587 
MPEGVideoTrack(Common::SeekableReadStream * firstPacket,const Graphics::PixelFormat & format)588 MPEGPSDecoder::MPEGVideoTrack::MPEGVideoTrack(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format) {
589 	_surface = 0;
590 	_endOfTrack = false;
591 	_curFrame = -1;
592 	_framePts = 0xFFFFFFFF;
593 	_nextFrameStartTime = Audio::Timestamp(0, 27000000); // 27 MHz timer
594 
595 	findDimensions(firstPacket, format);
596 
597 #ifdef USE_MPEG2
598 	_mpegDecoder = new Image::MPEGDecoder();
599 #endif
600 }
601 
~MPEGVideoTrack()602 MPEGPSDecoder::MPEGVideoTrack::~MPEGVideoTrack() {
603 #ifdef USE_MPEG2
604 	delete _mpegDecoder;
605 #endif
606 
607 	if (_surface) {
608 		_surface->free();
609 		delete _surface;
610 	}
611 }
612 
getWidth() const613 uint16 MPEGPSDecoder::MPEGVideoTrack::getWidth() const {
614 	return _surface ? _surface->w : 0;
615 }
616 
getHeight() const617 uint16 MPEGPSDecoder::MPEGVideoTrack::getHeight() const {
618 	return _surface ? _surface->h : 0;
619 }
620 
getPixelFormat() const621 Graphics::PixelFormat MPEGPSDecoder::MPEGVideoTrack::getPixelFormat() const {
622 	if (!_surface)
623 		return Graphics::PixelFormat();
624 
625 	return _surface->format;
626 }
627 
decodeNextFrame()628 const Graphics::Surface *MPEGPSDecoder::MPEGVideoTrack::decodeNextFrame() {
629 	return _surface;
630 }
631 
sendPacket(Common::SeekableReadStream * packet,uint32 pts,uint32 dts)632 bool MPEGPSDecoder::MPEGVideoTrack::sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts) {
633 #ifdef USE_MPEG2
634 	if (pts != 0xFFFFFFFF) {
635 		_framePts = pts;
636 	}
637 
638 	uint32 framePeriod;
639 	bool foundFrame = _mpegDecoder->decodePacket(*packet, framePeriod, _surface);
640 
641 	if (foundFrame) {
642 		_curFrame++;
643 
644 		// If there has been a timestamp since the previous frame, use that for
645 		// syncing. Usually it will be the timestamp from the current packet,
646 		// but it might not be.
647 
648 		if (_framePts != 0xFFFFFFFF) {
649 			_nextFrameStartTime = Audio::Timestamp(_framePts / 90, 27000000);
650 		} else {
651 			_nextFrameStartTime = _nextFrameStartTime.addFrames(framePeriod);
652 		}
653 
654 		_framePts = 0xFFFFFFFF;
655 	}
656 #endif
657 
658 	delete packet;
659 
660 #ifdef USE_MPEG2
661 	return foundFrame;
662 #else
663 	return true;
664 #endif
665 }
666 
findDimensions(Common::SeekableReadStream * firstPacket,const Graphics::PixelFormat & format)667 void MPEGPSDecoder::MPEGVideoTrack::findDimensions(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format) {
668 	// First, check for the picture start code
669 	if (firstPacket->readUint32BE() != 0x1B3)
670 		error("Failed to detect MPEG sequence start");
671 
672 	// This is part of the bitstream, but there's really no purpose
673 	// to use Common::BitStream just for this: 12 bits width, 12 bits
674 	// height
675 	uint16 width = firstPacket->readByte() << 4;
676 	uint16 height = firstPacket->readByte();
677 	width |= (height & 0xF0) >> 4;
678 	height = ((height & 0x0F) << 8) | firstPacket->readByte();
679 
680 	debug(0, "MPEG dimensions: %dx%d", width, height);
681 
682 	_surface = new Graphics::Surface();
683 	_surface->create(width, height, format);
684 
685 	firstPacket->seek(0);
686 }
687 
688 // --------------------------------------------------------------------------
689 // Audio track
690 // --------------------------------------------------------------------------
691 
692 #ifdef USE_MAD
693 
694 // The audio code here is almost entirely based on what we do in mp3.cpp
695 
MPEGAudioTrack(Common::SeekableReadStream & firstPacket,Audio::Mixer::SoundType soundType)696 MPEGPSDecoder::MPEGAudioTrack::MPEGAudioTrack(Common::SeekableReadStream &firstPacket, Audio::Mixer::SoundType soundType) :
697 		AudioTrack(soundType) {
698 	_audStream = Audio::makePacketizedMP3Stream(firstPacket);
699 }
700 
~MPEGAudioTrack()701 MPEGPSDecoder::MPEGAudioTrack::~MPEGAudioTrack() {
702 	delete _audStream;
703 }
704 
sendPacket(Common::SeekableReadStream * packet,uint32 pts,uint32 dts)705 bool MPEGPSDecoder::MPEGAudioTrack::sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts) {
706 	_audStream->queuePacket(packet);
707 	return true;
708 }
709 
getAudioStream() const710 Audio::AudioStream *MPEGPSDecoder::MPEGAudioTrack::getAudioStream() const {
711 	return _audStream;
712 }
713 
714 #endif
715 
716 #ifdef USE_A52
717 
AC3AudioTrack(Common::SeekableReadStream & firstPacket,double decibel,Audio::Mixer::SoundType soundType)718 MPEGPSDecoder::AC3AudioTrack::AC3AudioTrack(Common::SeekableReadStream &firstPacket, double decibel, Audio::Mixer::SoundType soundType) :
719 		AudioTrack(soundType) {
720 	_audStream = Audio::makeAC3Stream(firstPacket, decibel);
721 	if (!_audStream)
722 		error("Could not create AC-3 stream");
723 }
724 
~AC3AudioTrack()725 MPEGPSDecoder::AC3AudioTrack::~AC3AudioTrack() {
726 	delete _audStream;
727 }
728 
sendPacket(Common::SeekableReadStream * packet,uint32 pts,uint32 dts)729 bool MPEGPSDecoder::AC3AudioTrack::sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts) {
730 	// Skip DVD code
731 	packet->readUint32LE();
732 	if (packet->eos())
733 		return true;
734 
735 	_audStream->queuePacket(packet);
736 	return true;
737 }
738 
getAudioStream() const739 Audio::AudioStream *MPEGPSDecoder::AC3AudioTrack::getAudioStream() const {
740 	return _audStream;
741 }
742 
743 #endif
744 
PS2AudioTrack(Common::SeekableReadStream * firstPacket,Audio::Mixer::SoundType soundType)745 MPEGPSDecoder::PS2AudioTrack::PS2AudioTrack(Common::SeekableReadStream *firstPacket, Audio::Mixer::SoundType soundType) :
746 		AudioTrack(soundType) {
747 	firstPacket->seek(12); // unknown data (4), 'SShd', header size (4)
748 
749 	_soundType = firstPacket->readUint32LE();
750 
751 	if (_soundType == PS2_ADPCM)
752 		error("Unhandled PS2 ADPCM sound in MPEG-PS video");
753 	else if (_soundType != PS2_PCM)
754 		error("Unknown PS2 sound type %x", _soundType);
755 
756 	uint32 sampleRate = firstPacket->readUint32LE();
757 	_channels = firstPacket->readUint32LE();
758 	_interleave = firstPacket->readUint32LE();
759 
760 	byte flags = Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN;
761 	if (_channels == 2)
762 		flags |= Audio::FLAG_STEREO;
763 
764 	_blockBuffer = new byte[_interleave * _channels];
765 	_blockPos = _blockUsed = 0;
766 	_audStream = Audio::makePacketizedRawStream(sampleRate, flags);
767 	_isFirstPacket = true;
768 
769 	firstPacket->seek(0);
770 }
771 
~PS2AudioTrack()772 MPEGPSDecoder::PS2AudioTrack::~PS2AudioTrack() {
773 	delete[] _blockBuffer;
774 	delete _audStream;
775 }
776 
sendPacket(Common::SeekableReadStream * packet,uint32 pts,uint32 dts)777 bool MPEGPSDecoder::PS2AudioTrack::sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts) {
778 	packet->skip(4);
779 
780 	if (_isFirstPacket) {
781 		// Skip over the header which we already parsed
782 		packet->skip(4);
783 		packet->skip(packet->readUint32LE());
784 
785 		if (packet->readUint32BE() != MKTAG('S', 'S', 'b', 'd'))
786 			error("Failed to find 'SSbd' tag");
787 
788 		packet->readUint32LE(); // body size
789 		_isFirstPacket = false;
790 	}
791 
792 	uint32 size = packet->size() - packet->pos();
793 	uint32 bytesPerChunk = _interleave * _channels;
794 	uint32 sampleCount = calculateSampleCount(size);
795 
796 	byte *buffer = (byte *)malloc(sampleCount * 2);
797 	int16 *ptr = (int16 *)buffer;
798 
799 	// Handle any full chunks first
800 	while (size >= bytesPerChunk) {
801 		packet->read(_blockBuffer + _blockPos, bytesPerChunk - _blockPos);
802 		size -= bytesPerChunk - _blockPos;
803 		_blockPos = 0;
804 
805 		for (uint32 i = _blockUsed; i < _interleave / 2; i++)
806 			for (uint32 j = 0; j < _channels; j++)
807 				*ptr++ = READ_UINT16(_blockBuffer + i * 2 + j * _interleave);
808 
809 		_blockUsed = 0;
810 	}
811 
812 	// Then fallback on loading any leftover
813 	if (size > 0) {
814 		packet->read(_blockBuffer, size);
815 		_blockPos = size;
816 
817 		if (size > (_channels - 1) * _interleave) {
818 			_blockUsed = (size - (_channels - 1) * _interleave) / 2;
819 
820 			for (uint32 i = 0; i < _blockUsed; i++)
821 				for (uint32 j = 0; j < _channels; j++)
822 					*ptr++ = READ_UINT16(_blockBuffer + i * 2 + j * _interleave);
823 		}
824 	}
825 
826 	_audStream->queuePacket(new Common::MemoryReadStream(buffer, sampleCount * 2, DisposeAfterUse::YES));
827 
828 	delete packet;
829 	return true;
830 }
831 
getAudioStream() const832 Audio::AudioStream *MPEGPSDecoder::PS2AudioTrack::getAudioStream() const {
833 	return _audStream;
834 }
835 
calculateSampleCount(uint32 packetSize) const836 uint32 MPEGPSDecoder::PS2AudioTrack::calculateSampleCount(uint32 packetSize) const {
837 	uint32 bytesPerChunk = _interleave * _channels, result = 0;
838 
839 	// If we have a partial block, subtract the remainder from the size. That
840 	// gets put towards reading the partial block
841 	if (_blockPos != 0) {
842 		packetSize -= bytesPerChunk - _blockPos;
843 		result += (_interleave / 2) - _blockUsed;
844 	}
845 
846 	// Round the number of whole chunks down and then calculate how many samples that gives us
847 	result += (packetSize / bytesPerChunk) * _interleave / 2;
848 
849 	// Total up anything we can get from the remainder
850 	packetSize %= bytesPerChunk;
851 	if (packetSize > (_channels - 1) * _interleave)
852 		result += (packetSize - (_channels - 1) * _interleave) / 2;
853 
854 	return result * _channels;
855 }
856 } // End of namespace Video
857