aboutsummaryrefslogtreecommitdiff
path: root/video/video_decoder.cpp
diff options
context:
space:
mode:
authorMatthew Hoops2012-08-12 00:09:23 -0400
committerMatthew Hoops2012-08-12 00:09:23 -0400
commita458b91e7e4a1774d8dea1fe75966d834f43ee7b (patch)
treef62fa117e6baaef711f4d9054efcdc843ee5f593 /video/video_decoder.cpp
parent813689d68cd055935eaa12f614608d1237866b83 (diff)
downloadscummvm-rg350-a458b91e7e4a1774d8dea1fe75966d834f43ee7b.tar.gz
scummvm-rg350-a458b91e7e4a1774d8dea1fe75966d834f43ee7b.tar.bz2
scummvm-rg350-a458b91e7e4a1774d8dea1fe75966d834f43ee7b.zip
VIDEO: Add set/getStopTime functions to AdvancedVideoDecoder
A video can now be stopped at a requested time
Diffstat (limited to 'video/video_decoder.cpp')
-rw-r--r--video/video_decoder.cpp76
1 files changed, 72 insertions, 4 deletions
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index 44b05c4345..b27a0c512b 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -103,6 +103,8 @@ AdvancedVideoDecoder::AdvancedVideoDecoder() {
_pauseLevel = 0;
_needsUpdate = false;
_lastTimeChange = 0;
+ _stopTime = 0;
+ _stopTimeSet = false;
// Find the best format for output
_defaultHighColorFormat = g_system->getScreenFormat();
@@ -128,6 +130,8 @@ void AdvancedVideoDecoder::close() {
_pauseLevel = 0;
_needsUpdate = false;
_lastTimeChange = 0;
+ _stopTime = 0;
+ _stopTimeSet = false;
}
bool AdvancedVideoDecoder::isVideoLoaded() const {
@@ -247,6 +251,13 @@ bool AdvancedVideoDecoder::endOfVideo() const {
if (!isVideoLoaded())
return true;
+ if (_stopTimeSet) {
+ const VideoTrack *track = findNextVideoTrack();
+
+ if (track && track->getNextFrameStartTime() >= (uint)_stopTime.msecs())
+ return true;
+ }
+
for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
if (!(*it)->endOfTrack())
return false;
@@ -314,12 +325,15 @@ bool AdvancedVideoDecoder::seek(const Audio::Timestamp &time) {
if (!(*it)->seek(time))
return false;
+ _lastTimeChange = time;
+
// Now that we've seeked, start all tracks again
- if (isPlaying())
+ // Also reset our start time
+ if (isPlaying()) {
startAudio();
+ _startTime = g_system->getMillis() - time.msecs();
+ }
- _lastTimeChange = time;
- _startTime = g_system->getMillis() - time.msecs();
resetPauseStartTime();
_needsUpdate = true;
return true;
@@ -331,7 +345,10 @@ void AdvancedVideoDecoder::start() {
_isPlaying = true;
_startTime = g_system->getMillis();
- _lastTimeChange = 0;
+
+ // Adjust start time if we've seeked to something besides zero time
+ if (_lastTimeChange.totalNumberOfFrames() != 0)
+ _startTime -= _lastTimeChange.msecs();
// If someone previously called stop(), we'll rewind it.
if (_needsRewind)
@@ -471,6 +488,21 @@ void AdvancedVideoDecoder::AudioTrack::stop() {
g_system->getMixer()->stopHandle(_handle);
}
+void AdvancedVideoDecoder::AudioTrack::start(const Audio::Timestamp &limit) {
+ stop();
+
+ Audio::AudioStream *stream = getAudioStream();
+ assert(stream);
+
+ stream = Audio::makeLimitingAudioStream(stream, limit, DisposeAfterUse::NO);
+
+ g_system->getMixer()->playStream(getSoundType(), &_handle, stream, -1, getVolume(), getBalance(), DisposeAfterUse::YES);
+
+ // Pause the audio again if we're still paused
+ if (isPaused())
+ g_system->getMixer()->pauseHandle(_handle, true);
+}
+
uint32 AdvancedVideoDecoder::AudioTrack::getRunningTime() const {
if (g_system->getMixer()->isSoundHandleActive(_handle))
return g_system->getMixer()->getSoundElapsedTime(_handle);
@@ -553,6 +585,29 @@ bool AdvancedVideoDecoder::addStreamFileTrack(const Common::String &baseName) {
return result;
}
+void AdvancedVideoDecoder::setStopTime(const Audio::Timestamp &stopTime) {
+ Audio::Timestamp startTime = 0;
+
+ if (isPlaying()) {
+ startTime = getTime();
+ stopAudio();
+ }
+
+ _stopTime = stopTime;
+ _stopTimeSet = true;
+
+ if (startTime > stopTime)
+ return;
+
+ if (isPlaying()) {
+ // We'll assume the audio track is going to start up at the same time it just was
+ // and therefore not do any seeking.
+ // Might want to set it anyway if we're seekable.
+ startAudioLimit(_stopTime.msecs() - startTime.msecs());
+ _lastTimeChange = startTime;
+ }
+}
+
AdvancedVideoDecoder::Track *AdvancedVideoDecoder::getTrack(uint track) {
if (track > _tracks.size())
return 0;
@@ -614,6 +669,13 @@ const AdvancedVideoDecoder::VideoTrack *AdvancedVideoDecoder::findNextVideoTrack
}
void AdvancedVideoDecoder::startAudio() {
+ if (_stopTimeSet) {
+ // HACK: Timestamp's subtraction asserts out when subtracting two times
+ // with different rates.
+ startAudioLimit(_stopTime - _lastTimeChange.convertToFramerate(_stopTime.framerate()));
+ return;
+ }
+
for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
if ((*it)->getTrackType() == Track::kTrackTypeAudio)
((AudioTrack *)*it)->start();
@@ -625,6 +687,12 @@ void AdvancedVideoDecoder::stopAudio() {
((AudioTrack *)*it)->stop();
}
+void AdvancedVideoDecoder::startAudioLimit(const Audio::Timestamp &limit) {
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeAudio)
+ ((AudioTrack *)*it)->start(limit);
+}
+
//////////////////////////////////////////////
///////////////// DEPRECATED /////////////////
//////////////////////////////////////////////