diff options
author | Matthew Hoops | 2010-12-16 01:49:29 +0000 |
---|---|---|
committer | Matthew Hoops | 2010-12-16 01:49:29 +0000 |
commit | 98a2bc8a9a59d3e77d0a6dd3baf526c63ac8feda (patch) | |
tree | 8e812057e70c359545d55332564768a220e38cbf /graphics/video | |
parent | 1ead0d8436cdea9fd6a54af6bf749297afa75a17 (diff) | |
download | scummvm-rg350-98a2bc8a9a59d3e77d0a6dd3baf526c63ac8feda.tar.gz scummvm-rg350-98a2bc8a9a59d3e77d0a6dd3baf526c63ac8feda.tar.bz2 scummvm-rg350-98a2bc8a9a59d3e77d0a6dd3baf526c63ac8feda.zip |
VIDEO: Remove the need to call updateAudioBuffer() externally for QuickTime
svn-id: r54929
Diffstat (limited to 'graphics/video')
-rw-r--r-- | graphics/video/qt_decoder.cpp | 39 | ||||
-rw-r--r-- | graphics/video/qt_decoder.h | 10 |
2 files changed, 37 insertions, 12 deletions
diff --git a/graphics/video/qt_decoder.cpp b/graphics/video/qt_decoder.cpp index e7c1c3cab1..b8dc4c3d11 100644 --- a/graphics/video/qt_decoder.cpp +++ b/graphics/video/qt_decoder.cpp @@ -226,6 +226,9 @@ const Surface *QuickTimeDecoder::decodeNextFrame() { _curFrame++; _nextFrameStartTime += getFrameDuration(); + // Update the audio while we're at it + updateAudioBuffer(); + // Get the next packet uint32 descId; Common::SeekableReadStream *frameData = getNextFramePacket(descId); @@ -1277,23 +1280,49 @@ Audio::AudioStream *QuickTimeDecoder::createAudioStream(Common::SeekableReadStre return NULL; } +uint32 QuickTimeDecoder::getAudioChunkSampleCount(uint chunk) { + if (_audioStreamIndex < 0) + return 0; + + uint32 sampleCount = 0; + + for (uint32 j = 0; j < _streams[_audioStreamIndex]->sample_to_chunk_sz; j++) + if (chunk >= (_streams[_audioStreamIndex]->sample_to_chunk[j].first - 1)) + sampleCount = _streams[_audioStreamIndex]->sample_to_chunk[j].count; + + return sampleCount; +} + void QuickTimeDecoder::updateAudioBuffer() { if (!_audStream) return; STSDEntry *entry = &_streams[_audioStreamIndex]->stsdEntries[0]; + // Calculate the amount of chunks we need in memory until the next frame + uint32 timeToNextFrame = getTimeToNextFrame(); + uint32 numberOfChunksNeeded = 0; + uint32 timeFilled = 0; + uint32 curAudioChunk = _curAudioChunk - _audStream->numQueuedStreams(); + + for (; timeFilled < timeToNextFrame && curAudioChunk < _streams[_audioStreamIndex]->chunk_count; numberOfChunksNeeded++, curAudioChunk++) { + uint32 sampleCount = getAudioChunkSampleCount(curAudioChunk); + assert(sampleCount); + + timeFilled += sampleCount * 1000 / entry->sampleRate; + } + + // Add a couple extra to ensure we don't underrun + numberOfChunksNeeded += 3; + // Keep three streams in buffer so that if/when the first two end, it goes right into the next - for (; _audStream->numQueuedStreams() < 3 && _curAudioChunk < _streams[_audioStreamIndex]->chunk_count; _curAudioChunk++) { + for (; _audStream->numQueuedStreams() < numberOfChunksNeeded && _curAudioChunk < _streams[_audioStreamIndex]->chunk_count; _curAudioChunk++) { Common::MemoryWriteStreamDynamic *wStream = new Common::MemoryWriteStreamDynamic(); _fd->seek(_streams[_audioStreamIndex]->chunk_offsets[_curAudioChunk]); // First, we have to get the sample count - uint32 sampleCount = 0; - for (uint32 j = 0; j < _streams[_audioStreamIndex]->sample_to_chunk_sz; j++) - if (_curAudioChunk >= (_streams[_audioStreamIndex]->sample_to_chunk[j].first - 1)) - sampleCount = _streams[_audioStreamIndex]->sample_to_chunk[j].count; + uint32 sampleCount = getAudioChunkSampleCount(_curAudioChunk); assert(sampleCount); // Then calculate the right sizes diff --git a/graphics/video/qt_decoder.h b/graphics/video/qt_decoder.h index 8c1ab0b27b..fcb75bb4f0 100644 --- a/graphics/video/qt_decoder.h +++ b/graphics/video/qt_decoder.h @@ -116,13 +116,7 @@ public: // RewindableVideoDecoder API void rewind(); - // TODO: This audio function need to be removed from the public and/or added to - // the VideoDecoder API directly. I plan on replacing this function with something - // that can figure out how much audio is needed instead of constantly keeping two - // chunks in memory. - void updateAudioBuffer(); - -protected: +private: // This is the file handle from which data is read from. It can be the actual file handle or a decompressed stream. Common::SeekableReadStream *_fd; @@ -245,6 +239,8 @@ protected: Audio::QueuingAudioStream *_audStream; void startAudio(); void stopAudio(); + void updateAudioBuffer(); + uint32 getAudioChunkSampleCount(uint chunk); int8 _audioStreamIndex; uint _curAudioChunk; Audio::SoundHandle _audHandle; |