/src/x265/source/common/bitstream.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | #include "common.h" |
2 | | #include "bitstream.h" |
3 | | #include "threading.h" |
4 | | |
5 | | using namespace X265_NS; |
6 | | |
7 | | #if defined(_MSC_VER) |
8 | | #pragma warning(disable: 4244) |
9 | | #endif |
10 | | |
11 | 6.17k | #define MIN_FIFO_SIZE 1000 |
12 | | |
13 | | Bitstream::Bitstream() |
14 | 6.17k | { |
15 | 6.17k | m_fifo = X265_MALLOC(uint8_t, MIN_FIFO_SIZE); |
16 | 6.17k | m_byteAlloc = MIN_FIFO_SIZE; |
17 | 6.17k | resetBits(); |
18 | 6.17k | } |
19 | | |
20 | | void Bitstream::push_back(uint8_t val) |
21 | 99.5k | { |
22 | 99.5k | if (!m_fifo) |
23 | 0 | return; |
24 | | |
25 | 99.5k | if (m_byteOccupancy >= m_byteAlloc) |
26 | 0 | { |
27 | | /** reallocate buffer with doubled size */ |
28 | 0 | uint8_t *temp = X265_MALLOC(uint8_t, m_byteAlloc * 2); |
29 | 0 | if (temp) |
30 | 0 | { |
31 | 0 | memcpy(temp, m_fifo, m_byteOccupancy); |
32 | 0 | X265_FREE(m_fifo); |
33 | 0 | m_fifo = temp; |
34 | 0 | m_byteAlloc *= 2; |
35 | 0 | } |
36 | 0 | else |
37 | 0 | { |
38 | 0 | x265_log(NULL, X265_LOG_ERROR, "Unable to realloc bitstream buffer"); |
39 | 0 | return; |
40 | 0 | } |
41 | 0 | } |
42 | 99.5k | m_fifo[m_byteOccupancy++] = val; |
43 | 99.5k | } |
44 | | |
45 | | void Bitstream::write(uint32_t val, uint32_t numBits) |
46 | 169k | { |
47 | 169k | X265_CHECK(numBits <= 32, "numBits out of range\n"); |
48 | 169k | X265_CHECK(numBits == 32 || ((val & (~0u << numBits)) == 0), "numBits & val out of range\n"); |
49 | | |
50 | 169k | uint32_t totalPartialBits = m_partialByteBits + numBits; |
51 | 169k | uint32_t nextPartialBits = totalPartialBits & 7; |
52 | 169k | uint8_t nextHeldByte = val << (8 - nextPartialBits); |
53 | 169k | uint32_t writeBytes = totalPartialBits >> 3; |
54 | | |
55 | 169k | if (writeBytes) |
56 | 34.9k | { |
57 | | /* topword aligns m_partialByte with the msb of val */ |
58 | 34.9k | uint32_t topword = (numBits - nextPartialBits) & ~7; |
59 | | #if USING_FTRAPV |
60 | | uint32_t write_bits = (topword < 32 ? m_partialByte << topword : 0) | (val >> nextPartialBits); |
61 | | #else |
62 | 34.9k | uint32_t write_bits = (m_partialByte << topword) | (val >> nextPartialBits); |
63 | 34.9k | #endif |
64 | | |
65 | 34.9k | switch (writeBytes) |
66 | 34.9k | { |
67 | 1.39k | case 4: push_back(write_bits >> 24); // fall-through |
68 | 1.39k | case 3: push_back(write_bits >> 16); // fall-through |
69 | 6.28k | case 2: push_back(write_bits >> 8); // fall-through |
70 | 34.9k | case 1: push_back(write_bits); |
71 | 34.9k | } |
72 | | |
73 | 34.9k | m_partialByte = nextHeldByte; |
74 | 34.9k | m_partialByteBits = nextPartialBits; |
75 | 34.9k | } |
76 | 134k | else |
77 | 134k | { |
78 | 134k | m_partialByte |= nextHeldByte; |
79 | 134k | m_partialByteBits = nextPartialBits; |
80 | 134k | } |
81 | 169k | } |
82 | | |
83 | | void Bitstream::writeByte(uint32_t val) |
84 | 50.5k | { |
85 | | // Only CABAC will call writeByte, the fifo must be byte aligned |
86 | 50.5k | X265_CHECK(!m_partialByteBits, "expecting m_partialByteBits = 0\n"); |
87 | | |
88 | 50.5k | push_back(val); |
89 | 50.5k | } |
90 | | |
91 | | void Bitstream::writeAlignOne() |
92 | 0 | { |
93 | 0 | uint32_t numBits = (8 - m_partialByteBits) & 0x7; |
94 | |
|
95 | 0 | write((1 << numBits) - 1, numBits); |
96 | 0 | } |
97 | | |
98 | | void Bitstream::writeAlignZero() |
99 | 5.72k | { |
100 | 5.72k | if (m_partialByteBits) |
101 | 4.93k | { |
102 | 4.93k | push_back(m_partialByte); |
103 | 4.93k | m_partialByte = 0; |
104 | 4.93k | m_partialByteBits = 0; |
105 | 4.93k | } |
106 | 5.72k | } |
107 | | |
108 | | void Bitstream::writeByteAlignment() |
109 | 5.72k | { |
110 | 5.72k | write(1, 1); |
111 | 5.72k | writeAlignZero(); |
112 | 5.72k | } |
113 | | |
114 | | void SyntaxElementWriter::writeUvlc(uint32_t code) |
115 | 26.2k | { |
116 | 26.2k | ++code; |
117 | | |
118 | 26.2k | X265_CHECK(code, "writing -1 code, will cause infinite loop\n"); |
119 | | |
120 | 26.2k | unsigned long idx; |
121 | 26.2k | CLZ(idx, code); |
122 | 26.2k | uint32_t length = (uint32_t)idx * 2 + 1; |
123 | | |
124 | | // Take care of cases where length > 32 |
125 | 26.2k | m_bitIf->write(0, length >> 1); |
126 | 26.2k | m_bitIf->write(code, (length + 1) >> 1); |
127 | 26.2k | } |