diff options
Diffstat (limited to '')
-rw-r--r-- | xbmc/utils/BitstreamWriter.cpp | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/xbmc/utils/BitstreamWriter.cpp b/xbmc/utils/BitstreamWriter.cpp new file mode 100644 index 0000000..43c0788 --- /dev/null +++ b/xbmc/utils/BitstreamWriter.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2017-2018 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "BitstreamWriter.h" + +CBitstreamWriter::CBitstreamWriter(uint8_t *buffer, unsigned int buffer_size, int writer_le) + : writer_le(writer_le) + , bit_buf(0) + , bit_left(32) + , buf(buffer) + , buf_ptr(buf) +{ +} + +void CBitstreamWriter::WriteBits(int n, unsigned int value) +{ + // Write up to 32 bits into a bitstream. + unsigned int bit_buf; + int bit_left; + + if (n == 32) + { + // Write exactly 32 bits into a bitstream. + // danger, recursion in play. + int lo = value & 0xffff; + int hi = value >> 16; + if (writer_le) + { + WriteBits(16, lo); + WriteBits(16, hi); + } + else + { + WriteBits(16, hi); + WriteBits(16, lo); + } + return; + } + + bit_buf = this->bit_buf; + bit_left = this->bit_left; + + if (writer_le) + { + bit_buf |= value << (32 - bit_left); + if (n >= bit_left) { + BS_WL32(buf_ptr, bit_buf); + buf_ptr += 4; + bit_buf = (bit_left == 32) ? 0 : value >> bit_left; + bit_left += 32; + } + bit_left -= n; + } + else + { + if (n < bit_left) { + bit_buf = (bit_buf << n) | value; + bit_left -= n; + } + else { + bit_buf <<= bit_left; + bit_buf |= value >> (n - bit_left); + BS_WB32(buf_ptr, bit_buf); + buf_ptr += 4; + bit_left += 32 - n; + bit_buf = value; + } + } + + this->bit_buf = bit_buf; + this->bit_left = bit_left; +} + +void CBitstreamWriter::SkipBits(int n) +{ + // Skip the given number of bits. + // Must only be used if the actual values in the bitstream do not matter. + // If n is 0 the behavior is undefined. + bit_left -= n; + buf_ptr -= 4 * (bit_left >> 5); + bit_left &= 31; +} + +void CBitstreamWriter::FlushBits() +{ + if (!writer_le) + { + if (bit_left < 32) + bit_buf <<= bit_left; + } + while (bit_left < 32) + { + + if (writer_le) + { + *buf_ptr++ = bit_buf; + bit_buf >>= 8; + } + else + { + *buf_ptr++ = bit_buf >> 24; + bit_buf <<= 8; + } + bit_left += 8; + } + bit_left = 32; + bit_buf = 0; +} |