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
34
58
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
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
72 #define CTX_DC_F1 CTX_ZP_F5
74
79
82
85
89
91 {
92 #if HAVE_FAST_CLZ
94
98 #else
99 while (c->
range <= 0x4000) {
103 }
104 #endif
105 }
106
108 {
110
111 if (counter >= 0) {
112 int new = bytestream_get_be16(&c->
bytestream);
113
114 // the spec defines overread bits to be 1, and streams rely on this
116 new |= 0xff;
118 new |= 0xff00;
119
121 }
122
123 c->
low +=
new << counter;
124 counter -= 16;
125 }
127 }
128
130 {
132 int range_times_prob, bit;
133 unsigned low = c->
low;
134 int range = c->
range;
135
136 range_times_prob = (c->
range * prob_zero) >> 16;
137
138 #if ARCH_X86 && HAVE_FAST_CMOV && HAVE_INLINE_ASM && HAVE_6REGS
139 low -= range_times_prob << 16;
140 range -= range_times_prob;
141 bit = 0;
142 __asm__(
143 "cmpl %5, %4 \n\t"
144 "setae %b0 \n\t"
145 "cmovb %3, %2 \n\t"
146 "cmovb %5, %1 \n\t"
147 : "+q"(bit), "+r"(range), "+r"(low)
148 :
"r"(c->
low),
"r"(c->
low>>16),
149 "r"(range_times_prob)
150 );
151 #else
152 bit = (low >> 16) >= range_times_prob;
153 if (bit) {
154 low -= range_times_prob << 16;
155 range -= range_times_prob;
156 } else {
157 range = range_times_prob;
158 }
159 #endif
160
164
167 return bit;
168 }
169
171 {
174 if (ret >= 0x40000000) {
176 return -1;
177 }
178 ret <<= 1;
181 }
182 return ret-1;
183 }
184
186 {
191 }
192
194
195 #endif /* AVCODEC_DIRAC_ARITH_H */
static int shift(int a, int b)
int16_t ff_dirac_prob_branchless[256][2]
uint16_t contexts[DIRAC_CTX_COUNT]
static int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx)
int av_log2_16bit(unsigned v)
const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT]
static void renorm(DiracArith *c)
bitstream reader API header.
static void refill(DiracArith *c)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
const uint8_t * bytestream
const uint8_t * bytestream_end
static int dirac_get_arith_bit(DiracArith *c, int ctx)
const uint16_t ff_dirac_prob[256]
static int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx)
void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length)