yading@10
|
1 /*
|
yading@10
|
2 * Copyright (C) 2007 Marco Gerards <marco@gnu.org>
|
yading@10
|
3 * Copyright (C) 2009 David Conrad
|
yading@10
|
4 *
|
yading@10
|
5 * This file is part of FFmpeg.
|
yading@10
|
6 *
|
yading@10
|
7 * FFmpeg is free software; you can redistribute it and/or
|
yading@10
|
8 * modify it under the terms of the GNU Lesser General Public
|
yading@10
|
9 * License as published by the Free Software Foundation; either
|
yading@10
|
10 * version 2.1 of the License, or (at your option) any later version.
|
yading@10
|
11 *
|
yading@10
|
12 * FFmpeg is distributed in the hope that it will be useful,
|
yading@10
|
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
yading@10
|
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
yading@10
|
15 * Lesser General Public License for more details.
|
yading@10
|
16 *
|
yading@10
|
17 * You should have received a copy of the GNU Lesser General Public
|
yading@10
|
18 * License along with FFmpeg; if not, write to the Free Software
|
yading@10
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
yading@10
|
20 */
|
yading@10
|
21
|
yading@10
|
22 /**
|
yading@10
|
23 * @file
|
yading@10
|
24 * Arithmetic decoder for Dirac
|
yading@10
|
25 * @author Marco Gerards <marco@gnu.org>
|
yading@10
|
26 */
|
yading@10
|
27
|
yading@10
|
28 #ifndef AVCODEC_DIRAC_ARITH_H
|
yading@10
|
29 #define AVCODEC_DIRAC_ARITH_H
|
yading@10
|
30
|
yading@10
|
31 #include "bytestream.h"
|
yading@10
|
32 #include "get_bits.h"
|
yading@10
|
33
|
yading@10
|
34 enum dirac_arith_contexts {
|
yading@10
|
35 CTX_ZPZN_F1,
|
yading@10
|
36 CTX_ZPNN_F1,
|
yading@10
|
37 CTX_NPZN_F1,
|
yading@10
|
38 CTX_NPNN_F1,
|
yading@10
|
39 CTX_ZP_F2,
|
yading@10
|
40 CTX_ZP_F3,
|
yading@10
|
41 CTX_ZP_F4,
|
yading@10
|
42 CTX_ZP_F5,
|
yading@10
|
43 CTX_ZP_F6,
|
yading@10
|
44 CTX_NP_F2,
|
yading@10
|
45 CTX_NP_F3,
|
yading@10
|
46 CTX_NP_F4,
|
yading@10
|
47 CTX_NP_F5,
|
yading@10
|
48 CTX_NP_F6,
|
yading@10
|
49 CTX_COEFF_DATA,
|
yading@10
|
50 CTX_SIGN_NEG,
|
yading@10
|
51 CTX_SIGN_ZERO,
|
yading@10
|
52 CTX_SIGN_POS,
|
yading@10
|
53 CTX_ZERO_BLOCK,
|
yading@10
|
54 CTX_DELTA_Q_F,
|
yading@10
|
55 CTX_DELTA_Q_DATA,
|
yading@10
|
56 CTX_DELTA_Q_SIGN,
|
yading@10
|
57
|
yading@10
|
58 DIRAC_CTX_COUNT
|
yading@10
|
59 };
|
yading@10
|
60
|
yading@10
|
61 // Dirac resets the arith decoder between decoding various types of data,
|
yading@10
|
62 // so many contexts are never used simultaneously. Thus, we can reduce
|
yading@10
|
63 // the number of contexts needed by reusing them.
|
yading@10
|
64 #define CTX_SB_F1 CTX_ZP_F5
|
yading@10
|
65 #define CTX_SB_DATA 0
|
yading@10
|
66 #define CTX_PMODE_REF1 0
|
yading@10
|
67 #define CTX_PMODE_REF2 1
|
yading@10
|
68 #define CTX_GLOBAL_BLOCK 2
|
yading@10
|
69 #define CTX_MV_F1 CTX_ZP_F2
|
yading@10
|
70 #define CTX_MV_DATA 0
|
yading@10
|
71 #define CTX_DC_F1 CTX_ZP_F5
|
yading@10
|
72 #define CTX_DC_DATA 0
|
yading@10
|
73
|
yading@10
|
74 typedef struct {
|
yading@10
|
75 unsigned low;
|
yading@10
|
76 uint16_t range;
|
yading@10
|
77 int16_t counter;
|
yading@10
|
78
|
yading@10
|
79 const uint8_t *bytestream;
|
yading@10
|
80 const uint8_t *bytestream_end;
|
yading@10
|
81
|
yading@10
|
82 uint16_t contexts[DIRAC_CTX_COUNT];
|
yading@10
|
83 } DiracArith;
|
yading@10
|
84
|
yading@10
|
85 extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT];
|
yading@10
|
86 extern const uint16_t ff_dirac_prob[256];
|
yading@10
|
87 extern int16_t ff_dirac_prob_branchless[256][2];
|
yading@10
|
88
|
yading@10
|
89 static inline void renorm(DiracArith *c)
|
yading@10
|
90 {
|
yading@10
|
91 #if HAVE_FAST_CLZ
|
yading@10
|
92 int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15);
|
yading@10
|
93
|
yading@10
|
94 c->low <<= shift;
|
yading@10
|
95 c->range <<= shift;
|
yading@10
|
96 c->counter += shift;
|
yading@10
|
97 #else
|
yading@10
|
98 while (c->range <= 0x4000) {
|
yading@10
|
99 c->low <<= 1;
|
yading@10
|
100 c->range <<= 1;
|
yading@10
|
101 c->counter++;
|
yading@10
|
102 }
|
yading@10
|
103 #endif
|
yading@10
|
104 }
|
yading@10
|
105
|
yading@10
|
106 static inline void refill(DiracArith *c)
|
yading@10
|
107 {
|
yading@10
|
108 int counter = c->counter;
|
yading@10
|
109
|
yading@10
|
110 if (counter >= 0) {
|
yading@10
|
111 int new = bytestream_get_be16(&c->bytestream);
|
yading@10
|
112
|
yading@10
|
113 // the spec defines overread bits to be 1, and streams rely on this
|
yading@10
|
114 if (c->bytestream > c->bytestream_end) {
|
yading@10
|
115 new |= 0xff;
|
yading@10
|
116 if (c->bytestream > c->bytestream_end+1)
|
yading@10
|
117 new |= 0xff00;
|
yading@10
|
118
|
yading@10
|
119 c->bytestream = c->bytestream_end;
|
yading@10
|
120 }
|
yading@10
|
121
|
yading@10
|
122 c->low += new << counter;
|
yading@10
|
123 counter -= 16;
|
yading@10
|
124 }
|
yading@10
|
125 c->counter = counter;
|
yading@10
|
126 }
|
yading@10
|
127
|
yading@10
|
128 static inline int dirac_get_arith_bit(DiracArith *c, int ctx)
|
yading@10
|
129 {
|
yading@10
|
130 int prob_zero = c->contexts[ctx];
|
yading@10
|
131 int range_times_prob, bit;
|
yading@10
|
132 unsigned low = c->low;
|
yading@10
|
133 int range = c->range;
|
yading@10
|
134
|
yading@10
|
135 range_times_prob = (c->range * prob_zero) >> 16;
|
yading@10
|
136
|
yading@10
|
137 #if HAVE_FAST_CMOV && HAVE_INLINE_ASM
|
yading@10
|
138 low -= range_times_prob << 16;
|
yading@10
|
139 range -= range_times_prob;
|
yading@10
|
140 bit = 0;
|
yading@10
|
141 __asm__(
|
yading@10
|
142 "cmpl %5, %4 \n\t"
|
yading@10
|
143 "setae %b0 \n\t"
|
yading@10
|
144 "cmovb %3, %2 \n\t"
|
yading@10
|
145 "cmovb %5, %1 \n\t"
|
yading@10
|
146 : "+q"(bit), "+r"(range), "+r"(low)
|
yading@10
|
147 : "r"(c->low), "r"(c->low>>16),
|
yading@10
|
148 "r"(range_times_prob)
|
yading@10
|
149 );
|
yading@10
|
150 #else
|
yading@10
|
151 bit = (low >> 16) >= range_times_prob;
|
yading@10
|
152 if (bit) {
|
yading@10
|
153 low -= range_times_prob << 16;
|
yading@10
|
154 range -= range_times_prob;
|
yading@10
|
155 } else {
|
yading@10
|
156 range = range_times_prob;
|
yading@10
|
157 }
|
yading@10
|
158 #endif
|
yading@10
|
159
|
yading@10
|
160 c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit];
|
yading@10
|
161 c->low = low;
|
yading@10
|
162 c->range = range;
|
yading@10
|
163
|
yading@10
|
164 renorm(c);
|
yading@10
|
165 refill(c);
|
yading@10
|
166 return bit;
|
yading@10
|
167 }
|
yading@10
|
168
|
yading@10
|
169 static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx)
|
yading@10
|
170 {
|
yading@10
|
171 int ret = 1;
|
yading@10
|
172 while (!dirac_get_arith_bit(c, follow_ctx)) {
|
yading@10
|
173 ret <<= 1;
|
yading@10
|
174 ret += dirac_get_arith_bit(c, data_ctx);
|
yading@10
|
175 follow_ctx = ff_dirac_next_ctx[follow_ctx];
|
yading@10
|
176 }
|
yading@10
|
177 return ret-1;
|
yading@10
|
178 }
|
yading@10
|
179
|
yading@10
|
180 static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx)
|
yading@10
|
181 {
|
yading@10
|
182 int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx);
|
yading@10
|
183 if (ret && dirac_get_arith_bit(c, data_ctx+1))
|
yading@10
|
184 ret = -ret;
|
yading@10
|
185 return ret;
|
yading@10
|
186 }
|
yading@10
|
187
|
yading@10
|
188 void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length);
|
yading@10
|
189
|
yading@10
|
190 #endif /* AVCODEC_DIRAC_ARITH_H */
|