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 "common/scummsys.h"	// for USE_THEORADEC
24 
25 #ifdef USE_THEORADEC
26 
27 #ifndef VIDEO_THEORA_DECODER_H
28 #define VIDEO_THEORA_DECODER_H
29 
30 #include "common/rational.h"
31 #include "video/video_decoder.h"
32 #include "audio/mixer.h"
33 #include "graphics/surface.h"
34 
35 #include <theora/theoradec.h>
36 
37 #ifdef USE_TREMOR
38 #include <tremor/ivorbiscodec.h>
39 #else
40 #include <vorbis/codec.h>
41 #endif
42 
43 namespace Common {
44 class SeekableReadStream;
45 }
46 
47 namespace Audio {
48 class AudioStream;
49 class QueuingAudioStream;
50 }
51 
52 namespace Video {
53 
54 /**
55  *
56  * Decoder for Theora videos.
57  * Video decoder used in engines:
58  *  - pegasus
59  *  - sword25
60  *  - wintermute
61  */
62 class TheoraDecoder : public VideoDecoder {
63 public:
64 	TheoraDecoder();
65 	virtual ~TheoraDecoder();
66 
67 	/**
68 	 * Load a video file
69 	 * @param stream  the stream to load
70 	 */
71 	bool loadStream(Common::SeekableReadStream *stream);
72 	void close();
73 
74 protected:
75 	void readNextPacket();
76 
77 private:
78 	class TheoraVideoTrack : public VideoTrack {
79 	public:
80 		TheoraVideoTrack(const Graphics::PixelFormat &format, th_info &theoraInfo, th_setup_info *theoraSetup);
81 		~TheoraVideoTrack();
82 
endOfTrack()83 		bool endOfTrack() const { return _endOfVideo; }
getWidth()84 		uint16 getWidth() const { return _displaySurface.w; }
getHeight()85 		uint16 getHeight() const { return _displaySurface.h; }
getPixelFormat()86 		Graphics::PixelFormat getPixelFormat() const { return _displaySurface.format; }
getCurFrame()87 		int getCurFrame() const { return _curFrame; }
getNextFrameStartTime()88 		uint32 getNextFrameStartTime() const { return (uint32)(_nextFrameStartTime * 1000); }
decodeNextFrame()89 		const Graphics::Surface *decodeNextFrame() { return &_displaySurface; }
90 
91 		bool decodePacket(ogg_packet &oggPacket);
setEndOfVideo()92 		void setEndOfVideo() { _endOfVideo = true; }
93 
94 	private:
95 		int _curFrame;
96 		bool _endOfVideo;
97 		Common::Rational _frameRate;
98 		double _nextFrameStartTime;
99 
100 		Graphics::Surface _surface;
101 		Graphics::Surface _displaySurface;
102 
103 		th_dec_ctx *_theoraDecode;
104 
105 		void translateYUVtoRGBA(th_ycbcr_buffer &YUVBuffer);
106 	};
107 
108 	class VorbisAudioTrack : public AudioTrack {
109 	public:
110 		VorbisAudioTrack(Audio::Mixer::SoundType soundType, vorbis_info &vorbisInfo);
111 		~VorbisAudioTrack();
112 
113 		bool decodeSamples();
114 		bool hasAudio() const;
115 		bool needsAudio() const;
116 		void synthesizePacket(ogg_packet &oggPacket);
setEndOfAudio()117 		void setEndOfAudio() { _endOfAudio = true; }
118 
119 	protected:
120 		Audio::AudioStream *getAudioStream() const;
121 
122 	private:
123 		// single audio fragment audio buffering
124 		int _audioBufferFill;
125 		ogg_int16_t *_audioBuffer;
126 
127 		Audio::QueuingAudioStream *_audStream;
128 
129 		vorbis_block _vorbisBlock;
130 		vorbis_dsp_state _vorbisDSP;
131 
132 		bool _endOfAudio;
133 	};
134 
135 	void queuePage(ogg_page *page);
136 	int bufferData();
137 	bool queueAudio();
138 	void ensureAudioBufferSize();
139 
140 	Common::SeekableReadStream *_fileStream;
141 
142 	ogg_sync_state _oggSync;
143 	ogg_page _oggPage;
144 	ogg_packet _oggPacket;
145 
146 	ogg_stream_state _theoraOut, _vorbisOut;
147 	bool _hasVideo, _hasAudio;
148 
149 	vorbis_info _vorbisInfo;
150 
151 	TheoraVideoTrack *_videoTrack;
152 	VorbisAudioTrack *_audioTrack;
153 };
154 
155 } // End of namespace Video
156 
157 #endif
158 
159 #endif
160