00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00028 #ifndef AVCODEC_DIRAC_ARITH_H
00029 #define AVCODEC_DIRAC_ARITH_H
00030
00031 #include "bytestream.h"
00032 #include "get_bits.h"
00033
00034 enum dirac_arith_contexts {
00035 CTX_ZPZN_F1,
00036 CTX_ZPNN_F1,
00037 CTX_NPZN_F1,
00038 CTX_NPNN_F1,
00039 CTX_ZP_F2,
00040 CTX_ZP_F3,
00041 CTX_ZP_F4,
00042 CTX_ZP_F5,
00043 CTX_ZP_F6,
00044 CTX_NP_F2,
00045 CTX_NP_F3,
00046 CTX_NP_F4,
00047 CTX_NP_F5,
00048 CTX_NP_F6,
00049 CTX_COEFF_DATA,
00050 CTX_SIGN_NEG,
00051 CTX_SIGN_ZERO,
00052 CTX_SIGN_POS,
00053 CTX_ZERO_BLOCK,
00054 CTX_DELTA_Q_F,
00055 CTX_DELTA_Q_DATA,
00056 CTX_DELTA_Q_SIGN,
00057
00058 DIRAC_CTX_COUNT
00059 };
00060
00061
00062
00063
00064 #define CTX_SB_F1 CTX_ZP_F5
00065 #define CTX_SB_DATA 0
00066 #define CTX_PMODE_REF1 0
00067 #define CTX_PMODE_REF2 1
00068 #define CTX_GLOBAL_BLOCK 2
00069 #define CTX_MV_F1 CTX_ZP_F2
00070 #define CTX_MV_DATA 0
00071 #define CTX_DC_F1 CTX_ZP_F5
00072 #define CTX_DC_DATA 0
00073
00074 typedef struct {
00075 unsigned low;
00076 uint16_t range;
00077 int16_t counter;
00078
00079 const uint8_t *bytestream;
00080 const uint8_t *bytestream_end;
00081
00082 uint16_t contexts[DIRAC_CTX_COUNT];
00083 } DiracArith;
00084
00085 extern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT];
00086 extern const uint16_t ff_dirac_prob[256];
00087 extern int16_t ff_dirac_prob_branchless[256][2];
00088
00089 static inline void renorm(DiracArith *c)
00090 {
00091 #if HAVE_FAST_CLZ
00092 int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15);
00093
00094 c->low <<= shift;
00095 c->range <<= shift;
00096 c->counter += shift;
00097 #else
00098 while (c->range <= 0x4000) {
00099 c->low <<= 1;
00100 c->range <<= 1;
00101 c->counter++;
00102 }
00103 #endif
00104 }
00105
00106 static inline void refill(DiracArith *c)
00107 {
00108 int counter = c->counter;
00109
00110 if (counter >= 0) {
00111 int new = bytestream_get_be16(&c->bytestream);
00112
00113
00114 if (c->bytestream > c->bytestream_end) {
00115 new |= 0xff;
00116 if (c->bytestream > c->bytestream_end+1)
00117 new |= 0xff00;
00118
00119 c->bytestream = c->bytestream_end;
00120 }
00121
00122 c->low += new << counter;
00123 counter -= 16;
00124 }
00125 c->counter = counter;
00126 }
00127
00128 static inline int dirac_get_arith_bit(DiracArith *c, int ctx)
00129 {
00130 int prob_zero = c->contexts[ctx];
00131 int range_times_prob, bit;
00132 unsigned low = c->low;
00133 int range = c->range;
00134
00135 range_times_prob = (c->range * prob_zero) >> 16;
00136
00137 #if HAVE_FAST_CMOV && HAVE_INLINE_ASM
00138 low -= range_times_prob << 16;
00139 range -= range_times_prob;
00140 bit = 0;
00141 __asm__(
00142 "cmpl %5, %4 \n\t"
00143 "setae %b0 \n\t"
00144 "cmovb %3, %2 \n\t"
00145 "cmovb %5, %1 \n\t"
00146 : "+q"(bit), "+r"(range), "+r"(low)
00147 : "r"(c->low), "r"(c->low>>16),
00148 "r"(range_times_prob)
00149 );
00150 #else
00151 bit = (low >> 16) >= range_times_prob;
00152 if (bit) {
00153 low -= range_times_prob << 16;
00154 range -= range_times_prob;
00155 } else {
00156 range = range_times_prob;
00157 }
00158 #endif
00159
00160 c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit];
00161 c->low = low;
00162 c->range = range;
00163
00164 renorm(c);
00165 refill(c);
00166 return bit;
00167 }
00168
00169 static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx)
00170 {
00171 int ret = 1;
00172 while (!dirac_get_arith_bit(c, follow_ctx)) {
00173 ret <<= 1;
00174 ret += dirac_get_arith_bit(c, data_ctx);
00175 follow_ctx = ff_dirac_next_ctx[follow_ctx];
00176 }
00177 return ret-1;
00178 }
00179
00180 static inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx)
00181 {
00182 int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx);
00183 if (ret && dirac_get_arith_bit(c, data_ctx+1))
00184 ret = -ret;
00185 return ret;
00186 }
00187
00188 void ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length);
00189
00190 #endif