aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sword25/fmv/theora_decoder.cpp51
-rwxr-xr-xengines/sword25/fmv/theora_decoder.h18
2 files changed, 51 insertions, 18 deletions
diff --git a/engines/sword25/fmv/theora_decoder.cpp b/engines/sword25/fmv/theora_decoder.cpp
index 0a4de4e649..f0a4fd7eab 100644
--- a/engines/sword25/fmv/theora_decoder.cpp
+++ b/engines/sword25/fmv/theora_decoder.cpp
@@ -41,17 +41,22 @@
namespace Sword25 {
-TheoraDecoder::TheoraDecoder() {
+TheoraDecoder::TheoraDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) : _mixer(mixer) {
_fileStream = 0;
_surface = 0;
_theoraPacket = 0;
_vorbisPacket = 0;
- _stateFlag = 0;
+ _stateFlag = false;
+
+ _soundType = soundType;
+ _audStream = 0;
+ _audHandle = new Audio::SoundHandle();
}
TheoraDecoder::~TheoraDecoder() {
close();
+ delete _audHandle;
}
void TheoraDecoder::queuePage(ogg_page *page) {
@@ -102,7 +107,7 @@ bool TheoraDecoder::load(Common::SeekableReadStream &stream) {
if (!ogg_page_bos(&_oggPage)) {
// don't leak the page; get it into the appropriate stream
queuePage(&_oggPage);
- _stateFlag = 1;
+ _stateFlag = true;
break;
}
@@ -220,8 +225,11 @@ bool TheoraDecoder::load(Common::SeekableReadStream &stream) {
}
// open audio
- if (_vorbisPacket)
- open_audio();
+ if (_vorbisPacket) {
+ _audStream = createAudioStream();
+ if (_audStream)
+ _mixer->playStream(_soundType, _audHandle, _audStream);
+ }
return true;
}
@@ -233,6 +241,9 @@ void TheoraDecoder::close() {
vorbis_dsp_clear(&_vorbisDSP);
vorbis_comment_clear(&_vorbisComment);
vorbis_info_clear(&_vorbisInfo);
+
+ _mixer->stopHandle(*_audHandle);
+ _audStream = 0;
}
if (_theoraPacket) {
ogg_stream_clear(&_theoraOut);
@@ -258,7 +269,7 @@ void TheoraDecoder::close() {
Graphics::Surface *TheoraDecoder::decodeNextFrame() {
int i, j;
- _stateFlag = 0; // playback has not begun
+ _stateFlag = false; // playback has not begun
// we want a video and audio frame ready to go at all times. If
// we have to buffer incoming, buffer the compressed data (ie, let
@@ -281,7 +292,7 @@ Graphics::Surface *TheoraDecoder::decodeNextFrame() {
_audiobufFill += i * _vorbisInfo.channels * 2;
if (_audiobufFill == audiofd_fragsize)
- _audiobufReady = 1;
+ _audiobufReady = true;
if (_vorbisDSP.granulepos >= 0)
_audiobufGranulePos = _vorbisDSP.granulepos - ret + i;
@@ -327,7 +338,7 @@ Graphics::Surface *TheoraDecoder::decodeNextFrame() {
// with non-keyframe seeks.
if (_videobufTime >= get_time())
- _videobufReady = 1;
+ _videobufReady = true;
else {
// If we are too slow, reduce the pp level.
_ppInc = _ppLevel > 0 ? -1 : 0;
@@ -350,12 +361,13 @@ Graphics::Surface *TheoraDecoder::decodeNextFrame() {
}
// If playback has begun, top audio buffer off immediately.
- if (_stateFlag) audio_write_nonblocking();
+ if (_stateFlag)
+ audio_write_nonblocking();
// are we at or past time for this video frame?
if (_stateFlag && _videobufReady && _videobufTime <= get_time()) {
video_write();
- _videobufReady = 0;
+ _videobufReady = false;
}
if (_stateFlag &&
@@ -410,11 +422,11 @@ Graphics::Surface *TheoraDecoder::decodeNextFrame() {
// we can begin playback
if ((!_theoraPacket || _videobufReady) &&
(!_vorbisPacket || _audiobufReady))
- _stateFlag = 1;
+ _stateFlag = true;
// same if we've run out of input
if (_fileStream->eos())
- _stateFlag = 1;
+ _stateFlag = true;
}
void TheoraDecoder::reset() {
@@ -422,13 +434,24 @@ void TheoraDecoder::reset() {
if (_fileStream)
_fileStream->seek(0);
- _videobufReady = 0;
+ _videobufReady = false;
_videobufGranulePos = -1;
_videobufTime = 0;
_audiobufFill = 0;
- _audiobufReady = 0;
+ _audiobufReady = false;
_audiobufGranulePos = 0;
}
+uint32 TheoraDecoder::getElapsedTime() const {
+ if (_audStream)
+ return _mixer->getSoundElapsedTime(*_audHandle);
+
+ return VideoDecoder::getElapsedTime();
+}
+
+Audio::QueuingAudioStream *AviDecoder::createAudioStream() {
+ return Audio::makeQueuingAudioStream(_vorbisInfo.rate, _vorbisInfo.channels);
+}
+
} // End of namespace Sword25
diff --git a/engines/sword25/fmv/theora_decoder.h b/engines/sword25/fmv/theora_decoder.h
index cda1c8a6cb..cd526b6ba0 100755
--- a/engines/sword25/fmv/theora_decoder.h
+++ b/engines/sword25/fmv/theora_decoder.h
@@ -27,6 +27,8 @@
#define SWORD25_THEORADECODER_H
#include "graphics/video/video_decoder.h"
+#include "sound/audiostream.h"
+#include "sound/mixer.h"
#include <theora/theoradec.h>
#include <vorbis/codec.h>
@@ -45,7 +47,7 @@ namespace Sword25 {
*/
class TheoraDecoder : public Graphics::FixedRateVideoDecoder {
public:
- TheoraDecoder();
+ TheoraDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType);
virtual ~TheoraDecoder();
/**
@@ -68,6 +70,8 @@ public:
uint32 getFrameCount() const { return _frameCount; }
Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 0, 0, 0); }
+ uint32 getElapsedTime() const;
+
protected:
Common::Rational getFrameRate() const { return _frameRate; }
@@ -81,6 +85,12 @@ private:
Common::Rational _frameRate;
uint32 _frameCount;
+ Audio::Mixer *_mixer;
+ Audio::Mixer::SoundType _soundType;
+ Audio::SoundHandle *_audHandle;
+ Audio::QueuingAudioStream *_audStream;
+ Audio::QueuingAudioStream *createAudioStream();
+
ogg_sync_state _oggSync;
ogg_page _oggPage;
ogg_packet _oggPacket;
@@ -97,20 +107,20 @@ private:
int _theoraPacket;
int _vorbisPacket;
- int _stateFlag;
+ bool _stateFlag;
int _ppLevelMax;
int _ppLevel;
int _ppInc;
// single frame video buffering
- int _videobufReady;
+ bool _videobufReady;
ogg_int64_t _videobufGranulePos;
double _videobufTime;
// single audio fragment audio buffering
int _audiobufFill;
- int _audiobufReady;
+ bool _audiobufReady;
ogg_int16_t *_audiobuf;
ogg_int64_t _audiobufGranulePos; // time position of last sample
};