mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 05:38:56 +00:00
VIDEO: Migrate SVQ1 codec WIP to Common::BitStream.
This commit is contained in:
parent
e16270605a
commit
da35b9f5f6
@ -28,6 +28,7 @@
|
||||
#include "video/codecs/svq1_vlc.h"
|
||||
|
||||
#include "common/stream.h"
|
||||
#include "common/bitstream.h"
|
||||
#include "common/system.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/textconsole.h"
|
||||
@ -36,68 +37,6 @@
|
||||
|
||||
namespace Video {
|
||||
|
||||
// TODO: Common could do with a good Bitstream Reader Class
|
||||
// capable of wrapping ReadStream and byte *buffers
|
||||
// This would replace this, a similar class in SMK, QDM2
|
||||
// and probably a number of other similar pieces of code.
|
||||
class SVQ1BitStream {
|
||||
public:
|
||||
SVQ1BitStream(Common::SeekableReadStream *stream)
|
||||
: _stream(stream), _bitCount(0) {
|
||||
}
|
||||
|
||||
bool getBit();
|
||||
byte getBitsByte(uint n);
|
||||
uint32 getBitsUint32(uint n);
|
||||
|
||||
private:
|
||||
Common::SeekableReadStream *_stream;
|
||||
|
||||
byte _curByte;
|
||||
byte _bitCount;
|
||||
};
|
||||
|
||||
bool SVQ1BitStream::getBit() {
|
||||
if (_bitCount == 0) {
|
||||
assert(_stream->pos() < _stream->size());
|
||||
_curByte = _stream->readByte();
|
||||
_bitCount = 8;
|
||||
}
|
||||
|
||||
bool v = _curByte & 1;
|
||||
|
||||
_curByte >>= 1;
|
||||
--_bitCount;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
byte SVQ1BitStream::getBitsByte(uint n) {
|
||||
assert (n <= 8);
|
||||
byte v = 0;
|
||||
|
||||
for (uint i = 0; i < 8; i++) {
|
||||
v >>= 1;
|
||||
if (getBit() && i < n)
|
||||
v |= 0x80;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
uint32 SVQ1BitStream::getBitsUint32(uint n) {
|
||||
assert (n <= 32);
|
||||
uint32 v = 0;
|
||||
|
||||
for (uint i = 0; i < 32; i++) {
|
||||
v >>= 1;
|
||||
if (getBit() && i < n)
|
||||
v |= 0x8000;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
SVQ1Decoder::SVQ1Decoder(uint16 width, uint16 height) {
|
||||
_surface = new Graphics::Surface();
|
||||
_surface->create(width, height, g_system->getScreenFormat());
|
||||
@ -120,9 +59,9 @@ const Graphics::Surface *SVQ1Decoder::decodeImage(Common::SeekableReadStream *st
|
||||
stream->seek(startPos, SEEK_SET);
|
||||
#endif
|
||||
|
||||
SVQ1BitStream *frameData = new SVQ1BitStream(stream);
|
||||
Common::BitStream32LELSB frameData(*stream);
|
||||
|
||||
uint32 frameCode = frameData->getBitsUint32(22);
|
||||
uint32 frameCode = frameData.getBits(22);
|
||||
debug(1, " frameCode: %d", frameCode);
|
||||
|
||||
if ((frameCode & ~0x70) || !(frameCode & 0x60)) // Invalid
|
||||
@ -174,16 +113,16 @@ const Graphics::Surface *SVQ1Decoder::decodeImage(Common::SeekableReadStream *st
|
||||
};
|
||||
#endif
|
||||
|
||||
byte temporalReference = frameData->getBitsByte(8);
|
||||
byte temporalReference = frameData.getBits(8);
|
||||
debug(1, " temporalReference: %d", temporalReference);
|
||||
const char* types[4] = { "I Frame", "P Frame", "B Frame", "Invalid" };
|
||||
byte pictureType = frameData->getBitsByte(2);
|
||||
byte pictureType = frameData.getBits(2);
|
||||
debug(1, " pictureType: %d (%s)", pictureType, types[pictureType]);
|
||||
if (pictureType == 3) // Invalid
|
||||
return _surface;
|
||||
else if (pictureType == 0) { // I Frame
|
||||
if (frameCode == 0x50 || frameCode == 0x60) {
|
||||
uint32 checksum = frameData->getBitsUint32(16);
|
||||
uint32 checksum = frameData.getBits(16);
|
||||
debug(1, " checksum:0x%02x", checksum);
|
||||
// TODO: Validate checksum
|
||||
//uint16 calculate_packet_checksum (const uint8 *data, const int length) {
|
||||
@ -233,22 +172,22 @@ const Graphics::Surface *SVQ1Decoder::decodeImage(Common::SeekableReadStream *st
|
||||
if ((frameCode ^ 0x10) >= 0x50) {
|
||||
// Decode embedded string
|
||||
Common::String str;
|
||||
uint8 stringLen = frameData->getBitsByte(8);
|
||||
uint8 stringLen = frameData.getBits(8);
|
||||
byte xorVal = stringXORTable[stringLen];
|
||||
|
||||
for (uint16 i = 0; i < stringLen-1; i++) {
|
||||
byte data = frameData->getBitsByte(8);
|
||||
byte data = frameData.getBits(8);
|
||||
str += data ^ xorVal;
|
||||
xorVal = stringXORTable[data];
|
||||
}
|
||||
debug(1, " Embedded String of %d Characters: \"%s\"", stringLen, str.c_str());
|
||||
}
|
||||
|
||||
byte unk1 = frameData->getBitsByte(2); // Unknown
|
||||
byte unk1 = frameData.getBits(2); // Unknown
|
||||
debug(1, "unk1: %d", unk1);
|
||||
byte unk2 = frameData->getBitsByte(2); // Unknown
|
||||
byte unk2 = frameData.getBits(2); // Unknown
|
||||
debug(1, "unk2: %d", unk2);
|
||||
bool unk3 = frameData->getBit(); // Unknown
|
||||
bool unk3 = frameData.getBit(); // Unknown
|
||||
debug(1, "unk3: %d", unk3);
|
||||
|
||||
static const struct { uint w, h; } standardFrameSizes[7] = {
|
||||
@ -261,12 +200,12 @@ const Graphics::Surface *SVQ1Decoder::decodeImage(Common::SeekableReadStream *st
|
||||
{ 320, 240 } // 6
|
||||
};
|
||||
|
||||
byte frameSizeCode = frameData->getBitsByte(3);
|
||||
byte frameSizeCode = frameData.getBits(3);
|
||||
debug(1, " frameSizeCode: %d", frameSizeCode);
|
||||
uint16 frameWidth, frameHeight;
|
||||
if (frameSizeCode == 7) {
|
||||
frameWidth = frameData->getBitsUint32(12);
|
||||
frameHeight = frameData->getBitsUint32(12);
|
||||
frameWidth = frameData.getBits(12);
|
||||
frameHeight = frameData.getBits(12);
|
||||
} else {
|
||||
frameWidth = standardFrameSizes[frameSizeCode].w;
|
||||
frameHeight = standardFrameSizes[frameSizeCode].h;
|
||||
@ -276,32 +215,32 @@ const Graphics::Surface *SVQ1Decoder::decodeImage(Common::SeekableReadStream *st
|
||||
if (frameWidth == 0 || frameHeight == 0) // Invalid
|
||||
return _surface;
|
||||
|
||||
bool checksumPresent = frameData->getBit();
|
||||
bool checksumPresent = frameData.getBit();
|
||||
debug(1, " checksumPresent: %d", checksumPresent);
|
||||
if (checksumPresent) {
|
||||
bool usePacketChecksum = frameData->getBit();
|
||||
bool usePacketChecksum = frameData.getBit();
|
||||
debug(1, " usePacketChecksum: %d", usePacketChecksum);
|
||||
bool componentChecksumsAfterImageData = frameData->getBit();
|
||||
bool componentChecksumsAfterImageData = frameData.getBit();
|
||||
debug(1, " componentChecksumsAfterImageData: %d", componentChecksumsAfterImageData);
|
||||
byte unk4 = frameData->getBitsByte(2);
|
||||
byte unk4 = frameData.getBits(2);
|
||||
debug(1, " unk4: %d", unk4);
|
||||
if (unk4 != 0)
|
||||
warning("Invalid Frame Header in SVQ1 Frame Decode");
|
||||
}
|
||||
|
||||
bool unk5 = frameData->getBit();
|
||||
bool unk5 = frameData.getBit();
|
||||
debug(1, " unk5: %d", unk5);
|
||||
if (unk5) {
|
||||
bool unk6 = frameData->getBit();
|
||||
bool unk6 = frameData.getBit();
|
||||
debug(1, " unk6: %d", unk6);
|
||||
byte unk7 = frameData->getBitsByte(4);
|
||||
byte unk7 = frameData.getBits(4);
|
||||
debug(1, " unk7: %d", unk7);
|
||||
bool unk8 = frameData->getBit();
|
||||
bool unk8 = frameData.getBit();
|
||||
debug(1, " unk8: %d", unk8);
|
||||
byte unk9 = frameData->getBitsByte(2);
|
||||
byte unk9 = frameData.getBits(2);
|
||||
debug(1, " unk9: %d", unk9);
|
||||
while (frameData->getBit()) {
|
||||
byte unk10 = frameData->getBitsByte(8);
|
||||
while (frameData.getBit()) {
|
||||
byte unk10 = frameData.getBits(8);
|
||||
debug(1, " unk10: %d", unk10);
|
||||
}
|
||||
}
|
||||
@ -319,8 +258,6 @@ const Graphics::Surface *SVQ1Decoder::decodeImage(Common::SeekableReadStream *st
|
||||
vPlane[i] = 0;
|
||||
}
|
||||
|
||||
delete frameData;
|
||||
|
||||
convertYUV410ToRGB(_surface, yPlane, uPlane, vPlane, frameWidth, frameHeight, frameWidth, frameWidth/2);
|
||||
|
||||
delete[] yPlane;
|
||||
|
Loading…
Reference in New Issue
Block a user