VIDEO: Small refactoring of the Bink Decoder

This allows subclassing the Bink decoder to add seeking support
This commit is contained in:
Bastien Bouclet 2012-01-05 09:53:06 +01:00
parent e72201c6cc
commit 1432011fdc
2 changed files with 36 additions and 25 deletions

View File

@ -113,7 +113,22 @@ BinkDecoder::BinkDecoder() {
}
_audioStream = 0;
_audioStarted = false;
}
void BinkDecoder::startAudio() {
if (_audioTrack < _audioTracks.size()) {
const AudioTrack &audio = _audioTracks[_audioTrack];
_audioStream = Audio::makeQueuingAudioStream(audio.outSampleRate, audio.outChannels == 2);
g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream);
} // else no audio
}
void BinkDecoder::stopAudio() {
if (_audioStream) {
g_system->getMixer()->stopHandle(_audioHandle);
_audioStream = 0;
}
}
BinkDecoder::~BinkDecoder() {
@ -123,13 +138,8 @@ BinkDecoder::~BinkDecoder() {
void BinkDecoder::close() {
reset();
if (_audioStream) {
// Stop audio
g_system->getMixer()->stopHandle(_audioHandle);
_audioStream = 0;
}
_audioStarted = false;
// Stop audio
stopAudio();
for (int i = 0; i < 4; i++) {
delete[] _curPlanes[i]; _curPlanes[i] = 0;
@ -173,7 +183,7 @@ void BinkDecoder::close() {
uint32 BinkDecoder::getElapsedTime() const {
if (_audioStream && g_system->getMixer()->isSoundHandleActive(_audioHandle))
return g_system->getMixer()->getSoundElapsedTime(_audioHandle);
return g_system->getMixer()->getSoundElapsedTime(_audioHandle) + _audioStartOffset;
return g_system->getMillis() - _startTime;
}
@ -241,11 +251,6 @@ const Graphics::Surface *BinkDecoder::decodeNextFrame() {
if (_curFrame == 0)
_startTime = g_system->getMillis();
if (!_audioStarted && _audioStream) {
_audioStarted = true;
g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream);
}
return &_surface;
}
@ -510,6 +515,11 @@ void BinkDecoder::mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *
}
bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
Graphics::PixelFormat format = g_system->getScreenFormat();
return loadStream(stream, format);
}
bool BinkDecoder::loadStream(Common::SeekableReadStream *stream, const Graphics::PixelFormat &format) {
close();
_id = stream->readUint32BE();
@ -589,7 +599,6 @@ bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
_hasAlpha = _videoFlags & kVideoFlagAlpha;
_swapPlanes = (_id == kBIKhID) || (_id == kBIKiID); // BIKh and BIKi swap the chroma planes
Graphics::PixelFormat format = g_system->getScreenFormat();
_surface.create(width, height, format);
// Give the planes a bit extra space
@ -618,11 +627,8 @@ bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
initBundles();
initHuffman();
if (_audioTrack < _audioTracks.size()) {
const AudioTrack &audio = _audioTracks[_audioTrack];
_audioStream = Audio::makeQueuingAudioStream(audio.outSampleRate, audio.outChannels == 2);
}
startAudio();
_audioStartOffset = 0;
return true;
}

View File

@ -76,7 +76,9 @@ public:
// FixedRateVideoDecoder
Common::Rational getFrameRate() const { return _frameRate; }
private:
// Bink specific
bool loadStream(Common::SeekableReadStream *stream, const Graphics::PixelFormat &format);
protected:
static const int kAudioChannelsMax = 2;
static const int kAudioBlockSizeMax = (kAudioChannelsMax << 11);
@ -221,15 +223,13 @@ private:
Audio::SoundHandle _audioHandle;
Audio::QueuingAudioStream *_audioStream;
bool _audioStarted;
int32 _audioStartOffset;
uint32 _videoFlags; ///< Video frame features.
bool _hasAlpha; ///< Do video frames have alpha?
bool _swapPlanes; ///< Are the planes ordered (A)YVU instead of (A)YUV?
uint32 _audioFrame;
Common::Array<AudioTrack> _audioTracks; ///< All audio tracks.
Common::Array<VideoFrame> _frames; ///< All video frames.
@ -259,7 +259,7 @@ private:
/** Decode an audio packet. */
void audioPacket(AudioTrack &audio);
/** Decode a video packet. */
void videoPacket(VideoFrame &video);
virtual void videoPacket(VideoFrame &video);
/** Decode a plane. */
void decodePlane(VideoFrame &video, int planeIdx, bool isChroma);
@ -327,6 +327,11 @@ private:
void IDCT(int16 *block);
void IDCTPut(DecodeContext &ctx, int16 *block);
void IDCTAdd(DecodeContext &ctx, int16 *block);
/** Start playing the audio track */
void startAudio();
/** Stop playing the audio track */
void stopAudio();
};
} // End of namespace Video