1 |
|
|
/* |
2 |
|
|
* Copyright (C) 2007 Marco Gerards <marco@gnu.org> |
3 |
|
|
* Copyright (C) 2009 David Conrad |
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 |
|
|
* Arithmetic decoder for Dirac |
25 |
|
|
* @author Marco Gerards <marco@gnu.org> |
26 |
|
|
*/ |
27 |
|
|
|
28 |
|
|
#ifndef AVCODEC_DIRAC_ARITH_H |
29 |
|
|
#define AVCODEC_DIRAC_ARITH_H |
30 |
|
|
|
31 |
|
|
#include "libavutil/x86/asm.h" |
32 |
|
|
#include "bytestream.h" |
33 |
|
|
#include "get_bits.h" |
34 |
|
|
|
35 |
|
|
enum dirac_arith_contexts { |
36 |
|
|
CTX_ZPZN_F1, |
37 |
|
|
CTX_ZPNN_F1, |
38 |
|
|
CTX_NPZN_F1, |
39 |
|
|
CTX_NPNN_F1, |
40 |
|
|
CTX_ZP_F2, |
41 |
|
|
CTX_ZP_F3, |
42 |
|
|
CTX_ZP_F4, |
43 |
|
|
CTX_ZP_F5, |
44 |
|
|
CTX_ZP_F6, |
45 |
|
|
CTX_NP_F2, |
46 |
|
|
CTX_NP_F3, |
47 |
|
|
CTX_NP_F4, |
48 |
|
|
CTX_NP_F5, |
49 |
|
|
CTX_NP_F6, |
50 |
|
|
CTX_COEFF_DATA, |
51 |
|
|
CTX_SIGN_NEG, |
52 |
|
|
CTX_SIGN_ZERO, |
53 |
|
|
CTX_SIGN_POS, |
54 |
|
|
CTX_ZERO_BLOCK, |
55 |
|
|
CTX_DELTA_Q_F, |
56 |
|
|
CTX_DELTA_Q_DATA, |
57 |
|
|
CTX_DELTA_Q_SIGN, |
58 |
|
|
|
59 |
|
|
DIRAC_CTX_COUNT |
60 |
|
|
}; |
61 |
|
|
|
62 |
|
|
// Dirac resets the arith decoder between decoding various types of data, |
63 |
|
|
// so many contexts are never used simultaneously. Thus, we can reduce |
64 |
|
|
// the number of contexts needed by reusing them. |
65 |
|
|
#define CTX_SB_F1 CTX_ZP_F5 |
66 |
|
|
#define CTX_SB_DATA 0 |
67 |
|
|
#define CTX_PMODE_REF1 0 |
68 |
|
|
#define CTX_PMODE_REF2 1 |
69 |
|
|
#define CTX_GLOBAL_BLOCK 2 |
70 |
|
|
#define CTX_MV_F1 CTX_ZP_F2 |
71 |
|
|
#define CTX_MV_DATA 0 |
72 |
|
|
#define CTX_DC_F1 CTX_ZP_F5 |
73 |
|
|
#define CTX_DC_DATA 0 |
74 |
|
|
|
75 |
|
|
typedef struct { |
76 |
|
|
unsigned low; |
77 |
|
|
uint16_t range; |
78 |
|
|
int16_t counter; |
79 |
|
|
|
80 |
|
|
const uint8_t *bytestream; |
81 |
|
|
const uint8_t *bytestream_end; |
82 |
|
|
|
83 |
|
|
uint16_t contexts[DIRAC_CTX_COUNT]; |
84 |
|
|
int error; |
85 |
|
|
int overread; |
86 |
|
|
} DiracArith; |
87 |
|
|
|
88 |
|
|
extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT]; |
89 |
|
|
extern int16_t ff_dirac_prob_branchless[256][2]; |
90 |
|
|
|
91 |
|
1024041 |
static inline void renorm(DiracArith *c) |
92 |
|
|
{ |
93 |
|
|
#if HAVE_FAST_CLZ |
94 |
|
1024041 |
int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15); |
95 |
|
|
|
96 |
|
1024041 |
c->low <<= shift; |
97 |
|
1024041 |
c->range <<= shift; |
98 |
|
1024041 |
c->counter += shift; |
99 |
|
|
#else |
100 |
|
|
while (c->range <= 0x4000) { |
101 |
|
|
c->low <<= 1; |
102 |
|
|
c->range <<= 1; |
103 |
|
|
c->counter++; |
104 |
|
|
} |
105 |
|
|
#endif |
106 |
|
1024041 |
} |
107 |
|
|
|
108 |
|
1024041 |
static inline void refill(DiracArith *c) |
109 |
|
|
{ |
110 |
|
1024041 |
int counter = c->counter; |
111 |
|
|
|
112 |
✓✓ |
1024041 |
if (counter >= 0) { |
113 |
|
46510 |
int new = bytestream_get_be16(&c->bytestream); |
114 |
|
|
|
115 |
|
|
// the spec defines overread bits to be 1, and streams rely on this |
116 |
✓✓ |
46510 |
if (c->bytestream > c->bytestream_end) { |
117 |
|
495 |
new |= 0xff; |
118 |
✓✓ |
495 |
if (c->bytestream > c->bytestream_end+1) |
119 |
|
91 |
new |= 0xff00; |
120 |
|
|
|
121 |
|
495 |
c->bytestream = c->bytestream_end; |
122 |
|
495 |
c->overread ++; |
123 |
✗✓ |
495 |
if (c->overread > 4) |
124 |
|
|
c->error = AVERROR_INVALIDDATA; |
125 |
|
|
} |
126 |
|
|
|
127 |
|
46510 |
c->low += new << counter; |
128 |
|
46510 |
counter -= 16; |
129 |
|
|
} |
130 |
|
1024041 |
c->counter = counter; |
131 |
|
1024041 |
} |
132 |
|
|
|
133 |
|
1024041 |
static inline int dirac_get_arith_bit(DiracArith *c, int ctx) |
134 |
|
|
{ |
135 |
|
1024041 |
int prob_zero = c->contexts[ctx]; |
136 |
|
|
int range_times_prob, bit; |
137 |
|
1024041 |
unsigned low = c->low; |
138 |
|
1024041 |
int range = c->range; |
139 |
|
|
|
140 |
|
1024041 |
range_times_prob = (c->range * prob_zero) >> 16; |
141 |
|
|
|
142 |
|
|
#if ARCH_X86 && HAVE_FAST_CMOV && HAVE_INLINE_ASM && HAVE_6REGS |
143 |
|
1024041 |
low -= range_times_prob << 16; |
144 |
|
1024041 |
range -= range_times_prob; |
145 |
|
1024041 |
bit = 0; |
146 |
|
1024041 |
__asm__( |
147 |
|
|
"cmpl %5, %4 \n\t" |
148 |
|
|
"setae %b0 \n\t" |
149 |
|
|
"cmovb %3, %2 \n\t" |
150 |
|
|
"cmovb %5, %1 \n\t" |
151 |
|
|
: "+q"(bit), "+r"(range), "+r"(low) |
152 |
|
1024041 |
: "r"(c->low), "r"(c->low>>16), |
153 |
|
|
"r"(range_times_prob) |
154 |
|
|
); |
155 |
|
|
#else |
156 |
|
|
bit = (low >> 16) >= range_times_prob; |
157 |
|
|
if (bit) { |
158 |
|
|
low -= range_times_prob << 16; |
159 |
|
|
range -= range_times_prob; |
160 |
|
|
} else { |
161 |
|
|
range = range_times_prob; |
162 |
|
|
} |
163 |
|
|
#endif |
164 |
|
|
|
165 |
|
1024041 |
c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit]; |
166 |
|
1024041 |
c->low = low; |
167 |
|
1024041 |
c->range = range; |
168 |
|
|
|
169 |
|
1024041 |
renorm(c); |
170 |
|
1024041 |
refill(c); |
171 |
|
1024041 |
return bit; |
172 |
|
|
} |
173 |
|
|
|
174 |
|
353584 |
static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx) |
175 |
|
|
{ |
176 |
|
353584 |
int ret = 1; |
177 |
✓✓ |
573506 |
while (!dirac_get_arith_bit(c, follow_ctx)) { |
178 |
✗✓ |
219922 |
if (ret >= 0x40000000) { |
179 |
|
|
av_log(NULL, AV_LOG_ERROR, "dirac_get_arith_uint overflow\n"); |
180 |
|
|
c->error = AVERROR_INVALIDDATA; |
181 |
|
|
return -1; |
182 |
|
|
} |
183 |
|
219922 |
ret <<= 1; |
184 |
|
219922 |
ret += dirac_get_arith_bit(c, data_ctx); |
185 |
|
219922 |
follow_ctx = ff_dirac_next_ctx[follow_ctx]; |
186 |
|
|
} |
187 |
|
353584 |
return ret-1; |
188 |
|
|
} |
189 |
|
|
|
190 |
|
14164 |
static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx) |
191 |
|
|
{ |
192 |
|
14164 |
int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx); |
193 |
✓✓✓✓
|
14164 |
if (ret && dirac_get_arith_bit(c, data_ctx+1)) |
194 |
|
1346 |
ret = -ret; |
195 |
|
14164 |
return ret; |
196 |
|
|
} |
197 |
|
|
|
198 |
|
|
void ff_dirac_init_arith_tables(void); |
199 |
|
|
void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length); |
200 |
|
|
|
201 |
|
|
#endif /* AVCODEC_DIRAC_ARITH_H */ |