diff options
author | Matthew Hoops | 2012-08-12 00:09:23 -0400 |
---|---|---|
committer | Matthew Hoops | 2012-08-12 00:09:23 -0400 |
commit | a458b91e7e4a1774d8dea1fe75966d834f43ee7b (patch) | |
tree | f62fa117e6baaef711f4d9054efcdc843ee5f593 | |
parent | 813689d68cd055935eaa12f614608d1237866b83 (diff) | |
download | scummvm-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
-rw-r--r-- | video/video_decoder.cpp | 76 | ||||
-rw-r--r-- | video/video_decoder.h | 22 |
2 files changed, 88 insertions, 10 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 ///////////////// ////////////////////////////////////////////// diff --git a/video/video_decoder.h b/video/video_decoder.h index 26078d5750..7e89caee40 100644 --- a/video/video_decoder.h +++ b/video/video_decoder.h @@ -379,14 +379,20 @@ public: */ void setDefaultHighColorFormat(const Graphics::PixelFormat &format) { _defaultHighColorFormat = format; } + /** + * Set the time for this video to stop at. At this time in the video, + * all audio will stop and endOfVideo() will return true. + */ + void setStopTime(const Audio::Timestamp &stopTime); + + /** + * Get the stop time of the video (if not set, zero) + */ + Audio::Timestamp getStopTime() const { return _stopTime; } + // Future API //void setRate(const Common::Rational &rate); //Common::Rational getRate() const; - //void setStartTime(const Audio::Timestamp &startTime); - //Audio::Timestamp getStartTime() const; - //void setStopTime(const Audio::Timestamp &stopTime); - //Audio::Timestamp getStopTime() const; - //void setSegment(const Audio::Timestamp &startTime, const Audio::Timestamp &stopTime); protected: // Old API @@ -579,6 +585,8 @@ protected: */ void stop(); + void start(const Audio::Timestamp &limit); + /** * Get the volume for this track */ @@ -773,7 +781,8 @@ private: // Current playback status bool _isPlaying, _needsRewind, _needsUpdate; - Audio::Timestamp _lastTimeChange; + Audio::Timestamp _lastTimeChange, _stopTime; + bool _stopTimeSet; // Palette settings from individual tracks mutable bool _dirtyPalette; @@ -785,6 +794,7 @@ private: // Internal helper functions void stopAudio(); void startAudio(); + void startAudioLimit(const Audio::Timestamp &limit); }; /** |