[Scummvm-cvs-logs] SF.net SVN: scummvm:[53213] scummvm/trunk/engines/sword25/fmv

sev at users.sourceforge.net sev at users.sourceforge.net
Wed Oct 13 00:25:19 CEST 2010


Revision: 53213
          http://scummvm.svn.sourceforge.net/scummvm/?rev=53213&view=rev
Author:   sev
Date:     2010-10-12 22:25:18 +0000 (Tue, 12 Oct 2010)

Log Message:
-----------
SWORD25: Finish preliminary implementation of Theora decoder

Modified Paths:
--------------
    scummvm/trunk/engines/sword25/fmv/theora_decoder.cpp
    scummvm/trunk/engines/sword25/fmv/theora_decoder.h

Modified: scummvm/trunk/engines/sword25/fmv/theora_decoder.cpp
===================================================================
--- scummvm/trunk/engines/sword25/fmv/theora_decoder.cpp	2010-10-12 22:24:58 UTC (rev 53212)
+++ scummvm/trunk/engines/sword25/fmv/theora_decoder.cpp	2010-10-12 22:25:18 UTC (rev 53213)
@@ -37,10 +37,14 @@
  */
 
 #include "sword25/fmv/theora_decoder.h"
+
 #include "common/system.h"
+#include "sound/decoders/raw.h"
 
 namespace Sword25 {
 
+#define AUDIOFD_FRAGSIZE 10240
+
 TheoraDecoder::TheoraDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) : _mixer(mixer) {
 	_fileStream = 0;
 	_surface = 0;
@@ -180,6 +184,7 @@
 		debugN(1, "Ogg logical stream %lx is Theora %dx%d %.02f fps",
 		       _theoraOut.serialno, _theoraInfo.pic_width, _theoraInfo.pic_height,
 		       (double)_theoraInfo.fps_numerator / _theoraInfo.fps_denominator);
+
 		switch (_theoraInfo.pixel_fmt) {
 		case TH_PF_420:
 			debug(1, " 4:2:0 video");
@@ -231,6 +236,10 @@
 			_mixer->playStream(_soundType, _audHandle, _audStream);
 	}
 
+	_surface = new Graphics::Surface();
+
+	_surface->create(_theoraInfo.frame_width, _theoraInfo.frame_height, 3);
+
 	return true;
 }
 
@@ -281,17 +290,17 @@
 		// if there's pending, decoded audio, grab it
 		if ((ret = vorbis_synthesis_pcmout(&_vorbisDSP, &pcm)) > 0) {
 			int count = _audiobufFill / 2;
-			int maxsamples = (audiofd_fragsize - _audiobufFill) / 2 / _vorbisInfo.channels;
+			int maxsamples = (AUDIOFD_FRAGSIZE - _audiobufFill) / 2 / _vorbisInfo.channels;
 			for (i = 0; i < ret && i < maxsamples; i++)
 				for (j = 0; j < _vorbisInfo.channels; j++) {
-					int val = CLIP(rint(pcm[j][i] * 32767.f), -32768, 32768);
+					int val = CLIP((int)rint(pcm[j][i] * 32767.f), -32768, 32768);
 					_audiobuf[count++] = val;
 				}
 
 			vorbis_synthesis_read(&_vorbisDSP, i);
 			_audiobufFill += i * _vorbisInfo.channels * 2;
 
-			if (_audiobufFill == audiofd_fragsize)
+			if (_audiobufFill == AUDIOFD_FRAGSIZE)
 				_audiobufReady = true;
 
 			if (_vorbisDSP.granulepos >= 0)
@@ -331,26 +340,16 @@
 				_videobufTime = th_granule_time(_theoraDecode, _videobufGranulePos);
 				_curFrame++;
 
-				// is it already too old to be useful?  This is only actually
-				// useful cosmetically after a SIGSTOP.  Note that we have to
-				// decode the frame even if we don't show it (for now) due to
-				// keyframing.  Soon enough libtheora will be able to deal
-				// with non-keyframe seeks. 
-
-				if (_videobufTime >= get_time())
-					_videobufReady = true;
-				else {
-					// If we are too slow, reduce the pp level.
-					_ppInc = _ppLevel > 0 ? -1 : 0;
-					dropped++;
-				}
+				_videobufReady = true;
 			}
 		} else
 			break;
 	}
 
-	if (!_videobufReady && !_audiobufReady && _fileStream->eos())
-		break;
+	if (!_videobufReady && !_audiobufReady && _fileStream->eos()) {
+		close();
+		return _surface;
+	}
 
 	if (!_videobufReady || !_audiobufReady) {
 		// no data yet for somebody.  Grab another page
@@ -361,61 +360,29 @@
 	}
 
 	// If playback has begun, top audio buffer off immediately.
-	if (_stateFlag)
-		audio_write_nonblocking();
+	if (_stateFlag) {
+		_audStream->queueBuffer((byte *)_audiobuf, AUDIOFD_FRAGSIZE, DisposeAfterUse::NO, Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_STEREO);
+	}
 
 	// are we at or past time for this video frame?
-	if (_stateFlag && _videobufReady && _videobufTime <= get_time()) {
-		video_write();
-		_videobufReady = false;
-	}
+	if (_stateFlag && _videobufReady) {
+		th_ycbcr_buffer yuv;
+	
+		th_decode_ycbcr_out(_theoraDecode, yuv);
 
-	if (_stateFlag &&
-		(_audiobufReady || !_vorbisPacket) &&
-		(_videobufReady || !_theoraPacket) &&
-		!got_sigint) {
-		// we have an audio frame ready (which means the audio buffer is
-		// full), it's not time to play video, so wait until one of the
-		// audio buffer is ready or it's near time to play video
-
-		// set up select wait on the audiobuffer and a timeout for video
-		struct timeval timeout;
-		fd_set writefs;
-		fd_set empty;
-		int n = 0;
-
-		FD_ZERO(&writefs);
-		FD_ZERO(&empty);
-		if (audiofd >= 0) {
-			FD_SET(audiofd, &writefs);
-			n = audiofd + 1;
+		// TODO: YUV->RGB
+		switch (_theoraInfo.pixel_fmt) {
+		case TH_PF_420:
+			break;
+		case TH_PF_422:
+			break;
+		case TH_PF_444:
+			break;
+		default:
+			break;
 		}
 
-		if (_theoraPacket) {
-			double tdiff;
-			long milliseconds;
-			tdiff = _videobufTime - get_time();
-
-			// If we have lots of extra time, increase the post-processing level.
-			if (tdiff > _theoraInfo.fps_denominator * 0.25 / _theoraInfo.fps_numerator) {
-				_ppInc = _ppLevel < _ppLevelMax ? 1 : 0;
-			} else if (tdiff < _theoraInfo.fps_denominator * 0.05 / _theoraInfo.fps_numerator) {
-				_ppInc = _ppLevel > 0 ? -1 : 0;
-			}
-			milliseconds = tdiff * 1000 - 5;
-			if (milliseconds > 500)
-				milliseconds = 500;
-			if (milliseconds > 0) {
-				timeout.tv_sec = milliseconds / 1000;
-				timeout.tv_usec = (milliseconds % 1000) * 1000;
-
-				n = select(n, &empty, &writefs, &empty, &timeout);
-				if (n)
-					audio_calibrate_timer(0);
-			}
-		} else {
-			select(n, &empty, &writefs, &empty, NULL);
-		}
+		_videobufReady = false;
 	}
 
 	// if our buffers either don't exist or are ready to go,
@@ -427,6 +394,8 @@
 	// same if we've run out of input
 	if (_fileStream->eos())
 		_stateFlag = true;
+
+	return _surface;
 }
 
 void TheoraDecoder::reset() {
@@ -450,7 +419,7 @@
 	return VideoDecoder::getElapsedTime();
 }
 
-Audio::QueuingAudioStream *AviDecoder::createAudioStream() {
+Audio::QueuingAudioStream *TheoraDecoder::createAudioStream() {
 	return Audio::makeQueuingAudioStream(_vorbisInfo.rate, _vorbisInfo.channels);
 }
 

Modified: scummvm/trunk/engines/sword25/fmv/theora_decoder.h
===================================================================
--- scummvm/trunk/engines/sword25/fmv/theora_decoder.h	2010-10-12 22:24:58 UTC (rev 53212)
+++ scummvm/trunk/engines/sword25/fmv/theora_decoder.h	2010-10-12 22:25:18 UTC (rev 53213)
@@ -56,6 +56,7 @@
 	 */
 	bool load(Common::SeekableReadStream &stream);
 	void close();
+	void reset();
 
 	/**
 	 * Decode the next frame and return the frame's surface
@@ -78,6 +79,7 @@
 private:
 	void queuePage(ogg_page *page);
 	int bufferData();
+	Audio::QueuingAudioStream *createAudioStream();
 
 private:
 	Common::SeekableReadStream *_fileStream;
@@ -89,7 +91,6 @@
 	Audio::Mixer::SoundType _soundType;
 	Audio::SoundHandle *_audHandle;
 	Audio::QueuingAudioStream *_audStream;
-	Audio::QueuingAudioStream *createAudioStream();
 
 	ogg_sync_state _oggSync;
 	ogg_page _oggPage;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list