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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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;
}
|