1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Copyright (C) 2006 Aurelien Jacobs <aurel@gnuage.org> 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * This file is part of FFmpeg. 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 7cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 8cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 9cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 12cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 13cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14cabdff1aSopenharmony_ci * Lesser General Public License for more details. 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 17cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 18cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19cabdff1aSopenharmony_ci */ 20cabdff1aSopenharmony_ci 21cabdff1aSopenharmony_ci/** 22cabdff1aSopenharmony_ci * @file 23cabdff1aSopenharmony_ci * VP5 and VP6 compatible video decoder (common features) 24cabdff1aSopenharmony_ci */ 25cabdff1aSopenharmony_ci 26cabdff1aSopenharmony_ci#ifndef AVCODEC_VP56_H 27cabdff1aSopenharmony_ci#define AVCODEC_VP56_H 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h" 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci#include "avcodec.h" 32cabdff1aSopenharmony_ci#include "get_bits.h" 33cabdff1aSopenharmony_ci#include "hpeldsp.h" 34cabdff1aSopenharmony_ci#include "bytestream.h" 35cabdff1aSopenharmony_ci#include "h264chroma.h" 36cabdff1aSopenharmony_ci#include "videodsp.h" 37cabdff1aSopenharmony_ci#include "vp3dsp.h" 38cabdff1aSopenharmony_ci#include "vp56dsp.h" 39cabdff1aSopenharmony_ci 40cabdff1aSopenharmony_citypedef struct vp56_context VP56Context; 41cabdff1aSopenharmony_ci 42cabdff1aSopenharmony_citypedef enum { 43cabdff1aSopenharmony_ci VP56_FRAME_NONE =-1, 44cabdff1aSopenharmony_ci VP56_FRAME_CURRENT = 0, 45cabdff1aSopenharmony_ci VP56_FRAME_PREVIOUS = 1, 46cabdff1aSopenharmony_ci VP56_FRAME_GOLDEN = 2, 47cabdff1aSopenharmony_ci VP56_FRAME_GOLDEN2 = 3, 48cabdff1aSopenharmony_ci} VP56Frame; 49cabdff1aSopenharmony_ci 50cabdff1aSopenharmony_citypedef enum { 51cabdff1aSopenharmony_ci VP56_MB_INTER_NOVEC_PF = 0, /**< Inter MB, no vector, from previous frame */ 52cabdff1aSopenharmony_ci VP56_MB_INTRA = 1, /**< Intra MB */ 53cabdff1aSopenharmony_ci VP56_MB_INTER_DELTA_PF = 2, /**< Inter MB, above/left vector + delta, from previous frame */ 54cabdff1aSopenharmony_ci VP56_MB_INTER_V1_PF = 3, /**< Inter MB, first vector, from previous frame */ 55cabdff1aSopenharmony_ci VP56_MB_INTER_V2_PF = 4, /**< Inter MB, second vector, from previous frame */ 56cabdff1aSopenharmony_ci VP56_MB_INTER_NOVEC_GF = 5, /**< Inter MB, no vector, from golden frame */ 57cabdff1aSopenharmony_ci VP56_MB_INTER_DELTA_GF = 6, /**< Inter MB, above/left vector + delta, from golden frame */ 58cabdff1aSopenharmony_ci VP56_MB_INTER_4V = 7, /**< Inter MB, 4 vectors, from previous frame */ 59cabdff1aSopenharmony_ci VP56_MB_INTER_V1_GF = 8, /**< Inter MB, first vector, from golden frame */ 60cabdff1aSopenharmony_ci VP56_MB_INTER_V2_GF = 9, /**< Inter MB, second vector, from golden frame */ 61cabdff1aSopenharmony_ci} VP56mb; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_citypedef struct VP56Tree { 64cabdff1aSopenharmony_ci int8_t val; 65cabdff1aSopenharmony_ci int8_t prob_idx; 66cabdff1aSopenharmony_ci} VP56Tree; 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_citypedef struct VP56mv { 69cabdff1aSopenharmony_ci DECLARE_ALIGNED(4, int16_t, x); 70cabdff1aSopenharmony_ci int16_t y; 71cabdff1aSopenharmony_ci} VP56mv; 72cabdff1aSopenharmony_ci 73cabdff1aSopenharmony_ci#define VP56_SIZE_CHANGE 1 74cabdff1aSopenharmony_ci 75cabdff1aSopenharmony_citypedef void (*VP56ParseVectorAdjustment)(VP56Context *s, 76cabdff1aSopenharmony_ci VP56mv *vect); 77cabdff1aSopenharmony_citypedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src, 78cabdff1aSopenharmony_ci int offset1, int offset2, ptrdiff_t stride, 79cabdff1aSopenharmony_ci VP56mv mv, int mask, int select, int luma); 80cabdff1aSopenharmony_citypedef int (*VP56ParseCoeff)(VP56Context *s); 81cabdff1aSopenharmony_citypedef void (*VP56DefaultModelsInit)(VP56Context *s); 82cabdff1aSopenharmony_citypedef void (*VP56ParseVectorModels)(VP56Context *s); 83cabdff1aSopenharmony_citypedef int (*VP56ParseCoeffModels)(VP56Context *s); 84cabdff1aSopenharmony_citypedef int (*VP56ParseHeader)(VP56Context *s, const uint8_t *buf, 85cabdff1aSopenharmony_ci int buf_size); 86cabdff1aSopenharmony_ci 87cabdff1aSopenharmony_citypedef struct VP56RangeCoder { 88cabdff1aSopenharmony_ci int high; 89cabdff1aSopenharmony_ci int bits; /* stored negated (i.e. negative "bits" is a positive number of 90cabdff1aSopenharmony_ci bits left) in order to eliminate a negate in cache refilling */ 91cabdff1aSopenharmony_ci const uint8_t *buffer; 92cabdff1aSopenharmony_ci const uint8_t *end; 93cabdff1aSopenharmony_ci unsigned int code_word; 94cabdff1aSopenharmony_ci int end_reached; 95cabdff1aSopenharmony_ci} VP56RangeCoder; 96cabdff1aSopenharmony_ci 97cabdff1aSopenharmony_citypedef struct VP56RefDc { 98cabdff1aSopenharmony_ci uint8_t not_null_dc; 99cabdff1aSopenharmony_ci VP56Frame ref_frame; 100cabdff1aSopenharmony_ci int16_t dc_coeff; 101cabdff1aSopenharmony_ci} VP56RefDc; 102cabdff1aSopenharmony_ci 103cabdff1aSopenharmony_citypedef struct VP56Macroblock { 104cabdff1aSopenharmony_ci uint8_t type; 105cabdff1aSopenharmony_ci VP56mv mv; 106cabdff1aSopenharmony_ci} VP56Macroblock; 107cabdff1aSopenharmony_ci 108cabdff1aSopenharmony_citypedef struct VP56Model { 109cabdff1aSopenharmony_ci uint8_t coeff_reorder[64]; /* used in vp6 only */ 110cabdff1aSopenharmony_ci uint8_t coeff_index_to_pos[64]; /* used in vp6 only */ 111cabdff1aSopenharmony_ci uint8_t coeff_index_to_idct_selector[64]; /* used in vp6 only */ 112cabdff1aSopenharmony_ci uint8_t vector_sig[2]; /* delta sign */ 113cabdff1aSopenharmony_ci uint8_t vector_dct[2]; /* delta coding types */ 114cabdff1aSopenharmony_ci uint8_t vector_pdi[2][2]; /* predefined delta init */ 115cabdff1aSopenharmony_ci uint8_t vector_pdv[2][7]; /* predefined delta values */ 116cabdff1aSopenharmony_ci uint8_t vector_fdv[2][8]; /* 8 bit delta value definition */ 117cabdff1aSopenharmony_ci uint8_t coeff_dccv[2][11]; /* DC coeff value */ 118cabdff1aSopenharmony_ci uint8_t coeff_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */ 119cabdff1aSopenharmony_ci uint8_t coeff_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */ 120cabdff1aSopenharmony_ci uint8_t coeff_dcct[2][36][5]; /* DC coeff coding type */ 121cabdff1aSopenharmony_ci uint8_t coeff_runv[2][14]; /* run value (vp6 only) */ 122cabdff1aSopenharmony_ci uint8_t mb_type[3][10][10]; /* model for decoding MB type */ 123cabdff1aSopenharmony_ci uint8_t mb_types_stats[3][10][2];/* contextual, next MB type stats */ 124cabdff1aSopenharmony_ci} VP56Model; 125cabdff1aSopenharmony_ci 126cabdff1aSopenharmony_cistruct vp56_context { 127cabdff1aSopenharmony_ci AVCodecContext *avctx; 128cabdff1aSopenharmony_ci H264ChromaContext h264chroma; 129cabdff1aSopenharmony_ci HpelDSPContext hdsp; 130cabdff1aSopenharmony_ci VideoDSPContext vdsp; 131cabdff1aSopenharmony_ci VP3DSPContext vp3dsp; 132cabdff1aSopenharmony_ci VP56DSPContext vp56dsp; 133cabdff1aSopenharmony_ci uint8_t idct_scantable[64]; 134cabdff1aSopenharmony_ci AVFrame *frames[4]; 135cabdff1aSopenharmony_ci uint8_t *edge_emu_buffer_alloc; 136cabdff1aSopenharmony_ci uint8_t *edge_emu_buffer; 137cabdff1aSopenharmony_ci VP56RangeCoder c; 138cabdff1aSopenharmony_ci VP56RangeCoder cc; 139cabdff1aSopenharmony_ci VP56RangeCoder *ccp; 140cabdff1aSopenharmony_ci int sub_version; 141cabdff1aSopenharmony_ci 142cabdff1aSopenharmony_ci /* frame info */ 143cabdff1aSopenharmony_ci int golden_frame; 144cabdff1aSopenharmony_ci int plane_width[4]; 145cabdff1aSopenharmony_ci int plane_height[4]; 146cabdff1aSopenharmony_ci int mb_width; /* number of horizontal MB */ 147cabdff1aSopenharmony_ci int mb_height; /* number of vertical MB */ 148cabdff1aSopenharmony_ci int block_offset[6]; 149cabdff1aSopenharmony_ci 150cabdff1aSopenharmony_ci int quantizer; 151cabdff1aSopenharmony_ci uint16_t dequant_dc; 152cabdff1aSopenharmony_ci uint16_t dequant_ac; 153cabdff1aSopenharmony_ci 154cabdff1aSopenharmony_ci /* DC predictors management */ 155cabdff1aSopenharmony_ci VP56RefDc *above_blocks; 156cabdff1aSopenharmony_ci VP56RefDc left_block[4]; 157cabdff1aSopenharmony_ci int above_block_idx[6]; 158cabdff1aSopenharmony_ci int16_t prev_dc[3][3]; /* [plan][ref_frame] */ 159cabdff1aSopenharmony_ci 160cabdff1aSopenharmony_ci /* blocks / macroblock */ 161cabdff1aSopenharmony_ci VP56mb mb_type; 162cabdff1aSopenharmony_ci VP56Macroblock *macroblocks; 163cabdff1aSopenharmony_ci DECLARE_ALIGNED(16, int16_t, block_coeff)[6][64]; 164cabdff1aSopenharmony_ci int idct_selector[6]; 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci /* motion vectors */ 167cabdff1aSopenharmony_ci VP56mv mv[6]; /* vectors for each block in MB */ 168cabdff1aSopenharmony_ci VP56mv vector_candidate[2]; 169cabdff1aSopenharmony_ci int vector_candidate_pos; 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci /* filtering hints */ 172cabdff1aSopenharmony_ci int filter_header; /* used in vp6 only */ 173cabdff1aSopenharmony_ci int deblock_filtering; 174cabdff1aSopenharmony_ci int filter_selection; 175cabdff1aSopenharmony_ci int filter_mode; 176cabdff1aSopenharmony_ci int max_vector_length; 177cabdff1aSopenharmony_ci int sample_variance_threshold; 178cabdff1aSopenharmony_ci DECLARE_ALIGNED(8, int, bounding_values_array)[256]; 179cabdff1aSopenharmony_ci 180cabdff1aSopenharmony_ci uint8_t coeff_ctx[4][64]; /* used in vp5 only */ 181cabdff1aSopenharmony_ci uint8_t coeff_ctx_last[4]; /* used in vp5 only */ 182cabdff1aSopenharmony_ci 183cabdff1aSopenharmony_ci int has_alpha; 184cabdff1aSopenharmony_ci 185cabdff1aSopenharmony_ci /* upside-down flipping hints */ 186cabdff1aSopenharmony_ci int flip; /* are we flipping ? */ 187cabdff1aSopenharmony_ci int frbi; /* first row block index in MB */ 188cabdff1aSopenharmony_ci int srbi; /* second row block index in MB */ 189cabdff1aSopenharmony_ci ptrdiff_t stride[4]; /* stride for each plan */ 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci const uint8_t *vp56_coord_div; 192cabdff1aSopenharmony_ci VP56ParseVectorAdjustment parse_vector_adjustment; 193cabdff1aSopenharmony_ci VP56Filter filter; 194cabdff1aSopenharmony_ci VP56ParseCoeff parse_coeff; 195cabdff1aSopenharmony_ci VP56DefaultModelsInit default_models_init; 196cabdff1aSopenharmony_ci VP56ParseVectorModels parse_vector_models; 197cabdff1aSopenharmony_ci VP56ParseCoeffModels parse_coeff_models; 198cabdff1aSopenharmony_ci VP56ParseHeader parse_header; 199cabdff1aSopenharmony_ci 200cabdff1aSopenharmony_ci /* for "slice" parallelism between YUV and A */ 201cabdff1aSopenharmony_ci VP56Context *alpha_context; 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci VP56Model *modelp; 204cabdff1aSopenharmony_ci VP56Model model; 205cabdff1aSopenharmony_ci 206cabdff1aSopenharmony_ci /* huffman decoding */ 207cabdff1aSopenharmony_ci int use_huffman; 208cabdff1aSopenharmony_ci GetBitContext gb; 209cabdff1aSopenharmony_ci VLC dccv_vlc[2]; 210cabdff1aSopenharmony_ci VLC runv_vlc[2]; 211cabdff1aSopenharmony_ci VLC ract_vlc[2][3][6]; 212cabdff1aSopenharmony_ci unsigned int nb_null[2][2]; /* number of consecutive NULL DC/AC */ 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_ci int have_undamaged_frame; 215cabdff1aSopenharmony_ci int discard_frame; 216cabdff1aSopenharmony_ci}; 217cabdff1aSopenharmony_ci 218cabdff1aSopenharmony_ci 219cabdff1aSopenharmony_ci/** 220cabdff1aSopenharmony_ci * Initializes an VP56Context. Expects its caller to clean up 221cabdff1aSopenharmony_ci * in case of error. 222cabdff1aSopenharmony_ci */ 223cabdff1aSopenharmony_ciint ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s, 224cabdff1aSopenharmony_ci int flip, int has_alpha); 225cabdff1aSopenharmony_ciint ff_vp56_free_context(VP56Context *s); 226cabdff1aSopenharmony_civoid ff_vp56_init_dequant(VP56Context *s, int quantizer); 227cabdff1aSopenharmony_ciint ff_vp56_decode_frame(AVCodecContext *avctx, AVFrame *frame, 228cabdff1aSopenharmony_ci int *got_frame, AVPacket *avpkt); 229cabdff1aSopenharmony_ci 230cabdff1aSopenharmony_ci 231cabdff1aSopenharmony_ci/** 232cabdff1aSopenharmony_ci * vp56 specific range coder implementation 233cabdff1aSopenharmony_ci */ 234cabdff1aSopenharmony_ci 235cabdff1aSopenharmony_ciextern const uint8_t ff_vp56_norm_shift[256]; 236cabdff1aSopenharmony_ciint ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size); 237cabdff1aSopenharmony_ci 238cabdff1aSopenharmony_ci/** 239cabdff1aSopenharmony_ci * vp5689 returns 1 if the end of the stream has been reached, 0 otherwise. 240cabdff1aSopenharmony_ci */ 241cabdff1aSopenharmony_cistatic av_always_inline int vpX_rac_is_end(VP56RangeCoder *c) 242cabdff1aSopenharmony_ci{ 243cabdff1aSopenharmony_ci if (c->end <= c->buffer && c->bits >= 0) 244cabdff1aSopenharmony_ci c->end_reached ++; 245cabdff1aSopenharmony_ci return c->end_reached > 10; 246cabdff1aSopenharmony_ci} 247cabdff1aSopenharmony_ci 248cabdff1aSopenharmony_cistatic av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c) 249cabdff1aSopenharmony_ci{ 250cabdff1aSopenharmony_ci int shift = ff_vp56_norm_shift[c->high]; 251cabdff1aSopenharmony_ci int bits = c->bits; 252cabdff1aSopenharmony_ci unsigned int code_word = c->code_word; 253cabdff1aSopenharmony_ci 254cabdff1aSopenharmony_ci c->high <<= shift; 255cabdff1aSopenharmony_ci code_word <<= shift; 256cabdff1aSopenharmony_ci bits += shift; 257cabdff1aSopenharmony_ci if(bits >= 0 && c->buffer < c->end) { 258cabdff1aSopenharmony_ci code_word |= bytestream_get_be16(&c->buffer) << bits; 259cabdff1aSopenharmony_ci bits -= 16; 260cabdff1aSopenharmony_ci } 261cabdff1aSopenharmony_ci c->bits = bits; 262cabdff1aSopenharmony_ci return code_word; 263cabdff1aSopenharmony_ci} 264cabdff1aSopenharmony_ci 265cabdff1aSopenharmony_ci#if ARCH_ARM 266cabdff1aSopenharmony_ci#include "arm/vp56_arith.h" 267cabdff1aSopenharmony_ci#elif ARCH_X86 268cabdff1aSopenharmony_ci#include "x86/vp56_arith.h" 269cabdff1aSopenharmony_ci#endif 270cabdff1aSopenharmony_ci 271cabdff1aSopenharmony_ci#ifndef vp56_rac_get_prob 272cabdff1aSopenharmony_ci#define vp56_rac_get_prob vp56_rac_get_prob 273cabdff1aSopenharmony_cistatic av_always_inline int vp56_rac_get_prob(VP56RangeCoder *c, uint8_t prob) 274cabdff1aSopenharmony_ci{ 275cabdff1aSopenharmony_ci unsigned int code_word = vp56_rac_renorm(c); 276cabdff1aSopenharmony_ci unsigned int low = 1 + (((c->high - 1) * prob) >> 8); 277cabdff1aSopenharmony_ci unsigned int low_shift = low << 16; 278cabdff1aSopenharmony_ci int bit = code_word >= low_shift; 279cabdff1aSopenharmony_ci 280cabdff1aSopenharmony_ci c->high = bit ? c->high - low : low; 281cabdff1aSopenharmony_ci c->code_word = bit ? code_word - low_shift : code_word; 282cabdff1aSopenharmony_ci 283cabdff1aSopenharmony_ci return bit; 284cabdff1aSopenharmony_ci} 285cabdff1aSopenharmony_ci#endif 286cabdff1aSopenharmony_ci 287cabdff1aSopenharmony_ci#ifndef vp56_rac_get_prob_branchy 288cabdff1aSopenharmony_ci// branchy variant, to be used where there's a branch based on the bit decoded 289cabdff1aSopenharmony_cistatic av_always_inline int vp56_rac_get_prob_branchy(VP56RangeCoder *c, int prob) 290cabdff1aSopenharmony_ci{ 291cabdff1aSopenharmony_ci unsigned long code_word = vp56_rac_renorm(c); 292cabdff1aSopenharmony_ci unsigned low = 1 + (((c->high - 1) * prob) >> 8); 293cabdff1aSopenharmony_ci unsigned low_shift = low << 16; 294cabdff1aSopenharmony_ci 295cabdff1aSopenharmony_ci if (code_word >= low_shift) { 296cabdff1aSopenharmony_ci c->high -= low; 297cabdff1aSopenharmony_ci c->code_word = code_word - low_shift; 298cabdff1aSopenharmony_ci return 1; 299cabdff1aSopenharmony_ci } 300cabdff1aSopenharmony_ci 301cabdff1aSopenharmony_ci c->high = low; 302cabdff1aSopenharmony_ci c->code_word = code_word; 303cabdff1aSopenharmony_ci return 0; 304cabdff1aSopenharmony_ci} 305cabdff1aSopenharmony_ci#endif 306cabdff1aSopenharmony_ci 307cabdff1aSopenharmony_cistatic av_always_inline int vp56_rac_get(VP56RangeCoder *c) 308cabdff1aSopenharmony_ci{ 309cabdff1aSopenharmony_ci unsigned int code_word = vp56_rac_renorm(c); 310cabdff1aSopenharmony_ci /* equiprobable */ 311cabdff1aSopenharmony_ci int low = (c->high + 1) >> 1; 312cabdff1aSopenharmony_ci unsigned int low_shift = low << 16; 313cabdff1aSopenharmony_ci int bit = code_word >= low_shift; 314cabdff1aSopenharmony_ci if (bit) { 315cabdff1aSopenharmony_ci c->high -= low; 316cabdff1aSopenharmony_ci code_word -= low_shift; 317cabdff1aSopenharmony_ci } else { 318cabdff1aSopenharmony_ci c->high = low; 319cabdff1aSopenharmony_ci } 320cabdff1aSopenharmony_ci 321cabdff1aSopenharmony_ci c->code_word = code_word; 322cabdff1aSopenharmony_ci return bit; 323cabdff1aSopenharmony_ci} 324cabdff1aSopenharmony_ci 325cabdff1aSopenharmony_ci// rounding is different than vp56_rac_get, is vp56_rac_get wrong? 326cabdff1aSopenharmony_cistatic av_always_inline int vp8_rac_get(VP56RangeCoder *c) 327cabdff1aSopenharmony_ci{ 328cabdff1aSopenharmony_ci return vp56_rac_get_prob(c, 128); 329cabdff1aSopenharmony_ci} 330cabdff1aSopenharmony_ci 331cabdff1aSopenharmony_cistatic int vp56_rac_gets(VP56RangeCoder *c, int bits) 332cabdff1aSopenharmony_ci{ 333cabdff1aSopenharmony_ci int value = 0; 334cabdff1aSopenharmony_ci 335cabdff1aSopenharmony_ci while (bits--) { 336cabdff1aSopenharmony_ci value = (value << 1) | vp56_rac_get(c); 337cabdff1aSopenharmony_ci } 338cabdff1aSopenharmony_ci 339cabdff1aSopenharmony_ci return value; 340cabdff1aSopenharmony_ci} 341cabdff1aSopenharmony_ci 342cabdff1aSopenharmony_cistatic int vp8_rac_get_uint(VP56RangeCoder *c, int bits) 343cabdff1aSopenharmony_ci{ 344cabdff1aSopenharmony_ci int value = 0; 345cabdff1aSopenharmony_ci 346cabdff1aSopenharmony_ci while (bits--) { 347cabdff1aSopenharmony_ci value = (value << 1) | vp8_rac_get(c); 348cabdff1aSopenharmony_ci } 349cabdff1aSopenharmony_ci 350cabdff1aSopenharmony_ci return value; 351cabdff1aSopenharmony_ci} 352cabdff1aSopenharmony_ci 353cabdff1aSopenharmony_ci// fixme: add 1 bit to all the calls to this? 354cabdff1aSopenharmony_cistatic av_unused int vp8_rac_get_sint(VP56RangeCoder *c, int bits) 355cabdff1aSopenharmony_ci{ 356cabdff1aSopenharmony_ci int v; 357cabdff1aSopenharmony_ci 358cabdff1aSopenharmony_ci if (!vp8_rac_get(c)) 359cabdff1aSopenharmony_ci return 0; 360cabdff1aSopenharmony_ci 361cabdff1aSopenharmony_ci v = vp8_rac_get_uint(c, bits); 362cabdff1aSopenharmony_ci 363cabdff1aSopenharmony_ci if (vp8_rac_get(c)) 364cabdff1aSopenharmony_ci v = -v; 365cabdff1aSopenharmony_ci 366cabdff1aSopenharmony_ci return v; 367cabdff1aSopenharmony_ci} 368cabdff1aSopenharmony_ci 369cabdff1aSopenharmony_ci// P(7) 370cabdff1aSopenharmony_cistatic av_unused int vp56_rac_gets_nn(VP56RangeCoder *c, int bits) 371cabdff1aSopenharmony_ci{ 372cabdff1aSopenharmony_ci int v = vp56_rac_gets(c, 7) << 1; 373cabdff1aSopenharmony_ci return v + !v; 374cabdff1aSopenharmony_ci} 375cabdff1aSopenharmony_ci 376cabdff1aSopenharmony_cistatic av_unused int vp8_rac_get_nn(VP56RangeCoder *c) 377cabdff1aSopenharmony_ci{ 378cabdff1aSopenharmony_ci int v = vp8_rac_get_uint(c, 7) << 1; 379cabdff1aSopenharmony_ci return v + !v; 380cabdff1aSopenharmony_ci} 381cabdff1aSopenharmony_ci 382cabdff1aSopenharmony_cistatic av_always_inline 383cabdff1aSopenharmony_ciint vp56_rac_get_tree(VP56RangeCoder *c, 384cabdff1aSopenharmony_ci const VP56Tree *tree, 385cabdff1aSopenharmony_ci const uint8_t *probs) 386cabdff1aSopenharmony_ci{ 387cabdff1aSopenharmony_ci while (tree->val > 0) { 388cabdff1aSopenharmony_ci if (vp56_rac_get_prob_branchy(c, probs[tree->prob_idx])) 389cabdff1aSopenharmony_ci tree += tree->val; 390cabdff1aSopenharmony_ci else 391cabdff1aSopenharmony_ci tree++; 392cabdff1aSopenharmony_ci } 393cabdff1aSopenharmony_ci return -tree->val; 394cabdff1aSopenharmony_ci} 395cabdff1aSopenharmony_ci 396cabdff1aSopenharmony_ci// how probabilities are associated with decisions is different I think 397cabdff1aSopenharmony_ci// well, the new scheme fits in the old but this way has one fewer branches per decision 398cabdff1aSopenharmony_cistatic av_always_inline int vp8_rac_get_tree(VP56RangeCoder *c, const int8_t (*tree)[2], 399cabdff1aSopenharmony_ci const uint8_t *probs) 400cabdff1aSopenharmony_ci{ 401cabdff1aSopenharmony_ci int i = 0; 402cabdff1aSopenharmony_ci 403cabdff1aSopenharmony_ci do { 404cabdff1aSopenharmony_ci i = tree[i][vp56_rac_get_prob(c, probs[i])]; 405cabdff1aSopenharmony_ci } while (i > 0); 406cabdff1aSopenharmony_ci 407cabdff1aSopenharmony_ci return -i; 408cabdff1aSopenharmony_ci} 409cabdff1aSopenharmony_ci 410cabdff1aSopenharmony_ci// DCTextra 411cabdff1aSopenharmony_cistatic av_always_inline int vp8_rac_get_coeff(VP56RangeCoder *c, const uint8_t *prob) 412cabdff1aSopenharmony_ci{ 413cabdff1aSopenharmony_ci int v = 0; 414cabdff1aSopenharmony_ci 415cabdff1aSopenharmony_ci do { 416cabdff1aSopenharmony_ci v = (v<<1) + vp56_rac_get_prob(c, *prob++); 417cabdff1aSopenharmony_ci } while (*prob); 418cabdff1aSopenharmony_ci 419cabdff1aSopenharmony_ci return v; 420cabdff1aSopenharmony_ci} 421cabdff1aSopenharmony_ci 422cabdff1aSopenharmony_ci#endif /* AVCODEC_VP56_H */ 423