Mercurial > cgi-bin > hgwebdir.cgi > PR > Applications > VSs > VSs__H264__App
diff libavcodec/cell/cabac_spu.h @ 2:897f711a7157
rearrange to work with autoconf
| author | Nina Engelhardt <nengel@mailbox.tu-berlin.de> |
|---|---|
| date | Tue, 25 Sep 2012 15:55:33 +0200 |
| parents | |
| children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libavcodec/cell/cabac_spu.h Tue Sep 25 15:55:33 2012 +0200 1.3 @@ -0,0 +1,233 @@ 1.4 +/* 1.5 + * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder 1.6 + * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> 1.7 + * 1.8 + * This file is part of FFmpeg. 1.9 + * 1.10 + * FFmpeg is free software; you can redistribute it and/or 1.11 + * modify it under the terms of the GNU Lesser General Public 1.12 + * License as published by the Free Software Foundation; either 1.13 + * version 2.1 of the License, or (at your option) any later version. 1.14 + * 1.15 + * FFmpeg is distributed in the hope that it will be useful, 1.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 1.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.18 + * Lesser General Public License for more details. 1.19 + * 1.20 + * You should have received a copy of the GNU Lesser General Public 1.21 + * License along with FFmpeg; if not, write to the Free Software 1.22 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 1.23 + */ 1.24 + 1.25 +/** 1.26 + * @file 1.27 + * Context Adaptive Binary Arithmetic Coder. 1.28 + */ 1.29 + 1.30 +#ifndef AVCODEC_CABAC_H 1.31 +#define AVCODEC_CABAC_H 1.32 + 1.33 +//#undef NDEBUG 1.34 +#include <assert.h> 1.35 +#include "h264_dma.h" 1.36 +#include "libavutil/x86_cpu.h" 1.37 +#include "libavutil/attributes.h" 1.38 + 1.39 +#define CABAC_BITS 16 1.40 +#define CABAC_MASK ((1<<CABAC_BITS)-1) 1.41 +#define BRANCHLESS_CABAC_DECODER 1 1.42 + 1.43 +typedef struct CABACContext{ 1.44 + int low; 1.45 + int range; 1.46 + int outstanding_count; 1.47 +#ifdef STRICT_LIMITS 1.48 + int symCount; 1.49 +#endif 1.50 + const uint8_t *bytestream_ea_start; 1.51 + const uint8_t *bytestream_ea; 1.52 + const uint8_t *bytestream_ea_end; 1.53 + int slot; 1.54 + int bufsize; 1.55 + 1.56 + uint8_t *bytestream_start; 1.57 + uint8_t *bytestream; 1.58 + uint8_t *bytestream_end; 1.59 + uint8_t cabac_state[460]; 1.60 +}CABACContext; 1.61 + 1.62 +extern uint8_t ff_h264_mlps_state[4*64]; 1.63 +extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS 1.64 +extern uint8_t ff_h264_mps_state[2*64]; ///< transIdxMPS 1.65 +extern uint8_t ff_h264_lps_state[2*64]; ///< transIdxLPS 1.66 +extern const uint8_t ff_h264_norm_shift[512]; 1.67 + 1.68 +void ff_init_cabac_states(void); 1.69 + 1.70 +extern DECLARE_ALIGNED(128,uint8_t, bytestream_ls[4096]); 1.71 +extern int bytecount; 1.72 +static inline void dma_cabac(CABACContext *c){ 1.73 + bytecount++; 1.74 + if (c->bytestream == c->bytestream_end){ 1.75 + if (c->bufsize>0){ 1.76 + int size = (c->bufsize > sizeof(bytestream_ls)) ? sizeof(bytestream_ls) : c->bufsize; 1.77 + int align = size &0xF; 1.78 + int dma_size = size + (align? 16-align : 0); 1.79 + 1.80 + spu_dma_get(bytestream_ls, (unsigned) c->bytestream_ea, dma_size, ED_raw); 1.81 + wait_dma_id(ED_raw); 1.82 + c->bytestream = bytestream_ls; 1.83 + c->bytestream_end = &bytestream_ls[size]; 1.84 + c->bytestream_ea += dma_size; 1.85 + c->bufsize -= size; 1.86 + } 1.87 + bytecount =0; 1.88 + }else if((unsigned)c->bytestream > (unsigned)c->bytestream_end +2){ 1.89 + //fprintf(stderr, "Read beyond end of frame %d\n", c->bufsize); 1.90 + bytecount =0; 1.91 + } 1.92 +} 1.93 + 1.94 +static void refill(CABACContext *c){ 1.95 + dma_cabac(c); 1.96 + 1.97 + c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); 1.98 + 1.99 + c->low -= CABAC_MASK; 1.100 + c->bytestream+= CABAC_BITS/8; 1.101 +} 1.102 + 1.103 +static void refill2(CABACContext *c){ 1.104 + int i, x; 1.105 + 1.106 + dma_cabac(c); 1.107 + 1.108 + x= c->low ^ (c->low-1); 1.109 + i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; 1.110 + 1.111 + x= -CABAC_MASK; 1.112 + 1.113 + x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); 1.114 + 1.115 + c->low += x<<i; 1.116 + c->bytestream+= CABAC_BITS/8; 1.117 +} 1.118 + 1.119 +static inline void renorm_cabac_decoder(CABACContext *c){ 1.120 + while(c->range < 0x100){ 1.121 + c->range+= c->range; 1.122 + c->low+= c->low; 1.123 + if(!(c->low & CABAC_MASK)) 1.124 + refill(c); 1.125 + } 1.126 +} 1.127 + 1.128 +static inline void renorm_cabac_decoder_once(CABACContext *c){ 1.129 + 1.130 + int shift= (uint32_t)(c->range - 0x100)>>31; 1.131 + c->range<<= shift; 1.132 + c->low <<= shift; 1.133 + 1.134 + if(!(c->low & CABAC_MASK)) 1.135 + refill(c); 1.136 +} 1.137 + 1.138 +static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ 1.139 + 1.140 + int s = *state; 1.141 + int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; 1.142 + int bit, lps_mask av_unused; 1.143 + 1.144 + c->range -= RangeLPS; 1.145 +#ifndef BRANCHLESS_CABAC_DECODER 1.146 + if(c->low < (c->range<<(CABAC_BITS+1))){ 1.147 + bit= s&1; 1.148 + *state= ff_h264_mps_state[s]; 1.149 + renorm_cabac_decoder_once(c); 1.150 + }else{ 1.151 + bit= ff_h264_norm_shift[RangeLPS]; 1.152 + c->low -= (c->range<<(CABAC_BITS+1)); 1.153 + *state= ff_h264_lps_state[s]; 1.154 + c->range = RangeLPS<<bit; 1.155 + c->low <<= bit; 1.156 + bit= (s&1)^1; 1.157 + 1.158 + if(!(c->low & CABAC_MASK)){ 1.159 + refill2(c); 1.160 + } 1.161 + } 1.162 +#else /* BRANCHLESS_CABAC_DECODER */ 1.163 + lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; 1.164 + 1.165 + c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; 1.166 + c->range += (RangeLPS - c->range) & lps_mask; 1.167 + 1.168 + s^=lps_mask; 1.169 + *state= (ff_h264_mlps_state+128)[s]; 1.170 + bit= s&1; 1.171 + 1.172 + lps_mask= ff_h264_norm_shift[c->range]; 1.173 + c->range<<= lps_mask; 1.174 + c->low <<= lps_mask; 1.175 + if(!(c->low & CABAC_MASK)) 1.176 + refill2(c); 1.177 +#endif /* BRANCHLESS_CABAC_DECODER */ 1.178 + 1.179 + return bit; 1.180 +} 1.181 + 1.182 +static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ 1.183 + return get_cabac_inline(c, state); 1.184 +} 1.185 + 1.186 +static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ 1.187 + return get_cabac_inline(c, state); 1.188 +} 1.189 + 1.190 +static int av_unused get_cabac_bypass(CABACContext *c){ 1.191 + 1.192 + int range; 1.193 + c->low += c->low; 1.194 + 1.195 + if(!(c->low & CABAC_MASK)) 1.196 + refill(c); 1.197 + 1.198 + range= c->range<<(CABAC_BITS+1); 1.199 + if(c->low < range){ 1.200 + return 0; 1.201 + }else{ 1.202 + c->low -= range; 1.203 + return 1; 1.204 + } 1.205 +} 1.206 + 1.207 +static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ 1.208 + int range, mask; 1.209 + c->low += c->low; 1.210 + 1.211 + if(!(c->low & CABAC_MASK)) 1.212 + refill(c); 1.213 + 1.214 + range= c->range<<(CABAC_BITS+1); 1.215 + c->low -= range; 1.216 + mask= c->low >> 31; 1.217 + range &= mask; 1.218 + c->low += range; 1.219 + return (val^mask)-mask; 1.220 +} 1.221 + 1.222 +/** 1.223 + * 1.224 + * @return the number of bytes read or 0 if no end 1.225 + */ 1.226 +static int av_unused get_cabac_terminate(CABACContext *c){ 1.227 + c->range -= 2; 1.228 + if(c->low < c->range<<(CABAC_BITS+1)){ 1.229 + renorm_cabac_decoder_once(c); 1.230 + return 0; 1.231 + }else{ 1.232 + return c->bytestream - c->bytestream_start; 1.233 + } 1.234 +} 1.235 + 1.236 +#endif /* AVCODEC_CABAC_H */
