1 |
|
|
/* |
2 |
|
|
* Range coder |
3 |
|
|
* Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at> |
4 |
|
|
* |
5 |
|
|
* This file is part of FFmpeg. |
6 |
|
|
* |
7 |
|
|
* FFmpeg is free software; you can redistribute it and/or |
8 |
|
|
* modify it under the terms of the GNU Lesser General Public |
9 |
|
|
* License as published by the Free Software Foundation; either |
10 |
|
|
* version 2.1 of the License, or (at your option) any later version. |
11 |
|
|
* |
12 |
|
|
* FFmpeg is distributed in the hope that it will be useful, |
13 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 |
|
|
* Lesser General Public License for more details. |
16 |
|
|
* |
17 |
|
|
* You should have received a copy of the GNU Lesser General Public |
18 |
|
|
* License along with FFmpeg; if not, write to the Free Software |
19 |
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
20 |
|
|
*/ |
21 |
|
|
|
22 |
|
|
/** |
23 |
|
|
* @file |
24 |
|
|
* Range coder. |
25 |
|
|
*/ |
26 |
|
|
|
27 |
|
|
#ifndef AVCODEC_RANGECODER_H |
28 |
|
|
#define AVCODEC_RANGECODER_H |
29 |
|
|
|
30 |
|
|
#include <stdint.h> |
31 |
|
|
|
32 |
|
|
#include "libavutil/common.h" |
33 |
|
|
#include "libavutil/avassert.h" |
34 |
|
|
|
35 |
|
|
typedef struct RangeCoder { |
36 |
|
|
int low; |
37 |
|
|
int range; |
38 |
|
|
int outstanding_count; |
39 |
|
|
int outstanding_byte; |
40 |
|
|
uint8_t zero_state[256]; |
41 |
|
|
uint8_t one_state[256]; |
42 |
|
|
uint8_t *bytestream_start; |
43 |
|
|
uint8_t *bytestream; |
44 |
|
|
uint8_t *bytestream_end; |
45 |
|
|
int overread; |
46 |
|
|
#define MAX_OVERREAD 2 |
47 |
|
|
} RangeCoder; |
48 |
|
|
|
49 |
|
|
void ff_init_range_encoder(RangeCoder *c, uint8_t *buf, int buf_size); |
50 |
|
|
void ff_init_range_decoder(RangeCoder *c, const uint8_t *buf, int buf_size); |
51 |
|
|
|
52 |
|
|
/** |
53 |
|
|
* Terminates the range coder |
54 |
|
|
* @param version version 0 requires the decoder to know the data size in bytes |
55 |
|
|
* version 1 needs about 1 bit more space but does not need to |
56 |
|
|
* carry the size from encoder to decoder |
57 |
|
|
*/ |
58 |
|
|
int ff_rac_terminate(RangeCoder *c, int version); |
59 |
|
|
|
60 |
|
|
/** |
61 |
|
|
* Check if at the current position there is a valid looking termination |
62 |
|
|
* @param version version 0 requires the decoder to know the data size in bytes |
63 |
|
|
* version 1 needs about 1 bit more space but does not need to |
64 |
|
|
* carry the size from encoder to decoder |
65 |
|
|
* @returns negative AVERROR code on error or non negative. |
66 |
|
|
*/ |
67 |
|
|
int ff_rac_check_termination(RangeCoder *c, int version); |
68 |
|
|
|
69 |
|
|
void ff_build_rac_states(RangeCoder *c, int factor, int max_p); |
70 |
|
|
|
71 |
|
1362078737 |
static inline void renorm_encoder(RangeCoder *c) |
72 |
|
|
{ |
73 |
|
|
// FIXME: optimize |
74 |
✓✓ |
1446355023 |
while (c->range < 0x100) { |
75 |
✓✓ |
84276286 |
if (c->outstanding_byte < 0) { |
76 |
|
8395 |
c->outstanding_byte = c->low >> 8; |
77 |
✓✓ |
84267891 |
} else if (c->low <= 0xFF00) { |
78 |
|
55156256 |
*c->bytestream++ = c->outstanding_byte; |
79 |
✓✓ |
55678641 |
for (; c->outstanding_count; c->outstanding_count--) |
80 |
|
522385 |
*c->bytestream++ = 0xFF; |
81 |
|
55156256 |
c->outstanding_byte = c->low >> 8; |
82 |
✓✓ |
29111635 |
} else if (c->low >= 0x10000) { |
83 |
|
28478363 |
*c->bytestream++ = c->outstanding_byte + 1; |
84 |
✓✓ |
28589165 |
for (; c->outstanding_count; c->outstanding_count--) |
85 |
|
110802 |
*c->bytestream++ = 0x00; |
86 |
|
28478363 |
c->outstanding_byte = (c->low >> 8) & 0xFF; |
87 |
|
|
} else { |
88 |
|
633272 |
c->outstanding_count++; |
89 |
|
|
} |
90 |
|
|
|
91 |
|
84276286 |
c->low = (c->low & 0xFF) << 8; |
92 |
|
84276286 |
c->range <<= 8; |
93 |
|
|
} |
94 |
|
1362078737 |
} |
95 |
|
|
|
96 |
|
1673460 |
static inline int get_rac_count(RangeCoder *c) |
97 |
|
|
{ |
98 |
|
1673460 |
int x = c->bytestream - c->bytestream_start + c->outstanding_count; |
99 |
✓✓ |
1673460 |
if (c->outstanding_byte >= 0) |
100 |
|
1672998 |
x++; |
101 |
|
1673460 |
return 8 * x - av_log2(c->range); |
102 |
|
|
} |
103 |
|
|
|
104 |
|
1362063573 |
static inline void put_rac(RangeCoder *c, uint8_t *const state, int bit) |
105 |
|
|
{ |
106 |
|
1362063573 |
int range1 = (c->range * (*state)) >> 8; |
107 |
|
|
|
108 |
|
|
av_assert2(*state); |
109 |
|
|
av_assert2(range1 < c->range); |
110 |
|
|
av_assert2(range1 > 0); |
111 |
✓✓ |
1362063573 |
if (!bit) { |
112 |
|
581766013 |
c->range -= range1; |
113 |
|
581766013 |
*state = c->zero_state[*state]; |
114 |
|
|
} else { |
115 |
|
780297560 |
c->low += c->range - range1; |
116 |
|
780297560 |
c->range = range1; |
117 |
|
780297560 |
*state = c->one_state[*state]; |
118 |
|
|
} |
119 |
|
|
|
120 |
|
1362063573 |
renorm_encoder(c); |
121 |
|
1362063573 |
} |
122 |
|
|
|
123 |
|
1371689831 |
static inline void refill(RangeCoder *c) |
124 |
|
|
{ |
125 |
✓✓ |
1371689831 |
if (c->range < 0x100) { |
126 |
|
83731125 |
c->range <<= 8; |
127 |
|
83731125 |
c->low <<= 8; |
128 |
✓✓ |
83731125 |
if (c->bytestream < c->bytestream_end) { |
129 |
|
83729463 |
c->low += c->bytestream[0]; |
130 |
|
83729463 |
c->bytestream++; |
131 |
|
|
} else |
132 |
|
1662 |
c->overread ++; |
133 |
|
|
} |
134 |
|
1371689831 |
} |
135 |
|
|
|
136 |
|
1371689831 |
static inline int get_rac(RangeCoder *c, uint8_t *const state) |
137 |
|
|
{ |
138 |
|
1371689831 |
int range1 = (c->range * (*state)) >> 8; |
139 |
|
|
|
140 |
|
1371689831 |
c->range -= range1; |
141 |
✓✓ |
1371689831 |
if (c->low < c->range) { |
142 |
|
585236152 |
*state = c->zero_state[*state]; |
143 |
|
585236152 |
refill(c); |
144 |
|
585236152 |
return 0; |
145 |
|
|
} else { |
146 |
|
786453679 |
c->low -= c->range; |
147 |
|
786453679 |
*state = c->one_state[*state]; |
148 |
|
786453679 |
c->range = range1; |
149 |
|
786453679 |
refill(c); |
150 |
|
786453679 |
return 1; |
151 |
|
|
} |
152 |
|
|
} |
153 |
|
|
|
154 |
|
|
#endif /* AVCODEC_RANGECODER_H */ |