mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-31 07:53:36 +00:00
VIDEO: Allow for audio track selection in video types that support it
This commit is contained in:
parent
592526dc5d
commit
da604b530b
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user