From 0f57aea2df2a1272b57de896e2f6aad80809e5d3 Mon Sep 17 00:00:00 2001 From: Bastien Bouclet Date: Mon, 8 Apr 2019 19:24:00 +0200 Subject: COMMON: Use a prefix table to speed up the Huffman decoder Symbols for codes shorter than the prefix table index width are stored in the table. All the entries in the table with an index starting with the code are set to the symbol value. That way, when decoding it is possible to get the number of bits corresponding to the table width from the bitstream and directly find the symbol value. Longer code still need to be searched for in the codes list. --- video/bink_decoder.cpp | 2 +- video/bink_decoder.h | 3 ++- video/psx_decoder.cpp | 8 ++++---- video/psx_decoder.h | 7 +++++-- 4 files changed, 12 insertions(+), 8 deletions(-) (limited to 'video') diff --git a/video/bink_decoder.cpp b/video/bink_decoder.cpp index 406c6e4d34..4074043768 100644 --- a/video/bink_decoder.cpp +++ b/video/bink_decoder.cpp @@ -594,7 +594,7 @@ void BinkDecoder::BinkVideoTrack::deinitBundles() { void BinkDecoder::BinkVideoTrack::initHuffman() { for (int i = 0; i < 16; i++) - _huffman[i] = new Common::Huffman(binkHuffmanLengths[i][15], 16, binkHuffmanCodes[i], binkHuffmanLengths[i]); + _huffman[i] = new Common::Huffman(binkHuffmanLengths[i][15], 16, binkHuffmanCodes[i], binkHuffmanLengths[i]); } byte BinkDecoder::BinkVideoTrack::getHuffmanSymbol(VideoFrame &video, Huffman &huffman) { diff --git a/video/bink_decoder.h b/video/bink_decoder.h index 29d16020b1..11694314b7 100644 --- a/video/bink_decoder.h +++ b/video/bink_decoder.h @@ -46,6 +46,7 @@ class QueuingAudioStream; namespace Common { class SeekableReadStream; +template class Huffman; class RDFT; @@ -247,7 +248,7 @@ private: Bundle _bundles[kSourceMAX]; ///< Bundles for decoding all data types. - Common::Huffman *_huffman[16]; ///< The 16 Huffman codebooks used in Bink decoding. + 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]; diff --git a/video/psx_decoder.cpp b/video/psx_decoder.cpp index 562da885b1..ef42a72873 100644 --- a/video/psx_decoder.cpp +++ b/video/psx_decoder.cpp @@ -438,9 +438,9 @@ PSXStreamDecoder::PSXVideoTrack::PSXVideoTrack(Common::SeekableReadStream *first _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); + _acHuffman = new HuffmanDecoder(0, AC_CODE_COUNT, s_huffmanACCodes, s_huffmanACLengths, s_huffmanACSymbols); + _dcHuffmanChroma = new HuffmanDecoder(0, DC_CODE_COUNT, s_huffmanDCChromaCodes, s_huffmanDCChromaLengths, s_huffmanDCSymbols); + _dcHuffmanLuma = new HuffmanDecoder(0, DC_CODE_COUNT, s_huffmanDCLumaCodes, s_huffmanDCLumaLengths, s_huffmanDCSymbols); } PSXStreamDecoder::PSXVideoTrack::~PSXVideoTrack() { @@ -552,7 +552,7 @@ int PSXStreamDecoder::PSXVideoTrack::readDC(Common::BitStreamMemory16LEMSB *bits // Version 3 has it stored as huffman codes as a difference from the previous DC value - Common::Huffman *huffman = (plane == kPlaneY) ? _dcHuffmanLuma : _dcHuffmanChroma; + HuffmanDecoder *huffman = (plane == kPlaneY) ? _dcHuffmanLuma : _dcHuffmanChroma; uint32 symbol = huffman->getSymbol(*bits); int dc = 0; diff --git a/video/psx_decoder.h b/video/psx_decoder.h index c96642276a..183b6da317 100644 --- a/video/psx_decoder.h +++ b/video/psx_decoder.h @@ -36,6 +36,7 @@ class QueuingAudioStream; } namespace Common { +template class Huffman; } @@ -105,16 +106,18 @@ private: kPlaneV = 2 }; + typedef Common::Huffman HuffmanDecoder; + uint16 _macroBlocksW, _macroBlocksH; byte *_yBuffer, *_cbBuffer, *_crBuffer; void decodeMacroBlock(Common::BitStreamMemory16LEMSB *bits, int mbX, int mbY, uint16 scale, uint16 version); void decodeBlock(Common::BitStreamMemory16LEMSB *bits, byte *block, int pitch, uint16 scale, uint16 version, PlaneType plane); void readAC(Common::BitStreamMemory16LEMSB *bits, int *block); - Common::Huffman *_acHuffman; + HuffmanDecoder *_acHuffman; int readDC(Common::BitStreamMemory16LEMSB *bits, uint16 version, PlaneType plane); - Common::Huffman *_dcHuffmanLuma, *_dcHuffmanChroma; + HuffmanDecoder *_dcHuffmanLuma, *_dcHuffmanChroma; int _lastDC[3]; void dequantizeBlock(int *coefficients, float *block, uint16 scale); -- cgit v1.2.3