[Scummvm-cvs-logs] scummvm master -> 5cf0bfaab97955fe4d41afc2d64f8226ba74b9b6

clone2727 clone2727 at gmail.com
Sat Nov 24 07:05:42 CET 2012


This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
db908fcdc4 VIDEO: Add support for playing videos at a modified speed
5cf0bfaab9 PEGASUS: Use the new VideoDecoder::setRate code


Commit: db908fcdc40b1b337c1e07ecdb76a326ace005ba
    https://github.com/scummvm/scummvm/commit/db908fcdc40b1b337c1e07ecdb76a326ace005ba
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2012-11-23T22:03:36-08:00

Commit Message:
VIDEO: Add support for playing videos at a modified speed

Currently this only works for positive (forward) playback, but will eventually work for negative (backward).

Changed paths:
    video/video_decoder.cpp
    video/video_decoder.h



diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index 110afa7..6c45cc5 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -37,7 +37,7 @@ VideoDecoder::VideoDecoder() {
 	_startTime = 0;
 	_dirtyPalette = false;
 	_palette = 0;
-	_isPlaying = false;
+	_playbackRate = 0;
 	_audioVolume = Audio::Mixer::kMaxChannelVolume;
 	_audioBalance = 0;
 	_pauseLevel = 0;
@@ -212,7 +212,7 @@ uint32 VideoDecoder::getTime() const {
 		return _lastTimeChange.msecs();
 
 	if (isPaused())
-		return _pauseStartTime - _startTime;
+		return (_playbackRate * (_pauseStartTime - _startTime)).toInt();
 
 	if (useAudioSync()) {
 		for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++) {
@@ -225,7 +225,7 @@ uint32 VideoDecoder::getTime() const {
 		}
 	}
 
-	return g_system->getMillis() - _startTime;
+	return (_playbackRate * (g_system->getMillis() - _startTime)).toInt();
 }
 
 uint32 VideoDecoder::getTimeToNextFrame() const {
@@ -325,17 +325,8 @@ bool VideoDecoder::seek(const Audio::Timestamp &time) {
 }
 
 void VideoDecoder::start() {
-	if (isPlaying() || !isVideoLoaded())
-		return;
-
-	_isPlaying = true;
-	_startTime = g_system->getMillis();
-
-	// Adjust start time if we've seeked to something besides zero time
-	if (_lastTimeChange.totalNumberOfFrames() != 0)
-		_startTime -= _lastTimeChange.msecs();
-
-	startAudio();
+	if (!isPlaying())
+		setRate(1);
 }
 
 void VideoDecoder::stop() {
@@ -346,12 +337,12 @@ void VideoDecoder::stop() {
 	stopAudio();
 
 	// Keep the time marked down in case we start up again
-	// We do this before _isPlaying is set so we don't get
+	// We do this before _playbackRate is set so we don't get
 	// _lastTimeChange returned, but before _pauseLevel is
 	// reset.
 	_lastTimeChange = getTime();
 
-	_isPlaying = false;
+	_playbackRate = 0;
 	_startTime = 0;
 	_palette = 0;
 	_dirtyPalette = false;
@@ -365,6 +356,46 @@ void VideoDecoder::stop() {
 		(*it)->pause(false);
 }
 
+void VideoDecoder::setRate(const Common::Rational &rate) {
+	if (!isVideoLoaded() || _playbackRate == rate)
+		return;
+
+	if (rate == 0) {
+		stop();
+		return;
+	} else if (rate != 1 && hasAudio()) {
+		warning("Cannot set custom rate in videos with audio");
+		return;
+	}
+
+	Common::Rational targetRate = rate;
+
+	if (rate < 0) {
+		// TODO: Implement support for this
+		warning("Cannot set custom rate to backwards");
+		targetRate = 1;
+
+		if (_playbackRate == targetRate)
+			return;
+	}
+
+	if (_playbackRate != 0)
+		_lastTimeChange = getTime();
+
+	_playbackRate = targetRate;
+	_startTime = g_system->getMillis();
+
+	// Adjust start time if we've seeked to something besides zero time
+	if (_lastTimeChange.totalNumberOfFrames() != 0)
+		_startTime -= (_lastTimeChange.msecs() / _playbackRate).toInt();
+
+	startAudio();
+}
+
+bool VideoDecoder::isPlaying() const {
+	return _playbackRate != 0;
+}
+
 Audio::Timestamp VideoDecoder::getDuration() const {
 	Audio::Timestamp maxDuration(0, 1000);
 
@@ -676,4 +707,12 @@ bool VideoDecoder::hasFramesLeft() const {
 	return false;
 }
 
+bool VideoDecoder::hasAudio() const {
+	for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
+		if ((*it)->getTrackType() == Track::kTrackTypeAudio)
+			return true;
+
+	return false;
+}
+
 } // End of namespace Video
diff --git a/video/video_decoder.h b/video/video_decoder.h
index 860caec..ca88696 100644
--- a/video/video_decoder.h
+++ b/video/video_decoder.h
@@ -26,6 +26,7 @@
 #include "audio/mixer.h"
 #include "audio/timestamp.h"	// TODO: Move this to common/ ?
 #include "common/array.h"
+#include "common/rational.h"
 #include "common/str.h"
 #include "graphics/pixelformat.h"
 
@@ -36,7 +37,6 @@ class SeekableAudioStream;
 }
 
 namespace Common {
-class Rational;
 class SeekableReadStream;
 }
 
@@ -100,7 +100,7 @@ public:
 	/////////////////////////////////////////
 
 	/**
-	 * Begin playback of the video.
+	 * Begin playback of the video at normal speed.
 	 *
 	 * @note This has no effect if the video is already playing.
 	 */
@@ -114,6 +114,26 @@ public:
 	void stop();
 
 	/**
+	 * Set the rate of playback.
+	 *
+	 * For instance, a rate of 0 would stop the video, while a rate of 1
+	 * would play the video normally. Passing 2 to this function would
+	 * play the video at twice the normal speed.
+	 *
+	 * @note This function does not work for non-0/1 rates on videos that
+	 * have audio tracks.
+	 *
+	 * @todo This currently does not implement backwards playback, but will
+	 * be implemented soon.
+	 */
+	void setRate(const Common::Rational &rate);
+
+	/**
+	 * Returns the rate at which the video is being played.
+	 */
+	Common::Rational getRate() const { return _playbackRate; }
+
+	/**
 	 * Returns if the video is currently playing or not.
 	 *
 	 * This is not equivalent to the inverse of endOfVideo(). A video keeps
@@ -121,7 +141,7 @@ public:
 	 * return true after calling start() and will continue to return true
 	 * until stop() (or close()) is called.
 	 */
-	bool isPlaying() const { return _isPlaying; }
+	bool isPlaying() const;
 
 	/**
 	 * Returns if a video is rewindable or not. The default implementation
@@ -367,11 +387,6 @@ public:
 	 */
 	bool addStreamFileTrack(const Common::String &baseName);
 
-
-	// Future API
-	//void setRate(const Common::Rational &rate);
-	//Common::Rational getRate() const;
-
 protected:
 	/**
 	 * An abstract representation of a track in a movie. Since tracks here are designed
@@ -764,9 +779,10 @@ private:
 	TrackList _tracks;
 
 	// Current playback status
-	bool _isPlaying, _needsUpdate;
+	bool _needsUpdate;
 	Audio::Timestamp _lastTimeChange, _endTime;
 	bool _endTimeSet;
+	Common::Rational _playbackRate;
 
 	// Palette settings from individual tracks
 	mutable bool _dirtyPalette;
@@ -780,6 +796,7 @@ private:
 	void startAudio();
 	void startAudioLimit(const Audio::Timestamp &limit);
 	bool hasFramesLeft() const;
+	bool hasAudio() const;
 
 	int32 _startTime;
 	uint32 _pauseLevel;


Commit: 5cf0bfaab97955fe4d41afc2d64f8226ba74b9b6
    https://github.com/scummvm/scummvm/commit/5cf0bfaab97955fe4d41afc2d64f8226ba74b9b6
Author: Matthew Hoops (clone2727 at gmail.com)
Date: 2012-11-23T22:04:13-08:00

Commit Message:
PEGASUS: Use the new VideoDecoder::setRate code

The filling station now plays at the proper speed

Changed paths:
    engines/pegasus/movie.cpp



diff --git a/engines/pegasus/movie.cpp b/engines/pegasus/movie.cpp
index 75c287c..59814a7 100644
--- a/engines/pegasus/movie.cpp
+++ b/engines/pegasus/movie.cpp
@@ -161,9 +161,10 @@ void Movie::setTime(const TimeValue time, const TimeScale scale) {
 }
 
 void Movie::setRate(const Common::Rational rate) {
-	if (rate != 1 && rate != 0) {
-		warning("Cannot set movie rate");
-		start();
+	if (_video) {
+		_video->setRate(rate);
+
+		TimeBase::setRate(_video->getRate());
 		return;
 	}
 






More information about the Scummvm-git-logs mailing list