diff options
-rw-r--r-- | video/video_decoder.cpp | 40 | ||||
-rw-r--r-- | video/video_decoder.h | 29 |
2 files changed, 66 insertions, 3 deletions
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp index a8cf32575a..285290da6e 100644 --- a/video/video_decoder.cpp +++ b/video/video_decoder.cpp @@ -328,7 +328,21 @@ void AdvancedVideoDecoder::stop() { } Audio::Timestamp AdvancedVideoDecoder::getDuration() const { - return Audio::Timestamp(0, 1000); + Audio::Timestamp maxDuration(0, 1000); + + for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++) { + Audio::Timestamp startTime = (*it)->getStartTime(); + Audio::Timestamp duration = (*it)->getDuration(); + + if (duration.totalNumberOfFrames() != 0) { + // HACK: Timestamp's + operator doesn't do framerate conversion :( + duration = duration + startTime.convertToFramerate(duration.framerate()); + if (duration > maxDuration) + maxDuration = duration; + } + } + + return maxDuration; } void AdvancedVideoDecoder::pauseVideoIntern(bool pause) { @@ -359,7 +373,15 @@ bool AdvancedVideoDecoder::Track::isRewindable() const { } bool AdvancedVideoDecoder::Track::rewind() { - return seek(Audio::Timestamp(0, 1000)); + return seek(getStartTime()); +} + +Audio::Timestamp AdvancedVideoDecoder::Track::getStartTime() const { + return Audio::Timestamp(0, 1000); +} + +Audio::Timestamp AdvancedVideoDecoder::Track::getDuration() const { + return Audio::Timestamp(0, 1000); } uint32 AdvancedVideoDecoder::FixedRateVideoTrack::getNextFrameStartTime() const { @@ -375,6 +397,14 @@ bool AdvancedVideoDecoder::FixedLengthVideoTrack::endOfTrack() const { return getCurFrame() >= (getFrameCount() - 1); } +Audio::Timestamp AdvancedVideoDecoder::FixedDurationVideoTrack::getDuration() const { + // Since Audio::Timestamp doesn't support a fractional frame rate, we're currently + // just converting to milliseconds. + Common::Rational time = getFrameCount() * 1000; + time /= getFrameRate(); + return time.toInt(); +} + bool AdvancedVideoDecoder::AudioTrack::endOfTrack() const { Audio::AudioStream *stream = getAudioStream(); return !stream || (!g_system->getMixer()->isSoundHandleActive(_handle) && stream->endOfData()); @@ -433,6 +463,12 @@ bool AdvancedVideoDecoder::RewindableAudioTrack::rewind() { return stream->rewind(); } +Audio::Timestamp AdvancedVideoDecoder::SeekableAudioTrack::getDuration() const { + Audio::SeekableAudioStream *stream = getSeekableAudioStream(); + assert(stream); + return stream->getLength(); +} + Audio::AudioStream *AdvancedVideoDecoder::SeekableAudioTrack::getAudioStream() const { return getSeekableAudioStream(); } diff --git a/video/video_decoder.h b/video/video_decoder.h index ede2872c6a..87d832eeb9 100644 --- a/video/video_decoder.h +++ b/video/video_decoder.h @@ -423,7 +423,7 @@ protected: /** * Seek to the given time. - * @param time The time to seek to. + * @param time The time to seek to, from the beginning of the video. * @return true on success, false otherwise. */ virtual bool seek(const Audio::Timestamp &time) { return false; } @@ -448,6 +448,19 @@ protected: */ bool isPaused() const { return _paused; } + /** + * Get the start time of the track (starting from the beginning of the + * movie). + */ + virtual Audio::Timestamp getStartTime() const; + + /** + * Get the duration of the track (starting from this track's start time). + * + * By default, this returns 0 for unknown. + */ + virtual Audio::Timestamp getDuration() const; + protected: /** * Function called by pause() for subclasses to implement. @@ -510,6 +523,18 @@ protected: }; /** + * A FixedRateVideoTrack and FixedLengthVideoTrack that implements the getDuration() + * function. + */ + class FixedDurationVideoTrack : public FixedRateVideoTrack, public FixedLengthVideoTrack { + public: + FixedDurationVideoTrack() {} + virtual ~FixedDurationVideoTrack() {} + + virtual Audio::Timestamp getDuration() const; + }; + + /** * An abstract representation of an audio track. */ class AudioTrack : public Track { @@ -575,6 +600,8 @@ protected: bool isSeekable() const { return true; } bool seek(const Audio::Timestamp &time); + Audio::Timestamp getDuration() const; + protected: Audio::AudioStream *getAudioStream() const; |