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