00001 /* 00002 * Copyright (C) 2007 Marco Gerards <marco@gnu.org> 00003 * Copyright (C) 2009 David Conrad 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 // Dirac resets the arith decoder between decoding various types of data, 00062 // so many contexts are never used simultaneously. Thus, we can reduce 00063 // the number of contexts needed by reusing them. 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 // the spec defines overread bits to be 1, and streams rely on this 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 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 /* AVCODEC_DIRAC_ARITH_H */