2018-12-03 03:38:47 +01:00
|
|
|
using System.IO;
|
|
|
|
|
|
|
|
namespace Ryujinx.Graphics.VDec
|
|
|
|
{
|
|
|
|
class BitStreamWriter
|
|
|
|
{
|
|
|
|
private const int BufferSize = 8;
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private Stream _baseStream;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
private int _buffer;
|
|
|
|
private int _bufferPos;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
public BitStreamWriter(Stream baseStream)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_baseStream = baseStream;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
public void WriteBit(bool value)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
WriteBits(value ? 1 : 0, 1);
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
public void WriteBits(int value, int valueSize)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
int valuePos = 0;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int remaining = valueSize;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
while (remaining > 0)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
int copySize = remaining;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int free = GetFreeBufferBits();
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
if (copySize > free)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
copySize = free;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int mask = (1 << copySize) - 1;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
int srcShift = (valueSize - valuePos) - copySize;
|
|
|
|
int dstShift = (BufferSize - _bufferPos) - copySize;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
_buffer |= ((value >> srcShift) & mask) << dstShift;
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
valuePos += copySize;
|
|
|
|
_bufferPos += copySize;
|
|
|
|
remaining -= copySize;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private int GetFreeBufferBits()
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
if (_bufferPos == BufferSize)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
|
|
|
Flush();
|
|
|
|
}
|
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
return BufferSize - _bufferPos;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void Flush()
|
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
if (_bufferPos != 0)
|
2018-12-03 03:38:47 +01:00
|
|
|
{
|
2019-03-04 02:45:25 +01:00
|
|
|
_baseStream.WriteByte((byte)_buffer);
|
2018-12-03 03:38:47 +01:00
|
|
|
|
2019-03-04 02:45:25 +01:00
|
|
|
_buffer = 0;
|
|
|
|
_bufferPos = 0;
|
2018-12-03 03:38:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|