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