blob: 6f2a7ffabecf1cbe628f8d21d6e386a4bbfa7f67 (
plain)
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
|
/*
* 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 "BitstreamReader.h"
CBitstreamReader::CBitstreamReader(const uint8_t *buf, int len)
: buffer(buf)
, start(buf)
, offbits(0)
, length(len)
, oflow(0)
{
}
uint32_t CBitstreamReader::ReadBits(int nbits)
{
uint32_t ret = GetBits(nbits);
offbits += nbits;
buffer += offbits / 8;
offbits %= 8;
return ret;
}
void CBitstreamReader::SkipBits(int nbits)
{
offbits += nbits;
buffer += offbits / 8;
offbits %= 8;
if (buffer > (start + length))
oflow = 1;
}
uint32_t CBitstreamReader::GetBits(int nbits)
{
int i, nbytes;
uint32_t ret = 0;
const uint8_t *buf;
buf = buffer;
nbytes = (offbits + nbits) / 8;
if (((offbits + nbits) % 8) > 0)
nbytes++;
if ((buf + nbytes) > (start + length))
{
oflow = 1;
return 0;
}
for (i = 0; i<nbytes; i++)
ret += buf[i] << ((nbytes - i - 1) * 8);
i = (4 - nbytes) * 8 + offbits;
ret = ((ret << i) >> i) >> ((nbytes * 8) - nbits - offbits);
return ret;
}
const uint8_t* find_start_code(const uint8_t *p, const uint8_t *end, uint32_t *state)
{
if (p >= end)
return end;
for (int i = 0; i < 3; i++)
{
uint32_t tmp = *state << 8;
*state = tmp + *(p++);
if (tmp == 0x100 || p == end)
return p;
}
while (p < end)
{
if (p[-1] > 1) p += 3;
else if (p[-2]) p += 2;
else if (p[-3] | (p[-1] - 1)) p++;
else {
p++;
break;
}
}
p = (p < end)? p - 4 : end - 4;
*state = BS_RB32(p);
return p + 4;
}
|