X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=common%2Fcabac.h;h=fc02dfd508006156dc4db0b2ce797a3d7beea142;hb=75992107adcc8317ba2888e3957a7d56f16b5cd4;hp=a8dadf4eae7b6e3e76752fdf5ec776323a372f9b;hpb=faec300a71cdb64e1bd27d393de51d2e3d1f5992;p=x264 diff --git a/common/cabac.h b/common/cabac.h index a8dadf4e..fc02dfd5 100644 --- a/common/cabac.h +++ b/common/cabac.h @@ -1,10 +1,10 @@ /***************************************************************************** - * cabac.h: h264 encoder library + * cabac.h: arithmetic coder ***************************************************************************** - * Copyright (C) 2003 Laurent Aimar - * $Id: cabac.h,v 1.1 2004/06/03 19:27:06 fenrir Exp $ + * Copyright (C) 2003-2015 x264 project * - * Authors: Laurent Aimar + * Authors: Loren Merritt + * Laurent Aimar * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,51 +18,101 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. + * + * This program is also available under a commercial proprietary license. + * For more information, contact us at licensing@x264.com. *****************************************************************************/ -#ifndef _CABAC_H -#define _CABAC_H 1 +#ifndef X264_CABAC_H +#define X264_CABAC_H typedef struct { - /* context */ - uint8_t state[460]; - /* state */ int i_low; int i_range; /* bit stream */ - int i_bits_outstanding; - int f8_bits_encoded; // only if using x264_cabac_size_decision() - bs_t *s; + int i_queue; //stored with an offset of -8 for faster asm + int i_bytes_outstanding; + + uint8_t *p_start; + uint8_t *p; + uint8_t *p_end; + + /* aligned for memcpy_aligned starting here */ + ALIGNED_16( int f8_bits_encoded ); // only if using x264_cabac_size_decision() + + /* context */ + uint8_t state[1024]; + /* for 16-byte alignment */ + uint8_t padding[12]; } x264_cabac_t; -/* encoder/decoder: init the contexts given i_slice_type, the quantif and the model */ -void x264_cabac_context_init( x264_cabac_t *cb, int i_slice_type, int i_qp, int i_model ); - -/* decoder only: */ -void x264_cabac_decode_init ( x264_cabac_t *cb, bs_t *s ); -int x264_cabac_decode_decision( x264_cabac_t *cb, int i_ctx_idx ); -int x264_cabac_decode_bypass ( x264_cabac_t *cb ); -int x264_cabac_decode_terminal( x264_cabac_t *cb ); - -/* encoder only: */ -void x264_cabac_encode_init ( x264_cabac_t *cb, bs_t *s ); -void x264_cabac_encode_decision( x264_cabac_t *cb, int i_ctx_idx, int b ); -void x264_cabac_encode_bypass( x264_cabac_t *cb, int b ); -void x264_cabac_encode_terminal( x264_cabac_t *cb, int b ); -void x264_cabac_encode_flush( x264_cabac_t *cb ); -/* don't write the bitstream, just calculate cost: */ -void x264_cabac_size_decision( x264_cabac_t *cb, int i_ctx, int b ); -int x264_cabac_size_decision2( uint8_t *state, int b ); -int x264_cabac_size_decision_noup( uint8_t *state, int b ); - -static inline int x264_cabac_pos( x264_cabac_t *cb ) +extern const uint8_t x264_cabac_transition[128][2]; +extern const uint16_t x264_cabac_entropy[128]; + +/* init the contexts given i_slice_type, the quantif and the model */ +void x264_cabac_context_init( x264_t *h, x264_cabac_t *cb, int i_slice_type, int i_qp, int i_model ); + +void x264_cabac_encode_init_core( x264_cabac_t *cb ); +void x264_cabac_encode_init ( x264_cabac_t *cb, uint8_t *p_data, uint8_t *p_end ); +void x264_cabac_encode_decision_c( x264_cabac_t *cb, int i_ctx, int b ); +void x264_cabac_encode_decision_asm( x264_cabac_t *cb, int i_ctx, int b ); +void x264_cabac_encode_bypass_c( x264_cabac_t *cb, int b ); +void x264_cabac_encode_bypass_asm( x264_cabac_t *cb, int b ); +void x264_cabac_encode_terminal_c( x264_cabac_t *cb ); +void x264_cabac_encode_terminal_asm( x264_cabac_t *cb ); +void x264_cabac_encode_ue_bypass( x264_cabac_t *cb, int exp_bits, int val ); +void x264_cabac_encode_flush( x264_t *h, x264_cabac_t *cb ); + +#if HAVE_MMX +#define x264_cabac_encode_decision x264_cabac_encode_decision_asm +#define x264_cabac_encode_bypass x264_cabac_encode_bypass_asm +#define x264_cabac_encode_terminal x264_cabac_encode_terminal_asm +#elif defined(ARCH_AARCH64) +#define x264_cabac_encode_decision x264_cabac_encode_decision_asm +#define x264_cabac_encode_bypass x264_cabac_encode_bypass_asm +#define x264_cabac_encode_terminal x264_cabac_encode_terminal_asm +#else +#define x264_cabac_encode_decision x264_cabac_encode_decision_c +#define x264_cabac_encode_bypass x264_cabac_encode_bypass_c +#define x264_cabac_encode_terminal x264_cabac_encode_terminal_c +#endif +#define x264_cabac_encode_decision_noup x264_cabac_encode_decision + +static ALWAYS_INLINE int x264_cabac_pos( x264_cabac_t *cb ) +{ + return (cb->p - cb->p_start + cb->i_bytes_outstanding) * 8 + cb->i_queue; +} + +/* internal only. these don't write the bitstream, just calculate bit cost: */ + +static ALWAYS_INLINE void x264_cabac_size_decision( x264_cabac_t *cb, long i_ctx, long b ) +{ + int i_state = cb->state[i_ctx]; + cb->state[i_ctx] = x264_cabac_transition[i_state][b]; + cb->f8_bits_encoded += x264_cabac_entropy[i_state^b]; +} + +static ALWAYS_INLINE int x264_cabac_size_decision2( uint8_t *state, long b ) +{ + int i_state = *state; + *state = x264_cabac_transition[i_state][b]; + return x264_cabac_entropy[i_state^b]; +} + +static ALWAYS_INLINE void x264_cabac_size_decision_noup( x264_cabac_t *cb, long i_ctx, long b ) +{ + int i_state = cb->state[i_ctx]; + cb->f8_bits_encoded += x264_cabac_entropy[i_state^b]; +} + +static ALWAYS_INLINE int x264_cabac_size_decision_noup2( uint8_t *state, long b ) { - return bs_pos( cb->s ) + cb->i_bits_outstanding; + return x264_cabac_entropy[*state^b]; } #endif