aboutsummaryrefslogtreecommitdiff
path: root/audio/decoders/quicktime.cpp
diff options
context:
space:
mode:
authorMatthew Hoops2011-04-12 14:23:23 -0400
committerMatthew Hoops2011-04-12 14:23:23 -0400
commit08b70fa1a737f325a0114632b3cef8cbf028fd3a (patch)
tree560082302a0cef9b2d61e1053aa9d2e21b99e898 /audio/decoders/quicktime.cpp
parent4366f3632c1e89c026d8b28732e561062d168f82 (diff)
downloadscummvm-rg350-08b70fa1a737f325a0114632b3cef8cbf028fd3a.tar.gz
scummvm-rg350-08b70fa1a737f325a0114632b3cef8cbf028fd3a.tar.bz2
scummvm-rg350-08b70fa1a737f325a0114632b3cef8cbf028fd3a.zip
AUDIO: Fix QuickTime/MPEG-4 seeking
MPEG-4 seeking was broken while QuickTime seeking was extremely slow. All is fixed now
Diffstat (limited to 'audio/decoders/quicktime.cpp')
-rw-r--r--audio/decoders/quicktime.cpp58
1 files changed, 28 insertions, 30 deletions
diff --git a/audio/decoders/quicktime.cpp b/audio/decoders/quicktime.cpp
index 9b69012c7a..0888041cfc 100644
--- a/audio/decoders/quicktime.cpp
+++ b/audio/decoders/quicktime.cpp
@@ -226,6 +226,11 @@ uint32 QuickTimeAudioDecoder::getAudioChunkSampleCount(uint chunk) {
return sampleCount;
}
+bool QuickTimeAudioDecoder::isOldDemuxing() const {
+ assert(_audioStreamIndex >= 0);
+ return _streams[_audioStreamIndex]->stts_count == 1 && _streams[_audioStreamIndex]->stts_data[0].duration == 1;
+}
+
void QuickTimeAudioDecoder::queueNextAudioChunk() {
AudioSampleDesc *entry = (AudioSampleDesc *)_streams[_audioStreamIndex]->sampleDescs[0];
Common::MemoryWriteStreamDynamic *wStream = new Common::MemoryWriteStreamDynamic();
@@ -236,7 +241,7 @@ void QuickTimeAudioDecoder::queueNextAudioChunk() {
uint32 sampleCount = getAudioChunkSampleCount(_curAudioChunk);
assert(sampleCount);
- if (_streams[_audioStreamIndex]->stts_count == 1 && _streams[_audioStreamIndex]->stts_data[0].duration == 1) {
+ if (isOldDemuxing()) {
// Old-style audio demuxing
// Then calculate the right sizes
@@ -297,40 +302,32 @@ void QuickTimeAudioDecoder::setAudioStreamPos(const Timestamp &where) {
_audStream = Audio::makeQueuingAudioStream(entry->sampleRate, entry->channels == 2);
// First, we need to track down what audio sample we need
- Audio::Timestamp curAudioTime(0, _streams[_audioStreamIndex]->time_scale);
- uint sample = 0;
- bool done = false;
- for (int32 i = 0; i < _streams[_audioStreamIndex]->stts_count && !done; i++) {
- for (int32 j = 0; j < _streams[_audioStreamIndex]->stts_data[i].count; j++) {
- curAudioTime = curAudioTime.addFrames(_streams[_audioStreamIndex]->stts_data[i].duration);
-
- if (curAudioTime > where) {
- done = true;
- break;
- }
-
- sample++;
+ Audio::Timestamp curAudioTime = where;
+ curAudioTime.convertToFramerate(_streams[_audioStreamIndex]->time_scale);
+ uint32 sample = curAudioTime.totalNumberOfFrames() / entry->channels;
+ uint32 seekSample = sample;
+
+ if (!isOldDemuxing()) {
+ // We shouldn't have audio samples that are a different duration
+ // That would be quite bad!
+ if (_streams[_audioStreamIndex]->stts_count != 1) {
+ warning("Failed seeking");
+ return;
}
+
+ seekSample /= _streams[_audioStreamIndex]->stts_data[0].duration;
}
// Now to track down what chunk it's in
- _curAudioChunk = 0;
uint32 totalSamples = 0;
+ _curAudioChunk = 0;
for (uint32 i = 0; i < _streams[_audioStreamIndex]->chunk_count; i++, _curAudioChunk++) {
- int sampleToChunkIndex = -1;
+ uint32 chunkSampleCount = getAudioChunkSampleCount(i);
- for (uint32 j = 0; j < _streams[_audioStreamIndex]->sample_to_chunk_sz; j++)
- if (i >= _streams[_audioStreamIndex]->sample_to_chunk[j].first)
- sampleToChunkIndex = j;
-
- assert(sampleToChunkIndex >= 0);
-
- totalSamples += _streams[_audioStreamIndex]->sample_to_chunk[sampleToChunkIndex].count;
-
- if (sample < totalSamples) {
- totalSamples -= _streams[_audioStreamIndex]->sample_to_chunk[sampleToChunkIndex].count;
+ if (seekSample < totalSamples + chunkSampleCount)
break;
- }
+
+ totalSamples += chunkSampleCount;
}
// Reposition the audio stream
@@ -338,10 +335,11 @@ void QuickTimeAudioDecoder::setAudioStreamPos(const Timestamp &where) {
if (sample != totalSamples) {
// HACK: Skip a certain amount of samples from the stream
// (There's got to be a better way to do this!)
- int16 *tempBuffer = new int16[sample - totalSamples];
- _audStream->readBuffer(tempBuffer, sample - totalSamples);
+ int skipSamples = (sample - totalSamples) * ((AudioSampleDesc *)_streams[_audioStreamIndex]->sampleDescs[0])->channels;
+
+ int16 *tempBuffer = new int16[skipSamples];
+ _audStream->readBuffer(tempBuffer, skipSamples);
delete[] tempBuffer;
- debug(3, "Skipping %d audio samples", sample - totalSamples);
}
}