1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (C) 2007 Marco Gerards <marco@gnu.org> 3cabdff1aSopenharmony_ci * Copyright (C) 2009 David Conrad 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 * Arithmetic decoder for Dirac 25cabdff1aSopenharmony_ci * @author Marco Gerards <marco@gnu.org> 26cabdff1aSopenharmony_ci */ 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci#ifndef AVCODEC_DIRAC_ARITH_H 29cabdff1aSopenharmony_ci#define AVCODEC_DIRAC_ARITH_H 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#include "libavutil/x86/asm.h" 32cabdff1aSopenharmony_ci#include "bytestream.h" 33cabdff1aSopenharmony_ci#include "get_bits.h" 34cabdff1aSopenharmony_ci 35cabdff1aSopenharmony_cienum dirac_arith_contexts { 36cabdff1aSopenharmony_ci CTX_ZPZN_F1, 37cabdff1aSopenharmony_ci CTX_ZPNN_F1, 38cabdff1aSopenharmony_ci CTX_NPZN_F1, 39cabdff1aSopenharmony_ci CTX_NPNN_F1, 40cabdff1aSopenharmony_ci CTX_ZP_F2, 41cabdff1aSopenharmony_ci CTX_ZP_F3, 42cabdff1aSopenharmony_ci CTX_ZP_F4, 43cabdff1aSopenharmony_ci CTX_ZP_F5, 44cabdff1aSopenharmony_ci CTX_ZP_F6, 45cabdff1aSopenharmony_ci CTX_NP_F2, 46cabdff1aSopenharmony_ci CTX_NP_F3, 47cabdff1aSopenharmony_ci CTX_NP_F4, 48cabdff1aSopenharmony_ci CTX_NP_F5, 49cabdff1aSopenharmony_ci CTX_NP_F6, 50cabdff1aSopenharmony_ci CTX_COEFF_DATA, 51cabdff1aSopenharmony_ci CTX_SIGN_NEG, 52cabdff1aSopenharmony_ci CTX_SIGN_ZERO, 53cabdff1aSopenharmony_ci CTX_SIGN_POS, 54cabdff1aSopenharmony_ci CTX_ZERO_BLOCK, 55cabdff1aSopenharmony_ci CTX_DELTA_Q_F, 56cabdff1aSopenharmony_ci CTX_DELTA_Q_DATA, 57cabdff1aSopenharmony_ci CTX_DELTA_Q_SIGN, 58cabdff1aSopenharmony_ci 59cabdff1aSopenharmony_ci DIRAC_CTX_COUNT 60cabdff1aSopenharmony_ci}; 61cabdff1aSopenharmony_ci 62cabdff1aSopenharmony_ci// Dirac resets the arith decoder between decoding various types of data, 63cabdff1aSopenharmony_ci// so many contexts are never used simultaneously. Thus, we can reduce 64cabdff1aSopenharmony_ci// the number of contexts needed by reusing them. 65cabdff1aSopenharmony_ci#define CTX_SB_F1 CTX_ZP_F5 66cabdff1aSopenharmony_ci#define CTX_SB_DATA 0 67cabdff1aSopenharmony_ci#define CTX_PMODE_REF1 0 68cabdff1aSopenharmony_ci#define CTX_PMODE_REF2 1 69cabdff1aSopenharmony_ci#define CTX_GLOBAL_BLOCK 2 70cabdff1aSopenharmony_ci#define CTX_MV_F1 CTX_ZP_F2 71cabdff1aSopenharmony_ci#define CTX_MV_DATA 0 72cabdff1aSopenharmony_ci#define CTX_DC_F1 CTX_ZP_F5 73cabdff1aSopenharmony_ci#define CTX_DC_DATA 0 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_citypedef struct { 76cabdff1aSopenharmony_ci unsigned low; 77cabdff1aSopenharmony_ci uint16_t range; 78cabdff1aSopenharmony_ci int16_t counter; 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_ci const uint8_t *bytestream; 81cabdff1aSopenharmony_ci const uint8_t *bytestream_end; 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci uint16_t contexts[DIRAC_CTX_COUNT]; 84cabdff1aSopenharmony_ci int error; 85cabdff1aSopenharmony_ci int overread; 86cabdff1aSopenharmony_ci} DiracArith; 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ciextern const uint8_t ff_dirac_next_ctx[DIRAC_CTX_COUNT]; 89cabdff1aSopenharmony_ciextern int16_t ff_dirac_prob_branchless[256][2]; 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_cistatic inline void renorm(DiracArith *c) 92cabdff1aSopenharmony_ci{ 93cabdff1aSopenharmony_ci#if HAVE_FAST_CLZ 94cabdff1aSopenharmony_ci int shift = 14 - av_log2_16bit(c->range-1) + ((c->range-1)>>15); 95cabdff1aSopenharmony_ci 96cabdff1aSopenharmony_ci c->low <<= shift; 97cabdff1aSopenharmony_ci c->range <<= shift; 98cabdff1aSopenharmony_ci c->counter += shift; 99cabdff1aSopenharmony_ci#else 100cabdff1aSopenharmony_ci while (c->range <= 0x4000) { 101cabdff1aSopenharmony_ci c->low <<= 1; 102cabdff1aSopenharmony_ci c->range <<= 1; 103cabdff1aSopenharmony_ci c->counter++; 104cabdff1aSopenharmony_ci } 105cabdff1aSopenharmony_ci#endif 106cabdff1aSopenharmony_ci} 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_cistatic inline void refill(DiracArith *c) 109cabdff1aSopenharmony_ci{ 110cabdff1aSopenharmony_ci int counter = c->counter; 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci if (counter >= 0) { 113cabdff1aSopenharmony_ci int new = bytestream_get_be16(&c->bytestream); 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci // the spec defines overread bits to be 1, and streams rely on this 116cabdff1aSopenharmony_ci if (c->bytestream > c->bytestream_end) { 117cabdff1aSopenharmony_ci new |= 0xff; 118cabdff1aSopenharmony_ci if (c->bytestream > c->bytestream_end+1) 119cabdff1aSopenharmony_ci new |= 0xff00; 120cabdff1aSopenharmony_ci 121cabdff1aSopenharmony_ci c->bytestream = c->bytestream_end; 122cabdff1aSopenharmony_ci c->overread ++; 123cabdff1aSopenharmony_ci if (c->overread > 4) 124cabdff1aSopenharmony_ci c->error = AVERROR_INVALIDDATA; 125cabdff1aSopenharmony_ci } 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_ci c->low += new << counter; 128cabdff1aSopenharmony_ci counter -= 16; 129cabdff1aSopenharmony_ci } 130cabdff1aSopenharmony_ci c->counter = counter; 131cabdff1aSopenharmony_ci} 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_cistatic inline int dirac_get_arith_bit(DiracArith *c, int ctx) 134cabdff1aSopenharmony_ci{ 135cabdff1aSopenharmony_ci int prob_zero = c->contexts[ctx]; 136cabdff1aSopenharmony_ci int range_times_prob, bit; 137cabdff1aSopenharmony_ci unsigned low = c->low; 138cabdff1aSopenharmony_ci int range = c->range; 139cabdff1aSopenharmony_ci 140cabdff1aSopenharmony_ci range_times_prob = (c->range * prob_zero) >> 16; 141cabdff1aSopenharmony_ci 142cabdff1aSopenharmony_ci#if ARCH_X86 && HAVE_FAST_CMOV && HAVE_INLINE_ASM && HAVE_6REGS 143cabdff1aSopenharmony_ci low -= range_times_prob << 16; 144cabdff1aSopenharmony_ci range -= range_times_prob; 145cabdff1aSopenharmony_ci bit = 0; 146cabdff1aSopenharmony_ci __asm__( 147cabdff1aSopenharmony_ci "cmpl %5, %4 \n\t" 148cabdff1aSopenharmony_ci "setae %b0 \n\t" 149cabdff1aSopenharmony_ci "cmovb %3, %2 \n\t" 150cabdff1aSopenharmony_ci "cmovb %5, %1 \n\t" 151cabdff1aSopenharmony_ci : "+q"(bit), "+r"(range), "+r"(low) 152cabdff1aSopenharmony_ci : "r"(c->low), "r"(c->low>>16), 153cabdff1aSopenharmony_ci "r"(range_times_prob) 154cabdff1aSopenharmony_ci ); 155cabdff1aSopenharmony_ci#else 156cabdff1aSopenharmony_ci bit = (low >> 16) >= range_times_prob; 157cabdff1aSopenharmony_ci if (bit) { 158cabdff1aSopenharmony_ci low -= range_times_prob << 16; 159cabdff1aSopenharmony_ci range -= range_times_prob; 160cabdff1aSopenharmony_ci } else { 161cabdff1aSopenharmony_ci range = range_times_prob; 162cabdff1aSopenharmony_ci } 163cabdff1aSopenharmony_ci#endif 164cabdff1aSopenharmony_ci 165cabdff1aSopenharmony_ci c->contexts[ctx] += ff_dirac_prob_branchless[prob_zero>>8][bit]; 166cabdff1aSopenharmony_ci c->low = low; 167cabdff1aSopenharmony_ci c->range = range; 168cabdff1aSopenharmony_ci 169cabdff1aSopenharmony_ci renorm(c); 170cabdff1aSopenharmony_ci refill(c); 171cabdff1aSopenharmony_ci return bit; 172cabdff1aSopenharmony_ci} 173cabdff1aSopenharmony_ci 174cabdff1aSopenharmony_cistatic inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_ctx) 175cabdff1aSopenharmony_ci{ 176cabdff1aSopenharmony_ci int ret = 1; 177cabdff1aSopenharmony_ci while (!dirac_get_arith_bit(c, follow_ctx)) { 178cabdff1aSopenharmony_ci if (ret >= 0x40000000) { 179cabdff1aSopenharmony_ci av_log(NULL, AV_LOG_ERROR, "dirac_get_arith_uint overflow\n"); 180cabdff1aSopenharmony_ci c->error = AVERROR_INVALIDDATA; 181cabdff1aSopenharmony_ci return -1; 182cabdff1aSopenharmony_ci } 183cabdff1aSopenharmony_ci ret <<= 1; 184cabdff1aSopenharmony_ci ret += dirac_get_arith_bit(c, data_ctx); 185cabdff1aSopenharmony_ci follow_ctx = ff_dirac_next_ctx[follow_ctx]; 186cabdff1aSopenharmony_ci } 187cabdff1aSopenharmony_ci return ret-1; 188cabdff1aSopenharmony_ci} 189cabdff1aSopenharmony_ci 190cabdff1aSopenharmony_cistatic inline int dirac_get_arith_int(DiracArith *c, int follow_ctx, int data_ctx) 191cabdff1aSopenharmony_ci{ 192cabdff1aSopenharmony_ci int ret = dirac_get_arith_uint(c, follow_ctx, data_ctx); 193cabdff1aSopenharmony_ci if (ret && dirac_get_arith_bit(c, data_ctx+1)) 194cabdff1aSopenharmony_ci ret = -ret; 195cabdff1aSopenharmony_ci return ret; 196cabdff1aSopenharmony_ci} 197cabdff1aSopenharmony_ci 198cabdff1aSopenharmony_civoid ff_dirac_init_arith_tables(void); 199cabdff1aSopenharmony_civoid ff_dirac_init_arith_decoder(DiracArith *c, GetBitContext *gb, int length); 200cabdff1aSopenharmony_ci 201cabdff1aSopenharmony_ci#endif /* AVCODEC_DIRAC_ARITH_H */ 202