diff options
| author | Matthew Hoops | 2014-01-09 21:27:22 -0500 | 
|---|---|---|
| committer | Matthew Hoops | 2014-01-11 18:43:41 -0500 | 
| commit | da604b530b37ad1908644e97b816ae34118bd7c1 (patch) | |
| tree | a7b025c71a36890c38ee213c3ed3334abf24d31b | |
| parent | 592526dc5d66b4249f8acd1d4b3ad3d7fa1854bf (diff) | |
| download | scummvm-rg350-da604b530b37ad1908644e97b816ae34118bd7c1.tar.gz scummvm-rg350-da604b530b37ad1908644e97b816ae34118bd7c1.tar.bz2 scummvm-rg350-da604b530b37ad1908644e97b816ae34118bd7c1.zip  | |
VIDEO: Allow for audio track selection in video types that support it
| -rw-r--r-- | video/video_decoder.cpp | 60 | ||||
| -rw-r--r-- | video/video_decoder.h | 44 | 
2 files changed, 100 insertions, 4 deletions
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp index 0ab1478727..931bde20d0 100644 --- a/video/video_decoder.cpp +++ b/video/video_decoder.cpp @@ -46,6 +46,7 @@ VideoDecoder::VideoDecoder() {  	_endTime = 0;  	_endTimeSet = false;  	_nextVideoTrack = 0; +	_mainAudioTrack = 0;  	// Find the best format for output  	_defaultHighColorFormat = g_system->getScreenFormat(); @@ -75,6 +76,7 @@ void VideoDecoder::close() {  	_endTime = 0;  	_endTimeSet = false;  	_nextVideoTrack = 0; +	_mainAudioTrack = 0;  }  bool VideoDecoder::loadFile(const Common::String &filename) { @@ -553,6 +555,9 @@ Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getDuration() const {  	return getFrameTime(getFrameCount());  } +VideoDecoder::AudioTrack::AudioTrack() : _volume(Audio::Mixer::kMaxChannelVolume), _balance(0), _muted(false) { +} +  bool VideoDecoder::AudioTrack::endOfTrack() const {  	Audio::AudioStream *stream = getAudioStream();  	return !stream || !g_system->getMixer()->isSoundHandleActive(_handle) || stream->endOfData(); @@ -562,7 +567,7 @@ void VideoDecoder::AudioTrack::setVolume(byte volume) {  	_volume = volume;  	if (g_system->getMixer()->isSoundHandleActive(_handle)) -		g_system->getMixer()->setChannelVolume(_handle, _volume); +		g_system->getMixer()->setChannelVolume(_handle, _muted ? 0 : _volume);  }  void VideoDecoder::AudioTrack::setBalance(int8 balance) { @@ -578,7 +583,7 @@ void VideoDecoder::AudioTrack::start() {  	Audio::AudioStream *stream = getAudioStream();  	assert(stream); -	g_system->getMixer()->playStream(getSoundType(), &_handle, stream, -1, getVolume(), getBalance(), DisposeAfterUse::NO); +	g_system->getMixer()->playStream(getSoundType(), &_handle, stream, -1, _muted ? 0 : getVolume(), getBalance(), DisposeAfterUse::NO);  	// Pause the audio again if we're still paused  	if (isPaused()) @@ -597,7 +602,7 @@ void VideoDecoder::AudioTrack::start(const Audio::Timestamp &limit) {  	stream = Audio::makeLimitingAudioStream(stream, limit, DisposeAfterUse::NO); -	g_system->getMixer()->playStream(getSoundType(), &_handle, stream, -1, getVolume(), getBalance(), DisposeAfterUse::YES); +	g_system->getMixer()->playStream(getSoundType(), &_handle, stream, -1, _muted ? 0 : getVolume(), getBalance(), DisposeAfterUse::YES);  	// Pause the audio again if we're still paused  	if (isPaused()) @@ -611,6 +616,16 @@ uint32 VideoDecoder::AudioTrack::getRunningTime() const {  	return 0;  } +void VideoDecoder::AudioTrack::setMute(bool mute) { +	// Update the mute settings, if required +	if (_muted != mute) { +		_muted = mute; + +		if (g_system->getMixer()->isSoundHandleActive(_handle)) +			g_system->getMixer()->setChannelVolume(_handle, mute ? 0 : _volume); +	} +} +  void VideoDecoder::AudioTrack::pauseIntern(bool shouldPause) {  	if (g_system->getMixer()->isSoundHandleActive(_handle))  		g_system->getMixer()->pauseHandle(_handle, shouldPause); @@ -669,6 +684,17 @@ void VideoDecoder::addTrack(Track *track, bool isExternal) {  		// Update volume settings if it's an audio track  		((AudioTrack *)track)->setVolume(_audioVolume);  		((AudioTrack *)track)->setBalance(_audioBalance); + +		if (!isExternal && supportsAudioTrackSwitching()) { +			if (_mainAudioTrack) { +				// The main audio track has already been found +				((AudioTrack *)track)->setMute(true); +			} else { +				// First audio track found -> now the main one +				_mainAudioTrack = (AudioTrack *)track; +				_mainAudioTrack->setMute(false); +			} +		}  	} else if (track->getTrackType() == Track::kTrackTypeVideo) {  		// If this track has a better time, update _nextVideoTrack  		if (!_nextVideoTrack || ((VideoTrack *)track)->getNextFrameStartTime() < _nextVideoTrack->getNextFrameStartTime()) @@ -701,6 +727,34 @@ bool VideoDecoder::addStreamFileTrack(const Common::String &baseName) {  	return result;  } +bool VideoDecoder::setAudioTrack(int index) { +	if (!supportsAudioTrackSwitching()) +		return false; + +	AudioTrack *audioTrack = getAudioTrack(index); + +	if (!audioTrack) +		return false; + +	if (_mainAudioTrack == audioTrack) +		return true; + +	_mainAudioTrack->setMute(true); +	audioTrack->setMute(false); +	_mainAudioTrack = audioTrack; +	return true; +} + +uint VideoDecoder::getAudioTrackCount() const { +	uint count = 0; + +	for (TrackList::const_iterator it = _internalTracks.begin(); it != _internalTracks.end(); it++) +		if ((*it)->getTrackType() == Track::kTrackTypeAudio) +			count++; + +	return count; +} +  void VideoDecoder::setEndTime(const Audio::Timestamp &endTime) {  	Audio::Timestamp startTime = 0; diff --git a/video/video_decoder.h b/video/video_decoder.h index ac6586d8dd..99161d6f97 100644 --- a/video/video_decoder.h +++ b/video/video_decoder.h @@ -407,6 +407,21 @@ public:  	 */  	bool addStreamFileTrack(const Common::String &baseName); +	/** +	 * Set the internal audio track. +	 * +	 * Has no effect if the container does not support this. +	 * @see supportsAudioTrackSwitching() +	 * +	 * @param index The index of the track, whose meaning is dependent on the container +	 */ +	bool setAudioTrack(int index); + +	/** +	 * Get the number of internal audio tracks. +	 */ +	uint getAudioTrackCount() const; +  protected:  	/**  	 * An abstract representation of a track in a movie. Since tracks here are designed @@ -612,7 +627,7 @@ protected:  	 */  	class AudioTrack : public Track {  	public: -		AudioTrack() {} +		AudioTrack();  		virtual ~AudioTrack() {}  		TrackType getTrackType() const { return kTrackTypeAudio; } @@ -662,6 +677,11 @@ protected:  		 */  		virtual Audio::Mixer::SoundType getSoundType() const { return Audio::Mixer::kPlainSoundType; } +		/** +		 * Mute the track +		 */ +		void setMute(bool mute); +  	protected:  		void pauseIntern(bool shouldPause); @@ -674,6 +694,7 @@ protected:  		Audio::SoundHandle _handle;  		byte _volume;  		int8 _balance; +		bool _muted;  	};  	/** @@ -833,6 +854,25 @@ protected:  	 */  	virtual bool seekIntern(const Audio::Timestamp &time); +	/** +	 * Does this video format support switching between audio tracks? +	 * +	 * Returning true implies this format supports multiple audio tracks, +	 * can switch tracks, and defaults to playing the first found audio +	 * track. +	 */ +	virtual bool supportsAudioTrackSwitching() const { return false; } + +	/** +	 * Get the audio track for the given index. +	 * +	 * This is used only if supportsAudioTrackSwitching() returns true. +	 * +	 * @param index The index of the track, whose meaning is dependent on the container +	 * @return The audio track for the index, or 0 if not found +	 */ +	virtual AudioTrack *getAudioTrack(int index) { return 0; } +  private:  	// Tracks owned by this VideoDecoder  	TrackList _tracks; @@ -865,6 +905,8 @@ private:  	uint32 _pauseStartTime;  	byte _audioVolume;  	int8 _audioBalance; + +	AudioTrack *_mainAudioTrack;  };  } // End of namespace Video  | 
