00001 /* 00002 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder 00003 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> 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 00027 #ifndef AVCODEC_CABAC_FUNCTIONS_H 00028 #define AVCODEC_CABAC_FUNCTIONS_H 00029 00030 #include <stdint.h> 00031 00032 #include "cabac.h" 00033 #include "config.h" 00034 00035 #if ARCH_X86 00036 # include "x86/cabac.h" 00037 #endif 00038 00039 extern const uint8_t ff_h264_norm_shift[512]; 00040 extern uint8_t ff_h264_mlps_state[4*64]; 00041 extern uint8_t ff_h264_lps_range[4*2*64]; 00042 00043 static void refill(CABACContext *c){ 00044 #if CABAC_BITS == 16 00045 c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); 00046 #else 00047 c->low+= c->bytestream[0]<<1; 00048 #endif 00049 c->low -= CABAC_MASK; 00050 c->bytestream+= CABAC_BITS/8; 00051 } 00052 00053 static inline void renorm_cabac_decoder_once(CABACContext *c){ 00054 int shift= (uint32_t)(c->range - 0x100)>>31; 00055 c->range<<= shift; 00056 c->low <<= shift; 00057 if(!(c->low & CABAC_MASK)) 00058 refill(c); 00059 } 00060 00061 #ifndef get_cabac_inline 00062 static void refill2(CABACContext *c){ 00063 int i, x; 00064 00065 x= c->low ^ (c->low-1); 00066 i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; 00067 00068 x= -CABAC_MASK; 00069 00070 #if CABAC_BITS == 16 00071 x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); 00072 #else 00073 x+= c->bytestream[0]<<1; 00074 #endif 00075 00076 c->low += x<<i; 00077 c->bytestream+= CABAC_BITS/8; 00078 } 00079 00080 static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ 00081 int s = *state; 00082 int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; 00083 int bit, lps_mask; 00084 00085 c->range -= RangeLPS; 00086 lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; 00087 00088 c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; 00089 c->range += (RangeLPS - c->range) & lps_mask; 00090 00091 s^=lps_mask; 00092 *state= (ff_h264_mlps_state+128)[s]; 00093 bit= s&1; 00094 00095 lps_mask= ff_h264_norm_shift[c->range]; 00096 c->range<<= lps_mask; 00097 c->low <<= lps_mask; 00098 if(!(c->low & CABAC_MASK)) 00099 refill2(c); 00100 return bit; 00101 } 00102 #endif 00103 00104 static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ 00105 return get_cabac_inline(c,state); 00106 } 00107 00108 static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ 00109 return get_cabac_inline(c,state); 00110 } 00111 00112 static int av_unused get_cabac_bypass(CABACContext *c){ 00113 int range; 00114 c->low += c->low; 00115 00116 if(!(c->low & CABAC_MASK)) 00117 refill(c); 00118 00119 range= c->range<<(CABAC_BITS+1); 00120 if(c->low < range){ 00121 return 0; 00122 }else{ 00123 c->low -= range; 00124 return 1; 00125 } 00126 } 00127 00128 00129 #ifndef get_cabac_bypass_sign 00130 static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ 00131 int range, mask; 00132 c->low += c->low; 00133 00134 if(!(c->low & CABAC_MASK)) 00135 refill(c); 00136 00137 range= c->range<<(CABAC_BITS+1); 00138 c->low -= range; 00139 mask= c->low >> 31; 00140 range &= mask; 00141 c->low += range; 00142 return (val^mask)-mask; 00143 } 00144 #endif 00145 00150 static int av_unused get_cabac_terminate(CABACContext *c){ 00151 c->range -= 2; 00152 if(c->low < c->range<<(CABAC_BITS+1)){ 00153 renorm_cabac_decoder_once(c); 00154 return 0; 00155 }else{ 00156 return c->bytestream - c->bytestream_start; 00157 } 00158 } 00159 00160 #endif /* AVCODEC_CABAC_FUNCTIONS_H */