Imported Debian version 2.4.3~trusty1
[deb_ffmpeg.git] / ffmpeg / libavcodec / dirac_arith.h
CommitLineData
2ba45a60
DM
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
35enum 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
75typedef 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} DiracArith;
85
86extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT];
87extern const uint16_t ff_dirac_prob[256];
88extern int16_t ff_dirac_prob_branchless[256][2];
89
90static inline void renorm(DiracArith *c)
91{
92#if HAVE_FAST_CLZ
93 int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15);
94
95 c->low <<= shift;
96 c->range <<= shift;
97 c->counter += shift;
98#else
99 while (c->range <= 0x4000) {
100 c->low <<= 1;
101 c->range <<= 1;
102 c->counter++;
103 }
104#endif
105}
106
107static inline void refill(DiracArith *c)
108{
109 int counter = c->counter;
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
115 if (c->bytestream > c->bytestream_end) {
116 new |= 0xff;
117 if (c->bytestream > c->bytestream_end+1)
118 new |= 0xff00;
119
120 c->bytestream = c->bytestream_end;
121 }
122
123 c->low += new << counter;
124 counter -= 16;
125 }
126 c->counter = counter;
127}
128
129static inline int dirac_get_arith_bit(DiracArith *c, int ctx)
130{
131 int prob_zero = c->contexts[ctx];
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 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
161 c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit];
162 c->low = low;
163 c->range = range;
164
165 renorm(c);
166 refill(c);
167 return bit;
168}
169
170static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx)
171{
172 int ret = 1;
173 while (!dirac_get_arith_bit(c, follow_ctx)) {
174 if (ret >= 0x40000000) {
175 av_log(NULL, AV_LOG_ERROR, "dirac_get_arith_uint overflow\n");
176 return -1;
177 }
178 ret <<= 1;
179 ret += dirac_get_arith_bit(c, data_ctx);
180 follow_ctx = ff_dirac_next_ctx[follow_ctx];
181 }
182 return ret-1;
183}
184
185static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx)
186{
187 int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx);
188 if (ret && dirac_get_arith_bit(c, data_ctx+1))
189 ret = -ret;
190 return ret;
191}
192
193void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length);
194
195#endif /* AVCODEC_DIRAC_ARITH_H */