From 92432a136bff7c327b5328cc10a84198f571b0d0 Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Mon, 13 Aug 2012 16:23:47 -0400 Subject: VIDEO: Convert TheoraDecoder to the new AdvancedVideoDecoder API --- video/theora_decoder.h | 129 +++++++++++++++++++++++++++---------------------- 1 file changed, 71 insertions(+), 58 deletions(-) (limited to 'video/theora_decoder.h') diff --git a/video/theora_decoder.h b/video/theora_decoder.h index 459fc064d3..2244f7550d 100644 --- a/video/theora_decoder.h +++ b/video/theora_decoder.h @@ -29,9 +29,7 @@ #include "common/rational.h" #include "video/video_decoder.h" -#include "audio/audiostream.h" #include "audio/mixer.h" -#include "graphics/pixelformat.h" #include "graphics/surface.h" #include @@ -41,6 +39,11 @@ namespace Common { class SeekableReadStream; } +namespace Audio { +class AudioStream; +class QueuingAudioStream; +} + namespace Video { /** @@ -49,7 +52,7 @@ namespace Video { * Video decoder used in engines: * - sword25 */ -class TheoraDecoder : public VideoDecoder { +class TheoraDecoder : public AdvancedVideoDecoder { public: TheoraDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kMusicSoundType); virtual ~TheoraDecoder(); @@ -60,81 +63,91 @@ public: */ bool loadStream(Common::SeekableReadStream *stream); void close(); - void reset(); - /** - * Decode the next frame and return the frame's surface - * @note the return surface should *not* be freed - * @note this may return 0, in which case the last frame should be kept on screen - */ - const Graphics::Surface *decodeNextFrame(); +protected: + void readNextPacket(); - bool isVideoLoaded() const { return _fileStream != 0; } - uint16 getWidth() const { return _displaySurface.w; } - uint16 getHeight() const { return _displaySurface.h; } +private: + class TheoraVideoTrack : public VideoTrack { + public: + TheoraVideoTrack(const Graphics::PixelFormat &format, th_info &theoraInfo, th_setup_info *theoraSetup); + ~TheoraVideoTrack(); - uint32 getFrameCount() const { - // It is not possible to get frame count easily - // I.e. seeking is required - assert(0); - return 0; - } + bool endOfTrack() const { return _endOfVideo; } + uint16 getWidth() const { return _displaySurface.w; } + uint16 getHeight() const { return _displaySurface.h; } + Graphics::PixelFormat getPixelFormat() const { return _displaySurface.format; } + int getCurFrame() const { return _curFrame; } + uint32 getNextFrameStartTime() const { return (uint32)(_nextFrameStartTime * 1000); } + const Graphics::Surface *decodeNextFrame() { return &_displaySurface; } - Graphics::PixelFormat getPixelFormat() const { return _displaySurface.format; } - uint32 getTime() const; - uint32 getTimeToNextFrame() const; + bool decodePacket(ogg_packet &oggPacket); + void setEndOfVideo() { _endOfVideo = true; } - bool endOfVideo() const; + private: + int _curFrame; + bool _endOfVideo; + Common::Rational _frameRate; + double _nextFrameStartTime; -protected: - // VideoDecoder API - void updateVolume(); - void updateBalance(); - void pauseVideoIntern(bool pause); + Graphics::Surface _surface; + Graphics::Surface _displaySurface; + + th_dec_ctx *_theoraDecode; + + void translateYUVtoRGBA(th_ycbcr_buffer &YUVBuffer); + }; + + class VorbisAudioTrack : public AudioTrack { + public: + VorbisAudioTrack(Audio::Mixer::SoundType soundType, vorbis_info &vorbisInfo); + ~VorbisAudioTrack(); + + Audio::Mixer::SoundType getSoundType() const { return _soundType; } + + bool decodeSamples(); + bool hasAudio() const; + bool needsAudio() const; + void synthesizePacket(ogg_packet &oggPacket); + void setEndOfAudio() { _endOfAudio = true; } + + protected: + Audio::AudioStream *getAudioStream() const; + + private: + // single audio fragment audio buffering + int _audioBufferFill; + ogg_int16_t *_audioBuffer; + + Audio::Mixer::SoundType _soundType; + Audio::QueuingAudioStream *_audStream; + + vorbis_block _vorbisBlock; + vorbis_dsp_state _vorbisDSP; + + bool _endOfAudio; + }; -private: void queuePage(ogg_page *page); - bool queueAudio(); int bufferData(); - void translateYUVtoRGBA(th_ycbcr_buffer &YUVBuffer); + bool queueAudio(); + void ensureAudioBufferSize(); Common::SeekableReadStream *_fileStream; - Graphics::Surface _surface; - Graphics::Surface _displaySurface; - Common::Rational _frameRate; - double _nextFrameStartTime; - bool _endOfVideo; - bool _endOfAudio; Audio::Mixer::SoundType _soundType; - Audio::SoundHandle *_audHandle; - Audio::QueuingAudioStream *_audStream; ogg_sync_state _oggSync; ogg_page _oggPage; ogg_packet _oggPacket; - ogg_stream_state _vorbisOut; - ogg_stream_state _theoraOut; - th_info _theoraInfo; - th_comment _theoraComment; - th_dec_ctx *_theoraDecode; - th_setup_info *_theoraSetup; - vorbis_info _vorbisInfo; - vorbis_dsp_state _vorbisDSP; - vorbis_block _vorbisBlock; - vorbis_comment _vorbisComment; - int _theoraPacket; - int _vorbisPacket; + ogg_stream_state _theoraOut, _vorbisOut; + bool _hasVideo, _hasAudio; - int _ppLevelMax; - int _ppLevel; - int _ppInc; + vorbis_info _vorbisInfo; - // single audio fragment audio buffering - int _audiobufFill; - bool _audiobufReady; - ogg_int16_t *_audiobuf; + TheoraVideoTrack *_videoTrack; + VorbisAudioTrack *_audioTrack; }; } // End of namespace Video -- cgit v1.2.3