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 #ifndef VIDEO_MPEGPS_DECODER_H
24 #define VIDEO_MPEGPS_DECODER_H
25 
26 #include "common/hashmap.h"
27 #include "graphics/surface.h"
28 #include "video/video_decoder.h"
29 
30 namespace Audio {
31 class PacketizedAudioStream;
32 }
33 
34 namespace Common {
35 class SeekableReadStream;
36 }
37 
38 namespace Graphics {
39 struct PixelFormat;
40 }
41 
42 namespace Image {
43 class MPEGDecoder;
44 }
45 
46 namespace Video {
47 
48 /**
49  * Decoder for MPEG Program Stream videos.
50  * Video decoder used in engines:
51  *  - zvision
52  */
53 class MPEGPSDecoder : public VideoDecoder {
54 public:
55 	MPEGPSDecoder();
56 	virtual ~MPEGPSDecoder();
57 
58 	bool loadStream(Common::SeekableReadStream *stream);
59 	void close();
60 
61 protected:
62 	void readNextPacket();
useAudioSync()63 	bool useAudioSync() const { return false; }
64 
65 private:
66 	// Base class for handling MPEG streams
67 	class MPEGStream {
68 	public:
~MPEGStream()69 		virtual ~MPEGStream() {}
70 
71 		enum StreamType {
72 			kStreamTypeVideo,
73 			kStreamTypeAudio
74 		};
75 
76 		virtual bool sendPacket(Common::SeekableReadStream *firstPacket, uint32 pts, uint32 dts) = 0;
77 		virtual StreamType getStreamType() const = 0;
78 	};
79 
80 	// An MPEG 1/2 video track
81 	class MPEGVideoTrack : public VideoTrack, public MPEGStream {
82 	public:
83 		MPEGVideoTrack(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format);
84 		~MPEGVideoTrack();
85 
endOfTrack()86 		bool endOfTrack() const { return _endOfTrack; }
87 		uint16 getWidth() const;
88 		uint16 getHeight() const;
89 		Graphics::PixelFormat getPixelFormat() const;
getCurFrame()90 		int getCurFrame() const { return _curFrame; }
getNextFrameStartTime()91 		uint32 getNextFrameStartTime() const { return _nextFrameStartTime.msecs(); }
92 		const Graphics::Surface *decodeNextFrame();
93 
94 		bool sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts);
getStreamType()95 		StreamType getStreamType() const { return kStreamTypeVideo; }
96 
setEndOfTrack()97 		void setEndOfTrack() { _endOfTrack = true; }
98 
99 	private:
100 		bool _endOfTrack;
101 		int _curFrame;
102 		Audio::Timestamp _nextFrameStartTime;
103 		Graphics::Surface *_surface;
104 
105 		void findDimensions(Common::SeekableReadStream *firstPacket, const Graphics::PixelFormat &format);
106 
107 #ifdef USE_MPEG2
108 		Image::MPEGDecoder *_mpegDecoder;
109 #endif
110 	};
111 
112 #ifdef USE_MAD
113 	// An MPEG audio track
114 	class MPEGAudioTrack : public AudioTrack, public MPEGStream {
115 	public:
116 		MPEGAudioTrack(Common::SeekableReadStream &firstPacket, Audio::Mixer::SoundType soundType);
117 		~MPEGAudioTrack();
118 
119 		bool sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts);
getStreamType()120 		StreamType getStreamType() const { return kStreamTypeAudio; }
121 
122 	protected:
123 		Audio::AudioStream *getAudioStream() const;
124 
125 	private:
126 		Audio::PacketizedAudioStream *_audStream;
127 	};
128 #endif
129 // ResidualVM specific start
130 	class PS2AudioTrack : public AudioTrack, public MPEGStream {
131 	public:
132 		PS2AudioTrack(Common::SeekableReadStream *firstPacket, Audio::Mixer::SoundType soundType);
133 		~PS2AudioTrack();
134 
135 		bool sendPacket(Common::SeekableReadStream *packet, uint32 pts, uint32 dts);
getStreamType()136 		StreamType getStreamType() const { return kStreamTypeAudio; }
137 
138 	protected:
139 		Audio::AudioStream *getAudioStream() const;
140 
141 	private:
142 		Audio::PacketizedAudioStream *_audStream;
143 
144 		enum {
145 			PS2_PCM = 0x01,
146 			PS2_ADPCM = 0x10
147 		};
148 
149 		uint32 _channels;
150 		uint32 _soundType;
151 		uint32 _interleave;
152 		bool _isFirstPacket;
153 
154 		byte *_blockBuffer;
155 		uint32 _blockPos, _blockUsed;
156 
157 		uint32 calculateSampleCount(uint32 packetSize) const;
158 	};
159 // ResidualVM specific end
160 
161 	// The different types of private streams we can detect at the moment
162 	enum PrivateStreamType {
163 		kPrivateStreamUnknown,
164 		kPrivateStreamAC3,
165 		kPrivateStreamDTS,
166 		kPrivateStreamDVDPCM,
167 		kPrivateStreamPS2Audio
168 	};
169 
170 	PrivateStreamType detectPrivateStreamType(Common::SeekableReadStream *packet);
171 
172 	bool addFirstVideoTrack();
173 
174 	int readNextPacketHeader(int32 &startCode, uint32 &pts, uint32 &dts);
175 	int findNextStartCode(uint32 &size);
176 	uint32 readPTS(int c);
177 
178 	void parseProgramStreamMap(int length);
179 	byte _psmESType[256];
180 
181 	// A map from stream types to stream handlers
182 	typedef Common::HashMap<int, MPEGStream *> StreamMap;
183 	StreamMap _streamMap;
184 
185 	Common::SeekableReadStream *_stream;
186 };
187 
188 } // End of namespace Video
189 
190 #endif
191