aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2010-08-31 18:37:59 +0000
committerEugene Sandulenko2010-10-12 23:22:24 +0000
commitf06db87a0ee0323ceb5a1e946fa9ed1f8576abca (patch)
tree0470e0049d6c5248251cbc098863f4c5d12a3666
parent384468c0148ede9ae8140b4fd75183368d26ada6 (diff)
downloadscummvm-rg350-f06db87a0ee0323ceb5a1e946fa9ed1f8576abca.tar.gz
scummvm-rg350-f06db87a0ee0323ceb5a1e946fa9ed1f8576abca.tar.bz2
scummvm-rg350-f06db87a0ee0323ceb5a1e946fa9ed1f8576abca.zip
SWORD25: Implement playback. Blitting is TODO.
svn-id: r53298
-rw-r--r--engines/sword25/fmv/movieplayer.cpp20
-rw-r--r--engines/sword25/fmv/theora_decoder.cpp58
-rw-r--r--engines/sword25/fmv/theora_decoder.h12
3 files changed, 81 insertions, 9 deletions
diff --git a/engines/sword25/fmv/movieplayer.cpp b/engines/sword25/fmv/movieplayer.cpp
index 3114d68bdc..e4b417adc5 100644
--- a/engines/sword25/fmv/movieplayer.cpp
+++ b/engines/sword25/fmv/movieplayer.cpp
@@ -54,7 +54,7 @@ MoviePlayer::MoviePlayer(Kernel *pKernel) : Service(pKernel) {
_decoder = new TheoraDecoder();
}
-bool MoviePlayer::LoadMovie(const Common::String &filename, unsigned int Z) {
+bool MoviePlayer::LoadMovie(const Common::String &filename, unsigned int z) {
Common::SeekableReadStream *in = Kernel::GetInstance()->GetPackage()->GetStream(filename);
if (!in) {
@@ -62,11 +62,15 @@ bool MoviePlayer::LoadMovie(const Common::String &filename, unsigned int Z) {
return false;
}
+ debug(2, "LoadMovie(%s, %d)", filename.c_str(), z);
+
if (!_decoder->load(in)) {
BS_LOG_ERRORLN("Could not load movie file \"%s\".", filename.c_str());
return false;
}
+ warning("STUB: MoviePlayer::LoadMovie(). Z is not handled");
+
return true;
}
@@ -77,22 +81,30 @@ bool MoviePlayer::UnloadMovie() {
}
bool MoviePlayer::Play() {
+ _decoder->pauseVideo(false);
+
return true;
}
bool MoviePlayer::Pause() {
+ _decoder->pauseVideo(true);
+
return true;
}
void MoviePlayer::Update() {
+ if (!_decoder->isVideoLoaded())
+ return;
+
+ Graphics::Surface *surface = _decoder->decodeNextFrame();
}
bool MoviePlayer::IsMovieLoaded() {
- return true;
+ return _decoder->isVideoLoaded();
}
bool MoviePlayer::IsPaused() {
- return true;
+ return _decoder->isPaused();
}
float MoviePlayer::GetScaleFactor() {
@@ -103,7 +115,7 @@ void MoviePlayer::SetScaleFactor(float ScaleFactor) {
}
double MoviePlayer::GetTime() {
- return 1.0;
+ return (double)_decoder->getElapsedTime() / 1000.0;
}
diff --git a/engines/sword25/fmv/theora_decoder.cpp b/engines/sword25/fmv/theora_decoder.cpp
index 31458a2deb..bcd77ca880 100644
--- a/engines/sword25/fmv/theora_decoder.cpp
+++ b/engines/sword25/fmv/theora_decoder.cpp
@@ -60,11 +60,21 @@ TheoraDecoder::TheoraDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundT
_soundType = soundType;
_audStream = 0;
_audHandle = new Audio::SoundHandle();
+
+ _theoraDecode = 0;
+ _theoraSetup = 0;
+
+ _curFrame = 0;
+
+ _audiobuf = (ogg_int16_t *)calloc(AUDIOFD_FRAGSIZE, sizeof(ogg_int16_t));
+
+ reset();
}
TheoraDecoder::~TheoraDecoder() {
close();
delete _audHandle;
+ free(_audiobuf);
}
void TheoraDecoder::queuePage(ogg_page *page) {
@@ -81,7 +91,7 @@ int TheoraDecoder::bufferData() {
ogg_sync_wrote(&_oggSync, bytes);
- return(bytes);
+ return bytes;
}
bool TheoraDecoder::load(Common::SeekableReadStream *stream) {
@@ -209,6 +219,36 @@ bool TheoraDecoder::load(Common::SeekableReadStream *stream) {
debug(1, " Frame content is %dx%d with offset (%d,%d).",
_theoraInfo.frame_width, _theoraInfo.frame_height, _theoraInfo.pic_x, _theoraInfo.pic_y);
+ switch (_theoraInfo.colorspace){
+ case TH_CS_UNSPECIFIED:
+ /* nothing to report */
+ break;;
+ case TH_CS_ITU_REC_470M:
+ debug(1, " encoder specified ITU Rec 470M (NTSC) color.");
+ break;
+ case TH_CS_ITU_REC_470BG:
+ debug(1, " encoder specified ITU Rec 470BG (PAL) color.");
+ break;
+ default:
+ debug(1, "warning: encoder specified unknown colorspace (%d).", _theoraInfo.colorspace);
+ break;
+ }
+
+ debug(1, "Encoded by %s", _theoraComment.vendor);
+ if (_theoraComment.comments) {
+ debug(1, "theora comment header:");
+ for (int i = 0; i < _theoraComment.comments; i++) {
+ if (_theoraComment.user_comments[i]) {
+ int len = _theoraComment.comment_lengths[i];
+ char *value = (char *)malloc(len + 1);
+ memcpy(value, _theoraComment.user_comments[i], len);
+ value[len] = '\0';
+ debug(1, "\t%s", value);
+ free(value);
+ }
+ }
+ }
+
th_decode_ctl(_theoraDecode, TH_DECCTL_GET_PPLEVEL_MAX, &_ppLevelMax, sizeof(_ppLevelMax));
_ppLevel = _ppLevelMax;
th_decode_ctl(_theoraDecode, TH_DECCTL_SET_PPLEVEL, &_ppLevel, sizeof(_ppLevel));
@@ -220,7 +260,9 @@ bool TheoraDecoder::load(Common::SeekableReadStream *stream) {
th_comment_clear(&_theoraComment);
}
+
th_setup_free(_theoraSetup);
+ _theoraSetup = 0;
if (_vorbisPacket) {
vorbis_synthesis_init(&_vorbisDSP, &_vorbisInfo);
@@ -241,8 +283,7 @@ bool TheoraDecoder::load(Common::SeekableReadStream *stream) {
}
_surface = new Graphics::Surface();
-
- _surface->create(_theoraInfo.frame_width, _theoraInfo.frame_height, 3);
+ _surface->create(_theoraInfo.frame_width, _theoraInfo.frame_height, 4);
return true;
}
@@ -258,12 +299,15 @@ void TheoraDecoder::close() {
if (_mixer)
_mixer->stopHandle(*_audHandle);
_audStream = 0;
+ _vorbisPacket = 0;
}
if (_theoraPacket) {
ogg_stream_clear(&_theoraOut);
th_decode_free(_theoraDecode);
th_comment_clear(&_theoraComment);
th_info_clear(&_theoraInfo);
+ _theoraDecode = 0;
+ _theoraPacket = 0;
}
if (!_fileStream)
@@ -406,6 +450,7 @@ Graphics::Surface *TheoraDecoder::decodeNextFrame() {
void TheoraDecoder::reset() {
VideoDecoder::reset();
+
if (_fileStream)
_fileStream->seek(0);
@@ -416,8 +461,15 @@ void TheoraDecoder::reset() {
_audiobufFill = 0;
_audiobufReady = false;
_audiobufGranulePos = 0;
+
+ _curFrame = 0;
}
+bool TheoraDecoder::endOfVideo() const {
+ return !isVideoLoaded();
+}
+
+
uint32 TheoraDecoder::getElapsedTime() const {
if (_audStream && _mixer)
return _mixer->getSoundElapsedTime(*_audHandle);
diff --git a/engines/sword25/fmv/theora_decoder.h b/engines/sword25/fmv/theora_decoder.h
index 7faadfd9dc..3ce53e0900 100644
--- a/engines/sword25/fmv/theora_decoder.h
+++ b/engines/sword25/fmv/theora_decoder.h
@@ -68,6 +68,10 @@ public:
bool isVideoLoaded() const {
return _fileStream != 0;
}
+ bool isPaused() const {
+ return (VideoDecoder::isPaused() || !isVideoLoaded());
+ }
+
uint16 getWidth() const {
return _surface->w;
}
@@ -75,14 +79,18 @@ public:
return _surface->h;
}
uint32 getFrameCount() const {
- return _frameCount;
+ // It is not possible to get frame count easily
+ // I.e. seeking is required
+ assert(0);
}
Graphics::PixelFormat getPixelFormat() const {
- return Graphics::PixelFormat(3, 8, 8, 8, 0, 0, 0, 0, 0);
+ return Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
}
uint32 getElapsedTime() const;
+ bool endOfVideo() const;
+
protected:
Common::Rational getFrameRate() const {
return _frameRate;