aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/VDec/BitStreamWriter.cs
blob: 44d07906afa9ce5fc48e3be1e026df817c3595e6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using System.IO;

namespace Ryujinx.Graphics.VDec
{
    class BitStreamWriter
    {
        private const int BufferSize = 8;

        private Stream BaseStream;

        private int Buffer;
        private int BufferPos;

        public BitStreamWriter(Stream BaseStream)
        {
            this.BaseStream = BaseStream;
        }

        public void WriteBit(bool Value)
        {
            WriteBits(Value ? 1 : 0, 1);
        }

        public void WriteBits(int Value, int ValueSize)
        {
            int ValuePos = 0;

            int Remaining = ValueSize;

            while (Remaining > 0)
            {
                int CopySize = Remaining;

                int Free = GetFreeBufferBits();

                if (CopySize > Free)
                {
                    CopySize = Free;
                }

                int Mask = (1 << CopySize) - 1;

                int SrcShift = (ValueSize  - ValuePos)  - CopySize;
                int DstShift = (BufferSize - BufferPos) - CopySize;

                Buffer |= ((Value >> SrcShift) & Mask) << DstShift;

                ValuePos  += CopySize;
                BufferPos += CopySize;
                Remaining -= CopySize;
            }
        }

        private int GetFreeBufferBits()
        {
            if (BufferPos == BufferSize)
            {
                Flush();
            }

            return BufferSize - BufferPos;
        }

        public void Flush()
        {
            if (BufferPos != 0)
            {
                BaseStream.WriteByte((byte)Buffer);

                Buffer    = 0;
                BufferPos = 0;
            }
        }
    }
}