VIDEO: Allow for audio track selection in video types that support it

This commit is contained in:
Matthew Hoops 2014-01-09 21:27:22 -05:00
parent 592526dc5d
commit da604b530b
2 changed files with 100 additions and 4 deletions

View File

@ -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;

View File

@ -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