aboutsummaryrefslogtreecommitdiff
path: root/video
diff options
context:
space:
mode:
Diffstat (limited to 'video')
-rw-r--r--video/avi_decoder.cpp559
-rw-r--r--video/avi_decoder.h312
-rw-r--r--video/bink_decoder.cpp1022
-rw-r--r--video/bink_decoder.h419
-rw-r--r--video/codecs/qtrle.cpp135
-rw-r--r--video/codecs/qtrle.h3
-rw-r--r--video/codecs/rpza.cpp22
-rw-r--r--video/codecs/rpza.h3
-rw-r--r--video/codecs/svq1.cpp8
-rw-r--r--video/codecs/svq1_cb.h2900
-rw-r--r--video/coktel_decoder.cpp205
-rw-r--r--video/coktel_decoder.h124
-rw-r--r--video/dxa_decoder.cpp130
-rw-r--r--video/dxa_decoder.h102
-rw-r--r--video/flic_decoder.cpp302
-rw-r--r--video/flic_decoder.h101
-rw-r--r--video/module.mk5
-rw-r--r--video/psx_decoder.cpp248
-rw-r--r--video/psx_decoder.h107
-rw-r--r--video/qt_decoder.cpp638
-rw-r--r--video/qt_decoder.h179
-rw-r--r--video/smk_decoder.cpp388
-rw-r--r--video/smk_decoder.h118
-rw-r--r--video/theora_decoder.cpp487
-rw-r--r--video/theora_decoder.h157
-rw-r--r--video/video_decoder.cpp628
-rw-r--r--video/video_decoder.h708
27 files changed, 5927 insertions, 4083 deletions
diff --git a/video/avi_decoder.cpp b/video/avi_decoder.cpp
index 9685952304..0d51f5b130 100644
--- a/video/avi_decoder.cpp
+++ b/video/avi_decoder.cpp
@@ -42,106 +42,128 @@
namespace Video {
-/*
+#define UNKNOWN_HEADER(a) error("Unknown header found -- \'%s\'", tag2str(a))
+
+// IDs used throughout the AVI files
+// that will be handled by this player
+#define ID_RIFF MKTAG('R','I','F','F')
+#define ID_AVI MKTAG('A','V','I',' ')
+#define ID_LIST MKTAG('L','I','S','T')
+#define ID_HDRL MKTAG('h','d','r','l')
+#define ID_AVIH MKTAG('a','v','i','h')
+#define ID_STRL MKTAG('s','t','r','l')
+#define ID_STRH MKTAG('s','t','r','h')
+#define ID_VIDS MKTAG('v','i','d','s')
+#define ID_AUDS MKTAG('a','u','d','s')
+#define ID_MIDS MKTAG('m','i','d','s')
+#define ID_TXTS MKTAG('t','x','t','s')
+#define ID_JUNK MKTAG('J','U','N','K')
+#define ID_STRF MKTAG('s','t','r','f')
+#define ID_MOVI MKTAG('m','o','v','i')
+#define ID_REC MKTAG('r','e','c',' ')
+#define ID_VEDT MKTAG('v','e','d','t')
+#define ID_IDX1 MKTAG('i','d','x','1')
+#define ID_STRD MKTAG('s','t','r','d')
+#define ID_00AM MKTAG('0','0','A','M')
+//#define ID_INFO MKTAG('I','N','F','O')
+
+// Codec tags
+#define ID_RLE MKTAG('R','L','E',' ')
+#define ID_CRAM MKTAG('C','R','A','M')
+#define ID_MSVC MKTAG('m','s','v','c')
+#define ID_WHAM MKTAG('W','H','A','M')
+#define ID_CVID MKTAG('c','v','i','d')
+#define ID_IV32 MKTAG('i','v','3','2')
+#define ID_DUCK MKTAG('D','U','C','K')
+
static byte char2num(char c) {
- return (c >= 48 && c <= 57) ? c - 48 : 0;
+ c = tolower((byte)c);
+ return (c >= 'a' && c <= 'f') ? c - 'a' + 10 : c - '0';
}
-static byte getStreamNum(uint32 tag) {
- return char2num((char)(tag >> 24)) * 16 + char2num((char)(tag >> 16));
+static byte getStreamIndex(uint32 tag) {
+ return char2num((tag >> 24) & 0xFF) << 4 | char2num((tag >> 16) & 0xFF);
}
-*/
static uint16 getStreamType(uint32 tag) {
return tag & 0xffff;
}
-AviDecoder::AviDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) : _mixer(mixer) {
- _soundType = soundType;
-
- _videoCodec = NULL;
+AVIDecoder::AVIDecoder(Audio::Mixer::SoundType soundType) : _soundType(soundType) {
_decodedHeader = false;
- _audStream = NULL;
- _fileStream = NULL;
- _audHandle = new Audio::SoundHandle();
- _dirtyPalette = false;
- memset(_palette, 0, sizeof(_palette));
- memset(&_wvInfo, 0, sizeof(PCMWAVEFORMAT));
- memset(&_bmInfo, 0, sizeof(BITMAPINFOHEADER));
- memset(&_vidsHeader, 0, sizeof(AVIStreamHeader));
- memset(&_audsHeader, 0, sizeof(AVIStreamHeader));
- memset(&_ixInfo, 0, sizeof(AVIOLDINDEX));
+ _fileStream = 0;
+ memset(&_ixInfo, 0, sizeof(_ixInfo));
+ memset(&_header, 0, sizeof(_header));
}
-AviDecoder::~AviDecoder() {
+AVIDecoder::~AVIDecoder() {
close();
- delete _audHandle;
}
-void AviDecoder::runHandle(uint32 tag) {
- assert (_fileStream);
+void AVIDecoder::runHandle(uint32 tag) {
+ assert(_fileStream);
if (_fileStream->eos())
return;
- debug (3, "Decoding tag %s", tag2str(tag));
+ debug(3, "Decoding tag %s", tag2str(tag));
switch (tag) {
- case ID_RIFF:
- /*_filesize = */_fileStream->readUint32LE();
- if (_fileStream->readUint32BE() != ID_AVI)
- error("RIFF file is not an AVI video");
- break;
- case ID_LIST:
- handleList();
- break;
- case ID_AVIH:
- _header.size = _fileStream->readUint32LE();
- _header.microSecondsPerFrame = _fileStream->readUint32LE();
- _header.maxBytesPerSecond = _fileStream->readUint32LE();
- _header.padding = _fileStream->readUint32LE();
- _header.flags = _fileStream->readUint32LE();
- _header.totalFrames = _fileStream->readUint32LE();
- _header.initialFrames = _fileStream->readUint32LE();
- _header.streams = _fileStream->readUint32LE();
- _header.bufferSize = _fileStream->readUint32LE();
- _header.width = _fileStream->readUint32LE();
- _header.height = _fileStream->readUint32LE();
- //Ignore 16 bytes of reserved data
- _fileStream->skip(16);
- break;
- case ID_STRH:
- handleStreamHeader();
- break;
- case ID_STRD: // Extra stream info, safe to ignore
- case ID_VEDT: // Unknown, safe to ignore
- case ID_JUNK: // Alignment bytes, should be ignored
- {
- uint32 junkSize = _fileStream->readUint32LE();
- _fileStream->skip(junkSize + (junkSize & 1)); // Alignment
- } break;
- case ID_IDX1:
- _ixInfo.size = _fileStream->readUint32LE();
- _ixInfo.indices = new AVIOLDINDEX::Index[_ixInfo.size / 16];
- debug (0, "%d Indices", (_ixInfo.size / 16));
- for (uint32 i = 0; i < (_ixInfo.size / 16); i++) {
- _ixInfo.indices[i].id = _fileStream->readUint32BE();
- _ixInfo.indices[i].flags = _fileStream->readUint32LE();
- _ixInfo.indices[i].offset = _fileStream->readUint32LE();
- _ixInfo.indices[i].size = _fileStream->readUint32LE();
- debug (0, "Index %d == Tag \'%s\', Offset = %d, Size = %d", i, tag2str(_ixInfo.indices[i].id), _ixInfo.indices[i].offset, _ixInfo.indices[i].size);
- }
- break;
- default:
- error ("Unknown tag \'%s\' found", tag2str(tag));
+ case ID_RIFF:
+ /*_filesize = */_fileStream->readUint32LE();
+ if (_fileStream->readUint32BE() != ID_AVI)
+ error("RIFF file is not an AVI video");
+ break;
+ case ID_LIST:
+ handleList();
+ break;
+ case ID_AVIH:
+ _header.size = _fileStream->readUint32LE();
+ _header.microSecondsPerFrame = _fileStream->readUint32LE();
+ _header.maxBytesPerSecond = _fileStream->readUint32LE();
+ _header.padding = _fileStream->readUint32LE();
+ _header.flags = _fileStream->readUint32LE();
+ _header.totalFrames = _fileStream->readUint32LE();
+ _header.initialFrames = _fileStream->readUint32LE();
+ _header.streams = _fileStream->readUint32LE();
+ _header.bufferSize = _fileStream->readUint32LE();
+ _header.width = _fileStream->readUint32LE();
+ _header.height = _fileStream->readUint32LE();
+ // Ignore 16 bytes of reserved data
+ _fileStream->skip(16);
+ break;
+ case ID_STRH:
+ handleStreamHeader();
+ break;
+ case ID_STRD: // Extra stream info, safe to ignore
+ case ID_VEDT: // Unknown, safe to ignore
+ case ID_JUNK: // Alignment bytes, should be ignored
+ {
+ uint32 junkSize = _fileStream->readUint32LE();
+ _fileStream->skip(junkSize + (junkSize & 1)); // Alignment
+ } break;
+ case ID_IDX1:
+ _ixInfo.size = _fileStream->readUint32LE();
+ _ixInfo.indices = new OldIndex::Index[_ixInfo.size / 16];
+ debug(0, "%d Indices", (_ixInfo.size / 16));
+ for (uint32 i = 0; i < (_ixInfo.size / 16); i++) {
+ _ixInfo.indices[i].id = _fileStream->readUint32BE();
+ _ixInfo.indices[i].flags = _fileStream->readUint32LE();
+ _ixInfo.indices[i].offset = _fileStream->readUint32LE();
+ _ixInfo.indices[i].size = _fileStream->readUint32LE();
+ debug(0, "Index %d == Tag \'%s\', Offset = %d, Size = %d", i, tag2str(_ixInfo.indices[i].id), _ixInfo.indices[i].offset, _ixInfo.indices[i].size);
+ }
+ break;
+ default:
+ error("Unknown tag \'%s\' found", tag2str(tag));
}
}
-void AviDecoder::handleList() {
+void AVIDecoder::handleList() {
uint32 listSize = _fileStream->readUint32LE() - 4; // Subtract away listType's 4 bytes
uint32 listType = _fileStream->readUint32BE();
uint32 curPos = _fileStream->pos();
- debug (0, "Found LIST of type %s", tag2str(listType));
+ debug(0, "Found LIST of type %s", tag2str(listType));
while ((_fileStream->pos() - curPos) < listSize)
runHandle(_fileStream->readUint32BE());
@@ -151,12 +173,14 @@ void AviDecoder::handleList() {
_decodedHeader = true;
}
-void AviDecoder::handleStreamHeader() {
+void AVIDecoder::handleStreamHeader() {
AVIStreamHeader sHeader;
sHeader.size = _fileStream->readUint32LE();
sHeader.streamType = _fileStream->readUint32BE();
+
if (sHeader.streamType == ID_MIDS || sHeader.streamType == ID_TXTS)
- error ("Unhandled MIDI/Text stream");
+ error("Unhandled MIDI/Text stream");
+
sHeader.streamHandler = _fileStream->readUint32BE();
sHeader.flags = _fileStream->readUint32LE();
sHeader.priority = _fileStream->readUint16LE();
@@ -174,63 +198,67 @@ void AviDecoder::handleStreamHeader() {
if (_fileStream->readUint32BE() != ID_STRF)
error("Could not find STRF tag");
+
uint32 strfSize = _fileStream->readUint32LE();
uint32 startPos = _fileStream->pos();
if (sHeader.streamType == ID_VIDS) {
- _vidsHeader = sHeader;
-
- _bmInfo.size = _fileStream->readUint32LE();
- _bmInfo.width = _fileStream->readUint32LE();
- assert (_header.width == _bmInfo.width);
- _bmInfo.height = _fileStream->readUint32LE();
- assert (_header.height == _bmInfo.height);
- _bmInfo.planes = _fileStream->readUint16LE();
- _bmInfo.bitCount = _fileStream->readUint16LE();
- _bmInfo.compression = _fileStream->readUint32BE();
- _bmInfo.sizeImage = _fileStream->readUint32LE();
- _bmInfo.xPelsPerMeter = _fileStream->readUint32LE();
- _bmInfo.yPelsPerMeter = _fileStream->readUint32LE();
- _bmInfo.clrUsed = _fileStream->readUint32LE();
- _bmInfo.clrImportant = _fileStream->readUint32LE();
-
- if (_bmInfo.bitCount == 8) {
- if (_bmInfo.clrUsed == 0)
- _bmInfo.clrUsed = 256;
-
- for (uint32 i = 0; i < _bmInfo.clrUsed; i++) {
- _palette[i * 3 + 2] = _fileStream->readByte();
- _palette[i * 3 + 1] = _fileStream->readByte();
- _palette[i * 3] = _fileStream->readByte();
+ BitmapInfoHeader bmInfo;
+ bmInfo.size = _fileStream->readUint32LE();
+ bmInfo.width = _fileStream->readUint32LE();
+ bmInfo.height = _fileStream->readUint32LE();
+ bmInfo.planes = _fileStream->readUint16LE();
+ bmInfo.bitCount = _fileStream->readUint16LE();
+ bmInfo.compression = _fileStream->readUint32BE();
+ bmInfo.sizeImage = _fileStream->readUint32LE();
+ bmInfo.xPelsPerMeter = _fileStream->readUint32LE();
+ bmInfo.yPelsPerMeter = _fileStream->readUint32LE();
+ bmInfo.clrUsed = _fileStream->readUint32LE();
+ bmInfo.clrImportant = _fileStream->readUint32LE();
+
+ if (bmInfo.clrUsed == 0)
+ bmInfo.clrUsed = 256;
+
+ if (sHeader.streamHandler == 0)
+ sHeader.streamHandler = bmInfo.compression;
+
+ AVIVideoTrack *track = new AVIVideoTrack(_header.totalFrames, sHeader, bmInfo);
+
+ if (bmInfo.bitCount == 8) {
+ byte *palette = const_cast<byte *>(track->getPalette());
+ for (uint32 i = 0; i < bmInfo.clrUsed; i++) {
+ palette[i * 3 + 2] = _fileStream->readByte();
+ palette[i * 3 + 1] = _fileStream->readByte();
+ palette[i * 3] = _fileStream->readByte();
_fileStream->readByte();
}
- _dirtyPalette = true;
+ track->markPaletteDirty();
}
- if (!_vidsHeader.streamHandler)
- _vidsHeader.streamHandler = _bmInfo.compression;
+ addTrack(track);
} else if (sHeader.streamType == ID_AUDS) {
- _audsHeader = sHeader;
-
- _wvInfo.tag = _fileStream->readUint16LE();
- _wvInfo.channels = _fileStream->readUint16LE();
- _wvInfo.samplesPerSec = _fileStream->readUint32LE();
- _wvInfo.avgBytesPerSec = _fileStream->readUint32LE();
- _wvInfo.blockAlign = _fileStream->readUint16LE();
- _wvInfo.size = _fileStream->readUint16LE();
+ PCMWaveFormat wvInfo;
+ wvInfo.tag = _fileStream->readUint16LE();
+ wvInfo.channels = _fileStream->readUint16LE();
+ wvInfo.samplesPerSec = _fileStream->readUint32LE();
+ wvInfo.avgBytesPerSec = _fileStream->readUint32LE();
+ wvInfo.blockAlign = _fileStream->readUint16LE();
+ wvInfo.size = _fileStream->readUint16LE();
// AVI seems to treat the sampleSize as including the second
// channel as well, so divide for our sake.
- if (_wvInfo.channels == 2)
- _audsHeader.sampleSize /= 2;
+ if (wvInfo.channels == 2)
+ sHeader.sampleSize /= 2;
+
+ addTrack(new AVIAudioTrack(sHeader, wvInfo, _soundType));
}
// Ensure that we're at the end of the chunk
_fileStream->seek(startPos + strfSize);
}
-bool AviDecoder::loadStream(Common::SeekableReadStream *stream) {
+bool AVIDecoder::loadStream(Common::SeekableReadStream *stream) {
close();
_fileStream = stream;
@@ -252,74 +280,31 @@ bool AviDecoder::loadStream(Common::SeekableReadStream *stream) {
if (nextTag == ID_LIST) {
_fileStream->readUint32BE(); // Skip size
if (_fileStream->readUint32BE() != ID_MOVI)
- error ("Expected 'movi' LIST");
- } else
- error ("Expected 'movi' LIST");
-
- // Now, create the codec
- _videoCodec = createCodec();
-
- // Initialize the video stuff too
- _audStream = createAudioStream();
- if (_audStream)
- _mixer->playStream(_soundType, _audHandle, _audStream);
-
- debug (0, "Frames = %d, Dimensions = %d x %d", _header.totalFrames, _header.width, _header.height);
- debug (0, "Frame Rate = %d", _vidsHeader.rate / _vidsHeader.scale);
- if (_wvInfo.samplesPerSec != 0)
- debug (0, "Sound Rate = %d", _wvInfo.samplesPerSec);
- debug (0, "Video Codec = \'%s\'", tag2str(_vidsHeader.streamHandler));
-
- if (!_videoCodec)
- return false;
+ error("Expected 'movi' LIST");
+ } else {
+ error("Expected 'movi' LIST");
+ }
return true;
}
-void AviDecoder::close() {
- if (!_fileStream)
- return;
+void AVIDecoder::close() {
+ VideoDecoder::close();
delete _fileStream;
_fileStream = 0;
-
- // Deinitialize sound
- _mixer->stopHandle(*_audHandle);
- _audStream = 0;
-
_decodedHeader = false;
- delete _videoCodec;
- _videoCodec = 0;
-
delete[] _ixInfo.indices;
- _ixInfo.indices = 0;
-
- memset(_palette, 0, sizeof(_palette));
- memset(&_wvInfo, 0, sizeof(PCMWAVEFORMAT));
- memset(&_bmInfo, 0, sizeof(BITMAPINFOHEADER));
- memset(&_vidsHeader, 0, sizeof(AVIStreamHeader));
- memset(&_audsHeader, 0, sizeof(AVIStreamHeader));
- memset(&_ixInfo, 0, sizeof(AVIOLDINDEX));
-
- reset();
+ memset(&_ixInfo, 0, sizeof(_ixInfo));
+ memset(&_header, 0, sizeof(_header));
}
-uint32 AviDecoder::getElapsedTime() const {
- if (_audStream)
- return _mixer->getSoundElapsedTime(*_audHandle);
-
- return FixedRateVideoDecoder::getElapsedTime();
-}
-
-const Graphics::Surface *AviDecoder::decodeNextFrame() {
+void AVIDecoder::readNextPacket() {
uint32 nextTag = _fileStream->readUint32BE();
if (_fileStream->eos())
- return NULL;
-
- if (_curFrame == -1)
- _startTime = g_system->getMillis();
+ return;
if (nextTag == ID_LIST) {
// A list of audio/video chunks
@@ -327,128 +312,170 @@ const Graphics::Surface *AviDecoder::decodeNextFrame() {
int32 startPos = _fileStream->pos();
if (_fileStream->readUint32BE() != ID_REC)
- error ("Expected 'rec ' LIST");
-
- // Decode chunks in the list and see if we get a frame
- const Graphics::Surface *frame = NULL;
- while (_fileStream->pos() < startPos + (int32)listSize) {
- const Graphics::Surface *temp = decodeNextFrame();
- if (temp)
- frame = temp;
- }
+ error("Expected 'rec ' LIST");
+
+ // Decode chunks in the list
+ while (_fileStream->pos() < startPos + (int32)listSize)
+ readNextPacket();
+
+ return;
+ } else if (nextTag == ID_JUNK || nextTag == ID_IDX1) {
+ runHandle(nextTag);
+ return;
+ }
- return frame;
- } else if (getStreamType(nextTag) == 'wb') {
- // Audio Chunk
- uint32 chunkSize = _fileStream->readUint32LE();
- queueAudioBuffer(chunkSize);
- _fileStream->skip(chunkSize & 1); // Alignment
- } else if (getStreamType(nextTag) == 'dc' || getStreamType(nextTag) == 'id' ||
- getStreamType(nextTag) == 'AM' || getStreamType(nextTag) == '32' ||
- getStreamType(nextTag) == 'iv') {
- // Compressed Frame
- _curFrame++;
- uint32 chunkSize = _fileStream->readUint32LE();
-
- if (chunkSize == 0) // Keep last frame on screen
- return NULL;
-
- Common::SeekableReadStream *frameData = _fileStream->readStream(chunkSize);
- const Graphics::Surface *surface = _videoCodec->decodeImage(frameData);
- delete frameData;
- _fileStream->skip(chunkSize & 1); // Alignment
- return surface;
- } else if (getStreamType(nextTag) == 'pc') {
- // Palette Change
- _fileStream->readUint32LE(); // Chunk size, not needed here
- byte firstEntry = _fileStream->readByte();
- uint16 numEntries = _fileStream->readByte();
- _fileStream->readUint16LE(); // Reserved
-
- // 0 entries means all colors are going to be changed
- if (numEntries == 0)
- numEntries = 256;
-
- for (uint16 i = firstEntry; i < numEntries + firstEntry; i++) {
- _palette[i * 3] = _fileStream->readByte();
- _palette[i * 3 + 1] = _fileStream->readByte();
- _palette[i * 3 + 2] = _fileStream->readByte();
- _fileStream->readByte(); // Flags that don't serve us any purpose
+ Track *track = getTrack(getStreamIndex(nextTag));
+
+ if (!track)
+ error("Cannot get track from tag '%s'", tag2str(nextTag));
+
+ uint32 chunkSize = _fileStream->readUint32LE();
+ Common::SeekableReadStream *chunk = 0;
+
+ if (chunkSize != 0) {
+ chunk = _fileStream->readStream(chunkSize);
+ _fileStream->skip(chunkSize & 1);
+ }
+
+ if (track->getTrackType() == Track::kTrackTypeAudio) {
+ if (getStreamType(nextTag) != MKTAG16('w', 'b'))
+ error("Invalid audio track tag '%s'", tag2str(nextTag));
+
+ assert(chunk);
+ ((AVIAudioTrack *)track)->queueSound(chunk);
+ } else {
+ AVIVideoTrack *videoTrack = (AVIVideoTrack *)track;
+
+ if (getStreamType(nextTag) == MKTAG16('p', 'c')) {
+ // Palette Change
+ assert(chunk);
+ byte firstEntry = chunk->readByte();
+ uint16 numEntries = chunk->readByte();
+ chunk->readUint16LE(); // Reserved
+
+ // 0 entries means all colors are going to be changed
+ if (numEntries == 0)
+ numEntries = 256;
+
+ byte *palette = const_cast<byte *>(videoTrack->getPalette());
+
+ for (uint16 i = firstEntry; i < numEntries + firstEntry; i++) {
+ palette[i * 3] = chunk->readByte();
+ palette[i * 3 + 1] = chunk->readByte();
+ palette[i * 3 + 2] = chunk->readByte();
+ chunk->readByte(); // Flags that don't serve us any purpose
+ }
+
+ delete chunk;
+ videoTrack->markPaletteDirty();
+ } else if (getStreamType(nextTag) == MKTAG16('d', 'b')) {
+ // TODO: Check if this really is uncompressed. Many videos
+ // falsely put compressed data in here.
+ error("Uncompressed AVI frame found");
+ } else {
+ // Otherwise, assume it's a compressed frame
+ videoTrack->decodeFrame(chunk);
}
+ }
+}
- _dirtyPalette = true;
+AVIDecoder::AVIVideoTrack::AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader)
+ : _frameCount(frameCount), _vidsHeader(streamHeader), _bmInfo(bitmapInfoHeader) {
+ memset(_palette, 0, sizeof(_palette));
+ _videoCodec = createCodec();
+ _dirtyPalette = false;
+ _lastFrame = 0;
+ _curFrame = -1;
+}
- // No alignment necessary. It's always even.
- } else if (nextTag == ID_JUNK) {
- runHandle(ID_JUNK);
- } else if (nextTag == ID_IDX1) {
- runHandle(ID_IDX1);
- } else
- error("Tag = \'%s\', %d", tag2str(nextTag), _fileStream->pos());
+AVIDecoder::AVIVideoTrack::~AVIVideoTrack() {
+ delete _videoCodec;
+}
+
+void AVIDecoder::AVIVideoTrack::decodeFrame(Common::SeekableReadStream *stream) {
+ if (stream) {
+ if (_videoCodec)
+ _lastFrame = _videoCodec->decodeImage(stream);
+ } else {
+ // Empty frame
+ _lastFrame = 0;
+ }
- return NULL;
+ delete stream;
+ _curFrame++;
}
-Codec *AviDecoder::createCodec() {
+Graphics::PixelFormat AVIDecoder::AVIVideoTrack::getPixelFormat() const {
+ if (_videoCodec)
+ return _videoCodec->getPixelFormat();
+
+ return Graphics::PixelFormat();
+}
+
+Codec *AVIDecoder::AVIVideoTrack::createCodec() {
switch (_vidsHeader.streamHandler) {
- case ID_CRAM:
- case ID_MSVC:
- case ID_WHAM:
- return new MSVideo1Decoder(_bmInfo.width, _bmInfo.height, _bmInfo.bitCount);
- case ID_RLE:
- return new MSRLEDecoder(_bmInfo.width, _bmInfo.height, _bmInfo.bitCount);
- case ID_CVID:
- return new CinepakDecoder(_bmInfo.bitCount);
- case ID_IV32:
- return new Indeo3Decoder(_bmInfo.width, _bmInfo.height);
+ case ID_CRAM:
+ case ID_MSVC:
+ case ID_WHAM:
+ return new MSVideo1Decoder(_bmInfo.width, _bmInfo.height, _bmInfo.bitCount);
+ case ID_RLE:
+ return new MSRLEDecoder(_bmInfo.width, _bmInfo.height, _bmInfo.bitCount);
+ case ID_CVID:
+ return new CinepakDecoder(_bmInfo.bitCount);
+ case ID_IV32:
+ return new Indeo3Decoder(_bmInfo.width, _bmInfo.height);
#ifdef VIDEO_CODECS_TRUEMOTION1_H
- case ID_DUCK:
- return new TrueMotion1Decoder(_bmInfo.width, _bmInfo.height);
+ case ID_DUCK:
+ return new TrueMotion1Decoder(_bmInfo.width, _bmInfo.height);
#endif
- default:
- warning ("Unknown/Unhandled compression format \'%s\'", tag2str(_vidsHeader.streamHandler));
+ default:
+ warning("Unknown/Unhandled compression format \'%s\'", tag2str(_vidsHeader.streamHandler));
}
- return NULL;
+ return 0;
}
-Graphics::PixelFormat AviDecoder::getPixelFormat() const {
- assert(_videoCodec);
- return _videoCodec->getPixelFormat();
+AVIDecoder::AVIAudioTrack::AVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType)
+ : _audsHeader(streamHeader), _wvInfo(waveFormat), _soundType(soundType) {
+ _audStream = createAudioStream();
}
-Audio::QueuingAudioStream *AviDecoder::createAudioStream() {
- if (_wvInfo.tag == kWaveFormatPCM || _wvInfo.tag == kWaveFormatDK3)
- return Audio::makeQueuingAudioStream(_wvInfo.samplesPerSec, _wvInfo.channels == 2);
- else if (_wvInfo.tag != kWaveFormatNone) // No sound
- warning("Unsupported AVI audio format %d", _wvInfo.tag);
-
- return NULL;
+AVIDecoder::AVIAudioTrack::~AVIAudioTrack() {
+ delete _audStream;
}
-void AviDecoder::queueAudioBuffer(uint32 chunkSize) {
- // Return if we haven't created the queue (unsupported audio format)
- if (!_audStream) {
- _fileStream->skip(chunkSize);
- return;
+void AVIDecoder::AVIAudioTrack::queueSound(Common::SeekableReadStream *stream) {
+ if (_audStream) {
+ if (_wvInfo.tag == kWaveFormatPCM) {
+ byte flags = 0;
+ if (_audsHeader.sampleSize == 2)
+ flags |= Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN;
+ else
+ flags |= Audio::FLAG_UNSIGNED;
+
+ if (_wvInfo.channels == 2)
+ flags |= Audio::FLAG_STEREO;
+
+ _audStream->queueAudioStream(Audio::makeRawStream(stream, _wvInfo.samplesPerSec, flags, DisposeAfterUse::YES), DisposeAfterUse::YES);
+ } else if (_wvInfo.tag == kWaveFormatDK3) {
+ _audStream->queueAudioStream(Audio::makeADPCMStream(stream, DisposeAfterUse::YES, stream->size(), Audio::kADPCMDK3, _wvInfo.samplesPerSec, _wvInfo.channels, _wvInfo.blockAlign), DisposeAfterUse::YES);
+ }
+ } else {
+ delete stream;
}
+}
- Common::SeekableReadStream *stream = _fileStream->readStream(chunkSize);
-
- if (_wvInfo.tag == kWaveFormatPCM) {
- byte flags = 0;
- if (_audsHeader.sampleSize == 2)
- flags |= Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN;
- else
- flags |= Audio::FLAG_UNSIGNED;
+Audio::AudioStream *AVIDecoder::AVIAudioTrack::getAudioStream() const {
+ return _audStream;
+}
- if (_wvInfo.channels == 2)
- flags |= Audio::FLAG_STEREO;
+Audio::QueuingAudioStream *AVIDecoder::AVIAudioTrack::createAudioStream() {
+ if (_wvInfo.tag == kWaveFormatPCM || _wvInfo.tag == kWaveFormatDK3)
+ return Audio::makeQueuingAudioStream(_wvInfo.samplesPerSec, _wvInfo.channels == 2);
+ else if (_wvInfo.tag != kWaveFormatNone) // No sound
+ warning("Unsupported AVI audio format %d", _wvInfo.tag);
- _audStream->queueAudioStream(Audio::makeRawStream(stream, _wvInfo.samplesPerSec, flags, DisposeAfterUse::YES), DisposeAfterUse::YES);
- } else if (_wvInfo.tag == kWaveFormatDK3) {
- _audStream->queueAudioStream(Audio::makeADPCMStream(stream, DisposeAfterUse::YES, chunkSize, Audio::kADPCMDK3, _wvInfo.samplesPerSec, _wvInfo.channels, _wvInfo.blockAlign), DisposeAfterUse::YES);
- }
+ return 0;
}
} // End of namespace Video
diff --git a/video/avi_decoder.h b/video/avi_decoder.h
index 508760ec89..a3a262db36 100644
--- a/video/avi_decoder.h
+++ b/video/avi_decoder.h
@@ -47,191 +47,183 @@ namespace Video {
class Codec;
-#define UNKNOWN_HEADER(a) error("Unknown header found -- \'%s\'", tag2str(a))
-
-// IDs used throughout the AVI files
-// that will be handled by this player
-#define ID_RIFF MKTAG('R','I','F','F')
-#define ID_AVI MKTAG('A','V','I',' ')
-#define ID_LIST MKTAG('L','I','S','T')
-#define ID_HDRL MKTAG('h','d','r','l')
-#define ID_AVIH MKTAG('a','v','i','h')
-#define ID_STRL MKTAG('s','t','r','l')
-#define ID_STRH MKTAG('s','t','r','h')
-#define ID_VIDS MKTAG('v','i','d','s')
-#define ID_AUDS MKTAG('a','u','d','s')
-#define ID_MIDS MKTAG('m','i','d','s')
-#define ID_TXTS MKTAG('t','x','t','s')
-#define ID_JUNK MKTAG('J','U','N','K')
-#define ID_STRF MKTAG('s','t','r','f')
-#define ID_MOVI MKTAG('m','o','v','i')
-#define ID_REC MKTAG('r','e','c',' ')
-#define ID_VEDT MKTAG('v','e','d','t')
-#define ID_IDX1 MKTAG('i','d','x','1')
-#define ID_STRD MKTAG('s','t','r','d')
-#define ID_00AM MKTAG('0','0','A','M')
-//#define ID_INFO MKTAG('I','N','F','O')
-
-// Codec tags
-#define ID_RLE MKTAG('R','L','E',' ')
-#define ID_CRAM MKTAG('C','R','A','M')
-#define ID_MSVC MKTAG('m','s','v','c')
-#define ID_WHAM MKTAG('W','H','A','M')
-#define ID_CVID MKTAG('c','v','i','d')
-#define ID_IV32 MKTAG('i','v','3','2')
-#define ID_DUCK MKTAG('D','U','C','K')
-
-struct BITMAPINFOHEADER {
- uint32 size;
- uint32 width;
- uint32 height;
- uint16 planes;
- uint16 bitCount;
- uint32 compression;
- uint32 sizeImage;
- uint32 xPelsPerMeter;
- uint32 yPelsPerMeter;
- uint32 clrUsed;
- uint32 clrImportant;
-};
-
-struct WAVEFORMAT {
- uint16 tag;
- uint16 channels;
- uint32 samplesPerSec;
- uint32 avgBytesPerSec;
- uint16 blockAlign;
-};
-
-struct PCMWAVEFORMAT : public WAVEFORMAT {
- uint16 size;
-};
-
-struct WAVEFORMATEX : public WAVEFORMAT {
- uint16 bitsPerSample;
- uint16 size;
-};
-
-struct AVIOLDINDEX {
- uint32 size;
- struct Index {
- uint32 id;
- uint32 flags;
- uint32 offset;
- uint32 size;
- } *indices;
-};
-
-// Index Flags
-enum IndexFlags {
- AVIIF_INDEX = 0x10
-};
-
-// Audio Codecs
-enum {
- kWaveFormatNone = 0,
- kWaveFormatPCM = 1,
- kWaveFormatDK3 = 98
-};
-
-struct AVIHeader {
- uint32 size;
- uint32 microSecondsPerFrame;
- uint32 maxBytesPerSecond;
- uint32 padding;
- uint32 flags;
- uint32 totalFrames;
- uint32 initialFrames;
- uint32 streams;
- uint32 bufferSize;
- uint32 width;
- uint32 height;
-};
-
-// Flags from the AVIHeader
-enum AviFlags {
- AVIF_HASINDEX = 0x00000010,
- AVIF_MUSTUSEINDEX = 0x00000020,
- AVIF_ISINTERLEAVED = 0x00000100,
- AVIF_TRUSTCKTYPE = 0x00000800,
- AVIF_WASCAPTUREFILE = 0x00010000,
- AVIF_WASCOPYRIGHTED = 0x00020000
-};
-
-struct AVIStreamHeader {
- uint32 size;
- uint32 streamType;
- uint32 streamHandler;
- uint32 flags;
- uint16 priority;
- uint16 language;
- uint32 initialFrames;
- uint32 scale;
- uint32 rate;
- uint32 start;
- uint32 length;
- uint32 bufferSize;
- uint32 quality;
- uint32 sampleSize;
- Common::Rect frame;
-};
-
/**
* Decoder for AVI videos.
*
* Video decoder used in engines:
* - sci
*/
-class AviDecoder : public FixedRateVideoDecoder {
+class AVIDecoder : public VideoDecoder {
public:
- AviDecoder(Audio::Mixer *mixer,
- Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
- virtual ~AviDecoder();
+ AVIDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
+ virtual ~AVIDecoder();
bool loadStream(Common::SeekableReadStream *stream);
void close();
-
- bool isVideoLoaded() const { return _fileStream != 0; }
uint16 getWidth() const { return _header.width; }
uint16 getHeight() const { return _header.height; }
- uint32 getFrameCount() const { return _header.totalFrames; }
- uint32 getElapsedTime() const;
- const Graphics::Surface *decodeNextFrame();
- Graphics::PixelFormat getPixelFormat() const;
- const byte *getPalette() { _dirtyPalette = false; return _palette; }
- bool hasDirtyPalette() const { return _dirtyPalette; }
protected:
- Common::Rational getFrameRate() const { return Common::Rational(_vidsHeader.rate, _vidsHeader.scale); }
+ void readNextPacket();
private:
- Audio::Mixer *_mixer;
- BITMAPINFOHEADER _bmInfo;
- PCMWAVEFORMAT _wvInfo;
- AVIOLDINDEX _ixInfo;
- AVIHeader _header;
- AVIStreamHeader _vidsHeader;
- AVIStreamHeader _audsHeader;
- byte _palette[3 * 256];
- bool _dirtyPalette;
+ struct BitmapInfoHeader {
+ uint32 size;
+ uint32 width;
+ uint32 height;
+ uint16 planes;
+ uint16 bitCount;
+ uint32 compression;
+ uint32 sizeImage;
+ uint32 xPelsPerMeter;
+ uint32 yPelsPerMeter;
+ uint32 clrUsed;
+ uint32 clrImportant;
+ };
+
+ struct WaveFormat {
+ uint16 tag;
+ uint16 channels;
+ uint32 samplesPerSec;
+ uint32 avgBytesPerSec;
+ uint16 blockAlign;
+ };
+
+ struct PCMWaveFormat : public WaveFormat {
+ uint16 size;
+ };
+
+ struct WaveFormatEX : public WaveFormat {
+ uint16 bitsPerSample;
+ uint16 size;
+ };
+
+ struct OldIndex {
+ uint32 size;
+ struct Index {
+ uint32 id;
+ uint32 flags;
+ uint32 offset;
+ uint32 size;
+ } *indices;
+ };
+
+ // Index Flags
+ enum IndexFlags {
+ AVIIF_INDEX = 0x10
+ };
+
+ struct AVIHeader {
+ uint32 size;
+ uint32 microSecondsPerFrame;
+ uint32 maxBytesPerSecond;
+ uint32 padding;
+ uint32 flags;
+ uint32 totalFrames;
+ uint32 initialFrames;
+ uint32 streams;
+ uint32 bufferSize;
+ uint32 width;
+ uint32 height;
+ };
+
+ // Flags from the AVIHeader
+ enum AVIFlags {
+ AVIF_HASINDEX = 0x00000010,
+ AVIF_MUSTUSEINDEX = 0x00000020,
+ AVIF_ISINTERLEAVED = 0x00000100,
+ AVIF_TRUSTCKTYPE = 0x00000800,
+ AVIF_WASCAPTUREFILE = 0x00010000,
+ AVIF_WASCOPYRIGHTED = 0x00020000
+ };
+
+ struct AVIStreamHeader {
+ uint32 size;
+ uint32 streamType;
+ uint32 streamHandler;
+ uint32 flags;
+ uint16 priority;
+ uint16 language;
+ uint32 initialFrames;
+ uint32 scale;
+ uint32 rate;
+ uint32 start;
+ uint32 length;
+ uint32 bufferSize;
+ uint32 quality;
+ uint32 sampleSize;
+ Common::Rect frame;
+ };
+
+ class AVIVideoTrack : public FixedRateVideoTrack {
+ public:
+ AVIVideoTrack(int frameCount, const AVIStreamHeader &streamHeader, const BitmapInfoHeader &bitmapInfoHeader);
+ ~AVIVideoTrack();
+
+ void decodeFrame(Common::SeekableReadStream *stream);
+
+ uint16 getWidth() const { return _bmInfo.width; }
+ uint16 getHeight() const { return _bmInfo.height; }
+ Graphics::PixelFormat getPixelFormat() const;
+ int getCurFrame() const { return _curFrame; }
+ int getFrameCount() const { return _frameCount; }
+ const Graphics::Surface *decodeNextFrame() { return _lastFrame; }
+ const byte *getPalette() const { _dirtyPalette = false; return _palette; }
+ bool hasDirtyPalette() const { return _dirtyPalette; }
+ void markPaletteDirty() { _dirtyPalette = true; }
+
+ protected:
+ Common::Rational getFrameRate() const { return Common::Rational(_vidsHeader.rate, _vidsHeader.scale); }
+
+ private:
+ AVIStreamHeader _vidsHeader;
+ BitmapInfoHeader _bmInfo;
+ byte _palette[3 * 256];
+ mutable bool _dirtyPalette;
+ int _frameCount, _curFrame;
+
+ Codec *_videoCodec;
+ const Graphics::Surface *_lastFrame;
+ Codec *createCodec();
+ };
+
+ class AVIAudioTrack : public AudioTrack {
+ public:
+ AVIAudioTrack(const AVIStreamHeader &streamHeader, const PCMWaveFormat &waveFormat, Audio::Mixer::SoundType soundType);
+ ~AVIAudioTrack();
+
+ void queueSound(Common::SeekableReadStream *stream);
+ Audio::Mixer::SoundType getSoundType() const { return _soundType; }
+
+ protected:
+ Audio::AudioStream *getAudioStream() const;
+
+ private:
+ // Audio Codecs
+ enum {
+ kWaveFormatNone = 0,
+ kWaveFormatPCM = 1,
+ kWaveFormatDK3 = 98
+ };
+
+ AVIStreamHeader _audsHeader;
+ PCMWaveFormat _wvInfo;
+ Audio::Mixer::SoundType _soundType;
+ Audio::QueuingAudioStream *_audStream;
+ Audio::QueuingAudioStream *createAudioStream();
+ };
+
+ OldIndex _ixInfo;
+ AVIHeader _header;
Common::SeekableReadStream *_fileStream;
bool _decodedHeader;
- Codec *_videoCodec;
- Codec *createCodec();
-
Audio::Mixer::SoundType _soundType;
void runHandle(uint32 tag);
void handleList();
void handleStreamHeader();
- void handlePalChange();
-
- Audio::SoundHandle *_audHandle;
- Audio::QueuingAudioStream *_audStream;
- Audio::QueuingAudioStream *createAudioStream();
- void queueAudioBuffer(uint32 chunkSize);
};
} // End of namespace Video
diff --git a/video/bink_decoder.cpp b/video/bink_decoder.cpp
index 884ca69f17..620316806f 100644
--- a/video/bink_decoder.cpp
+++ b/video/bink_decoder.cpp
@@ -24,6 +24,7 @@
// based quite heavily on the Bink decoder found in FFmpeg.
// Many thanks to Kostya Shishkov for doing the hard work.
+#include "audio/audiostream.h"
#include "audio/decoders/raw.h"
#include "common/util.h"
@@ -60,139 +61,108 @@ static const uint32 kDCStartBits = 11;
namespace Video {
-BinkDecoder::VideoFrame::VideoFrame() : bits(0) {
-}
-
-BinkDecoder::VideoFrame::~VideoFrame() {
- delete bits;
+BinkDecoder::BinkDecoder() {
+ _bink = 0;
}
-
-BinkDecoder::AudioTrack::AudioTrack() : bits(0), bands(0), rdft(0), dct(0) {
+BinkDecoder::~BinkDecoder() {
+ close();
}
-BinkDecoder::AudioTrack::~AudioTrack() {
- delete bits;
-
- delete[] bands;
-
- delete rdft;
- delete dct;
-}
+bool BinkDecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
+ uint32 id = stream->readUint32BE();
+ if ((id != kBIKfID) && (id != kBIKgID) && (id != kBIKhID) && (id != kBIKiID))
+ return false;
-BinkDecoder::BinkDecoder() {
- _bink = 0;
- _audioTrack = 0;
+ uint32 fileSize = stream->readUint32LE() + 8;
+ uint32 frameCount = stream->readUint32LE();
+ uint32 largestFrameSize = stream->readUint32LE();
- for (int i = 0; i < 16; i++)
- _huffman[i] = 0;
+ if (largestFrameSize > fileSize) {
+ warning("Largest frame size greater than file size");
+ return false;
+ }
- for (int i = 0; i < kSourceMAX; i++) {
- _bundles[i].countLength = 0;
+ stream->skip(4);
- _bundles[i].huffman.index = 0;
- for (int j = 0; j < 16; j++)
- _bundles[i].huffman.symbols[j] = j;
+ uint32 width = stream->readUint32LE();
+ uint32 height = stream->readUint32LE();
- _bundles[i].data = 0;
- _bundles[i].dataEnd = 0;
- _bundles[i].curDec = 0;
- _bundles[i].curPtr = 0;
+ uint32 frameRateNum = stream->readUint32LE();
+ uint32 frameRateDen = stream->readUint32LE();
+ if (frameRateNum == 0 || frameRateDen == 0) {
+ warning("Invalid frame rate (%d/%d)", frameRateNum, frameRateDen);
+ return false;
}
- for (int i = 0; i < 16; i++) {
- _colHighHuffman[i].index = 0;
- for (int j = 0; j < 16; j++)
- _colHighHuffman[i].symbols[j] = j;
- }
+ _bink = stream;
- for (int i = 0; i < 4; i++) {
- _curPlanes[i] = 0;
- _oldPlanes[i] = 0;
- }
+ uint32 videoFlags = _bink->readUint32LE();
- _audioStream = 0;
-}
+ // BIKh and BIKi swap the chroma planes
+ addTrack(new BinkVideoTrack(width, height, getDefaultHighColorFormat(), frameCount,
+ Common::Rational(frameRateNum, frameRateDen), (id == kBIKhID || id == kBIKiID), videoFlags & kVideoFlagAlpha, id));
-void BinkDecoder::startAudio() {
- if (_audioTrack < _audioTracks.size()) {
- const AudioTrack &audio = _audioTracks[_audioTrack];
+ uint32 audioTrackCount = _bink->readUint32LE();
- _audioStream = Audio::makeQueuingAudioStream(audio.outSampleRate, audio.outChannels == 2);
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandle, _audioStream);
- } // else no audio
-}
+ if (audioTrackCount > 0) {
+ _audioTracks.reserve(audioTrackCount);
-void BinkDecoder::stopAudio() {
- if (_audioStream) {
- g_system->getMixer()->stopHandle(_audioHandle);
- _audioStream = 0;
- }
-}
+ _bink->skip(4 * audioTrackCount);
-BinkDecoder::~BinkDecoder() {
- close();
-}
+ // Reading audio track properties
+ for (uint32 i = 0; i < audioTrackCount; i++) {
+ AudioInfo track;
-void BinkDecoder::close() {
- reset();
+ track.sampleRate = _bink->readUint16LE();
+ track.flags = _bink->readUint16LE();
- // Stop audio
- stopAudio();
+ _audioTracks.push_back(track);
- for (int i = 0; i < 4; i++) {
- delete[] _curPlanes[i]; _curPlanes[i] = 0;
- delete[] _oldPlanes[i]; _oldPlanes[i] = 0;
+ initAudioTrack(_audioTracks[i]);
+ }
+
+ _bink->skip(4 * audioTrackCount);
}
- deinitBundles();
+ // Reading video frame properties
+ _frames.resize(frameCount);
+ for (uint32 i = 0; i < frameCount; i++) {
+ _frames[i].offset = _bink->readUint32LE();
+ _frames[i].keyFrame = _frames[i].offset & 1;
- for (int i = 0; i < 16; i++) {
- delete _huffman[i];
- _huffman[i] = 0;
- }
+ _frames[i].offset &= ~1;
- delete _bink; _bink = 0;
- _surface.free();
+ if (i != 0)
+ _frames[i - 1].size = _frames[i].offset - _frames[i - 1].offset;
- _audioTrack = 0;
+ _frames[i].bits = 0;
+ }
- for (int i = 0; i < kSourceMAX; i++) {
- _bundles[i].countLength = 0;
+ _frames[frameCount - 1].size = _bink->size() - _frames[frameCount - 1].offset;
- _bundles[i].huffman.index = 0;
- for (int j = 0; j < 16; j++)
- _bundles[i].huffman.symbols[j] = j;
+ return true;
+}
- _bundles[i].data = 0;
- _bundles[i].dataEnd = 0;
- _bundles[i].curDec = 0;
- _bundles[i].curPtr = 0;
- }
+void BinkDecoder::close() {
+ VideoDecoder::close();
- for (int i = 0; i < 16; i++) {
- _colHighHuffman[i].index = 0;
- for (int j = 0; j < 16; j++)
- _colHighHuffman[i].symbols[j] = j;
- }
+ delete _bink;
+ _bink = 0;
_audioTracks.clear();
_frames.clear();
}
-uint32 BinkDecoder::getElapsedTime() const {
- if (_audioStream && g_system->getMixer()->isSoundHandleActive(_audioHandle))
- return g_system->getMixer()->getSoundElapsedTime(_audioHandle) + _audioStartOffset;
+void BinkDecoder::readNextPacket() {
+ BinkVideoTrack *videoTrack = (BinkVideoTrack *)getTrack(0);
- return g_system->getMillis() - _startTime;
-}
-
-const Graphics::Surface *BinkDecoder::decodeNextFrame() {
- if (endOfVideo())
- return 0;
+ if (videoTrack->endOfTrack())
+ return;
- VideoFrame &frame = _frames[_curFrame + 1];
+ VideoFrame &frame = _frames[videoTrack->getCurFrame() + 1];
if (!_bink->seek(frame.offset))
error("Bad bink seek");
@@ -200,7 +170,7 @@ const Graphics::Surface *BinkDecoder::decodeNextFrame() {
uint32 frameSize = frame.size;
for (uint32 i = 0; i < _audioTracks.size(); i++) {
- AudioTrack &audio = _audioTracks[i];
+ AudioInfo &audio = _audioTracks[i];
uint32 audioPacketLength = _bink->readUint32LE();
@@ -210,24 +180,21 @@ const Graphics::Surface *BinkDecoder::decodeNextFrame() {
error("Audio packet too big for the frame");
if (audioPacketLength >= 4) {
+ // Get our track - audio index plus one as the first track is video
+ BinkAudioTrack *audioTrack = (BinkAudioTrack *)getTrack(i + 1);
uint32 audioPacketStart = _bink->pos();
uint32 audioPacketEnd = _bink->pos() + audioPacketLength;
- if (i == _audioTrack) {
- // Only play one audio track
-
- // Number of samples in bytes
- audio.sampleCount = _bink->readUint32LE() / (2 * audio.channels);
+ // Number of samples in bytes
+ audio.sampleCount = _bink->readUint32LE() / (2 * audio.channels);
- audio.bits =
- new Common::BitStream32LELSB(new Common::SeekableSubReadStream(_bink,
- audioPacketStart + 4, audioPacketEnd), true);
+ audio.bits = new Common::BitStream32LELSB(new Common::SeekableSubReadStream(_bink,
+ audioPacketStart + 4, audioPacketEnd), true);
- audioPacket(audio);
+ audioTrack->decodePacket();
- delete audio.bits;
- audio.bits = 0;
- }
+ delete audio.bits;
+ audio.bits = 0;
_bink->seek(audioPacketEnd);
@@ -238,67 +205,125 @@ const Graphics::Surface *BinkDecoder::decodeNextFrame() {
uint32 videoPacketStart = _bink->pos();
uint32 videoPacketEnd = _bink->pos() + frameSize;
- frame.bits =
- new Common::BitStream32LELSB(new Common::SeekableSubReadStream(_bink,
- videoPacketStart, videoPacketEnd), true);
+ frame.bits = new Common::BitStream32LELSB(new Common::SeekableSubReadStream(_bink,
+ videoPacketStart, videoPacketEnd), true);
- videoPacket(frame);
+ videoTrack->decodePacket(frame);
delete frame.bits;
frame.bits = 0;
+}
- _curFrame++;
- if (_curFrame == 0)
- _startTime = g_system->getMillis();
+BinkDecoder::VideoFrame::VideoFrame() : bits(0) {
+}
- return &_surface;
+BinkDecoder::VideoFrame::~VideoFrame() {
+ delete bits;
}
-void BinkDecoder::audioPacket(AudioTrack &audio) {
- if (!_audioStream)
- return;
- int outSize = audio.frameLen * audio.channels;
- while (audio.bits->pos() < audio.bits->size()) {
- int16 *out = (int16 *)malloc(outSize * 2);
- memset(out, 0, outSize * 2);
+BinkDecoder::AudioInfo::AudioInfo() : bits(0), bands(0), rdft(0), dct(0) {
+}
- audioBlock(audio, out);
+BinkDecoder::AudioInfo::~AudioInfo() {
+ delete bits;
- byte flags = Audio::FLAG_16BITS;
- if (audio.outChannels == 2)
- flags |= Audio::FLAG_STEREO;
+ delete[] bands;
-#ifdef SCUMM_LITTLE_ENDIAN
- flags |= Audio::FLAG_LITTLE_ENDIAN;
-#endif
+ delete rdft;
+ delete dct;
+}
+
+BinkDecoder::BinkVideoTrack::BinkVideoTrack(uint32 width, uint32 height, const Graphics::PixelFormat &format, uint32 frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32 id) :
+ _frameCount(frameCount), _frameRate(frameRate), _swapPlanes(swapPlanes), _hasAlpha(hasAlpha), _id(id) {
+ _curFrame = -1;
+
+ for (int i = 0; i < 16; i++)
+ _huffman[i] = 0;
+
+ for (int i = 0; i < kSourceMAX; i++) {
+ _bundles[i].countLength = 0;
+
+ _bundles[i].huffman.index = 0;
+ for (int j = 0; j < 16; j++)
+ _bundles[i].huffman.symbols[j] = j;
+
+ _bundles[i].data = 0;
+ _bundles[i].dataEnd = 0;
+ _bundles[i].curDec = 0;
+ _bundles[i].curPtr = 0;
+ }
+
+ for (int i = 0; i < 16; i++) {
+ _colHighHuffman[i].index = 0;
+ for (int j = 0; j < 16; j++)
+ _colHighHuffman[i].symbols[j] = j;
+ }
+
+ _surface.create(width, height, format);
+
+ // Give the planes a bit extra space
+ width = _surface.w + 32;
+ height = _surface.h + 32;
+
+ _curPlanes[0] = new byte[ width * height ]; // Y
+ _curPlanes[1] = new byte[(width >> 1) * (height >> 1)]; // U, 1/4 resolution
+ _curPlanes[2] = new byte[(width >> 1) * (height >> 1)]; // V, 1/4 resolution
+ _curPlanes[3] = new byte[ width * height ]; // A
+ _oldPlanes[0] = new byte[ width * height ]; // Y
+ _oldPlanes[1] = new byte[(width >> 1) * (height >> 1)]; // U, 1/4 resolution
+ _oldPlanes[2] = new byte[(width >> 1) * (height >> 1)]; // V, 1/4 resolution
+ _oldPlanes[3] = new byte[ width * height ]; // A
+
+ // Initialize the video with solid black
+ memset(_curPlanes[0], 0, width * height );
+ memset(_curPlanes[1], 0, (width >> 1) * (height >> 1));
+ memset(_curPlanes[2], 0, (width >> 1) * (height >> 1));
+ memset(_curPlanes[3], 255, width * height );
+ memset(_oldPlanes[0], 0, width * height );
+ memset(_oldPlanes[1], 0, (width >> 1) * (height >> 1));
+ memset(_oldPlanes[2], 0, (width >> 1) * (height >> 1));
+ memset(_oldPlanes[3], 255, width * height );
- _audioStream->queueBuffer((byte *)out, audio.blockSize * 2, DisposeAfterUse::YES, flags);
+ initBundles();
+ initHuffman();
+}
- if (audio.bits->pos() & 0x1F) // next data block starts at a 32-byte boundary
- audio.bits->skip(32 - (audio.bits->pos() & 0x1F));
+BinkDecoder::BinkVideoTrack::~BinkVideoTrack() {
+ for (int i = 0; i < 4; i++) {
+ delete[] _curPlanes[i]; _curPlanes[i] = 0;
+ delete[] _oldPlanes[i]; _oldPlanes[i] = 0;
}
+
+ deinitBundles();
+
+ for (int i = 0; i < 16; i++) {
+ delete _huffman[i];
+ _huffman[i] = 0;
+ }
+
+ _surface.free();
}
-void BinkDecoder::videoPacket(VideoFrame &video) {
- assert(video.bits);
+void BinkDecoder::BinkVideoTrack::decodePacket(VideoFrame &frame) {
+ assert(frame.bits);
if (_hasAlpha) {
if (_id == kBIKiID)
- video.bits->skip(32);
+ frame.bits->skip(32);
- decodePlane(video, 3, false);
+ decodePlane(frame, 3, false);
}
if (_id == kBIKiID)
- video.bits->skip(32);
+ frame.bits->skip(32);
for (int i = 0; i < 3; i++) {
int planeIdx = ((i == 0) || !_swapPlanes) ? i : (i ^ 3);
- decodePlane(video, planeIdx, i != 0);
+ decodePlane(frame, planeIdx, i != 0);
- if (video.bits->pos() >= video.bits->size())
+ if (frame.bits->pos() >= frame.bits->size())
break;
}
@@ -311,10 +336,11 @@ void BinkDecoder::videoPacket(VideoFrame &video) {
// And swap the planes with the reference planes
for (int i = 0; i < 4; i++)
SWAP(_curPlanes[i], _oldPlanes[i]);
-}
-void BinkDecoder::decodePlane(VideoFrame &video, int planeIdx, bool isChroma) {
+ _curFrame++;
+}
+void BinkDecoder::BinkVideoTrack::decodePlane(VideoFrame &video, int planeIdx, bool isChroma) {
uint32 blockWidth = isChroma ? ((_surface.w + 15) >> 4) : ((_surface.w + 7) >> 3);
uint32 blockHeight = isChroma ? ((_surface.h + 15) >> 4) : ((_surface.h + 7) >> 3);
uint32 width = isChroma ? (_surface.w >> 1) : _surface.w;
@@ -371,48 +397,38 @@ void BinkDecoder::decodePlane(VideoFrame &video, int planeIdx, bool isChroma) {
}
switch (blockType) {
- case kBlockSkip:
- blockSkip(ctx);
- break;
-
- case kBlockScaled:
- blockScaled(ctx);
- break;
-
- case kBlockMotion:
- blockMotion(ctx);
- break;
-
- case kBlockRun:
- blockRun(ctx);
- break;
-
- case kBlockResidue:
- blockResidue(ctx);
- break;
-
- case kBlockIntra:
- blockIntra(ctx);
- break;
-
- case kBlockFill:
- blockFill(ctx);
- break;
-
- case kBlockInter:
- blockInter(ctx);
- break;
-
- case kBlockPattern:
- blockPattern(ctx);
- break;
-
- case kBlockRaw:
- blockRaw(ctx);
- break;
-
- default:
- error("Unknown block type: %d", blockType);
+ case kBlockSkip:
+ blockSkip(ctx);
+ break;
+ case kBlockScaled:
+ blockScaled(ctx);
+ break;
+ case kBlockMotion:
+ blockMotion(ctx);
+ break;
+ case kBlockRun:
+ blockRun(ctx);
+ break;
+ case kBlockResidue:
+ blockResidue(ctx);
+ break;
+ case kBlockIntra:
+ blockIntra(ctx);
+ break;
+ case kBlockFill:
+ blockFill(ctx);
+ break;
+ case kBlockInter:
+ blockInter(ctx);
+ break;
+ case kBlockPattern:
+ blockPattern(ctx);
+ break;
+ case kBlockRaw:
+ blockRaw(ctx);
+ break;
+ default:
+ error("Unknown block type: %d", blockType);
}
}
@@ -424,7 +440,7 @@ void BinkDecoder::decodePlane(VideoFrame &video, int planeIdx, bool isChroma) {
}
-void BinkDecoder::readBundle(VideoFrame &video, Source source) {
+void BinkDecoder::BinkVideoTrack::readBundle(VideoFrame &video, Source source) {
if (source == kSourceColors) {
for (int i = 0; i < 16; i++)
readHuffman(video, _colHighHuffman[i]);
@@ -439,12 +455,11 @@ void BinkDecoder::readBundle(VideoFrame &video, Source source) {
_bundles[source].curPtr = _bundles[source].data;
}
-void BinkDecoder::readHuffman(VideoFrame &video, Huffman &huffman) {
+void BinkDecoder::BinkVideoTrack::readHuffman(VideoFrame &video, Huffman &huffman) {
huffman.index = video.bits->getBits(4);
if (huffman.index == 0) {
// The first tree always gives raw nibbles
-
for (int i = 0; i < 16; i++)
huffman.symbols[i] = i;
@@ -455,7 +470,6 @@ void BinkDecoder::readHuffman(VideoFrame &video, Huffman &huffman) {
if (video.bits->getBit()) {
// Symbol selection
-
memset(hasSymbol, 0, 16);
uint8 length = video.bits->getBits(3);
@@ -493,9 +507,9 @@ void BinkDecoder::readHuffman(VideoFrame &video, Huffman &huffman) {
memcpy(huffman.symbols, in, 16);
}
-void BinkDecoder::mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size) {
+void BinkDecoder::BinkVideoTrack::mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size) {
const byte *src2 = src + size;
- int size2 = size;
+ int size2 = size;
do {
if (!video.bits->getBit()) {
@@ -510,197 +524,12 @@ void BinkDecoder::mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *
while (size--)
*dst++ = *src++;
+
while (size2--)
*dst++ = *src2++;
}
-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();
- if ((_id != kBIKfID) && (_id != kBIKgID) && (_id != kBIKhID) && (_id != kBIKiID))
- return false;
-
- uint32 fileSize = stream->readUint32LE() + 8;
- uint32 frameCount = stream->readUint32LE();
- uint32 largestFrameSize = stream->readUint32LE();
-
- if (largestFrameSize > fileSize) {
- warning("Largest frame size greater than file size");
- return false;
- }
-
- stream->skip(4);
-
- uint32 width = stream->readUint32LE();
- uint32 height = stream->readUint32LE();
-
- uint32 frameRateNum = stream->readUint32LE();
- uint32 frameRateDen = stream->readUint32LE();
- if (frameRateNum == 0 || frameRateDen == 0) {
- warning("Invalid frame rate (%d/%d)", frameRateNum, frameRateDen);
- return false;
- }
-
- _frameRate = Common::Rational(frameRateNum, frameRateDen);
- _bink = stream;
-
- _videoFlags = _bink->readUint32LE();
-
- uint32 audioTrackCount = _bink->readUint32LE();
-
- if (audioTrackCount > 1) {
- warning("More than one audio track found. Using the first one");
-
- _audioTrack = 0;
- }
-
- if (audioTrackCount > 0) {
- _audioTracks.reserve(audioTrackCount);
-
- _bink->skip(4 * audioTrackCount);
-
- // Reading audio track properties
- for (uint32 i = 0; i < audioTrackCount; i++) {
- AudioTrack track;
-
- track.sampleRate = _bink->readUint16LE();
- track.flags = _bink->readUint16LE();
-
- _audioTracks.push_back(track);
-
- initAudioTrack(_audioTracks[i]);
- }
-
- _bink->skip(4 * audioTrackCount);
- }
-
- // Reading video frame properties
- _frames.resize(frameCount);
- for (uint32 i = 0; i < frameCount; i++) {
- _frames[i].offset = _bink->readUint32LE();
- _frames[i].keyFrame = _frames[i].offset & 1;
-
- _frames[i].offset &= ~1;
-
- if (i != 0)
- _frames[i - 1].size = _frames[i].offset - _frames[i - 1].offset;
-
- _frames[i].bits = 0;
- }
-
- _frames[frameCount - 1].size = _bink->size() - _frames[frameCount - 1].offset;
-
- _hasAlpha = _videoFlags & kVideoFlagAlpha;
- _swapPlanes = (_id == kBIKhID) || (_id == kBIKiID); // BIKh and BIKi swap the chroma planes
-
- _surface.create(width, height, format);
-
- // Give the planes a bit extra space
- width = _surface.w + 32;
- height = _surface.h + 32;
-
- _curPlanes[0] = new byte[ width * height ]; // Y
- _curPlanes[1] = new byte[(width >> 1) * (height >> 1)]; // U, 1/4 resolution
- _curPlanes[2] = new byte[(width >> 1) * (height >> 1)]; // V, 1/4 resolution
- _curPlanes[3] = new byte[ width * height ]; // A
- _oldPlanes[0] = new byte[ width * height ]; // Y
- _oldPlanes[1] = new byte[(width >> 1) * (height >> 1)]; // U, 1/4 resolution
- _oldPlanes[2] = new byte[(width >> 1) * (height >> 1)]; // V, 1/4 resolution
- _oldPlanes[3] = new byte[ width * height ]; // A
-
- // Initialize the video with solid black
- memset(_curPlanes[0], 0, width * height );
- memset(_curPlanes[1], 0, (width >> 1) * (height >> 1));
- memset(_curPlanes[2], 0, (width >> 1) * (height >> 1));
- memset(_curPlanes[3], 255, width * height );
- memset(_oldPlanes[0], 0, width * height );
- memset(_oldPlanes[1], 0, (width >> 1) * (height >> 1));
- memset(_oldPlanes[2], 0, (width >> 1) * (height >> 1));
- memset(_oldPlanes[3], 255, width * height );
-
- initBundles();
- initHuffman();
-
- startAudio();
- _audioStartOffset = 0;
-
- return true;
-}
-
-void BinkDecoder::initAudioTrack(AudioTrack &audio) {
- audio.sampleCount = 0;
- audio.bits = 0;
-
- audio.channels = ((audio.flags & kAudioFlagStereo) != 0) ? 2 : 1;
- audio.codec = ((audio.flags & kAudioFlagDCT ) != 0) ? kAudioCodecDCT : kAudioCodecRDFT;
-
- if (audio.channels > kAudioChannelsMax)
- error("Too many audio channels: %d", audio.channels);
-
- uint32 frameLenBits;
- // Calculate frame length
- if (audio.sampleRate < 22050)
- frameLenBits = 9;
- else if(audio.sampleRate < 44100)
- frameLenBits = 10;
- else
- frameLenBits = 11;
-
- audio.frameLen = 1 << frameLenBits;
-
- audio.outSampleRate = audio.sampleRate;
- audio.outChannels = audio.channels;
-
- if (audio.codec == kAudioCodecRDFT) {
- // RDFT audio already interleaves the samples correctly
-
- if (audio.channels == 2)
- frameLenBits++;
-
- audio.sampleRate *= audio.channels;
- audio.frameLen *= audio.channels;
- audio.channels = 1;
- }
-
- audio.overlapLen = audio.frameLen / 16;
- audio.blockSize = (audio.frameLen - audio.overlapLen) * audio.channels;
- audio.root = 2.0 / sqrt((double)audio.frameLen);
-
- uint32 sampleRateHalf = (audio.sampleRate + 1) / 2;
-
- // Calculate number of bands
- for (audio.bandCount = 1; audio.bandCount < 25; audio.bandCount++)
- if (sampleRateHalf <= binkCriticalFreqs[audio.bandCount - 1])
- break;
-
- audio.bands = new uint32[audio.bandCount + 1];
-
- // Populate bands
- audio.bands[0] = 1;
- for (uint32 i = 1; i < audio.bandCount; i++)
- audio.bands[i] = binkCriticalFreqs[i - 1] * (audio.frameLen / 2) / sampleRateHalf;
- audio.bands[audio.bandCount] = audio.frameLen / 2;
-
- audio.first = true;
-
- for (uint8 i = 0; i < audio.channels; i++)
- audio.coeffsPtr[i] = audio.coeffs + i * audio.frameLen;
-
- audio.codec = ((audio.flags & kAudioFlagDCT) != 0) ? kAudioCodecDCT : kAudioCodecRDFT;
-
- if (audio.codec == kAudioCodecRDFT)
- audio.rdft = new Common::RDFT(frameLenBits, Common::RDFT::DFT_C2R);
- else if (audio.codec == kAudioCodecDCT)
- audio.dct = new Common::DCT(frameLenBits, Common::DCT::DCT_III);
-}
-
-void BinkDecoder::initBundles() {
+void BinkDecoder::BinkVideoTrack::initBundles() {
uint32 bw = (_surface.w + 7) >> 3;
uint32 bh = (_surface.h + 7) >> 3;
uint32 blocks = bw * bh;
@@ -729,21 +558,21 @@ void BinkDecoder::initBundles() {
}
}
-void BinkDecoder::deinitBundles() {
+void BinkDecoder::BinkVideoTrack::deinitBundles() {
for (int i = 0; i < kSourceMAX; i++)
delete[] _bundles[i].data;
}
-void BinkDecoder::initHuffman() {
+void BinkDecoder::BinkVideoTrack::initHuffman() {
for (int i = 0; i < 16; i++)
_huffman[i] = new Common::Huffman(binkHuffmanLengths[i][15], 16, binkHuffmanCodes[i], binkHuffmanLengths[i]);
}
-byte BinkDecoder::getHuffmanSymbol(VideoFrame &video, Huffman &huffman) {
+byte BinkDecoder::BinkVideoTrack::getHuffmanSymbol(VideoFrame &video, Huffman &huffman) {
return huffman.symbols[_huffman[huffman.index]->getSymbol(*video.bits)];
}
-int32 BinkDecoder::getBundleValue(Source source) {
+int32 BinkDecoder::BinkVideoTrack::getBundleValue(Source source) {
if ((source < kSourceXOff) || (source == kSourceRun))
return *_bundles[source].curPtr++;
@@ -757,7 +586,7 @@ int32 BinkDecoder::getBundleValue(Source source) {
return ret;
}
-uint32 BinkDecoder::readBundleCount(VideoFrame &video, Bundle &bundle) {
+uint32 BinkDecoder::BinkVideoTrack::readBundleCount(VideoFrame &video, Bundle &bundle) {
if (!bundle.curDec || (bundle.curDec > bundle.curPtr))
return 0;
@@ -768,7 +597,7 @@ uint32 BinkDecoder::readBundleCount(VideoFrame &video, Bundle &bundle) {
return n;
}
-void BinkDecoder::blockSkip(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockSkip(DecodeContext &ctx) {
byte *dest = ctx.dest;
byte *prev = ctx.prev;
@@ -776,7 +605,7 @@ void BinkDecoder::blockSkip(DecodeContext &ctx) {
memcpy(dest, prev, 8);
}
-void BinkDecoder::blockScaledSkip(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockScaledSkip(DecodeContext &ctx) {
byte *dest = ctx.dest;
byte *prev = ctx.prev;
@@ -784,7 +613,7 @@ void BinkDecoder::blockScaledSkip(DecodeContext &ctx) {
memcpy(dest, prev, 16);
}
-void BinkDecoder::blockScaledRun(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockScaledRun(DecodeContext &ctx) {
const uint8 *scan = binkPatterns[ctx.video->bits->getBits(4)];
int i = 0;
@@ -820,7 +649,7 @@ void BinkDecoder::blockScaledRun(DecodeContext &ctx) {
ctx.dest[ctx.coordScaledMap4[*scan]] = getBundleValue(kSourceColors);
}
-void BinkDecoder::blockScaledIntra(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockScaledIntra(DecodeContext &ctx) {
int16 block[64];
memset(block, 0, 64 * sizeof(int16));
@@ -841,7 +670,7 @@ void BinkDecoder::blockScaledIntra(DecodeContext &ctx) {
}
}
-void BinkDecoder::blockScaledFill(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockScaledFill(DecodeContext &ctx) {
byte v = getBundleValue(kSourceColors);
byte *dest = ctx.dest;
@@ -849,7 +678,7 @@ void BinkDecoder::blockScaledFill(DecodeContext &ctx) {
memset(dest, v, 16);
}
-void BinkDecoder::blockScaledPattern(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockScaledPattern(DecodeContext &ctx) {
byte col[2];
for (int i = 0; i < 2; i++)
@@ -865,7 +694,7 @@ void BinkDecoder::blockScaledPattern(DecodeContext &ctx) {
}
}
-void BinkDecoder::blockScaledRaw(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockScaledRaw(DecodeContext &ctx) {
byte row[8];
byte *dest1 = ctx.dest;
@@ -880,32 +709,27 @@ void BinkDecoder::blockScaledRaw(DecodeContext &ctx) {
}
}
-void BinkDecoder::blockScaled(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockScaled(DecodeContext &ctx) {
BlockType blockType = (BlockType) getBundleValue(kSourceSubBlockTypes);
switch (blockType) {
- case kBlockRun:
- blockScaledRun(ctx);
- break;
-
- case kBlockIntra:
- blockScaledIntra(ctx);
- break;
-
- case kBlockFill:
- blockScaledFill(ctx);
- break;
-
- case kBlockPattern:
- blockScaledPattern(ctx);
- break;
-
- case kBlockRaw:
- blockScaledRaw(ctx);
- break;
-
- default:
- error("Invalid 16x16 block type: %d", blockType);
+ case kBlockRun:
+ blockScaledRun(ctx);
+ break;
+ case kBlockIntra:
+ blockScaledIntra(ctx);
+ break;
+ case kBlockFill:
+ blockScaledFill(ctx);
+ break;
+ case kBlockPattern:
+ blockScaledPattern(ctx);
+ break;
+ case kBlockRaw:
+ blockScaledRaw(ctx);
+ break;
+ default:
+ error("Invalid 16x16 block type: %d", blockType);
}
ctx.blockX += 1;
@@ -913,7 +737,7 @@ void BinkDecoder::blockScaled(DecodeContext &ctx) {
ctx.prev += 8;
}
-void BinkDecoder::blockMotion(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockMotion(DecodeContext &ctx) {
int8 xOff = getBundleValue(kSourceXOff);
int8 yOff = getBundleValue(kSourceYOff);
@@ -926,7 +750,7 @@ void BinkDecoder::blockMotion(DecodeContext &ctx) {
memcpy(dest, prev, 8);
}
-void BinkDecoder::blockRun(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockRun(DecodeContext &ctx) {
const uint8 *scan = binkPatterns[ctx.video->bits->getBits(4)];
int i = 0;
@@ -953,7 +777,7 @@ void BinkDecoder::blockRun(DecodeContext &ctx) {
ctx.dest[ctx.coordMap[*scan++]] = getBundleValue(kSourceColors);
}
-void BinkDecoder::blockResidue(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockResidue(DecodeContext &ctx) {
blockMotion(ctx);
byte v = ctx.video->bits->getBits(7);
@@ -970,7 +794,7 @@ void BinkDecoder::blockResidue(DecodeContext &ctx) {
dst[j] += src[j];
}
-void BinkDecoder::blockIntra(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockIntra(DecodeContext &ctx) {
int16 block[64];
memset(block, 0, 64 * sizeof(int16));
@@ -981,7 +805,7 @@ void BinkDecoder::blockIntra(DecodeContext &ctx) {
IDCTPut(ctx, block);
}
-void BinkDecoder::blockFill(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockFill(DecodeContext &ctx) {
byte v = getBundleValue(kSourceColors);
byte *dest = ctx.dest;
@@ -989,7 +813,7 @@ void BinkDecoder::blockFill(DecodeContext &ctx) {
memset(dest, v, 8);
}
-void BinkDecoder::blockInter(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockInter(DecodeContext &ctx) {
blockMotion(ctx);
int16 block[64];
@@ -1002,7 +826,7 @@ void BinkDecoder::blockInter(DecodeContext &ctx) {
IDCTAdd(ctx, block);
}
-void BinkDecoder::blockPattern(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockPattern(DecodeContext &ctx) {
byte col[2];
for (int i = 0; i < 2; i++)
@@ -1017,7 +841,7 @@ void BinkDecoder::blockPattern(DecodeContext &ctx) {
}
}
-void BinkDecoder::blockRaw(DecodeContext &ctx) {
+void BinkDecoder::BinkVideoTrack::blockRaw(DecodeContext &ctx) {
byte *dest = ctx.dest;
byte *data = _bundles[kSourceColors].curPtr;
for (int i = 0; i < 8; i++, dest += ctx.pitch, data += 8)
@@ -1026,7 +850,7 @@ void BinkDecoder::blockRaw(DecodeContext &ctx) {
_bundles[kSourceColors].curPtr += 64;
}
-void BinkDecoder::readRuns(VideoFrame &video, Bundle &bundle) {
+void BinkDecoder::BinkVideoTrack::readRuns(VideoFrame &video, Bundle &bundle) {
uint32 n = readBundleCount(video, bundle);
if (n == 0)
return;
@@ -1046,7 +870,7 @@ void BinkDecoder::readRuns(VideoFrame &video, Bundle &bundle) {
*bundle.curDec++ = getHuffmanSymbol(video, bundle.huffman);
}
-void BinkDecoder::readMotionValues(VideoFrame &video, Bundle &bundle) {
+void BinkDecoder::BinkVideoTrack::readMotionValues(VideoFrame &video, Bundle &bundle) {
uint32 n = readBundleCount(video, bundle);
if (n == 0)
return;
@@ -1083,7 +907,7 @@ void BinkDecoder::readMotionValues(VideoFrame &video, Bundle &bundle) {
}
const uint8 rleLens[4] = { 4, 8, 12, 32 };
-void BinkDecoder::readBlockTypes(VideoFrame &video, Bundle &bundle) {
+void BinkDecoder::BinkVideoTrack::readBlockTypes(VideoFrame &video, Bundle &bundle) {
uint32 n = readBundleCount(video, bundle);
if (n == 0)
return;
@@ -1120,7 +944,7 @@ void BinkDecoder::readBlockTypes(VideoFrame &video, Bundle &bundle) {
} while (bundle.curDec < decEnd);
}
-void BinkDecoder::readPatterns(VideoFrame &video, Bundle &bundle) {
+void BinkDecoder::BinkVideoTrack::readPatterns(VideoFrame &video, Bundle &bundle) {
uint32 n = readBundleCount(video, bundle);
if (n == 0)
return;
@@ -1138,7 +962,7 @@ void BinkDecoder::readPatterns(VideoFrame &video, Bundle &bundle) {
}
-void BinkDecoder::readColors(VideoFrame &video, Bundle &bundle) {
+void BinkDecoder::BinkVideoTrack::readColors(VideoFrame &video, Bundle &bundle) {
uint32 n = readBundleCount(video, bundle);
if (n == 0)
return;
@@ -1182,7 +1006,7 @@ void BinkDecoder::readColors(VideoFrame &video, Bundle &bundle) {
}
}
-void BinkDecoder::readDCS(VideoFrame &video, Bundle &bundle, int startBits, bool hasSign) {
+void BinkDecoder::BinkVideoTrack::readDCS(VideoFrame &video, Bundle &bundle, int startBits, bool hasSign) {
uint32 length = readBundleCount(video, bundle);
if (length == 0)
return;
@@ -1228,7 +1052,7 @@ void BinkDecoder::readDCS(VideoFrame &video, Bundle &bundle, int startBits, bool
}
/** Reads 8x8 block of DCT coefficients. */
-void BinkDecoder::readDCTCoeffs(VideoFrame &video, int16 *block, bool isIntra) {
+void BinkDecoder::BinkVideoTrack::readDCTCoeffs(VideoFrame &video, int16 *block, bool isIntra) {
int coefCount = 0;
int coefIdx[64];
@@ -1326,7 +1150,7 @@ void BinkDecoder::readDCTCoeffs(VideoFrame &video, int16 *block, bool isIntra) {
}
/** Reads 8x8 block with residue after motion compensation. */
-void BinkDecoder::readResidue(VideoFrame &video, int16 *block, int masksCount) {
+void BinkDecoder::BinkVideoTrack::readResidue(VideoFrame &video, int16 *block, int masksCount) {
int nzCoeff[64];
int nzCoeffCount = 0;
@@ -1417,63 +1241,170 @@ void BinkDecoder::readResidue(VideoFrame &video, int16 *block, int masksCount) {
}
}
-float BinkDecoder::getFloat(AudioTrack &audio) {
- int power = audio.bits->getBits(5);
+#define A1 2896 /* (1/sqrt(2))<<12 */
+#define A2 2217
+#define A3 3784
+#define A4 -5352
- float f = ldexp((float)audio.bits->getBits(23), power - 23);
+#define IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) {\
+ const int a0 = (src)[s0] + (src)[s4]; \
+ const int a1 = (src)[s0] - (src)[s4]; \
+ const int a2 = (src)[s2] + (src)[s6]; \
+ const int a3 = (A1*((src)[s2] - (src)[s6])) >> 11; \
+ const int a4 = (src)[s5] + (src)[s3]; \
+ const int a5 = (src)[s5] - (src)[s3]; \
+ const int a6 = (src)[s1] + (src)[s7]; \
+ const int a7 = (src)[s1] - (src)[s7]; \
+ const int b0 = a4 + a6; \
+ const int b1 = (A3*(a5 + a7)) >> 11; \
+ const int b2 = ((A4*a5) >> 11) - b0 + b1; \
+ const int b3 = (A1*(a6 - a4) >> 11) - b2; \
+ const int b4 = ((A2*a7) >> 11) + b3 - b1; \
+ (dest)[d0] = munge(a0+a2 +b0); \
+ (dest)[d1] = munge(a1+a3-a2+b2); \
+ (dest)[d2] = munge(a1-a3+a2+b3); \
+ (dest)[d3] = munge(a0-a2 -b4); \
+ (dest)[d4] = munge(a0-a2 +b4); \
+ (dest)[d5] = munge(a1-a3+a2-b3); \
+ (dest)[d6] = munge(a1+a3-a2-b2); \
+ (dest)[d7] = munge(a0+a2 -b0); \
+}
+/* end IDCT_TRANSFORM macro */
- if (audio.bits->getBit())
- f = -f;
+#define MUNGE_NONE(x) (x)
+#define IDCT_COL(dest,src) IDCT_TRANSFORM(dest,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,MUNGE_NONE,src)
- return f;
+#define MUNGE_ROW(x) (((x) + 0x7F)>>8)
+#define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src)
+
+static inline void IDCTCol(int16 *dest, const int16 *src) {
+ if ((src[8] | src[16] | src[24] | src[32] | src[40] | src[48] | src[56]) == 0) {
+ dest[ 0] =
+ dest[ 8] =
+ dest[16] =
+ dest[24] =
+ dest[32] =
+ dest[40] =
+ dest[48] =
+ dest[56] = src[0];
+ } else {
+ IDCT_COL(dest, src);
+ }
+}
+
+void BinkDecoder::BinkVideoTrack::IDCT(int16 *block) {
+ int i;
+ int16 temp[64];
+
+ for (i = 0; i < 8; i++)
+ IDCTCol(&temp[i], &block[i]);
+ for (i = 0; i < 8; i++) {
+ IDCT_ROW( (&block[8*i]), (&temp[8*i]) );
+ }
+}
+
+void BinkDecoder::BinkVideoTrack::IDCTAdd(DecodeContext &ctx, int16 *block) {
+ int i, j;
+
+ IDCT(block);
+ byte *dest = ctx.dest;
+ for (i = 0; i < 8; i++, dest += ctx.pitch, block += 8)
+ for (j = 0; j < 8; j++)
+ dest[j] += block[j];
+}
+
+void BinkDecoder::BinkVideoTrack::IDCTPut(DecodeContext &ctx, int16 *block) {
+ int i;
+ int16 temp[64];
+ for (i = 0; i < 8; i++)
+ IDCTCol(&temp[i], &block[i]);
+ for (i = 0; i < 8; i++) {
+ IDCT_ROW( (&ctx.dest[i*ctx.pitch]), (&temp[8*i]) );
+ }
+}
+
+BinkDecoder::BinkAudioTrack::BinkAudioTrack(BinkDecoder::AudioInfo &audio) : _audioInfo(&audio) {
+ _audioStream = Audio::makeQueuingAudioStream(_audioInfo->outSampleRate, _audioInfo->outChannels == 2);
+}
+
+BinkDecoder::BinkAudioTrack::~BinkAudioTrack() {
+ delete _audioStream;
+}
+
+Audio::AudioStream *BinkDecoder::BinkAudioTrack::getAudioStream() const {
+ return _audioStream;
+}
+
+void BinkDecoder::BinkAudioTrack::decodePacket() {
+ int outSize = _audioInfo->frameLen * _audioInfo->channels;
+
+ while (_audioInfo->bits->pos() < _audioInfo->bits->size()) {
+ int16 *out = (int16 *)malloc(outSize * 2);
+ memset(out, 0, outSize * 2);
+
+ audioBlock(out);
+
+ byte flags = Audio::FLAG_16BITS;
+ if (_audioInfo->outChannels == 2)
+ flags |= Audio::FLAG_STEREO;
+
+#ifdef SCUMM_LITTLE_ENDIAN
+ flags |= Audio::FLAG_LITTLE_ENDIAN;
+#endif
+
+ _audioStream->queueBuffer((byte *)out, _audioInfo->blockSize * 2, DisposeAfterUse::YES, flags);
+
+ if (_audioInfo->bits->pos() & 0x1F) // next data block starts at a 32-byte boundary
+ _audioInfo->bits->skip(32 - (_audioInfo->bits->pos() & 0x1F));
+ }
}
-void BinkDecoder::audioBlock(AudioTrack &audio, int16 *out) {
- if (audio.codec == kAudioCodecDCT)
- audioBlockDCT (audio);
- else if (audio.codec == kAudioCodecRDFT)
- audioBlockRDFT(audio);
+void BinkDecoder::BinkAudioTrack::audioBlock(int16 *out) {
+ if (_audioInfo->codec == kAudioCodecDCT)
+ audioBlockDCT ();
+ else if (_audioInfo->codec == kAudioCodecRDFT)
+ audioBlockRDFT();
- floatToInt16Interleave(out, const_cast<const float **>(audio.coeffsPtr), audio.frameLen, audio.channels);
+ floatToInt16Interleave(out, const_cast<const float **>(_audioInfo->coeffsPtr), _audioInfo->frameLen, _audioInfo->channels);
- if (!audio.first) {
- int count = audio.overlapLen * audio.channels;
+ if (!_audioInfo->first) {
+ int count = _audioInfo->overlapLen * _audioInfo->channels;
int shift = Common::intLog2(count);
for (int i = 0; i < count; i++) {
- out[i] = (audio.prevCoeffs[i] * (count - i) + out[i] * i) >> shift;
+ out[i] = (_audioInfo->prevCoeffs[i] * (count - i) + out[i] * i) >> shift;
}
}
- memcpy(audio.prevCoeffs, out + audio.blockSize, audio.overlapLen * audio.channels * sizeof(*out));
+ memcpy(_audioInfo->prevCoeffs, out + _audioInfo->blockSize, _audioInfo->overlapLen * _audioInfo->channels * sizeof(*out));
- audio.first = false;
+ _audioInfo->first = false;
}
-void BinkDecoder::audioBlockDCT(AudioTrack &audio) {
- audio.bits->skip(2);
+void BinkDecoder::BinkAudioTrack::audioBlockDCT() {
+ _audioInfo->bits->skip(2);
- for (uint8 i = 0; i < audio.channels; i++) {
- float *coeffs = audio.coeffsPtr[i];
+ for (uint8 i = 0; i < _audioInfo->channels; i++) {
+ float *coeffs = _audioInfo->coeffsPtr[i];
- readAudioCoeffs(audio, coeffs);
+ readAudioCoeffs(coeffs);
coeffs[0] /= 0.5;
- audio.dct->calc(coeffs);
+ _audioInfo->dct->calc(coeffs);
- for (uint32 j = 0; j < audio.frameLen; j++)
- coeffs[j] *= (audio.frameLen / 2.0);
+ for (uint32 j = 0; j < _audioInfo->frameLen; j++)
+ coeffs[j] *= (_audioInfo->frameLen / 2.0);
}
}
-void BinkDecoder::audioBlockRDFT(AudioTrack &audio) {
- for (uint8 i = 0; i < audio.channels; i++) {
- float *coeffs = audio.coeffsPtr[i];
+void BinkDecoder::BinkAudioTrack::audioBlockRDFT() {
+ for (uint8 i = 0; i < _audioInfo->channels; i++) {
+ float *coeffs = _audioInfo->coeffsPtr[i];
- readAudioCoeffs(audio, coeffs);
+ readAudioCoeffs(coeffs);
- audio.rdft->calc(coeffs);
+ _audioInfo->rdft->calc(coeffs);
}
}
@@ -1481,56 +1412,56 @@ static const uint8 rleLengthTab[16] = {
2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 32, 64
};
-void BinkDecoder::readAudioCoeffs(AudioTrack &audio, float *coeffs) {
- coeffs[0] = getFloat(audio) * audio.root;
- coeffs[1] = getFloat(audio) * audio.root;
+void BinkDecoder::BinkAudioTrack::readAudioCoeffs(float *coeffs) {
+ coeffs[0] = getFloat() * _audioInfo->root;
+ coeffs[1] = getFloat() * _audioInfo->root;
float quant[25];
- for (uint32 i = 0; i < audio.bandCount; i++) {
- int value = audio.bits->getBits(8);
+ for (uint32 i = 0; i < _audioInfo->bandCount; i++) {
+ int value = _audioInfo->bits->getBits(8);
// 0.066399999 / log10(M_E)
- quant[i] = exp(MIN(value, 95) * 0.15289164787221953823f) * audio.root;
+ quant[i] = exp(MIN(value, 95) * 0.15289164787221953823f) * _audioInfo->root;
}
float q = 0.0;
// Find band (k)
int k;
- for (k = 0; audio.bands[k] < 1; k++)
+ for (k = 0; _audioInfo->bands[k] < 1; k++)
q = quant[k];
// Parse coefficients
uint32 i = 2;
- while (i < audio.frameLen) {
+ while (i < _audioInfo->frameLen) {
uint32 j = 0;
- if (audio.bits->getBit())
- j = i + rleLengthTab[audio.bits->getBits(4)] * 8;
+ if (_audioInfo->bits->getBit())
+ j = i + rleLengthTab[_audioInfo->bits->getBits(4)] * 8;
else
j = i + 8;
- j = MIN(j, audio.frameLen);
+ j = MIN(j, _audioInfo->frameLen);
- int width = audio.bits->getBits(4);
+ int width = _audioInfo->bits->getBits(4);
if (width == 0) {
memset(coeffs + i, 0, (j - i) * sizeof(*coeffs));
i = j;
- while (audio.bands[k] * 2 < i)
+ while (_audioInfo->bands[k] * 2 < i)
q = quant[k++];
} else {
while (i < j) {
- if (audio.bands[k] * 2 == i)
+ if (_audioInfo->bands[k] * 2 == i)
q = quant[k++];
- int coeff = audio.bits->getBits(width);
+ int coeff = _audioInfo->bits->getBits(width);
if (coeff) {
- if (audio.bits->getBit())
+ if (_audioInfo->bits->getBit())
coeffs[i] = -q * coeff;
else
coeffs[i] = q * coeff;
@@ -1548,10 +1479,10 @@ void BinkDecoder::readAudioCoeffs(AudioTrack &audio, float *coeffs) {
}
static inline int floatToInt16One(float src) {
- return (int16) CLIP<int>((int) floor(src + 0.5), -32768, 32767);
+ return (int16)CLIP<int>((int)floor(src + 0.5), -32768, 32767);
}
-void BinkDecoder::floatToInt16Interleave(int16 *dst, const float **src, uint32 length, uint8 channels) {
+void BinkDecoder::BinkAudioTrack::floatToInt16Interleave(int16 *dst, const float **src, uint32 length, uint8 channels) {
if (channels == 2) {
for (uint32 i = 0; i < length; i++) {
dst[2 * i ] = floatToInt16One(src[0][i]);
@@ -1564,87 +1495,84 @@ void BinkDecoder::floatToInt16Interleave(int16 *dst, const float **src, uint32 l
}
}
-#define A1 2896 /* (1/sqrt(2))<<12 */
-#define A2 2217
-#define A3 3784
-#define A4 -5352
+float BinkDecoder::BinkAudioTrack::getFloat() {
+ int power = _audioInfo->bits->getBits(5);
-#define IDCT_TRANSFORM(dest,s0,s1,s2,s3,s4,s5,s6,s7,d0,d1,d2,d3,d4,d5,d6,d7,munge,src) {\
- const int a0 = (src)[s0] + (src)[s4]; \
- const int a1 = (src)[s0] - (src)[s4]; \
- const int a2 = (src)[s2] + (src)[s6]; \
- const int a3 = (A1*((src)[s2] - (src)[s6])) >> 11; \
- const int a4 = (src)[s5] + (src)[s3]; \
- const int a5 = (src)[s5] - (src)[s3]; \
- const int a6 = (src)[s1] + (src)[s7]; \
- const int a7 = (src)[s1] - (src)[s7]; \
- const int b0 = a4 + a6; \
- const int b1 = (A3*(a5 + a7)) >> 11; \
- const int b2 = ((A4*a5) >> 11) - b0 + b1; \
- const int b3 = (A1*(a6 - a4) >> 11) - b2; \
- const int b4 = ((A2*a7) >> 11) + b3 - b1; \
- (dest)[d0] = munge(a0+a2 +b0); \
- (dest)[d1] = munge(a1+a3-a2+b2); \
- (dest)[d2] = munge(a1-a3+a2+b3); \
- (dest)[d3] = munge(a0-a2 -b4); \
- (dest)[d4] = munge(a0-a2 +b4); \
- (dest)[d5] = munge(a1-a3+a2-b3); \
- (dest)[d6] = munge(a1+a3-a2-b2); \
- (dest)[d7] = munge(a0+a2 -b0); \
+ float f = ldexp((float)_audioInfo->bits->getBits(23), power - 23);
+
+ if (_audioInfo->bits->getBit())
+ f = -f;
+
+ return f;
}
-/* end IDCT_TRANSFORM macro */
-#define MUNGE_NONE(x) (x)
-#define IDCT_COL(dest,src) IDCT_TRANSFORM(dest,0,8,16,24,32,40,48,56,0,8,16,24,32,40,48,56,MUNGE_NONE,src)
+void BinkDecoder::initAudioTrack(AudioInfo &audio) {
+ audio.sampleCount = 0;
+ audio.bits = 0;
-#define MUNGE_ROW(x) (((x) + 0x7F)>>8)
-#define IDCT_ROW(dest,src) IDCT_TRANSFORM(dest,0,1,2,3,4,5,6,7,0,1,2,3,4,5,6,7,MUNGE_ROW,src)
+ audio.channels = ((audio.flags & kAudioFlagStereo) != 0) ? 2 : 1;
+ audio.codec = ((audio.flags & kAudioFlagDCT ) != 0) ? kAudioCodecDCT : kAudioCodecRDFT;
-static inline void IDCTCol(int16 *dest, const int16 *src)
-{
- if ((src[8] | src[16] | src[24] | src[32] | src[40] | src[48] | src[56]) == 0) {
- dest[ 0] =
- dest[ 8] =
- dest[16] =
- dest[24] =
- dest[32] =
- dest[40] =
- dest[48] =
- dest[56] = src[0];
- } else {
- IDCT_COL(dest, src);
- }
-}
+ if (audio.channels > kAudioChannelsMax)
+ error("Too many audio channels: %d", audio.channels);
-void BinkDecoder::IDCT(int16 *block) {
- int i;
- int16 temp[64];
+ uint32 frameLenBits;
+ // Calculate frame length
+ if (audio.sampleRate < 22050)
+ frameLenBits = 9;
+ else if(audio.sampleRate < 44100)
+ frameLenBits = 10;
+ else
+ frameLenBits = 11;
- for (i = 0; i < 8; i++)
- IDCTCol(&temp[i], &block[i]);
- for (i = 0; i < 8; i++) {
- IDCT_ROW( (&block[8*i]), (&temp[8*i]) );
- }
-}
+ audio.frameLen = 1 << frameLenBits;
-void BinkDecoder::IDCTAdd(DecodeContext &ctx, int16 *block) {
- int i, j;
+ audio.outSampleRate = audio.sampleRate;
+ audio.outChannels = audio.channels;
- IDCT(block);
- byte *dest = ctx.dest;
- for (i = 0; i < 8; i++, dest += ctx.pitch, block += 8)
- for (j = 0; j < 8; j++)
- dest[j] += block[j];
-}
+ if (audio.codec == kAudioCodecRDFT) {
+ // RDFT audio already interleaves the samples correctly
-void BinkDecoder::IDCTPut(DecodeContext &ctx, int16 *block) {
- int i;
- int16 temp[64];
- for (i = 0; i < 8; i++)
- IDCTCol(&temp[i], &block[i]);
- for (i = 0; i < 8; i++) {
- IDCT_ROW( (&ctx.dest[i*ctx.pitch]), (&temp[8*i]) );
+ if (audio.channels == 2)
+ frameLenBits++;
+
+ audio.sampleRate *= audio.channels;
+ audio.frameLen *= audio.channels;
+ audio.channels = 1;
}
+
+ audio.overlapLen = audio.frameLen / 16;
+ audio.blockSize = (audio.frameLen - audio.overlapLen) * audio.channels;
+ audio.root = 2.0 / sqrt((double)audio.frameLen);
+
+ uint32 sampleRateHalf = (audio.sampleRate + 1) / 2;
+
+ // Calculate number of bands
+ for (audio.bandCount = 1; audio.bandCount < 25; audio.bandCount++)
+ if (sampleRateHalf <= binkCriticalFreqs[audio.bandCount - 1])
+ break;
+
+ audio.bands = new uint32[audio.bandCount + 1];
+
+ // Populate bands
+ audio.bands[0] = 1;
+ for (uint32 i = 1; i < audio.bandCount; i++)
+ audio.bands[i] = binkCriticalFreqs[i - 1] * (audio.frameLen / 2) / sampleRateHalf;
+ audio.bands[audio.bandCount] = audio.frameLen / 2;
+
+ audio.first = true;
+
+ for (uint8 i = 0; i < audio.channels; i++)
+ audio.coeffsPtr[i] = audio.coeffs + i * audio.frameLen;
+
+ audio.codec = ((audio.flags & kAudioFlagDCT) != 0) ? kAudioCodecDCT : kAudioCodecRDFT;
+
+ if (audio.codec == kAudioCodecRDFT)
+ audio.rdft = new Common::RDFT(frameLenBits, Common::RDFT::DFT_C2R);
+ else if (audio.codec == kAudioCodecDCT)
+ audio.dct = new Common::DCT(frameLenBits, Common::DCT::DCT_III);
+
+ addTrack(new BinkAudioTrack(audio));
}
} // End of namespace Video
diff --git a/video/bink_decoder.h b/video/bink_decoder.h
index 3d5e882dd7..150e91aab7 100644
--- a/video/bink_decoder.h
+++ b/video/bink_decoder.h
@@ -31,22 +31,27 @@
#ifndef VIDEO_BINK_DECODER_H
#define VIDEO_BINK_DECODER_H
-#include "audio/audiostream.h"
-#include "audio/mixer.h"
#include "common/array.h"
#include "common/rational.h"
-#include "graphics/surface.h"
-
#include "video/video_decoder.h"
+namespace Audio {
+class AudioStream;
+class QueuingAudioStream;
+}
+
namespace Common {
- class SeekableReadStream;
- class BitStream;
- class Huffman;
+class SeekableReadStream;
+class BitStream;
+class Huffman;
- class RDFT;
- class DCT;
+class RDFT;
+class DCT;
+}
+
+namespace Graphics {
+struct Surface;
}
namespace Video {
@@ -57,87 +62,28 @@ namespace Video {
* Video decoder used in engines:
* - scumm (he)
*/
-class BinkDecoder : public FixedRateVideoDecoder {
+class BinkDecoder : public VideoDecoder {
public:
BinkDecoder();
~BinkDecoder();
- // VideoDecoder API
bool loadStream(Common::SeekableReadStream *stream);
void close();
- bool isVideoLoaded() const { return _bink != 0; }
- uint16 getWidth() const { return _surface.w; }
- uint16 getHeight() const { return _surface.h; }
- Graphics::PixelFormat getPixelFormat() const { return _surface.format; }
- uint32 getFrameCount() const { return _frames.size(); }
- uint32 getElapsedTime() const;
- const Graphics::Surface *decodeNextFrame();
-
- // FixedRateVideoDecoder
- Common::Rational getFrameRate() const { return _frameRate; }
-
- // Bink specific
- bool loadStream(Common::SeekableReadStream *stream, const Graphics::PixelFormat &format);
+
protected:
+ void readNextPacket();
+
+private:
static const int kAudioChannelsMax = 2;
static const int kAudioBlockSizeMax = (kAudioChannelsMax << 11);
- /** IDs for different data types used in Bink video codec. */
- enum Source {
- kSourceBlockTypes = 0, ///< 8x8 block types.
- kSourceSubBlockTypes , ///< 16x16 block types (a subset of 8x8 block types).
- kSourceColors , ///< Pixel values used for different block types.
- kSourcePattern , ///< 8-bit values for 2-color pattern fill.
- kSourceXOff , ///< X components of motion value.
- kSourceYOff , ///< Y components of motion value.
- kSourceIntraDC , ///< DC values for intrablocks with DCT.
- kSourceInterDC , ///< DC values for interblocks with DCT.
- kSourceRun , ///< Run lengths for special fill block.
-
- kSourceMAX
- };
-
- /** Bink video block types. */
- enum BlockType {
- kBlockSkip = 0, ///< Skipped block.
- kBlockScaled , ///< Block has size 16x16.
- kBlockMotion , ///< Block is copied from previous frame with some offset.
- kBlockRun , ///< Block is composed from runs of colors with custom scan order.
- kBlockResidue , ///< Motion block with some difference added.
- kBlockIntra , ///< Intra DCT block.
- kBlockFill , ///< Block is filled with single color.
- kBlockInter , ///< Motion block with DCT applied to the difference.
- kBlockPattern , ///< Block is filled with two colors following custom pattern.
- kBlockRaw ///< Uncoded 8x8 block.
- };
-
- /** Data structure for decoding and tranlating Huffman'd data. */
- struct Huffman {
- int index; ///< Index of the Huffman codebook to use.
- byte symbols[16]; ///< Huffman symbol => Bink symbol tranlation list.
- };
-
- /** Data structure used for decoding a single Bink data type. */
- struct Bundle {
- int countLengths[2]; ///< Lengths of number of entries to decode (in bits).
- int countLength; ///< Length of number of entries to decode (in bits) for the current plane.
-
- Huffman huffman; ///< Huffman codebook.
-
- byte *data; ///< Buffer for decoded symbols.
- byte *dataEnd; ///< Buffer end.
-
- byte *curDec; ///< Pointer to the data that wasn't yet decoded.
- byte *curPtr; ///< Pointer to the data that wasn't yet read.
- };
-
enum AudioCodec {
kAudioCodecDCT,
kAudioCodecRDFT
};
/** An audio track. */
- struct AudioTrack {
+ struct AudioInfo {
uint16 flags;
uint32 sampleRate;
@@ -172,8 +118,8 @@ protected:
Common::RDFT *rdft;
Common::DCT *dct;
- AudioTrack();
- ~AudioTrack();
+ AudioInfo();
+ ~AudioInfo();
};
/** A video frame. */
@@ -189,149 +135,218 @@ protected:
~VideoFrame();
};
- /** A decoder state. */
- struct DecodeContext {
- VideoFrame *video;
+ class BinkVideoTrack : public FixedRateVideoTrack {
+ public:
+ BinkVideoTrack(uint32 width, uint32 height, const Graphics::PixelFormat &format, uint32 frameCount, const Common::Rational &frameRate, bool swapPlanes, bool hasAlpha, uint32 id);
+ ~BinkVideoTrack();
+
+ uint16 getWidth() const { return _surface.w; }
+ uint16 getHeight() const { return _surface.h; }
+ Graphics::PixelFormat getPixelFormat() const { return _surface.format; }
+ int getCurFrame() const { return _curFrame; }
+ int getFrameCount() const { return _frameCount; }
+ const Graphics::Surface *decodeNextFrame() { return &_surface; }
+
+ /** Decode a video packet. */
+ void decodePacket(VideoFrame &frame);
+
+ protected:
+ Common::Rational getFrameRate() const { return _frameRate; }
- uint32 planeIdx;
+ private:
+ /** A decoder state. */
+ struct DecodeContext {
+ VideoFrame *video;
+
+ uint32 planeIdx;
- uint32 blockX;
- uint32 blockY;
+ uint32 blockX;
+ uint32 blockY;
- byte *dest;
- byte *prev;
+ byte *dest;
+ byte *prev;
- byte *destStart, *destEnd;
- byte *prevStart, *prevEnd;
+ byte *destStart, *destEnd;
+ byte *prevStart, *prevEnd;
- uint32 pitch;
+ uint32 pitch;
- int coordMap[64];
- int coordScaledMap1[64];
- int coordScaledMap2[64];
- int coordScaledMap3[64];
- int coordScaledMap4[64];
+ int coordMap[64];
+ int coordScaledMap1[64];
+ int coordScaledMap2[64];
+ int coordScaledMap3[64];
+ int coordScaledMap4[64];
+ };
+
+ /** IDs for different data types used in Bink video codec. */
+ enum Source {
+ kSourceBlockTypes = 0, ///< 8x8 block types.
+ kSourceSubBlockTypes , ///< 16x16 block types (a subset of 8x8 block types).
+ kSourceColors , ///< Pixel values used for different block types.
+ kSourcePattern , ///< 8-bit values for 2-color pattern fill.
+ kSourceXOff , ///< X components of motion value.
+ kSourceYOff , ///< Y components of motion value.
+ kSourceIntraDC , ///< DC values for intrablocks with DCT.
+ kSourceInterDC , ///< DC values for interblocks with DCT.
+ kSourceRun , ///< Run lengths for special fill block.
+
+ kSourceMAX
+ };
+
+ /** Bink video block types. */
+ enum BlockType {
+ kBlockSkip = 0, ///< Skipped block.
+ kBlockScaled , ///< Block has size 16x16.
+ kBlockMotion , ///< Block is copied from previous frame with some offset.
+ kBlockRun , ///< Block is composed from runs of colors with custom scan order.
+ kBlockResidue , ///< Motion block with some difference added.
+ kBlockIntra , ///< Intra DCT block.
+ kBlockFill , ///< Block is filled with single color.
+ kBlockInter , ///< Motion block with DCT applied to the difference.
+ kBlockPattern , ///< Block is filled with two colors following custom pattern.
+ kBlockRaw ///< Uncoded 8x8 block.
+ };
+
+ /** Data structure for decoding and tranlating Huffman'd data. */
+ struct Huffman {
+ int index; ///< Index of the Huffman codebook to use.
+ byte symbols[16]; ///< Huffman symbol => Bink symbol tranlation list.
+ };
+
+ /** Data structure used for decoding a single Bink data type. */
+ struct Bundle {
+ int countLengths[2]; ///< Lengths of number of entries to decode (in bits).
+ int countLength; ///< Length of number of entries to decode (in bits) for the current plane.
+
+ Huffman huffman; ///< Huffman codebook.
+
+ byte *data; ///< Buffer for decoded symbols.
+ byte *dataEnd; ///< Buffer end.
+
+ byte *curDec; ///< Pointer to the data that wasn't yet decoded.
+ byte *curPtr; ///< Pointer to the data that wasn't yet read.
+ };
+
+ int _curFrame;
+ int _frameCount;
+
+ Graphics::Surface _surface;
+
+ uint32 _id; ///< The BIK FourCC.
+
+ bool _hasAlpha; ///< Do video frames have alpha?
+ bool _swapPlanes; ///< Are the planes ordered (A)YVU instead of (A)YUV?
+
+ Common::Rational _frameRate;
+
+ Bundle _bundles[kSourceMAX]; ///< Bundles for decoding all data types.
+
+ Common::Huffman *_huffman[16]; ///< The 16 Huffman codebooks used in Bink decoding.
+
+ /** Huffman codebooks to use for decoding high nibbles in color data types. */
+ Huffman _colHighHuffman[16];
+ /** Value of the last decoded high nibble in color data types. */
+ int _colLastVal;
+
+ byte *_curPlanes[4]; ///< The 4 color planes, YUVA, current frame.
+ byte *_oldPlanes[4]; ///< The 4 color planes, YUVA, last frame.
+
+ /** Initialize the bundles. */
+ void initBundles();
+ /** Deinitialize the bundles. */
+ void deinitBundles();
+
+ /** Initialize the Huffman decoders. */
+ void initHuffman();
+
+ /** Decode a plane. */
+ void decodePlane(VideoFrame &video, int planeIdx, bool isChroma);
+
+ /** Read/Initialize a bundle for decoding a plane. */
+ void readBundle(VideoFrame &video, Source source);
+
+ /** Read the symbols for a Huffman code. */
+ void readHuffman(VideoFrame &video, Huffman &huffman);
+ /** Merge two Huffman symbol lists. */
+ void mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size);
+
+ /** Read and translate a symbol out of a Huffman code. */
+ byte getHuffmanSymbol(VideoFrame &video, Huffman &huffman);
+
+ /** Get a direct value out of a bundle. */
+ int32 getBundleValue(Source source);
+ /** Read a count value out of a bundle. */
+ uint32 readBundleCount(VideoFrame &video, Bundle &bundle);
+
+ // Handle the block types
+ void blockSkip (DecodeContext &ctx);
+ void blockScaledSkip (DecodeContext &ctx);
+ void blockScaledRun (DecodeContext &ctx);
+ void blockScaledIntra (DecodeContext &ctx);
+ void blockScaledFill (DecodeContext &ctx);
+ void blockScaledPattern(DecodeContext &ctx);
+ void blockScaledRaw (DecodeContext &ctx);
+ void blockScaled (DecodeContext &ctx);
+ void blockMotion (DecodeContext &ctx);
+ void blockRun (DecodeContext &ctx);
+ void blockResidue (DecodeContext &ctx);
+ void blockIntra (DecodeContext &ctx);
+ void blockFill (DecodeContext &ctx);
+ void blockInter (DecodeContext &ctx);
+ void blockPattern (DecodeContext &ctx);
+ void blockRaw (DecodeContext &ctx);
+
+ // Read the bundles
+ void readRuns (VideoFrame &video, Bundle &bundle);
+ void readMotionValues(VideoFrame &video, Bundle &bundle);
+ void readBlockTypes (VideoFrame &video, Bundle &bundle);
+ void readPatterns (VideoFrame &video, Bundle &bundle);
+ void readColors (VideoFrame &video, Bundle &bundle);
+ void readDCS (VideoFrame &video, Bundle &bundle, int startBits, bool hasSign);
+ void readDCTCoeffs (VideoFrame &video, int16 *block, bool isIntra);
+ void readResidue (VideoFrame &video, int16 *block, int masksCount);
+
+ // Bink video IDCT
+ void IDCT(int16 *block);
+ void IDCTPut(DecodeContext &ctx, int16 *block);
+ void IDCTAdd(DecodeContext &ctx, int16 *block);
};
- Common::SeekableReadStream *_bink;
+ class BinkAudioTrack : public AudioTrack {
+ public:
+ BinkAudioTrack(AudioInfo &audio);
+ ~BinkAudioTrack();
+
+ /** Decode an audio packet. */
+ void decodePacket();
- uint32 _id; ///< The BIK FourCC.
+ protected:
+ Audio::AudioStream *getAudioStream() const;
- Common::Rational _frameRate;
+ private:
+ AudioInfo *_audioInfo;
+ Audio::QueuingAudioStream *_audioStream;
- Graphics::Surface _surface;
+ float getFloat();
- Audio::SoundHandle _audioHandle;
- Audio::QueuingAudioStream *_audioStream;
- int32 _audioStartOffset;
+ /** Decode an audio block. */
+ void audioBlock(int16 *out);
+ /** Decode a DCT'd audio block. */
+ void audioBlockDCT();
+ /** Decode a RDFT'd audio block. */
+ void audioBlockRDFT();
- uint32 _videoFlags; ///< Video frame features.
+ void readAudioCoeffs(float *coeffs);
- bool _hasAlpha; ///< Do video frames have alpha?
- bool _swapPlanes; ///< Are the planes ordered (A)YVU instead of (A)YUV?
+ static void floatToInt16Interleave(int16 *dst, const float **src, uint32 length, uint8 channels);
+ };
+
+ Common::SeekableReadStream *_bink;
- Common::Array<AudioTrack> _audioTracks; ///< All audio tracks.
+ Common::Array<AudioInfo> _audioTracks; ///< All audio tracks.
Common::Array<VideoFrame> _frames; ///< All video frames.
- uint32 _audioTrack; ///< Audio track to use.
-
- Common::Huffman *_huffman[16]; ///< The 16 Huffman codebooks used in Bink decoding.
-
- Bundle _bundles[kSourceMAX]; ///< Bundles for decoding all data types.
-
- /** Huffman codebooks to use for decoding high nibbles in color data types. */
- Huffman _colHighHuffman[16];
- /** Value of the last decoded high nibble in color data types. */
- int _colLastVal;
-
- byte *_curPlanes[4]; ///< The 4 color planes, YUVA, current frame.
- byte *_oldPlanes[4]; ///< The 4 color planes, YUVA, last frame.
-
-
- /** Initialize the bundles. */
- void initBundles();
- /** Deinitialize the bundles. */
- void deinitBundles();
-
- /** Initialize the Huffman decoders. */
- void initHuffman();
-
- /** Decode an audio packet. */
- void audioPacket(AudioTrack &audio);
- /** Decode a video packet. */
- virtual void videoPacket(VideoFrame &video);
-
- /** Decode a plane. */
- void decodePlane(VideoFrame &video, int planeIdx, bool isChroma);
-
- /** Read/Initialize a bundle for decoding a plane. */
- void readBundle(VideoFrame &video, Source source);
-
- /** Read the symbols for a Huffman code. */
- void readHuffman(VideoFrame &video, Huffman &huffman);
- /** Merge two Huffman symbol lists. */
- void mergeHuffmanSymbols(VideoFrame &video, byte *dst, const byte *src, int size);
-
- /** Read and translate a symbol out of a Huffman code. */
- byte getHuffmanSymbol(VideoFrame &video, Huffman &huffman);
-
- /** Get a direct value out of a bundle. */
- int32 getBundleValue(Source source);
- /** Read a count value out of a bundle. */
- uint32 readBundleCount(VideoFrame &video, Bundle &bundle);
-
- // Handle the block types
- void blockSkip (DecodeContext &ctx);
- void blockScaledSkip (DecodeContext &ctx);
- void blockScaledRun (DecodeContext &ctx);
- void blockScaledIntra (DecodeContext &ctx);
- void blockScaledFill (DecodeContext &ctx);
- void blockScaledPattern(DecodeContext &ctx);
- void blockScaledRaw (DecodeContext &ctx);
- void blockScaled (DecodeContext &ctx);
- void blockMotion (DecodeContext &ctx);
- void blockRun (DecodeContext &ctx);
- void blockResidue (DecodeContext &ctx);
- void blockIntra (DecodeContext &ctx);
- void blockFill (DecodeContext &ctx);
- void blockInter (DecodeContext &ctx);
- void blockPattern (DecodeContext &ctx);
- void blockRaw (DecodeContext &ctx);
-
- // Read the bundles
- void readRuns (VideoFrame &video, Bundle &bundle);
- void readMotionValues(VideoFrame &video, Bundle &bundle);
- void readBlockTypes (VideoFrame &video, Bundle &bundle);
- void readPatterns (VideoFrame &video, Bundle &bundle);
- void readColors (VideoFrame &video, Bundle &bundle);
- void readDCS (VideoFrame &video, Bundle &bundle, int startBits, bool hasSign);
- void readDCTCoeffs (VideoFrame &video, int16 *block, bool isIntra);
- void readResidue (VideoFrame &video, int16 *block, int masksCount);
-
- void initAudioTrack(AudioTrack &audio);
-
- float getFloat(AudioTrack &audio);
-
- /** Decode an audio block. */
- void audioBlock (AudioTrack &audio, int16 *out);
- /** Decode a DCT'd audio block. */
- void audioBlockDCT (AudioTrack &audio);
- /** Decode a RDFT'd audio block. */
- void audioBlockRDFT(AudioTrack &audio);
-
- void readAudioCoeffs(AudioTrack &audio, float *coeffs);
-
- void floatToInt16Interleave(int16 *dst, const float **src, uint32 length, uint8 channels);
-
- // Bink video IDCT
- 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();
+ void initAudioTrack(AudioInfo &audio);
};
} // End of namespace Video
diff --git a/video/codecs/qtrle.cpp b/video/codecs/qtrle.cpp
index f01720ec86..d2cdea27de 100644
--- a/video/codecs/qtrle.cpp
+++ b/video/codecs/qtrle.cpp
@@ -37,28 +37,25 @@ namespace Video {
QTRLEDecoder::QTRLEDecoder(uint16 width, uint16 height, byte bitsPerPixel) : Codec() {
_bitsPerPixel = bitsPerPixel;
- _pixelFormat = g_system->getScreenFormat();
- // We need to increase the surface size to a multiple of 4
+ // We need to ensure the width is a multiple of 4
uint16 wMod = width % 4;
- if(wMod != 0)
+ if (wMod != 0)
width += 4 - wMod;
- debug(2, "QTRLE corrected width: %d", width);
-
_surface = new Graphics::Surface();
- _surface->create(width, height, _bitsPerPixel <= 8 ? Graphics::PixelFormat::createFormatCLUT8() : _pixelFormat);
+ _surface->create(width, height, getPixelFormat());
}
#define CHECK_STREAM_PTR(n) \
if ((stream->pos() + n) > stream->size()) { \
- warning ("Problem: stream out of bounds (%d >= %d)", stream->pos() + n, stream->size()); \
+ warning("QTRLE Problem: stream out of bounds (%d > %d)", stream->pos() + n, stream->size()); \
return; \
}
#define CHECK_PIXEL_PTR(n) \
if ((int32)pixelPtr + n > _surface->w * _surface->h) { \
- warning ("Problem: pixel ptr = %d, pixel limit = %d", pixelPtr + n, _surface->w * _surface->h); \
+ warning("QTRLE Problem: pixel ptr = %d, pixel limit = %d", pixelPtr + n, _surface->w * _surface->h); \
return; \
} \
@@ -132,8 +129,6 @@ void QTRLEDecoder::decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr,
for (int8 i = numPixels - 1; i >= 0; i--) {
pi[numPixels - 1 - i] = (stream->readByte() >> ((i * bpp) & 0x07)) & ((1 << bpp) - 1);
- // FIXME: Is this right?
- //stream_ptr += ((i & ((num_pixels>>2)-1)) == 0);
if ((i & ((numPixels >> 2) - 1)) == 0)
stream->readByte();
}
@@ -215,7 +210,7 @@ void QTRLEDecoder::decode8(Common::SeekableReadStream *stream, uint32 rowPtr, ui
void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
- OverlayColor *rgb = (OverlayColor *)_surface->pixels;
+ uint16 *rgb = (uint16 *)_surface->pixels;
while (linesToChange--) {
CHECK_STREAM_PTR(2);
@@ -235,25 +230,15 @@ void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, u
CHECK_PIXEL_PTR(rleCode);
- while (rleCode--) {
- // Convert from RGB555 to the format specified by the Overlay
- byte r = 0, g = 0, b = 0;
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(rgb16, r, g, b);
- rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
- }
+ while (rleCode--)
+ rgb[pixelPtr++] = rgb16;
} else {
CHECK_STREAM_PTR(rleCode * 2);
CHECK_PIXEL_PTR(rleCode);
// copy pixels directly to output
- while (rleCode--) {
- uint16 rgb16 = stream->readUint16BE();
-
- // Convert from RGB555 to the format specified by the Overlay
- byte r = 0, g = 0, b = 0;
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(rgb16, r, g, b);
- rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
- }
+ while (rleCode--)
+ rgb[pixelPtr++] = stream->readUint16BE();
}
}
@@ -263,7 +248,7 @@ void QTRLEDecoder::decode16(Common::SeekableReadStream *stream, uint32 rowPtr, u
void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
- OverlayColor *rgb = (OverlayColor *)_surface->pixels;
+ uint32 *rgb = (uint32 *)_surface->pixels;
while (linesToChange--) {
CHECK_STREAM_PTR(2);
@@ -283,11 +268,12 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u
byte r = stream->readByte();
byte g = stream->readByte();
byte b = stream->readByte();
+ uint32 color = _surface->format.RGBToColor(r, g, b);
CHECK_PIXEL_PTR(rleCode);
while (rleCode--)
- rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
+ rgb[pixelPtr++] = color;
} else {
CHECK_STREAM_PTR(rleCode * 3);
CHECK_PIXEL_PTR(rleCode);
@@ -297,7 +283,7 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u
byte r = stream->readByte();
byte g = stream->readByte();
byte b = stream->readByte();
- rgb[pixelPtr++] = _pixelFormat.RGBToColor(r, g, b);
+ rgb[pixelPtr++] = _surface->format.RGBToColor(r, g, b);
}
}
}
@@ -308,7 +294,7 @@ void QTRLEDecoder::decode24(Common::SeekableReadStream *stream, uint32 rowPtr, u
void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange) {
uint32 pixelPtr = 0;
- OverlayColor *rgb = (OverlayColor *)_surface->pixels;
+ uint32 *rgb = (uint32 *)_surface->pixels;
while (linesToChange--) {
CHECK_STREAM_PTR(2);
@@ -329,11 +315,12 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, u
byte r = stream->readByte();
byte g = stream->readByte();
byte b = stream->readByte();
+ uint32 color = _surface->format.ARGBToColor(a, r, g, b);
CHECK_PIXEL_PTR(rleCode);
while (rleCode--)
- rgb[pixelPtr++] = _pixelFormat.ARGBToColor(a, r, g, b);
+ rgb[pixelPtr++] = color;
} else {
CHECK_STREAM_PTR(rleCode * 4);
CHECK_PIXEL_PTR(rleCode);
@@ -344,7 +331,7 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, u
byte r = stream->readByte();
byte g = stream->readByte();
byte b = stream->readByte();
- rgb[pixelPtr++] = _pixelFormat.ARGBToColor(a, r, g, b);
+ rgb[pixelPtr++] = _surface->format.ARGBToColor(a, r, g, b);
}
}
}
@@ -354,7 +341,7 @@ void QTRLEDecoder::decode32(Common::SeekableReadStream *stream, uint32 rowPtr, u
}
const Graphics::Surface *QTRLEDecoder::decodeImage(Common::SeekableReadStream *stream) {
- uint16 start_line = 0;
+ uint16 startLine = 0;
uint16 height = _surface->h;
// check if this frame is even supposed to change
@@ -369,44 +356,45 @@ const Graphics::Surface *QTRLEDecoder::decodeImage(Common::SeekableReadStream *s
// if a header is present, fetch additional decoding parameters
if (header & 8) {
- if(stream->size() < 14)
+ if (stream->size() < 14)
return _surface;
- start_line = stream->readUint16BE();
+
+ startLine = stream->readUint16BE();
stream->readUint16BE(); // Unknown
height = stream->readUint16BE();
stream->readUint16BE(); // Unknown
}
- uint32 row_ptr = _surface->w * start_line;
+ uint32 rowPtr = _surface->w * startLine;
switch (_bitsPerPixel) {
- case 1:
- case 33:
- decode1(stream, row_ptr, height);
- break;
- case 2:
- case 34:
- decode2_4(stream, row_ptr, height, 2);
- break;
- case 4:
- case 36:
- decode2_4(stream, row_ptr, height, 4);
- break;
- case 8:
- case 40:
- decode8(stream, row_ptr, height);
- break;
- case 16:
- decode16(stream, row_ptr, height);
- break;
- case 24:
- decode24(stream, row_ptr, height);
- break;
- case 32:
- decode32(stream, row_ptr, height);
- break;
- default:
- error ("Unsupported bits per pixel %d", _bitsPerPixel);
+ case 1:
+ case 33:
+ decode1(stream, rowPtr, height);
+ break;
+ case 2:
+ case 34:
+ decode2_4(stream, rowPtr, height, 2);
+ break;
+ case 4:
+ case 36:
+ decode2_4(stream, rowPtr, height, 4);
+ break;
+ case 8:
+ case 40:
+ decode8(stream, rowPtr, height);
+ break;
+ case 16:
+ decode16(stream, rowPtr, height);
+ break;
+ case 24:
+ decode24(stream, rowPtr, height);
+ break;
+ case 32:
+ decode32(stream, rowPtr, height);
+ break;
+ default:
+ error("Unsupported QTRLE bits per pixel %d", _bitsPerPixel);
}
return _surface;
@@ -417,4 +405,27 @@ QTRLEDecoder::~QTRLEDecoder() {
delete _surface;
}
+Graphics::PixelFormat QTRLEDecoder::getPixelFormat() const {
+ switch (_bitsPerPixel) {
+ case 1:
+ case 33:
+ case 2:
+ case 34:
+ case 4:
+ case 36:
+ case 8:
+ case 40:
+ return Graphics::PixelFormat::createFormatCLUT8();
+ case 16:
+ return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+ case 24:
+ case 32:
+ return Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
+ default:
+ error("Unsupported QTRLE bits per pixel %d", _bitsPerPixel);
+ }
+
+ return Graphics::PixelFormat();
+}
+
} // End of namespace Video
diff --git a/video/codecs/qtrle.h b/video/codecs/qtrle.h
index 6f8e113ca5..d9db58ab23 100644
--- a/video/codecs/qtrle.h
+++ b/video/codecs/qtrle.h
@@ -34,13 +34,12 @@ public:
~QTRLEDecoder();
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
- Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
+ Graphics::PixelFormat getPixelFormat() const;
private:
byte _bitsPerPixel;
Graphics::Surface *_surface;
- Graphics::PixelFormat _pixelFormat;
void decode1(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange);
void decode2_4(Common::SeekableReadStream *stream, uint32 rowPtr, uint32 linesToChange, byte bpp);
diff --git a/video/codecs/rpza.cpp b/video/codecs/rpza.cpp
index df5738202e..acc1b7f358 100644
--- a/video/codecs/rpza.cpp
+++ b/video/codecs/rpza.cpp
@@ -28,22 +28,17 @@
#include "common/system.h"
#include "common/stream.h"
#include "common/textconsole.h"
-#include "graphics/colormasks.h"
namespace Video {
RPZADecoder::RPZADecoder(uint16 width, uint16 height) : Codec() {
- _pixelFormat = g_system->getScreenFormat();
-
// We need to increase the surface size to a multiple of 4
uint16 wMod = width % 4;
- if(wMod != 0)
+ if (wMod != 0)
width += 4 - wMod;
- debug(2, "RPZA corrected width: %d", width);
-
_surface = new Graphics::Surface();
- _surface->create(width, height, _pixelFormat);
+ _surface->create(width, height, getPixelFormat());
}
RPZADecoder::~RPZADecoder() {
@@ -59,18 +54,11 @@ RPZADecoder::~RPZADecoder() {
} \
totalBlocks--; \
if (totalBlocks < 0) \
- error("block counter just went negative (this should not happen)") \
+ error("rpza block counter just went negative (this should not happen)") \
-// Convert from RGB555 to the format specified by the screen
#define PUT_PIXEL(color) \
- if ((int32)blockPtr < _surface->w * _surface->h) { \
- byte r = 0, g = 0, b = 0; \
- Graphics::colorToRGB<Graphics::ColorMasks<555> >(color, r, g, b); \
- if (_pixelFormat.bytesPerPixel == 2) \
- *((uint16 *)_surface->pixels + blockPtr) = _pixelFormat.RGBToColor(r, g, b); \
- else \
- *((uint32 *)_surface->pixels + blockPtr) = _pixelFormat.RGBToColor(r, g, b); \
- } \
+ if ((int32)blockPtr < _surface->w * _surface->h) \
+ WRITE_UINT16((uint16 *)_surface->pixels + blockPtr, color); \
blockPtr++
const Graphics::Surface *RPZADecoder::decodeImage(Common::SeekableReadStream *stream) {
diff --git a/video/codecs/rpza.h b/video/codecs/rpza.h
index 809a69f444..f082d25549 100644
--- a/video/codecs/rpza.h
+++ b/video/codecs/rpza.h
@@ -34,11 +34,10 @@ public:
~RPZADecoder();
const Graphics::Surface *decodeImage(Common::SeekableReadStream *stream);
- Graphics::PixelFormat getPixelFormat() const { return _pixelFormat; }
+ Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0); }
private:
Graphics::Surface *_surface;
- Graphics::PixelFormat _pixelFormat;
};
} // End of namespace Video
diff --git a/video/codecs/svq1.cpp b/video/codecs/svq1.cpp
index eba0c90305..14452ab15b 100644
--- a/video/codecs/svq1.cpp
+++ b/video/codecs/svq1.cpp
@@ -317,7 +317,7 @@ bool SVQ1Decoder::svq1DecodeBlockIntra(Common::BitStream *s, byte *pixels, int p
for (uint y = 0; y < height; y++)
memset(&dst[y * (pitch / 4)], mean, width);
} else {
- const uint32 *codebook = s_svq1IntraCodebooks[level];
+ const uint32 *codebook = (const uint32 *)s_svq1IntraCodebooks[level];
uint32 bitCache = s->getBits(stages * 4);
// calculate codebook entries for this vector
@@ -336,7 +336,7 @@ bool SVQ1Decoder::svq1DecodeBlockIntra(Common::BitStream *s, byte *pixels, int p
// add codebook entries to vector
for (int j = 0; j < stages; j++) {
- n3 = codebook[entries[j]] ^ 0x80808080;
+ n3 = READ_UINT32(&codebook[entries[j]]) ^ 0x80808080;
n1 += (n3 & 0xFF00FF00) >> 8;
n2 += n3 & 0x00FF00FF;
}
@@ -409,7 +409,7 @@ bool SVQ1Decoder::svq1DecodeBlockNonIntra(Common::BitStream *s, byte *pixels, in
}
int mean = _interMean->getSymbol(*s) - 256;
- const uint32 *codebook = s_svq1InterCodebooks[level];
+ const uint32 *codebook = (const uint32 *)s_svq1InterCodebooks[level];
uint32 bitCache = s->getBits(stages * 4);
// calculate codebook entries for this vector
@@ -430,7 +430,7 @@ bool SVQ1Decoder::svq1DecodeBlockNonIntra(Common::BitStream *s, byte *pixels, in
// add codebook entries to vector
for (int j = 0; j < stages; j++) {
- n3 = codebook[entries[j]] ^ 0x80808080;
+ n3 = READ_UINT32(&codebook[entries[j]]) ^ 0x80808080;
n1 += (n3 & 0xFF00FF00) >> 8;
n2 += n3 & 0x00FF00FF;
}
diff --git a/video/codecs/svq1_cb.h b/video/codecs/svq1_cb.h
index f9a8c54e40..8281b3fc28 100644
--- a/video/codecs/svq1_cb.h
+++ b/video/codecs/svq1_cb.h
@@ -30,1477 +30,1477 @@
namespace Video {
-static const uint32 s_svq1InterCodebook4x2[192] = {
- 0xf9fa0207, 0xfcfd0307, 0x0807fef9, 0x0403fcf8,
- 0x03091113, 0xf8f4f0f2, 0xfdf8f0ee, 0x080c0e0b,
- 0x14f6f007, 0x14f6ef07, 0xeb0812fa, 0xec0912f9,
- 0xf2ec0319, 0xf3ee071d, 0x0e15fce3, 0x0e14fae1,
- 0xe8e4e6ed, 0x0a16201f, 0x1c1f180f, 0xf3eae0e0,
- 0xe6e9f802, 0x231b03f7, 0x15150b03, 0xdee5fc08,
- 0x2f0ce1e2, 0x2f0de2e3, 0xd2ef1e26, 0xd2ed1a22,
- 0xd5cdced6, 0x30373022, 0x2a333630, 0xd1cbccd4,
- 0xfa000504, 0x0100fefe, 0xfefffaf5, 0x01090801,
- 0x05fa0100, 0x02f40108, 0x08f9f207, 0x0800f805,
- 0x080b0401, 0xfb00f8f4, 0x040001ff, 0x1003f8f1,
- 0xfafc0811, 0xf8f3fc09, 0xee010602, 0xf40b0bff,
- 0x00020006, 0xebf9060e, 0xecf3ff01, 0x150a0101,
- 0x0d07fbea, 0x0c04fff5, 0x130e00f9, 0xedfb03fc,
- 0x0f0af2e6, 0xfefa0412, 0xeefb1319, 0x0204f9ec,
- 0xfcfffaf3, 0xddfe2519, 0x01010405, 0x2b02dceb,
- 0x03fffe02, 0xfffafe08, 0x0c02fdfe, 0xfffefefb,
- 0xfbfffffd, 0xfe0807ff, 0xfd050702, 0xf8fd0101,
- 0xfefdfffd, 0x0d02fdfe, 0xfaf5000f, 0x00000003,
- 0xfcfbf7fa, 0x03010412, 0x0400030c, 0xfd03fdf0,
- 0x021203ef, 0xfffffdff, 0x00f810fa, 0x00f90ef7,
- 0xfb0ef303, 0xfc0ef303, 0xe90e14f9, 0x04f8f908,
- 0x10edf108, 0xfd0b0df6, 0x1a01ff09, 0x02e5f105,
- 0xfc1007ec, 0x011f09d8, 0xf9e2f41a, 0x04edfe28,
- 0x00000006, 0x0201fefa, 0xfa00ff00, 0xfffe0009,
- 0xfd0208f9, 0x02fd02ff, 0x04fefc07, 0xfa000002,
- 0x0209fefd, 0xfc00fffe, 0xfd00fdfd, 0x040a02fa,
- 0x08f60003, 0x04fc0000, 0x020401ff, 0x07f7f903,
- 0xfcf70102, 0x00000cff, 0xfc07ff03, 0x0204f203,
- 0x0b01f7f4, 0x00010502, 0x02000103, 0xed060800,
- 0xfcf9f6fa, 0x07050709, 0xfd031506, 0xfefbf7f5,
- 0xfff0f7fc, 0x2401fbfe, 0x00130b08, 0xd7fc0502,
- 0xfffeffff, 0x0601fefe, 0xf8010400, 0x00010101,
- 0x0004fdfe, 0xfd03ff02, 0x01fc0301, 0xfb0003ff,
- 0x03020403, 0xfffafdfe, 0x02fefdfe, 0x000108fc,
- 0x060204f9, 0x0001fff9, 0x01fc02fe, 0xff02fa08,
- 0x020002fa, 0xfff80405, 0x0900f5ff, 0x0202fe00,
- 0xfffcfb11, 0xfefefcff, 0xfd09f300, 0x02f90cff,
- 0x02fbfe00, 0xfd14fbf9, 0xe2ff0707, 0x01080503,
- 0xfcff03fa, 0x12f5fe02, 0x0e03f900, 0xf7eefd14,
- 0xff00fe07, 0xff0000fe, 0x0001fffc, 0x040002fe,
- 0x0102fd01, 0x01fb0103, 0xfeff00fd, 0xfd000107,
- 0xfe000502, 0x01fffb02, 0xff04feff, 0x0005fd00,
- 0xfeff0300, 0xff0501fc, 0x09ff00ff, 0xfffffeff,
- 0xff0505fe, 0xfefd02fe, 0x01f50201, 0x02030102,
- 0xfefff602, 0x01040204, 0x01fb0504, 0x01f50600,
- 0x06060001, 0xf1010200, 0x09050307, 0x020202e2,
- 0x020901de, 0x02080805, 0x06060207, 0x0401e502
+static const int8 s_svq1InterCodebook4x2[768] = {
+ 7, 2, -6, -7, 7, 3, -3, -4, -7, -2, 7, 8, -8, -4, 3, 4,
+ 19, 17, 9, 3,-14,-16,-12, -8,-18,-16, -8, -3, 11, 14, 12, 8,
+ 7,-16,-10, 20, 7,-17,-10, 20, -6, 18, 8,-21, -7, 18, 9,-20,
+ 25, 3,-20,-14, 29, 7,-18,-13,-29, -4, 21, 14,-31, -6, 20, 14,
+ -19,-26,-28,-24, 31, 32, 22, 10, 15, 24, 31, 28,-32,-32,-22,-13,
+ 2, -8,-23,-26, -9, 3, 27, 35, 3, 11, 21, 21, 8, -4,-27,-34,
+ -30,-31, 12, 47,-29,-30, 13, 47, 38, 30,-17,-46, 34, 26,-19,-46,
+ -42,-50,-51,-43, 34, 48, 55, 48, 48, 54, 51, 42,-44,-52,-53,-47,
+ 4, 5, 0, -6, -2, -2, 0, 1,-11, -6, -1, -2, 1, 8, 9, 1,
+ 0, 1, -6, 5, 8, 1,-12, 2, 7,-14, -7, 8, 5, -8, 0, 8,
+ 1, 4, 11, 8,-12, -8, 0, -5, -1, 1, 0, 4,-15, -8, 3, 16,
+ 17, 8, -4, -6, 9, -4,-13, -8, 2, 6, 1,-18, -1, 11, 11,-12,
+ 6, 0, 2, 0, 14, 6, -7,-21, 1, -1,-13,-20, 1, 1, 10, 21,
+ -22, -5, 7, 13,-11, -1, 4, 12, -7, 0, 14, 19, -4, 3, -5,-19,
+ -26,-14, 10, 15, 18, 4, -6, -2, 25, 19, -5,-18,-20, -7, 4, 2,
+ -13, -6, -1, -4, 25, 37, -2,-35, 5, 4, 1, 1,-21,-36, 2, 43,
+ 2, -2, -1, 3, 8, -2, -6, -1, -2, -3, 2, 12, -5, -2, -2, -1,
+ -3, -1, -1, -5, -1, 7, 8, -2, 2, 7, 5, -3, 1, 1, -3, -8,
+ -3, -1, -3, -2, -2, -3, 2, 13, 15, 0,-11, -6, 3, 0, 0, 0,
+ -6, -9, -5, -4, 18, 4, 1, 3, 12, 3, 0, 4,-16, -3, 3, -3,
+ -17, 3, 18, 2, -1, -3, -1, -1, -6, 16, -8, 0, -9, 14, -7, 0,
+ 3,-13, 14, -5, 3,-13, 14, -4, -7, 20, 14,-23, 8, -7, -8, 4,
+ 8,-15,-19, 16,-10, 13, 11, -3, 9, -1, 1, 26, 5,-15,-27, 2,
+ -20, 7, 16, -4,-40, 9, 31, 1, 26,-12,-30, -7, 40, -2,-19, 4,
+ 6, 0, 0, 0, -6, -2, 1, 2, 0, -1, 0, -6, 9, 0, -2, -1,
+ -7, 8, 2, -3, -1, 2, -3, 2, 7, -4, -2, 4, 2, 0, 0, -6,
+ -3, -2, 9, 2, -2, -1, 0, -4, -3, -3, 0, -3, -6, 2, 10, 4,
+ 3, 0,-10, 8, 0, 0, -4, 4, -1, 1, 4, 2, 3, -7, -9, 7,
+ 2, 1, -9, -4, -1, 12, 0, 0, 3, -1, 7, -4, 3,-14, 4, 2,
+ -12, -9, 1, 11, 2, 5, 1, 0, 3, 1, 0, 2, 0, 8, 6,-19,
+ -6,-10, -7, -4, 9, 7, 5, 7, 6, 21, 3, -3,-11, -9, -5, -2,
+ -4, -9,-16, -1, -2, -5, 1, 36, 8, 11, 19, 0, 2, 5, -4,-41,
+ -1, -1, -2, -1, -2, -2, 1, 6, 0, 4, 1, -8, 1, 1, 1, 0,
+ -2, -3, 4, 0, 2, -1, 3, -3, 1, 3, -4, 1, -1, 3, 0, -5,
+ 3, 4, 2, 3, -2, -3, -6, -1, -2, -3, -2, 2, -4, 8, 1, 0,
+ -7, 4, 2, 6, -7, -1, 1, 0, -2, 2, -4, 1, 8, -6, 2, -1,
+ -6, 2, 0, 2, 5, 4, -8, -1, -1,-11, 0, 9, 0, -2, 2, 2,
+ 17, -5, -4, -1, -1, -4, -2, -2, 0,-13, 9, -3, -1, 12, -7, 2,
+ 0, -2, -5, 2, -7, -5, 20, -3, 7, 7, -1,-30, 3, 5, 8, 1,
+ -6, 3, -1, -4, 2, -2,-11, 18, 0, -7, 3, 14, 20, -3,-18, -9,
+ 7, -2, 0, -1, -2, 0, 0, -1, -4, -1, 1, 0, -2, 2, 0, 4,
+ 1, -3, 2, 1, 3, 1, -5, 1, -3, 0, -1, -2, 7, 1, 0, -3,
+ 2, 5, 0, -2, 2, -5, -1, 1, -1, -2, 4, -1, 0, -3, 5, 0,
+ 0, 3, -1, -2, -4, 1, 5, -1, -1, 0, -1, 9, -1, -2, -1, -1,
+ -2, 5, 5, -1, -2, 2, -3, -2, 1, 2,-11, 1, 2, 1, 3, 2,
+ 2,-10, -1, -2, 4, 2, 4, 1, 4, 5, -5, 1, 0, 6,-11, 1,
+ 1, 0, 6, 6, 0, 2, 1,-15, 7, 3, 5, 9,-30, 2, 2, 2,
+ -34, 1, 9, 2, 5, 8, 8, 2, 7, 2, 6, 6, 2,-27, 1, 4
};
-static const uint32 s_svq1InterCodebook4x4[384] = {
- 0xf9fa0004, 0xf7f3f8fc, 0x06fff8f8, 0x1b1605fe,
- 0x0a0bf9f0, 0x0a0df9ee, 0x080cfcf1, 0x0509fff7,
- 0xf00f02fe, 0xed1302fd, 0xed1302fd, 0xf20f03fe,
- 0x10161611, 0xfefbf9fa, 0xf4f0f0f4, 0xfdff0101,
- 0x0800ef0b, 0x09ffeb0e, 0x08feeb0e, 0x06fef00b,
- 0x0bf0fe07, 0x0eebfe09, 0x0eeaff0a, 0x0aeeff08,
- 0xf70310f6, 0xf50414f3, 0xf60415f2, 0xf80310f5,
- 0xf7f7040b, 0xf2f4060f, 0xf2f40811, 0xf5f90a10,
- 0x0d0e0a04, 0x100f07ff, 0x0803f9f4, 0xf6eee9ec,
- 0xe7e6eef6, 0xf5fa0104, 0x030b0f0d, 0x080d0f0c,
- 0xf5f0edf0, 0x0b0f0c07, 0x0b10100b, 0xf6f5f7fa,
- 0x050c1312, 0xfc051012, 0xf1f60006, 0xeae9eff7,
- 0x15fff2f6, 0x1d00eff5, 0x1e01f0f5, 0x1700f2f6,
- 0xfaf4eff0, 0xf9f2eded, 0x0201fffd, 0x131d231b,
- 0x1717f8db, 0x1d1cf7d6, 0x1c1af6d5, 0x1613f5da,
- 0xdff01020, 0xdbee1427, 0xdaed1326, 0xdeef0f20,
- 0xfcfa0918, 0x03faf6ff, 0x03fff7f8, 0xfa020703,
- 0x00fffdff, 0xf90204ff, 0xf0030bfd, 0xee091401,
- 0x0c06f8fd, 0x0d07f6fb, 0x0705f7fa, 0xff02fbfb,
- 0xfffd0cf8, 0x01fd0ff6, 0x01fc0df5, 0x02fd08f5,
- 0xf4fb0609, 0xf3f80003, 0xfffffcfc, 0x120f01fc,
- 0x0c0e0d09, 0xfeff0304, 0xfbf8fbfe, 0xfcf7f5f9,
- 0xfcf9fb07, 0xfcf9fe0e, 0xfbf80011, 0xfbf9010f,
- 0x0406fff6, 0x0402f7f1, 0x00fdff02, 0xf6f80d19,
- 0xf0fd0b07, 0xf1fd0b07, 0xf7fe0706, 0xfbfd0204,
- 0x00fffff9, 0x0602fef7, 0x0e06fcf4, 0x1308faf3,
- 0xfbf5eeee, 0x040300fd, 0x06060806, 0x06060606,
- 0xf60d03fb, 0xf70f01fa, 0xfa0ffdfa, 0xfd0afafa,
- 0xf7f70109, 0x0506090b, 0x07080300, 0xfbfaf2f1,
- 0x130bfaf5, 0xf8f7fbfe, 0xf6f70206, 0x05040506,
- 0x0f08fdf9, 0x0f0a03ff, 0xfeff0505, 0xe7ebfe04,
- 0x05fafa06, 0x09f9f708, 0x0df9f408, 0x0ef9f204,
- 0x0101fdfc, 0xfdfefbfd, 0xfcfe0007, 0xfcfc0714,
- 0x0afaecfd, 0x01000006, 0xff050805, 0xfe0000fd,
- 0x02ff060d, 0x03020305, 0x000300fd, 0xfbfef8f0,
- 0x00faf9fe, 0x01fdfafd, 0xff02fffb, 0x05100cff,
- 0x080901f9, 0x0305fef6, 0x030702fa, 0xf9ff00fc,
- 0xe8f70403, 0x03060200, 0x0704ffff, 0xfeff0305,
- 0x02f70603, 0x01f30601, 0x02f60801, 0x01f90801,
- 0x1602fdfd, 0x0cfbfdfe, 0x02f6fdfe, 0x02fcfffd,
- 0x02080c0b, 0xf8fbfbfb, 0xfd00fcfa, 0x0303fffe,
- 0xfffefa0c, 0xfefef80c, 0xfd00f909, 0xfe02fa04,
- 0xfd0c01ed, 0xfc0504fc, 0xfffe0106, 0x07fefc04,
- 0xf8f9fcfd, 0x00fefcfc, 0x100e02ff, 0x0404fefc,
- 0xfb0207ff, 0x01ff00fe, 0x0dfffd04, 0x08f2f406,
- 0xfb0405ff, 0xf70305fe, 0xf40407fe, 0xf70407ff,
- 0x0101fdfa, 0xfa000b0b, 0xf9fe0406, 0x0a03f6f4,
- 0xfefdfdfe, 0x0a0e0b06, 0xf6f6f5f7, 0x02030202,
- 0xfff9fbf9, 0x070002ff, 0x090001ff, 0xfffb0403,
- 0xfff1ff0a, 0x02fb0104, 0x01ff01fd, 0x040401fd,
- 0x0a04ff02, 0x00ff0206, 0xf4f90202, 0xfd0002fc,
- 0xf8fffcff, 0xf702ff03, 0xfb050004, 0x03080002,
- 0x01010203, 0x0300fe04, 0x0104ff02, 0xe7ff0600,
- 0xfcfefeff, 0xfcff00fd, 0x02fcffff, 0x1902fa00,
- 0x0005fff5, 0x02fe0007, 0x04fdff0a, 0xfffefbfb,
- 0xff030600, 0x01fffffe, 0xfbf4f9ff, 0x04020608,
- 0xfaff0602, 0xfcff0a09, 0x00fc0001, 0xfbf7fe03,
- 0x000403fc, 0x000303fc, 0x020300f5, 0x020703f5,
- 0x0307fc02, 0x0107f801, 0x0104f4ff, 0x0202f703,
- 0x09fefe02, 0x0103fdef, 0xfa0107fc, 0x03ff0405,
- 0xfc0002ff, 0xff0c08f9, 0xfb0405fe, 0xfef8fb03,
- 0xfefb0000, 0x1b03f8fe, 0x06fdfcff, 0xf9fe01fd,
- 0xff010404, 0xfdf9f6f9, 0x03050a0a, 0xfdfcfefe,
- 0x07050100, 0xecf0fe04, 0x08070400, 0xfffe0002,
- 0x110301fe, 0xfffe01fd, 0xfefffeff, 0x00fffbff,
- 0x0001fd05, 0x0000fe06, 0xfd00feff, 0xff0801f5,
- 0x00000003, 0x01040200, 0x01060002, 0x02fdeefe,
- 0x010600f2, 0x01fffefb, 0x010001ff, 0x00040701,
- 0xfc0100ff, 0xfc030801, 0x030104fd, 0x01fc01fa,
- 0x0303f401, 0xff00f6ff, 0x01020002, 0x04020203,
- 0x03000003, 0x01fe0002, 0x00fb0205, 0xfff2ff06,
- 0xfdfdfafe, 0x0504ff02, 0x00feff06, 0xfbff0404,
- 0x00f501fc, 0x01fc02ff, 0xff03fd02, 0x000ffe01,
- 0xfe00ff01, 0x01f9fc01, 0x15fffafe, 0x01ff02fe,
- 0x00feff15, 0xfe01fdff, 0xff02fef7, 0xfffc0102,
- 0xfa020801, 0x0004fff6, 0x0303fdfc, 0xffff0005,
- 0xfe010203, 0x0304fefe, 0xeffc0205, 0x0304fe00,
- 0x0300fcf9, 0xff020909, 0xff00faf5, 0x01000105,
- 0xf5051100, 0x00fafe03, 0x01fcfe02, 0xff0201fc,
- 0xfdfbfffb, 0xfefd05fd, 0xfb021004, 0xffff05fe,
- 0x01fc0000, 0x0b0502ff, 0x01feffff, 0xfffdfefc,
- 0x000afffb, 0xfd000106, 0x0001fc00, 0xff03fcfe,
- 0x00030906, 0x00fe01fe, 0xfefefdfe, 0xfa010001,
- 0x01020001, 0x01fe03ff, 0x00f1ff00, 0x060205ff,
- 0x02020002, 0x06fcf400, 0xff040100, 0xfc010201,
- 0x00f9fe01, 0xff000000, 0x030b02fb, 0xfa000301,
- 0xfcf7fd00, 0x00ff0301, 0x00fe0104, 0x06fffd07,
- 0x0206fe01, 0xfe03ff00, 0x020004fe, 0x02f202ff,
- 0xff000202, 0xf2fd03fe, 0xfd030200, 0x02030105,
- 0xf204fd01, 0xff0bfe01, 0x0003ff00, 0x020001ff,
- 0x02fd03fe, 0x03fcfffc, 0x030102ff, 0x0702fefa,
- 0x000201fe, 0xff0000fe, 0x02ff050c, 0xf901fff8,
- 0x02fcfe02, 0xfef5000b, 0xfffd0103, 0xff010300,
- 0xfe000300, 0xfdfffa00, 0x00fef90c, 0x0101fe07,
- 0x02020201, 0x020002ff, 0x000400e9, 0x03010203,
- 0x05fffbfc, 0xff0a05fd, 0xfc030000, 0xfb02ff01
+static const int8 s_svq1InterCodebook4x4[1536] = {
+ 4, 0, -6, -7, -4, -8,-13, -9, -8, -8, -1, 6, -2, 5, 22, 27,
+ -16, -7, 11, 10,-18, -7, 13, 10,-15, -4, 12, 8, -9, -1, 9, 5,
+ -2, 2, 15,-16, -3, 2, 19,-19, -3, 2, 19,-19, -2, 3, 15,-14,
+ 17, 22, 22, 16, -6, -7, -5, -2,-12,-16,-16,-12, 1, 1, -1, -3,
+ 11,-17, 0, 8, 14,-21, -1, 9, 14,-21, -2, 8, 11,-16, -2, 6,
+ 7, -2,-16, 11, 9, -2,-21, 14, 10, -1,-22, 14, 8, -1,-18, 10,
+ -10, 16, 3, -9,-13, 20, 4,-11,-14, 21, 4,-10,-11, 16, 3, -8,
+ 11, 4, -9, -9, 15, 6,-12,-14, 17, 8,-12,-14, 16, 10, -7,-11,
+ 4, 10, 14, 13, -1, 7, 15, 16,-12, -7, 3, 8,-20,-23,-18,-10,
+ -10,-18,-26,-25, 4, 1, -6,-11, 13, 15, 11, 3, 12, 15, 13, 8,
+ -16,-19,-16,-11, 7, 12, 15, 11, 11, 16, 16, 11, -6, -9,-11,-10,
+ 18, 19, 12, 5, 18, 16, 5, -4, 6, 0,-10,-15, -9,-17,-23,-22,
+ -10,-14, -1, 21,-11,-17, 0, 29,-11,-16, 1, 30,-10,-14, 0, 23,
+ -16,-17,-12, -6,-19,-19,-14, -7, -3, -1, 1, 2, 27, 35, 29, 19,
+ -37, -8, 23, 23,-42, -9, 28, 29,-43,-10, 26, 28,-38,-11, 19, 22,
+ 32, 16,-16,-33, 39, 20,-18,-37, 38, 19,-19,-38, 32, 15,-17,-34,
+ 24, 9, -6, -4, -1,-10, -6, 3, -8, -9, -1, 3, 3, 7, 2, -6,
+ -1, -3, -1, 0, -1, 4, 2, -7, -3, 11, 3,-16, 1, 20, 9,-18,
+ -3, -8, 6, 12, -5,-10, 7, 13, -6, -9, 5, 7, -5, -5, 2, -1,
+ -8, 12, -3, -1,-10, 15, -3, 1,-11, 13, -4, 1,-11, 8, -3, 2,
+ 9, 6, -5,-12, 3, 0, -8,-13, -4, -4, -1, -1, -4, 1, 15, 18,
+ 9, 13, 14, 12, 4, 3, -1, -2, -2, -5, -8, -5, -7,-11, -9, -4,
+ 7, -5, -7, -4, 14, -2, -7, -4, 17, 0, -8, -5, 15, 1, -7, -5,
+ -10, -1, 6, 4,-15, -9, 2, 4, 2, -1, -3, 0, 25, 13, -8,-10,
+ 7, 11, -3,-16, 7, 11, -3,-15, 6, 7, -2, -9, 4, 2, -3, -5,
+ -7, -1, -1, 0, -9, -2, 2, 6,-12, -4, 6, 14,-13, -6, 8, 19,
+ -18,-18,-11, -5, -3, 0, 3, 4, 6, 8, 6, 6, 6, 6, 6, 6,
+ -5, 3, 13,-10, -6, 1, 15, -9, -6, -3, 15, -6, -6, -6, 10, -3,
+ 9, 1, -9, -9, 11, 9, 6, 5, 0, 3, 8, 7,-15,-14, -6, -5,
+ -11, -6, 11, 19, -2, -5, -9, -8, 6, 2, -9,-10, 6, 5, 4, 5,
+ -7, -3, 8, 15, -1, 3, 10, 15, 5, 5, -1, -2, 4, -2,-21,-25,
+ 6, -6, -6, 5, 8, -9, -7, 9, 8,-12, -7, 13, 4,-14, -7, 14,
+ -4, -3, 1, 1, -3, -5, -2, -3, 7, 0, -2, -4, 20, 7, -4, -4,
+ -3,-20, -6, 10, 6, 0, 0, 1, 5, 8, 5, -1, -3, 0, 0, -2,
+ 13, 6, -1, 2, 5, 3, 2, 3, -3, 0, 3, 0,-16, -8, -2, -5,
+ -2, -7, -6, 0, -3, -6, -3, 1, -5, -1, 2, -1, -1, 12, 16, 5,
+ -7, 1, 9, 8,-10, -2, 5, 3, -6, 2, 7, 3, -4, 0, -1, -7,
+ 3, 4, -9,-24, 0, 2, 6, 3, -1, -1, 4, 7, 5, 3, -1, -2,
+ 3, 6, -9, 2, 1, 6,-13, 1, 1, 8,-10, 2, 1, 8, -7, 1,
+ -3, -3, 2, 22, -2, -3, -5, 12, -2, -3,-10, 2, -3, -1, -4, 2,
+ 11, 12, 8, 2, -5, -5, -5, -8, -6, -4, 0, -3, -2, -1, 3, 3,
+ 12, -6, -2, -1, 12, -8, -2, -2, 9, -7, 0, -3, 4, -6, 2, -2,
+ -19, 1, 12, -3, -4, 4, 5, -4, 6, 1, -2, -1, 4, -4, -2, 7,
+ -3, -4, -7, -8, -4, -4, -2, 0, -1, 2, 14, 16, -4, -2, 4, 4,
+ -1, 7, 2, -5, -2, 0, -1, 1, 4, -3, -1, 13, 6,-12,-14, 8,
+ -1, 5, 4, -5, -2, 5, 3, -9, -2, 7, 4,-12, -1, 7, 4, -9,
+ -6, -3, 1, 1, 11, 11, 0, -6, 6, 4, -2, -7,-12,-10, 3, 10,
+ -2, -3, -3, -2, 6, 11, 14, 10, -9,-11,-10,-10, 2, 2, 3, 2,
+ -7, -5, -7, -1, -1, 2, 0, 7, -1, 1, 0, 9, 3, 4, -5, -1,
+ 10, -1,-15, -1, 4, 1, -5, 2, -3, 1, -1, 1, -3, 1, 4, 4,
+ 2, -1, 4, 10, 6, 2, -1, 0, 2, 2, -7,-12, -4, 2, 0, -3,
+ -1, -4, -1, -8, 3, -1, 2, -9, 4, 0, 5, -5, 2, 0, 8, 3,
+ 3, 2, 1, 1, 4, -2, 0, 3, 2, -1, 4, 1, 0, 6, -1,-25,
+ -1, -2, -2, -4, -3, 0, -1, -4, -1, -1, -4, 2, 0, -6, 2, 25,
+ -11, -1, 5, 0, 7, 0, -2, 2, 10, -1, -3, 4, -5, -5, -2, -1,
+ 0, 6, 3, -1, -2, -1, -1, 1, -1, -7,-12, -5, 8, 6, 2, 4,
+ 2, 6, -1, -6, 9, 10, -1, -4, 1, 0, -4, 0, 3, -2, -9, -5,
+ -4, 3, 4, 0, -4, 3, 3, 0,-11, 0, 3, 2,-11, 3, 7, 2,
+ 2, -4, 7, 3, 1, -8, 7, 1, -1,-12, 4, 1, 3, -9, 2, 2,
+ 2, -2, -2, 9,-17, -3, 3, 1, -4, 7, 1, -6, 5, 4, -1, 3,
+ -1, 2, 0, -4, -7, 8, 12, -1, -2, 5, 4, -5, 3, -5, -8, -2,
+ 0, 0, -5, -2, -2, -8, 3, 27, -1, -4, -3, 6, -3, 1, -2, -7,
+ 4, 4, 1, -1, -7,-10, -7, -3, 10, 10, 5, 3, -2, -2, -4, -3,
+ 0, 1, 5, 7, 4, -2,-16,-20, 0, 4, 7, 8, 2, 0, -2, -1,
+ -2, 1, 3, 17, -3, 1, -2, -1, -1, -2, -1, -2, -1, -5, -1, 0,
+ 5, -3, 1, 0, 6, -2, 0, 0, -1, -2, 0, -3,-11, 1, 8, -1,
+ 3, 0, 0, 0, 0, 2, 4, 1, 2, 0, 6, 1, -2,-18, -3, 2,
+ -14, 0, 6, 1, -5, -2, -1, 1, -1, 1, 0, 1, 1, 7, 4, 0,
+ -1, 0, 1, -4, 1, 8, 3, -4, -3, 4, 1, 3, -6, 1, -4, 1,
+ 1,-12, 3, 3, -1,-10, 0, -1, 2, 0, 2, 1, 3, 2, 2, 4,
+ 3, 0, 0, 3, 2, 0, -2, 1, 5, 2, -5, 0, 6, -1,-14, -1,
+ -2, -6, -3, -3, 2, -1, 4, 5, 6, -1, -2, 0, 4, 4, -1, -5,
+ -4, 1,-11, 0, -1, 2, -4, 1, 2, -3, 3, -1, 1, -2, 15, 0,
+ 1, -1, 0, -2, 1, -4, -7, 1, -2, -6, -1, 21, -2, 2, -1, 1,
+ 21, -1, -2, 0, -1, -3, 1, -2, -9, -2, 2, -1, 2, 1, -4, -1,
+ 1, 8, 2, -6,-10, -1, 4, 0, -4, -3, 3, 3, 5, 0, -1, -1,
+ 3, 2, 1, -2, -2, -2, 4, 3, 5, 2, -4,-17, 0, -2, 4, 3,
+ -7, -4, 0, 3, 9, 9, 2, -1,-11, -6, 0, -1, 5, 1, 0, 1,
+ 0, 17, 5,-11, 3, -2, -6, 0, 2, -2, -4, 1, -4, 1, 2, -1,
+ -5, -1, -5, -3, -3, 5, -3, -2, 4, 16, 2, -5, -2, 5, -1, -1,
+ 0, 0, -4, 1, -1, 2, 5, 11, -1, -1, -2, 1, -4, -2, -3, -1,
+ -5, -1, 10, 0, 6, 1, 0, -3, 0, -4, 1, 0, -2, -4, 3, -1,
+ 6, 9, 3, 0, -2, 1, -2, 0, -2, -3, -2, -2, 1, 0, 1, -6,
+ 1, 0, 2, 1, -1, 3, -2, 1, 0, -1,-15, 0, -1, 5, 2, 6,
+ 2, 0, 2, 2, 0,-12, -4, 6, 0, 1, 4, -1, 1, 2, 1, -4,
+ 1, -2, -7, 0, 0, 0, 0, -1, -5, 2, 11, 3, 1, 3, 0, -6,
+ 0, -3, -9, -4, 1, 3, -1, 0, 4, 1, -2, 0, 7, -3, -1, 6,
+ 1, -2, 6, 2, 0, -1, 3, -2, -2, 4, 0, 2, -1, 2,-14, 2,
+ 2, 2, 0, -1, -2, 3, -3,-14, 0, 2, 3, -3, 5, 1, 3, 2,
+ 1, -3, 4,-14, 1, -2, 11, -1, 0, -1, 3, 0, -1, 1, 0, 2,
+ -2, 3, -3, 2, -4, -1, -4, 3, -1, 2, 1, 3, -6, -2, 2, 7,
+ -2, 1, 2, 0, -2, 0, 0, -1, 12, 5, -1, 2, -8, -1, 1, -7,
+ 2, -2, -4, 2, 11, 0,-11, -2, 3, 1, -3, -1, 0, 3, 1, -1,
+ 0, 3, 0, -2, 0, -6, -1, -3, 12, -7, -2, 0, 7, -2, 1, 1,
+ 1, 2, 2, 2, -1, 2, 0, 2,-23, 0, 4, 0, 3, 2, 1, 3,
+ -4, -5, -1, 5, -3, 5, 10, -1, 0, 0, 3, -4, 1, -1, 2, -5
};
-static const uint32 s_svq1InterCodebook8x4[768] = {
- 0x00040809, 0xfdfcfcfd, 0xff040809, 0xfdfbfbfc,
- 0xfe030708, 0xfcfbfbfb, 0xfe010406, 0xfdfcfbfc,
- 0xfcf5f2f4, 0x06060501, 0xfbf9f6f8, 0x010101fe,
- 0x01030405, 0xffff0000, 0x06090d0d, 0xfeff0003,
- 0xfffdfcfc, 0x0b080401, 0xfefcfafb, 0x0c080300,
- 0xfcfaf9f9, 0x0a0702fe, 0xfcfbf9f9, 0x080501fe,
- 0x01fffefd, 0x06070603, 0x07050302, 0x04060808,
- 0x03040504, 0xf9fafe01, 0xf9fe0001, 0xf0eff2f6,
- 0x0801fcfb, 0xf9fd0309, 0x0b01faf9, 0xf8fd050c,
- 0x0900f9f8, 0xf9fd050b, 0x05fffaf8, 0xfafe0408,
- 0xf8f9fbfc, 0xfaf8f7f7, 0xf9fafbfc, 0xfefcfaf9,
- 0x03020100, 0x090a0805, 0x06030201, 0x0d0e0c09,
- 0x05060605, 0x01020304, 0x07070605, 0x04060606,
- 0x010100ff, 0x05050503, 0xefeff0f3, 0xfcfaf6f2,
- 0x100d0b09, 0x0a0c0d0f, 0xf9fafbfc, 0xfbfaf9f9,
- 0xf9f9fafa, 0xfbfaf9f9, 0x0000fffe, 0xff000000,
- 0xf0f1f3f5, 0xf6f4f2f0, 0x05040302, 0x03030304,
- 0x08080706, 0x05060708, 0x03030403, 0x03030303,
- 0x01040403, 0xeff3f9fe, 0x05070705, 0xedf3fb01,
- 0x08090806, 0xf0f7ff05, 0x0a0a0806, 0xf5fc0207,
- 0xf6ff0912, 0x00fcf7f3, 0xf4ff0c16, 0x02fcf6f1,
- 0xf6000d17, 0x02fdf7f3, 0xfa020c14, 0x02fefaf7,
- 0xf9fafafa, 0xfaf9f9f9, 0xf8f8f9fa, 0xf8f7f7f7,
- 0xfdfdfdfd, 0xfdfdfdfd, 0x15120f0c, 0x0e111315,
- 0x1212100e, 0x0d0f1012, 0x05060605, 0x03040405,
- 0xf6f7f9fa, 0xf9f7f6f6, 0xf2f3f5f6, 0xf6f4f3f2,
- 0x05fcefe5, 0x070a0a09, 0x07fdede0, 0x080b0c0b,
- 0x08fef0e2, 0x070a0c0c, 0x0700f4e9, 0x06090b0a,
- 0x0c101110, 0xf4f8ff06, 0x0a0f1211, 0xeef1f801,
- 0x040a0e0f, 0xe9ecf2fb, 0xff04080a, 0xeaebf0f7,
- 0xf5f4f4f6, 0x140e04fb, 0xf4f1f3f5, 0x1b1307fc,
- 0xf5f2f3f5, 0x1c1508fd, 0xf7f4f5f6, 0x191208fe,
- 0x01ffffff, 0x05060604, 0x02000000, 0xfe010304,
- 0x04020000, 0xf6f9ff04, 0x05030000, 0xf1f5fd03,
- 0xfff8f3f2, 0xfcff0303, 0x04fffcfb, 0x00030808,
- 0x03020203, 0x01030504, 0xfe000305, 0xfffffffe,
- 0xfafa0109, 0xfffefdfb, 0xfafa010c, 0x00fffefc,
- 0xfcfc040e, 0xfffffefe, 0xffff060e, 0xffffffff,
- 0x0a080604, 0x0507090b, 0x00ffffff, 0xfeffff00,
- 0xfbfcfcfe, 0xfcfbfbfb, 0xfcfdfdfe, 0xfffefdfc,
- 0x04040302, 0x00000103, 0x050401ff, 0x03040506,
- 0x02fefaf8, 0x03040403, 0xfbf7f3f2, 0x0000fffe,
- 0xfcfbfcfd, 0x0d0c0700, 0xfbfbfcfd, 0x0a0904fe,
- 0xfbfcfdfe, 0x0403fffc, 0xfdfeffff, 0x0100fefd,
- 0xf8fe0509, 0xfcf9f6f5, 0x02060a0c, 0x0000ff00,
- 0x04030202, 0x01010103, 0x00fcf8f7, 0x00010201,
- 0x05080806, 0xf3f5fb01, 0x02020100, 0xf5f8fcff,
- 0x0301fefd, 0xfcff0103, 0x0502fffe, 0x01040606,
- 0x05050403, 0xfafd0104, 0x02040605, 0xfd000202,
- 0xfb000506, 0xfefffefb, 0xf5fd0407, 0xfefdf9f4,
- 0xffff0001, 0x000000ff, 0x04040302, 0x03040505,
- 0xf6f7f7f9, 0xfaf9f7f6, 0x06050403, 0x05050505,
- 0xf9f9f9f9, 0xfcfbfafa, 0xfffdfcfb, 0x0000ffff,
- 0x0401fefd, 0x05050505, 0x0603fffe, 0x090a0a09,
- 0x030a01f2, 0x010100fe, 0x030d02f0, 0x0001fffd,
- 0x030c02f1, 0x0101fefc, 0x020a03f6, 0x0101fffd,
- 0x02040100, 0x0bfdf6fb, 0x020401ff, 0x0ffef3fa,
- 0x010300ff, 0x0ffff4fa, 0x010201ff, 0x0b00f8fc,
- 0xfefe050a, 0xfc010502, 0xfaf80007, 0xfc020501,
- 0xf9f4fb02, 0xff040702, 0xfcf6f9ff, 0x02070904,
- 0xfafcfbfb, 0xfdfbfbfa, 0xfcfefeff, 0xfcfbfafb,
- 0x04070706, 0xfdfdfe00, 0x0a0d0e0d, 0xfeff0105,
- 0x02020101, 0x02020202, 0xf7f8fafb, 0xfaf9f8f7,
- 0x0b0a0907, 0x0507090b, 0xfdfdfeff, 0xfdfcfcfc,
- 0x0000ffff, 0xffff0000, 0xfbfcfdfd, 0xfefdfdfc,
- 0xfdff0102, 0x00fffefd, 0x03080c0c, 0x01000001,
- 0xfaf8f8fa, 0x080602fe, 0xfeff0101, 0x07050300,
- 0xff010303, 0x020000ff, 0xff000100, 0xfffeffff,
- 0x00000001, 0x04020000, 0x04030102, 0x02000103,
- 0x00000102, 0x0300ffff, 0xf4fa0105, 0x04fff8f3,
- 0xfeff00fe, 0x030200ff, 0x00fefdfa, 0x01010101,
- 0x0400fbf7, 0x00010305, 0x0703fdf8, 0x00010408,
- 0x03020201, 0xfdff0103, 0x06050504, 0x00020506,
- 0x00000000, 0xfcfe0001, 0xfdfcfdfd, 0xf8f9fcfd,
- 0xff060c0e, 0x0000fdfd, 0xfd010507, 0xfffefcfb,
- 0xfefefefe, 0xfffffefe, 0x01fffcfa, 0xff000101,
- 0xfd010202, 0xfdfaf9fa, 0xfdff0001, 0x060401fe,
- 0x02010000, 0x07080704, 0x00000000, 0xf8f9fcff,
- 0xfe010200, 0xfffefdfd, 0xfd0001ff, 0x0200fefb,
- 0xfbfefffe, 0x090601fc, 0xfcfdfefd, 0x0d0b05fe,
- 0x0602fefc, 0xf2f6fd04, 0x0401fffe, 0xfeff0104,
- 0xfeff0000, 0x060400fe, 0xfd000202, 0x090500fd,
- 0x01fefcfc, 0xf9030906, 0xfffefefe, 0xf5000804,
- 0x00000101, 0xf6ff0602, 0x00010202, 0xf9000402,
- 0xfafdfeff, 0xf8f8f8f9, 0x01030302, 0xfcfdfeff,
- 0x04050505, 0xff000203, 0x03030303, 0x01010202,
- 0xfe020303, 0x0a0700fd, 0xfe020201, 0x0300fcfb,
- 0x02040300, 0xfcfafbfd, 0x04040200, 0xf9f9fc01,
- 0x05050402, 0x06060505, 0xfbfdfcfc, 0xfefdfdfb,
- 0xfbfcfcfd, 0xfefefefc, 0x00000101, 0x04050402,
- 0x040300fe, 0x02020304, 0x00fcf9f7, 0x06060603,
- 0xfefdfbfb, 0x04030100, 0xfe020505, 0xfdfbfafc,
- 0x07fcfa01, 0x01fefe05, 0x06fcfb05, 0x01fcfb04,
- 0x06fcfb05, 0x01fdfb04, 0x08fdf901, 0x01fdff07,
- 0x00fcf9f8, 0x05050402, 0x02050605, 0xf9f9fbff,
- 0x01040605, 0xfbfafbfd, 0xfefbf9f9, 0x0a090601,
- 0x01000306, 0xf2f80003, 0x01ff0003, 0xfc000304,
- 0x01000001, 0x01010102, 0x0201ffff, 0x00ffff01,
- 0x01010101, 0x00fdfe00, 0x00010201, 0xfcf7f8fe,
- 0x02030301, 0x01fdfd01, 0x01010100, 0x08040101,
- 0x07090502, 0x01ffff02, 0x0001fffc, 0x02fffcfd,
- 0x030300fd, 0x0200ff00, 0x0101fffc, 0xfcfbfcfe,
- 0xfefeff01, 0x050402ff, 0x00010102, 0x0000ffff,
- 0x05040302, 0x00010204, 0xfdfaf7f7, 0xffffffff,
- 0x0704fafa, 0xfefffe00, 0x0605feff, 0xff00feff,
- 0x0001ff04, 0xfe00fefc, 0xfeff0107, 0x010301fd,
- 0x03010204, 0x02010103, 0x00fcfe02, 0x00000103,
- 0xfcf8fc01, 0x00010201, 0xfaf7fd02, 0x02030300,
- 0xff00ffff, 0x020100ff, 0xf8fc0103, 0x0201fdf9,
- 0xfefdff02, 0x000100ff, 0x0b0500ff, 0xfdff0309,
- 0xfffefeff, 0x01010101, 0x0300ff00, 0x05050606,
- 0xffff0102, 0xfcfafbfe, 0x01020202, 0xfbfbfcff,
- 0xf9fafdff, 0x01fffcfa, 0x04030505, 0x05040304,
- 0xfefdfeff, 0x0100fefe, 0x00000000, 0x03020100,
- 0xfffcfafa, 0x02020202, 0xfefbf9fa, 0x00ffff00,
- 0x04020202, 0x04030304, 0xff000102, 0x04020000,
- 0xf8fb050c, 0x020200fb, 0xfdfafd02, 0xfeff0000,
- 0x03fffdfe, 0xfdfe0104, 0x04030202, 0xffff0103,
- 0x00010203, 0x00030401, 0xfb000304, 0x030300fa,
- 0xf9010302, 0x0301faf4, 0xff040301, 0x0100fcfa,
- 0x0602fcf7, 0x00010407, 0x0604fff9, 0xfdfd0004,
- 0x040400fa, 0xfefdfe01, 0x020301fc, 0x00fffe00,
- 0xfb020500, 0xfc0103fd, 0xfa0204fe, 0xfd0406fd,
- 0xfb0305ff, 0xfc0307ff, 0xfa0002ff, 0xfd0305fd,
- 0x0503fdf8, 0xfefe0103, 0xfe040402, 0x0301fdfc,
- 0xfbfd0102, 0x030403fd, 0x03fbfafb, 0xfbff080a,
- 0xfc020300, 0x0600f9f7, 0x0705fffb, 0xfdfdff04,
- 0x03fefbfb, 0xfcff0506, 0xfc000609, 0xff0101fe,
- 0x01ffffff, 0x00ff0001, 0x000000ff, 0x00ffff00,
- 0xfffe0102, 0x00000101, 0xff02080c, 0xf9f9fcff,
- 0x06030102, 0x00020407, 0x00ff0001, 0xf8f9fcff,
- 0x00ff0000, 0xfdff0000, 0x00000000, 0xfe000101,
- 0x010100ff, 0xfeff0000, 0xfdff0000, 0x01fffdfc,
- 0x000000ff, 0x0c0a0401, 0xfefe00ff, 0x01fffdfd,
- 0xfcfefffd, 0x07090902, 0xfdff00fd, 0x01ff0200,
- 0xfdfe01ff, 0x00fdff00, 0xfefd0000, 0x01ffff00,
- 0xfffffeff, 0xfefffffe, 0xfffeff02, 0xfe000100,
- 0x02feff03, 0xfdff0305, 0x01fbfb01, 0x00020606,
- 0xff000201, 0xfe000100, 0x00fffdfb, 0xfe010201,
- 0xfefefbf9, 0x0100fefe, 0x010100ff, 0x0c090300,
- 0x01050600, 0x0300fdfe, 0x01050600, 0x03020101,
- 0xfdfefefb, 0x00000000, 0xfefdfdfa, 0xfeff0000,
- 0x01020404, 0x00ffff00, 0x0100fefe, 0x00010102,
- 0xff010202, 0xf6f7fbfd, 0xffff0102, 0x01040401,
- 0xfefe0004, 0x00fffefe, 0xfdfc0107, 0x010100fe,
- 0xfeff050a, 0x00010100, 0xfcfd0105, 0xfefffffd,
- 0xfdff0102, 0xff0101fd, 0x0003fffe, 0x000101ff,
- 0x020701fd, 0x00fffefd, 0xff0804fe, 0x0200fbf8,
- 0x0201fffc, 0xfefcfd01, 0x01fefdfb, 0x06040404,
- 0xfdfcfefd, 0x02010100, 0x01020202, 0xffff0102,
- 0xff00fffc, 0xfffffdfd, 0x02040401, 0xfdfeff00,
- 0x03050604, 0xfcfe0102, 0x01010100, 0xfafcff01,
- 0xff020201, 0x02fffbfa, 0x0101fefd, 0x0502fdfc,
- 0x0202fffe, 0x0300fcfd, 0x0602fefe, 0x02010205,
- 0x00fdfd02, 0x01030200, 0x0301ff03, 0xfbff0201,
- 0xfefcf9fb, 0x01080801, 0x000200ff, 0xfd0100fd,
- 0xfefbfbfe, 0xfe00fffd, 0x0400fcff, 0x00040200,
- 0x0a080000, 0xff030102, 0x0302fdfc, 0xff01fdfd,
- 0x02fcfe01, 0xfffe0307, 0xfffe0406, 0x03ff0002,
- 0xfefe0101, 0x04fdfbfe, 0x0101fefa, 0x04fefcff,
- 0xfefefffe, 0xfe000100, 0xff0001ff, 0xfdff0000,
- 0xfcfe0100, 0x0000fffd, 0x00050806, 0x03020100,
- 0x0502fefe, 0x01000002, 0xfffefe02, 0x040201ff,
- 0x0100ff02, 0x01000000, 0x01fff9f8, 0x0301ffff,
- 0x02060300, 0x000201fe, 0x00fff9f6, 0x0102fffd,
- 0x02020000, 0xff010101, 0xfefe0003, 0x00010200,
- 0x00000108, 0x00fffdfe, 0x0502fe02, 0x01fffe01,
- 0xfffdfafd, 0x02fffdfd, 0x02010002, 0x00000102,
- 0xfeffff01, 0x000100ff, 0xff02090f, 0xfdfdfdfe,
- 0x00fefd00, 0xffffff00, 0x00010001, 0xffffff00,
- 0xfe020200, 0xf8f9fdfd, 0x00020200, 0x01010201,
- 0x02020201, 0x03000103, 0xfeff0001, 0x0500feff,
- 0x01fffaf5, 0xfd010302, 0xff030401, 0xff0201fe,
- 0xff010202, 0xff0100fe, 0xffff0000, 0x02030200,
- 0x01020101, 0xfc0001ff, 0xfe000000, 0xfe0402fe,
- 0x0000fdfe, 0xfa0102ff, 0x05050200, 0xf9ff0203,
- 0x00000204, 0xff010303, 0x03ffff00, 0xff010406,
- 0x0200fefe, 0xfefe0002, 0xfbff00ff, 0x01fffbf9,
- 0x00feff05, 0xfb020402, 0x02fefb00, 0xfa000201,
- 0x01000106, 0x0204fffe, 0x00fdfd02, 0x0000feff,
- 0x0200ff01, 0x0b060000, 0x00ffff02, 0x0503fefd,
- 0x00fffe00, 0xfd0000ff, 0xffffff01, 0xf9fdfffe,
- 0xfefe0101, 0xfe010301, 0xff0002ff, 0x000001ff,
- 0xff0302fc, 0x0100fefe, 0x0504fef5, 0xfeff0206,
- 0xff01fefa, 0x0901fcfd, 0x030300fd, 0x03fdfd02,
- 0x00000101, 0x03feff01, 0xfdfd0002, 0x03ffff00,
- 0x01fdff01, 0x06fcfa02, 0xfefbfe00, 0x03fefd00,
- 0xfe010202, 0xff0201fe, 0xfe0101ff, 0xff0706ff,
- 0xfefc0001, 0x01fdfe01, 0xfefd00fc, 0x00fd0002,
- 0x010304fd, 0xff000708, 0xfc0104fd, 0xfdfe0302,
- 0xfc0106fd, 0xffff0101, 0xfdfd04fe, 0xffff0003,
- 0x02fc0201, 0x02fffd04, 0x05fcff03, 0x02fdfa04
+static const int8 s_svq1InterCodebook8x4[3072] = {
+ 9, 8, 4, 0, -3, -4, -4, -3, 9, 8, 4, -1, -4, -5, -5, -3,
+ 8, 7, 3, -2, -5, -5, -5, -4, 6, 4, 1, -2, -4, -5, -4, -3,
+ -12,-14,-11, -4, 1, 5, 6, 6, -8,-10, -7, -5, -2, 1, 1, 1,
+ 5, 4, 3, 1, 0, 0, -1, -1, 13, 13, 9, 6, 3, 0, -1, -2,
+ -4, -4, -3, -1, 1, 4, 8, 11, -5, -6, -4, -2, 0, 3, 8, 12,
+ -7, -7, -6, -4, -2, 2, 7, 10, -7, -7, -5, -4, -2, 1, 5, 8,
+ -3, -2, -1, 1, 3, 6, 7, 6, 2, 3, 5, 7, 8, 8, 6, 4,
+ 4, 5, 4, 3, 1, -2, -6, -7, 1, 0, -2, -7,-10,-14,-17,-16,
+ -5, -4, 1, 8, 9, 3, -3, -7, -7, -6, 1, 11, 12, 5, -3, -8,
+ -8, -7, 0, 9, 11, 5, -3, -7, -8, -6, -1, 5, 8, 4, -2, -6,
+ -4, -5, -7, -8, -9, -9, -8, -6, -4, -5, -6, -7, -7, -6, -4, -2,
+ 0, 1, 2, 3, 5, 8, 10, 9, 1, 2, 3, 6, 9, 12, 14, 13,
+ 5, 6, 6, 5, 4, 3, 2, 1, 5, 6, 7, 7, 6, 6, 6, 4,
+ -1, 0, 1, 1, 3, 5, 5, 5,-13,-16,-17,-17,-14,-10, -6, -4,
+ 9, 11, 13, 16, 15, 13, 12, 10, -4, -5, -6, -7, -7, -7, -6, -5,
+ -6, -6, -7, -7, -7, -7, -6, -5, -2, -1, 0, 0, 0, 0, 0, -1,
+ -11,-13,-15,-16,-16,-14,-12,-10, 2, 3, 4, 5, 4, 3, 3, 3,
+ 6, 7, 8, 8, 8, 7, 6, 5, 3, 4, 3, 3, 3, 3, 3, 3,
+ 3, 4, 4, 1, -2, -7,-13,-17, 5, 7, 7, 5, 1, -5,-13,-19,
+ 6, 8, 9, 8, 5, -1, -9,-16, 6, 8, 10, 10, 7, 2, -4,-11,
+ 18, 9, -1,-10,-13, -9, -4, 0, 22, 12, -1,-12,-15,-10, -4, 2,
+ 23, 13, 0,-10,-13, -9, -3, 2, 20, 12, 2, -6, -9, -6, -2, 2,
+ -6, -6, -6, -7, -7, -7, -7, -6, -6, -7, -8, -8, -9, -9, -9, -8,
+ -3, -3, -3, -3, -3, -3, -3, -3, 12, 15, 18, 21, 21, 19, 17, 14,
+ 14, 16, 18, 18, 18, 16, 15, 13, 5, 6, 6, 5, 5, 4, 4, 3,
+ -6, -7, -9,-10,-10,-10, -9, -7,-10,-11,-13,-14,-14,-13,-12,-10,
+ -27,-17, -4, 5, 9, 10, 10, 7,-32,-19, -3, 7, 11, 12, 11, 8,
+ -30,-16, -2, 8, 12, 12, 10, 7,-23,-12, 0, 7, 10, 11, 9, 6,
+ 16, 17, 16, 12, 6, -1, -8,-12, 17, 18, 15, 10, 1, -8,-15,-18,
+ 15, 14, 10, 4, -5,-14,-20,-23, 10, 8, 4, -1, -9,-16,-21,-22,
+ -10,-12,-12,-11, -5, 4, 14, 20,-11,-13,-15,-12, -4, 7, 19, 27,
+ -11,-13,-14,-11, -3, 8, 21, 28,-10,-11,-12, -9, -2, 8, 18, 25,
+ -1, -1, -1, 1, 4, 6, 6, 5, 0, 0, 0, 2, 4, 3, 1, -2,
+ 0, 0, 2, 4, 4, -1, -7,-10, 0, 0, 3, 5, 3, -3,-11,-15,
+ -14,-13, -8, -1, 3, 3, -1, -4, -5, -4, -1, 4, 8, 8, 3, 0,
+ 3, 2, 2, 3, 4, 5, 3, 1, 5, 3, 0, -2, -2, -1, -1, -1,
+ 9, 1, -6, -6, -5, -3, -2, -1, 12, 1, -6, -6, -4, -2, -1, 0,
+ 14, 4, -4, -4, -2, -2, -1, -1, 14, 6, -1, -1, -1, -1, -1, -1,
+ 4, 6, 8, 10, 11, 9, 7, 5, -1, -1, -1, 0, 0, -1, -1, -2,
+ -2, -4, -4, -5, -5, -5, -5, -4, -2, -3, -3, -4, -4, -3, -2, -1,
+ 2, 3, 4, 4, 3, 1, 0, 0, -1, 1, 4, 5, 6, 5, 4, 3,
+ -8, -6, -2, 2, 3, 4, 4, 3,-14,-13, -9, -5, -2, -1, 0, 0,
+ -3, -4, -5, -4, 0, 7, 12, 13, -3, -4, -5, -5, -2, 4, 9, 10,
+ -2, -3, -4, -5, -4, -1, 3, 4, -1, -1, -2, -3, -3, -2, 0, 1,
+ 9, 5, -2, -8,-11,-10, -7, -4, 12, 10, 6, 2, 0, -1, 0, 0,
+ 2, 2, 3, 4, 3, 1, 1, 1, -9, -8, -4, 0, 1, 2, 1, 0,
+ 6, 8, 8, 5, 1, -5,-11,-13, 0, 1, 2, 2, -1, -4, -8,-11,
+ -3, -2, 1, 3, 3, 1, -1, -4, -2, -1, 2, 5, 6, 6, 4, 1,
+ 3, 4, 5, 5, 4, 1, -3, -6, 5, 6, 4, 2, 2, 2, 0, -3,
+ 6, 5, 0, -5, -5, -2, -1, -2, 7, 4, -3,-11,-12, -7, -3, -2,
+ 1, 0, -1, -1, -1, 0, 0, 0, 2, 3, 4, 4, 5, 5, 4, 3,
+ -7, -9, -9,-10,-10, -9, -7, -6, 3, 4, 5, 6, 5, 5, 5, 5,
+ -7, -7, -7, -7, -6, -6, -5, -4, -5, -4, -3, -1, -1, -1, 0, 0,
+ -3, -2, 1, 4, 5, 5, 5, 5, -2, -1, 3, 6, 9, 10, 10, 9,
+ -14, 1, 10, 3, -2, 0, 1, 1,-16, 2, 13, 3, -3, -1, 1, 0,
+ -15, 2, 12, 3, -4, -2, 1, 1,-10, 3, 10, 2, -3, -1, 1, 1,
+ 0, 1, 4, 2, -5,-10, -3, 11, -1, 1, 4, 2, -6,-13, -2, 15,
+ -1, 0, 3, 1, -6,-12, -1, 15, -1, 1, 2, 1, -4, -8, 0, 11,
+ 10, 5, -2, -2, 2, 5, 1, -4, 7, 0, -8, -6, 1, 5, 2, -4,
+ 2, -5,-12, -7, 2, 7, 4, -1, -1, -7,-10, -4, 4, 9, 7, 2,
+ -5, -5, -4, -6, -6, -5, -5, -3, -1, -2, -2, -4, -5, -6, -5, -4,
+ 6, 7, 7, 4, 0, -2, -3, -3, 13, 14, 13, 10, 5, 1, -1, -2,
+ 1, 1, 2, 2, 2, 2, 2, 2, -5, -6, -8, -9, -9, -8, -7, -6,
+ 7, 9, 10, 11, 11, 9, 7, 5, -1, -2, -3, -3, -4, -4, -4, -3,
+ -1, -1, 0, 0, 0, 0, -1, -1, -3, -3, -4, -5, -4, -3, -3, -2,
+ 2, 1, -1, -3, -3, -2, -1, 0, 12, 12, 8, 3, 1, 0, 0, 1,
+ -6, -8, -8, -6, -2, 2, 6, 8, 1, 1, -1, -2, 0, 3, 5, 7,
+ 3, 3, 1, -1, -1, 0, 0, 2, 0, 1, 0, -1, -1, -1, -2, -1,
+ 1, 0, 0, 0, 0, 0, 2, 4, 2, 1, 3, 4, 3, 1, 0, 2,
+ 2, 1, 0, 0, -1, -1, 0, 3, 5, 1, -6,-12,-13, -8, -1, 4,
+ -2, 0, -1, -2, -1, 0, 2, 3, -6, -3, -2, 0, 1, 1, 1, 1,
+ -9, -5, 0, 4, 5, 3, 1, 0, -8, -3, 3, 7, 8, 4, 1, 0,
+ 1, 2, 2, 3, 3, 1, -1, -3, 4, 5, 5, 6, 6, 5, 2, 0,
+ 0, 0, 0, 0, 1, 0, -2, -4, -3, -3, -4, -3, -3, -4, -7, -8,
+ 14, 12, 6, -1, -3, -3, 0, 0, 7, 5, 1, -3, -5, -4, -2, -1,
+ -2, -2, -2, -2, -2, -2, -1, -1, -6, -4, -1, 1, 1, 1, 0, -1,
+ 2, 2, 1, -3, -6, -7, -6, -3, 1, 0, -1, -3, -2, 1, 4, 6,
+ 0, 0, 1, 2, 4, 7, 8, 7, 0, 0, 0, 0, -1, -4, -7, -8,
+ 0, 2, 1, -2, -3, -3, -2, -1, -1, 1, 0, -3, -5, -2, 0, 2,
+ -2, -1, -2, -5, -4, 1, 6, 9, -3, -2, -3, -4, -2, 5, 11, 13,
+ -4, -2, 2, 6, 4, -3,-10,-14, -2, -1, 1, 4, 4, 1, -1, -2,
+ 0, 0, -1, -2, -2, 0, 4, 6, 2, 2, 0, -3, -3, 0, 5, 9,
+ -4, -4, -2, 1, 6, 9, 3, -7, -2, -2, -2, -1, 4, 8, 0,-11,
+ 1, 1, 0, 0, 2, 6, -1,-10, 2, 2, 1, 0, 2, 4, 0, -7,
+ -1, -2, -3, -6, -7, -8, -8, -8, 2, 3, 3, 1, -1, -2, -3, -4,
+ 5, 5, 5, 4, 3, 2, 0, -1, 3, 3, 3, 3, 2, 2, 1, 1,
+ 3, 3, 2, -2, -3, 0, 7, 10, 1, 2, 2, -2, -5, -4, 0, 3,
+ 0, 3, 4, 2, -3, -5, -6, -4, 0, 2, 4, 4, 1, -4, -7, -7,
+ 2, 4, 5, 5, 5, 5, 6, 6, -4, -4, -3, -5, -5, -3, -3, -2,
+ -3, -4, -4, -5, -4, -2, -2, -2, 1, 1, 0, 0, 2, 4, 5, 4,
+ -2, 0, 3, 4, 4, 3, 2, 2, -9, -7, -4, 0, 3, 6, 6, 6,
+ -5, -5, -3, -2, 0, 1, 3, 4, 5, 5, 2, -2, -4, -6, -5, -3,
+ 1, -6, -4, 7, 5, -2, -2, 1, 5, -5, -4, 6, 4, -5, -4, 1,
+ 5, -5, -4, 6, 4, -5, -3, 1, 1, -7, -3, 8, 7, -1, -3, 1,
+ -8, -7, -4, 0, 2, 4, 5, 5, 5, 6, 5, 2, -1, -5, -7, -7,
+ 5, 6, 4, 1, -3, -5, -6, -5, -7, -7, -5, -2, 1, 6, 9, 10,
+ 6, 3, 0, 1, 3, 0, -8,-14, 3, 0, -1, 1, 4, 3, 0, -4,
+ 1, 0, 0, 1, 2, 1, 1, 1, -1, -1, 1, 2, 1, -1, -1, 0,
+ 1, 1, 1, 1, 0, -2, -3, 0, 1, 2, 1, 0, -2, -8, -9, -4,
+ 1, 3, 3, 2, 1, -3, -3, 1, 0, 1, 1, 1, 1, 1, 4, 8,
+ 2, 5, 9, 7, 2, -1, -1, 1, -4, -1, 1, 0, -3, -4, -1, 2,
+ -3, 0, 3, 3, 0, -1, 0, 2, -4, -1, 1, 1, -2, -4, -5, -4,
+ 1, -1, -2, -2, -1, 2, 4, 5, 2, 1, 1, 0, -1, -1, 0, 0,
+ 2, 3, 4, 5, 4, 2, 1, 0, -9, -9, -6, -3, -1, -1, -1, -1,
+ -6, -6, 4, 7, 0, -2, -1, -2, -1, -2, 5, 6, -1, -2, 0, -1,
+ 4, -1, 1, 0, -4, -2, 0, -2, 7, 1, -1, -2, -3, 1, 3, 1,
+ 4, 2, 1, 3, 3, 1, 1, 2, 2, -2, -4, 0, 3, 1, 0, 0,
+ 1, -4, -8, -4, 1, 2, 1, 0, 2, -3, -9, -6, 0, 3, 3, 2,
+ -1, -1, 0, -1, -1, 0, 1, 2, 3, 1, -4, -8, -7, -3, 1, 2,
+ 2, -1, -3, -2, -1, 0, 1, 0, -1, 0, 5, 11, 9, 3, -1, -3,
+ -1, -2, -2, -1, 1, 1, 1, 1, 0, -1, 0, 3, 6, 6, 5, 5,
+ 2, 1, -1, -1, -2, -5, -6, -4, 2, 2, 2, 1, -1, -4, -5, -5,
+ -1, -3, -6, -7, -6, -4, -1, 1, 5, 5, 3, 4, 4, 3, 4, 5,
+ -1, -2, -3, -2, -2, -2, 0, 1, 0, 0, 0, 0, 0, 1, 2, 3,
+ -6, -6, -4, -1, 2, 2, 2, 2, -6, -7, -5, -2, 0, -1, -1, 0,
+ 2, 2, 2, 4, 4, 3, 3, 4, 2, 1, 0, -1, 0, 0, 2, 4,
+ 12, 5, -5, -8, -5, 0, 2, 2, 2, -3, -6, -3, 0, 0, -1, -2,
+ -2, -3, -1, 3, 4, 1, -2, -3, 2, 2, 3, 4, 3, 1, -1, -1,
+ 3, 2, 1, 0, 1, 4, 3, 0, 4, 3, 0, -5, -6, 0, 3, 3,
+ 2, 3, 1, -7,-12, -6, 1, 3, 1, 3, 4, -1, -6, -4, 0, 1,
+ -9, -4, 2, 6, 7, 4, 1, 0, -7, -1, 4, 6, 4, 0, -3, -3,
+ -6, 0, 4, 4, 1, -2, -3, -2, -4, 1, 3, 2, 0, -2, -1, 0,
+ 0, 5, 2, -5, -3, 3, 1, -4, -2, 4, 2, -6, -3, 6, 4, -3,
+ -1, 5, 3, -5, -1, 7, 3, -4, -1, 2, 0, -6, -3, 5, 3, -3,
+ -8, -3, 3, 5, 3, 1, -2, -2, 2, 4, 4, -2, -4, -3, 1, 3,
+ 2, 1, -3, -5, -3, 3, 4, 3, -5, -6, -5, 3, 10, 8, -1, -5,
+ 0, 3, 2, -4, -9, -7, 0, 6, -5, -1, 5, 7, 4, -1, -3, -3,
+ -5, -5, -2, 3, 6, 5, -1, -4, 9, 6, 0, -4, -2, 1, 1, -1,
+ -1, -1, -1, 1, 1, 0, -1, 0, -1, 0, 0, 0, 0, -1, -1, 0,
+ 2, 1, -2, -1, 1, 1, 0, 0, 12, 8, 2, -1, -1, -4, -7, -7,
+ 2, 1, 3, 6, 7, 4, 2, 0, 1, 0, -1, 0, -1, -4, -7, -8,
+ 0, 0, -1, 0, 0, 0, -1, -3, 0, 0, 0, 0, 1, 1, 0, -2,
+ -1, 0, 1, 1, 0, 0, -1, -2, 0, 0, -1, -3, -4, -3, -1, 1,
+ -1, 0, 0, 0, 1, 4, 10, 12, -1, 0, -2, -2, -3, -3, -1, 1,
+ -3, -1, -2, -4, 2, 9, 9, 7, -3, 0, -1, -3, 0, 2, -1, 1,
+ -1, 1, -2, -3, 0, -1, -3, 0, 0, 0, -3, -2, 0, -1, -1, 1,
+ -1, -2, -1, -1, -2, -1, -1, -2, 2, -1, -2, -1, 0, 1, 0, -2,
+ 3, -1, -2, 2, 5, 3, -1, -3, 1, -5, -5, 1, 6, 6, 2, 0,
+ 1, 2, 0, -1, 0, 1, 0, -2, -5, -3, -1, 0, 1, 2, 1, -2,
+ -7, -5, -2, -2, -2, -2, 0, 1, -1, 0, 1, 1, 0, 3, 9, 12,
+ 0, 6, 5, 1, -2, -3, 0, 3, 0, 6, 5, 1, 1, 1, 2, 3,
+ -5, -2, -2, -3, 0, 0, 0, 0, -6, -3, -3, -2, 0, 0, -1, -2,
+ 4, 4, 2, 1, 0, -1, -1, 0, -2, -2, 0, 1, 2, 1, 1, 0,
+ 2, 2, 1, -1, -3, -5, -9,-10, 2, 1, -1, -1, 1, 4, 4, 1,
+ 4, 0, -2, -2, -2, -2, -1, 0, 7, 1, -4, -3, -2, 0, 1, 1,
+ 10, 5, -1, -2, 0, 1, 1, 0, 5, 1, -3, -4, -3, -1, -1, -2,
+ 2, 1, -1, -3, -3, 1, 1, -1, -2, -1, 3, 0, -1, 1, 1, 0,
+ -3, 1, 7, 2, -3, -2, -1, 0, -2, 4, 8, -1, -8, -5, 0, 2,
+ -4, -1, 1, 2, 1, -3, -4, -2, -5, -3, -2, 1, 4, 4, 4, 6,
+ -3, -2, -4, -3, 0, 1, 1, 2, 2, 2, 2, 1, 2, 1, -1, -1,
+ -4, -1, 0, -1, -3, -3, -1, -1, 1, 4, 4, 2, 0, -1, -2, -3,
+ 4, 6, 5, 3, 2, 1, -2, -4, 0, 1, 1, 1, 1, -1, -4, -6,
+ 1, 2, 2, -1, -6, -5, -1, 2, -3, -2, 1, 1, -4, -3, 2, 5,
+ -2, -1, 2, 2, -3, -4, 0, 3, -2, -2, 2, 6, 5, 2, 1, 2,
+ 2, -3, -3, 0, 0, 2, 3, 1, 3, -1, 1, 3, 1, 2, -1, -5,
+ -5, -7, -4, -2, 1, 8, 8, 1, -1, 0, 2, 0, -3, 0, 1, -3,
+ -2, -5, -5, -2, -3, -1, 0, -2, -1, -4, 0, 4, 0, 2, 4, 0,
+ 0, 0, 8, 10, 2, 1, 3, -1, -4, -3, 2, 3, -3, -3, 1, -1,
+ 1, -2, -4, 2, 7, 3, -2, -1, 6, 4, -2, -1, 2, 0, -1, 3,
+ 1, 1, -2, -2, -2, -5, -3, 4, -6, -2, 1, 1, -1, -4, -2, 4,
+ -2, -1, -2, -2, 0, 1, 0, -2, -1, 1, 0, -1, 0, 0, -1, -3,
+ 0, 1, -2, -4, -3, -1, 0, 0, 6, 8, 5, 0, 0, 1, 2, 3,
+ -2, -2, 2, 5, 2, 0, 0, 1, 2, -2, -2, -1, -1, 1, 2, 4,
+ 2, -1, 0, 1, 0, 0, 0, 1, -8, -7, -1, 1, -1, -1, 1, 3,
+ 0, 3, 6, 2, -2, 1, 2, 0,-10, -7, -1, 0, -3, -1, 2, 1,
+ 0, 0, 2, 2, 1, 1, 1, -1, 3, 0, -2, -2, 0, 2, 1, 0,
+ 8, 1, 0, 0, -2, -3, -1, 0, 2, -2, 2, 5, 1, -2, -1, 1,
+ -3, -6, -3, -1, -3, -3, -1, 2, 2, 0, 1, 2, 2, 1, 0, 0,
+ 1, -1, -1, -2, -1, 0, 1, 0, 15, 9, 2, -1, -2, -3, -3, -3,
+ 0, -3, -2, 0, 0, -1, -1, -1, 1, 0, 1, 0, 0, -1, -1, -1,
+ 0, 2, 2, -2, -3, -3, -7, -8, 0, 2, 2, 0, 1, 2, 1, 1,
+ 1, 2, 2, 2, 3, 1, 0, 3, 1, 0, -1, -2, -1, -2, 0, 5,
+ -11, -6, -1, 1, 2, 3, 1, -3, 1, 4, 3, -1, -2, 1, 2, -1,
+ 2, 2, 1, -1, -2, 0, 1, -1, 0, 0, -1, -1, 0, 2, 3, 2,
+ 1, 1, 2, 1, -1, 1, 0, -4, 0, 0, 0, -2, -2, 2, 4, -2,
+ -2, -3, 0, 0, -1, 2, 1, -6, 0, 2, 5, 5, 3, 2, -1, -7,
+ 4, 2, 0, 0, 3, 3, 1, -1, 0, -1, -1, 3, 6, 4, 1, -1,
+ -2, -2, 0, 2, 2, 0, -2, -2, -1, 0, -1, -5, -7, -5, -1, 1,
+ 5, -1, -2, 0, 2, 4, 2, -5, 0, -5, -2, 2, 1, 2, 0, -6,
+ 6, 1, 0, 1, -2, -1, 4, 2, 2, -3, -3, 0, -1, -2, 0, 0,
+ 1, -1, 0, 2, 0, 0, 6, 11, 2, -1, -1, 0, -3, -2, 3, 5,
+ 0, -2, -1, 0, -1, 0, 0, -3, 1, -1, -1, -1, -2, -1, -3, -7,
+ 1, 1, -2, -2, 1, 3, 1, -2, -1, 2, 0, -1, -1, 1, 0, 0,
+ -4, 2, 3, -1, -2, -2, 0, 1,-11, -2, 4, 5, 6, 2, -1, -2,
+ -6, -2, 1, -1, -3, -4, 1, 9, -3, 0, 3, 3, 2, -3, -3, 3,
+ 1, 1, 0, 0, 1, -1, -2, 3, 2, 0, -3, -3, 0, -1, -1, 3,
+ 1, -1, -3, 1, 2, -6, -4, 6, 0, -2, -5, -2, 0, -3, -2, 3,
+ 2, 2, 1, -2, -2, 1, 2, -1, -1, 1, 1, -2, -1, 6, 7, -1,
+ 1, 0, -4, -2, 1, -2, -3, 1, -4, 0, -3, -2, 2, 0, -3, 0,
+ -3, 4, 3, 1, 8, 7, 0, -1, -3, 4, 1, -4, 2, 3, -2, -3,
+ -3, 6, 1, -4, 1, 1, -1, -1, -2, 4, -3, -3, 3, 0, -1, -1,
+ 1, 2, -4, 2, 4, -3, -1, 2, 3, -1, -4, 5, 4, -6, -3, 2
};
-static const uint32 s_svq1InterCodebook8x8[1536] = {
- 0x0504fdfc, 0x00010102, 0x0505fdfb, 0x00000102,
- 0x0505fcfa, 0x00000102, 0x0504fcf9, 0x00000102,
- 0x0403fbf8, 0x00000102, 0x0403faf8, 0x00010101,
- 0x0402faf8, 0x00010102, 0x0402faf8, 0x01010101,
- 0xffffffff, 0xffffffff, 0xfefefeff, 0xfefefefe,
- 0xfdfdfdfe, 0xfdfdfdfd, 0xfdfdfdfe, 0xfdfcfdfd,
- 0xfefefefe, 0xfefdfdfe, 0x01010101, 0xffff0001,
- 0x05050504, 0x02030304, 0x08080707, 0x05060708,
- 0x04020102, 0xfafc0004, 0x05020101, 0xf9fb0105,
- 0x04010201, 0xf8fb0105, 0x05010101, 0xf8fa0005,
- 0x05010100, 0xf7fa0106, 0x04010000, 0xf8fb0005,
- 0x04010000, 0xf9fb0005, 0x04010000, 0xf9fc0104,
- 0x00030201, 0xfffdfcfd, 0x00040301, 0xfffdfcfd,
- 0x01050402, 0xfefdfcfd, 0x01060502, 0xfefcfbfd,
- 0x01060603, 0xfefcfbfd, 0x01060603, 0xfefcfbfd,
- 0x01060603, 0xfefcfbfd, 0x01050503, 0xfefcfcfd,
- 0x02020202, 0xff000001, 0x03040404, 0x00010102,
- 0x04040504, 0x01020303, 0x04040404, 0x02020304,
- 0x03030302, 0x01020303, 0xffffffff, 0x00000000,
- 0xfbfafafb, 0xfdfdfcfb, 0xf8f7f7f9, 0xfbfafaf9,
- 0x06060606, 0x04050506, 0x03040404, 0x02030303,
- 0xffffff00, 0xfffffefe, 0xfafafbfd, 0xfcfbfafa,
- 0xf9fafbfd, 0xfcfbfafa, 0xfefefeff, 0xfffffefe,
- 0x01010100, 0x01010101, 0x03030303, 0x03030303,
- 0xfbfe0102, 0x050200fc, 0xfafe0102, 0x050300fb,
- 0xfafe0102, 0x0603fffa, 0xf9fe0203, 0x070400fa,
- 0xf9fe0102, 0x070500fb, 0xfafe0102, 0x070400fb,
- 0xfafe0102, 0x060400fc, 0xfbfe0101, 0x060300fc,
- 0xfcfaf7f6, 0x020302ff, 0xfdfbf7f6, 0x03040400,
- 0xfffdf9f7, 0x03050502, 0x00fefbf9, 0x03050503,
- 0x0100fdfa, 0x03050604, 0x0201fefc, 0x02040503,
- 0x020100fe, 0x01030402, 0x020201ff, 0x01030302,
- 0xfafbfbfc, 0xfbfafafa, 0xfcfcfdfd, 0xfcfcfcfc,
- 0x00000000, 0xffffffff, 0x05060505, 0x02030405,
- 0x07070605, 0x04050607, 0x04040303, 0x02030404,
- 0x0000ff00, 0xff00ffff, 0xfcfcfdfd, 0xfdfdfcfc,
- 0x01fbfe01, 0x00020405, 0x01fafd01, 0x00020506,
- 0x00f9fc00, 0x01020606, 0xfff7fbff, 0x01030606,
- 0xfef6faff, 0x01030606, 0xfef7faff, 0x01030605,
- 0xfef7fafe, 0x01030505, 0xfef9fafe, 0x01020404,
- 0xf7f8f9fb, 0xfaf9f8f7, 0xf9fafafb, 0xfbfafaf9,
- 0xfcfdfdfd, 0xfcfcfbfb, 0xff0000ff, 0xffffffff,
- 0x02020100, 0x01020202, 0x05040302, 0x04050505,
- 0x06050403, 0x07080808, 0x06050403, 0x06070707,
- 0x08070605, 0x090a0a09, 0x07060403, 0x08090908,
- 0x03020100, 0x05050504, 0xfffffeff, 0x02020100,
- 0xfdfdfdfe, 0x00fffefd, 0xfbfbfcfd, 0xfcfbfbfb,
- 0xfafbfbfc, 0xfbfaf9f9, 0xfafbfcfd, 0xfafaf9f9,
- 0xfd00070d, 0xfbfcfcfd, 0xfd00070e, 0xfcfcfcfd,
- 0xfcff080f, 0xfcfbfcfc, 0xfcff080f, 0xfdfcfbfc,
- 0xfcff070f, 0xfcfbfbfb, 0xfcff070e, 0xfdfcfcfc,
- 0xfcff060c, 0xfdfcfcfc, 0xfcff050b, 0xfdfcfcfc,
- 0x0405fcef, 0x03030404, 0x0405fbee, 0x03030404,
- 0x0406fbed, 0x02030404, 0x0406fbec, 0x03030404,
- 0x0406fcec, 0x03030504, 0x0406fbed, 0x03030504,
- 0x0405fcee, 0x02030404, 0x0304fbef, 0x03030404,
- 0xfcfafafa, 0x0b0601fe, 0xfcf9f9fa, 0x0d0802fe,
- 0xfcf9f8f8, 0x0e0903fe, 0xfbf9f8f8, 0x100a04ff,
- 0xfbf9f8f8, 0x110a04ff, 0xfcf9f8f8, 0x100a0500,
- 0xfdfaf8f8, 0x0f090400, 0xfdfbf9f9, 0x0c080400,
- 0x05070708, 0xf2f8fe02, 0x05070808, 0xf1f8fe02,
- 0x05070808, 0xf0f7fd01, 0x05070808, 0xeff6fd01,
- 0x05080908, 0xeff6fd01, 0x04070808, 0xf0f6fc01,
- 0x04070707, 0xf2f7fd01, 0x03060706, 0xf3f7fd00,
- 0xfcfc0105, 0x0000fffd, 0xfdfd0207, 0x0001fffe,
- 0xfdfd0107, 0x010100ff, 0xfefd0106, 0x000101ff,
- 0xfefc0006, 0x000100ff, 0xfdfc0005, 0xff0000ff,
- 0xfffd0005, 0xfe000000, 0xfffe0104, 0xff000100,
- 0x01010202, 0xf8f8fafe, 0x01010101, 0xf8f8fbfe,
- 0x00010101, 0xfbfbfdff, 0x00000000, 0xfeffffff,
- 0x0000ff00, 0x00010000, 0x00000001, 0x02030201,
- 0x01010102, 0x03040302, 0x03030303, 0x04050404,
- 0xfefdfcfc, 0x01010000, 0xfefdfcfc, 0x010000ff,
- 0xfffefefe, 0x0000ffff, 0x00000100, 0xff000000,
- 0x02020202, 0x01010202, 0x04040403, 0x03040404,
- 0x03010101, 0x03030403, 0xfcfbfafb, 0xfefefdfd,
- 0xfffffefc, 0x0100ffff, 0xfffffefc, 0x0100ffff,
- 0xfffffefd, 0x020100ff, 0xfffefdfc, 0x030301ff,
- 0xfffdfdfc, 0x050401ff, 0xfefefdfc, 0x070401ff,
- 0xfffffefe, 0x08060200, 0x010000ff, 0x08070401,
- 0xfefdfdfd, 0x00fffffe, 0x0100ffff, 0x03030202,
- 0x04020100, 0x05060605, 0x030200ff, 0x03050605,
- 0x0200ffff, 0x01020303, 0x00fffefe, 0xfcfcfdff,
- 0xffff0000, 0xf9f8fcfe, 0x00010201, 0xf9fafcff,
- 0xfa0104fe, 0x00000300, 0xf90105fe, 0x00000300,
- 0xf80105fd, 0xffff0300, 0xf70106fe, 0xff000300,
- 0xf80206fe, 0xff000400, 0xf90105fd, 0x00000401,
- 0xf90104fe, 0x00010400, 0xfa0104ff, 0x00010300,
- 0x03000000, 0x01040504, 0x02010101, 0x00020303,
- 0x02010202, 0xfeff0102, 0x01010304, 0xfbfdff00,
- 0xff010305, 0xfafcfdfe, 0xfe000305, 0xf9fafbfd,
- 0xfe000304, 0xfbfbfcfd, 0xff000304, 0xfdfdfefe,
- 0x00000000, 0x06fefbff, 0x01000000, 0x08fefaff,
- 0x02000000, 0x09fdfa00, 0x0200ff00, 0x0afef900,
- 0x0200ff00, 0x0afdf8ff, 0x02ffff00, 0x09fdf9ff,
- 0x0100ff00, 0x08fdfaff, 0x01000000, 0x07fefb00,
- 0x02030302, 0xffff0001, 0x02030403, 0xfeff0001,
- 0x02040403, 0xfdfeff01, 0x02030302, 0xfdfeff00,
- 0x010100ff, 0xfefeff00, 0xfffdfcfb, 0x01010100,
- 0xfffbf8f8, 0x03040301, 0x00fbf7f6, 0x05060503,
- 0x0504fffb, 0x00000103, 0x0504fffa, 0xfeff0002,
- 0x0405fffa, 0xfefeff02, 0x0404fff9, 0xfdfdfe01,
- 0x0405fffa, 0xfdfdfe01, 0x040400fb, 0xfefeff01,
- 0x040500fc, 0xfeffff01, 0x030401fd, 0xfeffff01,
- 0x01fefdfe, 0x03050604, 0x00fcfcfd, 0x02040503,
- 0xfffbfbfd, 0x01030402, 0xfffcfafc, 0xff020402,
- 0x01fdfcfe, 0xff020402, 0x01fefcfe, 0xfe010303,
- 0x01fefdfe, 0xfe010303, 0x01fffefe, 0xfe000303,
- 0xfefdfcfc, 0x070502ff, 0xfdfdfcfc, 0x070501fe,
- 0xfdfefdfe, 0x0503fffd, 0xfe00ffff, 0x0402fefd,
- 0xff010101, 0x0301fdfc, 0xff020304, 0x01fffdfc,
- 0x00030406, 0x00fefdfd, 0x01030506, 0xfffefdfe,
- 0x04080b0c, 0xfffefe00, 0x0206090a, 0x00fffeff,
- 0x00020304, 0x0100ffff, 0xffffffff, 0x020100fe,
- 0xfefcfbfd, 0x030200fe, 0xfefcfbfb, 0x020100ff,
- 0xfefcfbfb, 0x010100ff, 0xfefdfcfc, 0x0000fffe,
- 0xff020303, 0xfefdfcfd, 0xfe000203, 0xfefdfcfc,
- 0xff010202, 0xfdfcfbfd, 0x01030303, 0xfdfdfdfe,
- 0x03040404, 0xfefefe00, 0x03050505, 0xfefeff00,
- 0x02040505, 0xfefdfeff, 0x00030303, 0xfcfcfcfe,
- 0xfe04ffff, 0xfb0206fe, 0xfe0400ff, 0xfa0206fd,
- 0xfe0400ff, 0xf90307fd, 0xfd04ffff, 0xf90308fc,
- 0xfd04ff00, 0xfa0307fc, 0xfd04ffff, 0xfa0307fc,
- 0xfd03ffff, 0xfa0306fc, 0xfe0300ff, 0xfb0306fd,
- 0x02f9fe01, 0x01fffe05, 0x03f8fe01, 0x02fffd06,
- 0x04f7fe02, 0x02fefc07, 0x05f7ff03, 0x03fffc07,
- 0x04f7ff03, 0x02fefc07, 0x04f9ff03, 0x01fefc06,
- 0x04fa0002, 0x01fffc06, 0x03fb0002, 0x01fffd04,
- 0x000202fe, 0xfcfdff00, 0x010202fe, 0xfcfe0001,
- 0x020202fe, 0xfeff0102, 0x030302fd, 0xfe000204,
- 0x020302fd, 0xfd000204, 0x010201fc, 0xfdff0102,
- 0x000100fb, 0xfdfe0101, 0x000000fc, 0xfdfe0001,
- 0xfeff0000, 0x080702fe, 0xfdff0000, 0x070601fe,
- 0xfdff0100, 0x050400fd, 0xff000100, 0x030100ff,
- 0x01010200, 0x0100ff00, 0x020100fe, 0xffff0001,
- 0x0100fefb, 0xfdfd0001, 0x01fffcfa, 0xfcfdff01,
- 0x0502fefc, 0x02030406, 0x0401fdfb, 0x00000204,
- 0x0200fefc, 0xfefeff01, 0x0100fffe, 0xfefdfe00,
- 0x000000fe, 0xfffeffff, 0x00fffffe, 0x02010000,
- 0xfffffefe, 0x04030100, 0xfffefdfe, 0x05040200,
- 0xfefe0102, 0x000100ff, 0xfdfd0001, 0x000100ff,
- 0xfdfdff00, 0x010101ff, 0xfffd0000, 0x03030201,
- 0xfffdff00, 0x03030301, 0xfefcfefe, 0x04040301,
- 0xfefcfdfd, 0x04030301, 0xfefbfdfe, 0x03030201,
- 0x04030504, 0x05040404, 0x00010303, 0x01000000,
- 0xfeff0101, 0xfefdfcfd, 0xfe000202, 0xfefdfcfe,
- 0xff010302, 0xfefdfdff, 0x00000201, 0xfffefeff,
- 0xff000100, 0xfffefdff, 0xff000101, 0xfefefeff,
- 0x00fffffe, 0x00010201, 0x05030201, 0x03050506,
- 0x04030201, 0x03040505, 0xfdfdfefe, 0x0000fffe,
- 0xfbfcfdfd, 0xfffefdfc, 0xfefeffff, 0x0000fffe,
- 0xff000100, 0x010000ff, 0xfeff00ff, 0xfffefefd,
- 0x05060707, 0xfeff0204, 0x02020303, 0xfdfe0001,
- 0xffffff00, 0xfefeff00, 0xfffefdff, 0x01000000,
- 0xfffefe00, 0x020201ff, 0xffff0103, 0x020201ff,
- 0xfdfe0103, 0x0201fffe, 0xfafbfe01, 0x00fefdfb,
- 0xfdfeff00, 0xfefe00ff, 0xffff0000, 0xfeff0100,
- 0xfffe0000, 0xfe000000, 0xfdfdfeff, 0xfdfdfffe,
- 0xfdfdfeff, 0xfcfdfefe, 0x00000202, 0xfeff0000,
- 0x02030505, 0xff000202, 0x05060808, 0x01020404,
- 0xfdfaf8f9, 0xfffeffff, 0x00fdfbfb, 0x00000102,
- 0x0300ffff, 0x01010304, 0x03010102, 0x02020304,
- 0x02000203, 0x02010203, 0xffff0204, 0x01010100,
- 0xfdfe0203, 0x0100fffe, 0xfcfd0103, 0x0100fefd,
- 0x02fffefc, 0x00010303, 0xfefcfbf9, 0xfeff0000,
- 0xfcfbfbfa, 0xfdfefefe, 0xffff00ff, 0xff000000,
- 0x02020302, 0x00010202, 0x03040503, 0x00010001,
- 0x02030403, 0xffffff00, 0x01030505, 0xffffff00,
- 0xff000101, 0xfcfafbfd, 0x00000101, 0xfffdfd00,
- 0x00ffff00, 0x03010001, 0xfffdfefe, 0x07040202,
- 0x00fefefe, 0x06030202, 0x010000ff, 0x03000001,
- 0x03030300, 0xfffdfe01, 0x03040301, 0xfcfbfd00,
- 0xff000200, 0xfefefcfd, 0x00020401, 0xfffefdfe,
- 0x01030603, 0xff00fefe, 0x01040704, 0x00fffdfe,
- 0x00030603, 0x00fffdfd, 0xff000301, 0x0101fefd,
- 0xfeff0100, 0x0202fffd, 0xfdfdfffe, 0x0201fffd,
- 0x00ff0103, 0x00000001, 0xfffeff02, 0xffff0001,
- 0x00feff01, 0xfdfe0001, 0x01fffe00, 0xfbfd0103,
- 0x02fffe00, 0xfbfd0205, 0x04fffe00, 0xfbfe0306,
- 0x0400fe00, 0xfcfe0407, 0x0400fe00, 0xfcfe0406,
- 0xfcfdfefe, 0x00fffefd, 0xff000101, 0x0100ffff,
- 0x02020303, 0x01010101, 0x02020202, 0x01000001,
- 0x00000000, 0xffffffff, 0xfcfcfcfc, 0xfdfcfcfc,
- 0xfdfefdfd, 0x00fffffe, 0x05040403, 0x07060605,
- 0xfe07feff, 0x00fffffc, 0xff09feff, 0x00fffffc,
- 0xff0afdff, 0x01fffffc, 0xfe0afdff, 0x02fffffd,
- 0xfe0afeff, 0x02fffffc, 0xfe09feff, 0x02fffffc,
- 0xfe08feff, 0x01ff00fc, 0xfe07fe00, 0x0200fffd,
- 0x0301fc03, 0x0001fefd, 0x0401fb03, 0x0001fefd,
- 0x0502fa03, 0x0003fffd, 0x0502fa03, 0x0002fffd,
- 0x0501fa03, 0x0003fefc, 0x0501fa03, 0x0002fefd,
- 0x0401fa02, 0x0001fffd, 0x0401fa02, 0x0001fffe,
- 0x01010000, 0x02000001, 0x0101ff00, 0x02000001,
- 0x0000ff00, 0x02000000, 0x0000ff00, 0x00ff0000,
- 0x00010001, 0xfffeff00, 0x00010103, 0xfdfcfe00,
- 0x01020305, 0xfcfbfd00, 0x00020405, 0xfbfbfcff,
- 0xfeff0001, 0xf7fafdfe, 0xffff0002, 0xfafd0000,
- 0xff000001, 0xfbfe0000, 0x01010102, 0xfdff0201,
- 0x01020101, 0xff010202, 0x01020101, 0x01010101,
- 0x01020000, 0x02020000, 0x02020100, 0x02020000,
- 0x0100fdfc, 0x03040604, 0x0000fefd, 0x00010402,
- 0x0000ffff, 0xfdfe0101, 0x00010101, 0xfbfd0101,
- 0x00010101, 0xfbfd0101, 0xff0000ff, 0xfcfe0101,
- 0xff0000ff, 0xfe000201, 0x000000ff, 0x00010302,
- 0x040300ff, 0xfbfbfc00, 0x05040000, 0xfefdfe02,
- 0x0402ff00, 0x00ffff02, 0x01fffe00, 0x0100fe00,
- 0x00fefe01, 0x01ffff00, 0x00fdfe01, 0x00ff0001,
- 0x01fefe01, 0x00000103, 0x02fffe01, 0x00000204,
- 0x02030201, 0x01020200, 0x000100ff, 0x010101fd,
- 0xfe0000ff, 0x010200fc, 0xff0202ff, 0x010200fb,
- 0xff0403ff, 0x010200fb, 0x000402fe, 0x0000fffc,
- 0x000200fc, 0x0000fefc, 0x0102fffb, 0x020301fe,
- 0x00010001, 0xfeff0201, 0xfeff0002, 0xff000301,
- 0xfcfe0003, 0x00010300, 0xfbfd0105, 0x010102fe,
- 0xfbfe0106, 0x010001fe, 0xfbff0105, 0x00ff00fe,
- 0xfcfe0003, 0x00ff00fe, 0xfe00ff01, 0x01000100,
- 0x03020101, 0x02010102, 0x0100ffff, 0x01010001,
- 0x0000fdfc, 0x02010101, 0x0200fdfc, 0x02030202,
- 0x0100fcfb, 0x02010101, 0xfffffcfb, 0x00fffefe,
- 0x0000fefd, 0xfffefdfe, 0x04040302, 0x00000002,
- 0x0100fefc, 0x00000000, 0x0101fffd, 0x00000000,
- 0x020200fe, 0x02000000, 0x010201ff, 0x050300ff,
- 0xff010200, 0x060500fe, 0xfd000100, 0x060400fd,
- 0xfcfe0101, 0x0201fdfc, 0xfcfe0001, 0x00fefcfb,
- 0xfdfdfdff, 0xfffffefd, 0x00010203, 0x01010100,
- 0x02030405, 0x02020101, 0xfe000102, 0xfffffefe,
- 0xff000000, 0xfefefefe, 0x03030100, 0xffff0102,
- 0x04030100, 0xff010203, 0x01fffdfc, 0xfdfdfe00,
- 0xf8f9fcfd, 0x02fffcf9, 0xfcfdff00, 0x0200fefc,
- 0xff000001, 0x0200fefd, 0x00010102, 0x0200ffff,
- 0x01010101, 0x01000000, 0x01010101, 0x01010101,
- 0x02010000, 0x02020303, 0x03010000, 0x02030404,
- 0x00030303, 0x020100ff, 0xff010101, 0x01fffffe,
- 0xfdfffefe, 0x00fefefd, 0xfefefcfc, 0x00fdfefe,
- 0x01fffcfc, 0x02ff0001, 0x0302fffd, 0x05030304,
- 0x030200fe, 0x03030303, 0x0000fefe, 0x01000000,
- 0xff010200, 0xfe03fffd, 0xffff00ff, 0xfe0400fd,
- 0xfefefefe, 0xfe0501fe, 0xfffdfefd, 0xfd0401fe,
- 0x00ff00fe, 0xfb0300ff, 0x02010201, 0xfb020000,
- 0x03020402, 0xfd030101, 0x01010201, 0xfe040100,
- 0xfffcfd04, 0x03010303, 0xfffcfc04, 0x02000203,
- 0x00fcfd04, 0x01ff0202, 0x01fefd04, 0x00fe0102,
- 0x01fefc02, 0x00fd0002, 0x00fefd02, 0x02fe0001,
- 0x00ffff03, 0x03000000, 0xfefefe02, 0x02ffffff,
- 0x04030202, 0xff000103, 0x02010001, 0xfefeff01,
- 0x01020102, 0xffff0001, 0x03040304, 0x01010102,
- 0x02020203, 0x01010101, 0x00fffeff, 0xffffffff,
- 0xfffefdfd, 0xfefefefe, 0xfdfdfcfc, 0xfdfdfcfc,
- 0xfdff0102, 0x0403fefc, 0xff010202, 0x0201fefd,
- 0x03030201, 0xfefffe00, 0x040200ff, 0xfdff0002,
- 0x0300fefe, 0xfd000203, 0xfffdfe00, 0xff020201,
- 0xfbfcff03, 0x000200fd, 0xfafe0306, 0x010300fb,
- 0x00fe03fe, 0x01fefe03, 0x00fd04fd, 0x02fffe03,
- 0x00fd05fd, 0x02fffe04, 0xfffc04fe, 0x02fefd03,
- 0x00fd04fd, 0x02fffd03, 0x00fe05fe, 0x02fffd03,
- 0x01fd04fe, 0x02fffe03, 0x01fe03fe, 0x0200fe03,
- 0xff000001, 0xfffc0201, 0xff000002, 0xfefc0201,
- 0xff010101, 0x00fe0402, 0xff01ff00, 0x01ff0502,
- 0xfe00ff00, 0x01ff0501, 0xfeffff00, 0xfffd0300,
- 0xfe000101, 0xfffd0300, 0xfd000101, 0x00fe0300,
- 0x01ff0001, 0x05040201, 0x01ff0001, 0x07050101,
- 0xfffe0000, 0x050300ff, 0xfffeff00, 0x0302ffff,
- 0xfffdff00, 0x0201ffff, 0xfefcfeff, 0x0000fefe,
- 0xfffefeff, 0x0000fefe, 0x00ffff00, 0x0000ffff,
- 0xff000303, 0x040401ff, 0xfe000302, 0x010100fe,
- 0xff010302, 0x000100ff, 0xff000201, 0xfe00ffff,
- 0xff000100, 0xfe00fffe, 0xff000100, 0x0001fffe,
- 0xfdff0101, 0x0301fdfc, 0xfdff0201, 0x0301fcfb,
- 0x0100fefd, 0xfe000101, 0x01010100, 0xfdff0000,
- 0x01010201, 0xfeffff00, 0xfffdff00, 0xff00ffff,
- 0xfdfafd00, 0x0101fffe, 0xfdfcff02, 0x020200fe,
- 0x01010405, 0x02030100, 0x01020405, 0x0100ff00,
- 0xfbfe00fe, 0x0000fdfa, 0x000100fe, 0x020201ff,
- 0x030100fe, 0x01020202, 0x040200fe, 0x01010203,
- 0x030200fe, 0x00ff0002, 0x0101fffd, 0x01ffff00,
- 0x0001fffc, 0x0200feff, 0xff00fffc, 0x0401feff,
- 0xff0000fd, 0x00010101, 0xff0001fd, 0xffff0000,
- 0x000303ff, 0x01000001, 0xfe0202fd, 0x010000ff,
- 0xfe0000fb, 0x020001ff, 0x0001fef9, 0x02020201,
- 0x020300fb, 0x02020303, 0x010402fd, 0xfdfe0000,
- 0xfefe0205, 0xffffff00, 0xfdfcff02, 0xfffffeff,
- 0x01fefe00, 0x0100ff02, 0x03fffeff, 0x0200ff03,
- 0x03000001, 0x02fffe03, 0x03010102, 0x00fefe02,
- 0x01ff0001, 0xfefdfd01, 0x02010001, 0x00000003,
- 0x00fdfbfc, 0xfffeff01, 0x01fffdfe, 0x00000002,
- 0x01020101, 0x01010102, 0x01030403, 0xfffffe00,
- 0x00020303, 0xfefdfdfe, 0xff000101, 0xfefefcfe,
- 0x00000102, 0x0100ff00, 0x01010102, 0x03010101,
- 0xff000000, 0x0001fffe, 0xfefffffe, 0x0000fefd,
- 0xff0000ff, 0x010100fe, 0xff000101, 0x010301ff,
- 0xfe000202, 0x000302ff, 0xffff0103, 0xfe020401,
- 0xfffd0002, 0xfb000503, 0x00feff01, 0xfaff0303,
- 0x040300ff, 0x02010002, 0x0100fffe, 0x0100feff,
- 0xfdfefdfe, 0xfdfaf9fa, 0x01030202, 0xfefdfeff,
- 0x01030202, 0x00000000, 0x00010102, 0x01000101,
- 0x00000001, 0x02010100, 0x00ff0001, 0x01020200,
- 0x01030101, 0x01ffffff, 0x0000fffe, 0x02fffefe,
- 0x0101fefe, 0x03010001, 0xff00fefe, 0x0200ff00,
- 0x00010000, 0x01feffff, 0x01020203, 0x01fefe00,
- 0x02030305, 0x04010101, 0xfbfcfd00, 0x01fffdfc,
- 0x02fffcfa, 0xff000002, 0x0301fefc, 0x00020203,
- 0x02fffefd, 0x00020303, 0x01fefefd, 0xff010102,
- 0x00fefefe, 0xff010202, 0x01ffffff, 0x00020302,
- 0x01feffff, 0xff020202, 0x00feff00, 0xff000102,
- 0x01020406, 0x01000000, 0xfeff0204, 0xfffffefe,
- 0xfeff0102, 0xfffefefe, 0xfe000202, 0x00fffefe,
- 0xfeff0000, 0x0100fffe, 0xfffefdfd, 0x00fffeff,
- 0x0302fefd, 0xfeff0002, 0x050400fe, 0xff000205,
- 0x00020405, 0xfffffeff, 0x01020304, 0xff00ff00,
- 0x01000101, 0xff010001, 0x00fffffe, 0xfdfefe00,
- 0x000000ff, 0xfbfdfdff, 0xff010100, 0xfdfefeff,
- 0xfeffffff, 0x010301ff, 0xfffefeff, 0x05060502,
- 0x01fefdfd, 0xfffffe01, 0x04030201, 0xfdfffd01,
- 0x01000203, 0xfdfffdff, 0x00ff0001, 0x0001ffff,
- 0x01000101, 0x03050202, 0x02010101, 0x00030202,
- 0xfefefffd, 0xfdfffdfd, 0x000101ff, 0xfe00ffff,
- 0xfefe0002, 0xfe010402, 0xfffe0001, 0xff020503,
- 0xfefdfeff, 0xfe010301, 0xfffffeff, 0xff010200,
- 0x01010000, 0x00020201, 0x04040100, 0x01030202,
- 0x0102fffe, 0xfdfefdfe, 0x000100ff, 0xfbfcfcfd,
- 0xfcfd0004, 0xfffefcfc, 0x00ff0005, 0xfffefdff,
- 0x01000004, 0x00000001, 0xfffefd00, 0x00010000,
- 0x0000fe00, 0x01020101, 0x00000002, 0x00010101,
- 0xffff0002, 0x00010101, 0xfefeff01, 0x02020200,
- 0x00fefbfd, 0x00fdfdff, 0x0200fe00, 0x03000002,
- 0x00feff02, 0x02ffff00, 0xffff0205, 0x02ffffff,
- 0xff000205, 0x02ff00ff, 0x00000102, 0x02000100,
- 0x0101ffff, 0x02010202, 0x0000fefd, 0xfffe0000,
- 0x00020300, 0xfdfdfdfe, 0x01030300, 0x02010000,
- 0xfeff00ff, 0x0301ffff, 0xfeff00ff, 0x0200ffff,
- 0xfeff00ff, 0x02ff0000, 0xfeff00ff, 0x01feffff,
- 0xfd000100, 0x02ffffff, 0xff020505, 0x0301ffff,
- 0xff010000, 0x0200fefd, 0x00030101, 0x0100fefe,
- 0x01030101, 0xffff0000, 0x0102ff00, 0xfdff0001,
- 0x0101feff, 0xfcfe0001, 0x010200ff, 0xfdff0001,
- 0x02030101, 0xfdfe0001, 0x02040202, 0xfcfeff01,
- 0x02020201, 0x0200fe00, 0xfdfeffff, 0x01fdfbfc,
- 0x00010100, 0x01ffffff, 0x01010100, 0x02000000,
- 0x02010100, 0x02010101, 0x0200ffff, 0x03020202,
- 0xfffcfcfe, 0x00fefefe, 0x01000001, 0x01000000,
- 0xfefdff00, 0x01020200, 0xfdfeff00, 0x02010100,
- 0xfdfe0001, 0x010000ff, 0xfeff00ff, 0x00ff0000,
- 0x000101ff, 0x00000202, 0x01030200, 0x02030503,
- 0xfe0101ff, 0x01010300, 0xfc0000ff, 0xfffffffc,
- 0x000101ff, 0x02010201, 0x000100fd, 0x02000101,
- 0xfffffdfb, 0x01000100, 0xfdfefdfc, 0x00fffffe,
- 0xfeff0000, 0x00fefefe, 0x00020403, 0x01000000,
- 0x00000102, 0x00ff0000, 0x03020100, 0x02030404,
- 0x040704ff, 0x00000000, 0x030604ff, 0x01010100,
- 0x00040300, 0x010000ff, 0xfe010100, 0xffff00ff,
- 0xffff00ff, 0x000000ff, 0x00ffffff, 0x00000000,
- 0x00fdfdff, 0xfffeff01, 0xfefcfcfd, 0xfffefeff,
- 0x00010202, 0xfd000101, 0x0000fffe, 0xfd000101,
- 0x0100fffe, 0xfe010102, 0x02020201, 0xff020303,
- 0x00010201, 0xff020101, 0xfcfe0100, 0xff0100fe,
- 0xfdff0101, 0xfdff00fe, 0xff000201, 0xfcff0100,
- 0xfefeffff, 0x03040300, 0xfdff0101, 0x000000fe,
- 0x02020202, 0xffff0102, 0x03010101, 0xfefe0003,
- 0xffffff00, 0xfffffe00, 0xfdfcfdff, 0x0200fefe,
- 0x0100ffff, 0x05030202, 0x00fffffe, 0x01000000,
- 0x0002fdfe, 0xff010100, 0xfe01fcff, 0x000202ff,
- 0xfe00fc01, 0xff0101fe, 0xff01fd02, 0xff0101ff,
- 0x0103fe03, 0xff010100, 0x0102fd01, 0xff000100,
- 0x0001fbff, 0x010100ff, 0x0303fd00, 0x03030201,
- 0x01feff00, 0xff020505, 0xfffeff01, 0xfbfe0101,
- 0xfeff0101, 0xfdffffff, 0xffff0101, 0x030402ff,
- 0xffffffff, 0x030400ff, 0x0100ffff, 0xfffffdff,
- 0x02000000, 0xff000002, 0x00fdfe00, 0x02030101,
- 0x01020302, 0xfefe0000, 0x01000302, 0x02030301,
- 0xfffd0000, 0x030202ff, 0x01fdfefe, 0x01010201,
- 0x02fefffe, 0xfeff0101, 0x02000100, 0xfefe0000,
- 0x02000100, 0xfefe0000, 0x00fefefd, 0xfdfefeff,
- 0x03ff0100, 0xff0301ff, 0x03ff0100, 0xfd02ffff,
- 0x03fe0101, 0xfd00fdff, 0x03fe0202, 0xfe01fe00,
- 0x03fd0101, 0xfd01feff, 0x03fd0101, 0xfe01ff00,
- 0x04ff0201, 0xfe01ff00, 0x03ff0100, 0xfd00fdff,
- 0x01fffdfd, 0xfeff0102, 0x0200fefe, 0xfefe0001,
- 0x0201fefd, 0xfffeff01, 0x0402fefd, 0x01fefe00,
- 0x0402fffd, 0x02fefe00, 0x030401ff, 0x02fefdff,
- 0x02040200, 0x02fffeff, 0x00020100, 0x030100ff,
- 0x01fb0003, 0x01000004, 0x02fbfe01, 0x01feff05,
- 0x030000ff, 0xff000103, 0xfe0403fe, 0xfe00fffd,
- 0xfd0503fd, 0xfe0000fd, 0xfe0203ff, 0xff0202fe,
- 0xff000002, 0x00000000, 0x01fefd00, 0xfefe0003
+static const int8 s_svq1InterCodebook8x8[6144] = {
+ -4, -3, 4, 5, 2, 1, 1, 0, -5, -3, 5, 5, 2, 1, 0, 0,
+ -6, -4, 5, 5, 2, 1, 0, 0, -7, -4, 4, 5, 2, 1, 0, 0,
+ -8, -5, 3, 4, 2, 1, 0, 0, -8, -6, 3, 4, 1, 1, 1, 0,
+ -8, -6, 2, 4, 2, 1, 1, 0, -8, -6, 2, 4, 1, 1, 1, 1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -2, -2, -2, -2, -2,
+ -2, -3, -3, -3, -3, -3, -3, -3, -2, -3, -3, -3, -3, -3, -4, -3,
+ -2, -2, -2, -2, -2, -3, -3, -2, 1, 1, 1, 1, 1, 0, -1, -1,
+ 4, 5, 5, 5, 4, 3, 3, 2, 7, 7, 8, 8, 8, 7, 6, 5,
+ 2, 1, 2, 4, 4, 0, -4, -6, 1, 1, 2, 5, 5, 1, -5, -7,
+ 1, 2, 1, 4, 5, 1, -5, -8, 1, 1, 1, 5, 5, 0, -6, -8,
+ 0, 1, 1, 5, 6, 1, -6, -9, 0, 0, 1, 4, 5, 0, -5, -8,
+ 0, 0, 1, 4, 5, 0, -5, -7, 0, 0, 1, 4, 4, 1, -4, -7,
+ 1, 2, 3, 0, -3, -4, -3, -1, 1, 3, 4, 0, -3, -4, -3, -1,
+ 2, 4, 5, 1, -3, -4, -3, -2, 2, 5, 6, 1, -3, -5, -4, -2,
+ 3, 6, 6, 1, -3, -5, -4, -2, 3, 6, 6, 1, -3, -5, -4, -2,
+ 3, 6, 6, 1, -3, -5, -4, -2, 3, 5, 5, 1, -3, -4, -4, -2,
+ 2, 2, 2, 2, 1, 0, 0, -1, 4, 4, 4, 3, 2, 1, 1, 0,
+ 4, 5, 4, 4, 3, 3, 2, 1, 4, 4, 4, 4, 4, 3, 2, 2,
+ 2, 3, 3, 3, 3, 3, 2, 1, -1, -1, -1, -1, 0, 0, 0, 0,
+ -5, -6, -6, -5, -5, -4, -3, -3, -7, -9, -9, -8, -7, -6, -6, -5,
+ 6, 6, 6, 6, 6, 5, 5, 4, 4, 4, 4, 3, 3, 3, 3, 2,
+ 0, -1, -1, -1, -2, -2, -1, -1, -3, -5, -6, -6, -6, -6, -5, -4,
+ -3, -5, -6, -7, -6, -6, -5, -4, -1, -2, -2, -2, -2, -2, -1, -1,
+ 0, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3,
+ 2, 1, -2, -5, -4, 0, 2, 5, 2, 1, -2, -6, -5, 0, 3, 5,
+ 2, 1, -2, -6, -6, -1, 3, 6, 3, 2, -2, -7, -6, 0, 4, 7,
+ 2, 1, -2, -7, -5, 0, 5, 7, 2, 1, -2, -6, -5, 0, 4, 7,
+ 2, 1, -2, -6, -4, 0, 4, 6, 1, 1, -2, -5, -4, 0, 3, 6,
+ -10, -9, -6, -4, -1, 2, 3, 2,-10, -9, -5, -3, 0, 4, 4, 3,
+ -9, -7, -3, -1, 2, 5, 5, 3, -7, -5, -2, 0, 3, 5, 5, 3,
+ -6, -3, 0, 1, 4, 6, 5, 3, -4, -2, 1, 2, 3, 5, 4, 2,
+ -2, 0, 1, 2, 2, 4, 3, 1, -1, 1, 2, 2, 2, 3, 3, 1,
+ -4, -5, -5, -6, -6, -6, -6, -5, -3, -3, -4, -4, -4, -4, -4, -4,
+ 0, 0, 0, 0, -1, -1, -1, -1, 5, 5, 6, 5, 5, 4, 3, 2,
+ 5, 6, 7, 7, 7, 6, 5, 4, 3, 3, 4, 4, 4, 4, 3, 2,
+ 0, -1, 0, 0, -1, -1, 0, -1, -3, -3, -4, -4, -4, -4, -3, -3,
+ 1, -2, -5, 1, 5, 4, 2, 0, 1, -3, -6, 1, 6, 5, 2, 0,
+ 0, -4, -7, 0, 6, 6, 2, 1, -1, -5, -9, -1, 6, 6, 3, 1,
+ -1, -6,-10, -2, 6, 6, 3, 1, -1, -6, -9, -2, 5, 6, 3, 1,
+ -2, -6, -9, -2, 5, 5, 3, 1, -2, -6, -7, -2, 4, 4, 2, 1,
+ -5, -7, -8, -9, -9, -8, -7, -6, -5, -6, -6, -7, -7, -6, -6, -5,
+ -3, -3, -3, -4, -5, -5, -4, -4, -1, 0, 0, -1, -1, -1, -1, -1,
+ 0, 1, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 5, 5, 5, 4,
+ 3, 4, 5, 6, 8, 8, 8, 7, 3, 4, 5, 6, 7, 7, 7, 6,
+ 5, 6, 7, 8, 9, 10, 10, 9, 3, 4, 6, 7, 8, 9, 9, 8,
+ 0, 1, 2, 3, 4, 5, 5, 5, -1, -2, -1, -1, 0, 1, 2, 2,
+ -2, -3, -3, -3, -3, -2, -1, 0, -3, -4, -5, -5, -5, -5, -5, -4,
+ -4, -5, -5, -6, -7, -7, -6, -5, -3, -4, -5, -6, -7, -7, -6, -6,
+ 13, 7, 0, -3, -3, -4, -4, -5, 14, 7, 0, -3, -3, -4, -4, -4,
+ 15, 8, -1, -4, -4, -4, -5, -4, 15, 8, -1, -4, -4, -5, -4, -3,
+ 15, 7, -1, -4, -5, -5, -5, -4, 14, 7, -1, -4, -4, -4, -4, -3,
+ 12, 6, -1, -4, -4, -4, -4, -3, 11, 5, -1, -4, -4, -4, -4, -3,
+ -17, -4, 5, 4, 4, 4, 3, 3,-18, -5, 5, 4, 4, 4, 3, 3,
+ -19, -5, 6, 4, 4, 4, 3, 2,-20, -5, 6, 4, 4, 4, 3, 3,
+ -20, -4, 6, 4, 4, 5, 3, 3,-19, -5, 6, 4, 4, 5, 3, 3,
+ -18, -4, 5, 4, 4, 4, 3, 2,-17, -5, 4, 3, 4, 4, 3, 3,
+ -6, -6, -6, -4, -2, 1, 6, 11, -6, -7, -7, -4, -2, 2, 8, 13,
+ -8, -8, -7, -4, -2, 3, 9, 14, -8, -8, -7, -5, -1, 4, 10, 16,
+ -8, -8, -7, -5, -1, 4, 10, 17, -8, -8, -7, -4, 0, 5, 10, 16,
+ -8, -8, -6, -3, 0, 4, 9, 15, -7, -7, -5, -3, 0, 4, 8, 12,
+ 8, 7, 7, 5, 2, -2, -8,-14, 8, 8, 7, 5, 2, -2, -8,-15,
+ 8, 8, 7, 5, 1, -3, -9,-16, 8, 8, 7, 5, 1, -3,-10,-17,
+ 8, 9, 8, 5, 1, -3,-10,-17, 8, 8, 7, 4, 1, -4,-10,-16,
+ 7, 7, 7, 4, 1, -3, -9,-14, 6, 7, 6, 3, 0, -3, -9,-13,
+ 5, 1, -4, -4, -3, -1, 0, 0, 7, 2, -3, -3, -2, -1, 1, 0,
+ 7, 1, -3, -3, -1, 0, 1, 1, 6, 1, -3, -2, -1, 1, 1, 0,
+ 6, 0, -4, -2, -1, 0, 1, 0, 5, 0, -4, -3, -1, 0, 0, -1,
+ 5, 0, -3, -1, 0, 0, 0, -2, 4, 1, -2, -1, 0, 1, 0, -1,
+ 2, 2, 1, 1, -2, -6, -8, -8, 1, 1, 1, 1, -2, -5, -8, -8,
+ 1, 1, 1, 0, -1, -3, -5, -5, 0, 0, 0, 0, -1, -1, -1, -2,
+ 0, -1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 3, 2,
+ 2, 1, 1, 1, 2, 3, 4, 3, 3, 3, 3, 3, 4, 4, 5, 4,
+ -4, -4, -3, -2, 0, 0, 1, 1, -4, -4, -3, -2, -1, 0, 0, 1,
+ -2, -2, -2, -1, -1, -1, 0, 0, 0, 1, 0, 0, 0, 0, 0, -1,
+ 2, 2, 2, 2, 2, 2, 1, 1, 3, 4, 4, 4, 4, 4, 4, 3,
+ 1, 1, 1, 3, 3, 4, 3, 3, -5, -6, -5, -4, -3, -3, -2, -2,
+ -4, -2, -1, -1, -1, -1, 0, 1, -4, -2, -1, -1, -1, -1, 0, 1,
+ -3, -2, -1, -1, -1, 0, 1, 2, -4, -3, -2, -1, -1, 1, 3, 3,
+ -4, -3, -3, -1, -1, 1, 4, 5, -4, -3, -2, -2, -1, 1, 4, 7,
+ -2, -2, -1, -1, 0, 2, 6, 8, -1, 0, 0, 1, 1, 4, 7, 8,
+ -3, -3, -3, -2, -2, -1, -1, 0, -1, -1, 0, 1, 2, 2, 3, 3,
+ 0, 1, 2, 4, 5, 6, 6, 5, -1, 0, 2, 3, 5, 6, 5, 3,
+ -1, -1, 0, 2, 3, 3, 2, 1, -2, -2, -1, 0, -1, -3, -4, -4,
+ 0, 0, -1, -1, -2, -4, -8, -7, 1, 2, 1, 0, -1, -4, -6, -7,
+ -2, 4, 1, -6, 0, 3, 0, 0, -2, 5, 1, -7, 0, 3, 0, 0,
+ -3, 5, 1, -8, 0, 3, -1, -1, -2, 6, 1, -9, 0, 3, 0, -1,
+ -2, 6, 2, -8, 0, 4, 0, -1, -3, 5, 1, -7, 1, 4, 0, 0,
+ -2, 4, 1, -7, 0, 4, 1, 0, -1, 4, 1, -6, 0, 3, 1, 0,
+ 0, 0, 0, 3, 4, 5, 4, 1, 1, 1, 1, 2, 3, 3, 2, 0,
+ 2, 2, 1, 2, 2, 1, -1, -2, 4, 3, 1, 1, 0, -1, -3, -5,
+ 5, 3, 1, -1, -2, -3, -4, -6, 5, 3, 0, -2, -3, -5, -6, -7,
+ 4, 3, 0, -2, -3, -4, -5, -5, 4, 3, 0, -1, -2, -2, -3, -3,
+ 0, 0, 0, 0, -1, -5, -2, 6, 0, 0, 0, 1, -1, -6, -2, 8,
+ 0, 0, 0, 2, 0, -6, -3, 9, 0, -1, 0, 2, 0, -7, -2, 10,
+ 0, -1, 0, 2, -1, -8, -3, 10, 0, -1, -1, 2, -1, -7, -3, 9,
+ 0, -1, 0, 1, -1, -6, -3, 8, 0, 0, 0, 1, 0, -5, -2, 7,
+ 2, 3, 3, 2, 1, 0, -1, -1, 3, 4, 3, 2, 1, 0, -1, -2,
+ 3, 4, 4, 2, 1, -1, -2, -3, 2, 3, 3, 2, 0, -1, -2, -3,
+ -1, 0, 1, 1, 0, -1, -2, -2, -5, -4, -3, -1, 0, 1, 1, 1,
+ -8, -8, -5, -1, 1, 3, 4, 3,-10, -9, -5, 0, 3, 5, 6, 5,
+ -5, -1, 4, 5, 3, 1, 0, 0, -6, -1, 4, 5, 2, 0, -1, -2,
+ -6, -1, 5, 4, 2, -1, -2, -2, -7, -1, 4, 4, 1, -2, -3, -3,
+ -6, -1, 5, 4, 1, -2, -3, -3, -5, 0, 4, 4, 1, -1, -2, -2,
+ -4, 0, 5, 4, 1, -1, -1, -2, -3, 1, 4, 3, 1, -1, -1, -2,
+ -2, -3, -2, 1, 4, 6, 5, 3, -3, -4, -4, 0, 3, 5, 4, 2,
+ -3, -5, -5, -1, 2, 4, 3, 1, -4, -6, -4, -1, 2, 4, 2, -1,
+ -2, -4, -3, 1, 2, 4, 2, -1, -2, -4, -2, 1, 3, 3, 1, -2,
+ -2, -3, -2, 1, 3, 3, 1, -2, -2, -2, -1, 1, 3, 3, 0, -2,
+ -4, -4, -3, -2, -1, 2, 5, 7, -4, -4, -3, -3, -2, 1, 5, 7,
+ -2, -3, -2, -3, -3, -1, 3, 5, -1, -1, 0, -2, -3, -2, 2, 4,
+ 1, 1, 1, -1, -4, -3, 1, 3, 4, 3, 2, -1, -4, -3, -1, 1,
+ 6, 4, 3, 0, -3, -3, -2, 0, 6, 5, 3, 1, -2, -3, -2, -1,
+ 12, 11, 8, 4, 0, -2, -2, -1, 10, 9, 6, 2, -1, -2, -1, 0,
+ 4, 3, 2, 0, -1, -1, 0, 1, -1, -1, -1, -1, -2, 0, 1, 2,
+ -3, -5, -4, -2, -2, 0, 2, 3, -5, -5, -4, -2, -1, 0, 1, 2,
+ -5, -5, -4, -2, -1, 0, 1, 1, -4, -4, -3, -2, -2, -1, 0, 0,
+ 3, 3, 2, -1, -3, -4, -3, -2, 3, 2, 0, -2, -4, -4, -3, -2,
+ 2, 2, 1, -1, -3, -5, -4, -3, 3, 3, 3, 1, -2, -3, -3, -3,
+ 4, 4, 4, 3, 0, -2, -2, -2, 5, 5, 5, 3, 0, -1, -2, -2,
+ 5, 5, 4, 2, -1, -2, -3, -2, 3, 3, 3, 0, -2, -4, -4, -4,
+ -1, -1, 4, -2, -2, 6, 2, -5, -1, 0, 4, -2, -3, 6, 2, -6,
+ -1, 0, 4, -2, -3, 7, 3, -7, -1, -1, 4, -3, -4, 8, 3, -7,
+ 0, -1, 4, -3, -4, 7, 3, -6, -1, -1, 4, -3, -4, 7, 3, -6,
+ -1, -1, 3, -3, -4, 6, 3, -6, -1, 0, 3, -2, -3, 6, 3, -5,
+ 1, -2, -7, 2, 5, -2, -1, 1, 1, -2, -8, 3, 6, -3, -1, 2,
+ 2, -2, -9, 4, 7, -4, -2, 2, 3, -1, -9, 5, 7, -4, -1, 3,
+ 3, -1, -9, 4, 7, -4, -2, 2, 3, -1, -7, 4, 6, -4, -2, 1,
+ 2, 0, -6, 4, 6, -4, -1, 1, 2, 0, -5, 3, 4, -3, -1, 1,
+ -2, 2, 2, 0, 0, -1, -3, -4, -2, 2, 2, 1, 1, 0, -2, -4,
+ -2, 2, 2, 2, 2, 1, -1, -2, -3, 2, 3, 3, 4, 2, 0, -2,
+ -3, 2, 3, 2, 4, 2, 0, -3, -4, 1, 2, 1, 2, 1, -1, -3,
+ -5, 0, 1, 0, 1, 1, -2, -3, -4, 0, 0, 0, 1, 0, -2, -3,
+ 0, 0, -1, -2, -2, 2, 7, 8, 0, 0, -1, -3, -2, 1, 6, 7,
+ 0, 1, -1, -3, -3, 0, 4, 5, 0, 1, 0, -1, -1, 0, 1, 3,
+ 0, 2, 1, 1, 0, -1, 0, 1, -2, 0, 1, 2, 1, 0, -1, -1,
+ -5, -2, 0, 1, 1, 0, -3, -3, -6, -4, -1, 1, 1, -1, -3, -4,
+ -4, -2, 2, 5, 6, 4, 3, 2, -5, -3, 1, 4, 4, 2, 0, 0,
+ -4, -2, 0, 2, 1, -1, -2, -2, -2, -1, 0, 1, 0, -2, -3, -2,
+ -2, 0, 0, 0, -1, -1, -2, -1, -2, -1, -1, 0, 0, 0, 1, 2,
+ -2, -2, -1, -1, 0, 1, 3, 4, -2, -3, -2, -1, 0, 2, 4, 5,
+ 2, 1, -2, -2, -1, 0, 1, 0, 1, 0, -3, -3, -1, 0, 1, 0,
+ 0, -1, -3, -3, -1, 1, 1, 1, 0, 0, -3, -1, 1, 2, 3, 3,
+ 0, -1, -3, -1, 1, 3, 3, 3, -2, -2, -4, -2, 1, 3, 4, 4,
+ -3, -3, -4, -2, 1, 3, 3, 4, -2, -3, -5, -2, 1, 2, 3, 3,
+ 4, 5, 3, 4, 4, 4, 4, 5, 3, 3, 1, 0, 0, 0, 0, 1,
+ 1, 1, -1, -2, -3, -4, -3, -2, 2, 2, 0, -2, -2, -4, -3, -2,
+ 2, 3, 1, -1, -1, -3, -3, -2, 1, 2, 0, 0, -1, -2, -2, -1,
+ 0, 1, 0, -1, -1, -3, -2, -1, 1, 1, 0, -1, -1, -2, -2, -2,
+ -2, -1, -1, 0, 1, 2, 1, 0, 1, 2, 3, 5, 6, 5, 5, 3,
+ 1, 2, 3, 4, 5, 5, 4, 3, -2, -2, -3, -3, -2, -1, 0, 0,
+ -3, -3, -4, -5, -4, -3, -2, -1, -1, -1, -2, -2, -2, -1, 0, 0,
+ 0, 1, 0, -1, -1, 0, 0, 1, -1, 0, -1, -2, -3, -2, -2, -1,
+ 7, 7, 6, 5, 4, 2, -1, -2, 3, 3, 2, 2, 1, 0, -2, -3,
+ 0, -1, -1, -1, 0, -1, -2, -2, -1, -3, -2, -1, 0, 0, 0, 1,
+ 0, -2, -2, -1, -1, 1, 2, 2, 3, 1, -1, -1, -1, 1, 2, 2,
+ 3, 1, -2, -3, -2, -1, 1, 2, 1, -2, -5, -6, -5, -3, -2, 0,
+ 0, -1, -2, -3, -1, 0, -2, -2, 0, 0, -1, -1, 0, 1, -1, -2,
+ 0, 0, -2, -1, 0, 0, 0, -2, -1, -2, -3, -3, -2, -1, -3, -3,
+ -1, -2, -3, -3, -2, -2, -3, -4, 2, 2, 0, 0, 0, 0, -1, -2,
+ 5, 5, 3, 2, 2, 2, 0, -1, 8, 8, 6, 5, 4, 4, 2, 1,
+ -7, -8, -6, -3, -1, -1, -2, -1, -5, -5, -3, 0, 2, 1, 0, 0,
+ -1, -1, 0, 3, 4, 3, 1, 1, 2, 1, 1, 3, 4, 3, 2, 2,
+ 3, 2, 0, 2, 3, 2, 1, 2, 4, 2, -1, -1, 0, 1, 1, 1,
+ 3, 2, -2, -3, -2, -1, 0, 1, 3, 1, -3, -4, -3, -2, 0, 1,
+ -4, -2, -1, 2, 3, 3, 1, 0, -7, -5, -4, -2, 0, 0, -1, -2,
+ -6, -5, -5, -4, -2, -2, -2, -3, -1, 0, -1, -1, 0, 0, 0, -1,
+ 2, 3, 2, 2, 2, 2, 1, 0, 3, 5, 4, 3, 1, 0, 1, 0,
+ 3, 4, 3, 2, 0, -1, -1, -1, 5, 5, 3, 1, 0, -1, -1, -1,
+ 1, 1, 0, -1, -3, -5, -6, -4, 1, 1, 0, 0, 0, -3, -3, -1,
+ 0, -1, -1, 0, 1, 0, 1, 3, -2, -2, -3, -1, 2, 2, 4, 7,
+ -2, -2, -2, 0, 2, 2, 3, 6, -1, 0, 0, 1, 1, 0, 0, 3,
+ 0, 3, 3, 3, 1, -2, -3, -1, 1, 3, 4, 3, 0, -3, -5, -4,
+ 0, 2, 0, -1, -3, -4, -2, -2, 1, 4, 2, 0, -2, -3, -2, -1,
+ 3, 6, 3, 1, -2, -2, 0, -1, 4, 7, 4, 1, -2, -3, -1, 0,
+ 3, 6, 3, 0, -3, -3, -1, 0, 1, 3, 0, -1, -3, -2, 1, 1,
+ 0, 1, -1, -2, -3, -1, 2, 2, -2, -1, -3, -3, -3, -1, 1, 2,
+ 3, 1, -1, 0, 1, 0, 0, 0, 2, -1, -2, -1, 1, 0, -1, -1,
+ 1, -1, -2, 0, 1, 0, -2, -3, 0, -2, -1, 1, 3, 1, -3, -5,
+ 0, -2, -1, 2, 5, 2, -3, -5, 0, -2, -1, 4, 6, 3, -2, -5,
+ 0, -2, 0, 4, 7, 4, -2, -4, 0, -2, 0, 4, 6, 4, -2, -4,
+ -2, -2, -3, -4, -3, -2, -1, 0, 1, 1, 0, -1, -1, -1, 0, 1,
+ 3, 3, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 1, 0, 0, 1,
+ 0, 0, 0, 0, -1, -1, -1, -1, -4, -4, -4, -4, -4, -4, -4, -3,
+ -3, -3, -2, -3, -2, -1, -1, 0, 3, 4, 4, 5, 5, 6, 6, 7,
+ -1, -2, 7, -2, -4, -1, -1, 0, -1, -2, 9, -1, -4, -1, -1, 0,
+ -1, -3, 10, -1, -4, -1, -1, 1, -1, -3, 10, -2, -3, -1, -1, 2,
+ -1, -2, 10, -2, -4, -1, -1, 2, -1, -2, 9, -2, -4, -1, -1, 2,
+ -1, -2, 8, -2, -4, 0, -1, 1, 0, -2, 7, -2, -3, -1, 0, 2,
+ 3, -4, 1, 3, -3, -2, 1, 0, 3, -5, 1, 4, -3, -2, 1, 0,
+ 3, -6, 2, 5, -3, -1, 3, 0, 3, -6, 2, 5, -3, -1, 2, 0,
+ 3, -6, 1, 5, -4, -2, 3, 0, 3, -6, 1, 5, -3, -2, 2, 0,
+ 2, -6, 1, 4, -3, -1, 1, 0, 2, -6, 1, 4, -2, -1, 1, 0,
+ 0, 0, 1, 1, 1, 0, 0, 2, 0, -1, 1, 1, 1, 0, 0, 2,
+ 0, -1, 0, 0, 0, 0, 0, 2, 0, -1, 0, 0, 0, 0, -1, 0,
+ 1, 0, 1, 0, 0, -1, -2, -1, 3, 1, 1, 0, 0, -2, -4, -3,
+ 5, 3, 2, 1, 0, -3, -5, -4, 5, 4, 2, 0, -1, -4, -5, -5,
+ 1, 0, -1, -2, -2, -3, -6, -9, 2, 0, -1, -1, 0, 0, -3, -6,
+ 1, 0, 0, -1, 0, 0, -2, -5, 2, 1, 1, 1, 1, 2, -1, -3,
+ 1, 1, 2, 1, 2, 2, 1, -1, 1, 1, 2, 1, 1, 1, 1, 1,
+ 0, 0, 2, 1, 0, 0, 2, 2, 0, 1, 2, 2, 0, 0, 2, 2,
+ -4, -3, 0, 1, 4, 6, 4, 3, -3, -2, 0, 0, 2, 4, 1, 0,
+ -1, -1, 0, 0, 1, 1, -2, -3, 1, 1, 1, 0, 1, 1, -3, -5,
+ 1, 1, 1, 0, 1, 1, -3, -5, -1, 0, 0, -1, 1, 1, -2, -4,
+ -1, 0, 0, -1, 1, 2, 0, -2, -1, 0, 0, 0, 2, 3, 1, 0,
+ -1, 0, 3, 4, 0, -4, -5, -5, 0, 0, 4, 5, 2, -2, -3, -2,
+ 0, -1, 2, 4, 2, -1, -1, 0, 0, -2, -1, 1, 0, -2, 0, 1,
+ 1, -2, -2, 0, 0, -1, -1, 1, 1, -2, -3, 0, 1, 0, -1, 0,
+ 1, -2, -2, 1, 3, 1, 0, 0, 1, -2, -1, 2, 4, 2, 0, 0,
+ 1, 2, 3, 2, 0, 2, 2, 1, -1, 0, 1, 0, -3, 1, 1, 1,
+ -1, 0, 0, -2, -4, 0, 2, 1, -1, 2, 2, -1, -5, 0, 2, 1,
+ -1, 3, 4, -1, -5, 0, 2, 1, -2, 2, 4, 0, -4, -1, 0, 0,
+ -4, 0, 2, 0, -4, -2, 0, 0, -5, -1, 2, 1, -2, 1, 3, 2,
+ 1, 0, 1, 0, 1, 2, -1, -2, 2, 0, -1, -2, 1, 3, 0, -1,
+ 3, 0, -2, -4, 0, 3, 1, 0, 5, 1, -3, -5, -2, 2, 1, 1,
+ 6, 1, -2, -5, -2, 1, 0, 1, 5, 1, -1, -5, -2, 0, -1, 0,
+ 3, 0, -2, -4, -2, 0, -1, 0, 1, -1, 0, -2, 0, 1, 0, 1,
+ 1, 1, 2, 3, 2, 1, 1, 2, -1, -1, 0, 1, 1, 0, 1, 1,
+ -4, -3, 0, 0, 1, 1, 1, 2, -4, -3, 0, 2, 2, 2, 3, 2,
+ -5, -4, 0, 1, 1, 1, 1, 2, -5, -4, -1, -1, -2, -2, -1, 0,
+ -3, -2, 0, 0, -2, -3, -2, -1, 2, 3, 4, 4, 2, 0, 0, 0,
+ -4, -2, 0, 1, 0, 0, 0, 0, -3, -1, 1, 1, 0, 0, 0, 0,
+ -2, 0, 2, 2, 0, 0, 0, 2, -1, 1, 2, 1, -1, 0, 3, 5,
+ 0, 2, 1, -1, -2, 0, 5, 6, 0, 1, 0, -3, -3, 0, 4, 6,
+ 1, 1, -2, -4, -4, -3, 1, 2, 1, 0, -2, -4, -5, -4, -2, 0,
+ -1, -3, -3, -3, -3, -2, -1, -1, 3, 2, 1, 0, 0, 1, 1, 1,
+ 5, 4, 3, 2, 1, 1, 2, 2, 2, 1, 0, -2, -2, -2, -1, -1,
+ 0, 0, 0, -1, -2, -2, -2, -2, 0, 1, 3, 3, 2, 1, -1, -1,
+ 0, 1, 3, 4, 3, 2, 1, -1, -4, -3, -1, 1, 0, -2, -3, -3,
+ -3, -4, -7, -8, -7, -4, -1, 2, 0, -1, -3, -4, -4, -2, 0, 2,
+ 1, 0, 0, -1, -3, -2, 0, 2, 2, 1, 1, 0, -1, -1, 0, 2,
+ 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 2, 3, 3, 2, 2, 0, 0, 1, 3, 4, 4, 3, 2,
+ 3, 3, 3, 0, -1, 0, 1, 2, 1, 1, 1, -1, -2, -1, -1, 1,
+ -2, -2, -1, -3, -3, -2, -2, 0, -4, -4, -2, -2, -2, -2, -3, 0,
+ -4, -4, -1, 1, 1, 0, -1, 2, -3, -1, 2, 3, 4, 3, 3, 5,
+ -2, 0, 2, 3, 3, 3, 3, 3, -2, -2, 0, 0, 0, 0, 0, 1,
+ 0, 2, 1, -1, -3, -1, 3, -2, -1, 0, -1, -1, -3, 0, 4, -2,
+ -2, -2, -2, -2, -2, 1, 5, -2, -3, -2, -3, -1, -2, 1, 4, -3,
+ -2, 0, -1, 0, -1, 0, 3, -5, 1, 2, 1, 2, 0, 0, 2, -5,
+ 2, 4, 2, 3, 1, 1, 3, -3, 1, 2, 1, 1, 0, 1, 4, -2,
+ 4, -3, -4, -1, 3, 3, 1, 3, 4, -4, -4, -1, 3, 2, 0, 2,
+ 4, -3, -4, 0, 2, 2, -1, 1, 4, -3, -2, 1, 2, 1, -2, 0,
+ 2, -4, -2, 1, 2, 0, -3, 0, 2, -3, -2, 0, 1, 0, -2, 2,
+ 3, -1, -1, 0, 0, 0, 0, 3, 2, -2, -2, -2, -1, -1, -1, 2,
+ 2, 2, 3, 4, 3, 1, 0, -1, 1, 0, 1, 2, 1, -1, -2, -2,
+ 2, 1, 2, 1, 1, 0, -1, -1, 4, 3, 4, 3, 2, 1, 1, 1,
+ 3, 2, 2, 2, 1, 1, 1, 1, -1, -2, -1, 0, -1, -1, -1, -1,
+ -3, -3, -2, -1, -2, -2, -2, -2, -4, -4, -3, -3, -4, -4, -3, -3,
+ 2, 1, -1, -3, -4, -2, 3, 4, 2, 2, 1, -1, -3, -2, 1, 2,
+ 1, 2, 3, 3, 0, -2, -1, -2, -1, 0, 2, 4, 2, 0, -1, -3,
+ -2, -2, 0, 3, 3, 2, 0, -3, 0, -2, -3, -1, 1, 2, 2, -1,
+ 3, -1, -4, -5, -3, 0, 2, 0, 6, 3, -2, -6, -5, 0, 3, 1,
+ -2, 3, -2, 0, 3, -2, -2, 1, -3, 4, -3, 0, 3, -2, -1, 2,
+ -3, 5, -3, 0, 4, -2, -1, 2, -2, 4, -4, -1, 3, -3, -2, 2,
+ -3, 4, -3, 0, 3, -3, -1, 2, -2, 5, -2, 0, 3, -3, -1, 2,
+ -2, 4, -3, 1, 3, -2, -1, 2, -2, 3, -2, 1, 3, -2, 0, 2,
+ 1, 0, 0, -1, 1, 2, -4, -1, 2, 0, 0, -1, 1, 2, -4, -2,
+ 1, 1, 1, -1, 2, 4, -2, 0, 0, -1, 1, -1, 2, 5, -1, 1,
+ 0, -1, 0, -2, 1, 5, -1, 1, 0, -1, -1, -2, 0, 3, -3, -1,
+ 1, 1, 0, -2, 0, 3, -3, -1, 1, 1, 0, -3, 0, 3, -2, 0,
+ 1, 0, -1, 1, 1, 2, 4, 5, 1, 0, -1, 1, 1, 1, 5, 7,
+ 0, 0, -2, -1, -1, 0, 3, 5, 0, -1, -2, -1, -1, -1, 2, 3,
+ 0, -1, -3, -1, -1, -1, 1, 2, -1, -2, -4, -2, -2, -2, 0, 0,
+ -1, -2, -2, -1, -2, -2, 0, 0, 0, -1, -1, 0, -1, -1, 0, 0,
+ 3, 3, 0, -1, -1, 1, 4, 4, 2, 3, 0, -2, -2, 0, 1, 1,
+ 2, 3, 1, -1, -1, 0, 1, 0, 1, 2, 0, -1, -1, -1, 0, -2,
+ 0, 1, 0, -1, -2, -1, 0, -2, 0, 1, 0, -1, -2, -1, 1, 0,
+ 1, 1, -1, -3, -4, -3, 1, 3, 1, 2, -1, -3, -5, -4, 1, 3,
+ -3, -2, 0, 1, 1, 1, 0, -2, 0, 1, 1, 1, 0, 0, -1, -3,
+ 1, 2, 1, 1, 0, -1, -1, -2, 0, -1, -3, -1, -1, -1, 0, -1,
+ 0, -3, -6, -3, -2, -1, 1, 1, 2, -1, -4, -3, -2, 0, 2, 2,
+ 5, 4, 1, 1, 0, 1, 3, 2, 5, 4, 2, 1, 0, -1, 0, 1,
+ -2, 0, -2, -5, -6, -3, 0, 0, -2, 0, 1, 0, -1, 1, 2, 2,
+ -2, 0, 1, 3, 2, 2, 2, 1, -2, 0, 2, 4, 3, 2, 1, 1,
+ -2, 0, 2, 3, 2, 0, -1, 0, -3, -1, 1, 1, 0, -1, -1, 1,
+ -4, -1, 1, 0, -1, -2, 0, 2, -4, -1, 0, -1, -1, -2, 1, 4,
+ -3, 0, 0, -1, 1, 1, 1, 0, -3, 1, 0, -1, 0, 0, -1, -1,
+ -1, 3, 3, 0, 1, 0, 0, 1, -3, 2, 2, -2, -1, 0, 0, 1,
+ -5, 0, 0, -2, -1, 1, 0, 2, -7, -2, 1, 0, 1, 2, 2, 2,
+ -5, 0, 3, 2, 3, 3, 2, 2, -3, 2, 4, 1, 0, 0, -2, -3,
+ 5, 2, -2, -2, 0, -1, -1, -1, 2, -1, -4, -3, -1, -2, -1, -1,
+ 0, -2, -2, 1, 2, -1, 0, 1, -1, -2, -1, 3, 3, -1, 0, 2,
+ 1, 0, 0, 3, 3, -2, -1, 2, 2, 1, 1, 3, 2, -2, -2, 0,
+ 1, 0, -1, 1, 1, -3, -3, -2, 1, 0, 1, 2, 3, 0, 0, 0,
+ -4, -5, -3, 0, 1, -1, -2, -1, -2, -3, -1, 1, 2, 0, 0, 0,
+ 1, 1, 2, 1, 2, 1, 1, 1, 3, 4, 3, 1, 0, -2, -1, -1,
+ 3, 3, 2, 0, -2, -3, -3, -2, 1, 1, 0, -1, -2, -4, -2, -2,
+ 2, 1, 0, 0, 0, -1, 0, 1, 2, 1, 1, 1, 1, 1, 1, 3,
+ 0, 0, 0, -1, -2, -1, 1, 0, -2, -1, -1, -2, -3, -2, 0, 0,
+ -1, 0, 0, -1, -2, 0, 1, 1, 1, 1, 0, -1, -1, 1, 3, 1,
+ 2, 2, 0, -2, -1, 2, 3, 0, 3, 1, -1, -1, 1, 4, 2, -2,
+ 2, 0, -3, -1, 3, 5, 0, -5, 1, -1, -2, 0, 3, 3, -1, -6,
+ -1, 0, 3, 4, 2, 0, 1, 2, -2, -1, 0, 1, -1, -2, 0, 1,
+ -2, -3, -2, -3, -6, -7, -6, -3, 2, 2, 3, 1, -1, -2, -3, -2,
+ 2, 2, 3, 1, 0, 0, 0, 0, 2, 1, 1, 0, 1, 1, 0, 1,
+ 1, 0, 0, 0, 0, 1, 1, 2, 1, 0, -1, 0, 0, 2, 2, 1,
+ 1, 1, 3, 1, -1, -1, -1, 1, -2, -1, 0, 0, -2, -2, -1, 2,
+ -2, -2, 1, 1, 1, 0, 1, 3, -2, -2, 0, -1, 0, -1, 0, 2,
+ 0, 0, 1, 0, -1, -1, -2, 1, 3, 2, 2, 1, 0, -2, -2, 1,
+ 5, 3, 3, 2, 1, 1, 1, 4, 0, -3, -4, -5, -4, -3, -1, 1,
+ -6, -4, -1, 2, 2, 0, 0, -1, -4, -2, 1, 3, 3, 2, 2, 0,
+ -3, -2, -1, 2, 3, 3, 2, 0, -3, -2, -2, 1, 2, 1, 1, -1,
+ -2, -2, -2, 0, 2, 2, 1, -1, -1, -1, -1, 1, 2, 3, 2, 0,
+ -1, -1, -2, 1, 2, 2, 2, -1, 0, -1, -2, 0, 2, 1, 0, -1,
+ 6, 4, 2, 1, 0, 0, 0, 1, 4, 2, -1, -2, -2, -2, -1, -1,
+ 2, 1, -1, -2, -2, -2, -2, -1, 2, 2, 0, -2, -2, -2, -1, 0,
+ 0, 0, -1, -2, -2, -1, 0, 1, -3, -3, -2, -1, -1, -2, -1, 0,
+ -3, -2, 2, 3, 2, 0, -1, -2, -2, 0, 4, 5, 5, 2, 0, -1,
+ 5, 4, 2, 0, -1, -2, -1, -1, 4, 3, 2, 1, 0, -1, 0, -1,
+ 1, 1, 0, 1, 1, 0, 1, -1, -2, -1, -1, 0, 0, -2, -2, -3,
+ -1, 0, 0, 0, -1, -3, -3, -5, 0, 1, 1, -1, -1, -2, -2, -3,
+ -1, -1, -1, -2, -1, 1, 3, 1, -1, -2, -2, -1, 2, 5, 6, 5,
+ -3, -3, -2, 1, 1, -2, -1, -1, 1, 2, 3, 4, 1, -3, -1, -3,
+ 3, 2, 0, 1, -1, -3, -1, -3, 1, 0, -1, 0, -1, -1, 1, 0,
+ 1, 1, 0, 1, 2, 2, 5, 3, 1, 1, 1, 2, 2, 2, 3, 0,
+ -3, -1, -2, -2, -3, -3, -1, -3, -1, 1, 1, 0, -1, -1, 0, -2,
+ 2, 0, -2, -2, 2, 4, 1, -2, 1, 0, -2, -1, 3, 5, 2, -1,
+ -1, -2, -3, -2, 1, 3, 1, -2, -1, -2, -1, -1, 0, 2, 1, -1,
+ 0, 0, 1, 1, 1, 2, 2, 0, 0, 1, 4, 4, 2, 2, 3, 1,
+ -2, -1, 2, 1, -2, -3, -2, -3, -1, 0, 1, 0, -3, -4, -4, -5,
+ 4, 0, -3, -4, -4, -4, -2, -1, 5, 0, -1, 0, -1, -3, -2, -1,
+ 4, 0, 0, 1, 1, 0, 0, 0, 0, -3, -2, -1, 0, 0, 1, 0,
+ 0, -2, 0, 0, 1, 1, 2, 1, 2, 0, 0, 0, 1, 1, 1, 0,
+ 2, 0, -1, -1, 1, 1, 1, 0, 1, -1, -2, -2, 0, 2, 2, 2,
+ -3, -5, -2, 0, -1, -3, -3, 0, 0, -2, 0, 2, 2, 0, 0, 3,
+ 2, -1, -2, 0, 0, -1, -1, 2, 5, 2, -1, -1, -1, -1, -1, 2,
+ 5, 2, 0, -1, -1, 0, -1, 2, 2, 1, 0, 0, 0, 1, 0, 2,
+ -1, -1, 1, 1, 2, 2, 1, 2, -3, -2, 0, 0, 0, 0, -2, -1,
+ 0, 3, 2, 0, -2, -3, -3, -3, 0, 3, 3, 1, 0, 0, 1, 2,
+ -1, 0, -1, -2, -1, -1, 1, 3, -1, 0, -1, -2, -1, -1, 0, 2,
+ -1, 0, -1, -2, 0, 0, -1, 2, -1, 0, -1, -2, -1, -1, -2, 1,
+ 0, 1, 0, -3, -1, -1, -1, 2, 5, 5, 2, -1, -1, -1, 1, 3,
+ 0, 0, 1, -1, -3, -2, 0, 2, 1, 1, 3, 0, -2, -2, 0, 1,
+ 1, 1, 3, 1, 0, 0, -1, -1, 0, -1, 2, 1, 1, 0, -1, -3,
+ -1, -2, 1, 1, 1, 0, -2, -4, -1, 0, 2, 1, 1, 0, -1, -3,
+ 1, 1, 3, 2, 1, 0, -2, -3, 2, 2, 4, 2, 1, -1, -2, -4,
+ 1, 2, 2, 2, 0, -2, 0, 2, -1, -1, -2, -3, -4, -5, -3, 1,
+ 0, 1, 1, 0, -1, -1, -1, 1, 0, 1, 1, 1, 0, 0, 0, 2,
+ 0, 1, 1, 2, 1, 1, 1, 2, -1, -1, 0, 2, 2, 2, 2, 3,
+ -2, -4, -4, -1, -2, -2, -2, 0, 1, 0, 0, 1, 0, 0, 0, 1,
+ 0, -1, -3, -2, 0, 2, 2, 1, 0, -1, -2, -3, 0, 1, 1, 2,
+ 1, 0, -2, -3, -1, 0, 0, 1, -1, 0, -1, -2, 0, 0, -1, 0,
+ -1, 1, 1, 0, 2, 2, 0, 0, 0, 2, 3, 1, 3, 5, 3, 2,
+ -1, 1, 1, -2, 0, 3, 1, 1, -1, 0, 0, -4, -4, -1, -1, -1,
+ -1, 1, 1, 0, 1, 2, 1, 2, -3, 0, 1, 0, 1, 1, 0, 2,
+ -5, -3, -1, -1, 0, 1, 0, 1, -4, -3, -2, -3, -2, -1, -1, 0,
+ 0, 0, -1, -2, -2, -2, -2, 0, 3, 4, 2, 0, 0, 0, 0, 1,
+ 2, 1, 0, 0, 0, 0, -1, 0, 0, 1, 2, 3, 4, 4, 3, 2,
+ -1, 4, 7, 4, 0, 0, 0, 0, -1, 4, 6, 3, 0, 1, 1, 1,
+ 0, 3, 4, 0, -1, 0, 0, 1, 0, 1, 1, -2, -1, 0, -1, -1,
+ -1, 0, -1, -1, -1, 0, 0, 0, -1, -1, -1, 0, 0, 0, 0, 0,
+ -1, -3, -3, 0, 1, -1, -2, -1, -3, -4, -4, -2, -1, -2, -2, -1,
+ 2, 2, 1, 0, 1, 1, 0, -3, -2, -1, 0, 0, 1, 1, 0, -3,
+ -2, -1, 0, 1, 2, 1, 1, -2, 1, 2, 2, 2, 3, 3, 2, -1,
+ 1, 2, 1, 0, 1, 1, 2, -1, 0, 1, -2, -4, -2, 0, 1, -1,
+ 1, 1, -1, -3, -2, 0, -1, -3, 1, 2, 0, -1, 0, 1, -1, -4,
+ -1, -1, -2, -2, 0, 3, 4, 3, 1, 1, -1, -3, -2, 0, 0, 0,
+ 2, 2, 2, 2, 2, 1, -1, -1, 1, 1, 1, 3, 3, 0, -2, -2,
+ 0, -1, -1, -1, 0, -2, -1, -1, -1, -3, -4, -3, -2, -2, 0, 2,
+ -1, -1, 0, 1, 2, 2, 3, 5, -2, -1, -1, 0, 0, 0, 0, 1,
+ -2, -3, 2, 0, 0, 1, 1, -1, -1, -4, 1, -2, -1, 2, 2, 0,
+ 1, -4, 0, -2, -2, 1, 1, -1, 2, -3, 1, -1, -1, 1, 1, -1,
+ 3, -2, 3, 1, 0, 1, 1, -1, 1, -3, 2, 1, 0, 1, 0, -1,
+ -1, -5, 1, 0, -1, 0, 1, 1, 0, -3, 3, 3, 1, 2, 3, 3,
+ 0, -1, -2, 1, 5, 5, 2, -1, 1, -1, -2, -1, 1, 1, -2, -5,
+ 1, 1, -1, -2, -1, -1, -1, -3, 1, 1, -1, -1, -1, 2, 4, 3,
+ -1, -1, -1, -1, -1, 0, 4, 3, -1, -1, 0, 1, -1, -3, -1, -1,
+ 0, 0, 0, 2, 2, 0, 0, -1, 0, -2, -3, 0, 1, 1, 3, 2,
+ 2, 3, 2, 1, 0, 0, -2, -2, 2, 3, 0, 1, 1, 3, 3, 2,
+ 0, 0, -3, -1, -1, 2, 2, 3, -2, -2, -3, 1, 1, 2, 1, 1,
+ -2, -1, -2, 2, 1, 1, -1, -2, 0, 1, 0, 2, 0, 0, -2, -2,
+ 0, 1, 0, 2, 0, 0, -2, -2, -3, -2, -2, 0, -1, -2, -2, -3,
+ 0, 1, -1, 3, -1, 1, 3, -1, 0, 1, -1, 3, -1, -1, 2, -3,
+ 1, 1, -2, 3, -1, -3, 0, -3, 2, 2, -2, 3, 0, -2, 1, -2,
+ 1, 1, -3, 3, -1, -2, 1, -3, 1, 1, -3, 3, 0, -1, 1, -2,
+ 1, 2, -1, 4, 0, -1, 1, -2, 0, 1, -1, 3, -1, -3, 0, -3,
+ -3, -3, -1, 1, 2, 1, -1, -2, -2, -2, 0, 2, 1, 0, -2, -2,
+ -3, -2, 1, 2, 1, -1, -2, -1, -3, -2, 2, 4, 0, -2, -2, 1,
+ -3, -1, 2, 4, 0, -2, -2, 2, -1, 1, 4, 3, -1, -3, -2, 2,
+ 0, 2, 4, 2, -1, -2, -1, 2, 0, 1, 2, 0, -1, 0, 1, 3,
+ 3, 0, -5, 1, 4, 0, 0, 1, 1, -2, -5, 2, 5, -1, -2, 1,
+ -1, 0, 0, 3, 3, 1, 0, -1, -2, 3, 4, -2, -3, -1, 0, -2,
+ -3, 3, 5, -3, -3, 0, 0, -2, -1, 3, 2, -2, -2, 2, 2, -1,
+ 2, 0, 0, -1, 0, 0, 0, 0, 0, -3, -2, 1, 3, 0, -2, -2
};
-const uint32 *const s_svq1InterCodebooks[6] = {
+static const int8 *const s_svq1InterCodebooks[6] = {
s_svq1InterCodebook4x2, s_svq1InterCodebook4x4,
s_svq1InterCodebook8x4, s_svq1InterCodebook8x8,
0, 0
};
-static const uint32 s_svq1IntraCodebook4x2[192] = {
- 0x0b0d0d0c, 0xeff1f6f9, 0xf6f4f1f0, 0x0c0f0f0b,
- 0x0f141102, 0x0d02e8d3, 0xdcfa1415, 0xe5ff100c,
- 0x2d0aebee, 0x15f9ecf5, 0x00e4f82b, 0x03e4f021,
- 0xfaeeeef4, 0x371cf6ec, 0xeeebeefb, 0xecfa1e38,
- 0xea1d1bde, 0xe71a1de2, 0x1a21221e, 0xdfdde1e7,
- 0xe0dcdde1, 0x1f25241d, 0x2226f4b9, 0x212affc1,
- 0xc4e1253a, 0xc3df2237, 0x5d16c7c7, 0x5d15c6c7,
- 0x3e46453b, 0xc4bcbcc1, 0xc0b9b9c0, 0x3e48493f,
- 0x0f0700fe, 0x05fdf6f5, 0xf6f6f8fb, 0x090e0901,
- 0xf5fc080f, 0xf4f5020c, 0x1c1300f8, 0xe6f1ff04,
- 0xf2021bf1, 0xf70116f2, 0xf6f3fafc, 0x2f06f2fa,
- 0x1706ecdd, 0x04060906, 0xea1702fa, 0xeb1c04f9,
- 0x06feea14, 0x08fbe416, 0xf4f0eef6, 0xff021324,
- 0x080400fd, 0x1717f6d3, 0xddec0f28, 0x0104fffc,
- 0x18dffb09, 0x13e60308, 0xfd0604ff, 0xcff31920,
- 0x070f1818, 0xf9ede5ef, 0x182700d1, 0x0407faeb,
- 0xf3f600ff, 0x10050101, 0xf7fd0514, 0xfafefcff,
- 0x0401f9ef, 0x0000070c, 0x0b0c0003, 0xe90001fd,
- 0x00fa1104, 0x00e70306, 0x05080aef, 0x040104f2,
- 0x02040a0d, 0x0201f7e9, 0x0701fd03, 0x14f9e901,
- 0x0c02eef9, 0x090afcfb, 0xe8070a04, 0xf6040306,
- 0x06eaf216, 0xff050500, 0xfcf503fc, 0xf2071ff9,
- 0x2afff0fb, 0xfbf7fefc, 0xfdfaf805, 0xfbebfc2a,
- 0xf4140cee, 0x07f6f30d, 0xeefef7f8, 0x082806f0,
- 0x0400ff0a, 0xf3ff04fd, 0xf10106fe, 0x02010305,
- 0x0301fefc, 0xfcf7000f, 0xfcfcfcfd, 0xfd1005fd,
- 0x04030d02, 0x00f6f8fd, 0xfffcfefa, 0x17fafdfe,
- 0x0107fa06, 0x0105ee04, 0x0ef101ff, 0x04fc06fb,
- 0x06020202, 0x030702e8, 0x030300e6, 0x06010705,
- 0xfdeefe0e, 0x02fc0507, 0x012003fa, 0xf4fafafa,
- 0x0607dc05, 0x000bff09, 0x03050404, 0xda030f04,
- 0xd6fb170a, 0x04040400, 0xf3fa1117, 0x1d01dbf3,
- 0x01fff205, 0x01030005, 0x02fb0400, 0xf6000008,
- 0xfdfe0704, 0x010103f6, 0x030dfff4, 0xfd01ff00,
- 0x0103ff00, 0x0903f7fa, 0xfafc01fa, 0x0800ff08,
- 0x1200fdfd, 0xfffcfffb, 0xfc03fef8, 0xfbff1100,
- 0xf609fe05, 0xfb06fb01, 0x03020204, 0x01f8f20a,
- 0xffeefeff, 0x020114ff, 0x01f701ff, 0xfc16f7ff,
- 0xfd08fc06, 0x05ed07ff, 0xfcfc1ff9, 0xfbfb00fa,
- 0xfcedf8f9, 0x20040101, 0x04f8ff26, 0xf4faf8f9,
- 0x01f900ff, 0x00ff09ff, 0x00ffff09, 0xfd01fa02,
- 0x010200f4, 0x00080101, 0x02000109, 0x00f501fe,
- 0xf6020800, 0x00ff02ff, 0xfb00fcfe, 0x0efffffe,
- 0x05ff07fd, 0x0101f600, 0xff0efbff, 0xfefd01fe,
- 0x060000fa, 0x04f70302, 0xfffffb04, 0xff0803f9,
- 0xf5fffc02, 0x0001020b, 0x090302ff, 0xf1000200,
- 0x03ec0503, 0x0303ff03, 0x0110ff01, 0x0209e302,
- 0xfdfffaf3, 0xfdf8ff24, 0x02040502, 0x030b09db
+static const int8 s_svq1IntraCodebook4x2[768] = {
+ 12, 13, 13, 11, -7,-10,-15,-17,-16,-15,-12,-10, 11, 15, 15, 12,
+ 2, 17, 20, 15,-45,-24, 2, 13, 21, 20, -6,-36, 12, 16, -1,-27,
+ -18,-21, 10, 45,-11,-20, -7, 21, 43, -8,-28, 0, 33,-16,-28, 3,
+ -12,-18,-18, -6,-20,-10, 28, 55, -5,-18,-21,-18, 56, 30, -6,-20,
+ -34, 27, 29,-22,-30, 29, 26,-25, 30, 34, 33, 26,-25,-31,-35,-33,
+ -31,-35,-36,-32, 29, 36, 37, 31,-71,-12, 38, 34,-63, -1, 42, 33,
+ 58, 37,-31,-60, 55, 34,-33,-61,-57,-57, 22, 93,-57,-58, 21, 93,
+ 59, 69, 70, 62,-63,-68,-68,-60,-64,-71,-71,-64, 63, 73, 72, 62,
+ -2, 0, 7, 15,-11,-10, -3, 5, -5, -8,-10,-10, 1, 9, 14, 9,
+ 15, 8, -4,-11, 12, 2,-11,-12, -8, 0, 19, 28, 4, -1,-15,-26,
+ -15, 27, 2,-14,-14, 22, 1, -9, -4, -6,-13,-10, -6,-14, 6, 47,
+ -35,-20, 6, 23, 6, 9, 6, 4, -6, 2, 23,-22, -7, 4, 28,-21,
+ 20,-22, -2, 6, 22,-28, -5, 8,-10,-18,-16,-12, 36, 19, 2, -1,
+ -3, 0, 4, 8,-45,-10, 23, 23, 40, 15,-20,-35, -4, -1, 4, 1,
+ 9, -5,-33, 24, 8, 3,-26, 19, -1, 4, 6, -3, 32, 25,-13,-49,
+ 24, 24, 15, 7,-17,-27,-19, -7,-47, 0, 39, 24,-21, -6, 7, 4,
+ -1, 0,-10,-13, 1, 1, 5, 16, 20, 5, -3, -9, -1, -4, -2, -6,
+ -17, -7, 1, 4, 12, 7, 0, 0, 3, 0, 12, 11, -3, 1, 0,-23,
+ 4, 17, -6, 0, 6, 3,-25, 0,-17, 10, 8, 5,-14, 4, 1, 4,
+ 13, 10, 4, 2,-23, -9, 1, 2, 3, -3, 1, 7, 1,-23, -7, 20,
+ -7,-18, 2, 12, -5, -4, 10, 9, 4, 10, 7,-24, 6, 3, 4,-10,
+ 22,-14,-22, 6, 0, 5, 5, -1, -4, 3,-11, -4, -7, 31, 7,-14,
+ -5,-16, -1, 42, -4, -2, -9, -5, 5, -8, -6, -3, 42, -4,-21, -5,
+ -18, 12, 20,-12, 13,-13,-10, 7, -8, -9, -2,-18,-16, 6, 40, 8,
+ 10, -1, 0, 4, -3, 4, -1,-13, -2, 6, 1,-15, 5, 3, 1, 2,
+ -4, -2, 1, 3, 15, 0, -9, -4, -3, -4, -4, -4, -3, 5, 16, -3,
+ 2, 13, 3, 4, -3, -8,-10, 0, -6, -2, -4, -1, -2, -3, -6, 23,
+ 6, -6, 7, 1, 4,-18, 5, 1, -1, 1,-15, 14, -5, 6, -4, 4,
+ 2, 2, 2, 6,-24, 2, 7, 3,-26, 0, 3, 3, 5, 7, 1, 6,
+ 14, -2,-18, -3, 7, 5, -4, 2, -6, 3, 32, 1, -6, -6, -6,-12,
+ 5,-36, 7, 6, 9, -1, 11, 0, 4, 4, 5, 3, 4, 15, 3,-38,
+ 10, 23, -5,-42, 0, 4, 4, 4, 23, 17, -6,-13,-13,-37, 1, 29,
+ 5,-14, -1, 1, 5, 0, 3, 1, 0, 4, -5, 2, 8, 0, 0,-10,
+ 4, 7, -2, -3,-10, 3, 1, 1,-12, -1, 13, 3, 0, -1, 1, -3,
+ 0, -1, 3, 1, -6, -9, 3, 9, -6, 1, -4, -6, 8, -1, 0, 8,
+ -3, -3, 0, 18, -5, -1, -4, -1, -8, -2, 3, -4, 0, 17, -1, -5,
+ 5, -2, 9,-10, 1, -5, 6, -5, 4, 2, 2, 3, 10,-14, -8, 1,
+ -1, -2,-18, -1, -1, 20, 1, 2, -1, 1, -9, 1, -1, -9, 22, -4,
+ 6, -4, 8, -3, -1, 7,-19, 5, -7, 31, -4, -4, -6, 0, -5, -5,
+ -7, -8,-19, -4, 1, 1, 4, 32, 38, -1, -8, 4, -7, -8, -6,-12,
+ -1, 0, -7, 1, -1, 9, -1, 0, 9, -1, -1, 0, 2, -6, 1, -3,
+ -12, 0, 2, 1, 1, 1, 8, 0, 9, 1, 0, 2, -2, 1,-11, 0,
+ 0, 8, 2,-10, -1, 2, -1, 0, -2, -4, 0, -5, -2, -1, -1, 14,
+ -3, 7, -1, 5, 0,-10, 1, 1, -1, -5, 14, -1, -2, 1, -3, -2,
+ -6, 0, 0, 6, 2, 3, -9, 4, 4, -5, -1, -1, -7, 3, 8, -1,
+ 2, -4, -1,-11, 11, 2, 1, 0, -1, 2, 3, 9, 0, 2, 0,-15,
+ 3, 5,-20, 3, 3, -1, 3, 3, 1, -1, 16, 1, 2,-29, 9, 2,
+ -13, -6, -1, -3, 36, -1, -8, -3, 2, 5, 4, 2,-37, 9, 11, 3
};
-static const uint32 s_svq1IntraCodebook4x4[384] = {
- 0x0603fdf5, 0x0705fff6, 0x0706fff7, 0x0604fff7,
- 0xf2000705, 0xf1020906, 0xf1020906, 0xf2000604,
- 0xfafb0310, 0xf8f80110, 0xf7f7ff0e, 0xf8f8000c,
- 0x11100c08, 0x090602fe, 0x00fcf8f6, 0xf9f5f2f1,
- 0x10fef6f9, 0x12fdf5f9, 0x14fff5f9, 0x1301f8fa,
- 0xeff0f3f7, 0xf7f9fe02, 0xff04080b, 0x070b0f10,
- 0x0f0dfeea, 0x100efee8, 0x0f0dfce7, 0x0d0afae7,
- 0x10161a1a, 0x03090f11, 0xf2f5fafe, 0xe4e4e7ec,
- 0xebe7e5e5, 0xf9f5f1f0, 0x0d0c0803, 0x1e1f1c17,
- 0xdff91014, 0xddfa1316, 0xdefa1316, 0xe0fa1114,
- 0x2602ecec, 0x2802eaeb, 0x2802eaeb, 0x2603ecec,
- 0x1a18fcd1, 0x1b1afdce, 0x1b1afdce, 0x1a18fcd1,
- 0xe5e9062d, 0xe4e70530, 0xe4e60530, 0xe5e8062c,
- 0x4cf6dce2, 0x4ef5dbe1, 0x4ef5dbe1, 0x4df6dce1,
- 0x3423e0cb, 0x3424deca, 0x3424deca, 0x3322dfcb,
- 0x413edea3, 0x423edea3, 0x413edea3, 0x403cdea3,
- 0x020200f9, 0x0303fff8, 0x050400f8, 0x050501fa,
- 0x0b0b0703, 0x03030202, 0xf9fafe01, 0xf3f5fb01,
- 0xfdfcfe03, 0xfbfb0007, 0xf9fb040c, 0xf9fc060e,
- 0xfe030e12, 0xfd000406, 0x00fefbf8, 0x02fef5f0,
- 0x1207faf8, 0x0d02f8f9, 0x06fefafc, 0x01fdfc00,
- 0xeef3fd01, 0xf9fbff00, 0x070601ff, 0x110f04fe,
- 0xfef9f2f1, 0x00fffbfa, 0x01030606, 0x01060d0f,
- 0x0af5fe02, 0x0bf4ff02, 0x0bf4ff03, 0x0bf5fe02,
- 0xfbff0ef7, 0xfbfe0ff7, 0xfbfe10f8, 0xfcff0ff9,
- 0x08080602, 0x0c0903fe, 0x0a04fbf5, 0x00f8f0ed,
- 0xf1f9080e, 0xf2f9070c, 0xf7fc0508, 0xfcff0305,
- 0x02fef20c, 0x03fff10d, 0x03fff10e, 0x03fff20d,
- 0xf30a0600, 0xf10a0600, 0xef090700, 0xf0080601,
- 0xfe0ffbf8, 0xfe11faf8, 0xfd10faf8, 0xfe0ffbf8,
- 0xf6f5f5f7, 0x08090a09, 0x090a0a08, 0xf9f8f7f8,
- 0x07090a09, 0xf6f6f6f8, 0xf5f5f6f9, 0x080b0c0b,
- 0x00070a00, 0xfa000700, 0xfafb0200, 0xfffcfffe,
- 0xf7fa0005, 0x01020202, 0x070500fe, 0x0401fbfa,
- 0xff02f803, 0x0003f704, 0x0003f905, 0x0003fb07,
- 0x0902fdfb, 0x0801fdfa, 0x0701fdfa, 0x0400fefb,
- 0x0103080d, 0xfffcfbfd, 0x00fdf9f8, 0x020301ff,
- 0xf4fb0203, 0xf7fe0304, 0xfc010403, 0xff040503,
- 0x00fcf8f7, 0x00020608, 0x0003080a, 0xfffdfbfa,
- 0xfbf4f7fd, 0x00fbfd00, 0x04020302, 0x06070805,
- 0x0c05feff, 0x0905ffff, 0xfeff0102, 0xeff5ff02,
- 0xff0303f9, 0xff0403f7, 0xff0604f6, 0x000705f7,
- 0x0202f9ee, 0x030501f8, 0x00010403, 0xfdfe0509,
- 0x080600fe, 0xfdfbfbfc, 0xf8fafe01, 0xff03090a,
- 0x00fefe00, 0x00fbfc00, 0x08fcf8fe, 0x1806f9fb,
- 0x01f90109, 0x01f80109, 0x01f60008, 0xfff5ff08,
- 0x03060808, 0x02030405, 0x00fffdfe, 0xfcf8f3f6,
- 0xfd020400, 0xfb030600, 0xf4020a03, 0xeafc0a05,
- 0x03fffc00, 0x05fffc01, 0x0800fb01, 0x07fefaff,
- 0xfcfeffff, 0xfafcfeff, 0xfeffffff, 0x090a0501,
- 0xfe00030a, 0xfbfeff06, 0xfafeff03, 0xfb000002,
- 0x00000306, 0x01010306, 0x01fefe04, 0xfef7f700,
- 0x0201fdf5, 0x050402fa, 0x040302fd, 0x020101fe,
- 0xfefffcfa, 0xfeffff02, 0xfefe020a, 0xfffc020b,
- 0x02fe0006, 0x00000303, 0x000303fa, 0x0005ffef,
- 0x0b0a04ff, 0x0100fefd, 0xfdfbfcfd, 0xfffefeff,
- 0xf4f7fd02, 0x02030303, 0x04040202, 0xfeff0102,
- 0xf60509fe, 0xfb0505fd, 0x000201fe, 0x01fefeff,
- 0xfe07fdfe, 0xfd07fdff, 0xfc08feff, 0xfd07fefe,
- 0x0cfdf801, 0x04fefe02, 0xfb000301, 0xf90205ff,
- 0xfb0103ff, 0x0103fef9, 0x02fef9fe, 0xfffb0314,
- 0xfefd0005, 0x0600f9f9, 0x060700fa, 0xf9000602,
- 0x01f906fe, 0x03f807fe, 0x03f907fe, 0x02fa07ff,
- 0x0705fefb, 0xf8fc0104, 0xfbfe0306, 0x0703fbf9,
- 0x0506ffff, 0xfc01ff00, 0xf9000102, 0xfc000001,
- 0x010300f8, 0xffff01fe, 0x01fdff01, 0x0901fe01,
- 0xfcfd0205, 0xfdff00ff, 0x010301fd, 0x020400fc,
- 0x0cfefe02, 0x03fbfe00, 0x01fd00ff, 0x01fefffd,
- 0x00030501, 0x01fefcfa, 0x02fefe00, 0xfffc0106,
- 0xfffbfbfd, 0x04050503, 0xff010300, 0xfdfe01fe,
- 0xfdfbfc02, 0xfefdfe04, 0xffff0006, 0x00000107,
- 0x00fefefd, 0xfffbfdfe, 0xff0002fe, 0xff090bff,
- 0xf6ff0100, 0xfa0001ff, 0x04010001, 0x0dfffb02,
- 0x000504fe, 0x030601fb, 0x0203fefa, 0xfe00fefb,
- 0xfe0101ff, 0x0200feff, 0x07050505, 0xf9f8fc00,
- 0xfbff0200, 0xfd0202ff, 0xfb030500, 0xf4020803,
- 0xfe000408, 0xfffcff0a, 0x00fdfa03, 0x0000fbfc,
- 0x02fcf600, 0x0503faff, 0x0406fdff, 0x0204fe00,
- 0xff010800, 0xfd010b00, 0xfcfe06ff, 0xfcf9fefd,
- 0xffffff00, 0x05060504, 0xfbf8f7fb, 0x02030202,
- 0x01060200, 0x00030002, 0xfefffe01, 0xfafdff00,
- 0x00020000, 0x01020004, 0x0000fe05, 0x02fff7fe,
- 0xf6000100, 0x000801ff, 0x0004feff, 0xff02ff01,
- 0xff02fefd, 0xfd02fffd, 0x0001ff00, 0x03ff0108,
- 0x02010100, 0x00fefc00, 0xff01fbff, 0x020bfffe,
- 0xfefe0501, 0x00fc0200, 0x01fb01fe, 0x01000500,
- 0x0600fdfb, 0x000002fc, 0x000105fd, 0x000003fd,
- 0x01fdfe03, 0x0800fc01, 0x03fefdfe, 0xffff0201,
- 0x02000101, 0x06010002, 0x0102ff01, 0xed000300,
- 0x02fefd01, 0xf9fe0506, 0x010301fd, 0x0200ffff,
- 0xfcfffff8, 0x02ff0101, 0x03020304, 0x000301fb,
- 0x01ff0200, 0x050000fd, 0x0800fefb, 0x06fcfcfc,
- 0x02010201, 0x02fd0202, 0x00f70004, 0x01f50007,
- 0xfe000000, 0xfaff0303, 0xf6fd0304, 0x020602ff,
- 0x05fdfe07, 0xff0300fc, 0xf90102fc, 0x03ffff02,
- 0x02020203, 0xfbf9f9fb, 0x02040605, 0x0100fffe
+static const int8 s_svq1IntraCodebook4x4[1536] = {
+ -11, -3, 3, 6,-10, -1, 5, 7, -9, -1, 6, 7, -9, -1, 4, 6,
+ 5, 7, 0,-14, 6, 9, 2,-15, 6, 9, 2,-15, 4, 6, 0,-14,
+ 16, 3, -5, -6, 16, 1, -8, -8, 14, -1, -9, -9, 12, 0, -8, -8,
+ 8, 12, 16, 17, -2, 2, 6, 9,-10, -8, -4, 0,-15,-14,-11, -7,
+ -7,-10, -2, 16, -7,-11, -3, 18, -7,-11, -1, 20, -6, -8, 1, 19,
+ -9,-13,-16,-17, 2, -2, -7, -9, 11, 8, 4, -1, 16, 15, 11, 7,
+ -22, -2, 13, 15,-24, -2, 14, 16,-25, -4, 13, 15,-25, -6, 10, 13,
+ 26, 26, 22, 16, 17, 15, 9, 3, -2, -6,-11,-14,-20,-25,-28,-28,
+ -27,-27,-25,-21,-16,-15,-11, -7, 3, 8, 12, 13, 23, 28, 31, 30,
+ 20, 16, -7,-33, 22, 19, -6,-35, 22, 19, -6,-34, 20, 17, -6,-32,
+ -20,-20, 2, 38,-21,-22, 2, 40,-21,-22, 2, 40,-20,-20, 3, 38,
+ -47, -4, 24, 26,-50, -3, 26, 27,-50, -3, 26, 27,-47, -4, 24, 26,
+ 45, 6,-23,-27, 48, 5,-25,-28, 48, 5,-26,-28, 44, 6,-24,-27,
+ -30,-36,-10, 76,-31,-37,-11, 78,-31,-37,-11, 78,-31,-36,-10, 77,
+ -53,-32, 35, 52,-54,-34, 36, 52,-54,-34, 36, 52,-53,-33, 34, 51,
+ -93,-34, 62, 65,-93,-34, 62, 66,-93,-34, 62, 65,-93,-34, 60, 64,
+ -7, 0, 2, 2, -8, -1, 3, 3, -8, 0, 4, 5, -6, 1, 5, 5,
+ 3, 7, 11, 11, 2, 2, 3, 3, 1, -2, -6, -7, 1, -5,-11,-13,
+ 3, -2, -4, -3, 7, 0, -5, -5, 12, 4, -5, -7, 14, 6, -4, -7,
+ 18, 14, 3, -2, 6, 4, 0, -3, -8, -5, -2, 0,-16,-11, -2, 2,
+ -8, -6, 7, 18, -7, -8, 2, 13, -4, -6, -2, 6, 0, -4, -3, 1,
+ 1, -3,-13,-18, 0, -1, -5, -7, -1, 1, 6, 7, -2, 4, 15, 17,
+ -15,-14, -7, -2, -6, -5, -1, 0, 6, 6, 3, 1, 15, 13, 6, 1,
+ 2, -2,-11, 10, 2, -1,-12, 11, 3, -1,-12, 11, 2, -2,-11, 11,
+ -9, 14, -1, -5, -9, 15, -2, -5, -8, 16, -2, -5, -7, 15, -1, -4,
+ 2, 6, 8, 8, -2, 3, 9, 12,-11, -5, 4, 10,-19,-16, -8, 0,
+ 14, 8, -7,-15, 12, 7, -7,-14, 8, 5, -4, -9, 5, 3, -1, -4,
+ 12,-14, -2, 2, 13,-15, -1, 3, 14,-15, -1, 3, 13,-14, -1, 3,
+ 0, 6, 10,-13, 0, 6, 10,-15, 0, 7, 9,-17, 1, 6, 8,-16,
+ -8, -5, 15, -2, -8, -6, 17, -2, -8, -6, 16, -3, -8, -5, 15, -2,
+ -9,-11,-11,-10, 9, 10, 9, 8, 8, 10, 10, 9, -8, -9, -8, -7,
+ 9, 10, 9, 7, -8,-10,-10,-10, -7,-10,-11,-11, 11, 12, 11, 8,
+ 0, 10, 7, 0, 0, 7, 0, -6, 0, 2, -5, -6, -2, -1, -4, -1,
+ 5, 0, -6, -9, 2, 2, 2, 1, -2, 0, 5, 7, -6, -5, 1, 4,
+ 3, -8, 2, -1, 4, -9, 3, 0, 5, -7, 3, 0, 7, -5, 3, 0,
+ -5, -3, 2, 9, -6, -3, 1, 8, -6, -3, 1, 7, -5, -2, 0, 4,
+ 13, 8, 3, 1, -3, -5, -4, -1, -8, -7, -3, 0, -1, 1, 3, 2,
+ 3, 2, -5,-12, 4, 3, -2, -9, 3, 4, 1, -4, 3, 5, 4, -1,
+ -9, -8, -4, 0, 8, 6, 2, 0, 10, 8, 3, 0, -6, -5, -3, -1,
+ -3, -9,-12, -5, 0, -3, -5, 0, 2, 3, 2, 4, 5, 8, 7, 6,
+ -1, -2, 5, 12, -1, -1, 5, 9, 2, 1, -1, -2, 2, -1,-11,-17,
+ -7, 3, 3, -1, -9, 3, 4, -1,-10, 4, 6, -1, -9, 5, 7, 0,
+ -18, -7, 2, 2, -8, 1, 5, 3, 3, 4, 1, 0, 9, 5, -2, -3,
+ -2, 0, 6, 8, -4, -5, -5, -3, 1, -2, -6, -8, 10, 9, 3, -1,
+ 0, -2, -2, 0, 0, -4, -5, 0, -2, -8, -4, 8, -5, -7, 6, 24,
+ 9, 1, -7, 1, 9, 1, -8, 1, 8, 0,-10, 1, 8, -1,-11, -1,
+ 8, 8, 6, 3, 5, 4, 3, 2, -2, -3, -1, 0,-10,-13, -8, -4,
+ 0, 4, 2, -3, 0, 6, 3, -5, 3, 10, 2,-12, 5, 10, -4,-22,
+ 0, -4, -1, 3, 1, -4, -1, 5, 1, -5, 0, 8, -1, -6, -2, 7,
+ -1, -1, -2, -4, -1, -2, -4, -6, -1, -1, -1, -2, 1, 5, 10, 9,
+ 10, 3, 0, -2, 6, -1, -2, -5, 3, -1, -2, -6, 2, 0, 0, -5,
+ 6, 3, 0, 0, 6, 3, 1, 1, 4, -2, -2, 1, 0, -9, -9, -2,
+ -11, -3, 1, 2, -6, 2, 4, 5, -3, 2, 3, 4, -2, 1, 1, 2,
+ -6, -4, -1, -2, 2, -1, -1, -2, 10, 2, -2, -2, 11, 2, -4, -1,
+ 6, 0, -2, 2, 3, 3, 0, 0, -6, 3, 3, 0,-17, -1, 5, 0,
+ -1, 4, 10, 11, -3, -2, 0, 1, -3, -4, -5, -3, -1, -2, -2, -1,
+ 2, -3, -9,-12, 3, 3, 3, 2, 2, 2, 4, 4, 2, 1, -1, -2,
+ -2, 9, 5,-10, -3, 5, 5, -5, -2, 1, 2, 0, -1, -2, -2, 1,
+ -2, -3, 7, -2, -1, -3, 7, -3, -1, -2, 8, -4, -2, -2, 7, -3,
+ 1, -8, -3, 12, 2, -2, -2, 4, 1, 3, 0, -5, -1, 5, 2, -7,
+ -1, 3, 1, -5, -7, -2, 3, 1, -2, -7, -2, 2, 20, 3, -5, -1,
+ 5, 0, -3, -2, -7, -7, 0, 6, -6, 0, 7, 6, 2, 6, 0, -7,
+ -2, 6, -7, 1, -2, 7, -8, 3, -2, 7, -7, 3, -1, 7, -6, 2,
+ -5, -2, 5, 7, 4, 1, -4, -8, 6, 3, -2, -5, -7, -5, 3, 7,
+ -1, -1, 6, 5, 0, -1, 1, -4, 2, 1, 0, -7, 1, 0, 0, -4,
+ -8, 0, 3, 1, -2, 1, -1, -1, 1, -1, -3, 1, 1, -2, 1, 9,
+ 5, 2, -3, -4, -1, 0, -1, -3, -3, 1, 3, 1, -4, 0, 4, 2,
+ 2, -2, -2, 12, 0, -2, -5, 3, -1, 0, -3, 1, -3, -1, -2, 1,
+ 1, 5, 3, 0, -6, -4, -2, 1, 0, -2, -2, 2, 6, 1, -4, -1,
+ -3, -5, -5, -1, 3, 5, 5, 4, 0, 3, 1, -1, -2, 1, -2, -3,
+ 2, -4, -5, -3, 4, -2, -3, -2, 6, 0, -1, -1, 7, 1, 0, 0,
+ -3, -2, -2, 0, -2, -3, -5, -1, -2, 2, 0, -1, -1, 11, 9, -1,
+ 0, 1, -1,-10, -1, 1, 0, -6, 1, 0, 1, 4, 2, -5, -1, 13,
+ -2, 4, 5, 0, -5, 1, 6, 3, -6, -2, 3, 2, -5, -2, 0, -2,
+ -1, 1, 1, -2, -1, -2, 0, 2, 5, 5, 5, 7, 0, -4, -8, -7,
+ 0, 2, -1, -5, -1, 2, 2, -3, 0, 5, 3, -5, 3, 8, 2,-12,
+ 8, 4, 0, -2, 10, -1, -4, -1, 3, -6, -3, 0, -4, -5, 0, 0,
+ 0,-10, -4, 2, -1, -6, 3, 5, -1, -3, 6, 4, 0, -2, 4, 2,
+ 0, 8, 1, -1, 0, 11, 1, -3, -1, 6, -2, -4, -3, -2, -7, -4,
+ 0, -1, -1, -1, 4, 5, 6, 5, -5, -9, -8, -5, 2, 2, 3, 2,
+ 0, 2, 6, 1, 2, 0, 3, 0, 1, -2, -1, -2, 0, -1, -3, -6,
+ 0, 0, 2, 0, 4, 0, 2, 1, 5, -2, 0, 0, -2, -9, -1, 2,
+ 0, 1, 0,-10, -1, 1, 8, 0, -1, -2, 4, 0, 1, -1, 2, -1,
+ -3, -2, 2, -1, -3, -1, 2, -3, 0, -1, 1, 0, 8, 1, -1, 3,
+ 0, 1, 1, 2, 0, -4, -2, 0, -1, -5, 1, -1, -2, -1, 11, 2,
+ 1, 5, -2, -2, 0, 2, -4, 0, -2, 1, -5, 1, 0, 5, 0, 1,
+ -5, -3, 0, 6, -4, 2, 0, 0, -3, 5, 1, 0, -3, 3, 0, 0,
+ 3, -2, -3, 1, 1, -4, 0, 8, -2, -3, -2, 3, 1, 2, -1, -1,
+ 1, 1, 0, 2, 2, 0, 1, 6, 1, -1, 2, 1, 0, 3, 0,-19,
+ 1, -3, -2, 2, 6, 5, -2, -7, -3, 1, 3, 1, -1, -1, 0, 2,
+ -8, -1, -1, -4, 1, 1, -1, 2, 4, 3, 2, 3, -5, 1, 3, 0,
+ 0, 2, -1, 1, -3, 0, 0, 5, -5, -2, 0, 8, -4, -4, -4, 6,
+ 1, 2, 1, 2, 2, 2, -3, 2, 4, 0, -9, 0, 7, 0,-11, 1,
+ 0, 0, 0, -2, 3, 3, -1, -6, 4, 3, -3,-10, -1, 2, 6, 2,
+ 7, -2, -3, 5, -4, 0, 3, -1, -4, 2, 1, -7, 2, -1, -1, 3,
+ 3, 2, 2, 2, -5, -7, -7, -5, 5, 6, 4, 2, -2, -1, 0, 1
};
-static const uint32 s_svq1IntraCodebook8x4[768] = {
- 0x06060605, 0x08080707, 0x00000000, 0x03020100,
- 0xfbfcfcfd, 0xfefdfcfb, 0xfbfcfcfc, 0xfdfdfcfc,
- 0x02020201, 0x03030302, 0x04030302, 0x05050504,
- 0x010100ff, 0x04040302, 0xf7f7f6f7, 0xfbfaf9f8,
- 0xfafbfcfc, 0xf9f9f9fa, 0xfefeff00, 0xfcfcfdfd,
- 0x03030404, 0x00010102, 0x06070707, 0x04040506,
- 0x06050402, 0xfafd0104, 0x05050403, 0xf8fb0004,
- 0x04040302, 0xf6f9fe02, 0x01020202, 0xf4f7fc00,
- 0x01fdf9f7, 0x03030404, 0x03fef9f6, 0x03030505,
- 0x03fefaf7, 0x03040506, 0x03fffaf8, 0x02030404,
- 0xfbfbfbfb, 0x070401fd, 0xfcfbfbfb, 0x080601fe,
- 0xfdfcfbfc, 0x0a0803ff, 0xfefdfcfd, 0x0b090501,
- 0xfefefefe, 0xfefefefe, 0xfbfbfbfc, 0xfcfbfbfb,
- 0xfcfcfcfd, 0xfdfcfcfc, 0x0b0a0a09, 0x0a0a0b0b,
- 0xfe010407, 0xf6f7fafc, 0x00030709, 0xf7f8fcfe,
- 0x0204080b, 0xf8fafd00, 0x0305090b, 0xf9fbfe01,
- 0xf4f3f3f3, 0xf8f8f6f5, 0x03020100, 0x03040404,
- 0x06050403, 0x04050606, 0x04040403, 0x02030303,
- 0x0a0b0a0a, 0x07080909, 0x06060606, 0x02030405,
- 0xff000000, 0xfcfcfdfe, 0xf4f5f6f6, 0xf2f2f2f3,
- 0x10111010, 0x0b0c0d0f, 0xfcfdfeff, 0xfdfcfcfc,
- 0xfafafbfc, 0xfafafafa, 0xfafafafb, 0xfbfbfafa,
- 0xf4f3f3f3, 0xfaf8f6f5, 0xfaf9f8f7, 0x0100fefc,
- 0x0301fffe, 0x09080705, 0x0b090705, 0x0f0f0e0d,
- 0x070b0e10, 0xf7f9fd02, 0x03080c0e, 0xf5f7faff,
- 0x0004090b, 0xf3f5f8fc, 0xfd010508, 0xf2f4f6fa,
- 0xfdf7f1ee, 0x0b090601, 0xfff9f3ef, 0x0c0b0703,
- 0x01fbf5f1, 0x0d0c0905, 0x02fdf7f3, 0x0d0b0905,
- 0x0f131516, 0xf7fc030a, 0x090f1214, 0xeff4fb02,
- 0x01080d10, 0xe8ecf2f9, 0xf8ff060a, 0xe5e7ebf1,
- 0xf2ece9e7, 0x0e0901f9, 0xf7f0ebe9, 0x15100900,
- 0xfff6f0ec, 0x19161008, 0x06fdf5f1, 0x1b19140e,
- 0x0100fefc, 0x02020202, 0x0200fefb, 0x03030303,
- 0x01fffcfa, 0x03030302, 0x00fefbf9, 0x02020101,
- 0x01010102, 0xfdfe0001, 0x01020303, 0xfcfdff00,
- 0x01020304, 0xfafcfe00, 0x01030405, 0xfafbfdff,
- 0x04060605, 0xfdfe0002, 0x04040403, 0xff000103,
- 0xfffffefe, 0xfefeffff, 0xfefdfcfb, 0xfdfdfefe,
- 0xffffffff, 0xffffffff, 0xfcfcfcfd, 0xfdfdfdfd,
- 0xffffffff, 0xfeffffff, 0x06060605, 0x03040506,
- 0x04040404, 0x07060504, 0xffffff00, 0x020100ff,
- 0xfdfdfdfe, 0x00fffefd, 0xfcfcfdfd, 0xfffefdfc,
- 0xfcfcfe00, 0x030200fe, 0xfdfdfe00, 0x050402ff,
- 0xfdfcfeff, 0x06050300, 0xfdfcfdfe, 0x050402ff,
- 0xfd000409, 0x0100fffd, 0xfcff0408, 0x0201fffd,
- 0xfbfd0206, 0x0100fefc, 0xfcfd0105, 0x0100fefc,
- 0xff010305, 0xf6f6f8fc, 0x01020303, 0xfcfdfe00,
- 0x02010101, 0x00010203, 0x020100ff, 0x02030403,
- 0x02020100, 0xfdfdff01, 0x01010100, 0xfdfcfeff,
- 0xfdfdfdfd, 0x02fffdfd, 0x00fdfcfc, 0x0e0c0703,
- 0xfafafbfb, 0xfbfafafa, 0x01020202, 0x00000000,
- 0x02030404, 0x00000001, 0x04050606, 0x01010202,
- 0xfdfaf9f9, 0x08070400, 0xfdfdfeff, 0x0201fffe,
- 0xff010303, 0xfffefefe, 0x02040606, 0xfefefe00,
- 0x02fefbfa, 0x0c0b0905, 0x00fefcfc, 0x06050402,
- 0xfefefefd, 0x0100fffe, 0xfdfefefe, 0xfefdfdfd,
- 0x0301fdf9, 0xfbfd0003, 0x0503fefa, 0xfbfd0104,
- 0x0604fffb, 0xfcfd0205, 0x070500fc, 0xfdff0306,
- 0x00000000, 0x00000000, 0xfdfdfefe, 0xfffefdfd,
- 0x09080706, 0x06070809, 0xfbfbfcfc, 0xfcfbfafa,
- 0xfcfaf8f7, 0x06060300, 0x03fffcfb, 0x03050605,
- 0x06060301, 0xfbfe0104, 0x01050706, 0xf5f6f9fd,
- 0x0105090a, 0xfcfafafd, 0xfbff0305, 0x02fefbfa,
- 0xfafafcfe, 0x0a0601fc, 0xfcf9f9fa, 0x0c0b0701,
- 0x02030506, 0x00000000, 0xfeff0102, 0xfffffefd,
- 0xfcfeff00, 0x01fffefc, 0xfeff0000, 0x030200ff,
- 0xfefeff00, 0xfffffefe, 0x01020405, 0x00000000,
- 0x01030506, 0x00000000, 0xfcfe0002, 0xfefefdfc,
- 0x0200fcf9, 0x01020202, 0x0000fdf9, 0x00000000,
- 0x0101fffc, 0x01000000, 0x020201ff, 0x03030202,
- 0x020200fe, 0x01010101, 0x020201ff, 0xff000001,
- 0x02040200, 0xfdfeff00, 0x01030201, 0xfafafcfe,
- 0x04020201, 0x01040605, 0xffffff00, 0xfcfe0000,
- 0xfeff0000, 0xfafcfefe, 0x00000102, 0xfdff0101,
- 0x01010101, 0x03030201, 0x00010000, 0x04040201,
- 0xffffffff, 0x03020100, 0xfbfbfcfc, 0x00fffdfb,
- 0xfcfbfbfa, 0xfffffefd, 0x010000ff, 0x03030201,
- 0x01010100, 0x04030202, 0xffff0000, 0x03020100,
- 0x01010100, 0xffff0000, 0x02030301, 0xfefeff01,
- 0x020200fe, 0x01010202, 0xfefcf8f7, 0x03030301,
- 0xfeffffff, 0xfcfdfdfd, 0xff000000, 0xfdfdfefe,
- 0x00020202, 0xffffffff, 0x03040505, 0x02020202,
- 0xfcff0306, 0x0101fffd, 0xfcfdff02, 0x000202ff,
- 0x01fefeff, 0xfd010404, 0x0401fffe, 0xf8fd0306,
- 0x01020303, 0xfefefeff, 0xfffefcfc, 0x04040301,
- 0xfcfbfbfc, 0x020200fe, 0x01040707, 0xfefdfeff,
- 0x000301ff, 0x0600fafc, 0x010401fe, 0x07fffafc,
- 0x020401fd, 0x06fffafd, 0x020300fe, 0x04fffbfe,
- 0x01feff01, 0xf9ff0404, 0xfffcff01, 0xfa000605,
- 0xfdfc0003, 0xfc020603, 0xfcfb0003, 0xfd010401,
- 0x03030202, 0x02020303, 0xf9fafbfc, 0xfaf9f9f9,
- 0x03030201, 0x02020303, 0x01010000, 0x01020201,
- 0x03fdfd03, 0x02fefe04, 0x04fcfc03, 0x02fcfc04,
- 0x04fcfc04, 0x03fdfc04, 0x03fcfd03, 0x03fdfd03,
- 0xfefefefe, 0xfffffefe, 0x08080706, 0x05060708,
- 0xf9f9fafb, 0xfbfaf9f8, 0x02020101, 0x01010202,
- 0x00000000, 0x0000ff00, 0x000000ff, 0x0000ff00,
- 0xfefefdfe, 0xfdfdfdfe, 0x06050302, 0x00010204,
- 0x00020608, 0x00000000, 0x00000104, 0xffffff00,
- 0x0000ff01, 0xfdfeff00, 0x00fffefe, 0xfbfcfe00,
- 0xfeff0103, 0xfbfbfcfd, 0x00000102, 0x00000101,
- 0x00ffff00, 0x02020202, 0x01fffeff, 0x02020202,
- 0xfffeff00, 0x00ffffff, 0xfffefeff, 0x010000ff,
- 0x02010102, 0x00010102, 0x01030506, 0xfcfcfe00,
- 0x00fffefd, 0xff000101, 0x04030100, 0x01030505,
- 0x00ffffff, 0xfeff0001, 0xfffefefe, 0xfdfeff00,
- 0xfefeff00, 0x0200ffff, 0xfffeff01, 0x0200ffff,
- 0xfefe0001, 0x0501fefe, 0xfefeff01, 0x0a0500fe,
- 0x00000000, 0xffffff00, 0x00ffffff, 0x02010000,
- 0x03020201, 0x05060404, 0xfefdfdfd, 0xfdfdfdfe,
- 0xfefeff01, 0x07050300, 0xfdfe0002, 0x030200fe,
- 0xfdfe0103, 0xfffffefd, 0xff000103, 0xffffffff,
- 0x04050301, 0xfcfdff02, 0x0201fefd, 0xfeff0001,
- 0x0200fdfb, 0x00000102, 0x0201fffd, 0x00000102,
- 0xffffff00, 0x04030201, 0xfdfcfcfd, 0x010000ff,
- 0xfffefdfe, 0x01010101, 0x0300fefe, 0x02030404,
- 0xfefdfcfc, 0x030201ff, 0x01010100, 0xfdfdfeff,
- 0x04050403, 0xfdfdff02, 0x0200fefe, 0x00010202,
- 0x070500fc, 0xfcfcff04, 0x030402ff, 0xfefdfd00,
- 0xff000102, 0x0100fefe, 0xfeff0000, 0x0201fffe,
- 0xfffefdfc, 0x02020100, 0x0005090a, 0xfefdfcfd,
- 0xfefeff01, 0x000000ff, 0x01fffefe, 0xff000101,
- 0x0300fdfb, 0xfe000204, 0x0100fffe, 0xffff0001,
- 0xfeff0203, 0x0101fffe, 0xfbff0507, 0x0402fefa,
- 0xfd0303fe, 0xfe0201fc, 0xfd0403fd, 0xfe0302fc,
- 0xfd0403fd, 0xfe0302fc, 0xfe0402fc, 0xff0201fd,
- 0xfdff0304, 0x0201fffd, 0x00fcfafc, 0x01040504,
- 0x06050200, 0xfcfbfd02, 0xfdff0101, 0x0402fefb,
- 0x020100ff, 0x04030302, 0x010100ff, 0xffffff00,
- 0x020100ff, 0xfeff0102, 0x00fffefd, 0xfdfeff00,
- 0x01010101, 0x02010000, 0x00ff0001, 0x00010100,
- 0xfffcfe01, 0x00010201, 0xfdf9fc01, 0x01020301,
- 0x01010101, 0xff000101, 0x00010101, 0x00020201,
- 0x00000101, 0xfd000200, 0xff000203, 0xf7fafeff,
- 0x01000000, 0x02010000, 0x00000001, 0x0200ffff,
- 0x01010100, 0x00fefdff, 0x0601fbf9, 0xffff0206,
- 0xfdff0103, 0x0401fefc, 0xfdfe0002, 0x02fffdfc,
- 0x01010202, 0x01000001, 0x00000101, 0x01000000,
- 0xfe0101ff, 0xfffcfafb, 0x030401ff, 0x02010002,
- 0x030200ff, 0x01000001, 0x000100ff, 0x00ffff00,
- 0x02020100, 0x01fffe00, 0xfefffffe, 0x080602ff,
- 0xfdfeffff, 0x020100fe, 0xff0000ff, 0xffff00ff,
- 0x01010102, 0x00000001, 0x01010000, 0x01ffff01,
- 0x020200ff, 0x03fefdff, 0x00030200, 0x04fef9fb,
- 0x000000ff, 0xfdfdfeff, 0xfeff00ff, 0xfefefefe,
- 0x00000101, 0xff000201, 0x02010201, 0x00020605,
- 0x00fdfcfe, 0xfd000202, 0x01000103, 0xfdfe0102,
- 0x00000103, 0xff000000, 0xfefeff01, 0x030301ff,
- 0x02010203, 0xfe010304, 0xfdfcfcfe, 0xfdfe00ff,
- 0xffff0001, 0xff000100, 0x00000203, 0x00010100,
- 0x00000101, 0x00000000, 0x02030302, 0x01010202,
- 0xfdfeff00, 0xfcfbfbfb, 0xff000101, 0x03030100,
- 0x00fefaf7, 0x02020101, 0x0201fefa, 0x01000101,
- 0x020201fe, 0x01010101, 0x01020200, 0x01010100,
- 0x00000001, 0x00ff0000, 0x00000000, 0x00fefdff,
- 0xfefdfdfd, 0x090703ff, 0x02020201, 0xfdfcfe00,
- 0xfffe0002, 0xfaff0403, 0xfdfe0001, 0x000303ff,
- 0x00030300, 0x0101fffe, 0x0203fffa, 0x0100feff,
- 0xfe000305, 0x010200fd, 0x02020101, 0xf9fcfe00,
- 0x0201fefd, 0xfcff0102, 0xfe000202, 0x020200fe,
- 0xfdfe0000, 0x0000fffe, 0x00000000, 0x02020000,
- 0x0100fffe, 0x03020100, 0x0000fefc, 0x030200ff,
- 0xfffefefe, 0x040200ff, 0x00000000, 0x0100ffff,
- 0xffffff00, 0x0000ffff, 0x00020406, 0xfffffeff,
- 0x01010100, 0xf6fbff01, 0x01010101, 0xfc000101,
- 0x01010001, 0xff010101, 0x01010102, 0x00000000,
- 0x030401fd, 0x00ff0103, 0x000100fc, 0x000000ff,
- 0x010200fb, 0xff000101, 0xfe0102ff, 0xff00fffe,
- 0x03050402, 0x0201ff00, 0x00010000, 0xfffffefe,
- 0xfefefefe, 0x00fffefd, 0x00010000, 0x02010000,
- 0xfdfefe00, 0xff0202ff, 0x00000001, 0xfe030501,
- 0xff00ffff, 0xfb000200, 0x000100ff, 0xfe020200,
- 0xffff0103, 0x02010100, 0x01000001, 0x01010101,
- 0x01fef8f6, 0x01010102, 0x010201ff, 0x00000000,
- 0x0100ffff, 0x01020202, 0x00ffffff, 0xfcfbfdff,
- 0x01020101, 0x02000001, 0xfffffeff, 0x040200ff,
- 0x00fbf9fd, 0x00000002, 0x01feff03, 0x02010102,
- 0x01fffe01, 0x01000102, 0x0300ff00, 0xffffff02,
- 0x00010102, 0x00000000, 0x03fef9f7, 0x01010203,
- 0xfe000203, 0x0101fffe, 0x0000ff00, 0x00000101,
- 0x0101fffe, 0x00000001, 0xfe010201, 0x0201fdfc,
- 0xfe010201, 0x010300fd, 0x0000ffff, 0xfc000301,
- 0x01ff0002, 0x03fefe02, 0x02ff0002, 0x01fcfe03,
- 0x01010100, 0xfefafe02, 0x000000ff, 0xfffe0002,
- 0x0201ffff, 0xfefdfe01, 0xfffeff03, 0x020100ff,
- 0x0000040a, 0xfffefeff, 0xfffeff03, 0x00ffff00,
- 0x010702fb, 0x0001fefc, 0xff0302fe, 0x000200fd,
- 0x00000102, 0xfeff0101, 0xfffefe01, 0x0000feff,
- 0xf9fe0300, 0x000003ff, 0xfbfd0301, 0x00ff0302,
- 0xfefe0200, 0x00fe0204, 0x00ff01ff, 0x01feff02,
- 0xfcfd0004, 0x010201fe, 0x05030000, 0xfeff0103,
- 0xff010101, 0x0101fffd, 0xfefeff01, 0xfeff0000
+static const int8 s_svq1IntraCodebook8x4[3072] = {
+ 5, 6, 6, 6, 7, 7, 8, 8, 0, 0, 0, 0, 0, 1, 2, 3,
+ -3, -4, -4, -5, -5, -4, -3, -2, -4, -4, -4, -5, -4, -4, -3, -3,
+ 1, 2, 2, 2, 2, 3, 3, 3, 2, 3, 3, 4, 4, 5, 5, 5,
+ -1, 0, 1, 1, 2, 3, 4, 4, -9,-10, -9, -9, -8, -7, -6, -5,
+ -4, -4, -5, -6, -6, -7, -7, -7, 0, -1, -2, -2, -3, -3, -4, -4,
+ 4, 4, 3, 3, 2, 1, 1, 0, 7, 7, 7, 6, 6, 5, 4, 4,
+ 2, 4, 5, 6, 4, 1, -3, -6, 3, 4, 5, 5, 4, 0, -5, -8,
+ 2, 3, 4, 4, 2, -2, -7,-10, 2, 2, 2, 1, 0, -4, -9,-12,
+ -9, -7, -3, 1, 4, 4, 3, 3,-10, -7, -2, 3, 5, 5, 3, 3,
+ -9, -6, -2, 3, 6, 5, 4, 3, -8, -6, -1, 3, 4, 4, 3, 2,
+ -5, -5, -5, -5, -3, 1, 4, 7, -5, -5, -5, -4, -2, 1, 6, 8,
+ -4, -5, -4, -3, -1, 3, 8, 10, -3, -4, -3, -2, 1, 5, 9, 11,
+ -2, -2, -2, -2, -2, -2, -2, -2, -4, -5, -5, -5, -5, -5, -5, -4,
+ -3, -4, -4, -4, -4, -4, -4, -3, 9, 10, 10, 11, 11, 11, 10, 10,
+ 7, 4, 1, -2, -4, -6, -9,-10, 9, 7, 3, 0, -2, -4, -8, -9,
+ 11, 8, 4, 2, 0, -3, -6, -8, 11, 9, 5, 3, 1, -2, -5, -7,
+ -13,-13,-13,-12,-11,-10, -8, -8, 0, 1, 2, 3, 4, 4, 4, 3,
+ 3, 4, 5, 6, 6, 6, 5, 4, 3, 4, 4, 4, 3, 3, 3, 2,
+ 10, 10, 11, 10, 9, 9, 8, 7, 6, 6, 6, 6, 5, 4, 3, 2,
+ 0, 0, 0, -1, -2, -3, -4, -4,-10,-10,-11,-12,-13,-14,-14,-14,
+ 16, 16, 17, 16, 15, 13, 12, 11, -1, -2, -3, -4, -4, -4, -4, -3,
+ -4, -5, -6, -6, -6, -6, -6, -6, -5, -6, -6, -6, -6, -6, -5, -5,
+ -13,-13,-13,-12,-11,-10, -8, -6, -9, -8, -7, -6, -4, -2, 0, 1,
+ -2, -1, 1, 3, 5, 7, 8, 9, 5, 7, 9, 11, 13, 14, 15, 15,
+ 16, 14, 11, 7, 2, -3, -7, -9, 14, 12, 8, 3, -1, -6, -9,-11,
+ 11, 9, 4, 0, -4, -8,-11,-13, 8, 5, 1, -3, -6,-10,-12,-14,
+ -18,-15, -9, -3, 1, 6, 9, 11,-17,-13, -7, -1, 3, 7, 11, 12,
+ -15,-11, -5, 1, 5, 9, 12, 13,-13, -9, -3, 2, 5, 9, 11, 13,
+ 22, 21, 19, 15, 10, 3, -4, -9, 20, 18, 15, 9, 2, -5,-12,-17,
+ 16, 13, 8, 1, -7,-14,-20,-24, 10, 6, -1, -8,-15,-21,-25,-27,
+ -25,-23,-20,-14, -7, 1, 9, 14,-23,-21,-16, -9, 0, 9, 16, 21,
+ -20,-16,-10, -1, 8, 16, 22, 25,-15,-11, -3, 6, 14, 20, 25, 27,
+ -4, -2, 0, 1, 2, 2, 2, 2, -5, -2, 0, 2, 3, 3, 3, 3,
+ -6, -4, -1, 1, 2, 3, 3, 3, -7, -5, -2, 0, 1, 1, 2, 2,
+ 2, 1, 1, 1, 1, 0, -2, -3, 3, 3, 2, 1, 0, -1, -3, -4,
+ 4, 3, 2, 1, 0, -2, -4, -6, 5, 4, 3, 1, -1, -3, -5, -6,
+ 5, 6, 6, 4, 2, 0, -2, -3, 3, 4, 4, 4, 3, 1, 0, -1,
+ -2, -2, -1, -1, -1, -1, -2, -2, -5, -4, -3, -2, -2, -2, -3, -3,
+ -1, -1, -1, -1, -1, -1, -1, -1, -3, -4, -4, -4, -3, -3, -3, -3,
+ -1, -1, -1, -1, -1, -1, -1, -2, 5, 6, 6, 6, 6, 5, 4, 3,
+ 4, 4, 4, 4, 4, 5, 6, 7, 0, -1, -1, -1, -1, 0, 1, 2,
+ -2, -3, -3, -3, -3, -2, -1, 0, -3, -3, -4, -4, -4, -3, -2, -1,
+ 0, -2, -4, -4, -2, 0, 2, 3, 0, -2, -3, -3, -1, 2, 4, 5,
+ -1, -2, -4, -3, 0, 3, 5, 6, -2, -3, -4, -3, -1, 2, 4, 5,
+ 9, 4, 0, -3, -3, -1, 0, 1, 8, 4, -1, -4, -3, -1, 1, 2,
+ 6, 2, -3, -5, -4, -2, 0, 1, 5, 1, -3, -4, -4, -2, 0, 1,
+ 5, 3, 1, -1, -4, -8,-10,-10, 3, 3, 2, 1, 0, -2, -3, -4,
+ 1, 1, 1, 2, 3, 2, 1, 0, -1, 0, 1, 2, 3, 4, 3, 2,
+ 0, 1, 2, 2, 1, -1, -3, -3, 0, 1, 1, 1, -1, -2, -4, -3,
+ -3, -3, -3, -3, -3, -3, -1, 2, -4, -4, -3, 0, 3, 7, 12, 14,
+ -5, -5, -6, -6, -6, -6, -6, -5, 2, 2, 2, 1, 0, 0, 0, 0,
+ 4, 4, 3, 2, 1, 0, 0, 0, 6, 6, 5, 4, 2, 2, 1, 1,
+ -7, -7, -6, -3, 0, 4, 7, 8, -1, -2, -3, -3, -2, -1, 1, 2,
+ 3, 3, 1, -1, -2, -2, -2, -1, 6, 6, 4, 2, 0, -2, -2, -2,
+ -6, -5, -2, 2, 5, 9, 11, 12, -4, -4, -2, 0, 2, 4, 5, 6,
+ -3, -2, -2, -2, -2, -1, 0, 1, -2, -2, -2, -3, -3, -3, -3, -2,
+ -7, -3, 1, 3, 3, 0, -3, -5, -6, -2, 3, 5, 4, 1, -3, -5,
+ -5, -1, 4, 6, 5, 2, -3, -4, -4, 0, 5, 7, 6, 3, -1, -3,
+ 0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -3, -3, -3, -3, -2, -1,
+ 6, 7, 8, 9, 9, 8, 7, 6, -4, -4, -5, -5, -6, -6, -5, -4,
+ -9, -8, -6, -4, 0, 3, 6, 6, -5, -4, -1, 3, 5, 6, 5, 3,
+ 1, 3, 6, 6, 4, 1, -2, -5, 6, 7, 5, 1, -3, -7,-10,-11,
+ 10, 9, 5, 1, -3, -6, -6, -4, 5, 3, -1, -5, -6, -5, -2, 2,
+ -2, -4, -6, -6, -4, 1, 6, 10, -6, -7, -7, -4, 1, 7, 11, 12,
+ 6, 5, 3, 2, 0, 0, 0, 0, 2, 1, -1, -2, -3, -2, -1, -1,
+ 0, -1, -2, -4, -4, -2, -1, 1, 0, 0, -1, -2, -1, 0, 2, 3,
+ 0, -1, -2, -2, -2, -2, -1, -1, 5, 4, 2, 1, 0, 0, 0, 0,
+ 6, 5, 3, 1, 0, 0, 0, 0, 2, 0, -2, -4, -4, -3, -2, -2,
+ -7, -4, 0, 2, 2, 2, 2, 1, -7, -3, 0, 0, 0, 0, 0, 0,
+ -4, -1, 1, 1, 0, 0, 0, 1, -1, 1, 2, 2, 2, 2, 3, 3,
+ -2, 0, 2, 2, 1, 1, 1, 1, -1, 1, 2, 2, 1, 0, 0, -1,
+ 0, 2, 4, 2, 0, -1, -2, -3, 1, 2, 3, 1, -2, -4, -6, -6,
+ 1, 2, 2, 4, 5, 6, 4, 1, 0, -1, -1, -1, 0, 0, -2, -4,
+ 0, 0, -1, -2, -2, -2, -4, -6, 2, 1, 0, 0, 1, 1, -1, -3,
+ 1, 1, 1, 1, 1, 2, 3, 3, 0, 0, 1, 0, 1, 2, 4, 4,
+ -1, -1, -1, -1, 0, 1, 2, 3, -4, -4, -5, -5, -5, -3, -1, 0,
+ -6, -5, -5, -4, -3, -2, -1, -1, -1, 0, 0, 1, 1, 2, 3, 3,
+ 0, 1, 1, 1, 2, 2, 3, 4, 0, 0, -1, -1, 0, 1, 2, 3,
+ 0, 1, 1, 1, 0, 0, -1, -1, 1, 3, 3, 2, 1, -1, -2, -2,
+ -2, 0, 2, 2, 2, 2, 1, 1, -9, -8, -4, -2, 1, 3, 3, 3,
+ -1, -1, -1, -2, -3, -3, -3, -4, 0, 0, 0, -1, -2, -2, -3, -3,
+ 2, 2, 2, 0, -1, -1, -1, -1, 5, 5, 4, 3, 2, 2, 2, 2,
+ 6, 3, -1, -4, -3, -1, 1, 1, 2, -1, -3, -4, -1, 2, 2, 0,
+ -1, -2, -2, 1, 4, 4, 1, -3, -2, -1, 1, 4, 6, 3, -3, -8,
+ 3, 3, 2, 1, -1, -2, -2, -2, -4, -4, -2, -1, 1, 3, 4, 4,
+ -4, -5, -5, -4, -2, 0, 2, 2, 7, 7, 4, 1, -1, -2, -3, -2,
+ -1, 1, 3, 0, -4, -6, 0, 6, -2, 1, 4, 1, -4, -6, -1, 7,
+ -3, 1, 4, 2, -3, -6, -1, 6, -2, 0, 3, 2, -2, -5, -1, 4,
+ 1, -1, -2, 1, 4, 4, -1, -7, 1, -1, -4, -1, 5, 6, 0, -6,
+ 3, 0, -4, -3, 3, 6, 2, -4, 3, 0, -5, -4, 1, 4, 1, -3,
+ 2, 2, 3, 3, 3, 3, 2, 2, -4, -5, -6, -7, -7, -7, -7, -6,
+ 1, 2, 3, 3, 3, 3, 2, 2, 0, 0, 1, 1, 1, 2, 2, 1,
+ 3, -3, -3, 3, 4, -2, -2, 2, 3, -4, -4, 4, 4, -4, -4, 2,
+ 4, -4, -4, 4, 4, -4, -3, 3, 3, -3, -4, 3, 3, -3, -3, 3,
+ -2, -2, -2, -2, -2, -2, -1, -1, 6, 7, 8, 8, 8, 7, 6, 5,
+ -5, -6, -7, -7, -8, -7, -6, -5, 1, 1, 2, 2, 2, 2, 1, 1,
+ 0, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, 0, 0, -1, 0, 0,
+ -2, -3, -2, -2, -2, -3, -3, -3, 2, 3, 5, 6, 4, 2, 1, 0,
+ 8, 6, 2, 0, 0, 0, 0, 0, 4, 1, 0, 0, 0, -1, -1, -1,
+ 1, -1, 0, 0, 0, -1, -2, -3, -2, -2, -1, 0, 0, -2, -4, -5,
+ 3, 1, -1, -2, -3, -4, -5, -5, 2, 1, 0, 0, 1, 1, 0, 0,
+ 0, -1, -1, 0, 2, 2, 2, 2, -1, -2, -1, 1, 2, 2, 2, 2,
+ 0, -1, -2, -1, -1, -1, -1, 0, -1, -2, -2, -1, -1, 0, 0, 1,
+ 2, 1, 1, 2, 2, 1, 1, 0, 6, 5, 3, 1, 0, -2, -4, -4,
+ -3, -2, -1, 0, 1, 1, 0, -1, 0, 1, 3, 4, 5, 5, 3, 1,
+ -1, -1, -1, 0, 1, 0, -1, -2, -2, -2, -2, -1, 0, -1, -2, -3,
+ 0, -1, -2, -2, -1, -1, 0, 2, 1, -1, -2, -1, -1, -1, 0, 2,
+ 1, 0, -2, -2, -2, -2, 1, 5, 1, -1, -2, -2, -2, 0, 5, 10,
+ 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, 0, 0, 0, 1, 2,
+ 1, 2, 2, 3, 4, 4, 6, 5, -3, -3, -3, -2, -2, -3, -3, -3,
+ 1, -1, -2, -2, 0, 3, 5, 7, 2, 0, -2, -3, -2, 0, 2, 3,
+ 3, 1, -2, -3, -3, -2, -1, -1, 3, 1, 0, -1, -1, -1, -1, -1,
+ 1, 3, 5, 4, 2, -1, -3, -4, -3, -2, 1, 2, 1, 0, -1, -2,
+ -5, -3, 0, 2, 2, 1, 0, 0, -3, -1, 1, 2, 2, 1, 0, 0,
+ 0, -1, -1, -1, 1, 2, 3, 4, -3, -4, -4, -3, -1, 0, 0, 1,
+ -2, -3, -2, -1, 1, 1, 1, 1, -2, -2, 0, 3, 4, 4, 3, 2,
+ -4, -4, -3, -2, -1, 1, 2, 3, 0, 1, 1, 1, -1, -2, -3, -3,
+ 3, 4, 5, 4, 2, -1, -3, -3, -2, -2, 0, 2, 2, 2, 1, 0,
+ -4, 0, 5, 7, 4, -1, -4, -4, -1, 2, 4, 3, 0, -3, -3, -2,
+ 2, 1, 0, -1, -2, -2, 0, 1, 0, 0, -1, -2, -2, -1, 1, 2,
+ -4, -3, -2, -1, 0, 1, 2, 2, 10, 9, 5, 0, -3, -4, -3, -2,
+ 1, -1, -2, -2, -1, 0, 0, 0, -2, -2, -1, 1, 1, 1, 0, -1,
+ -5, -3, 0, 3, 4, 2, 0, -2, -2, -1, 0, 1, 1, 0, -1, -1,
+ 3, 2, -1, -2, -2, -1, 1, 1, 7, 5, -1, -5, -6, -2, 2, 4,
+ -2, 3, 3, -3, -4, 1, 2, -2, -3, 3, 4, -3, -4, 2, 3, -2,
+ -3, 3, 4, -3, -4, 2, 3, -2, -4, 2, 4, -2, -3, 1, 2, -1,
+ 4, 3, -1, -3, -3, -1, 1, 2, -4, -6, -4, 0, 4, 5, 4, 1,
+ 0, 2, 5, 6, 2, -3, -5, -4, 1, 1, -1, -3, -5, -2, 2, 4,
+ -1, 0, 1, 2, 2, 3, 3, 4, -1, 0, 1, 1, 0, -1, -1, -1,
+ -1, 0, 1, 2, 2, 1, -1, -2, -3, -2, -1, 0, 0, -1, -2, -3,
+ 1, 1, 1, 1, 0, 0, 1, 2, 1, 0, -1, 0, 0, 1, 1, 0,
+ 1, -2, -4, -1, 1, 2, 1, 0, 1, -4, -7, -3, 1, 3, 2, 1,
+ 1, 1, 1, 1, 1, 1, 0, -1, 1, 1, 1, 0, 1, 2, 2, 0,
+ 1, 1, 0, 0, 0, 2, 0, -3, 3, 2, 0, -1, -1, -2, -6, -9,
+ 0, 0, 0, 1, 0, 0, 1, 2, 1, 0, 0, 0, -1, -1, 0, 2,
+ 0, 1, 1, 1, -1, -3, -2, 0, -7, -5, 1, 6, 6, 2, -1, -1,
+ 3, 1, -1, -3, -4, -2, 1, 4, 2, 0, -2, -3, -4, -3, -1, 2,
+ 2, 2, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1,
+ -1, 1, 1, -2, -5, -6, -4, -1, -1, 1, 4, 3, 2, 0, 1, 2,
+ -1, 0, 2, 3, 1, 0, 0, 1, -1, 0, 1, 0, 0, -1, -1, 0,
+ 0, 1, 2, 2, 0, -2, -1, 1, -2, -1, -1, -2, -1, 2, 6, 8,
+ -1, -1, -2, -3, -2, 0, 1, 2, -1, 0, 0, -1, -1, 0, -1, -1,
+ 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, -1, -1, 1,
+ -1, 0, 2, 2, -1, -3, -2, 3, 0, 2, 3, 0, -5, -7, -2, 4,
+ -1, 0, 0, 0, -1, -2, -3, -3, -1, 0, -1, -2, -2, -2, -2, -2,
+ 1, 1, 0, 0, 1, 2, 0, -1, 1, 2, 1, 2, 5, 6, 2, 0,
+ -2, -4, -3, 0, 2, 2, 0, -3, 3, 1, 0, 1, 2, 1, -2, -3,
+ 3, 1, 0, 0, 0, 0, 0, -1, 1, -1, -2, -2, -1, 1, 3, 3,
+ 3, 2, 1, 2, 4, 3, 1, -2, -2, -4, -4, -3, -1, 0, -2, -3,
+ 1, 0, -1, -1, 0, 1, 0, -1, 3, 2, 0, 0, 0, 1, 1, 0,
+ 1, 1, 0, 0, 0, 0, 0, 0, 2, 3, 3, 2, 2, 2, 1, 1,
+ 0, -1, -2, -3, -5, -5, -5, -4, 1, 1, 0, -1, 0, 1, 3, 3,
+ -9, -6, -2, 0, 1, 1, 2, 2, -6, -2, 1, 2, 1, 1, 0, 1,
+ -2, 1, 2, 2, 1, 1, 1, 1, 0, 2, 2, 1, 0, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, -1, -3, -2, 0,
+ -3, -3, -3, -2, -1, 3, 7, 9, 1, 2, 2, 2, 0, -2, -4, -3,
+ 2, 0, -2, -1, 3, 4, -1, -6, 1, 0, -2, -3, -1, 3, 3, 0,
+ 0, 3, 3, 0, -2, -1, 1, 1, -6, -1, 3, 2, -1, -2, 0, 1,
+ 5, 3, 0, -2, -3, 0, 2, 1, 1, 1, 2, 2, 0, -2, -4, -7,
+ -3, -2, 1, 2, 2, 1, -1, -4, 2, 2, 0, -2, -2, 0, 2, 2,
+ 0, 0, -2, -3, -2, -1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,
+ -2, -1, 0, 1, 0, 1, 2, 3, -4, -2, 0, 0, -1, 0, 2, 3,
+ -2, -2, -2, -1, -1, 0, 2, 4, 0, 0, 0, 0, -1, -1, 0, 1,
+ 0, -1, -1, -1, -1, -1, 0, 0, 6, 4, 2, 0, -1, -2, -1, -1,
+ 0, 1, 1, 1, 1, -1, -5,-10, 1, 1, 1, 1, 1, 1, 0, -4,
+ 1, 0, 1, 1, 1, 1, 1, -1, 2, 1, 1, 1, 0, 0, 0, 0,
+ -3, 1, 4, 3, 3, 1, -1, 0, -4, 0, 1, 0, -1, 0, 0, 0,
+ -5, 0, 2, 1, 1, 1, 0, -1, -1, 2, 1, -2, -2, -1, 0, -1,
+ 2, 4, 5, 3, 0, -1, 1, 2, 0, 0, 1, 0, -2, -2, -1, -1,
+ -2, -2, -2, -2, -3, -2, -1, 0, 0, 0, 1, 0, 0, 0, 1, 2,
+ 0, -2, -2, -3, -1, 2, 2, -1, 1, 0, 0, 0, 1, 5, 3, -2,
+ -1, -1, 0, -1, 0, 2, 0, -5, -1, 0, 1, 0, 0, 2, 2, -2,
+ 3, 1, -1, -1, 0, 1, 1, 2, 1, 0, 0, 1, 1, 1, 1, 1,
+ -10, -8, -2, 1, 2, 1, 1, 1, -1, 1, 2, 1, 0, 0, 0, 0,
+ -1, -1, 0, 1, 2, 2, 2, 1, -1, -1, -1, 0, -1, -3, -5, -4,
+ 1, 1, 2, 1, 1, 0, 0, 2, -1, -2, -1, -1, -1, 0, 2, 4,
+ -3, -7, -5, 0, 2, 0, 0, 0, 3, -1, -2, 1, 2, 1, 1, 2,
+ 1, -2, -1, 1, 2, 1, 0, 1, 0, -1, 0, 3, 2, -1, -1, -1,
+ 2, 1, 1, 0, 0, 0, 0, 0, -9, -7, -2, 3, 3, 2, 1, 1,
+ 3, 2, 0, -2, -2, -1, 1, 1, 0, -1, 0, 0, 1, 1, 0, 0,
+ -2, -1, 1, 1, 1, 0, 0, 0, 1, 2, 1, -2, -4, -3, 1, 2,
+ 1, 2, 1, -2, -3, 0, 3, 1, -1, -1, 0, 0, 1, 3, 0, -4,
+ 2, 0, -1, 1, 2, -2, -2, 3, 2, 0, -1, 2, 3, -2, -4, 1,
+ 0, 1, 1, 1, 2, -2, -6, -2, -1, 0, 0, 0, 2, 0, -2, -1,
+ -1, -1, 1, 2, 1, -2, -3, -2, 3, -1, -2, -1, -1, 0, 1, 2,
+ 10, 4, 0, 0, -1, -2, -2, -1, 3, -1, -2, -1, 0, -1, -1, 0,
+ -5, 2, 7, 1, -4, -2, 1, 0, -2, 2, 3, -1, -3, 0, 2, 0,
+ 2, 1, 0, 0, 1, 1, -1, -2, 1, -2, -2, -1, -1, -2, 0, 0,
+ 0, 3, -2, -7, -1, 3, 0, 0, 1, 3, -3, -5, 2, 3, -1, 0,
+ 0, 2, -2, -2, 4, 2, -2, 0, -1, 1, -1, 0, 2, -1, -2, 1,
+ 4, 0, -3, -4, -2, 1, 2, 1, 0, 0, 3, 5, 3, 1, -1, -2,
+ 1, 1, 1, -1, -3, -1, 1, 1, 1, -1, -2, -2, 0, 0, -1, -2
};
-static const uint32 s_svq1IntraCodebook8x8[1536] = {
- 0x02030404, 0xff000102, 0x02030304, 0xffff0001,
- 0x02020303, 0xfeff0001, 0x01020203, 0xfdfeff00,
- 0x00010202, 0xfdfeffff, 0x00000102, 0xfcfdfeff,
- 0xff000001, 0xfcfcfdfe, 0xfeff0000, 0xfcfcfdfe,
- 0x03030302, 0x03030303, 0x02020202, 0x03030202,
- 0x02020201, 0x02020202, 0x01010100, 0x01010101,
- 0x000000ff, 0x01010000, 0xfffffefe, 0xffffffff,
- 0xfdfdfdfd, 0xfefefdfd, 0xfcfcfcfb, 0xfdfcfcfc,
- 0x00fffefc, 0x03020201, 0x00fffefc, 0x03030201,
- 0x00fffdfc, 0x03030201, 0x00fffdfc, 0x03030201,
- 0x00fffdfb, 0x03030201, 0x00fffdfb, 0x03030201,
- 0x00fffdfb, 0x03020101, 0xfffefdfb, 0x03020100,
- 0x05050404, 0x07070606, 0x03020202, 0x04040403,
- 0x00000000, 0x02010101, 0xfefefefe, 0x00ffffff,
- 0xfefefefe, 0xfefefefe, 0xfefefefe, 0xfefefefe,
- 0xfefefeff, 0xfefefefe, 0xffffffff, 0xfefefefe,
- 0xff010305, 0xfdfdfdfe, 0xff010305, 0xfdfdfdfe,
- 0xff010305, 0xfdfdfdfe, 0xff010305, 0xfdfdfdfe,
- 0x00010405, 0xfdfdfdfe, 0x00020406, 0xfdfdfefe,
- 0x00020406, 0xfdfefeff, 0x01020406, 0xfefefeff,
- 0x030301ff, 0xfafd0002, 0x040301ff, 0xfafd0003,
- 0x040401ff, 0xfafd0103, 0x040301ff, 0xfafd0103,
- 0x040301fe, 0xfafd0103, 0x040301fe, 0xf9fd0103,
- 0x030301fe, 0xf9fd0002, 0x030200fe, 0xfafd0002,
- 0x0608090a, 0x04040506, 0x03040506, 0x01020202,
- 0xff000102, 0xfffefefe, 0xfcfdfeff, 0xfdfcfcfc,
- 0xfcfcfdfe, 0xfdfcfcfb, 0xfdfdfefe, 0xfefefdfd,
- 0xffffffff, 0x00ffffff, 0x01010101, 0x02010101,
- 0x0201fffe, 0x08070504, 0x0100fefd, 0x08070503,
- 0x00fffdfc, 0x07060402, 0xfffefcfb, 0x07050301,
- 0xfefdfbfa, 0x06040200, 0xfefcfbfa, 0x050301ff,
- 0xfdfbfaf9, 0x030200fe, 0xfcfbf9f8, 0x0201fffd,
- 0x0507090b, 0xffff0103, 0x0306080a, 0xfefe0001,
- 0x02050709, 0xfcfdfe00, 0x01030608, 0xfcfcfdff,
- 0xff020406, 0xfbfbfcfd, 0xfe000305, 0xfafafbfc,
- 0xfdff0103, 0xf9f9fafb, 0xfcfe0002, 0xf9f9fafa,
- 0x07070605, 0x08080807, 0x05050403, 0x06060606,
- 0x03020200, 0x05040404, 0x0100fffe, 0x03030202,
- 0xfffefdfc, 0x02010100, 0xfdfcfbfa, 0x00fffefe,
- 0xfafaf9f8, 0xfdfdfcfb, 0xf8f8f7f6, 0xfbfafaf9,
- 0x01030506, 0xf8fafdff, 0x02040506, 0xf8fafdff,
- 0x02040506, 0xf8fafd00, 0x02040506, 0xf8fafd00,
- 0x02040606, 0xf8fafd00, 0x02040506, 0xf8fafd00,
- 0x02040506, 0xf8fafd00, 0x02040506, 0xf8fbfdff,
- 0x08090a0b, 0x04050607, 0x06070808, 0x02030405,
- 0x04040506, 0x00010202, 0x01020303, 0xfeff0000,
- 0xff000101, 0xfdfdfefe, 0xfdfeffff, 0xfbfbfcfc,
- 0xfbfcfcfd, 0xf9f9fafa, 0xf9fafbfb, 0xf8f8f8f8,
- 0xf5f4f3f2, 0xfcfaf9f7, 0xf7f6f5f4, 0xfffdfbf9,
- 0xfaf9f7f6, 0x0200fefd, 0xfefcfaf8, 0x05040200,
- 0x0200fdfb, 0x08070504, 0x040200fe, 0x0a090806,
- 0x07050300, 0x0c0b0a08, 0x08070503, 0x0c0c0b0a,
- 0xeeeeeded, 0xf2f1f0ef, 0xf3f2f1f1, 0xf7f6f5f4,
- 0xf8f7f6f5, 0xfdfcfbfa, 0xfefdfbfa, 0x020100ff,
- 0x030200ff, 0x06060504, 0x08070604, 0x0a0a0a09,
- 0x0c0b0a09, 0x0e0e0e0d, 0x0f0e0e0c, 0x10101010,
- 0x11131516, 0x05090b0e, 0x0e111314, 0x0104080b,
- 0x0a0d0f11, 0xfc000306, 0x05080b0d, 0xf7fbfe01,
- 0xff030609, 0xf3f5f9fc, 0xfafd0004, 0xeff1f4f7,
- 0xf5f8fbfe, 0xeceef0f2, 0xf0f3f6f8, 0xeaebedef,
- 0x12121211, 0x0e101011, 0x0f0f1010, 0x0b0c0d0e,
- 0x0a0b0c0c, 0x05070809, 0x04060607, 0xff010203,
- 0xfeff0001, 0xfafbfcfd, 0xf8f9fafb, 0xf4f5f6f7,
- 0xf2f3f4f5, 0xeff0f0f1, 0xeeefeff0, 0xecececed,
- 0x00000000, 0xfdfeffff, 0x00000001, 0xfdfeff00,
- 0x00000101, 0xfefeffff, 0x00010101, 0xfeffff00,
- 0x01010102, 0xfeffff00, 0x01010202, 0xfeff0000,
- 0x01010202, 0xffff0001, 0x01010202, 0xfe000001,
- 0x00ffff00, 0x03020100, 0x00ffff00, 0x02020101,
- 0xffffffff, 0x02020100, 0xfffeffff, 0x02010100,
- 0xfffefeff, 0x02010000, 0xfefefeff, 0x020100ff,
- 0xfffeffff, 0x02010000, 0xffffffff, 0x02010100,
- 0x02020203, 0x00000101, 0x02020203, 0x00000102,
- 0x01020202, 0x00000101, 0x01010202, 0xff000001,
- 0x00010101, 0xffff0000, 0xffff0000, 0xffffffff,
- 0xfefefefe, 0xfefefefe, 0xfdfdfdfe, 0xfefefefe,
- 0x00000205, 0x000000ff, 0xff000204, 0xff00ffff,
- 0xffff0104, 0xfffffffe, 0xffff0104, 0xfffffffe,
- 0xfeff0104, 0xfffffffe, 0xfeff0104, 0xfffffffe,
- 0xffff0104, 0xffffffff, 0xff000204, 0xff000000,
- 0x0100fffe, 0x01010101, 0x0100fffd, 0x01010101,
- 0x0100fffd, 0x01010101, 0x0100fffd, 0x01010101,
- 0x0100fefd, 0x01010202, 0x0100fefc, 0x02020202,
- 0x01fffdfb, 0x02010201, 0x00fefdfb, 0x01010101,
- 0x00010303, 0xfbfcfcfe, 0x00020303, 0xfcfdfeff,
- 0x01010202, 0xfefeff00, 0x01010101, 0x00000001,
- 0x01000000, 0x01010101, 0x00fffffe, 0x02020100,
- 0xfffefefd, 0x03020100, 0xfffefdfd, 0x03020100,
- 0xfdfdfdfd, 0xfefefefd, 0xfefefdfd, 0xfffffffe,
- 0xfffefefe, 0xffffffff, 0x00ffffff, 0x00000000,
- 0x00000000, 0x01010101, 0x01010000, 0x02020202,
- 0x02010101, 0x03030302, 0x02020202, 0x03030303,
- 0xfdfbf9f8, 0xff00fffe, 0x00fffdfc, 0x01010201,
- 0x030201ff, 0x01020203, 0x03030201, 0x00010202,
- 0x02030302, 0xff000001, 0x00010201, 0xffffffff,
- 0xff000101, 0xfffefeff, 0x00000101, 0xff00ffff,
- 0x00fefdfc, 0x03030201, 0x00fefdfc, 0x02020201,
- 0xfffefdfd, 0x01010100, 0xfffefefe, 0x000000ff,
- 0xffffff00, 0xffffffff, 0x00010102, 0xfeffff00,
- 0x01030303, 0xfefeff00, 0x02040405, 0xfeff0001,
- 0x00000000, 0x03030201, 0x0000ff00, 0x03030201,
- 0x0000ff00, 0x02030201, 0x01000000, 0x02020201,
- 0x01010102, 0x00010101, 0x01020202, 0xfeff0000,
- 0x00000102, 0xfafbfdfe, 0xfdffff00, 0xf7f8fafb,
- 0x020100fe, 0xfcff0102, 0x020200fe, 0xfcff0102,
- 0x020200fe, 0xfdff0102, 0x020200fe, 0xfdff0102,
- 0x0202fffe, 0xfdff0102, 0x0201fffe, 0xfdff0102,
- 0x0201fffd, 0xfdff0102, 0x0201fffe, 0xfdff0102,
- 0xff0101ff, 0x0400fdfd, 0xff0101ff, 0x0400fdfd,
- 0x000101ff, 0x0400fdfd, 0x000201ff, 0x0500fdfd,
- 0x00020100, 0x0400fcfd, 0x00020100, 0x0500fcfd,
- 0x00020100, 0x0400fdfd, 0xff020100, 0x0400fefe,
- 0x06050606, 0x05050505, 0x02020202, 0x02020202,
- 0x00000000, 0x00000000, 0xffffffff, 0xfefefefe,
- 0xfefefefe, 0xfefefefe, 0xfefefefe, 0xfefefefe,
- 0xfffeffff, 0xffffffff, 0xffffffff, 0xffffffff,
- 0x02020202, 0x02020202, 0x00010100, 0x00000000,
- 0xfefefeff, 0xfffefefe, 0xfdfdfdfd, 0xfefdfdfd,
- 0xfdfcfcfd, 0xfefefdfd, 0xfefefefe, 0x0000ffff,
- 0x01010100, 0x03030202, 0x05040403, 0x06060605,
- 0xfdfe0104, 0x0301fffd, 0xfcfe0104, 0x0301fffd,
- 0xfcfe0105, 0x0401fffd, 0xfdfe0105, 0x0402fffd,
- 0xfdfe0105, 0x0402fffd, 0xfcfd0004, 0x0402fffd,
- 0xfdfd0004, 0x0301fffd, 0xfdfe0003, 0x0301fffe,
- 0xfcfcfcfd, 0xfcfcfcfc, 0xffffffff, 0xfefeffff,
- 0x02010102, 0x01010102, 0x04030303, 0x03030304,
- 0x04030303, 0x03030404, 0x02010201, 0x02020202,
- 0xfffefefe, 0x0000ffff, 0xfcfcfcfc, 0xfdfdfdfd,
- 0xfdfdfeff, 0x00fffefe, 0xfefeff00, 0x0100fffe,
- 0xffff0102, 0x0100ffff, 0xff000103, 0x010000ff,
- 0xff000203, 0x01000000, 0xff000103, 0x01000000,
- 0xff000103, 0x01000000, 0x00000102, 0x01000000,
- 0x01000000, 0x04030201, 0x00ff0000, 0x03020000,
- 0xffffff00, 0x0100ffff, 0xffffff00, 0x00ffffff,
- 0xffff0000, 0xfffefeff, 0xff000001, 0xfffefeff,
- 0x00010202, 0xffffffff, 0x01020303, 0x00ffff00,
- 0x00010001, 0xfffeff00, 0x00000000, 0xfffeffff,
- 0x0000ff00, 0xffffffff, 0x00ffffff, 0x00000000,
- 0x00ffffff, 0x01010000, 0x00ffffff, 0x03020101,
- 0x00fffefe, 0x04030201, 0x00fffefe, 0x05040201,
- 0x0001fffd, 0x0100ff00, 0x000100fd, 0x0200ffff,
- 0x000100fd, 0x0200ffff, 0x000201fe, 0x0200ffff,
- 0x000201fe, 0x0200ffff, 0x000201fe, 0x0200ffff,
- 0x000202ff, 0x0200ffff, 0x000101ff, 0x01ffffff,
- 0x01fffefe, 0x01030403, 0x00fffefe, 0x00020302,
- 0x00fffefe, 0xff010201, 0x00ffffff, 0xff010201,
- 0x00ffffff, 0xfe000101, 0x00ffff00, 0xff000101,
- 0x00ffff00, 0xff010101, 0x00ffff00, 0xff000100,
- 0x0100fffe, 0x01010101, 0x0000fffe, 0x00000000,
- 0x00fffffe, 0xfefeffff, 0xfffffffe, 0xfdfefeff,
- 0x010100ff, 0xfefeff00, 0x03030201, 0x00000102,
- 0x03030201, 0x00010203, 0x01010000, 0x00000101,
- 0xffffff00, 0x00000000, 0x00000001, 0x01010000,
- 0x01010101, 0x01010101, 0x02020101, 0x01010101,
- 0x01010101, 0x01010101, 0x010000ff, 0x00000001,
- 0xfffffefd, 0xff00ffff, 0xfdfcfbfb, 0xfffefefe,
- 0x01010101, 0xff000102, 0x02010101, 0xff000101,
- 0x01010101, 0xfe000101, 0x01010102, 0xfe000101,
- 0x00000101, 0xfdff0000, 0x00000101, 0xfdfeff00,
- 0x00000101, 0xfcfeffff, 0xff000001, 0xfcfdfefe,
- 0x03050708, 0x01010102, 0x00000102, 0xfffeffff,
- 0xfeffffff, 0xfffefefe, 0xffffffff, 0x00ffff00,
- 0x01000000, 0x00000001, 0x01010000, 0x00000001,
- 0x000000ff, 0xffff0000, 0xfffffefe, 0xfffefeff,
- 0xfe000409, 0xfffffefe, 0xfeff0207, 0x0000fffe,
- 0xfefe0004, 0x010100ff, 0xfefefe01, 0x010100ff,
- 0xfffefeff, 0x01010100, 0x00fffeff, 0x00010101,
- 0x0100ffff, 0xff000101, 0x0100ff00, 0xffff0000,
- 0x01010100, 0x00000101, 0x02020201, 0x00000001,
- 0x02020202, 0xffff0001, 0x00010101, 0xfefefeff,
- 0xff000000, 0xfefefdfe, 0xfeffffff, 0x00fffefe,
- 0xffffffff, 0x02010000, 0x00ffffff, 0x04030201,
- 0x0000ffff, 0xfdfdfeff, 0x0000ffff, 0xffffff00,
- 0x00fffefe, 0x01010101, 0x00fefefe, 0x03030201,
- 0x00ffffff, 0x03030301, 0x00000001, 0x02020101,
- 0x00010202, 0xffffff00, 0x00010203, 0xfdfdfeff,
- 0xfeffffff, 0xfbfcfdfe, 0xff000000, 0xfcfdfdff,
- 0x00010101, 0xfdfeff00, 0x01020202, 0xffff0001,
- 0x02020202, 0xff000101, 0x02020202, 0x00000102,
- 0x01020101, 0x00000101, 0x01010000, 0xff000000,
- 0x010302fe, 0xff0101ff, 0x000302fd, 0xff0101ff,
- 0x000302fd, 0xff0101ff, 0x000302fc, 0xfe0101ff,
- 0x000301fc, 0xfe0101ff, 0xff0301fc, 0xfe0101fe,
- 0x000201fd, 0xfe0101ff, 0x000201fd, 0xff0101ff,
- 0xfeffffff, 0xfefefefe, 0x01010101, 0x00000000,
- 0x02020201, 0x02020202, 0x01010000, 0x02020201,
- 0xfffffefe, 0x000000ff, 0xfdfdfdfd, 0xfefdfdfd,
- 0xffffffff, 0xfefefefe, 0x04040404, 0x02030304,
- 0xfffefdfd, 0x05020100, 0xfefdfdfd, 0x060301ff,
- 0xfefefdfd, 0x05030200, 0xfefefefd, 0x05030100,
- 0xfffefefe, 0x050301ff, 0xfffffefe, 0x04020100,
- 0xffffffff, 0x04010100, 0xffffffff, 0x03020100,
- 0x0100ff00, 0xffff0001, 0x01000000, 0xffff0002,
- 0x00ff0001, 0x00000001, 0xfffeff01, 0x00000000,
- 0xfffdfe01, 0x01000000, 0xfefdff01, 0x02010100,
- 0xfffeff01, 0x02010100, 0x00ff0002, 0x02020101,
- 0x01010101, 0x02010000, 0xff0000ff, 0x01000000,
- 0xfffffefd, 0x010100ff, 0x00fffefc, 0x01010100,
- 0x0000fefd, 0x01010101, 0x0100fffd, 0x00000101,
- 0x010100ff, 0xff000001, 0x02020100, 0xff000001,
- 0xfdfcfcfc, 0xfffffffe, 0xfffefefe, 0x00000000,
- 0x000000ff, 0x01010101, 0x01010000, 0x01010101,
- 0x01010000, 0x00010202, 0x01010000, 0x00010101,
- 0x01000000, 0x00010101, 0x010000ff, 0x00000101,
- 0x02020201, 0xfcfeff01, 0x02020101, 0xfcfe0001,
- 0x01010100, 0xfdff0001, 0x010100ff, 0xfeff0000,
- 0x010100ff, 0xff000001, 0x0000fffe, 0xff000000,
- 0x0100ffff, 0x00000001, 0x010100ff, 0x00010101,
- 0xff000202, 0xfefffffe, 0xfeff0101, 0xfefffffe,
- 0xfeff0101, 0xff0000fe, 0xfe000101, 0x000101ff,
- 0xff000101, 0x010201ff, 0xff000101, 0x010201ff,
- 0xff000101, 0x010101ff, 0xff000101, 0x01010100,
- 0xfeff0000, 0xfcfcfcfc, 0x02030303, 0x00000001,
- 0x03030303, 0x02020202, 0x00000000, 0x01000000,
- 0xffffffff, 0x00ffffff, 0x0000ff00, 0x000000ff,
- 0x00000000, 0x00000000, 0x00000000, 0x00ffff00,
- 0xff00ffff, 0xff0201ff, 0x00000101, 0xff030200,
- 0xff000101, 0xff0301ff, 0xfe000101, 0xfe0100fe,
- 0xfe000001, 0xfd0100fe, 0x00000000, 0xfd0101ff,
- 0x00010100, 0xfd010201, 0x010100ff, 0xfc010201,
- 0x0100fdfc, 0x00000101, 0x0100fefc, 0xff000101,
- 0x0101fffd, 0xffff0001, 0x010101ff, 0x00ff0001,
- 0x01020201, 0x0000ff00, 0x00010202, 0x0100ffff,
- 0xff000102, 0x0100fffe, 0xff000202, 0x0101fffe,
- 0x00000101, 0xffffffff, 0xffffff00, 0xffffffff,
- 0xffffffff, 0xffffffff, 0xffff0000, 0xffffffff,
- 0xff000001, 0xffffffff, 0x00000102, 0xffffffff,
- 0x01020305, 0x00000000, 0x02030506, 0x00000001,
- 0x01030404, 0x01000000, 0x01020303, 0x01000000,
- 0x00010202, 0x0100ffff, 0xff000000, 0x0100ffff,
- 0xffff0000, 0x0200fffe, 0xfeffff00, 0x0100fefe,
- 0xfeffff00, 0x00fffefe, 0xfeff0000, 0x00fffefe,
- 0xffff0000, 0x030200ff, 0xfefeff00, 0x0201ffff,
- 0xffff0001, 0x000000ff, 0x00010101, 0xffff0000,
- 0x00010201, 0xffffff00, 0x000000ff, 0xffffffff,
- 0xfffffefd, 0x02010100, 0x01fffdfc, 0x05050302,
- 0x00000000, 0x00000000, 0x01010101, 0x01010101,
- 0xff000000, 0x01000000, 0xfefeffff, 0x00fffffe,
- 0x00000000, 0x01010100, 0x02020202, 0x03030302,
- 0x01010101, 0x01010202, 0xfcfcfdfc, 0xfdfdfcfc,
- 0x020100ff, 0x03030302, 0xffffffff, 0x00000000,
- 0xfeff0000, 0xfefdfdfe, 0x00010203, 0xfefefeff,
- 0x01020304, 0x00000001, 0x01010202, 0x01010100,
- 0xffffff00, 0x010000ff, 0xfefefefe, 0x0000fffe,
- 0x0200ff01, 0x01fffe01, 0x0200ff01, 0x01fefe01,
- 0x0300ff01, 0x01fffe02, 0x0300fe00, 0x01fefe02,
- 0x0300fe00, 0x01fefe02, 0x0300fe00, 0x01fffe01,
- 0x0200fe00, 0x01fefe01, 0x0200ff00, 0x01fffe01,
- 0x02020100, 0x02020303, 0x02010100, 0x01020303,
- 0x02010000, 0x01020202, 0x010000ff, 0x01010101,
- 0x0000ffff, 0x00000000, 0xffffffff, 0xffffffff,
- 0xfefefefe, 0xfffefefe, 0xfefefefe, 0xfffefefe,
- 0xfeff0000, 0x050300ff, 0xffff0000, 0x040200ff,
- 0x00000101, 0x0201ffff, 0x01010201, 0x00ffff00,
- 0x01020100, 0xfefeff00, 0x020100ff, 0xfdfd0001,
- 0x0201fffe, 0xfcfe0002, 0x0200fffe, 0xfdff0102,
- 0x00000000, 0xffff0000, 0x00ff0000, 0x00000000,
- 0xffffffff, 0x00000000, 0xffffffff, 0x00ffffff,
- 0xffffffff, 0x00ffffff, 0x000000ff, 0x00ffff00,
- 0x01010000, 0x01000000, 0x04030303, 0x03030303,
- 0xfefe0105, 0xff000000, 0xfffdff04, 0xff000000,
- 0x00ffff03, 0xff000101, 0x01000002, 0xfe000101,
- 0x01000001, 0xfe000101, 0xffffff00, 0xff000000,
- 0xffffff00, 0xff0000ff, 0x00000102, 0x00000100,
- 0x01010001, 0x00000101, 0x01000001, 0x00000001,
- 0x00ffff01, 0x00000000, 0xffff0002, 0x00ffffff,
- 0xffff0103, 0xfffefefe, 0x00010204, 0xfffefeff,
- 0x00000102, 0x0000ffff, 0xffffff00, 0x010100ff,
- 0x02020100, 0xfdff0102, 0x01010000, 0xfeff0001,
- 0x00000000, 0xffff0000, 0x00ff0000, 0x00010100,
- 0x00ff0000, 0x01010101, 0x00000000, 0x00010101,
- 0x01010000, 0xfdff0102, 0x01000000, 0xfbfcff01,
- 0xfffefefe, 0x02020200, 0x00000000, 0x00010101,
- 0x01010101, 0xfdfe0001, 0x01010000, 0xfcfdff00,
- 0x0100ffff, 0xfdfe0000, 0x0100ffff, 0xff000101,
- 0x01000000, 0x00010101, 0x01010101, 0x00000000,
- 0x00000100, 0x02010101, 0x00000201, 0x01ff0000,
- 0xff000200, 0x00ff0001, 0x00000100, 0x01000102,
- 0x00ff0100, 0x01000202, 0xffff00ff, 0x02010102,
- 0xfefdfefe, 0x01010100, 0xfdfdfefe, 0x00ffffff,
- 0x0100fffd, 0x00010102, 0x0100fffd, 0x01010102,
- 0x010000fe, 0x01010101, 0x000000ff, 0x00000000,
- 0x000000fe, 0x00ffff00, 0x000000fe, 0xffff0000,
- 0x010100fd, 0x01000101, 0x0100fefb, 0x02010202,
- 0x00fffffe, 0x03020100, 0x01010000, 0x02010000,
- 0x00010000, 0x0100ffff, 0xffffffff, 0x00fffefe,
- 0xfefefefe, 0x0100fffe, 0xff000000, 0x02020100,
- 0x00000102, 0x02020100, 0xff000102, 0x0000ffff,
- 0x01010100, 0xfcff0101, 0x0100ffff, 0xfd000101,
- 0x0000fffe, 0xfe020201, 0x000000ff, 0xff030200,
- 0x000000ff, 0x00020100, 0xfeff0000, 0x000101ff,
- 0xfeff0000, 0x010200fe, 0xfeff0000, 0x020201ff,
- 0x00000001, 0xfdfefdfe, 0x00010000, 0xfffffefe,
- 0x0101ff00, 0x0000ffff, 0x0101ff00, 0x0000ffff,
- 0x01020100, 0x0100ffff, 0x02030201, 0x02010000,
- 0x010200ff, 0x03020000, 0x0000fffe, 0x020100ff,
- 0xff000101, 0x01fffefe, 0xff010101, 0x0200fefe,
- 0xff010101, 0x0200ffff, 0x00000000, 0x02010000,
- 0x00ffffff, 0x02010000, 0x01fffeff, 0x00000101,
- 0x01fffeff, 0xff000202, 0x02fffeff, 0xff000202,
- 0xfeffffff, 0x0100ffff, 0xffff0000, 0x020100ff,
- 0x00000001, 0x02010100, 0x00000101, 0x01010101,
- 0x01000101, 0x01010001, 0x01010101, 0xffffff00,
- 0x00010201, 0xfdfefeff, 0x00010202, 0xfcfcfdfe,
- 0x0101fefc, 0x00000101, 0x000100fe, 0x00000000,
- 0xfe010100, 0x0100fffe, 0xfe010202, 0x0201fffe,
- 0xfe010201, 0x0201fffe, 0xff0101ff, 0x0100ffff,
- 0x010100fe, 0x00ffff00, 0x020200fe, 0x00ffff01,
- 0x00000101, 0x00000100, 0xfefdfdfe, 0x0000fffe,
- 0xfefdfcfd, 0x000000ff, 0x0100ffff, 0x01020302,
- 0x03020100, 0x01020303, 0x02010101, 0xff000001,
- 0x00000000, 0xffffffff, 0x00ffff00, 0x00000000,
- 0x00000101, 0x0200ffff, 0x00010000, 0x0101ffff,
- 0x0100fffe, 0x01010101, 0x0200fdfd, 0x00010102,
- 0x0100fefe, 0x00000101, 0x00000001, 0xffff0000,
- 0xfdff0103, 0x0100fffe, 0xfdff0204, 0x0201fffd,
- 0xff000000, 0xffffffff, 0x00010201, 0xffff0000,
- 0x02030302, 0xffff0001, 0x02040403, 0xfeff0001,
- 0x01020303, 0xfefeff00, 0xff000101, 0xfdfefeff,
- 0xff000000, 0xfefefeff, 0xffffffff, 0xfffefeff,
- 0x02020201, 0x02020102, 0x01010100, 0x00000001,
- 0x01000000, 0xfeff0001, 0x00000000, 0xfcff0001,
- 0x00000001, 0xfbfe0000, 0x00000001, 0xfcff0000,
- 0x00ff0001, 0xfdff0000, 0x00ffff00, 0xff010101,
- 0x0000fffe, 0xfeffffff, 0x000000ff, 0xfefeffff,
- 0x00010100, 0xfeffffff, 0x00010100, 0xffff0000,
- 0x00000100, 0x00010101, 0x00000101, 0x01020201,
- 0x00000101, 0x01020201, 0xff000101, 0x00010100,
- 0x00010204, 0x01010100, 0x00010204, 0x01000000,
- 0x00000103, 0x00ffffff, 0xff000001, 0x00fffeff,
- 0x00000000, 0x00ffffff, 0x0000ffff, 0x0100ffff,
- 0xff00fffe, 0x010000ff, 0xfefffefe, 0x010000ff,
- 0x01010100, 0xff000102, 0x00ffffff, 0xfefeff00,
- 0x00ff00ff, 0xfffeff00, 0x00000000, 0x02010000,
- 0x00000000, 0x03020000, 0xffff00ff, 0x0300ffff,
- 0xff0000ff, 0x0300feff, 0x00000000, 0x0401ffff,
- 0x00000202, 0x01000000, 0xfeff0101, 0x01fffeff,
- 0xfefeffff, 0x00fefdfe, 0xffff00ff, 0x01fffeff,
- 0x00000101, 0x01000001, 0x00000202, 0x01000001,
- 0x00000202, 0xffff0000, 0x00000202, 0xffff0001,
- 0x010100ff, 0xffffff00, 0x02030201, 0x00000001,
- 0x01010100, 0x0000ff00, 0x00fffefe, 0x00000001,
- 0x02fffefe, 0x00010202, 0x0100fffe, 0xff000001,
- 0x0000ffff, 0xfefffeff, 0x01010100, 0x01010000,
- 0xfefdfdfd, 0xfefeffff, 0x0100ffff, 0x00000102,
- 0x02010101, 0x00000102, 0x01010101, 0x01ff0001,
- 0xffff0001, 0x01ff0000, 0xffffff00, 0x01ffff00,
- 0x00ff0001, 0x0200ff00, 0x00ff0002, 0x02000000,
- 0xfffe0001, 0x00010100, 0xffff0002, 0x00010100,
- 0xfffe0001, 0xff000100, 0xffff0001, 0xff000100,
- 0x00010100, 0x00000101, 0x010201fe, 0x01000000,
- 0x010200fb, 0x0100ff00, 0x0102fffa, 0x0000ff00,
- 0xff000305, 0xfffffffe, 0xff000101, 0xffff00ff,
- 0x010100ff, 0x00010202, 0x0100fffe, 0x01010102,
- 0xfffffffe, 0x0100ff00, 0x00000100, 0x0000ffff,
- 0x01010100, 0x00000001, 0x0100fefd, 0xff000001,
- 0x000100ff, 0x030200ff, 0xfe0000ff, 0x00fffefc,
- 0x00010100, 0xff00fffe, 0x01030201, 0x00010100,
- 0x010100ff, 0x00010101, 0x00fefdfe, 0x00010000,
- 0x00fefeff, 0xff000001, 0x00000103, 0xffff0001,
- 0x0000fffe, 0x0000ffff, 0x000000ff, 0x01010100,
- 0x00ffffff, 0x01010101, 0xfffdfe00, 0x00000001,
- 0xfffdff01, 0xff000101, 0x01ff0103, 0xff000202,
- 0x01000103, 0x00010102, 0xfffefe00, 0x000000ff,
- 0xffff0001, 0x00010201, 0xfffeff00, 0x01020201,
- 0x00ffffff, 0x00020100, 0x000000fe, 0xff010000,
- 0x000100ff, 0xffffffff, 0x02010100, 0x00fffe00,
- 0x02020201, 0x00ffff01, 0x01010100, 0xfffefe00,
- 0xffff0000, 0xfefeffff, 0x00ff0000, 0x01020201,
- 0xffff0000, 0x02020100, 0xfeff0101, 0xffffffff,
- 0x00010202, 0xfefeff00, 0x01020201, 0xfefe0000,
- 0x00000000, 0xff000101, 0xffffff00, 0x01020302,
- 0x0201fe00, 0x010000ff, 0x0302feff, 0x000000ff,
- 0x0302fe00, 0x0000ffff, 0x0203ff00, 0x000100fe,
- 0x0103ff00, 0x000100fe, 0x0102ff00, 0xff0001ff,
- 0xff010000, 0xff0000fe, 0xfe000001, 0xfffffffe,
- 0x01010101, 0xfeffff01, 0x01000000, 0x01010101,
- 0x01000000, 0x03020101, 0xff000001, 0x02010000,
- 0xfeffff00, 0x020100ff, 0xfefefefe, 0x010100ff,
- 0xffffffff, 0xff000000, 0x00020202, 0xfcfeffff,
- 0xfffffeff, 0x03020100, 0xffffffff, 0x03020100,
- 0x00ff0001, 0x020100ff, 0x00000001, 0x020200ff,
- 0xffff0001, 0x020100fe, 0xfefefe00, 0x0100fffd,
- 0xfefefe00, 0x0101fffe, 0x00000000, 0x02020100
+static const int8 s_svq1IntraCodebook8x8[6144] = {
+ 4, 4, 3, 2, 2, 1, 0, -1, 4, 3, 3, 2, 1, 0, -1, -1,
+ 3, 3, 2, 2, 1, 0, -1, -2, 3, 2, 2, 1, 0, -1, -2, -3,
+ 2, 2, 1, 0, -1, -1, -2, -3, 2, 1, 0, 0, -1, -2, -3, -4,
+ 1, 0, 0, -1, -2, -3, -4, -4, 0, 0, -1, -2, -2, -3, -4, -4,
+ 2, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3,
+ 1, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1, 1,
+ -1, 0, 0, 0, 0, 0, 1, 1, -2, -2, -1, -1, -1, -1, -1, -1,
+ -3, -3, -3, -3, -3, -3, -2, -2, -5, -4, -4, -4, -4, -4, -4, -3,
+ -4, -2, -1, 0, 1, 2, 2, 3, -4, -2, -1, 0, 1, 2, 3, 3,
+ -4, -3, -1, 0, 1, 2, 3, 3, -4, -3, -1, 0, 1, 2, 3, 3,
+ -5, -3, -1, 0, 1, 2, 3, 3, -5, -3, -1, 0, 1, 2, 3, 3,
+ -5, -3, -1, 0, 1, 1, 2, 3, -5, -3, -2, -1, 0, 1, 2, 3,
+ 4, 4, 5, 5, 6, 6, 7, 7, 2, 2, 2, 3, 3, 4, 4, 4,
+ 0, 0, 0, 0, 1, 1, 1, 2, -2, -2, -2, -2, -1, -1, -1, 0,
+ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+ -1, -2, -2, -2, -2, -2, -2, -2, -1, -1, -1, -1, -2, -2, -2, -2,
+ 5, 3, 1, -1, -2, -3, -3, -3, 5, 3, 1, -1, -2, -3, -3, -3,
+ 5, 3, 1, -1, -2, -3, -3, -3, 5, 3, 1, -1, -2, -3, -3, -3,
+ 5, 4, 1, 0, -2, -3, -3, -3, 6, 4, 2, 0, -2, -2, -3, -3,
+ 6, 4, 2, 0, -1, -2, -2, -3, 6, 4, 2, 1, -1, -2, -2, -2,
+ -1, 1, 3, 3, 2, 0, -3, -6, -1, 1, 3, 4, 3, 0, -3, -6,
+ -1, 1, 4, 4, 3, 1, -3, -6, -1, 1, 3, 4, 3, 1, -3, -6,
+ -2, 1, 3, 4, 3, 1, -3, -6, -2, 1, 3, 4, 3, 1, -3, -7,
+ -2, 1, 3, 3, 2, 0, -3, -7, -2, 0, 2, 3, 2, 0, -3, -6,
+ 10, 9, 8, 6, 6, 5, 4, 4, 6, 5, 4, 3, 2, 2, 2, 1,
+ 2, 1, 0, -1, -2, -2, -2, -1, -1, -2, -3, -4, -4, -4, -4, -3,
+ -2, -3, -4, -4, -5, -4, -4, -3, -2, -2, -3, -3, -3, -3, -2, -2,
+ -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 1, 1, 1, 1, 1, 2,
+ -2, -1, 1, 2, 4, 5, 7, 8, -3, -2, 0, 1, 3, 5, 7, 8,
+ -4, -3, -1, 0, 2, 4, 6, 7, -5, -4, -2, -1, 1, 3, 5, 7,
+ -6, -5, -3, -2, 0, 2, 4, 6, -6, -5, -4, -2, -1, 1, 3, 5,
+ -7, -6, -5, -3, -2, 0, 2, 3, -8, -7, -5, -4, -3, -1, 1, 2,
+ 11, 9, 7, 5, 3, 1, -1, -1, 10, 8, 6, 3, 1, 0, -2, -2,
+ 9, 7, 5, 2, 0, -2, -3, -4, 8, 6, 3, 1, -1, -3, -4, -4,
+ 6, 4, 2, -1, -3, -4, -5, -5, 5, 3, 0, -2, -4, -5, -6, -6,
+ 3, 1, -1, -3, -5, -6, -7, -7, 2, 0, -2, -4, -6, -6, -7, -7,
+ 5, 6, 7, 7, 7, 8, 8, 8, 3, 4, 5, 5, 6, 6, 6, 6,
+ 0, 2, 2, 3, 4, 4, 4, 5, -2, -1, 0, 1, 2, 2, 3, 3,
+ -4, -3, -2, -1, 0, 1, 1, 2, -6, -5, -4, -3, -2, -2, -1, 0,
+ -8, -7, -6, -6, -5, -4, -3, -3,-10, -9, -8, -8, -7, -6, -6, -5,
+ 6, 5, 3, 1, -1, -3, -6, -8, 6, 5, 4, 2, -1, -3, -6, -8,
+ 6, 5, 4, 2, 0, -3, -6, -8, 6, 5, 4, 2, 0, -3, -6, -8,
+ 6, 6, 4, 2, 0, -3, -6, -8, 6, 5, 4, 2, 0, -3, -6, -8,
+ 6, 5, 4, 2, 0, -3, -6, -8, 6, 5, 4, 2, -1, -3, -5, -8,
+ 11, 10, 9, 8, 7, 6, 5, 4, 8, 8, 7, 6, 5, 4, 3, 2,
+ 6, 5, 4, 4, 2, 2, 1, 0, 3, 3, 2, 1, 0, 0, -1, -2,
+ 1, 1, 0, -1, -2, -2, -3, -3, -1, -1, -2, -3, -4, -4, -5, -5,
+ -3, -4, -4, -5, -6, -6, -7, -7, -5, -5, -6, -7, -8, -8, -8, -8,
+ -14,-13,-12,-11, -9, -7, -6, -4,-12,-11,-10, -9, -7, -5, -3, -1,
+ -10, -9, -7, -6, -3, -2, 0, 2, -8, -6, -4, -2, 0, 2, 4, 5,
+ -5, -3, 0, 2, 4, 5, 7, 8, -2, 0, 2, 4, 6, 8, 9, 10,
+ 0, 3, 5, 7, 8, 10, 11, 12, 3, 5, 7, 8, 10, 11, 12, 12,
+ -19,-19,-18,-18,-17,-16,-15,-14,-15,-15,-14,-13,-12,-11,-10, -9,
+ -11,-10, -9, -8, -6, -5, -4, -3, -6, -5, -3, -2, -1, 0, 1, 2,
+ -1, 0, 2, 3, 4, 5, 6, 6, 4, 6, 7, 8, 9, 10, 10, 10,
+ 9, 10, 11, 12, 13, 14, 14, 14, 12, 14, 14, 15, 16, 16, 16, 16,
+ 22, 21, 19, 17, 14, 11, 9, 5, 20, 19, 17, 14, 11, 8, 4, 1,
+ 17, 15, 13, 10, 6, 3, 0, -4, 13, 11, 8, 5, 1, -2, -5, -9,
+ 9, 6, 3, -1, -4, -7,-11,-13, 4, 0, -3, -6, -9,-12,-15,-17,
+ -2, -5, -8,-11,-14,-16,-18,-20, -8,-10,-13,-16,-17,-19,-21,-22,
+ 17, 18, 18, 18, 17, 16, 16, 14, 16, 16, 15, 15, 14, 13, 12, 11,
+ 12, 12, 11, 10, 9, 8, 7, 5, 7, 6, 6, 4, 3, 2, 1, -1,
+ 1, 0, -1, -2, -3, -4, -5, -6, -5, -6, -7, -8, -9,-10,-11,-12,
+ -11,-12,-13,-14,-15,-16,-16,-17,-16,-17,-17,-18,-19,-20,-20,-20,
+ 0, 0, 0, 0, -1, -1, -2, -3, 1, 0, 0, 0, 0, -1, -2, -3,
+ 1, 1, 0, 0, -1, -1, -2, -2, 1, 1, 1, 0, 0, -1, -1, -2,
+ 2, 1, 1, 1, 0, -1, -1, -2, 2, 2, 1, 1, 0, 0, -1, -2,
+ 2, 2, 1, 1, 1, 0, -1, -1, 2, 2, 1, 1, 1, 0, 0, -2,
+ 0, -1, -1, 0, 0, 1, 2, 3, 0, -1, -1, 0, 1, 1, 2, 2,
+ -1, -1, -1, -1, 0, 1, 2, 2, -1, -1, -2, -1, 0, 1, 1, 2,
+ -1, -2, -2, -1, 0, 0, 1, 2, -1, -2, -2, -2, -1, 0, 1, 2,
+ -1, -1, -2, -1, 0, 0, 1, 2, -1, -1, -1, -1, 0, 1, 1, 2,
+ 3, 2, 2, 2, 1, 1, 0, 0, 3, 2, 2, 2, 2, 1, 0, 0,
+ 2, 2, 2, 1, 1, 1, 0, 0, 2, 2, 1, 1, 1, 0, 0, -1,
+ 1, 1, 1, 0, 0, 0, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1,
+ -2, -2, -2, -2, -2, -2, -2, -2, -2, -3, -3, -3, -2, -2, -2, -2,
+ 5, 2, 0, 0, -1, 0, 0, 0, 4, 2, 0, -1, -1, -1, 0, -1,
+ 4, 1, -1, -1, -2, -1, -1, -1, 4, 1, -1, -1, -2, -1, -1, -1,
+ 4, 1, -1, -2, -2, -1, -1, -1, 4, 1, -1, -2, -2, -1, -1, -1,
+ 4, 1, -1, -1, -1, -1, -1, -1, 4, 2, 0, -1, 0, 0, 0, -1,
+ -2, -1, 0, 1, 1, 1, 1, 1, -3, -1, 0, 1, 1, 1, 1, 1,
+ -3, -1, 0, 1, 1, 1, 1, 1, -3, -1, 0, 1, 1, 1, 1, 1,
+ -3, -2, 0, 1, 2, 2, 1, 1, -4, -2, 0, 1, 2, 2, 2, 2,
+ -5, -3, -1, 1, 1, 2, 1, 2, -5, -3, -2, 0, 1, 1, 1, 1,
+ 3, 3, 1, 0, -2, -4, -4, -5, 3, 3, 2, 0, -1, -2, -3, -4,
+ 2, 2, 1, 1, 0, -1, -2, -2, 1, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 1, 1, 1, 1, 1, -2, -1, -1, 0, 0, 1, 2, 2,
+ -3, -2, -2, -1, 0, 1, 2, 3, -3, -3, -2, -1, 0, 1, 2, 3,
+ -3, -3, -3, -3, -3, -2, -2, -2, -3, -3, -2, -2, -2, -1, -1, -1,
+ -2, -2, -2, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 2, 2, 2, 2,
+ 1, 1, 1, 2, 2, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3,
+ -8, -7, -5, -3, -2, -1, 0, -1, -4, -3, -1, 0, 1, 2, 1, 1,
+ -1, 1, 2, 3, 3, 2, 2, 1, 1, 2, 3, 3, 2, 2, 1, 0,
+ 2, 3, 3, 2, 1, 0, 0, -1, 1, 2, 1, 0, -1, -1, -1, -1,
+ 1, 1, 0, -1, -1, -2, -2, -1, 1, 1, 0, 0, -1, -1, 0, -1,
+ -4, -3, -2, 0, 1, 2, 3, 3, -4, -3, -2, 0, 1, 2, 2, 2,
+ -3, -3, -2, -1, 0, 1, 1, 1, -2, -2, -2, -1, -1, 0, 0, 0,
+ 0, -1, -1, -1, -1, -1, -1, -1, 2, 1, 1, 0, 0, -1, -1, -2,
+ 3, 3, 3, 1, 0, -1, -2, -2, 5, 4, 4, 2, 1, 0, -1, -2,
+ 0, 0, 0, 0, 1, 2, 3, 3, 0, -1, 0, 0, 1, 2, 3, 3,
+ 0, -1, 0, 0, 1, 2, 3, 2, 0, 0, 0, 1, 1, 2, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 1, 0, 0, -1, -2,
+ 2, 1, 0, 0, -2, -3, -5, -6, 0, -1, -1, -3, -5, -6, -8, -9,
+ -2, 0, 1, 2, 2, 1, -1, -4, -2, 0, 2, 2, 2, 1, -1, -4,
+ -2, 0, 2, 2, 2, 1, -1, -3, -2, 0, 2, 2, 2, 1, -1, -3,
+ -2, -1, 2, 2, 2, 1, -1, -3, -2, -1, 1, 2, 2, 1, -1, -3,
+ -3, -1, 1, 2, 2, 1, -1, -3, -2, -1, 1, 2, 2, 1, -1, -3,
+ -1, 1, 1, -1, -3, -3, 0, 4, -1, 1, 1, -1, -3, -3, 0, 4,
+ -1, 1, 1, 0, -3, -3, 0, 4, -1, 1, 2, 0, -3, -3, 0, 5,
+ 0, 1, 2, 0, -3, -4, 0, 4, 0, 1, 2, 0, -3, -4, 0, 5,
+ 0, 1, 2, 0, -3, -3, 0, 4, 0, 1, 2, -1, -2, -2, 0, 4,
+ 6, 6, 5, 6, 5, 5, 5, 5, 2, 2, 2, 2, 2, 2, 2, 2,
+ 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -2, -2, -2, -2,
+ -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,
+ -1, -1, -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 0, 1, 1, 0, 0, 0, 0, 0,
+ -1, -2, -2, -2, -2, -2, -2, -1, -3, -3, -3, -3, -3, -3, -3, -2,
+ -3, -4, -4, -3, -3, -3, -2, -2, -2, -2, -2, -2, -1, -1, 0, 0,
+ 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 6,
+ 4, 1, -2, -3, -3, -1, 1, 3, 4, 1, -2, -4, -3, -1, 1, 3,
+ 5, 1, -2, -4, -3, -1, 1, 4, 5, 1, -2, -3, -3, -1, 2, 4,
+ 5, 1, -2, -3, -3, -1, 2, 4, 4, 0, -3, -4, -3, -1, 2, 4,
+ 4, 0, -3, -3, -3, -1, 1, 3, 3, 0, -2, -3, -2, -1, 1, 3,
+ -3, -4, -4, -4, -4, -4, -4, -4, -1, -1, -1, -1, -1, -1, -2, -2,
+ 2, 1, 1, 2, 2, 1, 1, 1, 3, 3, 3, 4, 4, 3, 3, 3,
+ 3, 3, 3, 4, 4, 4, 3, 3, 1, 2, 1, 2, 2, 2, 2, 2,
+ -2, -2, -2, -1, -1, -1, 0, 0, -4, -4, -4, -4, -3, -3, -3, -3,
+ -1, -2, -3, -3, -2, -2, -1, 0, 0, -1, -2, -2, -2, -1, 0, 1,
+ 2, 1, -1, -1, -1, -1, 0, 1, 3, 1, 0, -1, -1, 0, 0, 1,
+ 3, 2, 0, -1, 0, 0, 0, 1, 3, 1, 0, -1, 0, 0, 0, 1,
+ 3, 1, 0, -1, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 1,
+ 0, 0, 0, 1, 1, 2, 3, 4, 0, 0, -1, 0, 0, 0, 2, 3,
+ 0, -1, -1, -1, -1, -1, 0, 1, 0, -1, -1, -1, -1, -1, -1, 0,
+ 0, 0, -1, -1, -1, -2, -2, -1, 1, 0, 0, -1, -1, -2, -2, -1,
+ 2, 2, 1, 0, -1, -1, -1, -1, 3, 3, 2, 1, 0, -1, -1, 0,
+ 1, 0, 1, 0, 0, -1, -2, -1, 0, 0, 0, 0, -1, -1, -2, -1,
+ 0, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0,
+ -1, -1, -1, 0, 0, 0, 1, 1, -1, -1, -1, 0, 1, 1, 2, 3,
+ -2, -2, -1, 0, 1, 2, 3, 4, -2, -2, -1, 0, 1, 2, 4, 5,
+ -3, -1, 1, 0, 0, -1, 0, 1, -3, 0, 1, 0, -1, -1, 0, 2,
+ -3, 0, 1, 0, -1, -1, 0, 2, -2, 1, 2, 0, -1, -1, 0, 2,
+ -2, 1, 2, 0, -1, -1, 0, 2, -2, 1, 2, 0, -1, -1, 0, 2,
+ -1, 2, 2, 0, -1, -1, 0, 2, -1, 1, 1, 0, -1, -1, -1, 1,
+ -2, -2, -1, 1, 3, 4, 3, 1, -2, -2, -1, 0, 2, 3, 2, 0,
+ -2, -2, -1, 0, 1, 2, 1, -1, -1, -1, -1, 0, 1, 2, 1, -1,
+ -1, -1, -1, 0, 1, 1, 0, -2, 0, -1, -1, 0, 1, 1, 0, -1,
+ 0, -1, -1, 0, 1, 1, 1, -1, 0, -1, -1, 0, 0, 1, 0, -1,
+ -2, -1, 0, 1, 1, 1, 1, 1, -2, -1, 0, 0, 0, 0, 0, 0,
+ -2, -1, -1, 0, -1, -1, -2, -2, -2, -1, -1, -1, -1, -2, -2, -3,
+ -1, 0, 1, 1, 0, -1, -2, -2, 1, 2, 3, 3, 2, 1, 0, 0,
+ 1, 2, 3, 3, 3, 2, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0,
+ 0, -1, -1, -1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, -1, 0, 0, 1, 1, 0, 0, 0,
+ -3, -2, -1, -1, -1, -1, 0, -1, -5, -5, -4, -3, -2, -2, -2, -1,
+ 1, 1, 1, 1, 2, 1, 0, -1, 1, 1, 1, 2, 1, 1, 0, -1,
+ 1, 1, 1, 1, 1, 1, 0, -2, 2, 1, 1, 1, 1, 1, 0, -2,
+ 1, 1, 0, 0, 0, 0, -1, -3, 1, 1, 0, 0, 0, -1, -2, -3,
+ 1, 1, 0, 0, -1, -1, -2, -4, 1, 0, 0, -1, -2, -2, -3, -4,
+ 8, 7, 5, 3, 2, 1, 1, 1, 2, 1, 0, 0, -1, -1, -2, -1,
+ -1, -1, -1, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0, -1, -1, 0,
+ 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
+ -1, 0, 0, 0, 0, 0, -1, -1, -2, -2, -1, -1, -1, -2, -2, -1,
+ 9, 4, 0, -2, -2, -2, -1, -1, 7, 2, -1, -2, -2, -1, 0, 0,
+ 4, 0, -2, -2, -1, 0, 1, 1, 1, -2, -2, -2, -1, 0, 1, 1,
+ -1, -2, -2, -1, 0, 1, 1, 1, -1, -2, -1, 0, 1, 1, 1, 0,
+ -1, -1, 0, 1, 1, 1, 0, -1, 0, -1, 0, 1, 0, 0, -1, -1,
+ 0, 1, 1, 1, 1, 1, 0, 0, 1, 2, 2, 2, 1, 0, 0, 0,
+ 2, 2, 2, 2, 1, 0, -1, -1, 1, 1, 1, 0, -1, -2, -2, -2,
+ 0, 0, 0, -1, -2, -3, -2, -2, -1, -1, -1, -2, -2, -2, -1, 0,
+ -1, -1, -1, -1, 0, 0, 1, 2, -1, -1, -1, 0, 1, 2, 3, 4,
+ -1, -1, 0, 0, -1, -2, -3, -3, -1, -1, 0, 0, 0, -1, -1, -1,
+ -2, -2, -1, 0, 1, 1, 1, 1, -2, -2, -2, 0, 1, 2, 3, 3,
+ -1, -1, -1, 0, 1, 3, 3, 3, 1, 0, 0, 0, 1, 1, 2, 2,
+ 2, 2, 1, 0, 0, -1, -1, -1, 3, 2, 1, 0, -1, -2, -3, -3,
+ -1, -1, -1, -2, -2, -3, -4, -5, 0, 0, 0, -1, -1, -3, -3, -4,
+ 1, 1, 1, 0, 0, -1, -2, -3, 2, 2, 2, 1, 1, 0, -1, -1,
+ 2, 2, 2, 2, 1, 1, 0, -1, 2, 2, 2, 2, 2, 1, 0, 0,
+ 1, 1, 2, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, -1,
+ -2, 2, 3, 1, -1, 1, 1, -1, -3, 2, 3, 0, -1, 1, 1, -1,
+ -3, 2, 3, 0, -1, 1, 1, -1, -4, 2, 3, 0, -1, 1, 1, -2,
+ -4, 1, 3, 0, -1, 1, 1, -2, -4, 1, 3, -1, -2, 1, 1, -2,
+ -3, 1, 2, 0, -1, 1, 1, -2, -3, 1, 2, 0, -1, 1, 1, -1,
+ -1, -1, -1, -2, -2, -2, -2, -2, 1, 1, 1, 1, 0, 0, 0, 0,
+ 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, 1, 1, 1, 2, 2, 2,
+ -2, -2, -1, -1, -1, 0, 0, 0, -3, -3, -3, -3, -3, -3, -3, -2,
+ -1, -1, -1, -1, -2, -2, -2, -2, 4, 4, 4, 4, 4, 3, 3, 2,
+ -3, -3, -2, -1, 0, 1, 2, 5, -3, -3, -3, -2, -1, 1, 3, 6,
+ -3, -3, -2, -2, 0, 2, 3, 5, -3, -2, -2, -2, 0, 1, 3, 5,
+ -2, -2, -2, -1, -1, 1, 3, 5, -2, -2, -1, -1, 0, 1, 2, 4,
+ -1, -1, -1, -1, 0, 1, 1, 4, -1, -1, -1, -1, 0, 1, 2, 3,
+ 0, -1, 0, 1, 1, 0, -1, -1, 0, 0, 0, 1, 2, 0, -1, -1,
+ 1, 0, -1, 0, 1, 0, 0, 0, 1, -1, -2, -1, 0, 0, 0, 0,
+ 1, -2, -3, -1, 0, 0, 0, 1, 1, -1, -3, -2, 0, 1, 1, 2,
+ 1, -1, -2, -1, 0, 1, 1, 2, 2, 0, -1, 0, 1, 1, 2, 2,
+ 1, 1, 1, 1, 0, 0, 1, 2, -1, 0, 0, -1, 0, 0, 0, 1,
+ -3, -2, -1, -1, -1, 0, 1, 1, -4, -2, -1, 0, 0, 1, 1, 1,
+ -3, -2, 0, 0, 1, 1, 1, 1, -3, -1, 0, 1, 1, 1, 0, 0,
+ -1, 0, 1, 1, 1, 0, 0, -1, 0, 1, 2, 2, 1, 0, 0, -1,
+ -4, -4, -4, -3, -2, -1, -1, -1, -2, -2, -2, -1, 0, 0, 0, 0,
+ -1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 2, 2, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0,
+ 0, 0, 0, 1, 1, 1, 1, 0, -1, 0, 0, 1, 1, 1, 0, 0,
+ 1, 2, 2, 2, 1, -1, -2, -4, 1, 1, 2, 2, 1, 0, -2, -4,
+ 0, 1, 1, 1, 1, 0, -1, -3, -1, 0, 1, 1, 0, 0, -1, -2,
+ -1, 0, 1, 1, 1, 0, 0, -1, -2, -1, 0, 0, 0, 0, 0, -1,
+ -1, -1, 0, 1, 1, 0, 0, 0, -1, 0, 1, 1, 1, 1, 1, 0,
+ 2, 2, 0, -1, -2, -1, -1, -2, 1, 1, -1, -2, -2, -1, -1, -2,
+ 1, 1, -1, -2, -2, 0, 0, -1, 1, 1, 0, -2, -1, 1, 1, 0,
+ 1, 1, 0, -1, -1, 1, 2, 1, 1, 1, 0, -1, -1, 1, 2, 1,
+ 1, 1, 0, -1, -1, 1, 1, 1, 1, 1, 0, -1, 0, 1, 1, 1,
+ 0, 0, -1, -2, -4, -4, -4, -4, 3, 3, 3, 2, 1, 0, 0, 0,
+ 3, 3, 3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 1,
+ -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1, 0,
+ -1, -1, 0, -1, -1, 1, 2, -1, 1, 1, 0, 0, 0, 2, 3, -1,
+ 1, 1, 0, -1, -1, 1, 3, -1, 1, 1, 0, -2, -2, 0, 1, -2,
+ 1, 0, 0, -2, -2, 0, 1, -3, 0, 0, 0, 0, -1, 1, 1, -3,
+ 0, 1, 1, 0, 1, 2, 1, -3, -1, 0, 1, 1, 1, 2, 1, -4,
+ -4, -3, 0, 1, 1, 1, 0, 0, -4, -2, 0, 1, 1, 1, 0, -1,
+ -3, -1, 1, 1, 1, 0, -1, -1, -1, 1, 1, 1, 1, 0, -1, 0,
+ 1, 2, 2, 1, 0, -1, 0, 0, 2, 2, 1, 0, -1, -1, 0, 1,
+ 2, 1, 0, -1, -2, -1, 0, 1, 2, 2, 0, -1, -2, -1, 1, 1,
+ 1, 1, 0, 0, -1, -1, -1, -1, 0, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1,
+ 1, 0, 0, -1, -1, -1, -1, -1, 2, 1, 0, 0, -1, -1, -1, -1,
+ 5, 3, 2, 1, 0, 0, 0, 0, 6, 5, 3, 2, 1, 0, 0, 0,
+ 4, 4, 3, 1, 0, 0, 0, 1, 3, 3, 2, 1, 0, 0, 0, 1,
+ 2, 2, 1, 0, -1, -1, 0, 1, 0, 0, 0, -1, -1, -1, 0, 1,
+ 0, 0, -1, -1, -2, -1, 0, 2, 0, -1, -1, -2, -2, -2, 0, 1,
+ 0, -1, -1, -2, -2, -2, -1, 0, 0, 0, -1, -2, -2, -2, -1, 0,
+ 0, 0, -1, -1, -1, 0, 2, 3, 0, -1, -2, -2, -1, -1, 1, 2,
+ 1, 0, -1, -1, -1, 0, 0, 0, 1, 1, 1, 0, 0, 0, -1, -1,
+ 1, 2, 1, 0, 0, -1, -1, -1, -1, 0, 0, 0, -1, -1, -1, -1,
+ -3, -2, -1, -1, 0, 1, 1, 2, -4, -3, -1, 1, 2, 3, 5, 5,
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 0, 0, -1, 0, 0, 0, 1, -1, -1, -2, -2, -2, -1, -1, 0,
+ 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3,
+ 1, 1, 1, 1, 2, 2, 1, 1, -4, -3, -4, -4, -4, -4, -3, -3,
+ -1, 0, 1, 2, 2, 3, 3, 3, -1, -1, -1, -1, 0, 0, 0, 0,
+ 0, 0, -1, -2, -2, -3, -3, -2, 3, 2, 1, 0, -1, -2, -2, -2,
+ 4, 3, 2, 1, 1, 0, 0, 0, 2, 2, 1, 1, 0, 1, 1, 1,
+ 0, -1, -1, -1, -1, 0, 0, 1, -2, -2, -2, -2, -2, -1, 0, 0,
+ 1, -1, 0, 2, 1, -2, -1, 1, 1, -1, 0, 2, 1, -2, -2, 1,
+ 1, -1, 0, 3, 2, -2, -1, 1, 0, -2, 0, 3, 2, -2, -2, 1,
+ 0, -2, 0, 3, 2, -2, -2, 1, 0, -2, 0, 3, 1, -2, -1, 1,
+ 0, -2, 0, 2, 1, -2, -2, 1, 0, -1, 0, 2, 1, -2, -1, 1,
+ 0, 1, 2, 2, 3, 3, 2, 2, 0, 1, 1, 2, 3, 3, 2, 1,
+ 0, 0, 1, 2, 2, 2, 2, 1, -1, 0, 0, 1, 1, 1, 1, 1,
+ -1, -1, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1,
+ -2, -2, -2, -2, -2, -2, -2, -1, -2, -2, -2, -2, -2, -2, -2, -1,
+ 0, 0, -1, -2, -1, 0, 3, 5, 0, 0, -1, -1, -1, 0, 2, 4,
+ 1, 1, 0, 0, -1, -1, 1, 2, 1, 2, 1, 1, 0, -1, -1, 0,
+ 0, 1, 2, 1, 0, -1, -2, -2, -1, 0, 1, 2, 1, 0, -3, -3,
+ -2, -1, 1, 2, 2, 0, -2, -4, -2, -1, 0, 2, 2, 1, -1, -3,
+ 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, -1, 0, 0, 0, 0, 0,
+ -1, -1, -1, -1, 0, 0, 0, 0, -1, -1, -1, -1, -1, -1, -1, 0,
+ -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, 0, 0, 0, -1, -1, 0,
+ 0, 0, 1, 1, 0, 0, 0, 1, 3, 3, 3, 4, 3, 3, 3, 3,
+ 5, 1, -2, -2, 0, 0, 0, -1, 4, -1, -3, -1, 0, 0, 0, -1,
+ 3, -1, -1, 0, 1, 1, 0, -1, 2, 0, 0, 1, 1, 1, 0, -2,
+ 1, 0, 0, 1, 1, 1, 0, -2, 0, -1, -1, -1, 0, 0, 0, -1,
+ 0, -1, -1, -1, -1, 0, 0, -1, 2, 1, 0, 0, 0, 1, 0, 0,
+ 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0,
+ 1, -1, -1, 0, 0, 0, 0, 0, 2, 0, -1, -1, -1, -1, -1, 0,
+ 3, 1, -1, -1, -2, -2, -2, -1, 4, 2, 1, 0, -1, -2, -2, -1,
+ 2, 1, 0, 0, -1, -1, 0, 0, 0, -1, -1, -1, -1, 0, 1, 1,
+ 0, 1, 2, 2, 2, 1, -1, -3, 0, 0, 1, 1, 1, 0, -1, -2,
+ 0, 0, 0, 0, 0, 0, -1, -1, 0, 0, -1, 0, 0, 1, 1, 0,
+ 0, 0, -1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0,
+ 0, 0, 1, 1, 2, 1, -1, -3, 0, 0, 0, 1, 1, -1, -4, -5,
+ -2, -2, -2, -1, 0, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 0,
+ 1, 1, 1, 1, 1, 0, -2, -3, 0, 0, 1, 1, 0, -1, -3, -4,
+ -1, -1, 0, 1, 0, 0, -2, -3, -1, -1, 0, 1, 1, 1, 0, -1,
+ 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 1, 0, 0, 1, 1, 1, 2, 1, 2, 0, 0, 0, 0, -1, 1,
+ 0, 2, 0, -1, 1, 0, -1, 0, 0, 1, 0, 0, 2, 1, 0, 1,
+ 0, 1, -1, 0, 2, 2, 0, 1, -1, 0, -1, -1, 2, 1, 1, 2,
+ -2, -2, -3, -2, 0, 1, 1, 1, -2, -2, -3, -3, -1, -1, -1, 0,
+ -3, -1, 0, 1, 2, 1, 1, 0, -3, -1, 0, 1, 2, 1, 1, 1,
+ -2, 0, 0, 1, 1, 1, 1, 1, -1, 0, 0, 0, 0, 0, 0, 0,
+ -2, 0, 0, 0, 0, -1, -1, 0, -2, 0, 0, 0, 0, 0, -1, -1,
+ -3, 0, 1, 1, 1, 1, 0, 1, -5, -2, 0, 1, 2, 2, 1, 2,
+ -2, -1, -1, 0, 0, 1, 2, 3, 0, 0, 1, 1, 0, 0, 1, 2,
+ 0, 0, 1, 0, -1, -1, 0, 1, -1, -1, -1, -1, -2, -2, -1, 0,
+ -2, -2, -2, -2, -2, -1, 0, 1, 0, 0, 0, -1, 0, 1, 2, 2,
+ 2, 1, 0, 0, 0, 1, 2, 2, 2, 1, 0, -1, -1, -1, 0, 0,
+ 0, 1, 1, 1, 1, 1, -1, -4, -1, -1, 0, 1, 1, 1, 0, -3,
+ -2, -1, 0, 0, 1, 2, 2, -2, -1, 0, 0, 0, 0, 2, 3, -1,
+ -1, 0, 0, 0, 0, 1, 2, 0, 0, 0, -1, -2, -1, 1, 1, 0,
+ 0, 0, -1, -2, -2, 0, 2, 1, 0, 0, -1, -2, -1, 1, 2, 2,
+ 1, 0, 0, 0, -2, -3, -2, -3, 0, 0, 1, 0, -2, -2, -1, -1,
+ 0, -1, 1, 1, -1, -1, 0, 0, 0, -1, 1, 1, -1, -1, 0, 0,
+ 0, 1, 2, 1, -1, -1, 0, 1, 1, 2, 3, 2, 0, 0, 1, 2,
+ -1, 0, 2, 1, 0, 0, 2, 3, -2, -1, 0, 0, -1, 0, 1, 2,
+ 1, 1, 0, -1, -2, -2, -1, 1, 1, 1, 1, -1, -2, -2, 0, 2,
+ 1, 1, 1, -1, -1, -1, 0, 2, 0, 0, 0, 0, 0, 0, 1, 2,
+ -1, -1, -1, 0, 0, 0, 1, 2, -1, -2, -1, 1, 1, 1, 0, 0,
+ -1, -2, -1, 1, 2, 2, 0, -1, -1, -2, -1, 2, 2, 2, 0, -1,
+ -1, -1, -1, -2, -1, -1, 0, 1, 0, 0, -1, -1, -1, 0, 1, 2,
+ 1, 0, 0, 0, 0, 1, 1, 2, 1, 1, 0, 0, 1, 1, 1, 1,
+ 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1,
+ 1, 2, 1, 0, -1, -2, -2, -3, 2, 2, 1, 0, -2, -3, -4, -4,
+ -4, -2, 1, 1, 1, 1, 0, 0, -2, 0, 1, 0, 0, 0, 0, 0,
+ 0, 1, 1, -2, -2, -1, 0, 1, 2, 2, 1, -2, -2, -1, 1, 2,
+ 1, 2, 1, -2, -2, -1, 1, 2, -1, 1, 1, -1, -1, -1, 0, 1,
+ -2, 0, 1, 1, 0, -1, -1, 0, -2, 0, 2, 2, 1, -1, -1, 0,
+ 1, 1, 0, 0, 0, 1, 0, 0, -2, -3, -3, -2, -2, -1, 0, 0,
+ -3, -4, -3, -2, -1, 0, 0, 0, -1, -1, 0, 1, 2, 3, 2, 1,
+ 0, 1, 2, 3, 3, 3, 2, 1, 1, 1, 1, 2, 1, 0, 0, -1,
+ 0, 0, 0, 0, -1, -1, -1, -1, 0, -1, -1, 0, 0, 0, 0, 0,
+ 1, 1, 0, 0, -1, -1, 0, 2, 0, 0, 1, 0, -1, -1, 1, 1,
+ -2, -1, 0, 1, 1, 1, 1, 1, -3, -3, 0, 2, 2, 1, 1, 0,
+ -2, -2, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, -1, -1,
+ 3, 1, -1, -3, -2, -1, 0, 1, 4, 2, -1, -3, -3, -1, 1, 2,
+ 0, 0, 0, -1, -1, -1, -1, -1, 1, 2, 1, 0, 0, 0, -1, -1,
+ 2, 3, 3, 2, 1, 0, -1, -1, 3, 4, 4, 2, 1, 0, -1, -2,
+ 3, 3, 2, 1, 0, -1, -2, -2, 1, 1, 0, -1, -1, -2, -2, -3,
+ 0, 0, 0, -1, -1, -2, -2, -2, -1, -1, -1, -1, -1, -2, -2, -1,
+ 1, 2, 2, 2, 2, 1, 2, 2, 0, 1, 1, 1, 1, 0, 0, 0,
+ 0, 0, 0, 1, 1, 0, -1, -2, 0, 0, 0, 0, 1, 0, -1, -4,
+ 1, 0, 0, 0, 0, 0, -2, -5, 1, 0, 0, 0, 0, 0, -1, -4,
+ 1, 0, -1, 0, 0, 0, -1, -3, 0, -1, -1, 0, 1, 1, 1, -1,
+ -2, -1, 0, 0, -1, -1, -1, -2, -1, 0, 0, 0, -1, -1, -2, -2,
+ 0, 1, 1, 0, -1, -1, -1, -2, 0, 1, 1, 0, 0, 0, -1, -1,
+ 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 2, 2, 1,
+ 1, 1, 0, 0, 1, 2, 2, 1, 1, 1, 0, -1, 0, 1, 1, 0,
+ 4, 2, 1, 0, 0, 1, 1, 1, 4, 2, 1, 0, 0, 0, 0, 1,
+ 3, 1, 0, 0, -1, -1, -1, 0, 1, 0, 0, -1, -1, -2, -1, 0,
+ 0, 0, 0, 0, -1, -1, -1, 0, -1, -1, 0, 0, -1, -1, 0, 1,
+ -2, -1, 0, -1, -1, 0, 0, 1, -2, -2, -1, -2, -1, 0, 0, 1,
+ 0, 1, 1, 1, 2, 1, 0, -1, -1, -1, -1, 0, 0, -1, -2, -2,
+ -1, 0, -1, 0, 0, -1, -2, -1, 0, 0, 0, 0, 0, 0, 1, 2,
+ 0, 0, 0, 0, 0, 0, 2, 3, -1, 0, -1, -1, -1, -1, 0, 3,
+ -1, 0, 0, -1, -1, -2, 0, 3, 0, 0, 0, 0, -1, -1, 1, 4,
+ 2, 2, 0, 0, 0, 0, 0, 1, 1, 1, -1, -2, -1, -2, -1, 1,
+ -1, -1, -2, -2, -2, -3, -2, 0, -1, 0, -1, -1, -1, -2, -1, 1,
+ 1, 1, 0, 0, 1, 0, 0, 1, 2, 2, 0, 0, 1, 0, 0, 1,
+ 2, 2, 0, 0, 0, 0, -1, -1, 2, 2, 0, 0, 1, 0, -1, -1,
+ -1, 0, 1, 1, 0, -1, -1, -1, 1, 2, 3, 2, 1, 0, 0, 0,
+ 0, 1, 1, 1, 0, -1, 0, 0, -2, -2, -1, 0, 1, 0, 0, 0,
+ -2, -2, -1, 2, 2, 2, 1, 0, -2, -1, 0, 1, 1, 0, 0, -1,
+ -1, -1, 0, 0, -1, -2, -1, -2, 0, 1, 1, 1, 0, 0, 1, 1,
+ -3, -3, -3, -2, -1, -1, -2, -2, -1, -1, 0, 1, 2, 1, 0, 0,
+ 1, 1, 1, 2, 2, 1, 0, 0, 1, 1, 1, 1, 1, 0, -1, 1,
+ 1, 0, -1, -1, 0, 0, -1, 1, 0, -1, -1, -1, 0, -1, -1, 1,
+ 1, 0, -1, 0, 0, -1, 0, 2, 2, 0, -1, 0, 0, 0, 0, 2,
+ 1, 0, -2, -1, 0, 1, 1, 0, 2, 0, -1, -1, 0, 1, 1, 0,
+ 1, 0, -2, -1, 0, 1, 0, -1, 1, 0, -1, -1, 0, 1, 0, -1,
+ 0, 1, 1, 0, 1, 1, 0, 0, -2, 1, 2, 1, 0, 0, 0, 1,
+ -5, 0, 2, 1, 0, -1, 0, 1, -6, -1, 2, 1, 0, -1, 0, 0,
+ 5, 3, 0, -1, -2, -1, -1, -1, 1, 1, 0, -1, -1, 0, -1, -1,
+ -1, 0, 1, 1, 2, 2, 1, 0, -2, -1, 0, 1, 2, 1, 1, 1,
+ -2, -1, -1, -1, 0, -1, 0, 1, 0, 1, 0, 0, -1, -1, 0, 0,
+ 0, 1, 1, 1, 1, 0, 0, 0, -3, -2, 0, 1, 1, 0, 0, -1,
+ -1, 0, 1, 0, -1, 0, 2, 3, -1, 0, 0, -2, -4, -2, -1, 0,
+ 0, 1, 1, 0, -2, -1, 0, -1, 1, 2, 3, 1, 0, 1, 1, 0,
+ -1, 0, 1, 1, 1, 1, 1, 0, -2, -3, -2, 0, 0, 0, 1, 0,
+ -1, -2, -2, 0, 1, 0, 0, -1, 3, 1, 0, 0, 1, 0, -1, -1,
+ -2, -1, 0, 0, -1, -1, 0, 0, -1, 0, 0, 0, 0, 1, 1, 1,
+ -1, -1, -1, 0, 1, 1, 1, 1, 0, -2, -3, -1, 1, 0, 0, 0,
+ 1, -1, -3, -1, 1, 1, 0, -1, 3, 1, -1, 1, 2, 2, 0, -1,
+ 3, 1, 0, 1, 2, 1, 1, 0, 0, -2, -2, -1, -1, 0, 0, 0,
+ 1, 0, -1, -1, 1, 2, 1, 0, 0, -1, -2, -1, 1, 2, 2, 1,
+ -1, -1, -1, 0, 0, 1, 2, 0, -2, 0, 0, 0, 0, 0, 1, -1,
+ -1, 0, 1, 0, -1, -1, -1, -1, 0, 1, 1, 2, 0, -2, -1, 0,
+ 1, 2, 2, 2, 1, -1, -1, 0, 0, 1, 1, 1, 0, -2, -2, -1,
+ 0, 0, -1, -1, -1, -1, -2, -2, 0, 0, -1, 0, 1, 2, 2, 1,
+ 0, 0, -1, -1, 0, 1, 2, 2, 1, 1, -1, -2, -1, -1, -1, -1,
+ 2, 2, 1, 0, 0, -1, -2, -2, 1, 2, 2, 1, 0, 0, -2, -2,
+ 0, 0, 0, 0, 1, 1, 0, -1, 0, -1, -1, -1, 2, 3, 2, 1,
+ 0, -2, 1, 2, -1, 0, 0, 1, -1, -2, 2, 3, -1, 0, 0, 0,
+ 0, -2, 2, 3, -1, -1, 0, 0, 0, -1, 3, 2, -2, 0, 1, 0,
+ 0, -1, 3, 1, -2, 0, 1, 0, 0, -1, 2, 1, -1, 1, 0, -1,
+ 0, 0, 1, -1, -2, 0, 0, -1, 1, 0, 0, -2, -2, -1, -1, -1,
+ 1, 1, 1, 1, 1, -1, -1, -2, 0, 0, 0, 1, 1, 1, 1, 1,
+ 0, 0, 0, 1, 1, 1, 2, 3, 1, 0, 0, -1, 0, 0, 1, 2,
+ 0, -1, -1, -2, -1, 0, 1, 2, -2, -2, -2, -2, -1, 0, 1, 1,
+ -1, -1, -1, -1, 0, 0, 0, -1, 2, 2, 2, 0, -1, -1, -2, -4,
+ -1, -2, -1, -1, 0, 1, 2, 3, -1, -1, -1, -1, 0, 1, 2, 3,
+ 1, 0, -1, 0, -1, 0, 1, 2, 1, 0, 0, 0, -1, 0, 2, 2,
+ 1, 0, -1, -1, -2, 0, 1, 2, 0, -2, -2, -2, -3, -1, 0, 1,
+ 0, -2, -2, -2, -2, -1, 1, 1, 0, 0, 0, 0, 0, 1, 2, 2
};
-const uint32 *const s_svq1IntraCodebooks[6] = {
+static const int8 *const s_svq1IntraCodebooks[6] = {
s_svq1IntraCodebook4x2, s_svq1IntraCodebook4x4,
s_svq1IntraCodebook8x4, s_svq1IntraCodebook8x8,
0, 0
diff --git a/video/coktel_decoder.cpp b/video/coktel_decoder.cpp
index ae0c35cd76..5d7efe87af 100644
--- a/video/coktel_decoder.cpp
+++ b/video/coktel_decoder.cpp
@@ -53,7 +53,8 @@ CoktelDecoder::CoktelDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundT
_mixer(mixer), _soundType(soundType), _width(0), _height(0), _x(0), _y(0),
_defaultX(0), _defaultY(0), _features(0), _frameCount(0), _paletteDirty(false),
_ownSurface(true), _frameRate(12), _hasSound(false), _soundEnabled(false),
- _soundStage(kSoundNone), _audioStream(0) {
+ _soundStage(kSoundNone), _audioStream(0), _startTime(0), _pauseStartTime(0),
+ _isPaused(false) {
assert(_mixer);
@@ -261,6 +262,10 @@ bool CoktelDecoder::isPaletted() const {
return true;
}
+int CoktelDecoder::getCurFrame() const {
+ return _curFrame;
+}
+
void CoktelDecoder::close() {
disableSound();
freeSurface();
@@ -273,9 +278,22 @@ void CoktelDecoder::close() {
_features = 0;
- _frameCount = 0;
+ _curFrame = -1;
+ _frameCount = 0;
+
+ _startTime = 0;
_hasSound = false;
+
+ _isPaused = false;
+}
+
+Audio::Mixer::SoundType CoktelDecoder::getSoundType() const {
+ return _soundType;
+}
+
+Audio::AudioStream *CoktelDecoder::getAudioStream() const {
+ return _audioStream;
}
uint16 CoktelDecoder::getWidth() const {
@@ -291,6 +309,7 @@ uint32 CoktelDecoder::getFrameCount() const {
}
const byte *CoktelDecoder::getPalette() {
+ _paletteDirty = false;
return _palette;
}
@@ -625,14 +644,45 @@ Common::Rational CoktelDecoder::getFrameRate() const {
return _frameRate;
}
+uint32 CoktelDecoder::getTimeToNextFrame() const {
+ if (endOfVideo() || _curFrame < 0)
+ return 0;
+
+ uint32 elapsedTime = g_system->getMillis() - _startTime;
+ uint32 nextFrameStartTime = (Common::Rational((_curFrame + 1) * 1000) / getFrameRate()).toInt();
+
+ if (nextFrameStartTime <= elapsedTime)
+ return 0;
+
+ return nextFrameStartTime - elapsedTime;
+}
+
uint32 CoktelDecoder::getStaticTimeToNextFrame() const {
return (1000 / _frameRate).toInt();
}
+void CoktelDecoder::pauseVideo(bool pause) {
+ if (_isPaused != pause) {
+ if (_isPaused) {
+ // Add the time we were paused to the initial starting time
+ _startTime += g_system->getMillis() - _pauseStartTime;
+ } else {
+ // Store the time we paused for use later
+ _pauseStartTime = g_system->getMillis();
+ }
+
+ _isPaused = pause;
+ }
+}
+
inline void CoktelDecoder::unsignedToSigned(byte *buffer, int length) {
while (length-- > 0) *buffer++ ^= 0x80;
}
+bool CoktelDecoder::endOfVideo() const {
+ return !isVideoLoaded() || (getCurFrame() >= (int32)getFrameCount() - 1);
+}
+
PreIMDDecoder::PreIMDDecoder(uint16 width, uint16 height,
Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) : CoktelDecoder(mixer, soundType),
@@ -646,6 +696,21 @@ PreIMDDecoder::~PreIMDDecoder() {
close();
}
+bool PreIMDDecoder::reloadStream(Common::SeekableReadStream *stream) {
+ if (!_stream)
+ return false;
+
+ if (!stream->seek(_stream->pos())) {
+ close();
+ return false;
+ }
+
+ delete _stream;
+ _stream = stream;
+
+ return true;
+}
+
bool PreIMDDecoder::seek(int32 frame, int whence, bool restart) {
if (!evaluateSeekFrame(frame, whence))
return false;
@@ -690,8 +755,6 @@ bool PreIMDDecoder::loadStream(Common::SeekableReadStream *stream) {
}
void PreIMDDecoder::close() {
- reset();
-
CoktelDecoder::close();
delete _stream;
@@ -840,6 +903,21 @@ IMDDecoder::~IMDDecoder() {
close();
}
+bool IMDDecoder::reloadStream(Common::SeekableReadStream *stream) {
+ if (!_stream)
+ return false;
+
+ if (!stream->seek(_stream->pos())) {
+ close();
+ return false;
+ }
+
+ delete _stream;
+ _stream = stream;
+
+ return true;
+}
+
bool IMDDecoder::seek(int32 frame, int whence, bool restart) {
if (!evaluateSeekFrame(frame, whence))
return false;
@@ -1129,8 +1207,6 @@ bool IMDDecoder::loadFrameTables(uint32 framePosPos, uint32 frameCoordsPos) {
}
void IMDDecoder::close() {
- reset();
-
CoktelDecoder::close();
delete _stream;
@@ -1195,8 +1271,6 @@ void IMDDecoder::processFrame() {
_dirtyRects.clear();
- _paletteDirty = false;
-
uint32 cmd = 0;
bool hasNextCmd = false;
bool startSound = false;
@@ -1243,7 +1317,7 @@ void IMDDecoder::processFrame() {
// Set palette
if (cmd == kCommandPalette) {
_stream->skip(2);
-
+
_paletteDirty = true;
for (int i = 0; i < 768; i++)
@@ -1512,7 +1586,7 @@ VMDDecoder::VMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType) :
_soundLastFilledFrame(0), _audioFormat(kAudioFormat8bitRaw),
_hasVideo(false), _videoCodec(0), _blitMode(0), _bytesPerPixel(0),
_firstFramePos(0), _videoBufferSize(0), _externalCodec(false), _codec(0),
- _subtitle(-1), _isPaletted(true) {
+ _subtitle(-1), _isPaletted(true), _autoStartSound(true) {
_videoBuffer [0] = 0;
_videoBuffer [1] = 0;
@@ -1526,6 +1600,21 @@ VMDDecoder::~VMDDecoder() {
close();
}
+bool VMDDecoder::reloadStream(Common::SeekableReadStream *stream) {
+ if (!_stream)
+ return false;
+
+ if (!stream->seek(_stream->pos())) {
+ close();
+ return false;
+ }
+
+ delete _stream;
+ _stream = stream;
+
+ return true;
+}
+
bool VMDDecoder::seek(int32 frame, int whence, bool restart) {
if (!evaluateSeekFrame(frame, whence))
return false;
@@ -1959,8 +2048,6 @@ bool VMDDecoder::readFiles() {
}
void VMDDecoder::close() {
- reset();
-
CoktelDecoder::close();
delete _stream;
@@ -2040,7 +2127,6 @@ void VMDDecoder::processFrame() {
_dirtyRects.clear();
- _paletteDirty = false;
_subtitle = -1;
bool startSound = false;
@@ -2160,8 +2246,9 @@ void VMDDecoder::processFrame() {
if (startSound && _soundEnabled) {
if (_hasSound && _audioStream) {
- _mixer->playStream(_soundType, &_audioHandle, _audioStream,
- -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+ if (_autoStartSound)
+ _mixer->playStream(_soundType, &_audioHandle, _audioStream,
+ -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
_soundStage = kSoundPlaying;
} else
_soundStage = kSoundNone;
@@ -2687,6 +2774,94 @@ bool VMDDecoder::isPaletted() const {
return _isPaletted;
}
+void VMDDecoder::setAutoStartSound(bool autoStartSound) {
+ _autoStartSound = autoStartSound;
+}
+
+AdvancedVMDDecoder::AdvancedVMDDecoder(Audio::Mixer::SoundType soundType) {
+ _decoder = new VMDDecoder(g_system->getMixer(), soundType);
+ _decoder->setAutoStartSound(false);
+}
+
+AdvancedVMDDecoder::~AdvancedVMDDecoder() {
+ close();
+ delete _decoder;
+}
+
+bool AdvancedVMDDecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
+
+ if (!_decoder->loadStream(stream))
+ return false;
+
+ if (_decoder->hasVideo()) {
+ _videoTrack = new VMDVideoTrack(_decoder);
+ addTrack(_videoTrack);
+ }
+
+ if (_decoder->hasSound()) {
+ _audioTrack = new VMDAudioTrack(_decoder);
+ addTrack(_audioTrack);
+ }
+
+ return true;
+}
+
+void AdvancedVMDDecoder::close() {
+ VideoDecoder::close();
+ _decoder->close();
+}
+
+AdvancedVMDDecoder::VMDVideoTrack::VMDVideoTrack(VMDDecoder *decoder) : _decoder(decoder) {
+}
+
+uint16 AdvancedVMDDecoder::VMDVideoTrack::getWidth() const {
+ return _decoder->getWidth();
+}
+
+uint16 AdvancedVMDDecoder::VMDVideoTrack::getHeight() const {
+ return _decoder->getHeight();
+}
+
+Graphics::PixelFormat AdvancedVMDDecoder::VMDVideoTrack::getPixelFormat() const {
+ return _decoder->getPixelFormat();
+}
+
+int AdvancedVMDDecoder::VMDVideoTrack::getCurFrame() const {
+ return _decoder->getCurFrame();
+}
+
+int AdvancedVMDDecoder::VMDVideoTrack::getFrameCount() const {
+ return _decoder->getFrameCount();
+}
+
+const Graphics::Surface *AdvancedVMDDecoder::VMDVideoTrack::decodeNextFrame() {
+ return _decoder->decodeNextFrame();
+}
+
+const byte *AdvancedVMDDecoder::VMDVideoTrack::getPalette() const {
+ return _decoder->getPalette();
+}
+
+bool AdvancedVMDDecoder::VMDVideoTrack::hasDirtyPalette() const {
+ return _decoder->hasDirtyPalette();
+}
+
+Common::Rational AdvancedVMDDecoder::VMDVideoTrack::getFrameRate() const {
+ return _decoder->getFrameRate();
+}
+
+AdvancedVMDDecoder::VMDAudioTrack::VMDAudioTrack(VMDDecoder *decoder) : _decoder(decoder) {
+}
+
+Audio::Mixer::SoundType AdvancedVMDDecoder::VMDAudioTrack::getSoundType() const {
+ return _decoder->getSoundType();
+}
+
+Audio::AudioStream *AdvancedVMDDecoder::VMDAudioTrack::getAudioStream() const {
+ return _decoder->getAudioStream();
+}
+
} // End of namespace Video
#endif // VIDEO_COKTELDECODER_H
diff --git a/video/coktel_decoder.h b/video/coktel_decoder.h
index b99a44f332..91d52b65e6 100644
--- a/video/coktel_decoder.h
+++ b/video/coktel_decoder.h
@@ -64,7 +64,7 @@ class Codec;
* - gob
* - sci
*/
-class CoktelDecoder : public FixedRateVideoDecoder {
+class CoktelDecoder {
public:
struct State {
/** Set accordingly to what was done. */
@@ -77,7 +77,10 @@ public:
CoktelDecoder(Audio::Mixer *mixer,
Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
- ~CoktelDecoder();
+ virtual ~CoktelDecoder();
+
+ /** Replace the current video stream with this identical one. */
+ virtual bool reloadStream(Common::SeekableReadStream *stream) = 0;
virtual bool seek(int32 frame, int whence = SEEK_SET, bool restart = false) = 0;
@@ -95,6 +98,8 @@ public:
/** Override the video's frame rate. */
void setFrameRate(Common::Rational frameRate);
+ /** Get the video's frame rate. */
+ Common::Rational getFrameRate() const;
/** Get the video's default X position. */
uint16 getDefaultX() const;
@@ -135,21 +140,52 @@ public:
/** Is the video paletted or true color? */
virtual bool isPaletted() const;
+ /**
+ * Get the current frame
+ * @see VideoDecoder::getCurFrame()
+ */
+ int getCurFrame() const;
+
+ /**
+ * Decode the next frame
+ * @see VideoDecoder::decodeNextFrame()
+ */
+ virtual const Graphics::Surface *decodeNextFrame() = 0;
- // VideoDecoder interface
+ /**
+ * Load a video from a stream
+ * @see VideoDecoder::loadStream()
+ */
+ virtual bool loadStream(Common::SeekableReadStream *stream) = 0;
+ /** Has a video been loaded? */
+ virtual bool isVideoLoaded() const = 0;
+
+ /** Has the end of the video been reached? */
+ bool endOfVideo() const;
+
+ /** Close the video. */
void close();
+ /** Get the Mixer SoundType audio is being played with. */
+ Audio::Mixer::SoundType getSoundType() const;
+ /** Get the AudioStream for the audio. */
+ Audio::AudioStream *getAudioStream() const;
+
uint16 getWidth() const;
uint16 getHeight() const;
+ virtual Graphics::PixelFormat getPixelFormat() const = 0;
uint32 getFrameCount() const;
const byte *getPalette();
bool hasDirtyPalette() const;
+ uint32 getTimeToNextFrame() const;
uint32 getStaticTimeToNextFrame() const;
+ void pauseVideo(bool pause);
+
protected:
enum SoundStage {
kSoundNone = 0, ///< No sound.
@@ -183,8 +219,11 @@ protected:
uint32 _features;
+ int32 _curFrame;
uint32 _frameCount;
+ uint32 _startTime;
+
byte _palette[768];
bool _paletteDirty;
@@ -225,10 +264,9 @@ protected:
// Sound helper functions
inline void unsignedToSigned(byte *buffer, int length);
-
- // FixedRateVideoDecoder interface
-
- Common::Rational getFrameRate() const;
+private:
+ uint32 _pauseStartTime;
+ bool _isPaused;
};
class PreIMDDecoder : public CoktelDecoder {
@@ -237,10 +275,9 @@ public:
Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
~PreIMDDecoder();
- bool seek(int32 frame, int whence = SEEK_SET, bool restart = false);
-
+ bool reloadStream(Common::SeekableReadStream *stream);
- // VideoDecoder interface
+ bool seek(int32 frame, int whence = SEEK_SET, bool restart = false);
bool loadStream(Common::SeekableReadStream *stream);
void close();
@@ -268,13 +305,12 @@ public:
IMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
~IMDDecoder();
+ bool reloadStream(Common::SeekableReadStream *stream);
+
bool seek(int32 frame, int whence = SEEK_SET, bool restart = false);
void setXY(uint16 x, uint16 y);
-
- // VideoDecoder interface
-
bool loadStream(Common::SeekableReadStream *stream);
void close();
@@ -355,10 +391,14 @@ private:
};
class VMDDecoder : public CoktelDecoder {
+friend class AdvancedVMDDecoder;
+
public:
VMDDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
~VMDDecoder();
+ bool reloadStream(Common::SeekableReadStream *stream);
+
bool seek(int32 frame, int whence = SEEK_SET, bool restart = false);
void setXY(uint16 x, uint16 y);
@@ -376,9 +416,6 @@ public:
bool hasVideo() const;
bool isPaletted() const;
-
- // VideoDecoder interface
-
bool loadStream(Common::SeekableReadStream *stream);
void close();
@@ -388,6 +425,9 @@ public:
Graphics::PixelFormat getPixelFormat() const;
+protected:
+ void setAutoStartSound(bool autoStartSound);
+
private:
enum PartType {
kPartTypeSeparator = 0,
@@ -459,6 +499,7 @@ private:
uint32 _soundDataSize;
uint32 _soundLastFilledFrame;
AudioFormat _audioFormat;
+ bool _autoStartSound;
// Video properties
bool _hasVideo;
@@ -513,6 +554,57 @@ private:
bool getPartCoords(int16 frame, PartType type, int16 &x, int16 &y, int16 &width, int16 &height);
};
+/**
+ * A wrapper around the VMD code that implements the VideoDecoder
+ * API.
+ */
+class AdvancedVMDDecoder : public VideoDecoder {
+public:
+ AdvancedVMDDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
+ ~AdvancedVMDDecoder();
+
+ bool loadStream(Common::SeekableReadStream *stream);
+ void close();
+
+private:
+ class VMDVideoTrack : public FixedRateVideoTrack {
+ public:
+ VMDVideoTrack(VMDDecoder *decoder);
+
+ uint16 getWidth() const;
+ uint16 getHeight() const;
+ Graphics::PixelFormat getPixelFormat() const;
+ int getCurFrame() const;
+ int getFrameCount() const;
+ const Graphics::Surface *decodeNextFrame();
+ const byte *getPalette() const;
+ bool hasDirtyPalette() const;
+
+ protected:
+ Common::Rational getFrameRate() const;
+
+ private:
+ VMDDecoder *_decoder;
+ };
+
+ class VMDAudioTrack : public AudioTrack {
+ public:
+ VMDAudioTrack(VMDDecoder *decoder);
+
+ Audio::Mixer::SoundType getSoundType() const;
+
+ protected:
+ virtual Audio::AudioStream *getAudioStream() const;
+
+ private:
+ VMDDecoder *_decoder;
+ };
+
+ VMDDecoder *_decoder;
+ VMDVideoTrack *_videoTrack;
+ VMDAudioTrack *_audioTrack;
+};
+
} // End of namespace Video
#endif // VIDEO_COKTELDECODER_H
diff --git a/video/dxa_decoder.cpp b/video/dxa_decoder.cpp
index 7d1112a59c..5ac9bd2088 100644
--- a/video/dxa_decoder.cpp
+++ b/video/dxa_decoder.cpp
@@ -37,41 +37,43 @@
namespace Video {
DXADecoder::DXADecoder() {
- _fileStream = 0;
- _surface = 0;
- _dirtyPalette = false;
+}
- _frameBuffer1 = 0;
- _frameBuffer2 = 0;
- _scaledBuffer = 0;
+DXADecoder::~DXADecoder() {
+ close();
+}
- _inBuffer = 0;
- _inBufferSize = 0;
+bool DXADecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
- _decompBuffer = 0;
- _decompBufferSize = 0;
+ uint32 tag = stream->readUint32BE();
- _width = 0;
- _height = 0;
+ if (tag != MKTAG('D','E','X','A')) {
+ close();
+ return false;
+ }
- _frameSize = 0;
- _frameCount = 0;
- _frameRate = 0;
+ DXAVideoTrack *track = new DXAVideoTrack(stream);
+ addTrack(track);
- _scaleMode = S_NONE;
-}
+ readSoundData(stream);
-DXADecoder::~DXADecoder() {
- close();
+ track->setFrameStartPos();
+ return true;
}
-bool DXADecoder::loadStream(Common::SeekableReadStream *stream) {
- close();
+void DXADecoder::readSoundData(Common::SeekableReadStream *stream) {
+ // Skip over the tag by default
+ stream->readUint32BE();
+}
+DXADecoder::DXAVideoTrack::DXAVideoTrack(Common::SeekableReadStream *stream) {
_fileStream = stream;
-
- uint32 tag = _fileStream->readUint32BE();
- assert(tag == MKTAG('D','E','X','A'));
+ _curFrame = -1;
+ _frameStartOffset = 0;
+ _decompBuffer = 0;
+ _inBuffer = 0;
+ memset(_palette, 0, 256 * 3);
uint8 flags = _fileStream->readByte();
_frameCount = _fileStream->readUint16BE();
@@ -105,18 +107,14 @@ bool DXADecoder::loadStream(Common::SeekableReadStream *stream) {
_frameSize = _width * _height;
_decompBufferSize = _frameSize;
- _frameBuffer1 = (uint8 *)malloc(_frameSize);
+ _frameBuffer1 = new byte[_frameSize];
memset(_frameBuffer1, 0, _frameSize);
- _frameBuffer2 = (uint8 *)malloc(_frameSize);
+ _frameBuffer2 = new byte[_frameSize];
memset(_frameBuffer2, 0, _frameSize);
- if (!_frameBuffer1 || !_frameBuffer2)
- error("DXADecoder: Error allocating frame buffers (size %u)", _frameSize);
_scaledBuffer = 0;
if (_scaleMode != S_NONE) {
- _scaledBuffer = (uint8 *)malloc(_frameSize);
- if (!_scaledBuffer)
- error("Error allocating scale buffer (size %u)", _frameSize);
+ _scaledBuffer = new byte[_frameSize];
memset(_scaledBuffer, 0, _frameSize);
}
@@ -148,36 +146,33 @@ bool DXADecoder::loadStream(Common::SeekableReadStream *stream) {
} while (tag != 0);
}
#endif
-
- // Read the sound header
- _soundTag = _fileStream->readUint32BE();
-
- return true;
}
-void DXADecoder::close() {
- if (!_fileStream)
- return;
-
+DXADecoder::DXAVideoTrack::~DXAVideoTrack() {
delete _fileStream;
- _fileStream = 0;
-
delete _surface;
- _surface = 0;
+ delete[] _frameBuffer1;
+ delete[] _frameBuffer2;
+ delete[] _scaledBuffer;
+ delete[] _inBuffer;
+ delete[] _decompBuffer;
+}
- free(_frameBuffer1);
- free(_frameBuffer2);
- free(_scaledBuffer);
- free(_inBuffer);
- free(_decompBuffer);
+bool DXADecoder::DXAVideoTrack::rewind() {
+ _curFrame = -1;
+ _fileStream->seek(_frameStartOffset);
+ return true;
+}
- _inBuffer = 0;
- _decompBuffer = 0;
+Graphics::PixelFormat DXADecoder::DXAVideoTrack::getPixelFormat() const {
+ return _surface->format;
+}
- reset();
+void DXADecoder::DXAVideoTrack::setFrameStartPos() {
+ _frameStartOffset = _fileStream->pos();
}
-void DXADecoder::decodeZlib(byte *data, int size, int totalSize) {
+void DXADecoder::DXAVideoTrack::decodeZlib(byte *data, int size, int totalSize) {
#ifdef USE_ZLIB
unsigned long dstLen = totalSize;
Common::uncompress(data, &dstLen, _inBuffer, size);
@@ -187,14 +182,13 @@ void DXADecoder::decodeZlib(byte *data, int size, int totalSize) {
#define BLOCKW 4
#define BLOCKH 4
-void DXADecoder::decode12(int size) {
+void DXADecoder::DXAVideoTrack::decode12(int size) {
#ifdef USE_ZLIB
- if (_decompBuffer == NULL) {
- _decompBuffer = (byte *)malloc(_decompBufferSize);
+ if (!_decompBuffer) {
+ _decompBuffer = new byte[_decompBufferSize];
memset(_decompBuffer, 0, _decompBufferSize);
- if (_decompBuffer == NULL)
- error("Error allocating decomp buffer (size %u)", _decompBufferSize);
}
+
/* decompress the input data */
decodeZlib(_decompBuffer, size, _decompBufferSize);
@@ -287,15 +281,13 @@ void DXADecoder::decode12(int size) {
#endif
}
-void DXADecoder::decode13(int size) {
+void DXADecoder::DXAVideoTrack::decode13(int size) {
#ifdef USE_ZLIB
uint8 *codeBuf, *dataBuf, *motBuf, *maskBuf;
- if (_decompBuffer == NULL) {
- _decompBuffer = (byte *)malloc(_decompBufferSize);
+ if (!_decompBuffer) {
+ _decompBuffer = new byte[_decompBufferSize];
memset(_decompBuffer, 0, _decompBufferSize);
- if (_decompBuffer == NULL)
- error("Error allocating decomp buffer (size %u)", _decompBufferSize);
}
/* decompress the input data */
@@ -475,7 +467,7 @@ void DXADecoder::decode13(int size) {
#endif
}
-const Graphics::Surface *DXADecoder::decodeNextFrame() {
+const Graphics::Surface *DXADecoder::DXAVideoTrack::decodeNextFrame() {
uint32 tag = _fileStream->readUint32BE();
if (tag == MKTAG('C','M','A','P')) {
_fileStream->read(_palette, 256 * 3);
@@ -486,11 +478,10 @@ const Graphics::Surface *DXADecoder::decodeNextFrame() {
if (tag == MKTAG('F','R','A','M')) {
byte type = _fileStream->readByte();
uint32 size = _fileStream->readUint32BE();
- if ((_inBuffer == NULL) || (_inBufferSize < size)) {
- free(_inBuffer);
- _inBuffer = (byte *)malloc(size);
- if (_inBuffer == NULL)
- error("Error allocating input buffer (size %u)", size);
+
+ if (!_inBuffer || _inBufferSize < size) {
+ delete[] _inBuffer;
+ _inBuffer = new byte[size];
memset(_inBuffer, 0, size);
_inBufferSize = size;
}
@@ -551,9 +542,6 @@ const Graphics::Surface *DXADecoder::decodeNextFrame() {
_curFrame++;
- if (_curFrame == 0)
- _startTime = g_system->getMillis();
-
return _surface;
}
diff --git a/video/dxa_decoder.h b/video/dxa_decoder.h
index d13cd3076c..b3f2eca5e2 100644
--- a/video/dxa_decoder.h
+++ b/video/dxa_decoder.h
@@ -41,62 +41,74 @@ namespace Video {
* - sword1
* - sword2
*/
-class DXADecoder : public FixedRateVideoDecoder {
+class DXADecoder : public VideoDecoder {
public:
DXADecoder();
virtual ~DXADecoder();
bool loadStream(Common::SeekableReadStream *stream);
- void close();
-
- bool isVideoLoaded() const { return _fileStream != 0; }
- uint16 getWidth() const { return _width; }
- uint16 getHeight() const { return _height; }
- uint32 getFrameCount() const { return _frameCount; }
- const Graphics::Surface *decodeNextFrame();
- Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
- const byte *getPalette() { _dirtyPalette = false; return _palette; }
- bool hasDirtyPalette() const { return _dirtyPalette; }
+protected:
/**
- * Get the sound chunk tag of the loaded DXA file
+ * Read the sound data out of the given DXA stream
*/
- uint32 getSoundTag() { return _soundTag; }
-
-protected:
- Common::Rational getFrameRate() const { return _frameRate; }
-
- Common::SeekableReadStream *_fileStream;
+ virtual void readSoundData(Common::SeekableReadStream *stream);
private:
- void decodeZlib(byte *data, int size, int totalSize);
- void decode12(int size);
- void decode13(int size);
-
- enum ScaleMode {
- S_NONE,
- S_INTERLACED,
- S_DOUBLE
+ class DXAVideoTrack : public FixedRateVideoTrack {
+ public:
+ DXAVideoTrack(Common::SeekableReadStream *stream);
+ ~DXAVideoTrack();
+
+ bool isRewindable() const { return true; }
+ bool rewind();
+
+ uint16 getWidth() const { return _width; }
+ uint16 getHeight() const { return _height; }
+ Graphics::PixelFormat getPixelFormat() const;
+ int getCurFrame() const { return _curFrame; }
+ int getFrameCount() const { return _frameCount; }
+ const Graphics::Surface *decodeNextFrame();
+ const byte *getPalette() const { _dirtyPalette = false; return _palette; }
+ bool hasDirtyPalette() const { return _dirtyPalette; }
+
+ void setFrameStartPos();
+
+ protected:
+ Common::Rational getFrameRate() const { return _frameRate; }
+
+ private:
+ void decodeZlib(byte *data, int size, int totalSize);
+ void decode12(int size);
+ void decode13(int size);
+
+ enum ScaleMode {
+ S_NONE,
+ S_INTERLACED,
+ S_DOUBLE
+ };
+
+ Common::SeekableReadStream *_fileStream;
+ Graphics::Surface *_surface;
+
+ byte *_frameBuffer1;
+ byte *_frameBuffer2;
+ byte *_scaledBuffer;
+ byte *_inBuffer;
+ uint32 _inBufferSize;
+ byte *_decompBuffer;
+ uint32 _decompBufferSize;
+ uint16 _curHeight;
+ uint32 _frameSize;
+ ScaleMode _scaleMode;
+ uint16 _width, _height;
+ uint32 _frameRate;
+ uint32 _frameCount;
+ byte _palette[256 * 3];
+ mutable bool _dirtyPalette;
+ int _curFrame;
+ uint32 _frameStartOffset;
};
-
- Graphics::Surface *_surface;
- byte _palette[256 * 3];
- bool _dirtyPalette;
-
- byte *_frameBuffer1;
- byte *_frameBuffer2;
- byte *_scaledBuffer;
- byte *_inBuffer;
- uint32 _inBufferSize;
- byte *_decompBuffer;
- uint32 _decompBufferSize;
- uint16 _curHeight;
- uint32 _frameSize;
- ScaleMode _scaleMode;
- uint32 _soundTag;
- uint16 _width, _height;
- uint32 _frameRate;
- uint32 _frameCount;
};
} // End of namespace Video
diff --git a/video/flic_decoder.cpp b/video/flic_decoder.cpp
index bdcdedc142..1a0627615b 100644
--- a/video/flic_decoder.cpp
+++ b/video/flic_decoder.cpp
@@ -26,13 +26,11 @@
#include "common/stream.h"
#include "common/system.h"
#include "common/textconsole.h"
+#include "graphics/surface.h"
namespace Video {
FlicDecoder::FlicDecoder() {
- _paletteChanged = false;
- _fileStream = 0;
- _surface = 0;
}
FlicDecoder::~FlicDecoder() {
@@ -42,35 +40,59 @@ FlicDecoder::~FlicDecoder() {
bool FlicDecoder::loadStream(Common::SeekableReadStream *stream) {
close();
- _fileStream = stream;
-
- /* uint32 frameSize = */ _fileStream->readUint32LE();
- uint16 frameType = _fileStream->readUint16LE();
+ /* uint32 frameSize = */ stream->readUint32LE();
+ uint16 frameType = stream->readUint16LE();
// Check FLC magic number
if (frameType != 0xAF12) {
- warning("FlicDecoder::FlicDecoder(): attempted to load non-FLC data (type = 0x%04X)", frameType);
- delete _fileStream;
- _fileStream = 0;
+ warning("FlicDecoder::loadStream(): attempted to load non-FLC data (type = 0x%04X)", frameType);
return false;
}
-
- _frameCount = _fileStream->readUint16LE();
- uint16 width = _fileStream->readUint16LE();
- uint16 height = _fileStream->readUint16LE();
- uint16 colorDepth = _fileStream->readUint16LE();
+ uint16 frameCount = stream->readUint16LE();
+ uint16 width = stream->readUint16LE();
+ uint16 height = stream->readUint16LE();
+ uint16 colorDepth = stream->readUint16LE();
if (colorDepth != 8) {
- warning("FlicDecoder::FlicDecoder(): attempted to load an FLC with a palette of color depth %d. Only 8-bit color palettes are supported", frameType);
- delete _fileStream;
- _fileStream = 0;
+ warning("FlicDecoder::loadStream(): attempted to load an FLC with a palette of color depth %d. Only 8-bit color palettes are supported", colorDepth);
return false;
}
+ addTrack(new FlicVideoTrack(stream, frameCount, width, height));
+ return true;
+}
+
+const Common::List<Common::Rect> *FlicDecoder::getDirtyRects() const {
+ const Track *track = getTrack(0);
+
+ if (track)
+ return ((const FlicVideoTrack *)track)->getDirtyRects();
+
+ return 0;
+}
+
+void FlicDecoder::clearDirtyRects() {
+ Track *track = getTrack(0);
+
+ if (track)
+ ((FlicVideoTrack *)track)->clearDirtyRects();
+}
+
+void FlicDecoder::copyDirtyRectsToBuffer(uint8 *dst, uint pitch) {
+ Track *track = getTrack(0);
+
+ if (track)
+ ((FlicVideoTrack *)track)->copyDirtyRectsToBuffer(dst, pitch);
+}
+
+FlicDecoder::FlicVideoTrack::FlicVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height) {
+ _fileStream = stream;
+ _frameCount = frameCount;
+
_fileStream->readUint16LE(); // flags
// Note: The normal delay is a 32-bit integer (dword), whereas the overridden delay is a 16-bit integer (word)
// the frame delay is the FLIC "speed", in milliseconds.
- _frameRate = Common::Rational(1000, _fileStream->readUint32LE());
+ _frameDelay = _startFrameDelay = _fileStream->readUint32LE();
_fileStream->seek(80);
_offsetFrame1 = _fileStream->readUint32LE();
@@ -78,112 +100,53 @@ bool FlicDecoder::loadStream(Common::SeekableReadStream *stream) {
_surface = new Graphics::Surface();
_surface->create(width, height, Graphics::PixelFormat::createFormatCLUT8());
- _palette = (byte *)malloc(3 * 256);
+ _palette = new byte[3 * 256];
memset(_palette, 0, 3 * 256);
- _paletteChanged = false;
+ _dirtyPalette = false;
+
+ _curFrame = -1;
+ _nextFrameStartTime = 0;
+ _atRingFrame = false;
// Seek to the first frame
_fileStream->seek(_offsetFrame1);
- return true;
}
-void FlicDecoder::close() {
- if (!_fileStream)
- return;
-
+FlicDecoder::FlicVideoTrack::~FlicVideoTrack() {
delete _fileStream;
- _fileStream = 0;
+ delete[] _palette;
_surface->free();
delete _surface;
- _surface = 0;
-
- free(_palette);
- _dirtyRects.clear();
-
- reset();
}
-void FlicDecoder::decodeByteRun(uint8 *data) {
- byte *ptr = (byte *)_surface->pixels;
- while ((int32)(ptr - (byte *)_surface->pixels) < (getWidth() * getHeight())) {
- int chunks = *data++;
- while (chunks--) {
- int count = (int8)*data++;
- if (count > 0) {
- memset(ptr, *data++, count);
- } else {
- count = -count;
- memcpy(ptr, data, count);
- data += count;
- }
- ptr += count;
- }
- }
-
- // Redraw
- _dirtyRects.clear();
- _dirtyRects.push_back(Common::Rect(0, 0, getWidth(), getHeight()));
+bool FlicDecoder::FlicVideoTrack::endOfTrack() const {
+ return getCurFrame() >= getFrameCount() - 1;
}
-#define OP_PACKETCOUNT 0
-#define OP_UNDEFINED 1
-#define OP_LASTPIXEL 2
-#define OP_LINESKIPCOUNT 3
-
-void FlicDecoder::decodeDeltaFLC(uint8 *data) {
- uint16 linesInChunk = READ_LE_UINT16(data); data += 2;
- uint16 currentLine = 0;
- uint16 packetCount = 0;
-
- while (linesInChunk--) {
- uint16 opcode;
+bool FlicDecoder::FlicVideoTrack::rewind() {
+ _curFrame = -1;
+ _nextFrameStartTime = 0;
- // First process all the opcodes.
- do {
- opcode = READ_LE_UINT16(data); data += 2;
+ if (endOfTrack() && _fileStream->pos() < _fileStream->size())
+ _atRingFrame = true;
+ else
+ _fileStream->seek(_offsetFrame1);
- switch ((opcode >> 14) & 3) {
- case OP_PACKETCOUNT:
- packetCount = opcode;
- break;
- case OP_UNDEFINED:
- break;
- case OP_LASTPIXEL:
- *((byte *)_surface->pixels + currentLine * getWidth() + getWidth() - 1) = (opcode & 0xFF);
- _dirtyRects.push_back(Common::Rect(getWidth() - 1, currentLine, getWidth(), currentLine + 1));
- break;
- case OP_LINESKIPCOUNT:
- currentLine += -(int16)opcode;
- break;
- }
- } while (((opcode >> 14) & 3) != OP_PACKETCOUNT);
+ _frameDelay = _startFrameDelay;
+ return true;
+}
- uint16 column = 0;
+uint16 FlicDecoder::FlicVideoTrack::getWidth() const {
+ return _surface->w;
+}
- // Now interpret the RLE data
- while (packetCount--) {
- column += *data++;
- int rleCount = (int8)*data++;
- if (rleCount > 0) {
- memcpy((byte *)_surface->pixels + (currentLine * getWidth()) + column, data, rleCount * 2);
- data += rleCount * 2;
- _dirtyRects.push_back(Common::Rect(column, currentLine, column + rleCount * 2, currentLine + 1));
- } else if (rleCount < 0) {
- rleCount = -rleCount;
- uint16 dataWord = READ_UINT16(data); data += 2;
- for (int i = 0; i < rleCount; ++i) {
- WRITE_UINT16((byte *)_surface->pixels + currentLine * getWidth() + column + i * 2, dataWord);
- }
- _dirtyRects.push_back(Common::Rect(column, currentLine, column + rleCount * 2, currentLine + 1));
- } else { // End of cutscene ?
- return;
- }
- column += rleCount * 2;
- }
+uint16 FlicDecoder::FlicVideoTrack::getHeight() const {
+ return _surface->h;
+}
- currentLine++;
- }
+Graphics::PixelFormat FlicDecoder::FlicVideoTrack::getPixelFormat() const {
+ return _surface->format;
}
#define FLI_SETPAL 4
@@ -192,7 +155,7 @@ void FlicDecoder::decodeDeltaFLC(uint8 *data) {
#define PSTAMP 18
#define FRAME_TYPE 0xF1FA
-const Graphics::Surface *FlicDecoder::decodeNextFrame() {
+const Graphics::Surface *FlicDecoder::FlicVideoTrack::decodeNextFrame() {
// Read chunk
uint32 frameSize = _fileStream->readUint32LE();
uint16 frameType = _fileStream->readUint16LE();
@@ -201,15 +164,12 @@ const Graphics::Surface *FlicDecoder::decodeNextFrame() {
switch (frameType) {
case FRAME_TYPE:
{
- // FIXME: FLIC should be switched over to a variable frame rate VideoDecoder to handle
- // this properly.
-
chunkCount = _fileStream->readUint16LE();
// Note: The overridden delay is a 16-bit integer (word), whereas the normal delay is a 32-bit integer (dword)
// the frame delay is the FLIC "speed", in milliseconds.
uint16 newFrameDelay = _fileStream->readUint16LE(); // "speed", in milliseconds
if (newFrameDelay > 0)
- _frameRate = Common::Rational(1000, newFrameDelay);
+ _frameDelay = newFrameDelay;
_fileStream->readUint16LE(); // reserved, always 0
uint16 newWidth = _fileStream->readUint16LE();
@@ -240,10 +200,11 @@ const Graphics::Surface *FlicDecoder::decodeNextFrame() {
frameType = _fileStream->readUint16LE();
uint8 *data = new uint8[frameSize - 6];
_fileStream->read(data, frameSize - 6);
+
switch (frameType) {
case FLI_SETPAL:
unpackPalette(data);
- _paletteChanged = true;
+ _dirtyPalette = true;
break;
case FLI_SS2:
decodeDeltaFLC(data);
@@ -264,26 +225,111 @@ const Graphics::Surface *FlicDecoder::decodeNextFrame() {
}
_curFrame++;
+ _nextFrameStartTime += _frameDelay;
- // If we just processed the ring frame, set the next frame
- if (_curFrame == (int32)_frameCount) {
- _curFrame = 0;
+ if (_atRingFrame) {
+ // If we decoded the ring frame, seek to the second frame
+ _atRingFrame = false;
_fileStream->seek(_offsetFrame2);
}
- if (_curFrame == 0)
- _startTime = g_system->getMillis();
-
return _surface;
}
-void FlicDecoder::reset() {
- FixedRateVideoDecoder::reset();
- if (_fileStream)
- _fileStream->seek(_offsetFrame1);
+void FlicDecoder::FlicVideoTrack::copyDirtyRectsToBuffer(uint8 *dst, uint pitch) {
+ for (Common::List<Common::Rect>::const_iterator it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
+ for (int y = (*it).top; y < (*it).bottom; ++y) {
+ const int x = (*it).left;
+ memcpy(dst + y * pitch + x, (byte *)_surface->pixels + y * getWidth() + x, (*it).right - x);
+ }
+ }
+
+ clearDirtyRects();
}
-void FlicDecoder::unpackPalette(uint8 *data) {
+void FlicDecoder::FlicVideoTrack::decodeByteRun(uint8 *data) {
+ byte *ptr = (byte *)_surface->pixels;
+ while ((int32)(ptr - (byte *)_surface->pixels) < (getWidth() * getHeight())) {
+ int chunks = *data++;
+ while (chunks--) {
+ int count = (int8)*data++;
+ if (count > 0) {
+ memset(ptr, *data++, count);
+ } else {
+ count = -count;
+ memcpy(ptr, data, count);
+ data += count;
+ }
+ ptr += count;
+ }
+ }
+
+ // Redraw
+ _dirtyRects.clear();
+ _dirtyRects.push_back(Common::Rect(0, 0, getWidth(), getHeight()));
+}
+
+#define OP_PACKETCOUNT 0
+#define OP_UNDEFINED 1
+#define OP_LASTPIXEL 2
+#define OP_LINESKIPCOUNT 3
+
+void FlicDecoder::FlicVideoTrack::decodeDeltaFLC(uint8 *data) {
+ uint16 linesInChunk = READ_LE_UINT16(data); data += 2;
+ uint16 currentLine = 0;
+ uint16 packetCount = 0;
+
+ while (linesInChunk--) {
+ uint16 opcode;
+
+ // First process all the opcodes.
+ do {
+ opcode = READ_LE_UINT16(data); data += 2;
+
+ switch ((opcode >> 14) & 3) {
+ case OP_PACKETCOUNT:
+ packetCount = opcode;
+ break;
+ case OP_UNDEFINED:
+ break;
+ case OP_LASTPIXEL:
+ *((byte *)_surface->pixels + currentLine * getWidth() + getWidth() - 1) = (opcode & 0xFF);
+ _dirtyRects.push_back(Common::Rect(getWidth() - 1, currentLine, getWidth(), currentLine + 1));
+ break;
+ case OP_LINESKIPCOUNT:
+ currentLine += -(int16)opcode;
+ break;
+ }
+ } while (((opcode >> 14) & 3) != OP_PACKETCOUNT);
+
+ uint16 column = 0;
+
+ // Now interpret the RLE data
+ while (packetCount--) {
+ column += *data++;
+ int rleCount = (int8)*data++;
+ if (rleCount > 0) {
+ memcpy((byte *)_surface->pixels + (currentLine * getWidth()) + column, data, rleCount * 2);
+ data += rleCount * 2;
+ _dirtyRects.push_back(Common::Rect(column, currentLine, column + rleCount * 2, currentLine + 1));
+ } else if (rleCount < 0) {
+ rleCount = -rleCount;
+ uint16 dataWord = READ_UINT16(data); data += 2;
+ for (int i = 0; i < rleCount; ++i) {
+ WRITE_UINT16((byte *)_surface->pixels + currentLine * getWidth() + column + i * 2, dataWord);
+ }
+ _dirtyRects.push_back(Common::Rect(column, currentLine, column + rleCount * 2, currentLine + 1));
+ } else { // End of cutscene ?
+ return;
+ }
+ column += rleCount * 2;
+ }
+
+ currentLine++;
+ }
+}
+
+void FlicDecoder::FlicVideoTrack::unpackPalette(uint8 *data) {
uint16 numPackets = READ_LE_UINT16(data); data += 2;
if (0 == READ_LE_UINT16(data)) { //special case
@@ -308,14 +354,4 @@ void FlicDecoder::unpackPalette(uint8 *data) {
}
}
-void FlicDecoder::copyDirtyRectsToBuffer(uint8 *dst, uint pitch) {
- for (Common::List<Common::Rect>::const_iterator it = _dirtyRects.begin(); it != _dirtyRects.end(); ++it) {
- for (int y = (*it).top; y < (*it).bottom; ++y) {
- const int x = (*it).left;
- memcpy(dst + y * pitch + x, (byte *)_surface->pixels + y * getWidth() + x, (*it).right - x);
- }
- }
- _dirtyRects.clear();
-}
-
} // End of namespace Video
diff --git a/video/flic_decoder.h b/video/flic_decoder.h
index 9badc3da2e..9037af05d6 100644
--- a/video/flic_decoder.h
+++ b/video/flic_decoder.h
@@ -25,15 +25,17 @@
#include "video/video_decoder.h"
#include "common/list.h"
-#include "common/rational.h"
#include "common/rect.h"
-#include "graphics/pixelformat.h"
-#include "graphics/surface.h"
namespace Common {
class SeekableReadStream;
}
+namespace Graphics {
+struct PixelFormat;
+struct Surface;
+}
+
namespace Video {
/**
@@ -42,58 +44,63 @@ namespace Video {
* Video decoder used in engines:
* - tucker
*/
-class FlicDecoder : public FixedRateVideoDecoder {
+class FlicDecoder : public VideoDecoder {
public:
FlicDecoder();
virtual ~FlicDecoder();
- /**
- * Load a video file
- * @param stream the stream to load
- */
bool loadStream(Common::SeekableReadStream *stream);
- void close();
-
- /**
- * Decode the next frame and return the frame's surface
- * @note the return surface should *not* be freed
- * @note this may return 0, in which case the last frame should be kept on screen
- */
- const Graphics::Surface *decodeNextFrame();
-
- bool isVideoLoaded() const { return _fileStream != 0; }
- uint16 getWidth() const { return _surface->w; }
- uint16 getHeight() const { return _surface->h; }
- uint32 getFrameCount() const { return _frameCount; }
- Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
-
- const Common::List<Common::Rect> *getDirtyRects() const { return &_dirtyRects; }
- void clearDirtyRects() { _dirtyRects.clear(); }
- void copyDirtyRectsToBuffer(uint8 *dst, uint pitch);
-
- const byte *getPalette() { _paletteChanged = false; return _palette; }
- bool hasDirtyPalette() const { return _paletteChanged; }
- void reset();
-protected:
- Common::Rational getFrameRate() const { return _frameRate; }
+ const Common::List<Common::Rect> *getDirtyRects() const;
+ void clearDirtyRects();
+ void copyDirtyRectsToBuffer(uint8 *dst, uint pitch);
private:
- uint16 _offsetFrame1;
- uint16 _offsetFrame2;
- byte *_palette;
- bool _paletteChanged;
-
- void decodeByteRun(uint8 *data);
- void decodeDeltaFLC(uint8 *data);
- void unpackPalette(uint8 *mem);
-
- Common::SeekableReadStream *_fileStream;
- Graphics::Surface *_surface;
- uint32 _frameCount;
- Common::Rational _frameRate;
-
- Common::List<Common::Rect> _dirtyRects;
+ class FlicVideoTrack : public VideoTrack {
+ public:
+ FlicVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height);
+ ~FlicVideoTrack();
+
+ bool endOfTrack() const;
+ bool isRewindable() const { return true; }
+ bool rewind();
+
+ uint16 getWidth() const;
+ uint16 getHeight() const;
+ Graphics::PixelFormat getPixelFormat() const;
+ int getCurFrame() const { return _curFrame; }
+ int getFrameCount() const { return _frameCount; }
+ uint32 getNextFrameStartTime() const { return _nextFrameStartTime; }
+ const Graphics::Surface *decodeNextFrame();
+ const byte *getPalette() const { _dirtyPalette = false; return _palette; }
+ bool hasDirtyPalette() const { return _dirtyPalette; }
+
+ const Common::List<Common::Rect> *getDirtyRects() const { return &_dirtyRects; }
+ void clearDirtyRects() { _dirtyRects.clear(); }
+ void copyDirtyRectsToBuffer(uint8 *dst, uint pitch);
+
+ private:
+ Common::SeekableReadStream *_fileStream;
+ Graphics::Surface *_surface;
+
+ int _curFrame;
+ bool _atRingFrame;
+
+ uint16 _offsetFrame1;
+ uint16 _offsetFrame2;
+ byte *_palette;
+ mutable bool _dirtyPalette;
+
+ uint32 _frameCount;
+ uint32 _frameDelay, _startFrameDelay;
+ uint32 _nextFrameStartTime;
+
+ Common::List<Common::Rect> _dirtyRects;
+
+ void decodeByteRun(uint8 *data);
+ void decodeDeltaFLC(uint8 *data);
+ void unpackPalette(uint8 *mem);
+ };
};
} // End of namespace Video
diff --git a/video/module.mk b/video/module.mk
index cebd403ca2..287e14ce18 100644
--- a/video/module.mk
+++ b/video/module.mk
@@ -26,5 +26,10 @@ MODULE_OBJS += \
bink_decoder.o
endif
+ifdef USE_THEORADEC
+MODULE_OBJS += \
+ theora_decoder.o
+endif
+
# Include common rules
include $(srcdir)/rules.mk
diff --git a/video/psx_decoder.cpp b/video/psx_decoder.cpp
index 7c04b7f041..fa7f1e8cfe 100644
--- a/video/psx_decoder.cpp
+++ b/video/psx_decoder.cpp
@@ -149,22 +149,12 @@ static const uint32 s_huffmanACSymbols[AC_CODE_COUNT] = {
END_OF_BLOCK
};
-PSXStreamDecoder::PSXStreamDecoder(CDSpeed speed, uint32 frameCount) : _nextFrameStartTime(0, speed), _frameCount(frameCount) {
+PSXStreamDecoder::PSXStreamDecoder(CDSpeed speed, uint32 frameCount) : _speed(speed), _frameCount(frameCount) {
_stream = 0;
- _audStream = 0;
- _surface = new Graphics::Surface();
- _yBuffer = _cbBuffer = _crBuffer = 0;
- _acHuffman = new Common::Huffman(0, AC_CODE_COUNT, s_huffmanACCodes, s_huffmanACLengths, s_huffmanACSymbols);
- _dcHuffmanChroma = new Common::Huffman(0, DC_CODE_COUNT, s_huffmanDCChromaCodes, s_huffmanDCChromaLengths, s_huffmanDCSymbols);
- _dcHuffmanLuma = new Common::Huffman(0, DC_CODE_COUNT, s_huffmanDCLumaCodes, s_huffmanDCLumaLengths, s_huffmanDCSymbols);
}
PSXStreamDecoder::~PSXStreamDecoder() {
close();
- delete _surface;
- delete _acHuffman;
- delete _dcHuffmanLuma;
- delete _dcHuffmanChroma;
}
#define RAW_CD_SECTOR_SIZE 2352
@@ -178,95 +168,30 @@ bool PSXStreamDecoder::loadStream(Common::SeekableReadStream *stream) {
close();
_stream = stream;
-
- Common::SeekableReadStream *sector = readSector();
-
- if (!sector) {
- close();
- return false;
- }
-
- // Rip out video info from the first frame
- sector->seek(18);
- byte sectorType = sector->readByte() & CDXA_TYPE_MASK;
-
- if (sectorType != CDXA_TYPE_VIDEO && sectorType != CDXA_TYPE_DATA) {
- close();
- return false;
- }
-
- sector->seek(40);
-
- uint16 width = sector->readUint16LE();
- uint16 height = sector->readUint16LE();
- _surface->create(width, height, g_system->getScreenFormat());
-
- _macroBlocksW = (width + 15) / 16;
- _macroBlocksH = (height + 15) / 16;
- _yBuffer = new byte[_macroBlocksW * _macroBlocksH * 16 * 16];
- _cbBuffer = new byte[_macroBlocksW * _macroBlocksH * 8 * 8];
- _crBuffer = new byte[_macroBlocksW * _macroBlocksH * 8 * 8];
-
- delete sector;
- _stream->seek(0);
+ readNextPacket();
return true;
}
void PSXStreamDecoder::close() {
- if (!_stream)
- return;
+ VideoDecoder::close();
+ _audioTrack = 0;
+ _videoTrack = 0;
+ _frameCount = 0;
delete _stream;
_stream = 0;
-
- // Deinitialize sound
- g_system->getMixer()->stopHandle(_audHandle);
- _audStream = 0;
-
- _surface->free();
-
- memset(&_adpcmStatus, 0, sizeof(_adpcmStatus));
-
- _macroBlocksW = _macroBlocksH = 0;
- delete[] _yBuffer; _yBuffer = 0;
- delete[] _cbBuffer; _cbBuffer = 0;
- delete[] _crBuffer; _crBuffer = 0;
-
- reset();
-}
-
-uint32 PSXStreamDecoder::getElapsedTime() const {
- // TODO: Currently, the audio is always after the video so using this
- // can often lead to gaps in the audio...
- //if (_audStream)
- // return _mixer->getSoundElapsedTime(_audHandle);
-
- return VideoDecoder::getElapsedTime();
-}
-
-uint32 PSXStreamDecoder::getTimeToNextFrame() const {
- if (!isVideoLoaded() || endOfVideo())
- return 0;
-
- uint32 nextTimeMillis = _nextFrameStartTime.msecs();
- uint32 elapsedTime = getElapsedTime();
-
- if (elapsedTime > nextTimeMillis)
- return 0;
-
- return nextTimeMillis - elapsedTime;
}
#define VIDEO_DATA_CHUNK_SIZE 2016
#define VIDEO_DATA_HEADER_SIZE 56
-const Graphics::Surface *PSXStreamDecoder::decodeNextFrame() {
+void PSXStreamDecoder::readNextPacket() {
Common::SeekableReadStream *sector = 0;
byte *partialFrame = 0;
int sectorsRead = 0;
- while (!endOfVideo()) {
+ while (_stream->pos() < _stream->size()) {
sector = readSector();
sectorsRead++;
@@ -284,6 +209,11 @@ const Graphics::Surface *PSXStreamDecoder::decodeNextFrame() {
case CDXA_TYPE_DATA:
case CDXA_TYPE_VIDEO:
if (track == 1) {
+ if (!_videoTrack) {
+ _videoTrack = new PSXVideoTrack(sector, _speed, _frameCount);
+ addTrack(_videoTrack);
+ }
+
sector->seek(28);
uint16 curSector = sector->readUint16LE();
uint16 sectorCount = sector->readUint16LE();
@@ -303,35 +233,27 @@ const Graphics::Surface *PSXStreamDecoder::decodeNextFrame() {
// Done assembling the frame
Common::SeekableReadStream *frame = new Common::MemoryReadStream(partialFrame, frameSize, DisposeAfterUse::YES);
- decodeFrame(frame);
+ _videoTrack->decodeFrame(frame, sectorsRead);
delete frame;
delete sector;
-
- _curFrame++;
- if (_curFrame == 0)
- _startTime = g_system->getMillis();
-
- // Increase the time by the amount of sectors we read
- // One may notice that this is still not the most precise
- // method since a frame takes up the time its sectors took
- // up instead of the amount of time it takes the next frame
- // to be read from the sectors. The actual frame rate should
- // be constant instead of variable, so the slight difference
- // in a frame's showing time is negligible (1/150 of a second).
- _nextFrameStartTime = _nextFrameStartTime.addFrames(sectorsRead);
-
- return _surface;
+ return;
}
} else
error("Unhandled multi-track video");
break;
case CDXA_TYPE_AUDIO:
// We only handle one audio channel so far
- if (track == 1)
- queueAudioFromSector(sector);
- else
+ if (track == 1) {
+ if (!_audioTrack) {
+ _audioTrack = new PSXAudioTrack(sector);
+ addTrack(_audioTrack);
+ }
+
+ _audioTrack->queueAudioFromSector(sector);
+ } else {
warning("Unhandled multi-track audio");
+ }
break;
default:
// This shows up way too often, but the other sectors
@@ -343,7 +265,19 @@ const Graphics::Surface *PSXStreamDecoder::decodeNextFrame() {
delete sector;
}
- return 0;
+ if (_stream->pos() >= _stream->size()) {
+ if (_videoTrack)
+ _videoTrack->setEndOfTrack();
+
+ if (_audioTrack)
+ _audioTrack->setEndOfTrack();
+ }
+}
+
+bool PSXStreamDecoder::useAudioSync() const {
+ // Audio sync is disabled since most audio data comes after video
+ // data.
+ return false;
}
static const byte s_syncHeader[12] = { 0x00, 0xff ,0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 };
@@ -373,20 +307,29 @@ static const int s_xaTable[5][2] = {
{ 122, -60 }
};
-void PSXStreamDecoder::queueAudioFromSector(Common::SeekableReadStream *sector) {
+PSXStreamDecoder::PSXAudioTrack::PSXAudioTrack(Common::SeekableReadStream *sector) {
assert(sector);
+ _endOfTrack = false;
+
+ sector->seek(19);
+ byte format = sector->readByte();
+ bool stereo = (format & (1 << 0)) != 0;
+ uint rate = (format & (1 << 2)) ? 18900 : 37800;
+ _audStream = Audio::makeQueuingAudioStream(rate, stereo);
- if (!_audStream) {
- // Initialize audio stream
- sector->seek(19);
- byte format = sector->readByte();
+ memset(&_adpcmStatus, 0, sizeof(_adpcmStatus));
+}
- bool stereo = (format & (1 << 0)) != 0;
- uint rate = (format & (1 << 2)) ? 18900 : 37800;
+PSXStreamDecoder::PSXAudioTrack::~PSXAudioTrack() {
+ delete _audStream;
+}
- _audStream = Audio::makeQueuingAudioStream(rate, stereo);
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audHandle, _audStream);
- }
+bool PSXStreamDecoder::PSXAudioTrack::endOfTrack() const {
+ return AudioTrack::endOfTrack() && _endOfTrack;
+}
+
+void PSXStreamDecoder::PSXAudioTrack::queueAudioFromSector(Common::SeekableReadStream *sector) {
+ assert(sector);
sector->seek(24);
@@ -472,7 +415,54 @@ void PSXStreamDecoder::queueAudioFromSector(Common::SeekableReadStream *sector)
delete[] buf;
}
-void PSXStreamDecoder::decodeFrame(Common::SeekableReadStream *frame) {
+Audio::AudioStream *PSXStreamDecoder::PSXAudioTrack::getAudioStream() const {
+ return _audStream;
+}
+
+
+PSXStreamDecoder::PSXVideoTrack::PSXVideoTrack(Common::SeekableReadStream *firstSector, CDSpeed speed, int frameCount) : _nextFrameStartTime(0, speed), _frameCount(frameCount) {
+ assert(firstSector);
+
+ firstSector->seek(40);
+ uint16 width = firstSector->readUint16LE();
+ uint16 height = firstSector->readUint16LE();
+ _surface = new Graphics::Surface();
+ _surface->create(width, height, g_system->getScreenFormat());
+
+ _macroBlocksW = (width + 15) / 16;
+ _macroBlocksH = (height + 15) / 16;
+ _yBuffer = new byte[_macroBlocksW * _macroBlocksH * 16 * 16];
+ _cbBuffer = new byte[_macroBlocksW * _macroBlocksH * 8 * 8];
+ _crBuffer = new byte[_macroBlocksW * _macroBlocksH * 8 * 8];
+
+ _endOfTrack = false;
+ _curFrame = -1;
+ _acHuffman = new Common::Huffman(0, AC_CODE_COUNT, s_huffmanACCodes, s_huffmanACLengths, s_huffmanACSymbols);
+ _dcHuffmanChroma = new Common::Huffman(0, DC_CODE_COUNT, s_huffmanDCChromaCodes, s_huffmanDCChromaLengths, s_huffmanDCSymbols);
+ _dcHuffmanLuma = new Common::Huffman(0, DC_CODE_COUNT, s_huffmanDCLumaCodes, s_huffmanDCLumaLengths, s_huffmanDCSymbols);
+}
+
+PSXStreamDecoder::PSXVideoTrack::~PSXVideoTrack() {
+ _surface->free();
+ delete _surface;
+
+ delete[] _yBuffer;
+ delete[] _cbBuffer;
+ delete[] _crBuffer;
+ delete _acHuffman;
+ delete _dcHuffmanChroma;
+ delete _dcHuffmanLuma;
+}
+
+uint32 PSXStreamDecoder::PSXVideoTrack::getNextFrameStartTime() const {
+ return _nextFrameStartTime.msecs();
+}
+
+const Graphics::Surface *PSXStreamDecoder::PSXVideoTrack::decodeNextFrame() {
+ return _surface;
+}
+
+void PSXStreamDecoder::PSXVideoTrack::decodeFrame(Common::SeekableReadStream *frame, uint sectorCount) {
// A frame is essentially an MPEG-1 intra frame
Common::BitStream16LEMSB bits(frame);
@@ -494,9 +484,20 @@ void PSXStreamDecoder::decodeFrame(Common::SeekableReadStream *frame) {
// Output data onto the frame
Graphics::convertYUV420ToRGB(_surface, _yBuffer, _cbBuffer, _crBuffer, _surface->w, _surface->h, _macroBlocksW * 16, _macroBlocksW * 8);
+
+ _curFrame++;
+
+ // Increase the time by the amount of sectors we read
+ // One may notice that this is still not the most precise
+ // method since a frame takes up the time its sectors took
+ // up instead of the amount of time it takes the next frame
+ // to be read from the sectors. The actual frame rate should
+ // be constant instead of variable, so the slight difference
+ // in a frame's showing time is negligible (1/150 of a second).
+ _nextFrameStartTime = _nextFrameStartTime.addFrames(sectorCount);
}
-void PSXStreamDecoder::decodeMacroBlock(Common::BitStream *bits, int mbX, int mbY, uint16 scale, uint16 version) {
+void PSXStreamDecoder::PSXVideoTrack::decodeMacroBlock(Common::BitStream *bits, int mbX, int mbY, uint16 scale, uint16 version) {
int pitchY = _macroBlocksW * 16;
int pitchC = _macroBlocksW * 8;
@@ -533,7 +534,7 @@ static const byte s_quantizationTable[8 * 8] = {
27, 29, 35, 38, 46, 56, 69, 83
};
-void PSXStreamDecoder::dequantizeBlock(int *coefficients, float *block, uint16 scale) {
+void PSXStreamDecoder::PSXVideoTrack::dequantizeBlock(int *coefficients, float *block, uint16 scale) {
// Dequantize the data, un-zig-zagging as we go along
for (int i = 0; i < 8 * 8; i++) {
if (i == 0) // Special case for the DC coefficient
@@ -543,7 +544,7 @@ void PSXStreamDecoder::dequantizeBlock(int *coefficients, float *block, uint16 s
}
}
-int PSXStreamDecoder::readDC(Common::BitStream *bits, uint16 version, PlaneType plane) {
+int PSXStreamDecoder::PSXVideoTrack::readDC(Common::BitStream *bits, uint16 version, PlaneType plane) {
// Version 2 just has its coefficient as 10-bits
if (version == 2)
return readSignedCoefficient(bits);
@@ -573,7 +574,7 @@ int PSXStreamDecoder::readDC(Common::BitStream *bits, uint16 version, PlaneType
if (count > 63) \
error("PSXStreamDecoder::readAC(): Too many coefficients")
-void PSXStreamDecoder::readAC(Common::BitStream *bits, int *block) {
+void PSXStreamDecoder::PSXVideoTrack::readAC(Common::BitStream *bits, int *block) {
// Clear the block first
for (int i = 0; i < 63; i++)
block[i] = 0;
@@ -608,7 +609,7 @@ void PSXStreamDecoder::readAC(Common::BitStream *bits, int *block) {
}
}
-int PSXStreamDecoder::readSignedCoefficient(Common::BitStream *bits) {
+int PSXStreamDecoder::PSXVideoTrack::readSignedCoefficient(Common::BitStream *bits) {
uint val = bits->getBits(10);
// extend the sign
@@ -630,7 +631,7 @@ static const double s_idct8x8[8][8] = {
{ 0.353553390593274, -0.490392640201615, 0.461939766255643, -0.415734806151273, 0.353553390593273, -0.277785116509801, 0.191341716182545, -0.097545161008064 }
};
-void PSXStreamDecoder::idct(float *dequantData, float *result) {
+void PSXStreamDecoder::PSXVideoTrack::idct(float *dequantData, float *result) {
// IDCT code based on JPEG's IDCT code
// TODO: Switch to the integer-based one mentioned in the docs
// This is by far the costliest operation here
@@ -669,7 +670,7 @@ void PSXStreamDecoder::idct(float *dequantData, float *result) {
}
}
-void PSXStreamDecoder::decodeBlock(Common::BitStream *bits, byte *block, int pitch, uint16 scale, uint16 version, PlaneType plane) {
+void PSXStreamDecoder::PSXVideoTrack::decodeBlock(Common::BitStream *bits, byte *block, int pitch, uint16 scale, uint16 version, PlaneType plane) {
// Version 2 just has signed 10 bits for DC
// Version 3 has them huffman coded
int coefficients[8 * 8];
@@ -686,12 +687,13 @@ void PSXStreamDecoder::decodeBlock(Common::BitStream *bits, byte *block, int pit
// Now output the data
for (int y = 0; y < 8; y++) {
- byte *start = block + pitch * y;
+ byte *dst = block + pitch * y;
// Convert the result to be in the range [0, 255]
for (int x = 0; x < 8; x++)
- *start++ = (int)CLIP<float>(idctData[y * 8 + x], -128.0f, 127.0f) + 128;
+ *dst++ = (int)CLIP<float>(idctData[y * 8 + x], -128.0f, 127.0f) + 128;
}
}
+
} // End of namespace Video
diff --git a/video/psx_decoder.h b/video/psx_decoder.h
index c8ad92c45a..11f311594d 100644
--- a/video/psx_decoder.h
+++ b/video/psx_decoder.h
@@ -71,54 +71,85 @@ public:
bool loadStream(Common::SeekableReadStream *stream);
void close();
- bool isVideoLoaded() const { return _stream != 0; }
- uint16 getWidth() const { return _surface->w; }
- uint16 getHeight() const { return _surface->h; }
- uint32 getFrameCount() const { return _frameCount; }
- uint32 getElapsedTime() const;
- uint32 getTimeToNextFrame() const;
- const Graphics::Surface *decodeNextFrame();
- Graphics::PixelFormat getPixelFormat() const { return _surface->format; }
- bool endOfVideo() const { return _stream->pos() >= _stream->size(); }
+protected:
+ void readNextPacket();
+ bool useAudioSync() const;
private:
- void initCommon();
- Common::SeekableReadStream *_stream;
- Graphics::Surface *_surface;
+ class PSXVideoTrack : public VideoTrack {
+ public:
+ PSXVideoTrack(Common::SeekableReadStream *firstSector, CDSpeed speed, int frameCount);
+ ~PSXVideoTrack();
+
+ uint16 getWidth() const { return _surface->w; }
+ uint16 getHeight() const { return _surface->h; }
+ Graphics::PixelFormat getPixelFormat() const { return _surface->format; }
+ bool endOfTrack() const { return _endOfTrack; }
+ int getCurFrame() const { return _curFrame; }
+ int getFrameCount() const { return _frameCount; }
+ uint32 getNextFrameStartTime() const;
+ const Graphics::Surface *decodeNextFrame();
+
+ void setEndOfTrack() { _endOfTrack = true; }
+ void decodeFrame(Common::SeekableReadStream *frame, uint sectorCount);
+
+ private:
+ Graphics::Surface *_surface;
+ uint32 _frameCount;
+ Audio::Timestamp _nextFrameStartTime;
+ bool _endOfTrack;
+ int _curFrame;
+
+ enum PlaneType {
+ kPlaneY = 0,
+ kPlaneU = 1,
+ kPlaneV = 2
+ };
+
+ uint16 _macroBlocksW, _macroBlocksH;
+ byte *_yBuffer, *_cbBuffer, *_crBuffer;
+ void decodeMacroBlock(Common::BitStream *bits, int mbX, int mbY, uint16 scale, uint16 version);
+ void decodeBlock(Common::BitStream *bits, byte *block, int pitch, uint16 scale, uint16 version, PlaneType plane);
+
+ void readAC(Common::BitStream *bits, int *block);
+ Common::Huffman *_acHuffman;
+
+ int readDC(Common::BitStream *bits, uint16 version, PlaneType plane);
+ Common::Huffman *_dcHuffmanLuma, *_dcHuffmanChroma;
+ int _lastDC[3];
+
+ void dequantizeBlock(int *coefficients, float *block, uint16 scale);
+ void idct(float *dequantData, float *result);
+ int readSignedCoefficient(Common::BitStream *bits);
+ };
- uint32 _frameCount;
- Audio::Timestamp _nextFrameStartTime;
+ class PSXAudioTrack : public AudioTrack {
+ public:
+ PSXAudioTrack(Common::SeekableReadStream *sector);
+ ~PSXAudioTrack();
- Audio::SoundHandle _audHandle;
- Audio::QueuingAudioStream *_audStream;
- void queueAudioFromSector(Common::SeekableReadStream *sector);
+ bool endOfTrack() const;
- enum PlaneType {
- kPlaneY = 0,
- kPlaneU = 1,
- kPlaneV = 2
- };
+ void setEndOfTrack() { _endOfTrack = true; }
+ void queueAudioFromSector(Common::SeekableReadStream *sector);
- uint16 _macroBlocksW, _macroBlocksH;
- byte *_yBuffer, *_cbBuffer, *_crBuffer;
- void decodeFrame(Common::SeekableReadStream *frame);
- void decodeMacroBlock(Common::BitStream *bits, int mbX, int mbY, uint16 scale, uint16 version);
- void decodeBlock(Common::BitStream *bits, byte *block, int pitch, uint16 scale, uint16 version, PlaneType plane);
+ private:
+ Audio::AudioStream *getAudioStream() const;
- void readAC(Common::BitStream *bits, int *block);
- Common::Huffman *_acHuffman;
+ Audio::QueuingAudioStream *_audStream;
- int readDC(Common::BitStream *bits, uint16 version, PlaneType plane);
- Common::Huffman *_dcHuffmanLuma, *_dcHuffmanChroma;
- int _lastDC[3];
+ struct ADPCMStatus {
+ int16 sample[2];
+ } _adpcmStatus[2];
- void dequantizeBlock(int *coefficients, float *block, uint16 scale);
- void idct(float *dequantData, float *result);
- int readSignedCoefficient(Common::BitStream *bits);
+ bool _endOfTrack;
+ };
- struct ADPCMStatus {
- int16 sample[2];
- } _adpcmStatus[2];
+ CDSpeed _speed;
+ uint32 _frameCount;
+ Common::SeekableReadStream *_stream;
+ PSXVideoTrack *_videoTrack;
+ PSXAudioTrack *_audioTrack;
Common::SeekableReadStream *readSector();
};
diff --git a/video/qt_decoder.cpp b/video/qt_decoder.cpp
index 0d80c93a1f..87c530dba0 100644
--- a/video/qt_decoder.cpp
+++ b/video/qt_decoder.cpp
@@ -33,14 +33,12 @@
#include "audio/audiostream.h"
#include "common/debug.h"
-#include "common/endian.h"
#include "common/memstream.h"
#include "common/system.h"
#include "common/textconsole.h"
#include "common/util.h"
// Video codecs
-#include "video/codecs/codec.h"
#include "video/codecs/cinepak.h"
#include "video/codecs/mjpeg.h"
#include "video/codecs/qtrle.h"
@@ -56,97 +54,43 @@ namespace Video {
////////////////////////////////////////////
QuickTimeDecoder::QuickTimeDecoder() {
- _setStartTime = false;
_scaledSurface = 0;
- _dirtyPalette = false;
- _palette = 0;
_width = _height = 0;
- _needUpdate = false;
}
QuickTimeDecoder::~QuickTimeDecoder() {
close();
}
-int32 QuickTimeDecoder::getCurFrame() const {
- // TODO: This is rather simplistic and doesn't take edits that
- // repeat sections of the media into account. Doing that
- // over-complicates things and shouldn't be necessary, but
- // it would be nice to have in the future.
-
- int32 frame = -1;
-
- for (uint32 i = 0; i < _handlers.size(); i++)
- if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo)
- frame += ((VideoTrackHandler *)_handlers[i])->getCurFrame() + 1;
-
- return frame;
-}
-
-uint32 QuickTimeDecoder::getFrameCount() const {
- uint32 count = 0;
-
- for (uint32 i = 0; i < _handlers.size(); i++)
- if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo)
- count += ((VideoTrackHandler *)_handlers[i])->getFrameCount();
-
- return count;
-}
-
-void QuickTimeDecoder::startAudio() {
- updateAudioBuffer();
-
- for (uint32 i = 0; i < _audioTracks.size(); i++) {
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_audioHandles[i], _audioTracks[i], -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
+bool QuickTimeDecoder::loadFile(const Common::String &filename) {
+ if (!Common::QuickTimeParser::parseFile(filename))
+ return false;
- // Pause the audio again if we're still paused
- if (isPaused())
- g_system->getMixer()->pauseHandle(_audioHandles[i], true);
- }
+ init();
+ return true;
}
-void QuickTimeDecoder::stopAudio() {
- for (uint32 i = 0; i < _audioHandles.size(); i++)
- g_system->getMixer()->stopHandle(_audioHandles[i]);
-}
+bool QuickTimeDecoder::loadStream(Common::SeekableReadStream *stream) {
+ if (!Common::QuickTimeParser::parseStream(stream))
+ return false;
-void QuickTimeDecoder::pauseVideoIntern(bool pause) {
- for (uint32 i = 0; i < _audioHandles.size(); i++)
- g_system->getMixer()->pauseHandle(_audioHandles[i], pause);
+ init();
+ return true;
}
-QuickTimeDecoder::VideoTrackHandler *QuickTimeDecoder::findNextVideoTrack() const {
- VideoTrackHandler *bestTrack = 0;
- uint32 bestTime = 0xffffffff;
-
- for (uint32 i = 0; i < _handlers.size(); i++) {
- if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo && !_handlers[i]->endOfTrack()) {
- VideoTrackHandler *track = (VideoTrackHandler *)_handlers[i];
- uint32 time = track->getNextFrameStartTime();
+void QuickTimeDecoder::close() {
+ VideoDecoder::close();
+ Common::QuickTimeParser::close();
- if (time < bestTime) {
- bestTime = time;
- bestTrack = track;
- }
- }
+ if (_scaledSurface) {
+ _scaledSurface->free();
+ delete _scaledSurface;
+ _scaledSurface = 0;
}
-
- return bestTrack;
}
const Graphics::Surface *QuickTimeDecoder::decodeNextFrame() {
- if (!_nextVideoTrack)
- return 0;
-
- const Graphics::Surface *frame = _nextVideoTrack->decodeNextFrame();
-
- if (!_setStartTime) {
- _startTime = g_system->getMillis();
- _setStartTime = true;
- }
-
- _nextVideoTrack = findNextVideoTrack();
- _needUpdate = false;
+ const Graphics::Surface *frame = VideoDecoder::decodeNextFrame();
// Update audio buffers too
// (needs to be done after we find the next track)
@@ -166,126 +110,7 @@ const Graphics::Surface *QuickTimeDecoder::decodeNextFrame() {
return frame;
}
-void QuickTimeDecoder::scaleSurface(const Graphics::Surface *src, Graphics::Surface *dst, Common::Rational scaleFactorX, Common::Rational scaleFactorY) {
- assert(src && dst);
-
- for (int32 j = 0; j < dst->h; j++)
- for (int32 k = 0; k < dst->w; k++)
- memcpy(dst->getBasePtr(k, j), src->getBasePtr((k * scaleFactorX).toInt() , (j * scaleFactorY).toInt()), src->format.bytesPerPixel);
-}
-
-bool QuickTimeDecoder::endOfVideo() const {
- if (!isVideoLoaded())
- return true;
-
- for (uint32 i = 0; i < _handlers.size(); i++)
- if (!_handlers[i]->endOfTrack())
- return false;
-
- return true;
-}
-
-uint32 QuickTimeDecoder::getElapsedTime() const {
- // Try to base sync off an active audio track
- for (uint32 i = 0; i < _audioHandles.size(); i++) {
- if (g_system->getMixer()->isSoundHandleActive(_audioHandles[i])) {
- uint32 time = g_system->getMixer()->getSoundElapsedTime(_audioHandles[i]) + _audioStartOffset.msecs();
- if (Audio::Timestamp(time, 1000) < _audioTracks[i]->getLength())
- return time;
- }
- }
-
- // Just use time elapsed since the beginning
- return SeekableVideoDecoder::getElapsedTime();
-}
-
-uint32 QuickTimeDecoder::getTimeToNextFrame() const {
- if (_needUpdate)
- return 0;
-
- if (_nextVideoTrack) {
- uint32 nextFrameStartTime = _nextVideoTrack->getNextFrameStartTime();
-
- if (nextFrameStartTime == 0)
- return 0;
-
- // TODO: Add support for rate modification
-
- uint32 elapsedTime = getElapsedTime();
-
- if (elapsedTime < nextFrameStartTime)
- return nextFrameStartTime - elapsedTime;
- }
-
- return 0;
-}
-
-bool QuickTimeDecoder::loadFile(const Common::String &filename) {
- if (!Common::QuickTimeParser::parseFile(filename))
- return false;
-
- init();
- return true;
-}
-
-bool QuickTimeDecoder::loadStream(Common::SeekableReadStream *stream) {
- if (!Common::QuickTimeParser::parseStream(stream))
- return false;
-
- init();
- return true;
-}
-
-void QuickTimeDecoder::init() {
- Audio::QuickTimeAudioDecoder::init();
-
- _startTime = 0;
- _setStartTime = false;
-
- // Initialize all the audio tracks
- if (!_audioTracks.empty()) {
- _audioHandles.resize(_audioTracks.size());
-
- for (uint32 i = 0; i < _audioTracks.size(); i++)
- _handlers.push_back(new AudioTrackHandler(this, _audioTracks[i]));
- }
-
- // Initialize all the video tracks
- for (uint32 i = 0; i < _tracks.size(); i++) {
- if (_tracks[i]->codecType == CODEC_TYPE_VIDEO) {
- for (uint32 j = 0; j < _tracks[i]->sampleDescs.size(); j++)
- ((VideoSampleDesc *)_tracks[i]->sampleDescs[j])->initCodec();
-
- _handlers.push_back(new VideoTrackHandler(this, _tracks[i]));
- }
- }
-
- // Prepare the first video track
- _nextVideoTrack = findNextVideoTrack();
-
- if (_nextVideoTrack) {
- if (_scaleFactorX != 1 || _scaleFactorY != 1) {
- // We have to take the scale into consideration when setting width/height
- _width = (_nextVideoTrack->getWidth() / _scaleFactorX).toInt();
- _height = (_nextVideoTrack->getHeight() / _scaleFactorY).toInt();
- } else {
- _width = _nextVideoTrack->getWidth().toInt();
- _height = _nextVideoTrack->getHeight().toInt();
- }
-
- _needUpdate = true;
- } else {
- _needUpdate = false;
- }
-
- // Now start any audio
- if (!_audioTracks.empty()) {
- startAudio();
- _audioStartOffset = Audio::Timestamp(0);
- }
-}
-
-Common::QuickTimeParser::SampleDesc *QuickTimeDecoder::readSampleDesc(Track *track, uint32 format) {
+Common::QuickTimeParser::SampleDesc *QuickTimeDecoder::readSampleDesc(Common::QuickTimeParser::Track *track, uint32 format) {
if (track->codecType == CODEC_TYPE_VIDEO) {
debug(0, "Video Codec FourCC: \'%s\'", tag2str(format));
@@ -383,61 +208,52 @@ Common::QuickTimeParser::SampleDesc *QuickTimeDecoder::readSampleDesc(Track *tra
return Audio::QuickTimeAudioDecoder::readSampleDesc(track, format);
}
-void QuickTimeDecoder::close() {
- stopAudio();
- freeAllTrackHandlers();
-
- if (_scaledSurface) {
- _scaledSurface->free();
- delete _scaledSurface;
- _scaledSurface = 0;
- }
-
- _width = _height = 0;
-
- Common::QuickTimeParser::close();
- SeekableVideoDecoder::reset();
-}
-
-void QuickTimeDecoder::freeAllTrackHandlers() {
- for (uint32 i = 0; i < _handlers.size(); i++)
- delete _handlers[i];
-
- _handlers.clear();
-}
+void QuickTimeDecoder::init() {
+ Audio::QuickTimeAudioDecoder::init();
-void QuickTimeDecoder::seekToTime(Audio::Timestamp time) {
- stopAudio();
- _audioStartOffset = time;
+ // Initialize all the audio tracks
+ for (uint32 i = 0; i < _audioTracks.size(); i++)
+ addTrack(new AudioTrackHandler(this, _audioTracks[i]));
- // Sets all tracks to this time
- for (uint32 i = 0; i < _handlers.size(); i++)
- _handlers[i]->seekToTime(time);
+ // Initialize all the video tracks
+ Common::Array<Common::QuickTimeParser::Track *> &tracks = Common::QuickTimeParser::_tracks;
+ for (uint32 i = 0; i < tracks.size(); i++) {
+ if (tracks[i]->codecType == CODEC_TYPE_VIDEO) {
+ for (uint32 j = 0; j < tracks[i]->sampleDescs.size(); j++)
+ ((VideoSampleDesc *)tracks[i]->sampleDescs[j])->initCodec();
- startAudio();
+ addTrack(new VideoTrackHandler(this, tracks[i]));
+ }
+ }
- // Reset our start time
- _startTime = g_system->getMillis() - time.msecs();
- _setStartTime = true;
- resetPauseStartTime();
+ // Prepare the first video track
+ VideoTrackHandler *nextVideoTrack = (VideoTrackHandler *)findNextVideoTrack();
- // Reset the next video track too
- _nextVideoTrack = findNextVideoTrack();
- _needUpdate = _nextVideoTrack != 0;
+ if (nextVideoTrack) {
+ if (_scaleFactorX != 1 || _scaleFactorY != 1) {
+ // We have to take the scale into consideration when setting width/height
+ _width = (nextVideoTrack->getScaledWidth() / _scaleFactorX).toInt();
+ _height = (nextVideoTrack->getScaledHeight() / _scaleFactorY).toInt();
+ } else {
+ _width = nextVideoTrack->getWidth();
+ _height = nextVideoTrack->getHeight();
+ }
+ }
}
void QuickTimeDecoder::updateAudioBuffer() {
// Updates the audio buffers for all audio tracks
- for (uint32 i = 0; i < _handlers.size(); i++)
- if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeAudio)
- ((AudioTrackHandler *)_handlers[i])->updateBuffer();
+ for (TrackListIterator it = getTrackListBegin(); it != getTrackListEnd(); it++)
+ if ((*it)->getTrackType() == VideoDecoder::Track::kTrackTypeAudio)
+ ((AudioTrackHandler *)*it)->updateBuffer();
}
-Graphics::PixelFormat QuickTimeDecoder::getPixelFormat() const {
- if (_nextVideoTrack)
- return _nextVideoTrack->getPixelFormat();
+void QuickTimeDecoder::scaleSurface(const Graphics::Surface *src, Graphics::Surface *dst, const Common::Rational &scaleFactorX, const Common::Rational &scaleFactorY) {
+ assert(src && dst);
- return Graphics::PixelFormat();
+ for (int32 j = 0; j < dst->h; j++)
+ for (int32 k = 0; k < dst->w; k++)
+ memcpy(dst->getBasePtr(k, j), src->getBasePtr((k * scaleFactorX).toInt() , (j * scaleFactorY).toInt()), src->format.bytesPerPixel);
}
QuickTimeDecoder::VideoSampleDesc::VideoSampleDesc(Common::QuickTimeParser::Track *parentTrack, uint32 codecTag) : Common::QuickTimeParser::SampleDesc(parentTrack, codecTag) {
@@ -492,25 +308,8 @@ void QuickTimeDecoder::VideoSampleDesc::initCodec() {
}
}
-bool QuickTimeDecoder::endOfVideoTracks() const {
- for (uint32 i = 0; i < _handlers.size(); i++)
- if (_handlers[i]->getTrackType() == TrackHandler::kTrackTypeVideo && !_handlers[i]->endOfTrack())
- return false;
-
- return true;
-}
-
-QuickTimeDecoder::TrackHandler::TrackHandler(QuickTimeDecoder *decoder, Track *parent) : _decoder(decoder), _parent(parent), _fd(_decoder->_fd) {
- _curEdit = 0;
-}
-
-bool QuickTimeDecoder::TrackHandler::endOfTrack() {
- // A track is over when we've finished going through all edits
- return _curEdit == _parent->editCount;
-}
-
QuickTimeDecoder::AudioTrackHandler::AudioTrackHandler(QuickTimeDecoder *decoder, QuickTimeAudioTrack *audioTrack)
- : TrackHandler(decoder, audioTrack->getParent()), _audioTrack(audioTrack) {
+ : _decoder(decoder), _audioTrack(audioTrack) {
}
void QuickTimeDecoder::AudioTrackHandler::updateBuffer() {
@@ -520,21 +319,20 @@ void QuickTimeDecoder::AudioTrackHandler::updateBuffer() {
_audioTrack->queueAudio(Audio::Timestamp(_decoder->getTimeToNextFrame() + 500, 1000));
}
-bool QuickTimeDecoder::AudioTrackHandler::endOfTrack() {
- return _audioTrack->endOfData();
+Audio::SeekableAudioStream *QuickTimeDecoder::AudioTrackHandler::getSeekableAudioStream() const {
+ return _audioTrack;
}
-void QuickTimeDecoder::AudioTrackHandler::seekToTime(Audio::Timestamp time) {
- _audioTrack->seek(time);
-}
-
-QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : TrackHandler(decoder, parent) {
+QuickTimeDecoder::VideoTrackHandler::VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent) : _decoder(decoder), _parent(parent) {
+ _curEdit = 0;
enterNewEditList(false);
_holdNextFrameStartTime = false;
_curFrame = -1;
_durationOverride = -1;
_scaledSurface = 0;
+ _curPalette = 0;
+ _dirtyPalette = false;
}
QuickTimeDecoder::VideoTrackHandler::~VideoTrackHandler() {
@@ -544,6 +342,88 @@ QuickTimeDecoder::VideoTrackHandler::~VideoTrackHandler() {
}
}
+bool QuickTimeDecoder::VideoTrackHandler::endOfTrack() const {
+ // A track is over when we've finished going through all edits
+ return _curEdit == _parent->editCount;
+}
+
+bool QuickTimeDecoder::VideoTrackHandler::seek(const Audio::Timestamp &requestedTime) {
+ // First, figure out what edit we're in
+ Audio::Timestamp time = requestedTime.convertToFramerate(_parent->timeScale);
+
+ // Continue until we get to where we need to be
+ for (_curEdit = 0; !endOfTrack(); _curEdit++)
+ if ((uint32)time.totalNumberOfFrames() >= getCurEditTimeOffset() && (uint32)time.totalNumberOfFrames() < getCurEditTimeOffset() + getCurEditTrackDuration())
+ break;
+
+ // This track is done
+ if (endOfTrack())
+ return true;
+
+ enterNewEditList(false);
+
+ // One extra check for the end of a track
+ if (endOfTrack())
+ return true;
+
+ // Now we're in the edit and need to figure out what frame we need
+ while (getRateAdjustedFrameTime() < (uint32)time.totalNumberOfFrames()) {
+ _curFrame++;
+ if (_durationOverride >= 0) {
+ _nextFrameStartTime += _durationOverride;
+ _durationOverride = -1;
+ } else {
+ _nextFrameStartTime += getFrameDuration();
+ }
+ }
+
+ // All that's left is to figure out what our starting time is going to be
+ // Compare the starting point for the frame to where we need to be
+ _holdNextFrameStartTime = getRateAdjustedFrameTime() != (uint32)time.totalNumberOfFrames();
+
+ // If we went past the time, go back a frame
+ if (_holdNextFrameStartTime)
+ _curFrame--;
+
+ // Handle the keyframe here
+ int32 destinationFrame = _curFrame + 1;
+
+ assert(destinationFrame < (int32)_parent->frameCount);
+ _curFrame = findKeyFrame(destinationFrame) - 1;
+ while (_curFrame < destinationFrame - 1)
+ bufferNextFrame();
+
+ return true;
+}
+
+Audio::Timestamp QuickTimeDecoder::VideoTrackHandler::getDuration() const {
+ return Audio::Timestamp(0, _parent->duration, _decoder->_timeScale);
+}
+
+uint16 QuickTimeDecoder::VideoTrackHandler::getWidth() const {
+ return getScaledWidth().toInt();
+}
+
+uint16 QuickTimeDecoder::VideoTrackHandler::getHeight() const {
+ return getScaledHeight().toInt();
+}
+
+Graphics::PixelFormat QuickTimeDecoder::VideoTrackHandler::getPixelFormat() const {
+ return ((VideoSampleDesc *)_parent->sampleDescs[0])->_videoCodec->getPixelFormat();
+}
+
+int QuickTimeDecoder::VideoTrackHandler::getFrameCount() const {
+ return _parent->frameCount;
+}
+
+uint32 QuickTimeDecoder::VideoTrackHandler::getNextFrameStartTime() const {
+ if (endOfTrack())
+ return 0;
+
+ // Convert to milliseconds so the tracks can be compared
+ return getRateAdjustedFrameTime() * 1000 / _parent->timeScale;
+}
+
const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame() {
if (endOfTrack())
return 0;
@@ -574,7 +454,7 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame()
if (frame && (_parent->scaleFactorX != 1 || _parent->scaleFactorY != 1)) {
if (!_scaledSurface) {
_scaledSurface = new Graphics::Surface();
- _scaledSurface->create(getWidth().toInt(), getHeight().toInt(), getPixelFormat());
+ _scaledSurface->create(getScaledWidth().toInt(), getScaledHeight().toInt(), getPixelFormat());
}
_decoder->scaleSurface(frame, _scaledSurface, _parent->scaleFactorX, _parent->scaleFactorY);
@@ -584,6 +464,85 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::decodeNextFrame()
return frame;
}
+Common::Rational QuickTimeDecoder::VideoTrackHandler::getScaledWidth() const {
+ return Common::Rational(_parent->width) / _parent->scaleFactorX;
+}
+
+Common::Rational QuickTimeDecoder::VideoTrackHandler::getScaledHeight() const {
+ return Common::Rational(_parent->height) / _parent->scaleFactorY;
+}
+
+Common::SeekableReadStream *QuickTimeDecoder::VideoTrackHandler::getNextFramePacket(uint32 &descId) {
+ // First, we have to track down which chunk holds the sample and which sample in the chunk contains the frame we are looking for.
+ int32 totalSampleCount = 0;
+ int32 sampleInChunk = 0;
+ int32 actualChunk = -1;
+ uint32 sampleToChunkIndex = 0;
+
+ for (uint32 i = 0; i < _parent->chunkCount; i++) {
+ if (sampleToChunkIndex < _parent->sampleToChunkCount && i >= _parent->sampleToChunk[sampleToChunkIndex].first)
+ sampleToChunkIndex++;
+
+ totalSampleCount += _parent->sampleToChunk[sampleToChunkIndex - 1].count;
+
+ if (totalSampleCount > _curFrame) {
+ actualChunk = i;
+ descId = _parent->sampleToChunk[sampleToChunkIndex - 1].id;
+ sampleInChunk = _parent->sampleToChunk[sampleToChunkIndex - 1].count - totalSampleCount + _curFrame;
+ break;
+ }
+ }
+
+ if (actualChunk < 0) {
+ warning("Could not find data for frame %d", _curFrame);
+ return 0;
+ }
+
+ // Next seek to that frame
+ Common::SeekableReadStream *stream = _decoder->_fd;
+ stream->seek(_parent->chunkOffsets[actualChunk]);
+
+ // Then, if the chunk holds more than one frame, seek to where the frame we want is located
+ for (int32 i = _curFrame - sampleInChunk; i < _curFrame; i++) {
+ if (_parent->sampleSize != 0)
+ stream->skip(_parent->sampleSize);
+ else
+ stream->skip(_parent->sampleSizes[i]);
+ }
+
+ // Finally, read in the raw data for the frame
+ //debug("Frame Data[%d]: Offset = %d, Size = %d", _curFrame, stream->pos(), _parent->sampleSizes[_curFrame]);
+
+ if (_parent->sampleSize != 0)
+ return stream->readStream(_parent->sampleSize);
+
+ return stream->readStream(_parent->sampleSizes[_curFrame]);
+}
+
+uint32 QuickTimeDecoder::VideoTrackHandler::getFrameDuration() {
+ uint32 curFrameIndex = 0;
+ for (int32 i = 0; i < _parent->timeToSampleCount; i++) {
+ curFrameIndex += _parent->timeToSample[i].count;
+ if ((uint32)_curFrame < curFrameIndex) {
+ // Ok, now we have what duration this frame has.
+ return _parent->timeToSample[i].duration;
+ }
+ }
+
+ // This should never occur
+ error("Cannot find duration for frame %d", _curFrame);
+ return 0;
+}
+
+uint32 QuickTimeDecoder::VideoTrackHandler::findKeyFrame(uint32 frame) const {
+ for (int i = _parent->keyframeCount - 1; i >= 0; i--)
+ if (_parent->keyframes[i] <= frame)
+ return _parent->keyframes[i];
+
+ // If none found, we'll assume the requested frame is a key frame
+ return frame;
+}
+
void QuickTimeDecoder::VideoTrackHandler::enterNewEditList(bool bufferFrames) {
// Bypass all empty edit lists first
while (!endOfTrack() && _parent->editList[_curEdit].mediaTime == -1)
@@ -655,166 +614,25 @@ const Graphics::Surface *QuickTimeDecoder::VideoTrackHandler::bufferNextFrame()
if (entry->_videoCodec->containsPalette()) {
// The codec itself contains a palette
if (entry->_videoCodec->hasDirtyPalette()) {
- _decoder->_palette = entry->_videoCodec->getPalette();
- _decoder->_dirtyPalette = true;
+ _curPalette = entry->_videoCodec->getPalette();
+ _dirtyPalette = true;
}
} else {
// Check if the video description has been updated
byte *palette = entry->_palette;
- if (palette !=_decoder-> _palette) {
- _decoder->_palette = palette;
- _decoder->_dirtyPalette = true;
- }
- }
-
- return frame;
-}
-
-uint32 QuickTimeDecoder::VideoTrackHandler::getNextFrameStartTime() {
- if (endOfTrack())
- return 0;
-
- // Convert to milliseconds so the tracks can be compared
- return getRateAdjustedFrameTime() * 1000 / _parent->timeScale;
-}
-
-uint32 QuickTimeDecoder::VideoTrackHandler::getFrameCount() {
- return _parent->frameCount;
-}
-
-uint32 QuickTimeDecoder::VideoTrackHandler::getFrameDuration() {
- uint32 curFrameIndex = 0;
- for (int32 i = 0; i < _parent->timeToSampleCount; i++) {
- curFrameIndex += _parent->timeToSample[i].count;
- if ((uint32)_curFrame < curFrameIndex) {
- // Ok, now we have what duration this frame has.
- return _parent->timeToSample[i].duration;
- }
- }
-
- // This should never occur
- error("Cannot find duration for frame %d", _curFrame);
- return 0;
-}
-
-Common::SeekableReadStream *QuickTimeDecoder::VideoTrackHandler::getNextFramePacket(uint32 &descId) {
- // First, we have to track down which chunk holds the sample and which sample in the chunk contains the frame we are looking for.
- int32 totalSampleCount = 0;
- int32 sampleInChunk = 0;
- int32 actualChunk = -1;
- uint32 sampleToChunkIndex = 0;
-
- for (uint32 i = 0; i < _parent->chunkCount; i++) {
- if (sampleToChunkIndex < _parent->sampleToChunkCount && i >= _parent->sampleToChunk[sampleToChunkIndex].first)
- sampleToChunkIndex++;
-
- totalSampleCount += _parent->sampleToChunk[sampleToChunkIndex - 1].count;
-
- if (totalSampleCount > _curFrame) {
- actualChunk = i;
- descId = _parent->sampleToChunk[sampleToChunkIndex - 1].id;
- sampleInChunk = _parent->sampleToChunk[sampleToChunkIndex - 1].count - totalSampleCount + _curFrame;
- break;
+ if (palette != _curPalette) {
+ _curPalette = palette;
+ _dirtyPalette = true;
}
}
- if (actualChunk < 0) {
- warning("Could not find data for frame %d", _curFrame);
- return 0;
- }
-
- // Next seek to that frame
- _fd->seek(_parent->chunkOffsets[actualChunk]);
-
- // Then, if the chunk holds more than one frame, seek to where the frame we want is located
- for (int32 i = _curFrame - sampleInChunk; i < _curFrame; i++) {
- if (_parent->sampleSize != 0)
- _fd->skip(_parent->sampleSize);
- else
- _fd->skip(_parent->sampleSizes[i]);
- }
-
- // Finally, read in the raw data for the frame
- //debug("Frame Data[%d]: Offset = %d, Size = %d", _curFrame, _fd->pos(), _parent->sampleSizes[_curFrame]);
-
- if (_parent->sampleSize != 0)
- return _fd->readStream(_parent->sampleSize);
-
- return _fd->readStream(_parent->sampleSizes[_curFrame]);
-}
-
-uint32 QuickTimeDecoder::VideoTrackHandler::findKeyFrame(uint32 frame) const {
- for (int i = _parent->keyframeCount - 1; i >= 0; i--)
- if (_parent->keyframes[i] <= frame)
- return _parent->keyframes[i];
-
- // If none found, we'll assume the requested frame is a key frame
return frame;
}
-void QuickTimeDecoder::VideoTrackHandler::seekToTime(Audio::Timestamp time) {
- // First, figure out what edit we're in
- time = time.convertToFramerate(_parent->timeScale);
-
- // Continue until we get to where we need to be
- for (_curEdit = 0; !endOfTrack(); _curEdit++)
- if ((uint32)time.totalNumberOfFrames() >= getCurEditTimeOffset() && (uint32)time.totalNumberOfFrames() < getCurEditTimeOffset() + getCurEditTrackDuration())
- break;
-
- // This track is done
- if (endOfTrack())
- return;
-
- enterNewEditList(false);
-
- // One extra check for the end of a track
- if (endOfTrack())
- return;
-
- // Now we're in the edit and need to figure out what frame we need
- while (getRateAdjustedFrameTime() < (uint32)time.totalNumberOfFrames()) {
- _curFrame++;
- if (_durationOverride >= 0) {
- _nextFrameStartTime += _durationOverride;
- _durationOverride = -1;
- } else {
- _nextFrameStartTime += getFrameDuration();
- }
- }
-
- // All that's left is to figure out what our starting time is going to be
- // Compare the starting point for the frame to where we need to be
- _holdNextFrameStartTime = getRateAdjustedFrameTime() != (uint32)time.totalNumberOfFrames();
-
- // If we went past the time, go back a frame
- if (_holdNextFrameStartTime)
- _curFrame--;
-
- // Handle the keyframe here
- int32 destinationFrame = _curFrame + 1;
-
- assert(destinationFrame < (int32)_parent->frameCount);
- _curFrame = findKeyFrame(destinationFrame) - 1;
- while (_curFrame < destinationFrame - 1)
- bufferNextFrame();
-}
-
-Common::Rational QuickTimeDecoder::VideoTrackHandler::getWidth() const {
- return Common::Rational(_parent->width) / _parent->scaleFactorX;
-}
-
-Common::Rational QuickTimeDecoder::VideoTrackHandler::getHeight() const {
- return Common::Rational(_parent->height) / _parent->scaleFactorY;
-}
-
-Graphics::PixelFormat QuickTimeDecoder::VideoTrackHandler::getPixelFormat() const {
- return ((VideoSampleDesc *)_parent->sampleDescs[0])->_videoCodec->getPixelFormat();
-}
-
uint32 QuickTimeDecoder::VideoTrackHandler::getRateAdjustedFrameTime() const {
// Figure out what time the next frame is at taking the edit list rate into account
- uint32 convertedTime = (Common::Rational(_nextFrameStartTime - getCurEditTimeOffset()) / _parent->editList[_curEdit].mediaRate).toInt();
+ uint32 convertedTime = (Common::Rational(_nextFrameStartTime - getCurEditTimeOffset()) / _parent->editList[_curEdit].mediaRate).toInt();
return convertedTime + getCurEditTimeOffset();
}
diff --git a/video/qt_decoder.h b/video/qt_decoder.h
index 583b4b44b5..71d33711a6 100644
--- a/video/qt_decoder.h
+++ b/video/qt_decoder.h
@@ -31,16 +31,17 @@
#ifndef VIDEO_QT_DECODER_H
#define VIDEO_QT_DECODER_H
-#include "audio/mixer.h"
#include "audio/decoders/quicktime_intern.h"
#include "common/scummsys.h"
-#include "common/rational.h"
-#include "graphics/pixelformat.h"
#include "video/video_decoder.h"
namespace Common {
- class Rational;
+class Rational;
+}
+
+namespace Graphics {
+struct PixelFormat;
}
namespace Video {
@@ -54,68 +55,33 @@ class Codec;
* - mohawk
* - sci
*/
-class QuickTimeDecoder : public SeekableVideoDecoder, public Audio::QuickTimeAudioDecoder {
+class QuickTimeDecoder : public VideoDecoder, public Audio::QuickTimeAudioDecoder {
public:
QuickTimeDecoder();
virtual ~QuickTimeDecoder();
- /**
- * Returns the width of the video
- * @return the width of the video
- */
- uint16 getWidth() const { return _width; }
-
- /**
- * Returns the height of the video
- * @return the height of the video
- */
- uint16 getHeight() const { return _height; }
-
- /**
- * Returns the amount of frames in the video
- * @return the amount of frames in the video
- */
- uint32 getFrameCount() const;
-
- /**
- * Load a video file
- * @param filename the filename to load
- */
bool loadFile(const Common::String &filename);
-
- /**
- * Load a QuickTime video file from a SeekableReadStream
- * @param stream the stream to load
- */
bool loadStream(Common::SeekableReadStream *stream);
-
- /**
- * Close a QuickTime encoded video file
- */
void close();
+ uint16 getWidth() const { return _width; }
+ uint16 getHeight() const { return _height; }
+ const Graphics::Surface *decodeNextFrame();
+ Audio::Timestamp getDuration() const { return Audio::Timestamp(0, _duration, _timeScale); }
- /**
- * Returns the palette of the video
- * @return the palette of the video
- */
- const byte *getPalette() { _dirtyPalette = false; return _palette; }
- bool hasDirtyPalette() const { return _dirtyPalette; }
+protected:
+ Common::QuickTimeParser::SampleDesc *readSampleDesc(Common::QuickTimeParser::Track *track, uint32 format);
- int32 getCurFrame() const;
+private:
+ void init();
- bool isVideoLoaded() const { return isOpen(); }
- const Graphics::Surface *decodeNextFrame();
- bool endOfVideo() const;
- uint32 getElapsedTime() const;
- uint32 getTimeToNextFrame() const;
- Graphics::PixelFormat getPixelFormat() const;
+ void updateAudioBuffer();
- // SeekableVideoDecoder API
- void seekToFrame(uint32 frame);
- void seekToTime(Audio::Timestamp time);
- uint32 getDuration() const { return _duration * 1000 / _timeScale; }
+ uint16 _width, _height;
+
+ Graphics::Surface *_scaledSurface;
+ void scaleSurface(const Graphics::Surface *src, Graphics::Surface *dst,
+ const Common::Rational &scaleFactorX, const Common::Rational &scaleFactorY);
-protected:
class VideoSampleDesc : public Common::QuickTimeParser::SampleDesc {
public:
VideoSampleDesc(Common::QuickTimeParser::Track *parentTrack, uint32 codecTag);
@@ -131,106 +97,59 @@ protected:
Codec *_videoCodec;
};
- Common::QuickTimeParser::SampleDesc *readSampleDesc(Track *track, uint32 format);
-
-private:
- void init();
-
- void startAudio();
- void stopAudio();
- void updateAudioBuffer();
- void readNextAudioChunk();
- Common::Array<Audio::SoundHandle> _audioHandles;
- Audio::Timestamp _audioStartOffset;
-
- Codec *createCodec(uint32 codecTag, byte bitsPerPixel);
- uint32 findKeyFrame(uint32 frame) const;
-
- bool _dirtyPalette;
- const byte *_palette;
- bool _setStartTime;
- bool _needUpdate;
-
- uint16 _width, _height;
-
- Graphics::Surface *_scaledSurface;
- void scaleSurface(const Graphics::Surface *src, Graphics::Surface *dst,
- Common::Rational scaleFactorX, Common::Rational scaleFactorY);
-
- void pauseVideoIntern(bool pause);
- bool endOfVideoTracks() const;
-
- // The TrackHandler is a class that wraps around a QuickTime Track
- // and handles playback in this decoder class.
- class TrackHandler {
- public:
- TrackHandler(QuickTimeDecoder *decoder, Track *parent);
- virtual ~TrackHandler() {}
-
- enum TrackType {
- kTrackTypeAudio,
- kTrackTypeVideo
- };
-
- virtual TrackType getTrackType() const = 0;
-
- virtual void seekToTime(Audio::Timestamp time) = 0;
-
- virtual bool endOfTrack();
-
- protected:
- uint32 _curEdit;
- QuickTimeDecoder *_decoder;
- Common::SeekableReadStream *_fd;
- Track *_parent;
- };
-
// The AudioTrackHandler is currently just a wrapper around some
// QuickTimeDecoder functions.
- class AudioTrackHandler : public TrackHandler {
+ class AudioTrackHandler : public SeekableAudioTrack {
public:
AudioTrackHandler(QuickTimeDecoder *decoder, QuickTimeAudioTrack *audioTrack);
- TrackType getTrackType() const { return kTrackTypeAudio; }
void updateBuffer();
- void seekToTime(Audio::Timestamp time);
- bool endOfTrack();
+
+ protected:
+ Audio::SeekableAudioStream *getSeekableAudioStream() const;
private:
+ QuickTimeDecoder *_decoder;
QuickTimeAudioTrack *_audioTrack;
};
// The VideoTrackHandler is the bridge between the time of playback
// and the media for the given track. It calculates when to start
// tracks and at what rate to play the media using the edit list.
- class VideoTrackHandler : public TrackHandler {
+ class VideoTrackHandler : public VideoTrack {
public:
- VideoTrackHandler(QuickTimeDecoder *decoder, Track *parent);
+ VideoTrackHandler(QuickTimeDecoder *decoder, Common::QuickTimeParser::Track *parent);
~VideoTrackHandler();
- TrackType getTrackType() const { return kTrackTypeVideo; }
-
- const Graphics::Surface *decodeNextFrame();
-
- uint32 getNextFrameStartTime();
-
- uint32 getFrameCount();
-
- int32 getCurFrame() { return _curFrame; }
+ bool endOfTrack() const;
+ bool isSeekable() const { return true; }
+ bool seek(const Audio::Timestamp &time);
+ Audio::Timestamp getDuration() const;
+ uint16 getWidth() const;
+ uint16 getHeight() const;
Graphics::PixelFormat getPixelFormat() const;
+ int getCurFrame() const { return _curFrame; }
+ int getFrameCount() const;
+ uint32 getNextFrameStartTime() const;
+ const Graphics::Surface *decodeNextFrame();
+ const byte *getPalette() const { _dirtyPalette = false; return _curPalette; }
+ bool hasDirtyPalette() const { return _curPalette; }
- void seekToTime(Audio::Timestamp time);
-
- Common::Rational getWidth() const;
- Common::Rational getHeight() const;
+ Common::Rational getScaledWidth() const;
+ Common::Rational getScaledHeight() const;
private:
+ QuickTimeDecoder *_decoder;
+ Common::QuickTimeParser::Track *_parent;
+ uint32 _curEdit;
int32 _curFrame;
uint32 _nextFrameStartTime;
Graphics::Surface *_scaledSurface;
bool _holdNextFrameStartTime;
int32 _durationOverride;
+ const byte *_curPalette;
+ mutable bool _dirtyPalette;
Common::SeekableReadStream *getNextFramePacket(uint32 &descId);
uint32 getFrameDuration();
@@ -241,12 +160,6 @@ private:
uint32 getCurEditTimeOffset() const;
uint32 getCurEditTrackDuration() const;
};
-
- Common::Array<TrackHandler *> _handlers;
- VideoTrackHandler *_nextVideoTrack;
- VideoTrackHandler *findNextVideoTrack() const;
-
- void freeAllTrackHandlers();
};
} // End of namespace Video
diff --git a/video/smk_decoder.cpp b/video/smk_decoder.cpp
index 084028300d..bea65142a1 100644
--- a/video/smk_decoder.cpp
+++ b/video/smk_decoder.cpp
@@ -204,8 +204,7 @@ BigHuffmanTree::BigHuffmanTree(Common::BitStream &bs, int allocSize)
delete _hiBytes;
}
-BigHuffmanTree::~BigHuffmanTree()
-{
+BigHuffmanTree::~BigHuffmanTree() {
delete[] _tree;
}
@@ -278,24 +277,17 @@ uint32 BigHuffmanTree::getCode(Common::BitStream &bs) {
return v;
}
-SmackerDecoder::SmackerDecoder(Audio::Mixer *mixer, Audio::Mixer::SoundType soundType)
- : _audioStarted(false), _audioStream(0), _mixer(mixer), _soundType(soundType) {
- _surface = 0;
+SmackerDecoder::SmackerDecoder(Audio::Mixer::SoundType soundType) : _soundType(soundType) {
_fileStream = 0;
- _dirtyPalette = false;
+ _firstFrameStart = 0;
+ _frameTypes = 0;
+ _frameSizes = 0;
}
SmackerDecoder::~SmackerDecoder() {
close();
}
-uint32 SmackerDecoder::getElapsedTime() const {
- if (_audioStream && _audioStarted)
- return _mixer->getSoundElapsedTime(_audioHandle);
-
- return FixedRateVideoDecoder::getElapsedTime();
-}
-
bool SmackerDecoder::loadStream(Common::SeekableReadStream *stream) {
close();
@@ -309,16 +301,17 @@ bool SmackerDecoder::loadStream(Common::SeekableReadStream *stream) {
uint32 width = _fileStream->readUint32LE();
uint32 height = _fileStream->readUint32LE();
- _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);
+ uint32 frameCount = _fileStream->readUint32LE();
+ int32 frameDelay = _fileStream->readSint32LE();
+
+ // frame rate contains 2 digits after the comma, so 1497 is actually 14.97 fps
+ Common::Rational frameRate;
+ if (frameDelay > 0)
+ frameRate = Common::Rational(1000, frameDelay);
+ else if (frameDelay < 0)
+ frameRate = Common::Rational(100000, -frameDelay);
else
- _frameRate = 1000;
+ 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.
@@ -328,6 +321,9 @@ bool SmackerDecoder::loadStream(Common::SeekableReadStream *stream) {
// before it is displayed.
_header.flags = _fileStream->readUint32LE();
+ SmackerVideoTrack *videoTrack = createVideoTrack(width, height, frameCount, frameRate, _header.flags, _header.signature);
+ addTrack(videoTrack);
+
// TODO: should we do any extra processing for Smacker files with ring frames?
// TODO: should we do any extra processing for Y-doubled videos? Are they the
@@ -374,92 +370,77 @@ bool SmackerDecoder::loadStream(Common::SeekableReadStream *stream) {
warning("Unhandled Smacker v2 audio compression");
if (i == 0)
- _audioStream = Audio::makeQueuingAudioStream(_header.audioInfo[0].sampleRate, _header.audioInfo[0].isStereo);
+ addTrack(new SmackerAudioTrack(_header.audioInfo[i], _soundType));
}
}
_header.dummy = _fileStream->readUint32LE();
- _frameSizes = new uint32[_frameCount];
- for (i = 0; i < _frameCount; ++i)
+ _frameSizes = new uint32[frameCount];
+ for (i = 0; i < frameCount; ++i)
_frameSizes[i] = _fileStream->readUint32LE();
- _frameTypes = new byte[_frameCount];
- for (i = 0; i < _frameCount; ++i)
+ _frameTypes = new byte[frameCount];
+ for (i = 0; i < frameCount; ++i)
_frameTypes[i] = _fileStream->readByte();
byte *huffmanTrees = (byte *) malloc(_header.treesSize);
_fileStream->read(huffmanTrees, _header.treesSize);
Common::BitStream8LSB bs(new Common::MemoryReadStream(huffmanTrees, _header.treesSize, DisposeAfterUse::YES), true);
+ videoTrack->readTrees(bs, _header.mMapSize, _header.mClrSize, _header.fullSize, _header.typeSize);
- _MMapTree = new BigHuffmanTree(bs, _header.mMapSize);
- _MClrTree = new BigHuffmanTree(bs, _header.mClrSize);
- _FullTree = new BigHuffmanTree(bs, _header.fullSize);
- _TypeTree = new BigHuffmanTree(bs, _header.typeSize);
-
- _surface = new Graphics::Surface();
+ _firstFrameStart = _fileStream->pos();
- // Height needs to be doubled if we have flags (Y-interlaced or Y-doubled)
- _surface->create(width, height * (_header.flags ? 2 : 1), Graphics::PixelFormat::createFormatCLUT8());
-
- memset(_palette, 0, 3 * 256);
return true;
}
void SmackerDecoder::close() {
- if (!_fileStream)
- return;
-
- if (_audioStream) {
- if (_audioStarted) {
- // The mixer will delete the stream.
- _mixer->stopHandle(_audioHandle);
- _audioStarted = false;
- } else {
- delete _audioStream;
- }
- _audioStream = 0;
- }
+ VideoDecoder::close();
delete _fileStream;
_fileStream = 0;
- _surface->free();
- delete _surface;
- _surface = 0;
-
- delete _MMapTree;
- delete _MClrTree;
- delete _FullTree;
- delete _TypeTree;
+ delete[] _frameTypes;
+ _frameTypes = 0;
delete[] _frameSizes;
- delete[] _frameTypes;
+ _frameSizes = 0;
+}
- reset();
+bool SmackerDecoder::rewind() {
+ // Call the parent method to rewind the tracks first
+ if (!VideoDecoder::rewind())
+ return false;
+
+ // And seek back to where the first frame begins
+ _fileStream->seek(_firstFrameStart);
+ return true;
}
-const Graphics::Surface *SmackerDecoder::decodeNextFrame() {
+void SmackerDecoder::readNextPacket() {
+ SmackerVideoTrack *videoTrack = (SmackerVideoTrack *)getTrack(0);
+
+ if (videoTrack->endOfTrack())
+ return;
+
+ videoTrack->increaseCurFrame();
+
uint i;
uint32 chunkSize = 0;
uint32 dataSizeUnpacked = 0;
uint32 startPos = _fileStream->pos();
- _curFrame++;
-
// Check if we got a frame with palette data, and
// call back the virtual setPalette function to set
// the current palette
- if (_frameTypes[_curFrame] & 1) {
- unpackPalette();
- _dirtyPalette = true;
- }
+ if (_frameTypes[videoTrack->getCurFrame()] & 1)
+ videoTrack->unpackPalette(_fileStream);
// Load audio tracks
for (i = 0; i < 7; ++i) {
- if (!(_frameTypes[_curFrame] & (2 << i)))
+ if (!(_frameTypes[videoTrack->getCurFrame()] & (2 << i)))
continue;
chunkSize = _fileStream->readUint32LE();
@@ -475,29 +456,109 @@ const Graphics::Surface *SmackerDecoder::decodeNextFrame() {
handleAudioTrack(i, chunkSize, dataSizeUnpacked);
}
- uint32 frameSize = _frameSizes[_curFrame] & ~3;
-// uint32 remainder = _frameSizes[_curFrame] & 3;
+ uint32 frameSize = _frameSizes[videoTrack->getCurFrame()] & ~3;
+// uint32 remainder = _frameSizes[videoTrack->getCurFrame()] & 3;
if (_fileStream->pos() - startPos > frameSize)
error("Smacker actual frame size exceeds recorded frame size");
uint32 frameDataSize = frameSize - (_fileStream->pos() - startPos);
- _frameData = (byte *)malloc(frameDataSize + 1);
+ byte *frameData = (byte *)malloc(frameDataSize + 1);
// Padding to keep the BigHuffmanTrees from reading past the data end
- _frameData[frameDataSize] = 0x00;
+ frameData[frameDataSize] = 0x00;
+
+ _fileStream->read(frameData, frameDataSize);
+
+ Common::BitStream8LSB bs(new Common::MemoryReadStream(frameData, frameDataSize + 1, DisposeAfterUse::YES), true);
+ videoTrack->decodeFrame(bs);
+
+ _fileStream->seek(startPos + frameSize);
+}
+
+void SmackerDecoder::handleAudioTrack(byte track, uint32 chunkSize, uint32 unpackedSize) {
+ if (_header.audioInfo[track].hasAudio && chunkSize > 0 && track == 0) {
+ // Get the audio track, which start at offset 1 (first track is video)
+ SmackerAudioTrack *audioTrack = (SmackerAudioTrack *)getTrack(track + 1);
+
+ // If it's track 0, play the audio data
+ byte *soundBuffer = (byte *)malloc(chunkSize + 1);
+ // Padding to keep the SmallHuffmanTrees from reading past the data end
+ soundBuffer[chunkSize] = 0x00;
+
+ _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)
+ audioTrack->queueCompressedBuffer(soundBuffer, chunkSize + 1, unpackedSize);
+ free(soundBuffer);
+ } else {
+ // Uncompressed audio (PCM)
+ audioTrack->queuePCM(soundBuffer, chunkSize);
+ }
+ } 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);
+ }
+}
- _fileStream->read(_frameData, frameDataSize);
+SmackerDecoder::SmackerVideoTrack::SmackerVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, uint32 flags, uint32 signature) {
+ _surface = new Graphics::Surface();
+ _surface->create(width, height * (flags ? 2 : 1), Graphics::PixelFormat::createFormatCLUT8());
+ _frameCount = frameCount;
+ _frameRate = frameRate;
+ _flags = flags;
+ _signature = signature;
+ _curFrame = -1;
+ _dirtyPalette = false;
+ _MMapTree = _MClrTree = _FullTree = _TypeTree = 0;
+ memset(_palette, 0, 3 * 256);
+}
- Common::BitStream8LSB bs(new Common::MemoryReadStream(_frameData, frameDataSize + 1, DisposeAfterUse::YES), true);
+SmackerDecoder::SmackerVideoTrack::~SmackerVideoTrack() {
+ _surface->free();
+ delete _surface;
+ delete _MMapTree;
+ delete _MClrTree;
+ delete _FullTree;
+ delete _TypeTree;
+}
+
+uint16 SmackerDecoder::SmackerVideoTrack::getWidth() const {
+ return _surface->w;
+}
+
+uint16 SmackerDecoder::SmackerVideoTrack::getHeight() const {
+ return _surface->h;
+}
+
+Graphics::PixelFormat SmackerDecoder::SmackerVideoTrack::getPixelFormat() const {
+ return _surface->format;
+}
+
+void SmackerDecoder::SmackerVideoTrack::readTrees(Common::BitStream &bs, uint32 mMapSize, uint32 mClrSize, uint32 fullSize, uint32 typeSize) {
+ _MMapTree = new BigHuffmanTree(bs, mMapSize);
+ _MClrTree = new BigHuffmanTree(bs, mClrSize);
+ _FullTree = new BigHuffmanTree(bs, fullSize);
+ _TypeTree = new BigHuffmanTree(bs, typeSize);
+}
+
+void SmackerDecoder::SmackerVideoTrack::decodeFrame(Common::BitStream &bs) {
_MMapTree->reset();
_MClrTree->reset();
_FullTree->reset();
_TypeTree->reset();
// Height needs to be doubled if we have flags (Y-interlaced or Y-doubled)
- uint doubleY = _header.flags ? 2 : 1;
+ uint doubleY = _flags ? 2 : 1;
uint bw = getWidth() / 4;
uint bh = getHeight() / doubleY / 4;
@@ -508,6 +569,7 @@ const Graphics::Surface *SmackerDecoder::decodeNextFrame() {
uint type, run, j, mode;
uint32 p1, p2, clr, map;
byte hi, lo;
+ uint i;
while (block < blocks) {
type = _TypeTree->getCode(bs);
@@ -536,7 +598,7 @@ const Graphics::Surface *SmackerDecoder::decodeNextFrame() {
break;
case SMK_BLOCK_FULL:
// Smacker v2 has one mode, Smacker v4 has three
- if (_header.signature == MKTAG('S','M','K','2')) {
+ if (_signature == MKTAG('S','M','K','2')) {
mode = 0;
} else {
// 00 - mode 0
@@ -628,60 +690,81 @@ const Graphics::Surface *SmackerDecoder::decodeNextFrame() {
break;
}
}
+}
- _fileStream->seek(startPos + frameSize);
+void SmackerDecoder::SmackerVideoTrack::unpackPalette(Common::SeekableReadStream *stream) {
+ uint startPos = stream->pos();
+ uint32 len = 4 * stream->readByte();
- if (_curFrame == 0)
- _startTime = g_system->getMillis();
+ byte *chunk = (byte *)malloc(len);
+ stream->read(chunk, len);
+ byte *p = chunk;
- return _surface;
-}
+ byte oldPalette[3 * 256];
+ memcpy(oldPalette, _palette, 3 * 256);
-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 + 1);
- // Padding to keep the SmallHuffmanTrees from reading past the data end
- soundBuffer[chunkSize] = 0x00;
+ byte *pal = _palette;
- _fileStream->read(soundBuffer, chunkSize);
+ int sz = 0;
+ byte b0;
+ while (sz < 256) {
+ b0 = *p++;
+ if (b0 & 0x80) { // if top bit is 1 (0x80 = 10000000)
+ sz += (b0 & 0x7f) + 1; // get lower 7 bits + 1 (0x7f = 01111111)
+ pal += 3 * ((b0 & 0x7f) + 1);
+ } else if (b0 & 0x40) { // if top 2 bits are 01 (0x40 = 01000000)
+ byte c = (b0 & 0x3f) + 1; // get lower 6 bits + 1 (0x3f = 00111111)
+ uint s = 3 * *p++;
+ sz += c;
- 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 + 1, 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
- }
+ while (c--) {
+ *pal++ = oldPalette[s + 0];
+ *pal++ = oldPalette[s + 1];
+ *pal++ = oldPalette[s + 2];
+ s += 3;
+ }
+ } else { // top 2 bits are 00
+ sz++;
+ // get the lower 6 bits for each component (0x3f = 00111111)
+ byte b = b0 & 0x3f;
+ byte g = (*p++) & 0x3f;
+ byte r = (*p++) & 0x3f;
+
+ assert(g < 0xc0 && b < 0xc0);
- if (!_audioStarted) {
- _mixer->playStream(_soundType, &_audioHandle, _audioStream, -1, 255);
- _audioStarted = true;
+ // upscale to full 8-bit color values by multiplying by 4
+ *pal++ = b * 4;
+ *pal++ = g * 4;
+ *pal++ = r * 4;
}
- } 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);
}
+
+ stream->seek(startPos + len);
+ free(chunk);
+
+ _dirtyPalette = true;
}
-void SmackerDecoder::queueCompressedBuffer(byte *buffer, uint32 bufferSize,
- uint32 unpackedSize, int streamNum) {
+SmackerDecoder::SmackerAudioTrack::SmackerAudioTrack(const AudioInfo &audioInfo, Audio::Mixer::SoundType soundType) :
+ _audioInfo(audioInfo), _soundType(soundType) {
+ _audioStream = Audio::makeQueuingAudioStream(_audioInfo.sampleRate, _audioInfo.isStereo);
+}
+SmackerDecoder::SmackerAudioTrack::~SmackerAudioTrack() {
+ delete _audioStream;
+}
+
+bool SmackerDecoder::SmackerAudioTrack::rewind() {
+ delete _audioStream;
+ _audioStream = Audio::makeQueuingAudioStream(_audioInfo.sampleRate, _audioInfo.isStereo);
+ return true;
+}
+
+Audio::AudioStream *SmackerDecoder::SmackerAudioTrack::getAudioStream() const {
+ return _audioStream;
+}
+
+void SmackerDecoder::SmackerAudioTrack::queueCompressedBuffer(byte *buffer, uint32 bufferSize, uint32 unpackedSize) {
Common::BitStream8LSB audioBS(new Common::MemoryReadStream(buffer, bufferSize), true);
bool dataPresent = audioBS.getBit();
@@ -689,9 +772,9 @@ void SmackerDecoder::queueCompressedBuffer(byte *buffer, uint32 bufferSize,
return;
bool isStereo = audioBS.getBit();
- assert(isStereo == _header.audioInfo[streamNum].isStereo);
+ assert(isStereo == _audioInfo.isStereo);
bool is16Bits = audioBS.getBit();
- assert(is16Bits == _header.audioInfo[streamNum].is16Bits);
+ assert(is16Bits == _audioInfo.is16Bits);
int numBytes = 1 * (isStereo ? 2 : 1) * (is16Bits ? 2 : 1);
@@ -759,64 +842,21 @@ void SmackerDecoder::queueCompressedBuffer(byte *buffer, uint32 bufferSize,
for (int k = 0; k < numBytes; k++)
delete audioTrees[k];
- 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(unpackedBuffer, unpackedSize, DisposeAfterUse::YES, flags);
- // unpackedBuffer will be deleted by QueuingAudioStream
+ queuePCM(unpackedBuffer, unpackedSize);
}
-void SmackerDecoder::unpackPalette() {
- uint startPos = _fileStream->pos();
- uint32 len = 4 * _fileStream->readByte();
-
- byte *chunk = (byte *)malloc(len);
- _fileStream->read(chunk, len);
- byte *p = chunk;
-
- byte oldPalette[3*256];
- memcpy(oldPalette, _palette, 3 * 256);
-
- byte *pal = _palette;
-
- int sz = 0;
- byte b0;
- while (sz < 256) {
- b0 = *p++;
- if (b0 & 0x80) { // if top bit is 1 (0x80 = 10000000)
- sz += (b0 & 0x7f) + 1; // get lower 7 bits + 1 (0x7f = 01111111)
- pal += 3 * ((b0 & 0x7f) + 1);
- } else if (b0 & 0x40) { // if top 2 bits are 01 (0x40 = 01000000)
- byte c = (b0 & 0x3f) + 1; // get lower 6 bits + 1 (0x3f = 00111111)
- uint s = 3 * *p++;
- sz += c;
-
- while (c--) {
- *pal++ = oldPalette[s + 0];
- *pal++ = oldPalette[s + 1];
- *pal++ = oldPalette[s + 2];
- s += 3;
- }
- } else { // top 2 bits are 00
- sz++;
- // get the lower 6 bits for each component (0x3f = 00111111)
- byte b = b0 & 0x3f;
- byte g = (*p++) & 0x3f;
- byte r = (*p++) & 0x3f;
-
- assert(g < 0xc0 && b < 0xc0);
+void SmackerDecoder::SmackerAudioTrack::queuePCM(byte *buffer, uint32 bufferSize) {
+ byte flags = 0;
+ if (_audioInfo.is16Bits)
+ flags |= Audio::FLAG_16BITS;
+ if (_audioInfo.isStereo)
+ flags |= Audio::FLAG_STEREO;
- // upscale to full 8-bit color values by multiplying by 4
- *pal++ = b * 4;
- *pal++ = g * 4;
- *pal++ = r * 4;
- }
- }
+ _audioStream->queueBuffer(buffer, bufferSize, DisposeAfterUse::YES, flags);
+}
- _fileStream->seek(startPos + len);
- free(chunk);
+SmackerDecoder::SmackerVideoTrack *SmackerDecoder::createVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, uint32 flags, uint32 signature) const {
+ return new SmackerVideoTrack(width, height, frameCount, frameRate, flags, signature);
}
} // End of namespace Video
diff --git a/video/smk_decoder.h b/video/smk_decoder.h
index 72cd32a222..7227238373 100644
--- a/video/smk_decoder.h
+++ b/video/smk_decoder.h
@@ -34,6 +34,7 @@ class QueuingAudioStream;
}
namespace Common {
+class BitStream;
class SeekableReadStream;
}
@@ -56,36 +57,72 @@ class BigHuffmanTree;
* - sword2
* - toon
*/
-class SmackerDecoder : public FixedRateVideoDecoder {
+class SmackerDecoder : public VideoDecoder {
public:
- SmackerDecoder(Audio::Mixer *mixer,
- Audio::Mixer::SoundType soundType = Audio::Mixer::kSFXSoundType);
+ SmackerDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kSFXSoundType);
virtual ~SmackerDecoder();
- bool loadStream(Common::SeekableReadStream *stream);
+ virtual bool loadStream(Common::SeekableReadStream *stream);
void close();
- bool isVideoLoaded() const { return _fileStream != 0; }
- uint16 getWidth() const { return _surface->w; }
- uint16 getHeight() const { return _surface->h; }
- uint32 getFrameCount() const { return _frameCount; }
- uint32 getElapsedTime() const;
- const Graphics::Surface *decodeNextFrame();
- Graphics::PixelFormat getPixelFormat() const { return Graphics::PixelFormat::createFormatCLUT8(); }
- const byte *getPalette() { _dirtyPalette = false; return _palette; }
- bool hasDirtyPalette() const { return _dirtyPalette; }
- virtual void handleAudioTrack(byte track, uint32 chunkSize, uint32 unpackedSize);
+ bool rewind();
protected:
- Common::Rational getFrameRate() const { return _frameRate; }
- Common::SeekableReadStream *_fileStream;
+ void readNextPacket();
-protected:
- void unpackPalette();
- // Possible runs of blocks
- uint getBlockRun(int index) { return (index <= 58) ? index + 1 : 128 << (index - 59); }
- void queueCompressedBuffer(byte *buffer, uint32 bufferSize, uint32 unpackedSize, int streamNum);
+ virtual void handleAudioTrack(byte track, uint32 chunkSize, uint32 unpackedSize);
+
+ class SmackerVideoTrack : public FixedRateVideoTrack {
+ public:
+ SmackerVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, uint32 flags, uint32 signature);
+ ~SmackerVideoTrack();
+
+ bool isRewindable() const { return true; }
+ bool rewind() { _curFrame = -1; return true; }
+
+ uint16 getWidth() const;
+ uint16 getHeight() const;
+ Graphics::PixelFormat getPixelFormat() const;
+ int getCurFrame() const { return _curFrame; }
+ int getFrameCount() const { return _frameCount; }
+ const Graphics::Surface *decodeNextFrame() { return _surface; }
+ const byte *getPalette() const { _dirtyPalette = false; return _palette; }
+ bool hasDirtyPalette() const { return _dirtyPalette; }
+
+ void readTrees(Common::BitStream &bs, uint32 mMapSize, uint32 mClrSize, uint32 fullSize, uint32 typeSize);
+ void increaseCurFrame() { _curFrame++; }
+ void decodeFrame(Common::BitStream &bs);
+ void unpackPalette(Common::SeekableReadStream *stream);
+
+ protected:
+ Common::Rational getFrameRate() const { return _frameRate; }
+
+ Graphics::Surface *_surface;
+
+ private:
+ Common::Rational _frameRate;
+ uint32 _flags, _signature;
+
+ byte _palette[3 * 256];
+ mutable bool _dirtyPalette;
+
+ int _curFrame;
+ uint32 _frameCount;
+ BigHuffmanTree *_MMapTree;
+ BigHuffmanTree *_MClrTree;
+ BigHuffmanTree *_FullTree;
+ BigHuffmanTree *_TypeTree;
+
+ // Possible runs of blocks
+ static uint getBlockRun(int index) { return (index <= 58) ? index + 1 : 128 << (index - 59); }
+ };
+
+ virtual SmackerVideoTrack *createVideoTrack(uint32 width, uint32 height, uint32 frameCount, const Common::Rational &frameRate, uint32 flags, uint32 signature) const;
+
+ Common::SeekableReadStream *_fileStream;
+
+private:
enum AudioCompression {
kCompressionNone,
kCompressionDPCM,
@@ -114,6 +151,28 @@ protected:
uint32 dummy;
} _header;
+ class SmackerAudioTrack : public AudioTrack {
+ public:
+ SmackerAudioTrack(const AudioInfo &audioInfo, Audio::Mixer::SoundType soundType);
+ ~SmackerAudioTrack();
+
+ bool isRewindable() const { return true; }
+ bool rewind();
+
+ Audio::Mixer::SoundType getSoundType() const { return _soundType; }
+
+ void queueCompressedBuffer(byte *buffer, uint32 bufferSize, uint32 unpackedSize);
+ void queuePCM(byte *buffer, uint32 bufferSize);
+
+ protected:
+ Audio::AudioStream *getAudioStream() const;
+
+ private:
+ Audio::Mixer::SoundType _soundType;
+ Audio::QueuingAudioStream *_audioStream;
+ AudioInfo _audioInfo;
+ };
+
uint32 *_frameSizes;
// The FrameTypes section of a Smacker file contains an array of bytes, where
// the 8 bits of each byte describe the contents of the corresponding frame.
@@ -121,25 +180,10 @@ protected:
// and so on), so there can be up to 7 different audio tracks. When the lowest bit
// (bit 0) is set, it denotes a frame that contains a palette record
byte *_frameTypes;
- byte *_frameData;
- // The RGB palette
- byte _palette[3 * 256];
- bool _dirtyPalette;
- Common::Rational _frameRate;
- uint32 _frameCount;
- Graphics::Surface *_surface;
+ uint32 _firstFrameStart;
Audio::Mixer::SoundType _soundType;
- Audio::Mixer *_mixer;
- bool _audioStarted;
- Audio::QueuingAudioStream *_audioStream;
- Audio::SoundHandle _audioHandle;
-
- BigHuffmanTree *_MMapTree;
- BigHuffmanTree *_MClrTree;
- BigHuffmanTree *_FullTree;
- BigHuffmanTree *_TypeTree;
};
} // End of namespace Video
diff --git a/video/theora_decoder.cpp b/video/theora_decoder.cpp
new file mode 100644
index 0000000000..d7260469e6
--- /dev/null
+++ b/video/theora_decoder.cpp
@@ -0,0 +1,487 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * Source is based on the player example from libvorbis package,
+ * available at: http://svn.xiph.org/trunk/theora/examples/player_example.c
+ *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.
+ *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009
+ * by the Xiph.Org Foundation and contributors http://www.xiph.org/
+ *
+ */
+
+#include "video/theora_decoder.h"
+
+#include "audio/audiostream.h"
+#include "audio/decoders/raw.h"
+#include "common/stream.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+#include "common/util.h"
+#include "graphics/pixelformat.h"
+#include "graphics/yuv_to_rgb.h"
+
+namespace Video {
+
+TheoraDecoder::TheoraDecoder(Audio::Mixer::SoundType soundType) : _soundType(soundType) {
+ _fileStream = 0;
+
+ _videoTrack = 0;
+ _audioTrack = 0;
+ _hasVideo = _hasAudio = false;
+}
+
+TheoraDecoder::~TheoraDecoder() {
+ close();
+}
+
+bool TheoraDecoder::loadStream(Common::SeekableReadStream *stream) {
+ close();
+
+ _fileStream = stream;
+
+ // start up Ogg stream synchronization layer
+ ogg_sync_init(&_oggSync);
+
+ // init supporting Vorbis structures needed in header parsing
+ vorbis_info_init(&_vorbisInfo);
+ vorbis_comment vorbisComment;
+ vorbis_comment_init(&vorbisComment);
+
+ // init supporting Theora structures needed in header parsing
+ th_info theoraInfo;
+ th_info_init(&theoraInfo);
+ th_comment theoraComment;
+ th_comment_init(&theoraComment);
+ th_setup_info *theoraSetup = 0;
+
+ uint theoraPackets = 0, vorbisPackets = 0;
+
+ // Ogg file open; parse the headers
+ // Only interested in Vorbis/Theora streams
+ bool foundHeader = false;
+ while (!foundHeader) {
+ int ret = bufferData();
+
+ if (ret == 0)
+ break; // FIXME: Shouldn't this error out?
+
+ while (ogg_sync_pageout(&_oggSync, &_oggPage) > 0) {
+ ogg_stream_state test;
+
+ // is this a mandated initial header? If not, stop parsing
+ if (!ogg_page_bos(&_oggPage)) {
+ // don't leak the page; get it into the appropriate stream
+ queuePage(&_oggPage);
+ foundHeader = true;
+ break;
+ }
+
+ ogg_stream_init(&test, ogg_page_serialno(&_oggPage));
+ ogg_stream_pagein(&test, &_oggPage);
+ ogg_stream_packetout(&test, &_oggPacket);
+
+ // identify the codec: try theora
+ if (theoraPackets == 0 && th_decode_headerin(&theoraInfo, &theoraComment, &theoraSetup, &_oggPacket) >= 0) {
+ // it is theora
+ memcpy(&_theoraOut, &test, sizeof(test));
+ theoraPackets = 1;
+ _hasVideo = true;
+ } else if (vorbisPackets == 0 && vorbis_synthesis_headerin(&_vorbisInfo, &vorbisComment, &_oggPacket) >= 0) {
+ // it is vorbis
+ memcpy(&_vorbisOut, &test, sizeof(test));
+ vorbisPackets = 1;
+ _hasAudio = true;
+ } else {
+ // whatever it is, we don't care about it
+ ogg_stream_clear(&test);
+ }
+ }
+ // fall through to non-bos page parsing
+ }
+
+ // we're expecting more header packets.
+ while ((theoraPackets && theoraPackets < 3) || (vorbisPackets && vorbisPackets < 3)) {
+ int ret;
+
+ // look for further theora headers
+ while (theoraPackets && (theoraPackets < 3) && (ret = ogg_stream_packetout(&_theoraOut, &_oggPacket))) {
+ if (ret < 0)
+ error("Error parsing Theora stream headers; corrupt stream?");
+
+ if (!th_decode_headerin(&theoraInfo, &theoraComment, &theoraSetup, &_oggPacket))
+ error("Error parsing Theora stream headers; corrupt stream?");
+
+ theoraPackets++;
+ }
+
+ // look for more vorbis header packets
+ while (vorbisPackets && (vorbisPackets < 3) && (ret = ogg_stream_packetout(&_vorbisOut, &_oggPacket))) {
+ if (ret < 0)
+ error("Error parsing Vorbis stream headers; corrupt stream?");
+
+ if (vorbis_synthesis_headerin(&_vorbisInfo, &vorbisComment, &_oggPacket))
+ error("Error parsing Vorbis stream headers; corrupt stream?");
+
+ vorbisPackets++;
+
+ if (vorbisPackets == 3)
+ break;
+ }
+
+ // The header pages/packets will arrive before anything else we
+ // care about, or the stream is not obeying spec
+
+ if (ogg_sync_pageout(&_oggSync, &_oggPage) > 0) {
+ queuePage(&_oggPage); // demux into the appropriate stream
+ } else {
+ ret = bufferData(); // someone needs more data
+
+ if (ret == 0)
+ error("End of file while searching for codec headers.");
+ }
+ }
+
+ // And now we have it all. Initialize decoders next
+ if (_hasVideo) {
+ _videoTrack = new TheoraVideoTrack(getDefaultHighColorFormat(), theoraInfo, theoraSetup);
+ addTrack(_videoTrack);
+ }
+
+ th_info_clear(&theoraInfo);
+ th_comment_clear(&theoraComment);
+ th_setup_free(theoraSetup);
+
+ if (_hasAudio) {
+ _audioTrack = new VorbisAudioTrack(_soundType, _vorbisInfo);
+
+ // Get enough audio data to start us off
+ while (!_audioTrack->hasAudio()) {
+ // Queue more data
+ bufferData();
+ while (ogg_sync_pageout(&_oggSync, &_oggPage) > 0)
+ queuePage(&_oggPage);
+
+ queueAudio();
+ }
+
+ addTrack(_audioTrack);
+ }
+
+ vorbis_comment_clear(&vorbisComment);
+
+ return true;
+}
+
+void TheoraDecoder::close() {
+ VideoDecoder::close();
+
+ if (!_fileStream)
+ return;
+
+ if (_videoTrack) {
+ ogg_stream_clear(&_theoraOut);
+ _videoTrack = 0;
+ }
+
+ if (_audioTrack) {
+ ogg_stream_clear(&_vorbisOut);
+ _audioTrack = 0;
+ }
+
+ ogg_sync_clear(&_oggSync);
+ vorbis_info_clear(&_vorbisInfo);
+
+ delete _fileStream;
+ _fileStream = 0;
+
+ _hasVideo = _hasAudio = false;
+}
+
+void TheoraDecoder::readNextPacket() {
+ // First, let's get our frame
+ if (_hasVideo) {
+ while (!_videoTrack->endOfTrack()) {
+ // theora is one in, one out...
+ if (ogg_stream_packetout(&_theoraOut, &_oggPacket) > 0) {
+ if (_videoTrack->decodePacket(_oggPacket))
+ break;
+ } else if (_theoraOut.e_o_s || _fileStream->eos()) {
+ // If we can't get any more frames, we're done.
+ _videoTrack->setEndOfVideo();
+ } else {
+ // Queue more data
+ bufferData();
+ while (ogg_sync_pageout(&_oggSync, &_oggPage) > 0)
+ queuePage(&_oggPage);
+ }
+
+ // Update audio if we can
+ queueAudio();
+ }
+ }
+
+ // Then make sure we have enough audio buffered
+ ensureAudioBufferSize();
+}
+
+TheoraDecoder::TheoraVideoTrack::TheoraVideoTrack(const Graphics::PixelFormat &format, th_info &theoraInfo, th_setup_info *theoraSetup) {
+ _theoraDecode = th_decode_alloc(&theoraInfo, theoraSetup);
+
+ if (theoraInfo.pixel_fmt != TH_PF_420)
+ error("Only theora YUV420 is supported");
+
+ int postProcessingMax;
+ th_decode_ctl(_theoraDecode, TH_DECCTL_GET_PPLEVEL_MAX, &postProcessingMax, sizeof(postProcessingMax));
+ th_decode_ctl(_theoraDecode, TH_DECCTL_SET_PPLEVEL, &postProcessingMax, sizeof(postProcessingMax));
+
+ _surface.create(theoraInfo.frame_width, theoraInfo.frame_height, format);
+
+ // Set up a display surface
+ _displaySurface.pixels = _surface.getBasePtr(theoraInfo.pic_x, theoraInfo.pic_y);
+ _displaySurface.w = theoraInfo.pic_width;
+ _displaySurface.h = theoraInfo.pic_height;
+ _displaySurface.format = format;
+ _displaySurface.pitch = _surface.pitch;
+
+ // Set the frame rate
+ _frameRate = Common::Rational(theoraInfo.fps_numerator, theoraInfo.fps_denominator);
+
+ _endOfVideo = false;
+ _nextFrameStartTime = 0.0;
+ _curFrame = -1;
+}
+
+TheoraDecoder::TheoraVideoTrack::~TheoraVideoTrack() {
+ th_decode_free(_theoraDecode);
+
+ _surface.free();
+ _displaySurface.pixels = 0;
+}
+
+bool TheoraDecoder::TheoraVideoTrack::decodePacket(ogg_packet &oggPacket) {
+ if (th_decode_packetin(_theoraDecode, &oggPacket, 0) == 0) {
+ _curFrame++;
+
+ // Convert YUV data to RGB data
+ th_ycbcr_buffer yuv;
+ th_decode_ycbcr_out(_theoraDecode, yuv);
+ translateYUVtoRGBA(yuv);
+
+ double time = th_granule_time(_theoraDecode, oggPacket.granulepos);
+
+ // We need to calculate when the next frame should be shown
+ // This is all in floating point because that's what the Ogg code gives us
+ // Ogg is a lossy container format, so it doesn't always list the time to the
+ // next frame. In such cases, we need to calculate it ourselves.
+ if (time == -1.0)
+ _nextFrameStartTime += _frameRate.getInverse().toDouble();
+ else
+ _nextFrameStartTime = time;
+
+ return true;
+ }
+
+ return false;
+}
+
+enum TheoraYUVBuffers {
+ kBufferY = 0,
+ kBufferU = 1,
+ kBufferV = 2
+};
+
+void TheoraDecoder::TheoraVideoTrack::translateYUVtoRGBA(th_ycbcr_buffer &YUVBuffer) {
+ // Width and height of all buffers have to be divisible by 2.
+ assert((YUVBuffer[kBufferY].width & 1) == 0);
+ assert((YUVBuffer[kBufferY].height & 1) == 0);
+ assert((YUVBuffer[kBufferU].width & 1) == 0);
+ assert((YUVBuffer[kBufferV].width & 1) == 0);
+
+ // UV images have to have a quarter of the Y image resolution
+ assert(YUVBuffer[kBufferU].width == YUVBuffer[kBufferY].width >> 1);
+ assert(YUVBuffer[kBufferV].width == YUVBuffer[kBufferY].width >> 1);
+ assert(YUVBuffer[kBufferU].height == YUVBuffer[kBufferY].height >> 1);
+ assert(YUVBuffer[kBufferV].height == YUVBuffer[kBufferY].height >> 1);
+
+ Graphics::convertYUV420ToRGB(&_surface, YUVBuffer[kBufferY].data, YUVBuffer[kBufferU].data, YUVBuffer[kBufferV].data, YUVBuffer[kBufferY].width, YUVBuffer[kBufferY].height, YUVBuffer[kBufferY].stride, YUVBuffer[kBufferU].stride);
+}
+
+static vorbis_info *info = 0;
+
+TheoraDecoder::VorbisAudioTrack::VorbisAudioTrack(Audio::Mixer::SoundType soundType, vorbis_info &vorbisInfo) : _soundType(soundType) {
+ vorbis_synthesis_init(&_vorbisDSP, &vorbisInfo);
+ vorbis_block_init(&_vorbisDSP, &_vorbisBlock);
+ info = &vorbisInfo;
+
+ _audStream = Audio::makeQueuingAudioStream(vorbisInfo.rate, vorbisInfo.channels);
+
+ _audioBufferFill = 0;
+ _audioBuffer = 0;
+ _endOfAudio = false;
+}
+
+TheoraDecoder::VorbisAudioTrack::~VorbisAudioTrack() {
+ vorbis_dsp_clear(&_vorbisDSP);
+ vorbis_block_clear(&_vorbisBlock);
+ delete _audStream;
+ free(_audioBuffer);
+}
+
+Audio::AudioStream *TheoraDecoder::VorbisAudioTrack::getAudioStream() const {
+ return _audStream;
+}
+
+#define AUDIOFD_FRAGSIZE 10240
+
+static double rint(double v) {
+ return floor(v + 0.5);
+}
+
+bool TheoraDecoder::VorbisAudioTrack::decodeSamples() {
+ float **pcm;
+
+ // if there's pending, decoded audio, grab it
+ int ret = vorbis_synthesis_pcmout(&_vorbisDSP, &pcm);
+
+ if (ret > 0) {
+ if (!_audioBuffer) {
+ _audioBuffer = (ogg_int16_t *)malloc(AUDIOFD_FRAGSIZE * sizeof(ogg_int16_t));
+ assert(_audioBuffer);
+ }
+
+ int channels = _audStream->isStereo() ? 2 : 1;
+ int count = _audioBufferFill / 2;
+ int maxsamples = ((AUDIOFD_FRAGSIZE - _audioBufferFill) / channels) >> 1;
+ int i;
+
+ for (i = 0; i < ret && i < maxsamples; i++) {
+ for (int j = 0; j < channels; j++) {
+ int val = CLIP((int)rint(pcm[j][i] * 32767.f), -32768, 32767);
+ _audioBuffer[count++] = val;
+ }
+ }
+
+ vorbis_synthesis_read(&_vorbisDSP, i);
+ _audioBufferFill += (i * channels) << 1;
+
+ if (_audioBufferFill == AUDIOFD_FRAGSIZE) {
+ byte flags = Audio::FLAG_16BITS;
+
+ if (_audStream->isStereo())
+ flags |= Audio::FLAG_STEREO;
+
+#ifdef SCUMM_LITTLE_ENDIAN
+ flags |= Audio::FLAG_LITTLE_ENDIAN;
+#endif
+
+ _audStream->queueBuffer((byte *)_audioBuffer, AUDIOFD_FRAGSIZE, DisposeAfterUse::YES, flags);
+
+ // The audio mixer is now responsible for the old audio buffer.
+ // We need to create a new one.
+ _audioBuffer = 0;
+ _audioBufferFill = 0;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool TheoraDecoder::VorbisAudioTrack::hasAudio() const {
+ return _audStream->numQueuedStreams() > 0;
+}
+
+bool TheoraDecoder::VorbisAudioTrack::needsAudio() const {
+ // TODO: 5 is very arbitrary. We probably should do something like QuickTime does.
+ return !_endOfAudio && _audStream->numQueuedStreams() < 5;
+}
+
+void TheoraDecoder::VorbisAudioTrack::synthesizePacket(ogg_packet &oggPacket) {
+ if (vorbis_synthesis(&_vorbisBlock, &oggPacket) == 0) // test for success
+ vorbis_synthesis_blockin(&_vorbisDSP, &_vorbisBlock);
+}
+
+void TheoraDecoder::queuePage(ogg_page *page) {
+ if (_hasVideo)
+ ogg_stream_pagein(&_theoraOut, page);
+
+ if (_hasAudio)
+ ogg_stream_pagein(&_vorbisOut, page);
+}
+
+int TheoraDecoder::bufferData() {
+ char *buffer = ogg_sync_buffer(&_oggSync, 4096);
+ int bytes = _fileStream->read(buffer, 4096);
+
+ ogg_sync_wrote(&_oggSync, bytes);
+
+ return bytes;
+}
+
+bool TheoraDecoder::queueAudio() {
+ if (!_hasAudio)
+ return false;
+
+ bool queuedAudio = false;
+
+ for (;;) {
+ if (_audioTrack->decodeSamples()) {
+ // we queued some pending audio
+ queuedAudio = true;
+ } else if (ogg_stream_packetout(&_vorbisOut, &_oggPacket) > 0) {
+ // no pending audio; is there a pending packet to decode?
+ _audioTrack->synthesizePacket(_oggPacket);
+ } else {
+ // we've buffered all we have, break out for now
+ break;
+ }
+ }
+
+ return queuedAudio;
+}
+
+void TheoraDecoder::ensureAudioBufferSize() {
+ if (!_hasAudio)
+ return;
+
+ // Force at least some audio to be buffered
+ while (_audioTrack->needsAudio()) {
+ bufferData();
+ while (ogg_sync_pageout(&_oggSync, &_oggPage) > 0)
+ queuePage(&_oggPage);
+
+ bool queuedAudio = queueAudio();
+ if ((_vorbisOut.e_o_s || _fileStream->eos()) && !queuedAudio) {
+ _audioTrack->setEndOfAudio();
+ break;
+ }
+ }
+}
+
+} // End of namespace Video
diff --git a/video/theora_decoder.h b/video/theora_decoder.h
new file mode 100644
index 0000000000..7e36d829e7
--- /dev/null
+++ b/video/theora_decoder.h
@@ -0,0 +1,157 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "common/scummsys.h" // for USE_THEORADEC
+
+#ifdef USE_THEORADEC
+
+#ifndef VIDEO_THEORA_DECODER_H
+#define VIDEO_THEORA_DECODER_H
+
+#include "common/rational.h"
+#include "video/video_decoder.h"
+#include "audio/mixer.h"
+#include "graphics/surface.h"
+
+#include <theora/theoradec.h>
+#include <vorbis/codec.h>
+
+namespace Common {
+class SeekableReadStream;
+}
+
+namespace Audio {
+class AudioStream;
+class QueuingAudioStream;
+}
+
+namespace Video {
+
+/**
+ *
+ * Decoder for Theora videos.
+ * Video decoder used in engines:
+ * - sword25
+ */
+class TheoraDecoder : public VideoDecoder {
+public:
+ TheoraDecoder(Audio::Mixer::SoundType soundType = Audio::Mixer::kMusicSoundType);
+ virtual ~TheoraDecoder();
+
+ /**
+ * Load a video file
+ * @param stream the stream to load
+ */
+ bool loadStream(Common::SeekableReadStream *stream);
+ void close();
+
+protected:
+ void readNextPacket();
+
+private:
+ class TheoraVideoTrack : public VideoTrack {
+ public:
+ TheoraVideoTrack(const Graphics::PixelFormat &format, th_info &theoraInfo, th_setup_info *theoraSetup);
+ ~TheoraVideoTrack();
+
+ bool endOfTrack() const { return _endOfVideo; }
+ uint16 getWidth() const { return _displaySurface.w; }
+ uint16 getHeight() const { return _displaySurface.h; }
+ Graphics::PixelFormat getPixelFormat() const { return _displaySurface.format; }
+ int getCurFrame() const { return _curFrame; }
+ uint32 getNextFrameStartTime() const { return (uint32)(_nextFrameStartTime * 1000); }
+ const Graphics::Surface *decodeNextFrame() { return &_displaySurface; }
+
+ bool decodePacket(ogg_packet &oggPacket);
+ void setEndOfVideo() { _endOfVideo = true; }
+
+ private:
+ int _curFrame;
+ bool _endOfVideo;
+ Common::Rational _frameRate;
+ double _nextFrameStartTime;
+
+ Graphics::Surface _surface;
+ Graphics::Surface _displaySurface;
+
+ th_dec_ctx *_theoraDecode;
+
+ void translateYUVtoRGBA(th_ycbcr_buffer &YUVBuffer);
+ };
+
+ class VorbisAudioTrack : public AudioTrack {
+ public:
+ VorbisAudioTrack(Audio::Mixer::SoundType soundType, vorbis_info &vorbisInfo);
+ ~VorbisAudioTrack();
+
+ Audio::Mixer::SoundType getSoundType() const { return _soundType; }
+
+ bool decodeSamples();
+ bool hasAudio() const;
+ bool needsAudio() const;
+ void synthesizePacket(ogg_packet &oggPacket);
+ void setEndOfAudio() { _endOfAudio = true; }
+
+ protected:
+ Audio::AudioStream *getAudioStream() const;
+
+ private:
+ // single audio fragment audio buffering
+ int _audioBufferFill;
+ ogg_int16_t *_audioBuffer;
+
+ Audio::Mixer::SoundType _soundType;
+ Audio::QueuingAudioStream *_audStream;
+
+ vorbis_block _vorbisBlock;
+ vorbis_dsp_state _vorbisDSP;
+
+ bool _endOfAudio;
+ };
+
+ void queuePage(ogg_page *page);
+ int bufferData();
+ bool queueAudio();
+ void ensureAudioBufferSize();
+
+ Common::SeekableReadStream *_fileStream;
+
+ Audio::Mixer::SoundType _soundType;
+
+ ogg_sync_state _oggSync;
+ ogg_page _oggPage;
+ ogg_packet _oggPacket;
+
+ ogg_stream_state _theoraOut, _vorbisOut;
+ bool _hasVideo, _hasAudio;
+
+ vorbis_info _vorbisInfo;
+
+ TheoraVideoTrack *_videoTrack;
+ VorbisAudioTrack *_audioTrack;
+};
+
+} // End of namespace Video
+
+#endif
+
+#endif
diff --git a/video/video_decoder.cpp b/video/video_decoder.cpp
index e1122132a8..559880acee 100644
--- a/video/video_decoder.cpp
+++ b/video/video_decoder.cpp
@@ -22,6 +22,9 @@
#include "video/video_decoder.h"
+#include "audio/audiostream.h"
+#include "audio/mixer.h" // for kMaxChannelVolume
+
#include "common/rational.h"
#include "common/file.h"
#include "common/system.h"
@@ -31,7 +34,45 @@
namespace Video {
VideoDecoder::VideoDecoder() {
- reset();
+ _startTime = 0;
+ _needsRewind = false;
+ _dirtyPalette = false;
+ _palette = 0;
+ _isPlaying = false;
+ _audioVolume = Audio::Mixer::kMaxChannelVolume;
+ _audioBalance = 0;
+ _pauseLevel = 0;
+ _needsUpdate = false;
+ _lastTimeChange = 0;
+ _endTime = 0;
+ _endTimeSet = false;
+
+ // Find the best format for output
+ _defaultHighColorFormat = g_system->getScreenFormat();
+
+ if (_defaultHighColorFormat.bytesPerPixel == 1)
+ _defaultHighColorFormat = Graphics::PixelFormat(4, 8, 8, 8, 8, 8, 16, 24, 0);
+}
+
+void VideoDecoder::close() {
+ if (isPlaying())
+ stop();
+
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ delete *it;
+
+ _tracks.clear();
+ _needsRewind = false;
+ _dirtyPalette = false;
+ _palette = 0;
+ _startTime = 0;
+ _audioVolume = Audio::Mixer::kMaxChannelVolume;
+ _audioBalance = 0;
+ _pauseLevel = 0;
+ _needsUpdate = false;
+ _lastTimeChange = 0;
+ _endTime = 0;
+ _endTimeSet = false;
}
bool VideoDecoder::loadFile(const Common::String &filename) {
@@ -45,28 +86,10 @@ bool VideoDecoder::loadFile(const Common::String &filename) {
return loadStream(file);
}
-uint32 VideoDecoder::getElapsedTime() const {
- return g_system->getMillis() - _startTime;
-}
-
-void VideoDecoder::setSystemPalette() {
- g_system->getPaletteManager()->setPalette(getPalette(), 0, 256);
-}
-
bool VideoDecoder::needsUpdate() const {
return !endOfVideo() && getTimeToNextFrame() == 0;
}
-void VideoDecoder::reset() {
- _curFrame = -1;
- _startTime = 0;
- _pauseLevel = 0;
-}
-
-bool VideoDecoder::endOfVideo() const {
- return !isVideoLoaded() || (getCurFrame() >= (int32)getFrameCount() - 1);
-}
-
void VideoDecoder::pauseVideo(bool pause) {
if (pause) {
_pauseLevel++;
@@ -82,10 +105,14 @@ void VideoDecoder::pauseVideo(bool pause) {
if (_pauseLevel == 1 && pause) {
_pauseStartTime = g_system->getMillis(); // Store the starting time from pausing to keep it for later
- pauseVideoIntern(true);
+
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ (*it)->pause(true);
} else if (_pauseLevel == 0) {
- pauseVideoIntern(false);
- addPauseTime(g_system->getMillis() - _pauseStartTime);
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ (*it)->pause(false);
+
+ _startTime += (g_system->getMillis() - _pauseStartTime);
}
}
@@ -94,25 +121,562 @@ void VideoDecoder::resetPauseStartTime() {
_pauseStartTime = g_system->getMillis();
}
-uint32 FixedRateVideoDecoder::getTimeToNextFrame() const {
- if (endOfVideo() || _curFrame < 0)
+void VideoDecoder::setVolume(byte volume) {
+ _audioVolume = volume;
+
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeAudio)
+ ((AudioTrack *)*it)->setVolume(_audioVolume);
+}
+
+void VideoDecoder::setBalance(int8 balance) {
+ _audioBalance = balance;
+
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeAudio)
+ ((AudioTrack *)*it)->setBalance(_audioBalance);
+}
+
+bool VideoDecoder::isVideoLoaded() const {
+ return !_tracks.empty();
+}
+
+uint16 VideoDecoder::getWidth() const {
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo)
+ return ((VideoTrack *)*it)->getWidth();
+
+ return 0;
+}
+
+uint16 VideoDecoder::getHeight() const {
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo)
+ return ((VideoTrack *)*it)->getHeight();
+
+ return 0;
+}
+
+Graphics::PixelFormat VideoDecoder::getPixelFormat() const {
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo)
+ return ((VideoTrack *)*it)->getPixelFormat();
+
+ return Graphics::PixelFormat();
+}
+
+const Graphics::Surface *VideoDecoder::decodeNextFrame() {
+ _needsUpdate = false;
+
+ readNextPacket();
+ VideoTrack *track = findNextVideoTrack();
+
+ if (!track)
return 0;
- uint32 elapsedTime = getElapsedTime();
- uint32 nextFrameStartTime = getFrameBeginTime(_curFrame + 1);
+ const Graphics::Surface *frame = track->decodeNextFrame();
+
+ if (track->hasDirtyPalette()) {
+ _palette = track->getPalette();
+ _dirtyPalette = true;
+ }
+
+ return frame;
+}
+
+const byte *VideoDecoder::getPalette() {
+ _dirtyPalette = false;
+ return _palette;
+}
+
+int VideoDecoder::getCurFrame() const {
+ int32 frame = -1;
+
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo)
+ frame += ((VideoTrack *)*it)->getCurFrame() + 1;
+
+ return frame;
+}
+
+uint32 VideoDecoder::getFrameCount() const {
+ int count = 0;
+
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo)
+ count += ((VideoTrack *)*it)->getFrameCount();
+
+ return count;
+}
+
+uint32 VideoDecoder::getTime() const {
+ if (!isPlaying())
+ return _lastTimeChange.msecs();
+
+ if (isPaused())
+ return _pauseStartTime - _startTime;
+
+ if (useAudioSync()) {
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++) {
+ if ((*it)->getTrackType() == Track::kTrackTypeAudio && !(*it)->endOfTrack()) {
+ uint32 time = ((const AudioTrack *)*it)->getRunningTime();
+
+ if (time != 0)
+ return time + _lastTimeChange.msecs();
+ }
+ }
+ }
+
+ return g_system->getMillis() - _startTime;
+}
+
+uint32 VideoDecoder::getTimeToNextFrame() const {
+ if (endOfVideo() || _needsUpdate)
+ return 0;
+
+ const VideoTrack *track = findNextVideoTrack();
+
+ if (!track)
+ return 0;
+
+ uint32 elapsedTime = getTime();
+ uint32 nextFrameStartTime = track->getNextFrameStartTime();
- // If the time that the next frame should be shown has past
- // the frame should be shown ASAP.
if (nextFrameStartTime <= elapsedTime)
return 0;
return nextFrameStartTime - elapsedTime;
}
-uint32 FixedRateVideoDecoder::getFrameBeginTime(uint32 frame) const {
- Common::Rational beginTime = frame * 1000;
- beginTime /= getFrameRate();
- return beginTime.toInt();
+bool VideoDecoder::endOfVideo() const {
+ if (!isVideoLoaded())
+ return true;
+
+ if (_endTimeSet) {
+ const VideoTrack *track = findNextVideoTrack();
+
+ if (track && track->getNextFrameStartTime() >= (uint)_endTime.msecs())
+ return true;
+ }
+
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if (!(*it)->endOfTrack())
+ return false;
+
+ return true;
+}
+
+bool VideoDecoder::isRewindable() const {
+ if (!isVideoLoaded())
+ return false;
+
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if (!(*it)->isRewindable())
+ return false;
+
+ return true;
+}
+
+bool VideoDecoder::rewind() {
+ if (!isRewindable())
+ return false;
+
+ _needsRewind = false;
+
+ // Stop all tracks so they can be rewound
+ if (isPlaying())
+ stopAudio();
+
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if (!(*it)->rewind())
+ return false;
+
+ // Now that we've rewound, start all tracks again
+ if (isPlaying())
+ startAudio();
+
+ _lastTimeChange = 0;
+ _startTime = g_system->getMillis();
+ resetPauseStartTime();
+ return true;
+}
+
+bool VideoDecoder::isSeekable() const {
+ if (!isVideoLoaded())
+ return false;
+
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if (!(*it)->isSeekable())
+ return false;
+
+ return true;
+}
+
+bool VideoDecoder::seek(const Audio::Timestamp &time) {
+ if (!isSeekable())
+ return false;
+
+ _needsRewind = false;
+
+ // Stop all tracks so they can be seeked
+ if (isPlaying())
+ stopAudio();
+
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if (!(*it)->seek(time))
+ return false;
+
+ _lastTimeChange = time;
+
+ // Now that we've seeked, start all tracks again
+ // Also reset our start time
+ if (isPlaying()) {
+ startAudio();
+ _startTime = g_system->getMillis() - time.msecs();
+ }
+
+ resetPauseStartTime();
+ _needsUpdate = true;
+ return true;
+}
+
+void VideoDecoder::start() {
+ if (isPlaying() || !isVideoLoaded())
+ return;
+
+ _isPlaying = true;
+ _startTime = g_system->getMillis();
+
+ // If someone previously called stop(), we'll rewind it.
+ if (_needsRewind)
+ rewind();
+
+ // Adjust start time if we've seeked to something besides zero time
+ if (_lastTimeChange.totalNumberOfFrames() != 0)
+ _startTime -= _lastTimeChange.msecs();
+
+ startAudio();
+}
+
+void VideoDecoder::stop() {
+ if (!isPlaying())
+ return;
+
+ _isPlaying = false;
+ _startTime = 0;
+ _palette = 0;
+ _dirtyPalette = false;
+ _needsUpdate = false;
+
+ stopAudio();
+
+ // Also reset the pause state.
+ _pauseLevel = 0;
+
+ // If this is a rewindable video, don't close it too. We'll just rewind() the video
+ // the next time someone calls start(). Otherwise, since it can't be rewound, we
+ // just close it.
+ if (isRewindable()) {
+ _lastTimeChange = getTime();
+ _needsRewind = true;
+ } else {
+ close();
+ }
+}
+
+Audio::Timestamp VideoDecoder::getDuration() const {
+ Audio::Timestamp maxDuration(0, 1000);
+
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++) {
+ Audio::Timestamp duration = (*it)->getDuration();
+
+ if (duration > maxDuration)
+ maxDuration = duration;
+ }
+
+ return maxDuration;
+}
+
+VideoDecoder::Track::Track() {
+ _paused = false;
+}
+
+bool VideoDecoder::Track::isRewindable() const {
+ return isSeekable();
+}
+
+bool VideoDecoder::Track::rewind() {
+ return seek(Audio::Timestamp(0, 1000));
+}
+
+Audio::Timestamp VideoDecoder::Track::getDuration() const {
+ return Audio::Timestamp(0, 1000);
+}
+
+bool VideoDecoder::VideoTrack::endOfTrack() const {
+ return getCurFrame() >= (getFrameCount() - 1);
+}
+
+uint32 VideoDecoder::FixedRateVideoTrack::getNextFrameStartTime() const {
+ if (endOfTrack() || getCurFrame() < 0)
+ return 0;
+
+ Common::Rational time = (getCurFrame() + 1) * 1000;
+ time /= getFrameRate();
+ return time.toInt();
+}
+
+Audio::Timestamp VideoDecoder::FixedRateVideoTrack::getDuration() const {
+ // Since Audio::Timestamp doesn't support a fractional frame rate, we're currently
+ // just converting to milliseconds.
+ Common::Rational time = getFrameCount() * 1000;
+ time /= getFrameRate();
+ return time.toInt();
+}
+
+bool VideoDecoder::AudioTrack::endOfTrack() const {
+ Audio::AudioStream *stream = getAudioStream();
+ return !stream || !g_system->getMixer()->isSoundHandleActive(_handle) || stream->endOfData();
+}
+
+void VideoDecoder::AudioTrack::setVolume(byte volume) {
+ _volume = volume;
+
+ if (g_system->getMixer()->isSoundHandleActive(_handle))
+ g_system->getMixer()->setChannelVolume(_handle, _volume);
+}
+
+void VideoDecoder::AudioTrack::setBalance(int8 balance) {
+ _balance = balance;
+
+ if (g_system->getMixer()->isSoundHandleActive(_handle))
+ g_system->getMixer()->setChannelBalance(_handle, _balance);
+}
+
+void VideoDecoder::AudioTrack::start() {
+ stop();
+
+ Audio::AudioStream *stream = getAudioStream();
+ assert(stream);
+
+ g_system->getMixer()->playStream(getSoundType(), &_handle, stream, -1, getVolume(), getBalance(), DisposeAfterUse::NO);
+
+ // Pause the audio again if we're still paused
+ if (isPaused())
+ g_system->getMixer()->pauseHandle(_handle, true);
+}
+
+void VideoDecoder::AudioTrack::stop() {
+ g_system->getMixer()->stopHandle(_handle);
+}
+
+void VideoDecoder::AudioTrack::start(const Audio::Timestamp &limit) {
+ stop();
+
+ Audio::AudioStream *stream = getAudioStream();
+ assert(stream);
+
+ stream = Audio::makeLimitingAudioStream(stream, limit, DisposeAfterUse::NO);
+
+ g_system->getMixer()->playStream(getSoundType(), &_handle, stream, -1, getVolume(), getBalance(), DisposeAfterUse::YES);
+
+ // Pause the audio again if we're still paused
+ if (isPaused())
+ g_system->getMixer()->pauseHandle(_handle, true);
+}
+
+uint32 VideoDecoder::AudioTrack::getRunningTime() const {
+ if (g_system->getMixer()->isSoundHandleActive(_handle))
+ return g_system->getMixer()->getSoundElapsedTime(_handle);
+
+ return 0;
+}
+
+void VideoDecoder::AudioTrack::pauseIntern(bool shouldPause) {
+ if (g_system->getMixer()->isSoundHandleActive(_handle))
+ g_system->getMixer()->pauseHandle(_handle, shouldPause);
+}
+
+Audio::AudioStream *VideoDecoder::RewindableAudioTrack::getAudioStream() const {
+ return getRewindableAudioStream();
+}
+
+bool VideoDecoder::RewindableAudioTrack::rewind() {
+ Audio::RewindableAudioStream *stream = getRewindableAudioStream();
+ assert(stream);
+ return stream->rewind();
+}
+
+Audio::Timestamp VideoDecoder::SeekableAudioTrack::getDuration() const {
+ Audio::SeekableAudioStream *stream = getSeekableAudioStream();
+ assert(stream);
+ return stream->getLength();
+}
+
+Audio::AudioStream *VideoDecoder::SeekableAudioTrack::getAudioStream() const {
+ return getSeekableAudioStream();
+}
+
+bool VideoDecoder::SeekableAudioTrack::seek(const Audio::Timestamp &time) {
+ Audio::SeekableAudioStream *stream = getSeekableAudioStream();
+ assert(stream);
+ return stream->seek(time);
+}
+
+VideoDecoder::StreamFileAudioTrack::StreamFileAudioTrack() {
+ _stream = 0;
+}
+
+VideoDecoder::StreamFileAudioTrack::~StreamFileAudioTrack() {
+ delete _stream;
+}
+
+bool VideoDecoder::StreamFileAudioTrack::loadFromFile(const Common::String &baseName) {
+ // TODO: Make sure the stream isn't being played
+ delete _stream;
+ _stream = Audio::SeekableAudioStream::openStreamFile(baseName);
+ return _stream != 0;
+}
+
+void VideoDecoder::addTrack(Track *track) {
+ _tracks.push_back(track);
+
+ // Update volume settings if it's an audio track
+ if (track->getTrackType() == Track::kTrackTypeAudio) {
+ ((AudioTrack *)track)->setVolume(_audioVolume);
+ ((AudioTrack *)track)->setBalance(_audioBalance);
+ }
+
+ // Keep the track paused if we're paused
+ if (isPaused())
+ track->pause(true);
+
+ // Start the track if we're playing
+ if (isPlaying() && track->getTrackType() == Track::kTrackTypeAudio)
+ ((AudioTrack *)track)->start();
+}
+
+bool VideoDecoder::addStreamFileTrack(const Common::String &baseName) {
+ // Only allow adding external tracks if a video is already loaded
+ if (!isVideoLoaded())
+ return false;
+
+ StreamFileAudioTrack *track = new StreamFileAudioTrack();
+
+ bool result = track->loadFromFile(baseName);
+
+ if (result)
+ addTrack(track);
+
+ return result;
+}
+
+void VideoDecoder::setEndTime(const Audio::Timestamp &endTime) {
+ Audio::Timestamp startTime = 0;
+
+ if (isPlaying()) {
+ startTime = getTime();
+ stopAudio();
+ }
+
+ _endTime = endTime;
+ _endTimeSet = true;
+
+ if (startTime > endTime)
+ return;
+
+ if (isPlaying()) {
+ // We'll assume the audio track is going to start up at the same time it just was
+ // and therefore not do any seeking.
+ // Might want to set it anyway if we're seekable.
+ startAudioLimit(_endTime.msecs() - startTime.msecs());
+ _lastTimeChange = startTime;
+ }
+}
+
+VideoDecoder::Track *VideoDecoder::getTrack(uint track) {
+ if (track > _tracks.size())
+ return 0;
+
+ return _tracks[track];
+}
+
+const VideoDecoder::Track *VideoDecoder::getTrack(uint track) const {
+ if (track > _tracks.size())
+ return 0;
+
+ return _tracks[track];
+}
+
+bool VideoDecoder::endOfVideoTracks() const {
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo && !(*it)->endOfTrack())
+ return false;
+
+ return true;
+}
+
+VideoDecoder::VideoTrack *VideoDecoder::findNextVideoTrack() {
+ VideoTrack *bestTrack = 0;
+ uint32 bestTime = 0xFFFFFFFF;
+
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++) {
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo && !(*it)->endOfTrack()) {
+ VideoTrack *track = (VideoTrack *)*it;
+ uint32 time = track->getNextFrameStartTime();
+
+ if (time < bestTime) {
+ bestTime = time;
+ bestTrack = track;
+ }
+ }
+ }
+
+ return bestTrack;
+}
+
+const VideoDecoder::VideoTrack *VideoDecoder::findNextVideoTrack() const {
+ const VideoTrack *bestTrack = 0;
+ uint32 bestTime = 0xFFFFFFFF;
+
+ for (TrackList::const_iterator it = _tracks.begin(); it != _tracks.end(); it++) {
+ if ((*it)->getTrackType() == Track::kTrackTypeVideo && !(*it)->endOfTrack()) {
+ const VideoTrack *track = (const VideoTrack *)*it;
+ uint32 time = track->getNextFrameStartTime();
+
+ if (time < bestTime) {
+ bestTime = time;
+ bestTrack = track;
+ }
+ }
+ }
+
+ return bestTrack;
+}
+
+void VideoDecoder::startAudio() {
+ if (_endTimeSet) {
+ // HACK: Timestamp's subtraction asserts out when subtracting two times
+ // with different rates.
+ startAudioLimit(_endTime - _lastTimeChange.convertToFramerate(_endTime.framerate()));
+ return;
+ }
+
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeAudio)
+ ((AudioTrack *)*it)->start();
+}
+
+void VideoDecoder::stopAudio() {
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeAudio)
+ ((AudioTrack *)*it)->stop();
+}
+
+void VideoDecoder::startAudioLimit(const Audio::Timestamp &limit) {
+ for (TrackList::iterator it = _tracks.begin(); it != _tracks.end(); it++)
+ if ((*it)->getTrackType() == Track::kTrackTypeAudio)
+ ((AudioTrack *)*it)->start(limit);
}
} // End of namespace Video
diff --git a/video/video_decoder.h b/video/video_decoder.h
index 52ced4777c..5abe1d917c 100644
--- a/video/video_decoder.h
+++ b/video/video_decoder.h
@@ -23,10 +23,17 @@
#ifndef VIDEO_DECODER_H
#define VIDEO_DECODER_H
-#include "common/str.h"
-
+#include "audio/mixer.h"
#include "audio/timestamp.h" // TODO: Move this to common/ ?
+#include "common/array.h"
+#include "common/str.h"
+#include "graphics/pixelformat.h"
+namespace Audio {
+class AudioStream;
+class RewindableAudioStream;
+class SeekableAudioStream;
+}
namespace Common {
class Rational;
@@ -34,7 +41,6 @@ class SeekableReadStream;
}
namespace Graphics {
-struct PixelFormat;
struct Surface;
}
@@ -48,10 +54,14 @@ public:
VideoDecoder();
virtual ~VideoDecoder() {}
+ /////////////////////////////////////////
+ // Opening/Closing a Video
+ /////////////////////////////////////////
+
/**
* Load a video from a file with the given name.
*
- * A default implementation using loadStream is provided.
+ * A default implementation using Common::File and loadStream is provided.
*
* @param filename the filename to load
* @return whether loading the file succeeded
@@ -62,6 +72,10 @@ public:
* Load a video from a generic read stream. The ownership of the
* stream object transfers to this VideoDecoder instance, which is
* hence also responsible for eventually deleting it.
+ *
+ * Implementations of this function are required to call addTrack()
+ * for each track in the video upon success.
+ *
* @param stream the stream to load
* @return whether loading the stream succeeded
*/
@@ -69,206 +83,706 @@ public:
/**
* Close the active video stream and free any associated resources.
+ *
+ * All subclasses that need to close their own resources should still
+ * call the base class' close() function at the start of their function.
*/
- virtual void close() = 0;
+ virtual void close();
/**
* Returns if a video stream is currently loaded or not.
*/
- virtual bool isVideoLoaded() const = 0;
+ bool isVideoLoaded() const;
+ /////////////////////////////////////////
+ // Playback Control
+ /////////////////////////////////////////
/**
- * Returns the width of the video's frames.
- * @return the width of the video's frames
+ * Begin playback of the video.
+ *
+ * @note This has no effect is the video is already playing.
*/
- virtual uint16 getWidth() const = 0;
+ void start();
/**
- * Returns the height of the video's frames.
- * @return the height of the video's frames
+ * Stop playback of the video.
+ *
+ * @note This will close() the video if it is not rewindable.
+ * @note If the video is rewindable, the video will be rewound on the
+ * next start() call unless rewind() or seek() is called before then.
*/
- virtual uint16 getHeight() const = 0;
+ void stop();
/**
- * Get the pixel format of the currently loaded video.
+ * Returns if the video is currently playing or not.
+ *
+ * This is not equivalent to the inverse of endOfVideo(). A video keeps
+ * its playing status even after reaching the end of the video. This will
+ * return true after calling start() and will continue to return true
+ * until stop() (or close()) is called.
*/
- virtual Graphics::PixelFormat getPixelFormat() const = 0;
+ bool isPlaying() const { return _isPlaying; }
/**
- * Get the palette for the video in RGB format (if 8bpp or less).
+ * Returns if a video is rewindable or not. The default implementation
+ * polls each track for rewindability.
*/
- virtual const byte *getPalette() { return 0; }
+ virtual bool isRewindable() const;
/**
- * Returns if the palette is dirty or not.
+ * Rewind a video to its beginning.
+ *
+ * If the video is playing, it will continue to play. The default
+ * implementation will rewind each track.
+ *
+ * @return true on success, false otherwise
+ */
+ virtual bool rewind();
+
+ /**
+ * Returns if a video is seekable or not. The default implementation
+ * polls each track for seekability.
*/
- virtual bool hasDirtyPalette() const { return false; }
+ virtual bool isSeekable() const;
/**
- * Set the system palette to the palette returned by getPalette.
- * @see getPalette
+ * Seek to a given time in the video.
+ *
+ * If the video is playing, it will continue to play. The default
+ * implementation will seek each track and must still be called
+ * from any other implementation.
+ *
+ * @param time The time to seek to
+ * @return true on success, false otherwise
*/
- void setSystemPalette();
+ virtual bool seek(const Audio::Timestamp &time);
+
+ /**
+ * Pause or resume the video. This should stop/resume any audio playback
+ * and other stuff. The initial pause time is kept so that any timing
+ * variables can be updated appropriately.
+ *
+ * This is a convenience method which automatically keeps track on how
+ * often the video has been paused, ensuring that after pausing an video
+ * e.g. twice, it has to be unpaused twice before actuallying resuming.
+ *
+ * @param pause true to pause the video, false to resume it
+ */
+ void pauseVideo(bool pause);
+
+ /**
+ * Return whether the video is currently paused or not.
+ */
+ bool isPaused() const { return _pauseLevel != 0; }
+
+ /**
+ * Set the time for this video to end at. At this time in the video,
+ * all audio will stop and endOfVideo() will return true.
+ */
+ void setEndTime(const Audio::Timestamp &endTime);
+
+ /**
+ * Get the stop time of the video (if not set, zero)
+ */
+ Audio::Timestamp getEndTime() const { return _endTime; }
+
+
+ /////////////////////////////////////////
+ // Playback Status
+ /////////////////////////////////////////
+
+ /**
+ * Returns if the video has reached the end or not.
+ * @return true if the video has finished playing or if none is loaded, false otherwise
+ */
+ bool endOfVideo() const;
/**
* Returns the current frame number of the video.
* @return the last frame decoded by the video
*/
- virtual int32 getCurFrame() const { return _curFrame; }
+ int32 getCurFrame() const;
/**
* Returns the number of frames in the video.
* @return the number of frames in the video
*/
- virtual uint32 getFrameCount() const = 0;
+ uint32 getFrameCount() const;
/**
- * Returns the time (in ms) that the video has been running.
- * This is based on the "wall clock" time as determined by
- * OSystem::getMillis, and takes pausing the video into account.
+ * Returns the time position (in ms) of the current video.
+ * This can be based on the "wall clock" time as determined by
+ * OSystem::getMillis() or the current time of any audio track
+ * running in the video, and takes pausing the video into account.
*
- * As such, it can differ from what multiplying getCurFrame() by
+ * As such, it will differ from what multiplying getCurFrame() by
* some constant would yield, e.g. for a video with non-constant
* frame rate.
+ *
+ * Due to the nature of the timing, this value may not always be
+ * completely accurate (since our mixer does not have precise
+ * timing).
+ */
+ uint32 getTime() const;
+
+
+ /////////////////////////////////////////
+ // Video Info
+ /////////////////////////////////////////
+
+ /**
+ * Returns the width of the video's frames.
+ *
+ * By default, this finds the largest width between all of the loaded
+ * tracks. However, a subclass may override this if it does any kind
+ * of post-processing on it.
+ *
+ * @return the width of the video's frames
+ */
+ virtual uint16 getWidth() const;
+
+ /**
+ * Returns the height of the video's frames.
+ *
+ * By default, this finds the largest height between all of the loaded
+ * tracks. However, a subclass may override this if it does any kind
+ * of post-processing on it.
+ *
+ * @return the height of the video's frames
+ */
+ virtual uint16 getHeight() const;
+
+ /**
+ * Get the pixel format of the currently loaded video.
+ */
+ Graphics::PixelFormat getPixelFormat() const;
+
+ /**
+ * Get the duration of the video.
+ *
+ * If the duration is unknown, this will return 0. If this is not
+ * overriden, it will take the length of the longest track.
+ */
+ virtual Audio::Timestamp getDuration() const;
+
+
+ /////////////////////////////////////////
+ // Frame Decoding
+ /////////////////////////////////////////
+
+ /**
+ * Get the palette for the video in RGB format (if 8bpp or less).
+ *
+ * The palette's format is the same as PaletteManager's palette
+ * (interleaved RGB values).
+ */
+ const byte *getPalette();
+
+ /**
+ * Returns if the palette is dirty or not.
*/
- virtual uint32 getElapsedTime() const;
+ bool hasDirtyPalette() const { return _dirtyPalette; }
/**
* Return the time (in ms) until the next frame should be displayed.
*/
- virtual uint32 getTimeToNextFrame() const = 0;
+ uint32 getTimeToNextFrame() const;
/**
* Check whether a new frame should be decoded, i.e. because enough
* time has elapsed since the last frame was decoded.
* @return whether a new frame should be decoded or not
*/
- virtual bool needsUpdate() const;
+ bool needsUpdate() const;
/**
* Decode the next frame into a surface and return the latter.
+ *
+ * A subclass may override this, but must still call this function. As an
+ * example, a subclass may do this to apply some global video scale to
+ * individual track's frame.
+ *
+ * Note that this will call readNextPacket() internally first before calling
+ * the next video track's decodeNextFrame() function.
+ *
* @return a surface containing the decoded frame, or 0
* @note Ownership of the returned surface stays with the VideoDecoder,
* hence the caller must *not* free it.
* @note this may return 0, in which case the last frame should be kept on screen
*/
- virtual const Graphics::Surface *decodeNextFrame() = 0;
+ virtual const Graphics::Surface *decodeNextFrame();
/**
- * Returns if the video has finished playing or not.
- * @return true if the video has finished playing or if none is loaded, false otherwise
+ * Set the default high color format for videos that convert from YUV.
+ *
+ * By default, VideoDecoder will attempt to use the screen format
+ * if it's >8bpp and use a 32bpp format when not.
+ *
+ * This must be set before calling loadStream().
*/
- virtual bool endOfVideo() const;
+ void setDefaultHighColorFormat(const Graphics::PixelFormat &format) { _defaultHighColorFormat = format; }
+
+
+ /////////////////////////////////////////
+ // Audio Control
+ /////////////////////////////////////////
/**
- * Pause or resume the video. This should stop/resume any audio playback
- * and other stuff. The initial pause time is kept so that any timing
- * variables can be updated appropriately.
+ * Get the current volume at which the audio in the video is being played
+ * @return the current volume at which the audio in the video is being played
+ */
+ byte getVolume() const { return _audioVolume; }
+
+ /**
+ * Set the volume at which the audio in the video should be played.
+ * This setting remains until close() is called (which may be called
+ * from loadStream()). The default volume is the maximum.
*
- * This is a convenience method which automatically keeps track on how
- * often the video has been paused, ensuring that after pausing an video
- * e.g. twice, it has to be unpaused twice before actuallying resuming.
+ * @param volume The volume at which to play the audio in the video
+ */
+ void setVolume(byte volume);
+
+ /**
+ * Get the current balance at which the audio in the video is being played
+ * @return the current balance at which the audio in the video is being played
+ */
+ int8 getBalance() const { return _audioBalance; }
+
+ /**
+ * Set the balance at which the audio in the video should be played.
+ * This setting remains until close() is called (which may be called
+ * from loadStream()). The default balance is 0.
*
- * @param pause true to pause the video, false to resume it
+ * @param balance The balance at which to play the audio in the video
*/
- void pauseVideo(bool pause);
+ void setBalance(int8 balance);
/**
- * Return whether the video is currently paused or not.
+ * Add an audio track from a stream file.
+ *
+ * This calls SeekableAudioStream::openStreamFile() internally
*/
- bool isPaused() const { return _pauseLevel != 0; }
+ bool addStreamFileTrack(const Common::String &baseName);
+
+
+ // Future API
+ //void setRate(const Common::Rational &rate);
+ //Common::Rational getRate() const;
protected:
/**
- * Resets _curFrame and _startTime. Should be called from every close() function.
+ * An abstract representation of a track in a movie.
*/
- void reset();
+ class Track {
+ public:
+ Track();
+ virtual ~Track() {}
+
+ /**
+ * The types of tracks this class can be.
+ */
+ enum TrackType {
+ kTrackTypeNone,
+ kTrackTypeVideo,
+ kTrackTypeAudio
+ };
+
+ /**
+ * Get the type of track.
+ */
+ virtual TrackType getTrackType() const = 0;
+
+ /**
+ * Return if the track has finished.
+ */
+ virtual bool endOfTrack() const = 0;
+
+ /**
+ * Return if the track is rewindable.
+ *
+ * If a video is seekable, it does not need to implement this
+ * for it to also be rewindable.
+ */
+ virtual bool isRewindable() const;
+
+ /**
+ * Rewind the video to the beginning.
+ *
+ * If a video is seekable, it does not need to implement this
+ * for it to also be rewindable.
+ *
+ * @return true on success, false otherwise.
+ */
+ virtual bool rewind();
+
+ /**
+ * Return if the track is seekable.
+ */
+ virtual bool isSeekable() const { return false; }
+
+ /**
+ * Seek to the given time.
+ * @param time The time to seek to, from the beginning of the video.
+ * @return true on success, false otherwise.
+ */
+ virtual bool seek(const Audio::Timestamp &time) { return false; }
+
+ /**
+ * Set the pause status of the track.
+ */
+ void pause(bool shouldPause) {}
+
+ /**
+ * Return if the track is paused.
+ */
+ bool isPaused() const { return _paused; }
+
+ /**
+ * Get the duration of the track (starting from this track's start time).
+ *
+ * By default, this returns 0 for unknown.
+ */
+ virtual Audio::Timestamp getDuration() const;
+
+ protected:
+ /**
+ * Function called by pause() for subclasses to implement.
+ */
+ void pauseIntern(bool pause);
+
+ private:
+ bool _paused;
+ };
/**
- * Actual implementation of pause by subclasses. See pause()
- * for details.
+ * An abstract representation of a video track.
*/
- virtual void pauseVideoIntern(bool pause) {}
+ class VideoTrack : public Track {
+ public:
+ VideoTrack() {}
+ virtual ~VideoTrack() {}
+
+ TrackType getTrackType() const { return kTrackTypeVideo; }
+ virtual bool endOfTrack() const;
+
+ /**
+ * Get the width of this track
+ */
+ virtual uint16 getWidth() const = 0;
+
+ /**
+ * Get the height of this track
+ */
+ virtual uint16 getHeight() const = 0;
+
+ /**
+ * Get the pixel format of this track
+ */
+ virtual Graphics::PixelFormat getPixelFormat() const = 0;
+
+ /**
+ * Get the current frame of this track
+ *
+ * @see VideoDecoder::getCurFrame()
+ */
+ virtual int getCurFrame() const = 0;
+
+ /**
+ * Get the frame count of this track
+ *
+ * @note If the frame count is unknown, return 0 (which is also
+ * the default implementation of the function). However, one must
+ * also implement endOfTrack() in that case.
+ */
+ virtual int getFrameCount() const { return 0; }
+
+ /**
+ * Get the start time of the next frame in milliseconds since
+ * the start of the video
+ */
+ virtual uint32 getNextFrameStartTime() const = 0;
+
+ /**
+ * Decode the next frame
+ */
+ virtual const Graphics::Surface *decodeNextFrame() = 0;
+
+ /**
+ * Get the palette currently in use by this track
+ */
+ virtual const byte *getPalette() const { return 0; }
+
+ /**
+ * Does the palette currently in use by this track need to be updated?
+ */
+ virtual bool hasDirtyPalette() const { return false; }
+ };
/**
- * Add the time the video has been paused to maintain sync
+ * A VideoTrack that is played at a constant rate.
+ *
+ * If the frame count is unknown, you must override endOfTrack().
+ */
+ class FixedRateVideoTrack : public VideoTrack {
+ public:
+ FixedRateVideoTrack() {}
+ virtual ~FixedRateVideoTrack() {}
+
+ uint32 getNextFrameStartTime() const;
+ virtual Audio::Timestamp getDuration() const;
+
+ protected:
+ /**
+ * Get the rate at which this track is played.
+ */
+ virtual Common::Rational getFrameRate() const = 0;
+ };
+
+ /**
+ * An abstract representation of an audio track.
+ */
+ class AudioTrack : public Track {
+ public:
+ AudioTrack() {}
+ virtual ~AudioTrack() {}
+
+ TrackType getTrackType() const { return kTrackTypeAudio; }
+
+ virtual bool endOfTrack() const;
+
+ /**
+ * Start playing this track
+ */
+ void start();
+
+ /**
+ * Stop playing this track
+ */
+ void stop();
+
+ void start(const Audio::Timestamp &limit);
+
+ /**
+ * Get the volume for this track
+ */
+ byte getVolume() const { return _volume; }
+
+ /**
+ * Set the volume for this track
+ */
+ void setVolume(byte volume);
+
+ /**
+ * Get the balance for this track
+ */
+ int8 getBalance() const { return _balance; }
+
+ /**
+ * Set the balance for this track
+ */
+ void setBalance(int8 balance);
+
+ /**
+ * Get the time the AudioStream behind this track has been
+ * running
+ */
+ uint32 getRunningTime() const;
+
+ /**
+ * Get the sound type to be used when playing this audio track
+ */
+ virtual Audio::Mixer::SoundType getSoundType() const { return Audio::Mixer::kPlainSoundType; }
+
+ protected:
+ void pauseIntern(bool pause);
+
+ /**
+ * Get the AudioStream that is the representation of this AudioTrack
+ */
+ virtual Audio::AudioStream *getAudioStream() const = 0;
+
+ private:
+ Audio::SoundHandle _handle;
+ byte _volume;
+ int8 _balance;
+ };
+
+ /**
+ * An AudioTrack that implements isRewindable() and rewind() using
+ * RewindableAudioStream.
+ */
+ class RewindableAudioTrack : public AudioTrack {
+ public:
+ RewindableAudioTrack() {}
+ virtual ~RewindableAudioTrack() {}
+
+ bool isRewindable() const { return true; }
+ bool rewind();
+
+ protected:
+ Audio::AudioStream *getAudioStream() const;
+
+ /**
+ * Get the RewindableAudioStream pointer to be used by this class
+ * for rewind() and getAudioStream()
+ */
+ virtual Audio::RewindableAudioStream *getRewindableAudioStream() const = 0;
+ };
+
+ /**
+ * An AudioTrack that implements isSeekable() and seek() using
+ * SeekableAudioStream.
+ */
+ class SeekableAudioTrack : public AudioTrack {
+ public:
+ SeekableAudioTrack() {}
+ virtual ~SeekableAudioTrack() {}
+
+ bool isSeekable() const { return true; }
+ bool seek(const Audio::Timestamp &time);
+
+ Audio::Timestamp getDuration() const;
+
+ protected:
+ Audio::AudioStream *getAudioStream() const;
+
+ /**
+ * Get the SeekableAudioStream pointer to be used by this class
+ * for seek(), getDuration(), and getAudioStream()
+ */
+ virtual Audio::SeekableAudioStream *getSeekableAudioStream() const = 0;
+ };
+
+ /**
+ * A SeekableAudioTrack that constructs its SeekableAudioStream using
+ * SeekableAudioStream::openStreamFile()
*/
- virtual void addPauseTime(uint32 ms) { _startTime += ms; }
+ class StreamFileAudioTrack : public SeekableAudioTrack {
+ public:
+ StreamFileAudioTrack();
+ ~StreamFileAudioTrack();
+
+ /**
+ * Load the track from a file with the given base name.
+ *
+ * @return true on success, false otherwise
+ */
+ bool loadFromFile(const Common::String &baseName);
+
+ protected:
+ Audio::SeekableAudioStream *_stream;
+ Audio::SeekableAudioStream *getSeekableAudioStream() const { return _stream; }
+ };
/**
* Reset the pause start time (which should be called when seeking)
*/
void resetPauseStartTime();
- int32 _curFrame;
- int32 _startTime;
-
-private:
- uint32 _pauseLevel;
- uint32 _pauseStartTime;
-};
+ /**
+ * Decode enough data for the next frame and enough audio to last that long.
+ *
+ * This function is used by the decodeNextFrame() function. A subclass
+ * of a Track may decide to just have its decodeNextFrame() function read
+ * and decode the frame.
+ */
+ virtual void readNextPacket() {}
-/**
- * A VideoDecoder wrapper that implements getTimeToNextFrame() based on getFrameRate().
- */
-class FixedRateVideoDecoder : public virtual VideoDecoder {
-public:
- uint32 getTimeToNextFrame() const;
+ /**
+ * Define a track to be used by this class.
+ *
+ * The pointer is then owned by this base class.
+ */
+ void addTrack(Track *track);
-protected:
/**
- * Return the frame rate in frames per second.
- * This returns a Rational because videos can have rates that are not integers and
- * there are some videos with frame rates < 1.
+ * Whether or not getTime() will sync with a playing audio track.
+ *
+ * A subclass can override this to disable this feature.
*/
- virtual Common::Rational getFrameRate() const = 0;
+ virtual bool useAudioSync() const { return true; }
-private:
- uint32 getFrameBeginTime(uint32 frame) const;
-};
+ /**
+ * Get the given track based on its index.
+ *
+ * @return A valid track pointer on success, 0 otherwise
+ */
+ Track *getTrack(uint track);
-/**
- * A VideoDecoder that can be rewound back to the beginning.
- */
-class RewindableVideoDecoder : public virtual VideoDecoder {
-public:
/**
- * Rewind to the beginning of the video.
+ * Get the given track based on its index
+ *
+ * @return A valid track pointer on success, 0 otherwise
*/
- virtual void rewind() = 0;
-};
+ const Track *getTrack(uint track) const;
-/**
- * A VideoDecoder that can seek to a frame or point in time.
- */
-class SeekableVideoDecoder : public virtual RewindableVideoDecoder {
-public:
/**
- * Seek to the specified time.
+ * Find out if all video tracks have finished
*
- * This will round to the previous frame showing. If the time would happen to
- * land while a frame is showing, this function will seek to the beginning of that
- * frame. In other words, there is *no* subframe accuracy. This may change in a
- * later revision of the API.
+ * This is useful if one wants to figure out if they need to buffer all
+ * remaining audio in a file.
+ */
+ bool endOfVideoTracks() const;
+
+ /**
+ * Get the default high color format
+ */
+ Graphics::PixelFormat getDefaultHighColorFormat() const { return _defaultHighColorFormat; }
+
+ /**
+ * Find the video track with the lowest start time for the next frame
+ */
+ VideoTrack *findNextVideoTrack();
+
+ /**
+ * Find the video track with the lowest start time for the next frame
*/
- virtual void seekToTime(Audio::Timestamp time) = 0;
+ const VideoTrack *findNextVideoTrack() const;
/**
- * Seek to the specified time (in ms).
+ * Typedef helpers for accessing tracks
*/
- void seekToTime(uint32 msecs) { seekToTime(Audio::Timestamp(msecs, 1000)); }
+ typedef Common::Array<Track *> TrackList;
+ typedef TrackList::iterator TrackListIterator;
/**
- * Implementation of RewindableVideoDecoder::rewind().
+ * Get the begin iterator of the tracks
*/
- virtual void rewind() { seekToTime(0); }
+ TrackListIterator getTrackListBegin() { return _tracks.begin(); }
/**
- * Get the total duration of the video (in ms).
+ * Get the end iterator of the tracks
*/
- virtual uint32 getDuration() const = 0;
+ TrackListIterator getTrackListEnd() { return _tracks.end(); }
+
+private:
+ // Tracks owned by this VideoDecoder
+ TrackList _tracks;
+
+ // Current playback status
+ bool _isPlaying, _needsRewind, _needsUpdate;
+ Audio::Timestamp _lastTimeChange, _endTime;
+ bool _endTimeSet;
+
+ // Palette settings from individual tracks
+ mutable bool _dirtyPalette;
+ const byte *_palette;
+
+ // Default PixelFormat settings
+ Graphics::PixelFormat _defaultHighColorFormat;
+
+ // Internal helper functions
+ void stopAudio();
+ void startAudio();
+ void startAudioLimit(const Audio::Timestamp &limit);
+
+ int32 _startTime;
+ uint32 _pauseLevel;
+ uint32 _pauseStartTime;
+ byte _audioVolume;
+ int8 _audioBalance;
};
} // End of namespace Video