1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder 3cabdff1aSopenharmony_ci * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> 4cabdff1aSopenharmony_ci * 5cabdff1aSopenharmony_ci * This file is part of FFmpeg. 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 8cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 9cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 10cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 13cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 14cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15cabdff1aSopenharmony_ci * Lesser General Public License for more details. 16cabdff1aSopenharmony_ci * 17cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 18cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 19cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20cabdff1aSopenharmony_ci */ 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci/** 23cabdff1aSopenharmony_ci * @file 24cabdff1aSopenharmony_ci * Context Adaptive Binary Arithmetic Coder inline functions 25cabdff1aSopenharmony_ci */ 26cabdff1aSopenharmony_ci 27cabdff1aSopenharmony_ci#ifndef AVCODEC_CABAC_FUNCTIONS_H 28cabdff1aSopenharmony_ci#define AVCODEC_CABAC_FUNCTIONS_H 29cabdff1aSopenharmony_ci 30cabdff1aSopenharmony_ci#include <stddef.h> 31cabdff1aSopenharmony_ci#include <stdint.h> 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 34cabdff1aSopenharmony_ci#include "libavutil/intmath.h" 35cabdff1aSopenharmony_ci#include "cabac.h" 36cabdff1aSopenharmony_ci#include "config.h" 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_ci#ifndef UNCHECKED_BITSTREAM_READER 39cabdff1aSopenharmony_ci#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER 40cabdff1aSopenharmony_ci#endif 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_ci#if ARCH_AARCH64 43cabdff1aSopenharmony_ci# include "aarch64/cabac.h" 44cabdff1aSopenharmony_ci#endif 45cabdff1aSopenharmony_ci#if ARCH_ARM 46cabdff1aSopenharmony_ci# include "arm/cabac.h" 47cabdff1aSopenharmony_ci#endif 48cabdff1aSopenharmony_ci#if ARCH_X86 49cabdff1aSopenharmony_ci# include "x86/cabac.h" 50cabdff1aSopenharmony_ci#endif 51cabdff1aSopenharmony_ci#if ARCH_MIPS 52cabdff1aSopenharmony_ci# include "mips/cabac.h" 53cabdff1aSopenharmony_ci#endif 54cabdff1aSopenharmony_ci#if ARCH_LOONGARCH64 55cabdff1aSopenharmony_ci# include "loongarch/cabac.h" 56cabdff1aSopenharmony_ci#endif 57cabdff1aSopenharmony_ci 58cabdff1aSopenharmony_cistatic const uint8_t * const ff_h264_norm_shift = ff_h264_cabac_tables + H264_NORM_SHIFT_OFFSET; 59cabdff1aSopenharmony_cistatic const uint8_t * const ff_h264_lps_range = ff_h264_cabac_tables + H264_LPS_RANGE_OFFSET; 60cabdff1aSopenharmony_cistatic const uint8_t * const ff_h264_mlps_state = ff_h264_cabac_tables + H264_MLPS_STATE_OFFSET; 61cabdff1aSopenharmony_cistatic const uint8_t * const ff_h264_last_coeff_flag_offset_8x8 = ff_h264_cabac_tables + H264_LAST_COEFF_FLAG_OFFSET_8x8_OFFSET; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_ci#if !defined(get_cabac_bypass) || !defined(get_cabac_terminate) 64cabdff1aSopenharmony_cistatic void refill(CABACContext *c){ 65cabdff1aSopenharmony_ci#if CABAC_BITS == 16 66cabdff1aSopenharmony_ci c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); 67cabdff1aSopenharmony_ci#else 68cabdff1aSopenharmony_ci c->low+= c->bytestream[0]<<1; 69cabdff1aSopenharmony_ci#endif 70cabdff1aSopenharmony_ci c->low -= CABAC_MASK; 71cabdff1aSopenharmony_ci#if !UNCHECKED_BITSTREAM_READER 72cabdff1aSopenharmony_ci if (c->bytestream < c->bytestream_end) 73cabdff1aSopenharmony_ci#endif 74cabdff1aSopenharmony_ci c->bytestream += CABAC_BITS / 8; 75cabdff1aSopenharmony_ci} 76cabdff1aSopenharmony_ci#endif 77cabdff1aSopenharmony_ci 78cabdff1aSopenharmony_ci#ifndef get_cabac_terminate 79cabdff1aSopenharmony_cistatic inline void renorm_cabac_decoder_once(CABACContext *c){ 80cabdff1aSopenharmony_ci int shift= (uint32_t)(c->range - 0x100)>>31; 81cabdff1aSopenharmony_ci c->range<<= shift; 82cabdff1aSopenharmony_ci c->low <<= shift; 83cabdff1aSopenharmony_ci if(!(c->low & CABAC_MASK)) 84cabdff1aSopenharmony_ci refill(c); 85cabdff1aSopenharmony_ci} 86cabdff1aSopenharmony_ci#endif 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ci#ifndef get_cabac_inline 89cabdff1aSopenharmony_cistatic void refill2(CABACContext *c){ 90cabdff1aSopenharmony_ci int i; 91cabdff1aSopenharmony_ci unsigned x; 92cabdff1aSopenharmony_ci#if !HAVE_FAST_CLZ 93cabdff1aSopenharmony_ci x= c->low ^ (c->low-1); 94cabdff1aSopenharmony_ci i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; 95cabdff1aSopenharmony_ci#else 96cabdff1aSopenharmony_ci i = ff_ctz(c->low) - CABAC_BITS; 97cabdff1aSopenharmony_ci#endif 98cabdff1aSopenharmony_ci 99cabdff1aSopenharmony_ci x= -CABAC_MASK; 100cabdff1aSopenharmony_ci 101cabdff1aSopenharmony_ci#if CABAC_BITS == 16 102cabdff1aSopenharmony_ci x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); 103cabdff1aSopenharmony_ci#else 104cabdff1aSopenharmony_ci x+= c->bytestream[0]<<1; 105cabdff1aSopenharmony_ci#endif 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci c->low += x<<i; 108cabdff1aSopenharmony_ci#if !UNCHECKED_BITSTREAM_READER 109cabdff1aSopenharmony_ci if (c->bytestream < c->bytestream_end) 110cabdff1aSopenharmony_ci#endif 111cabdff1aSopenharmony_ci c->bytestream += CABAC_BITS/8; 112cabdff1aSopenharmony_ci} 113cabdff1aSopenharmony_ci#endif 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci#ifndef get_cabac_inline 116cabdff1aSopenharmony_cistatic av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ 117cabdff1aSopenharmony_ci int s = *state; 118cabdff1aSopenharmony_ci int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; 119cabdff1aSopenharmony_ci int bit, lps_mask; 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci c->range -= RangeLPS; 122cabdff1aSopenharmony_ci lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_ci c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; 125cabdff1aSopenharmony_ci c->range += (RangeLPS - c->range) & lps_mask; 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_ci s^=lps_mask; 128cabdff1aSopenharmony_ci *state= (ff_h264_mlps_state+128)[s]; 129cabdff1aSopenharmony_ci bit= s&1; 130cabdff1aSopenharmony_ci 131cabdff1aSopenharmony_ci lps_mask= ff_h264_norm_shift[c->range]; 132cabdff1aSopenharmony_ci c->range<<= lps_mask; 133cabdff1aSopenharmony_ci c->low <<= lps_mask; 134cabdff1aSopenharmony_ci if(!(c->low & CABAC_MASK)) 135cabdff1aSopenharmony_ci refill2(c); 136cabdff1aSopenharmony_ci return bit; 137cabdff1aSopenharmony_ci} 138cabdff1aSopenharmony_ci#endif 139cabdff1aSopenharmony_ci 140cabdff1aSopenharmony_cistatic int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ 141cabdff1aSopenharmony_ci return get_cabac_inline(c,state); 142cabdff1aSopenharmony_ci} 143cabdff1aSopenharmony_ci 144cabdff1aSopenharmony_cistatic int av_unused get_cabac(CABACContext *c, uint8_t * const state){ 145cabdff1aSopenharmony_ci return get_cabac_inline(c,state); 146cabdff1aSopenharmony_ci} 147cabdff1aSopenharmony_ci 148cabdff1aSopenharmony_ci#ifndef get_cabac_bypass 149cabdff1aSopenharmony_cistatic int av_unused get_cabac_bypass(CABACContext *c){ 150cabdff1aSopenharmony_ci int range; 151cabdff1aSopenharmony_ci c->low += c->low; 152cabdff1aSopenharmony_ci 153cabdff1aSopenharmony_ci if(!(c->low & CABAC_MASK)) 154cabdff1aSopenharmony_ci refill(c); 155cabdff1aSopenharmony_ci 156cabdff1aSopenharmony_ci range= c->range<<(CABAC_BITS+1); 157cabdff1aSopenharmony_ci if(c->low < range){ 158cabdff1aSopenharmony_ci return 0; 159cabdff1aSopenharmony_ci }else{ 160cabdff1aSopenharmony_ci c->low -= range; 161cabdff1aSopenharmony_ci return 1; 162cabdff1aSopenharmony_ci } 163cabdff1aSopenharmony_ci} 164cabdff1aSopenharmony_ci#endif 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci#ifndef get_cabac_bypass_sign 167cabdff1aSopenharmony_cistatic av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ 168cabdff1aSopenharmony_ci int range, mask; 169cabdff1aSopenharmony_ci c->low += c->low; 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci if(!(c->low & CABAC_MASK)) 172cabdff1aSopenharmony_ci refill(c); 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_ci range= c->range<<(CABAC_BITS+1); 175cabdff1aSopenharmony_ci c->low -= range; 176cabdff1aSopenharmony_ci mask= c->low >> 31; 177cabdff1aSopenharmony_ci range &= mask; 178cabdff1aSopenharmony_ci c->low += range; 179cabdff1aSopenharmony_ci return (val^mask)-mask; 180cabdff1aSopenharmony_ci} 181cabdff1aSopenharmony_ci#endif 182cabdff1aSopenharmony_ci 183cabdff1aSopenharmony_ci/** 184cabdff1aSopenharmony_ci * @return the number of bytes read or 0 if no end 185cabdff1aSopenharmony_ci */ 186cabdff1aSopenharmony_ci#ifndef get_cabac_terminate 187cabdff1aSopenharmony_cistatic int av_unused get_cabac_terminate(CABACContext *c){ 188cabdff1aSopenharmony_ci c->range -= 2; 189cabdff1aSopenharmony_ci if(c->low < c->range<<(CABAC_BITS+1)){ 190cabdff1aSopenharmony_ci renorm_cabac_decoder_once(c); 191cabdff1aSopenharmony_ci return 0; 192cabdff1aSopenharmony_ci }else{ 193cabdff1aSopenharmony_ci return c->bytestream - c->bytestream_start; 194cabdff1aSopenharmony_ci } 195cabdff1aSopenharmony_ci} 196cabdff1aSopenharmony_ci#endif 197cabdff1aSopenharmony_ci 198cabdff1aSopenharmony_ci/** 199cabdff1aSopenharmony_ci * Skip @p n bytes and reset the decoder. 200cabdff1aSopenharmony_ci * @return the address of the first skipped byte or NULL if there's less than @p n bytes left 201cabdff1aSopenharmony_ci */ 202cabdff1aSopenharmony_ci#ifndef skip_bytes 203cabdff1aSopenharmony_cistatic av_unused const uint8_t* skip_bytes(CABACContext *c, int n) { 204cabdff1aSopenharmony_ci const uint8_t *ptr = c->bytestream; 205cabdff1aSopenharmony_ci 206cabdff1aSopenharmony_ci if (c->low & 0x1) 207cabdff1aSopenharmony_ci ptr--; 208cabdff1aSopenharmony_ci#if CABAC_BITS == 16 209cabdff1aSopenharmony_ci if (c->low & 0x1FF) 210cabdff1aSopenharmony_ci ptr--; 211cabdff1aSopenharmony_ci#endif 212cabdff1aSopenharmony_ci if ((int) (c->bytestream_end - ptr) < n) 213cabdff1aSopenharmony_ci return NULL; 214cabdff1aSopenharmony_ci if (ff_init_cabac_decoder(c, ptr + n, c->bytestream_end - ptr - n) < 0) 215cabdff1aSopenharmony_ci return NULL; 216cabdff1aSopenharmony_ci 217cabdff1aSopenharmony_ci return ptr; 218cabdff1aSopenharmony_ci} 219cabdff1aSopenharmony_ci#endif 220cabdff1aSopenharmony_ci 221cabdff1aSopenharmony_ci#endif /* AVCODEC_CABAC_FUNCTIONS_H */ 222