File: BitWriter.cpp

package info (click to toggle)
firefox 148.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 4,719,656 kB
  • sloc: cpp: 7,618,171; javascript: 6,701,506; ansic: 3,781,787; python: 1,418,364; xml: 638,647; asm: 438,962; java: 186,285; sh: 62,885; makefile: 19,010; objc: 13,092; perl: 12,763; yacc: 4,583; cs: 3,846; pascal: 3,448; lex: 1,720; ruby: 1,003; php: 436; lisp: 258; awk: 247; sql: 66; sed: 54; csh: 10; exp: 6
file content (104 lines) | stat: -rw-r--r-- 3,294 bytes parent folder | download | duplicates (13)
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
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "BitWriter.h"

#include <stdint.h>

#include "MediaData.h"
#include "mozilla/MathAlgorithms.h"

namespace mozilla {

constexpr uint8_t golombLen[256] = {
    1,  3,  3,  5,  5,  5,  5,  7,  7,  7,  7,  7,  7,  7,  7,  9,  9,  9,  9,
    9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  11, 11, 11, 11, 11, 11, 11,
    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
    11, 11, 11, 11, 11, 11, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
    15, 15, 15, 15, 15, 15, 15, 15, 17,
};

BitWriter::BitWriter(MediaByteBuffer* aBuffer) : mBuffer(aBuffer) {}

BitWriter::~BitWriter() = default;

void BitWriter::WriteBits(uint64_t aValue, size_t aBits) {
  MOZ_ASSERT(aBits <= sizeof(uint64_t) * 8);

  while (aBits) {
    if (mBitIndex == 0) {
      mBuffer->AppendElement(0);
    }

    const uint8_t clearMask = ~(~0u << (8 - mBitIndex));
    uint8_t mask = 0;

    if (mBitIndex + aBits > 8) {
      // Not enough bits in the current byte to write all the bits
      // required, we'll process what we can and continue with the left over.
      const uint8_t leftOverBits = mBitIndex + aBits - 8;
      const uint64_t leftOver = aValue & (~uint64_t(0) >> (8 - mBitIndex));
      mask = aValue >> leftOverBits;

      mBitIndex = 8;
      aValue = leftOver;
      aBits = leftOverBits;
    } else {
      const uint8_t offset = 8 - mBitIndex - aBits;
      mask = aValue << offset;

      mBitIndex += aBits;
      aBits = 0;
    }

    mBuffer->ElementAt(mPosition) |= mask & clearMask;

    if (mBitIndex == 8) {
      mPosition++;
      mBitIndex = 0;
    }
  }
}

void BitWriter::WriteUE(uint32_t aValue) {
  MOZ_ASSERT(aValue <= (UINT32_MAX - 1));

  if (aValue < 256) {
    WriteBits(aValue + 1, golombLen[aValue]);
  } else {
    const uint32_t e = FloorLog2(aValue + 1);
    WriteBits(aValue + 1, e * 2 + 1);
  }
}

void BitWriter::WriteULEB128(uint64_t aValue) {
  // See https://en.wikipedia.org/wiki/LEB128#Encode_unsigned_integer
  do {
    uint8_t byte = aValue & 0x7F;
    aValue >>= 7;
    WriteBit(aValue != 0);
    WriteBits(byte, 7);
  } while (aValue != 0);
}

void BitWriter::CloseWithRbspTrailing() {
  WriteBit(true);
  WriteBits(0, (8 - mBitIndex) & 7);
}

void BitWriter::AdvanceBytes(uint32_t aByteOffset) {
  MOZ_DIAGNOSTIC_ASSERT(mBitIndex == 0);
  mPosition += aByteOffset;
}

}  // namespace mozilla