/src/mozilla-central/dom/media/BitWriter.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
2 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | | |
5 | | #include "BitWriter.h" |
6 | | #include "MediaData.h" |
7 | | #include "mozilla/MathAlgorithms.h" |
8 | | |
9 | | namespace mozilla |
10 | | { |
11 | | |
12 | | constexpr uint8_t golombLen[256] = { |
13 | | 1, 3, 3, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 9, 9, 9, 9, |
14 | | 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11, 11, 11, |
15 | | 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, |
16 | | 11, 11, 11, 11, 11, 11, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, |
17 | | 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, |
18 | | 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, |
19 | | 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 15, 15, 15, 15, |
20 | | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, |
21 | | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, |
22 | | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, |
23 | | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, |
24 | | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, |
25 | | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, |
26 | | 15, 15, 15, 15, 15, 15, 15, 15, 17, |
27 | | }; |
28 | | |
29 | | BitWriter::BitWriter(MediaByteBuffer* aBuffer) |
30 | | : mBuffer(aBuffer) |
31 | 0 | { |
32 | 0 | } |
33 | | |
34 | 0 | BitWriter::~BitWriter() {} |
35 | | |
36 | | void |
37 | | BitWriter::WriteBits(uint64_t aValue, size_t aBits) |
38 | 0 | { |
39 | 0 | MOZ_ASSERT(aBits <= sizeof(uint64_t) * 8); |
40 | 0 |
|
41 | 0 | while (aBits) { |
42 | 0 | if (mBitIndex == 0) { |
43 | 0 | mBuffer->AppendElement(0); |
44 | 0 | } |
45 | 0 |
|
46 | 0 | const uint8_t clearMask = ~(~0 << (8 - mBitIndex)); |
47 | 0 | uint8_t mask = 0; |
48 | 0 |
|
49 | 0 | if (mBitIndex + aBits > 8) { |
50 | 0 | // Not enough bits in the current byte to write all the bits |
51 | 0 | // required, we'll process what we can and continue with the left over. |
52 | 0 | const uint8_t leftOverBits = mBitIndex + aBits - 8; |
53 | 0 | const uint64_t leftOver = aValue & (~uint64_t(0) >> (8 - mBitIndex)); |
54 | 0 | mask = aValue >> leftOverBits; |
55 | 0 |
|
56 | 0 | mBitIndex = 8; |
57 | 0 | aValue = leftOver; |
58 | 0 | aBits = leftOverBits; |
59 | 0 | } else { |
60 | 0 | const uint8_t offset = 8 - mBitIndex - aBits; |
61 | 0 | mask = aValue << offset; |
62 | 0 |
|
63 | 0 | mBitIndex += aBits; |
64 | 0 | aBits = 0; |
65 | 0 | } |
66 | 0 |
|
67 | 0 | mBuffer->ElementAt(mPosition) |= mask & clearMask; |
68 | 0 |
|
69 | 0 | if (mBitIndex == 8) { |
70 | 0 | mPosition++; |
71 | 0 | mBitIndex = 0; |
72 | 0 | } |
73 | 0 | } |
74 | 0 | } |
75 | | |
76 | | void |
77 | | BitWriter::WriteUE(uint32_t aValue) |
78 | 0 | { |
79 | 0 | MOZ_ASSERT(aValue <= (UINT32_MAX - 1)); |
80 | 0 |
|
81 | 0 | if (aValue < 256) { |
82 | 0 | WriteBits(aValue + 1, golombLen[aValue]); |
83 | 0 | } else { |
84 | 0 | const uint32_t e = FloorLog2(aValue + 1); |
85 | 0 | WriteBits(aValue + 1, e * 2 + 1); |
86 | 0 | } |
87 | 0 | } |
88 | | |
89 | | void |
90 | | BitWriter::CloseWithRbspTrailing() |
91 | 0 | { |
92 | 0 | WriteBit(true); |
93 | 0 | WriteBits(0, (8 - mBitIndex) & 7); |
94 | 0 | } |
95 | | |
96 | | } // namespace mozilla |