[Scummvm-cvs-logs] SF.net SVN: scummvm:[53894] scummvm/branches/branch-1-2-0/graphics/video/ smk_decoder.cpp
athrxx at users.sourceforge.net
athrxx at users.sourceforge.net
Thu Oct 28 00:50:13 CEST 2010
Revision: 53894
http://scummvm.svn.sourceforge.net/scummvm/?rev=53894&view=rev
Author: athrxx
Date: 2010-10-27 22:50:13 +0000 (Wed, 27 Oct 2010)
Log Message:
-----------
VIDEO: (backport) fix some evaluation order bugs in smacker decoder
These bugs would cause crashs in MSVC 2008/2010 release builds.
Modified Paths:
--------------
scummvm/branches/branch-1-2-0/graphics/video/smk_decoder.cpp
Modified: scummvm/branches/branch-1-2-0/graphics/video/smk_decoder.cpp
===================================================================
--- scummvm/branches/branch-1-2-0/graphics/video/smk_decoder.cpp 2010-10-27 22:41:08 UTC (rev 53893)
+++ scummvm/branches/branch-1-2-0/graphics/video/smk_decoder.cpp 2010-10-27 22:50:13 UTC (rev 53894)
@@ -252,9 +252,12 @@
_loBytes = new SmallHuffmanTree(_bs);
_hiBytes = new SmallHuffmanTree(_bs);
- _markers[0] = _bs.getBits8() | (_bs.getBits8() << 8);
- _markers[1] = _bs.getBits8() | (_bs.getBits8() << 8);
- _markers[2] = _bs.getBits8() | (_bs.getBits8() << 8);
+ _markers[0] = _bs.getBits8();
+ _markers[0] |= (_bs.getBits8() << 8);
+ _markers[1] = _bs.getBits8();
+ _markers[1] |= (_bs.getBits8() << 8);
+ _markers[2] = _bs.getBits8();
+ _markers[2] |= (_bs.getBits8() << 8);
_last[0] = _last[1] = _last[2] = 0xffffffff;
@@ -389,12 +392,13 @@
_frameCount = _fileStream->readUint32LE();
int32 frameRate = _fileStream->readSint32LE();
+ // framerate contains 2 digits after the comma, so 1497 is actually 14.97 fps
if (frameRate > 0)
_frameRate = Common::Rational(1000, frameRate);
else if (frameRate < 0)
_frameRate = Common::Rational(100000, -frameRate);
else
- _frameRate = 10;
+ _frameRate = 1000;
// Flags are determined by which bit is set, which can be one of the following:
// 0 - set to 1 if file contains a ring frame.
@@ -540,53 +544,18 @@
chunkSize = _fileStream->readUint32LE();
chunkSize -= 4; // subtract the first 4 bytes (chunk size)
- if (_header.audioInfo[i].compression != kCompressionNone) {
+ if (_header.audioInfo[i].compression == kCompressionNone) {
+ dataSizeUnpacked = chunkSize;
+ } else {
dataSizeUnpacked = _fileStream->readUint32LE();
chunkSize -= 4; // subtract the next 4 bytes (unpacked data size)
- } else {
- dataSizeUnpacked = 0;
}
- if (_header.audioInfo[i].hasAudio && chunkSize > 0 && i == 0) {
- // If it's track 0, play the audio data
- byte *soundBuffer = (byte *)malloc(chunkSize);
-
- _fileStream->read(soundBuffer, chunkSize);
-
- if (_header.audioInfo[i].compression == kCompressionRDFT || _header.audioInfo[i].compression == kCompressionDCT) {
- // TODO: Compressed audio (Bink RDFT/DCT encoded)
- free(soundBuffer);
- continue;
- } else if (_header.audioInfo[i].compression == kCompressionDPCM) {
- // Compressed audio (Huffman DPCM encoded)
- queueCompressedBuffer(soundBuffer, chunkSize, dataSizeUnpacked, i);
- free(soundBuffer);
- } else {
- // Uncompressed audio (PCM)
- byte flags = 0;
- if (_header.audioInfo[0].is16Bits)
- flags = flags | Audio::FLAG_16BITS;
- if (_header.audioInfo[0].isStereo)
- flags = flags | Audio::FLAG_STEREO;
-
- _audioStream->queueBuffer(soundBuffer, chunkSize, DisposeAfterUse::YES, flags);
- // The sound buffer will be deleted by QueuingAudioStream
- }
-
- if (!_audioStarted) {
- _mixer->playStream(_soundType, &_audioHandle, _audioStream, -1, 255);
- _audioStarted = true;
- }
- } else {
- // Ignore the rest of the audio tracks, if they exist
- // TODO: Are there any Smacker videos with more than one audio stream?
- // If yes, we should play the rest of the audio streams as well
- if (chunkSize > 0)
- _fileStream->skip(chunkSize);
- }
+ handleAudioTrack(i, chunkSize, dataSizeUnpacked);
}
uint32 frameSize = _frameSizes[_curFrame] & ~3;
+// uint32 remainder = _frameSizes[_curFrame] & 3;
if (_fileStream->pos() - startPos > frameSize)
error("Smacker actual frame size exceeds recorded frame size");
@@ -746,6 +715,46 @@
return _surface;
}
+void SmackerDecoder::handleAudioTrack(byte track, uint32 chunkSize, uint32 unpackedSize) {
+ if (_header.audioInfo[track].hasAudio && chunkSize > 0 && track == 0) {
+ // If it's track 0, play the audio data
+ byte *soundBuffer = (byte *)malloc(chunkSize);
+
+ _fileStream->read(soundBuffer, chunkSize);
+
+ if (_header.audioInfo[track].compression == kCompressionRDFT || _header.audioInfo[track].compression == kCompressionDCT) {
+ // TODO: Compressed audio (Bink RDFT/DCT encoded)
+ free(soundBuffer);
+ return;
+ } else if (_header.audioInfo[track].compression == kCompressionDPCM) {
+ // Compressed audio (Huffman DPCM encoded)
+ queueCompressedBuffer(soundBuffer, chunkSize, unpackedSize, track);
+ free(soundBuffer);
+ } else {
+ // Uncompressed audio (PCM)
+ byte flags = 0;
+ if (_header.audioInfo[track].is16Bits)
+ flags = flags | Audio::FLAG_16BITS;
+ if (_header.audioInfo[track].isStereo)
+ flags = flags | Audio::FLAG_STEREO;
+
+ _audioStream->queueBuffer(soundBuffer, chunkSize, DisposeAfterUse::YES, flags);
+ // The sound buffer will be deleted by QueuingAudioStream
+ }
+
+ if (!_audioStarted) {
+ _mixer->playStream(_soundType, &_audioHandle, _audioStream, -1, 255);
+ _audioStarted = true;
+ }
+ } else {
+ // Ignore the rest of the audio tracks, if they exist
+ // TODO: Are there any Smacker videos with more than one audio stream?
+ // If yes, we should play the rest of the audio streams as well
+ if (chunkSize > 0)
+ _fileStream->skip(chunkSize);
+ }
+}
+
void SmackerDecoder::queueCompressedBuffer(byte *buffer, uint32 bufferSize,
uint32 unpackedSize, int streamNum) {
@@ -774,14 +783,24 @@
int32 bases[2];
- if (isStereo)
- bases[1] = (!is16Bits) ? audioBS.getBits8() :
- ((int16) (((audioBS.getBits8() << 8) | audioBS.getBits8())));
+ if (isStereo) {
+ if (is16Bits) {
+ byte hi = audioBS.getBits8();
+ byte lo = audioBS.getBits8();
+ bases[1] = (int16) ((hi << 8) | lo);
+ } else {
+ bases[1] = audioBS.getBits8();
+ }
+ }
- bases[0] = (!is16Bits) ? audioBS.getBits8() :
- ((int16) (((audioBS.getBits8() << 8) | audioBS.getBits8())));
+ if (is16Bits) {
+ byte hi = audioBS.getBits8();
+ byte lo = audioBS.getBits8();
+ bases[0] = (int16) ((hi << 8) | lo);
+ } else {
+ bases[0] = audioBS.getBits8();
+ }
-
// The bases are the first samples, too
for (int i = 0; i < (isStereo ? 2 : 1); i++, curPointer += (is16Bits ? 2 : 1), curPos += (is16Bits ? 2 : 1)) {
if (is16Bits)
@@ -805,10 +824,11 @@
}
} else {
for (int k = 0; k < (isStereo ? 2 : 1); k++) {
- bases[k] += (int16) (audioTrees[k * 2]->getCode(audioBS) |
- (audioTrees[k * 2 + 1]->getCode(audioBS) << 8));
+ byte lo = audioTrees[k * 2]->getCode(audioBS);
+ byte hi = audioTrees[k * 2 + 1]->getCode(audioBS);
+ bases[k] += (int16) (lo | (hi << 8));
- WRITE_BE_UINT16(curPointer, CLIP<int32>(bases[k], -32768, 32767));
+ WRITE_BE_UINT16(curPointer, bases[k]);
curPointer += 2;
curPos += 2;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list