2 * Copyright (C) 2007 Marco Gerards <marco@gnu.org>
3 * Copyright (C) 2009 David Conrad
5 * This file is part of FFmpeg.
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.
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.
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
24 * Arithmetic decoder for Dirac
25 * @author Marco Gerards <marco@gnu.org>
28 #ifndef AVCODEC_DIRAC_ARITH_H
29 #define AVCODEC_DIRAC_ARITH_H
31 #include "bytestream.h"
34 enum dirac_arith_contexts {
61 // Dirac resets the arith decoder between decoding various types of data,
62 // so many contexts are never used simultaneously. Thus, we can reduce
63 // the number of contexts needed by reusing them.
64 #define CTX_SB_F1 CTX_ZP_F5
66 #define CTX_PMODE_REF1 0
67 #define CTX_PMODE_REF2 1
68 #define CTX_GLOBAL_BLOCK 2
69 #define CTX_MV_F1 CTX_ZP_F2
71 #define CTX_DC_F1 CTX_ZP_F5
79 const uint8_t *bytestream;
80 const uint8_t *bytestream_end;
82 uint16_t contexts[DIRAC_CTX_COUNT];
85 extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT];
86 extern const uint16_t ff_dirac_prob[256];
87 extern int16_t ff_dirac_prob_branchless[256][2];
89 static inline void renorm(DiracArith *c)
92 int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15);
98 while (c->range <= 0x4000) {
106 static inline void refill(DiracArith *c)
108 int counter = c->counter;
111 int new = bytestream_get_be16(&c->bytestream);
113 // the spec defines overread bits to be 1, and streams rely on this
114 if (c->bytestream > c->bytestream_end) {
116 if (c->bytestream > c->bytestream_end+1)
119 c->bytestream = c->bytestream_end;
122 c->low += new << counter;
125 c->counter = counter;
128 static inline int dirac_get_arith_bit(DiracArith *c, int ctx)
130 int prob_zero = c->contexts[ctx];
131 int range_times_prob, bit;
132 unsigned low = c->low;
133 int range = c->range;
135 range_times_prob = (c->range * prob_zero) >> 16;
137 #if HAVE_FAST_CMOV && HAVE_INLINE_ASM
138 low -= range_times_prob << 16;
139 range -= range_times_prob;
146 : "+q"(bit), "+r"(range), "+r"(low)
147 : "r"(c->low), "r"(c->low>>16),
148 "r"(range_times_prob)
151 bit = (low >> 16) >= range_times_prob;
153 low -= range_times_prob << 16;
154 range -= range_times_prob;
156 range = range_times_prob;
160 c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit];
169 static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx)
172 while (!dirac_get_arith_bit(c, follow_ctx)) {
174 ret += dirac_get_arith_bit(c, data_ctx);
175 follow_ctx = ff_dirac_next_ctx[follow_ctx];
180 static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx)
182 int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx);
183 if (ret && dirac_get_arith_bit(c, data_ctx+1))
188 void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length);
190 #endif /* AVCODEC_DIRAC_ARITH_H */