diff options
Diffstat (limited to 'engines/sword25')
-rw-r--r-- | engines/sword25/fmv/theora_decoder.cpp | 51 | ||||
-rwxr-xr-x | engines/sword25/fmv/theora_decoder.h | 18 |
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 }; |