annotate libavcodec/cabac.h @ 9:ea1ba68cf0ed

update to match api changes + add sscc produced source
author Nina Engelhardt <nengel@mailbox.tu-berlin.de>
date Wed, 05 Jun 2013 14:43:26 +0200
parents
children
rev   line source
nengel@2 1 /*
nengel@2 2 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
nengel@2 3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
nengel@2 4 *
nengel@2 5 * This file is part of FFmpeg.
nengel@2 6 *
nengel@2 7 * FFmpeg is free software; you can redistribute it and/or
nengel@2 8 * modify it under the terms of the GNU Lesser General Public
nengel@2 9 * License as published by the Free Software Foundation; either
nengel@2 10 * version 2.1 of the License, or (at your option) any later version.
nengel@2 11 *
nengel@2 12 * FFmpeg is distributed in the hope that it will be useful,
nengel@2 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nengel@2 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
nengel@2 15 * Lesser General Public License for more details.
nengel@2 16 *
nengel@2 17 * You should have received a copy of the GNU Lesser General Public
nengel@2 18 * License along with FFmpeg; if not, write to the Free Software
nengel@2 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
nengel@2 20 */
nengel@2 21
nengel@2 22 /**
nengel@2 23 * @file
nengel@2 24 * Context Adaptive Binary Arithmetic Coder.
nengel@2 25 */
nengel@2 26
nengel@2 27 #ifndef AVCODEC_CABAC_H
nengel@2 28 #define AVCODEC_CABAC_H
nengel@2 29
nengel@2 30 //#undef NDEBUG
nengel@2 31 #include <assert.h>
nengel@2 32 #include "libavutil/x86_cpu.h"
nengel@2 33 #include "libavutil/attributes.h"
nengel@2 34
nengel@2 35 #define CABAC_BITS 16
nengel@2 36 #define CABAC_MASK ((1<<CABAC_BITS)-1)
nengel@2 37 #define BRANCHLESS_CABAC_DECODER 1
nengel@2 38
nengel@2 39 typedef struct CABACContext{
nengel@2 40 int low;
nengel@2 41 int range;
nengel@2 42 int outstanding_count;
nengel@2 43 #ifdef STRICT_LIMITS
nengel@2 44 int symCount;
nengel@2 45 #endif
nengel@2 46 const uint8_t *bytestream_start;
nengel@2 47 const uint8_t *bytestream;
nengel@2 48 const uint8_t *bytestream_end;
nengel@2 49 uint8_t cabac_state[460];
nengel@2 50 }CABACContext;
nengel@2 51
nengel@2 52 extern uint8_t ff_h264_mlps_state[4*64];
nengel@2 53 extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS
nengel@2 54 extern uint8_t ff_h264_mps_state[2*64]; ///< transIdxMPS
nengel@2 55 extern uint8_t ff_h264_lps_state[2*64]; ///< transIdxLPS
nengel@2 56 extern const uint8_t ff_h264_norm_shift[512];
nengel@2 57
nengel@2 58 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
nengel@2 59 void ff_init_cabac_states(void);
nengel@2 60
nengel@2 61 static void refill(CABACContext *c){
nengel@2 62 #if CABAC_BITS == 16
nengel@2 63 c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
nengel@2 64 #else
nengel@2 65 c->low+= c->bytestream[0]<<1;
nengel@2 66 #endif
nengel@2 67 c->low -= CABAC_MASK;
nengel@2 68 c->bytestream+= CABAC_BITS/8;
nengel@2 69 }
nengel@2 70
nengel@2 71 static void refill2(CABACContext *c){
nengel@2 72 int i, x;
nengel@2 73
nengel@2 74 x= c->low ^ (c->low-1);
nengel@2 75 i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)];
nengel@2 76
nengel@2 77 x= -CABAC_MASK;
nengel@2 78
nengel@2 79 #if CABAC_BITS == 16
nengel@2 80 x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
nengel@2 81 #else
nengel@2 82 x+= c->bytestream[0]<<1;
nengel@2 83 #endif
nengel@2 84
nengel@2 85 c->low += x<<i;
nengel@2 86 c->bytestream+= CABAC_BITS/8;
nengel@2 87 }
nengel@2 88
nengel@2 89 static inline void renorm_cabac_decoder(CABACContext *c){
nengel@2 90 while(c->range < 0x100){
nengel@2 91 c->range+= c->range;
nengel@2 92 c->low+= c->low;
nengel@2 93 if(!(c->low & CABAC_MASK))
nengel@2 94 refill(c);
nengel@2 95 }
nengel@2 96 }
nengel@2 97
nengel@2 98 static inline void renorm_cabac_decoder_once(CABACContext *c){
nengel@2 99
nengel@2 100 int shift= (uint32_t)(c->range - 0x100)>>31;
nengel@2 101 c->range<<= shift;
nengel@2 102 c->low <<= shift;
nengel@2 103
nengel@2 104 if(!(c->low & CABAC_MASK))
nengel@2 105 refill(c);
nengel@2 106 }
nengel@2 107
nengel@2 108 static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){
nengel@2 109
nengel@2 110 int s = *state;
nengel@2 111 int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s];
nengel@2 112 int bit, lps_mask av_unused;
nengel@2 113
nengel@2 114 c->range -= RangeLPS;
nengel@2 115 #ifndef BRANCHLESS_CABAC_DECODER
nengel@2 116 if(c->low < (c->range<<(CABAC_BITS+1))){
nengel@2 117 bit= s&1;
nengel@2 118 *state= ff_h264_mps_state[s];
nengel@2 119 renorm_cabac_decoder_once(c);
nengel@2 120 }else{
nengel@2 121 bit= ff_h264_norm_shift[RangeLPS];
nengel@2 122 c->low -= (c->range<<(CABAC_BITS+1));
nengel@2 123 *state= ff_h264_lps_state[s];
nengel@2 124 c->range = RangeLPS<<bit;
nengel@2 125 c->low <<= bit;
nengel@2 126 bit= (s&1)^1;
nengel@2 127
nengel@2 128 if(!(c->low & CABAC_MASK)){
nengel@2 129 refill2(c);
nengel@2 130 }
nengel@2 131 }
nengel@2 132 #else /* BRANCHLESS_CABAC_DECODER */
nengel@2 133 lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31;
nengel@2 134
nengel@2 135 c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask;
nengel@2 136 c->range += (RangeLPS - c->range) & lps_mask;
nengel@2 137
nengel@2 138 s^=lps_mask;
nengel@2 139 *state= (ff_h264_mlps_state+128)[s];
nengel@2 140 bit= s&1;
nengel@2 141
nengel@2 142 lps_mask= ff_h264_norm_shift[c->range];
nengel@2 143 c->range<<= lps_mask;
nengel@2 144 c->low <<= lps_mask;
nengel@2 145 if(!(c->low & CABAC_MASK))
nengel@2 146 refill2(c);
nengel@2 147 #endif /* BRANCHLESS_CABAC_DECODER */
nengel@2 148
nengel@2 149 return bit;
nengel@2 150 }
nengel@2 151
nengel@2 152 static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){
nengel@2 153 return get_cabac_inline(c, state);
nengel@2 154 }
nengel@2 155
nengel@2 156 static int av_unused get_cabac(CABACContext *c, uint8_t * const state){
nengel@2 157 return get_cabac_inline(c, state);
nengel@2 158 }
nengel@2 159
nengel@2 160 static int av_unused get_cabac_bypass(CABACContext *c){
nengel@2 161
nengel@2 162 int range;
nengel@2 163 c->low += c->low;
nengel@2 164
nengel@2 165 if(!(c->low & CABAC_MASK))
nengel@2 166 refill(c);
nengel@2 167
nengel@2 168 range= c->range<<(CABAC_BITS+1);
nengel@2 169 if(c->low < range){
nengel@2 170 return 0;
nengel@2 171 }else{
nengel@2 172 c->low -= range;
nengel@2 173 return 1;
nengel@2 174 }
nengel@2 175 }
nengel@2 176
nengel@2 177 static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){
nengel@2 178 int range, mask;
nengel@2 179 c->low += c->low;
nengel@2 180
nengel@2 181 if(!(c->low & CABAC_MASK))
nengel@2 182 refill(c);
nengel@2 183
nengel@2 184 range= c->range<<(CABAC_BITS+1);
nengel@2 185 c->low -= range;
nengel@2 186 mask= c->low >> 31;
nengel@2 187 range &= mask;
nengel@2 188 c->low += range;
nengel@2 189 return (val^mask)-mask;
nengel@2 190 }
nengel@2 191
nengel@2 192 /**
nengel@2 193 *
nengel@2 194 * @return the number of bytes read or 0 if no end
nengel@2 195 */
nengel@2 196 static int av_unused get_cabac_terminate(CABACContext *c){
nengel@2 197 c->range -= 2;
nengel@2 198 if(c->low < c->range<<(CABAC_BITS+1)){
nengel@2 199 renorm_cabac_decoder_once(c);
nengel@2 200 return 0;
nengel@2 201 }else{
nengel@2 202 return c->bytestream - c->bytestream_start;
nengel@2 203 }
nengel@2 204 }
nengel@2 205
nengel@2 206 #endif /* AVCODEC_CABAC_H */