1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * Bink video decoder 3cabdff1aSopenharmony_ci * Copyright (c) 2009 Konstantin Shishkov 4cabdff1aSopenharmony_ci * Copyright (C) 2011 Peter Ross <pross@xvid.org> 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * This file is part of FFmpeg. 7cabdff1aSopenharmony_ci * 8cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 9cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 10cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 11cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 14cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 15cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16cabdff1aSopenharmony_ci * Lesser General Public License for more details. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 19cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 20cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21cabdff1aSopenharmony_ci */ 22cabdff1aSopenharmony_ci 23cabdff1aSopenharmony_ci#include "libavutil/attributes.h" 24cabdff1aSopenharmony_ci#include "libavutil/imgutils.h" 25cabdff1aSopenharmony_ci#include "libavutil/internal.h" 26cabdff1aSopenharmony_ci#include "libavutil/mem_internal.h" 27cabdff1aSopenharmony_ci#include "libavutil/thread.h" 28cabdff1aSopenharmony_ci 29cabdff1aSopenharmony_ci#define BITSTREAM_READER_LE 30cabdff1aSopenharmony_ci#include "avcodec.h" 31cabdff1aSopenharmony_ci#include "binkdata.h" 32cabdff1aSopenharmony_ci#include "binkdsp.h" 33cabdff1aSopenharmony_ci#include "blockdsp.h" 34cabdff1aSopenharmony_ci#include "codec_internal.h" 35cabdff1aSopenharmony_ci#include "get_bits.h" 36cabdff1aSopenharmony_ci#include "hpeldsp.h" 37cabdff1aSopenharmony_ci#include "internal.h" 38cabdff1aSopenharmony_ci#include "mathops.h" 39cabdff1aSopenharmony_ci 40cabdff1aSopenharmony_ci#define BINK_FLAG_ALPHA 0x00100000 41cabdff1aSopenharmony_ci#define BINK_FLAG_GRAY 0x00020000 42cabdff1aSopenharmony_ci 43cabdff1aSopenharmony_cistatic VLC bink_trees[16]; 44cabdff1aSopenharmony_ci 45cabdff1aSopenharmony_ci/** 46cabdff1aSopenharmony_ci * IDs for different data types used in old version of Bink video codec 47cabdff1aSopenharmony_ci */ 48cabdff1aSopenharmony_cienum OldSources { 49cabdff1aSopenharmony_ci BINKB_SRC_BLOCK_TYPES = 0, ///< 8x8 block types 50cabdff1aSopenharmony_ci BINKB_SRC_COLORS, ///< pixel values used for different block types 51cabdff1aSopenharmony_ci BINKB_SRC_PATTERN, ///< 8-bit values for 2-colour pattern fill 52cabdff1aSopenharmony_ci BINKB_SRC_X_OFF, ///< X components of motion value 53cabdff1aSopenharmony_ci BINKB_SRC_Y_OFF, ///< Y components of motion value 54cabdff1aSopenharmony_ci BINKB_SRC_INTRA_DC, ///< DC values for intrablocks with DCT 55cabdff1aSopenharmony_ci BINKB_SRC_INTER_DC, ///< DC values for interblocks with DCT 56cabdff1aSopenharmony_ci BINKB_SRC_INTRA_Q, ///< quantizer values for intrablocks with DCT 57cabdff1aSopenharmony_ci BINKB_SRC_INTER_Q, ///< quantizer values for interblocks with DCT 58cabdff1aSopenharmony_ci BINKB_SRC_INTER_COEFS, ///< number of coefficients for residue blocks 59cabdff1aSopenharmony_ci 60cabdff1aSopenharmony_ci BINKB_NB_SRC 61cabdff1aSopenharmony_ci}; 62cabdff1aSopenharmony_ci 63cabdff1aSopenharmony_cistatic const int binkb_bundle_sizes[BINKB_NB_SRC] = { 64cabdff1aSopenharmony_ci 4, 8, 8, 5, 5, 11, 11, 4, 4, 7 65cabdff1aSopenharmony_ci}; 66cabdff1aSopenharmony_ci 67cabdff1aSopenharmony_cistatic const int binkb_bundle_signed[BINKB_NB_SRC] = { 68cabdff1aSopenharmony_ci 0, 0, 0, 1, 1, 0, 1, 0, 0, 0 69cabdff1aSopenharmony_ci}; 70cabdff1aSopenharmony_ci 71cabdff1aSopenharmony_cistatic int32_t binkb_intra_quant[16][64]; 72cabdff1aSopenharmony_cistatic int32_t binkb_inter_quant[16][64]; 73cabdff1aSopenharmony_ci 74cabdff1aSopenharmony_ci/** 75cabdff1aSopenharmony_ci * IDs for different data types used in Bink video codec 76cabdff1aSopenharmony_ci */ 77cabdff1aSopenharmony_cienum Sources { 78cabdff1aSopenharmony_ci BINK_SRC_BLOCK_TYPES = 0, ///< 8x8 block types 79cabdff1aSopenharmony_ci BINK_SRC_SUB_BLOCK_TYPES, ///< 16x16 block types (a subset of 8x8 block types) 80cabdff1aSopenharmony_ci BINK_SRC_COLORS, ///< pixel values used for different block types 81cabdff1aSopenharmony_ci BINK_SRC_PATTERN, ///< 8-bit values for 2-colour pattern fill 82cabdff1aSopenharmony_ci BINK_SRC_X_OFF, ///< X components of motion value 83cabdff1aSopenharmony_ci BINK_SRC_Y_OFF, ///< Y components of motion value 84cabdff1aSopenharmony_ci BINK_SRC_INTRA_DC, ///< DC values for intrablocks with DCT 85cabdff1aSopenharmony_ci BINK_SRC_INTER_DC, ///< DC values for interblocks with DCT 86cabdff1aSopenharmony_ci BINK_SRC_RUN, ///< run lengths for special fill block 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ci BINK_NB_SRC 89cabdff1aSopenharmony_ci}; 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci/** 92cabdff1aSopenharmony_ci * data needed to decode 4-bit Huffman-coded value 93cabdff1aSopenharmony_ci */ 94cabdff1aSopenharmony_citypedef struct Tree { 95cabdff1aSopenharmony_ci int vlc_num; ///< tree number (in bink_trees[]) 96cabdff1aSopenharmony_ci uint8_t syms[16]; ///< leaf value to symbol mapping 97cabdff1aSopenharmony_ci} Tree; 98cabdff1aSopenharmony_ci 99cabdff1aSopenharmony_ci#define GET_HUFF(gb, tree) (tree).syms[get_vlc2(gb, bink_trees[(tree).vlc_num].table,\ 100cabdff1aSopenharmony_ci bink_trees[(tree).vlc_num].bits, 1)] 101cabdff1aSopenharmony_ci 102cabdff1aSopenharmony_ci/** 103cabdff1aSopenharmony_ci * data structure used for decoding single Bink data type 104cabdff1aSopenharmony_ci */ 105cabdff1aSopenharmony_citypedef struct Bundle { 106cabdff1aSopenharmony_ci int len; ///< length of number of entries to decode (in bits) 107cabdff1aSopenharmony_ci Tree tree; ///< Huffman tree-related data 108cabdff1aSopenharmony_ci uint8_t *data; ///< buffer for decoded symbols 109cabdff1aSopenharmony_ci uint8_t *data_end; ///< buffer end 110cabdff1aSopenharmony_ci uint8_t *cur_dec; ///< pointer to the not yet decoded part of the buffer 111cabdff1aSopenharmony_ci uint8_t *cur_ptr; ///< pointer to the data that is not read from buffer yet 112cabdff1aSopenharmony_ci} Bundle; 113cabdff1aSopenharmony_ci 114cabdff1aSopenharmony_ci/* 115cabdff1aSopenharmony_ci * Decoder context 116cabdff1aSopenharmony_ci */ 117cabdff1aSopenharmony_citypedef struct BinkContext { 118cabdff1aSopenharmony_ci AVCodecContext *avctx; 119cabdff1aSopenharmony_ci BlockDSPContext bdsp; 120cabdff1aSopenharmony_ci op_pixels_func put_pixels_tab; 121cabdff1aSopenharmony_ci BinkDSPContext binkdsp; 122cabdff1aSopenharmony_ci AVFrame *last; 123cabdff1aSopenharmony_ci int version; ///< internal Bink file version 124cabdff1aSopenharmony_ci int has_alpha; 125cabdff1aSopenharmony_ci int swap_planes; 126cabdff1aSopenharmony_ci unsigned frame_num; 127cabdff1aSopenharmony_ci 128cabdff1aSopenharmony_ci Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types 129cabdff1aSopenharmony_ci Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type 130cabdff1aSopenharmony_ci int col_lastval; ///< value of last decoded high nibble in "colours" data type 131cabdff1aSopenharmony_ci} BinkContext; 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_ci/** 134cabdff1aSopenharmony_ci * Bink video block types 135cabdff1aSopenharmony_ci */ 136cabdff1aSopenharmony_cienum BlockTypes { 137cabdff1aSopenharmony_ci SKIP_BLOCK = 0, ///< skipped block 138cabdff1aSopenharmony_ci SCALED_BLOCK, ///< block has size 16x16 139cabdff1aSopenharmony_ci MOTION_BLOCK, ///< block is copied from previous frame with some offset 140cabdff1aSopenharmony_ci RUN_BLOCK, ///< block is composed from runs of colours with custom scan order 141cabdff1aSopenharmony_ci RESIDUE_BLOCK, ///< motion block with some difference added 142cabdff1aSopenharmony_ci INTRA_BLOCK, ///< intra DCT block 143cabdff1aSopenharmony_ci FILL_BLOCK, ///< block is filled with single colour 144cabdff1aSopenharmony_ci INTER_BLOCK, ///< motion block with DCT applied to the difference 145cabdff1aSopenharmony_ci PATTERN_BLOCK, ///< block is filled with two colours following custom pattern 146cabdff1aSopenharmony_ci RAW_BLOCK, ///< uncoded 8x8 block 147cabdff1aSopenharmony_ci}; 148cabdff1aSopenharmony_ci 149cabdff1aSopenharmony_ci/** 150cabdff1aSopenharmony_ci * Initialize length in all bundles. 151cabdff1aSopenharmony_ci * 152cabdff1aSopenharmony_ci * @param c decoder context 153cabdff1aSopenharmony_ci * @param width plane width 154cabdff1aSopenharmony_ci * @param bw plane width in 8x8 blocks 155cabdff1aSopenharmony_ci */ 156cabdff1aSopenharmony_cistatic void init_lengths(BinkContext *c, int width, int bw) 157cabdff1aSopenharmony_ci{ 158cabdff1aSopenharmony_ci width = FFALIGN(width, 8); 159cabdff1aSopenharmony_ci 160cabdff1aSopenharmony_ci c->bundle[BINK_SRC_BLOCK_TYPES].len = av_log2((width >> 3) + 511) + 1; 161cabdff1aSopenharmony_ci 162cabdff1aSopenharmony_ci c->bundle[BINK_SRC_SUB_BLOCK_TYPES].len = av_log2((width >> 4) + 511) + 1; 163cabdff1aSopenharmony_ci 164cabdff1aSopenharmony_ci c->bundle[BINK_SRC_COLORS].len = av_log2(bw*64 + 511) + 1; 165cabdff1aSopenharmony_ci 166cabdff1aSopenharmony_ci c->bundle[BINK_SRC_INTRA_DC].len = 167cabdff1aSopenharmony_ci c->bundle[BINK_SRC_INTER_DC].len = 168cabdff1aSopenharmony_ci c->bundle[BINK_SRC_X_OFF].len = 169cabdff1aSopenharmony_ci c->bundle[BINK_SRC_Y_OFF].len = av_log2((width >> 3) + 511) + 1; 170cabdff1aSopenharmony_ci 171cabdff1aSopenharmony_ci c->bundle[BINK_SRC_PATTERN].len = av_log2((bw << 3) + 511) + 1; 172cabdff1aSopenharmony_ci 173cabdff1aSopenharmony_ci c->bundle[BINK_SRC_RUN].len = av_log2(bw*48 + 511) + 1; 174cabdff1aSopenharmony_ci} 175cabdff1aSopenharmony_ci 176cabdff1aSopenharmony_ci/** 177cabdff1aSopenharmony_ci * Allocate memory for bundles. 178cabdff1aSopenharmony_ci * 179cabdff1aSopenharmony_ci * @param c decoder context 180cabdff1aSopenharmony_ci */ 181cabdff1aSopenharmony_cistatic av_cold int init_bundles(BinkContext *c) 182cabdff1aSopenharmony_ci{ 183cabdff1aSopenharmony_ci int bw, bh, blocks; 184cabdff1aSopenharmony_ci uint8_t *tmp; 185cabdff1aSopenharmony_ci int i; 186cabdff1aSopenharmony_ci 187cabdff1aSopenharmony_ci bw = (c->avctx->width + 7) >> 3; 188cabdff1aSopenharmony_ci bh = (c->avctx->height + 7) >> 3; 189cabdff1aSopenharmony_ci blocks = bw * bh; 190cabdff1aSopenharmony_ci 191cabdff1aSopenharmony_ci tmp = av_calloc(blocks, 64 * BINKB_NB_SRC); 192cabdff1aSopenharmony_ci if (!tmp) 193cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 194cabdff1aSopenharmony_ci for (i = 0; i < BINKB_NB_SRC; i++) { 195cabdff1aSopenharmony_ci c->bundle[i].data = tmp; 196cabdff1aSopenharmony_ci tmp += blocks * 64; 197cabdff1aSopenharmony_ci c->bundle[i].data_end = tmp; 198cabdff1aSopenharmony_ci } 199cabdff1aSopenharmony_ci 200cabdff1aSopenharmony_ci return 0; 201cabdff1aSopenharmony_ci} 202cabdff1aSopenharmony_ci 203cabdff1aSopenharmony_ci/** 204cabdff1aSopenharmony_ci * Free memory used by bundles. 205cabdff1aSopenharmony_ci * 206cabdff1aSopenharmony_ci * @param c decoder context 207cabdff1aSopenharmony_ci */ 208cabdff1aSopenharmony_cistatic av_cold void free_bundles(BinkContext *c) 209cabdff1aSopenharmony_ci{ 210cabdff1aSopenharmony_ci av_freep(&c->bundle[0].data); 211cabdff1aSopenharmony_ci} 212cabdff1aSopenharmony_ci 213cabdff1aSopenharmony_ci/** 214cabdff1aSopenharmony_ci * Merge two consequent lists of equal size depending on bits read. 215cabdff1aSopenharmony_ci * 216cabdff1aSopenharmony_ci * @param gb context for reading bits 217cabdff1aSopenharmony_ci * @param dst buffer where merged list will be written to 218cabdff1aSopenharmony_ci * @param src pointer to the head of the first list (the second lists starts at src+size) 219cabdff1aSopenharmony_ci * @param size input lists size 220cabdff1aSopenharmony_ci */ 221cabdff1aSopenharmony_cistatic void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size) 222cabdff1aSopenharmony_ci{ 223cabdff1aSopenharmony_ci uint8_t *src2 = src + size; 224cabdff1aSopenharmony_ci int size2 = size; 225cabdff1aSopenharmony_ci 226cabdff1aSopenharmony_ci do { 227cabdff1aSopenharmony_ci if (!get_bits1(gb)) { 228cabdff1aSopenharmony_ci *dst++ = *src++; 229cabdff1aSopenharmony_ci size--; 230cabdff1aSopenharmony_ci } else { 231cabdff1aSopenharmony_ci *dst++ = *src2++; 232cabdff1aSopenharmony_ci size2--; 233cabdff1aSopenharmony_ci } 234cabdff1aSopenharmony_ci } while (size && size2); 235cabdff1aSopenharmony_ci 236cabdff1aSopenharmony_ci while (size--) 237cabdff1aSopenharmony_ci *dst++ = *src++; 238cabdff1aSopenharmony_ci while (size2--) 239cabdff1aSopenharmony_ci *dst++ = *src2++; 240cabdff1aSopenharmony_ci} 241cabdff1aSopenharmony_ci 242cabdff1aSopenharmony_ci/** 243cabdff1aSopenharmony_ci * Read information about Huffman tree used to decode data. 244cabdff1aSopenharmony_ci * 245cabdff1aSopenharmony_ci * @param gb context for reading bits 246cabdff1aSopenharmony_ci * @param tree pointer for storing tree data 247cabdff1aSopenharmony_ci */ 248cabdff1aSopenharmony_cistatic int read_tree(GetBitContext *gb, Tree *tree) 249cabdff1aSopenharmony_ci{ 250cabdff1aSopenharmony_ci uint8_t tmp1[16] = { 0 }, tmp2[16], *in = tmp1, *out = tmp2; 251cabdff1aSopenharmony_ci int i, t, len; 252cabdff1aSopenharmony_ci 253cabdff1aSopenharmony_ci if (get_bits_left(gb) < 4) 254cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 255cabdff1aSopenharmony_ci 256cabdff1aSopenharmony_ci tree->vlc_num = get_bits(gb, 4); 257cabdff1aSopenharmony_ci if (!tree->vlc_num) { 258cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) 259cabdff1aSopenharmony_ci tree->syms[i] = i; 260cabdff1aSopenharmony_ci return 0; 261cabdff1aSopenharmony_ci } 262cabdff1aSopenharmony_ci if (get_bits1(gb)) { 263cabdff1aSopenharmony_ci len = get_bits(gb, 3); 264cabdff1aSopenharmony_ci for (i = 0; i <= len; i++) { 265cabdff1aSopenharmony_ci tree->syms[i] = get_bits(gb, 4); 266cabdff1aSopenharmony_ci tmp1[tree->syms[i]] = 1; 267cabdff1aSopenharmony_ci } 268cabdff1aSopenharmony_ci for (i = 0; i < 16 && len < 16 - 1; i++) 269cabdff1aSopenharmony_ci if (!tmp1[i]) 270cabdff1aSopenharmony_ci tree->syms[++len] = i; 271cabdff1aSopenharmony_ci } else { 272cabdff1aSopenharmony_ci len = get_bits(gb, 2); 273cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) 274cabdff1aSopenharmony_ci in[i] = i; 275cabdff1aSopenharmony_ci for (i = 0; i <= len; i++) { 276cabdff1aSopenharmony_ci int size = 1 << i; 277cabdff1aSopenharmony_ci for (t = 0; t < 16; t += size << 1) 278cabdff1aSopenharmony_ci merge(gb, out + t, in + t, size); 279cabdff1aSopenharmony_ci FFSWAP(uint8_t*, in, out); 280cabdff1aSopenharmony_ci } 281cabdff1aSopenharmony_ci memcpy(tree->syms, in, 16); 282cabdff1aSopenharmony_ci } 283cabdff1aSopenharmony_ci return 0; 284cabdff1aSopenharmony_ci} 285cabdff1aSopenharmony_ci 286cabdff1aSopenharmony_ci/** 287cabdff1aSopenharmony_ci * Prepare bundle for decoding data. 288cabdff1aSopenharmony_ci * 289cabdff1aSopenharmony_ci * @param gb context for reading bits 290cabdff1aSopenharmony_ci * @param c decoder context 291cabdff1aSopenharmony_ci * @param bundle_num number of the bundle to initialize 292cabdff1aSopenharmony_ci */ 293cabdff1aSopenharmony_cistatic int read_bundle(GetBitContext *gb, BinkContext *c, int bundle_num) 294cabdff1aSopenharmony_ci{ 295cabdff1aSopenharmony_ci int i; 296cabdff1aSopenharmony_ci 297cabdff1aSopenharmony_ci if (bundle_num == BINK_SRC_COLORS) { 298cabdff1aSopenharmony_ci for (i = 0; i < 16; i++) { 299cabdff1aSopenharmony_ci int ret = read_tree(gb, &c->col_high[i]); 300cabdff1aSopenharmony_ci if (ret < 0) 301cabdff1aSopenharmony_ci return ret; 302cabdff1aSopenharmony_ci } 303cabdff1aSopenharmony_ci c->col_lastval = 0; 304cabdff1aSopenharmony_ci } 305cabdff1aSopenharmony_ci if (bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC) { 306cabdff1aSopenharmony_ci int ret = read_tree(gb, &c->bundle[bundle_num].tree); 307cabdff1aSopenharmony_ci if (ret < 0) 308cabdff1aSopenharmony_ci return ret; 309cabdff1aSopenharmony_ci } 310cabdff1aSopenharmony_ci c->bundle[bundle_num].cur_dec = 311cabdff1aSopenharmony_ci c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data; 312cabdff1aSopenharmony_ci 313cabdff1aSopenharmony_ci return 0; 314cabdff1aSopenharmony_ci} 315cabdff1aSopenharmony_ci 316cabdff1aSopenharmony_ci/** 317cabdff1aSopenharmony_ci * common check before starting decoding bundle data 318cabdff1aSopenharmony_ci * 319cabdff1aSopenharmony_ci * @param gb context for reading bits 320cabdff1aSopenharmony_ci * @param b bundle 321cabdff1aSopenharmony_ci * @param t variable where number of elements to decode will be stored 322cabdff1aSopenharmony_ci */ 323cabdff1aSopenharmony_ci#define CHECK_READ_VAL(gb, b, t) \ 324cabdff1aSopenharmony_ci if (!b->cur_dec || (b->cur_dec > b->cur_ptr)) \ 325cabdff1aSopenharmony_ci return 0; \ 326cabdff1aSopenharmony_ci t = get_bits(gb, b->len); \ 327cabdff1aSopenharmony_ci if (!t) { \ 328cabdff1aSopenharmony_ci b->cur_dec = NULL; \ 329cabdff1aSopenharmony_ci return 0; \ 330cabdff1aSopenharmony_ci } \ 331cabdff1aSopenharmony_ci 332cabdff1aSopenharmony_cistatic int read_runs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 333cabdff1aSopenharmony_ci{ 334cabdff1aSopenharmony_ci int t, v; 335cabdff1aSopenharmony_ci const uint8_t *dec_end; 336cabdff1aSopenharmony_ci 337cabdff1aSopenharmony_ci CHECK_READ_VAL(gb, b, t); 338cabdff1aSopenharmony_ci dec_end = b->cur_dec + t; 339cabdff1aSopenharmony_ci if (dec_end > b->data_end) { 340cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Run value went out of bounds\n"); 341cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 342cabdff1aSopenharmony_ci } 343cabdff1aSopenharmony_ci if (get_bits_left(gb) < 1) 344cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 345cabdff1aSopenharmony_ci if (get_bits1(gb)) { 346cabdff1aSopenharmony_ci v = get_bits(gb, 4); 347cabdff1aSopenharmony_ci memset(b->cur_dec, v, t); 348cabdff1aSopenharmony_ci b->cur_dec += t; 349cabdff1aSopenharmony_ci } else { 350cabdff1aSopenharmony_ci while (b->cur_dec < dec_end) 351cabdff1aSopenharmony_ci *b->cur_dec++ = GET_HUFF(gb, b->tree); 352cabdff1aSopenharmony_ci } 353cabdff1aSopenharmony_ci return 0; 354cabdff1aSopenharmony_ci} 355cabdff1aSopenharmony_ci 356cabdff1aSopenharmony_cistatic int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 357cabdff1aSopenharmony_ci{ 358cabdff1aSopenharmony_ci int t, sign, v; 359cabdff1aSopenharmony_ci const uint8_t *dec_end; 360cabdff1aSopenharmony_ci 361cabdff1aSopenharmony_ci CHECK_READ_VAL(gb, b, t); 362cabdff1aSopenharmony_ci dec_end = b->cur_dec + t; 363cabdff1aSopenharmony_ci if (dec_end > b->data_end) { 364cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Too many motion values\n"); 365cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 366cabdff1aSopenharmony_ci } 367cabdff1aSopenharmony_ci if (get_bits_left(gb) < 1) 368cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 369cabdff1aSopenharmony_ci if (get_bits1(gb)) { 370cabdff1aSopenharmony_ci v = get_bits(gb, 4); 371cabdff1aSopenharmony_ci if (v) { 372cabdff1aSopenharmony_ci sign = -get_bits1(gb); 373cabdff1aSopenharmony_ci v = (v ^ sign) - sign; 374cabdff1aSopenharmony_ci } 375cabdff1aSopenharmony_ci memset(b->cur_dec, v, t); 376cabdff1aSopenharmony_ci b->cur_dec += t; 377cabdff1aSopenharmony_ci } else { 378cabdff1aSopenharmony_ci while (b->cur_dec < dec_end) { 379cabdff1aSopenharmony_ci v = GET_HUFF(gb, b->tree); 380cabdff1aSopenharmony_ci if (v) { 381cabdff1aSopenharmony_ci sign = -get_bits1(gb); 382cabdff1aSopenharmony_ci v = (v ^ sign) - sign; 383cabdff1aSopenharmony_ci } 384cabdff1aSopenharmony_ci *b->cur_dec++ = v; 385cabdff1aSopenharmony_ci } 386cabdff1aSopenharmony_ci } 387cabdff1aSopenharmony_ci return 0; 388cabdff1aSopenharmony_ci} 389cabdff1aSopenharmony_ci 390cabdff1aSopenharmony_cistatic const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 }; 391cabdff1aSopenharmony_ci 392cabdff1aSopenharmony_cistatic int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 393cabdff1aSopenharmony_ci{ 394cabdff1aSopenharmony_ci BinkContext * const c = avctx->priv_data; 395cabdff1aSopenharmony_ci int t, v; 396cabdff1aSopenharmony_ci int last = 0; 397cabdff1aSopenharmony_ci const uint8_t *dec_end; 398cabdff1aSopenharmony_ci 399cabdff1aSopenharmony_ci CHECK_READ_VAL(gb, b, t); 400cabdff1aSopenharmony_ci if (c->version == 'k') { 401cabdff1aSopenharmony_ci t ^= 0xBBu; 402cabdff1aSopenharmony_ci if (t == 0) { 403cabdff1aSopenharmony_ci b->cur_dec = NULL; 404cabdff1aSopenharmony_ci return 0; 405cabdff1aSopenharmony_ci } 406cabdff1aSopenharmony_ci } 407cabdff1aSopenharmony_ci dec_end = b->cur_dec + t; 408cabdff1aSopenharmony_ci if (dec_end > b->data_end) { 409cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Too many block type values\n"); 410cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 411cabdff1aSopenharmony_ci } 412cabdff1aSopenharmony_ci if (get_bits_left(gb) < 1) 413cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 414cabdff1aSopenharmony_ci if (get_bits1(gb)) { 415cabdff1aSopenharmony_ci v = get_bits(gb, 4); 416cabdff1aSopenharmony_ci memset(b->cur_dec, v, t); 417cabdff1aSopenharmony_ci b->cur_dec += t; 418cabdff1aSopenharmony_ci } else { 419cabdff1aSopenharmony_ci while (b->cur_dec < dec_end) { 420cabdff1aSopenharmony_ci v = GET_HUFF(gb, b->tree); 421cabdff1aSopenharmony_ci if (v < 12) { 422cabdff1aSopenharmony_ci last = v; 423cabdff1aSopenharmony_ci *b->cur_dec++ = v; 424cabdff1aSopenharmony_ci } else { 425cabdff1aSopenharmony_ci int run = bink_rlelens[v - 12]; 426cabdff1aSopenharmony_ci 427cabdff1aSopenharmony_ci if (dec_end - b->cur_dec < run) 428cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 429cabdff1aSopenharmony_ci memset(b->cur_dec, last, run); 430cabdff1aSopenharmony_ci b->cur_dec += run; 431cabdff1aSopenharmony_ci } 432cabdff1aSopenharmony_ci } 433cabdff1aSopenharmony_ci } 434cabdff1aSopenharmony_ci return 0; 435cabdff1aSopenharmony_ci} 436cabdff1aSopenharmony_ci 437cabdff1aSopenharmony_cistatic int read_patterns(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 438cabdff1aSopenharmony_ci{ 439cabdff1aSopenharmony_ci int t, v; 440cabdff1aSopenharmony_ci const uint8_t *dec_end; 441cabdff1aSopenharmony_ci 442cabdff1aSopenharmony_ci CHECK_READ_VAL(gb, b, t); 443cabdff1aSopenharmony_ci dec_end = b->cur_dec + t; 444cabdff1aSopenharmony_ci if (dec_end > b->data_end) { 445cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Too many pattern values\n"); 446cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 447cabdff1aSopenharmony_ci } 448cabdff1aSopenharmony_ci while (b->cur_dec < dec_end) { 449cabdff1aSopenharmony_ci if (get_bits_left(gb) < 2) 450cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 451cabdff1aSopenharmony_ci v = GET_HUFF(gb, b->tree); 452cabdff1aSopenharmony_ci v |= GET_HUFF(gb, b->tree) << 4; 453cabdff1aSopenharmony_ci *b->cur_dec++ = v; 454cabdff1aSopenharmony_ci } 455cabdff1aSopenharmony_ci 456cabdff1aSopenharmony_ci return 0; 457cabdff1aSopenharmony_ci} 458cabdff1aSopenharmony_ci 459cabdff1aSopenharmony_cistatic int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c) 460cabdff1aSopenharmony_ci{ 461cabdff1aSopenharmony_ci int t, sign, v; 462cabdff1aSopenharmony_ci const uint8_t *dec_end; 463cabdff1aSopenharmony_ci 464cabdff1aSopenharmony_ci CHECK_READ_VAL(gb, b, t); 465cabdff1aSopenharmony_ci dec_end = b->cur_dec + t; 466cabdff1aSopenharmony_ci if (dec_end > b->data_end) { 467cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_ERROR, "Too many color values\n"); 468cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 469cabdff1aSopenharmony_ci } 470cabdff1aSopenharmony_ci if (get_bits_left(gb) < 1) 471cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 472cabdff1aSopenharmony_ci if (get_bits1(gb)) { 473cabdff1aSopenharmony_ci c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); 474cabdff1aSopenharmony_ci v = GET_HUFF(gb, b->tree); 475cabdff1aSopenharmony_ci v = (c->col_lastval << 4) | v; 476cabdff1aSopenharmony_ci if (c->version < 'i') { 477cabdff1aSopenharmony_ci sign = ((int8_t) v) >> 7; 478cabdff1aSopenharmony_ci v = ((v & 0x7F) ^ sign) - sign; 479cabdff1aSopenharmony_ci v += 0x80; 480cabdff1aSopenharmony_ci } 481cabdff1aSopenharmony_ci memset(b->cur_dec, v, t); 482cabdff1aSopenharmony_ci b->cur_dec += t; 483cabdff1aSopenharmony_ci } else { 484cabdff1aSopenharmony_ci while (b->cur_dec < dec_end) { 485cabdff1aSopenharmony_ci if (get_bits_left(gb) < 2) 486cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 487cabdff1aSopenharmony_ci c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); 488cabdff1aSopenharmony_ci v = GET_HUFF(gb, b->tree); 489cabdff1aSopenharmony_ci v = (c->col_lastval << 4) | v; 490cabdff1aSopenharmony_ci if (c->version < 'i') { 491cabdff1aSopenharmony_ci sign = ((int8_t) v) >> 7; 492cabdff1aSopenharmony_ci v = ((v & 0x7F) ^ sign) - sign; 493cabdff1aSopenharmony_ci v += 0x80; 494cabdff1aSopenharmony_ci } 495cabdff1aSopenharmony_ci *b->cur_dec++ = v; 496cabdff1aSopenharmony_ci } 497cabdff1aSopenharmony_ci } 498cabdff1aSopenharmony_ci return 0; 499cabdff1aSopenharmony_ci} 500cabdff1aSopenharmony_ci 501cabdff1aSopenharmony_ci/** number of bits used to store first DC value in bundle */ 502cabdff1aSopenharmony_ci#define DC_START_BITS 11 503cabdff1aSopenharmony_ci 504cabdff1aSopenharmony_cistatic int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, 505cabdff1aSopenharmony_ci int start_bits, int has_sign) 506cabdff1aSopenharmony_ci{ 507cabdff1aSopenharmony_ci int i, j, len, len2, bsize, sign, v, v2; 508cabdff1aSopenharmony_ci int16_t *dst = (int16_t*)b->cur_dec; 509cabdff1aSopenharmony_ci int16_t *dst_end = (int16_t*)b->data_end; 510cabdff1aSopenharmony_ci 511cabdff1aSopenharmony_ci CHECK_READ_VAL(gb, b, len); 512cabdff1aSopenharmony_ci if (get_bits_left(gb) < start_bits - has_sign) 513cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 514cabdff1aSopenharmony_ci v = get_bits(gb, start_bits - has_sign); 515cabdff1aSopenharmony_ci if (v && has_sign) { 516cabdff1aSopenharmony_ci sign = -get_bits1(gb); 517cabdff1aSopenharmony_ci v = (v ^ sign) - sign; 518cabdff1aSopenharmony_ci } 519cabdff1aSopenharmony_ci if (dst_end - dst < 1) 520cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 521cabdff1aSopenharmony_ci *dst++ = v; 522cabdff1aSopenharmony_ci len--; 523cabdff1aSopenharmony_ci for (i = 0; i < len; i += 8) { 524cabdff1aSopenharmony_ci len2 = FFMIN(len - i, 8); 525cabdff1aSopenharmony_ci if (dst_end - dst < len2) 526cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 527cabdff1aSopenharmony_ci bsize = get_bits(gb, 4); 528cabdff1aSopenharmony_ci if (bsize) { 529cabdff1aSopenharmony_ci for (j = 0; j < len2; j++) { 530cabdff1aSopenharmony_ci v2 = get_bits(gb, bsize); 531cabdff1aSopenharmony_ci if (v2) { 532cabdff1aSopenharmony_ci sign = -get_bits1(gb); 533cabdff1aSopenharmony_ci v2 = (v2 ^ sign) - sign; 534cabdff1aSopenharmony_ci } 535cabdff1aSopenharmony_ci v += v2; 536cabdff1aSopenharmony_ci *dst++ = v; 537cabdff1aSopenharmony_ci if (v < -32768 || v > 32767) { 538cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "DC value went out of bounds: %d\n", v); 539cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 540cabdff1aSopenharmony_ci } 541cabdff1aSopenharmony_ci } 542cabdff1aSopenharmony_ci } else { 543cabdff1aSopenharmony_ci for (j = 0; j < len2; j++) 544cabdff1aSopenharmony_ci *dst++ = v; 545cabdff1aSopenharmony_ci } 546cabdff1aSopenharmony_ci } 547cabdff1aSopenharmony_ci 548cabdff1aSopenharmony_ci b->cur_dec = (uint8_t*)dst; 549cabdff1aSopenharmony_ci return 0; 550cabdff1aSopenharmony_ci} 551cabdff1aSopenharmony_ci 552cabdff1aSopenharmony_ci/** 553cabdff1aSopenharmony_ci * Retrieve next value from bundle. 554cabdff1aSopenharmony_ci * 555cabdff1aSopenharmony_ci * @param c decoder context 556cabdff1aSopenharmony_ci * @param bundle bundle number 557cabdff1aSopenharmony_ci */ 558cabdff1aSopenharmony_cistatic inline int get_value(BinkContext *c, int bundle) 559cabdff1aSopenharmony_ci{ 560cabdff1aSopenharmony_ci int ret; 561cabdff1aSopenharmony_ci 562cabdff1aSopenharmony_ci if (bundle < BINK_SRC_X_OFF || bundle == BINK_SRC_RUN) 563cabdff1aSopenharmony_ci return *c->bundle[bundle].cur_ptr++; 564cabdff1aSopenharmony_ci if (bundle == BINK_SRC_X_OFF || bundle == BINK_SRC_Y_OFF) 565cabdff1aSopenharmony_ci return (int8_t)*c->bundle[bundle].cur_ptr++; 566cabdff1aSopenharmony_ci ret = *(int16_t*)c->bundle[bundle].cur_ptr; 567cabdff1aSopenharmony_ci c->bundle[bundle].cur_ptr += 2; 568cabdff1aSopenharmony_ci return ret; 569cabdff1aSopenharmony_ci} 570cabdff1aSopenharmony_ci 571cabdff1aSopenharmony_cistatic av_cold void binkb_init_bundle(BinkContext *c, int bundle_num) 572cabdff1aSopenharmony_ci{ 573cabdff1aSopenharmony_ci c->bundle[bundle_num].cur_dec = 574cabdff1aSopenharmony_ci c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data; 575cabdff1aSopenharmony_ci c->bundle[bundle_num].len = 13; 576cabdff1aSopenharmony_ci} 577cabdff1aSopenharmony_ci 578cabdff1aSopenharmony_cistatic av_cold void binkb_init_bundles(BinkContext *c) 579cabdff1aSopenharmony_ci{ 580cabdff1aSopenharmony_ci int i; 581cabdff1aSopenharmony_ci for (i = 0; i < BINKB_NB_SRC; i++) 582cabdff1aSopenharmony_ci binkb_init_bundle(c, i); 583cabdff1aSopenharmony_ci} 584cabdff1aSopenharmony_ci 585cabdff1aSopenharmony_cistatic int binkb_read_bundle(BinkContext *c, GetBitContext *gb, int bundle_num) 586cabdff1aSopenharmony_ci{ 587cabdff1aSopenharmony_ci const int bits = binkb_bundle_sizes[bundle_num]; 588cabdff1aSopenharmony_ci const int mask = 1 << (bits - 1); 589cabdff1aSopenharmony_ci const int issigned = binkb_bundle_signed[bundle_num]; 590cabdff1aSopenharmony_ci Bundle *b = &c->bundle[bundle_num]; 591cabdff1aSopenharmony_ci int i, len; 592cabdff1aSopenharmony_ci 593cabdff1aSopenharmony_ci CHECK_READ_VAL(gb, b, len); 594cabdff1aSopenharmony_ci if (b->data_end - b->cur_dec < len * (1 + (bits > 8))) 595cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 596cabdff1aSopenharmony_ci if (bits <= 8) { 597cabdff1aSopenharmony_ci if (!issigned) { 598cabdff1aSopenharmony_ci for (i = 0; i < len; i++) 599cabdff1aSopenharmony_ci *b->cur_dec++ = get_bits(gb, bits); 600cabdff1aSopenharmony_ci } else { 601cabdff1aSopenharmony_ci for (i = 0; i < len; i++) 602cabdff1aSopenharmony_ci *b->cur_dec++ = get_bits(gb, bits) - mask; 603cabdff1aSopenharmony_ci } 604cabdff1aSopenharmony_ci } else { 605cabdff1aSopenharmony_ci int16_t *dst = (int16_t*)b->cur_dec; 606cabdff1aSopenharmony_ci 607cabdff1aSopenharmony_ci if (!issigned) { 608cabdff1aSopenharmony_ci for (i = 0; i < len; i++) 609cabdff1aSopenharmony_ci *dst++ = get_bits(gb, bits); 610cabdff1aSopenharmony_ci } else { 611cabdff1aSopenharmony_ci for (i = 0; i < len; i++) 612cabdff1aSopenharmony_ci *dst++ = get_bits(gb, bits) - mask; 613cabdff1aSopenharmony_ci } 614cabdff1aSopenharmony_ci b->cur_dec = (uint8_t*)dst; 615cabdff1aSopenharmony_ci } 616cabdff1aSopenharmony_ci return 0; 617cabdff1aSopenharmony_ci} 618cabdff1aSopenharmony_ci 619cabdff1aSopenharmony_cistatic inline int binkb_get_value(BinkContext *c, int bundle_num) 620cabdff1aSopenharmony_ci{ 621cabdff1aSopenharmony_ci int16_t ret; 622cabdff1aSopenharmony_ci const int bits = binkb_bundle_sizes[bundle_num]; 623cabdff1aSopenharmony_ci 624cabdff1aSopenharmony_ci if (bits <= 8) { 625cabdff1aSopenharmony_ci int val = *c->bundle[bundle_num].cur_ptr++; 626cabdff1aSopenharmony_ci return binkb_bundle_signed[bundle_num] ? (int8_t)val : val; 627cabdff1aSopenharmony_ci } 628cabdff1aSopenharmony_ci ret = *(int16_t*)c->bundle[bundle_num].cur_ptr; 629cabdff1aSopenharmony_ci c->bundle[bundle_num].cur_ptr += 2; 630cabdff1aSopenharmony_ci return ret; 631cabdff1aSopenharmony_ci} 632cabdff1aSopenharmony_ci 633cabdff1aSopenharmony_ci/** 634cabdff1aSopenharmony_ci * Read 8x8 block of DCT coefficients. 635cabdff1aSopenharmony_ci * 636cabdff1aSopenharmony_ci * @param gb context for reading bits 637cabdff1aSopenharmony_ci * @param block place for storing coefficients 638cabdff1aSopenharmony_ci * @param scan scan order table 639cabdff1aSopenharmony_ci * @param quant_matrices quantization matrices 640cabdff1aSopenharmony_ci * @return 0 for success, negative value in other cases 641cabdff1aSopenharmony_ci */ 642cabdff1aSopenharmony_cistatic int read_dct_coeffs(BinkContext *c, GetBitContext *gb, int32_t block[64], 643cabdff1aSopenharmony_ci const uint8_t *scan, int *coef_count_, 644cabdff1aSopenharmony_ci int coef_idx[64], int q) 645cabdff1aSopenharmony_ci{ 646cabdff1aSopenharmony_ci int coef_list[128]; 647cabdff1aSopenharmony_ci int mode_list[128]; 648cabdff1aSopenharmony_ci int i, t, bits, ccoef, mode, sign; 649cabdff1aSopenharmony_ci int list_start = 64, list_end = 64, list_pos; 650cabdff1aSopenharmony_ci int coef_count = 0; 651cabdff1aSopenharmony_ci int quant_idx; 652cabdff1aSopenharmony_ci 653cabdff1aSopenharmony_ci if (get_bits_left(gb) < 4) 654cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 655cabdff1aSopenharmony_ci 656cabdff1aSopenharmony_ci coef_list[list_end] = 4; mode_list[list_end++] = 0; 657cabdff1aSopenharmony_ci coef_list[list_end] = 24; mode_list[list_end++] = 0; 658cabdff1aSopenharmony_ci coef_list[list_end] = 44; mode_list[list_end++] = 0; 659cabdff1aSopenharmony_ci coef_list[list_end] = 1; mode_list[list_end++] = 3; 660cabdff1aSopenharmony_ci coef_list[list_end] = 2; mode_list[list_end++] = 3; 661cabdff1aSopenharmony_ci coef_list[list_end] = 3; mode_list[list_end++] = 3; 662cabdff1aSopenharmony_ci 663cabdff1aSopenharmony_ci for (bits = get_bits(gb, 4) - 1; bits >= 0; bits--) { 664cabdff1aSopenharmony_ci list_pos = list_start; 665cabdff1aSopenharmony_ci while (list_pos < list_end) { 666cabdff1aSopenharmony_ci if (!(mode_list[list_pos] | coef_list[list_pos]) || !get_bits1(gb)) { 667cabdff1aSopenharmony_ci list_pos++; 668cabdff1aSopenharmony_ci continue; 669cabdff1aSopenharmony_ci } 670cabdff1aSopenharmony_ci ccoef = coef_list[list_pos]; 671cabdff1aSopenharmony_ci mode = mode_list[list_pos]; 672cabdff1aSopenharmony_ci switch (mode) { 673cabdff1aSopenharmony_ci case 0: 674cabdff1aSopenharmony_ci coef_list[list_pos] = ccoef + 4; 675cabdff1aSopenharmony_ci mode_list[list_pos] = 1; 676cabdff1aSopenharmony_ci case 2: 677cabdff1aSopenharmony_ci if (mode == 2) { 678cabdff1aSopenharmony_ci coef_list[list_pos] = 0; 679cabdff1aSopenharmony_ci mode_list[list_pos++] = 0; 680cabdff1aSopenharmony_ci } 681cabdff1aSopenharmony_ci for (i = 0; i < 4; i++, ccoef++) { 682cabdff1aSopenharmony_ci if (get_bits1(gb)) { 683cabdff1aSopenharmony_ci coef_list[--list_start] = ccoef; 684cabdff1aSopenharmony_ci mode_list[ list_start] = 3; 685cabdff1aSopenharmony_ci } else { 686cabdff1aSopenharmony_ci if (!bits) { 687cabdff1aSopenharmony_ci t = 1 - (get_bits1(gb) << 1); 688cabdff1aSopenharmony_ci } else { 689cabdff1aSopenharmony_ci t = get_bits(gb, bits) | 1 << bits; 690cabdff1aSopenharmony_ci sign = -get_bits1(gb); 691cabdff1aSopenharmony_ci t = (t ^ sign) - sign; 692cabdff1aSopenharmony_ci } 693cabdff1aSopenharmony_ci block[scan[ccoef]] = t; 694cabdff1aSopenharmony_ci coef_idx[coef_count++] = ccoef; 695cabdff1aSopenharmony_ci } 696cabdff1aSopenharmony_ci } 697cabdff1aSopenharmony_ci break; 698cabdff1aSopenharmony_ci case 1: 699cabdff1aSopenharmony_ci mode_list[list_pos] = 2; 700cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) { 701cabdff1aSopenharmony_ci ccoef += 4; 702cabdff1aSopenharmony_ci coef_list[list_end] = ccoef; 703cabdff1aSopenharmony_ci mode_list[list_end++] = 2; 704cabdff1aSopenharmony_ci } 705cabdff1aSopenharmony_ci break; 706cabdff1aSopenharmony_ci case 3: 707cabdff1aSopenharmony_ci if (!bits) { 708cabdff1aSopenharmony_ci t = 1 - (get_bits1(gb) << 1); 709cabdff1aSopenharmony_ci } else { 710cabdff1aSopenharmony_ci t = get_bits(gb, bits) | 1 << bits; 711cabdff1aSopenharmony_ci sign = -get_bits1(gb); 712cabdff1aSopenharmony_ci t = (t ^ sign) - sign; 713cabdff1aSopenharmony_ci } 714cabdff1aSopenharmony_ci block[scan[ccoef]] = t; 715cabdff1aSopenharmony_ci coef_idx[coef_count++] = ccoef; 716cabdff1aSopenharmony_ci coef_list[list_pos] = 0; 717cabdff1aSopenharmony_ci mode_list[list_pos++] = 0; 718cabdff1aSopenharmony_ci break; 719cabdff1aSopenharmony_ci } 720cabdff1aSopenharmony_ci } 721cabdff1aSopenharmony_ci } 722cabdff1aSopenharmony_ci 723cabdff1aSopenharmony_ci if (q == -1) { 724cabdff1aSopenharmony_ci quant_idx = get_bits(gb, 4); 725cabdff1aSopenharmony_ci } else { 726cabdff1aSopenharmony_ci quant_idx = q; 727cabdff1aSopenharmony_ci if (quant_idx > 15U) { 728cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_ERROR, "quant_index %d out of range\n", quant_idx); 729cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 730cabdff1aSopenharmony_ci } 731cabdff1aSopenharmony_ci } 732cabdff1aSopenharmony_ci 733cabdff1aSopenharmony_ci *coef_count_ = coef_count; 734cabdff1aSopenharmony_ci 735cabdff1aSopenharmony_ci return quant_idx; 736cabdff1aSopenharmony_ci} 737cabdff1aSopenharmony_ci 738cabdff1aSopenharmony_cistatic void unquantize_dct_coeffs(int32_t block[64], const uint32_t quant[64], 739cabdff1aSopenharmony_ci int coef_count, int coef_idx[64], 740cabdff1aSopenharmony_ci const uint8_t *scan) 741cabdff1aSopenharmony_ci{ 742cabdff1aSopenharmony_ci int i; 743cabdff1aSopenharmony_ci block[0] = (int)(block[0] * quant[0]) >> 11; 744cabdff1aSopenharmony_ci for (i = 0; i < coef_count; i++) { 745cabdff1aSopenharmony_ci int idx = coef_idx[i]; 746cabdff1aSopenharmony_ci block[scan[idx]] = (int)(block[scan[idx]] * quant[idx]) >> 11; 747cabdff1aSopenharmony_ci } 748cabdff1aSopenharmony_ci} 749cabdff1aSopenharmony_ci 750cabdff1aSopenharmony_ci/** 751cabdff1aSopenharmony_ci * Read 8x8 block with residue after motion compensation. 752cabdff1aSopenharmony_ci * 753cabdff1aSopenharmony_ci * @param gb context for reading bits 754cabdff1aSopenharmony_ci * @param block place to store read data 755cabdff1aSopenharmony_ci * @param masks_count number of masks to decode 756cabdff1aSopenharmony_ci * @return 0 on success, negative value in other cases 757cabdff1aSopenharmony_ci */ 758cabdff1aSopenharmony_cistatic int read_residue(GetBitContext *gb, int16_t block[64], int masks_count) 759cabdff1aSopenharmony_ci{ 760cabdff1aSopenharmony_ci int coef_list[128]; 761cabdff1aSopenharmony_ci int mode_list[128]; 762cabdff1aSopenharmony_ci int i, sign, mask, ccoef, mode; 763cabdff1aSopenharmony_ci int list_start = 64, list_end = 64, list_pos; 764cabdff1aSopenharmony_ci int nz_coeff[64]; 765cabdff1aSopenharmony_ci int nz_coeff_count = 0; 766cabdff1aSopenharmony_ci 767cabdff1aSopenharmony_ci coef_list[list_end] = 4; mode_list[list_end++] = 0; 768cabdff1aSopenharmony_ci coef_list[list_end] = 24; mode_list[list_end++] = 0; 769cabdff1aSopenharmony_ci coef_list[list_end] = 44; mode_list[list_end++] = 0; 770cabdff1aSopenharmony_ci coef_list[list_end] = 0; mode_list[list_end++] = 2; 771cabdff1aSopenharmony_ci 772cabdff1aSopenharmony_ci for (mask = 1 << get_bits(gb, 3); mask; mask >>= 1) { 773cabdff1aSopenharmony_ci for (i = 0; i < nz_coeff_count; i++) { 774cabdff1aSopenharmony_ci if (!get_bits1(gb)) 775cabdff1aSopenharmony_ci continue; 776cabdff1aSopenharmony_ci if (block[nz_coeff[i]] < 0) 777cabdff1aSopenharmony_ci block[nz_coeff[i]] -= mask; 778cabdff1aSopenharmony_ci else 779cabdff1aSopenharmony_ci block[nz_coeff[i]] += mask; 780cabdff1aSopenharmony_ci masks_count--; 781cabdff1aSopenharmony_ci if (masks_count < 0) 782cabdff1aSopenharmony_ci return 0; 783cabdff1aSopenharmony_ci } 784cabdff1aSopenharmony_ci list_pos = list_start; 785cabdff1aSopenharmony_ci while (list_pos < list_end) { 786cabdff1aSopenharmony_ci if (!(coef_list[list_pos] | mode_list[list_pos]) || !get_bits1(gb)) { 787cabdff1aSopenharmony_ci list_pos++; 788cabdff1aSopenharmony_ci continue; 789cabdff1aSopenharmony_ci } 790cabdff1aSopenharmony_ci ccoef = coef_list[list_pos]; 791cabdff1aSopenharmony_ci mode = mode_list[list_pos]; 792cabdff1aSopenharmony_ci switch (mode) { 793cabdff1aSopenharmony_ci case 0: 794cabdff1aSopenharmony_ci coef_list[list_pos] = ccoef + 4; 795cabdff1aSopenharmony_ci mode_list[list_pos] = 1; 796cabdff1aSopenharmony_ci case 2: 797cabdff1aSopenharmony_ci if (mode == 2) { 798cabdff1aSopenharmony_ci coef_list[list_pos] = 0; 799cabdff1aSopenharmony_ci mode_list[list_pos++] = 0; 800cabdff1aSopenharmony_ci } 801cabdff1aSopenharmony_ci for (i = 0; i < 4; i++, ccoef++) { 802cabdff1aSopenharmony_ci if (get_bits1(gb)) { 803cabdff1aSopenharmony_ci coef_list[--list_start] = ccoef; 804cabdff1aSopenharmony_ci mode_list[ list_start] = 3; 805cabdff1aSopenharmony_ci } else { 806cabdff1aSopenharmony_ci nz_coeff[nz_coeff_count++] = bink_scan[ccoef]; 807cabdff1aSopenharmony_ci sign = -get_bits1(gb); 808cabdff1aSopenharmony_ci block[bink_scan[ccoef]] = (mask ^ sign) - sign; 809cabdff1aSopenharmony_ci masks_count--; 810cabdff1aSopenharmony_ci if (masks_count < 0) 811cabdff1aSopenharmony_ci return 0; 812cabdff1aSopenharmony_ci } 813cabdff1aSopenharmony_ci } 814cabdff1aSopenharmony_ci break; 815cabdff1aSopenharmony_ci case 1: 816cabdff1aSopenharmony_ci mode_list[list_pos] = 2; 817cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) { 818cabdff1aSopenharmony_ci ccoef += 4; 819cabdff1aSopenharmony_ci coef_list[list_end] = ccoef; 820cabdff1aSopenharmony_ci mode_list[list_end++] = 2; 821cabdff1aSopenharmony_ci } 822cabdff1aSopenharmony_ci break; 823cabdff1aSopenharmony_ci case 3: 824cabdff1aSopenharmony_ci nz_coeff[nz_coeff_count++] = bink_scan[ccoef]; 825cabdff1aSopenharmony_ci sign = -get_bits1(gb); 826cabdff1aSopenharmony_ci block[bink_scan[ccoef]] = (mask ^ sign) - sign; 827cabdff1aSopenharmony_ci coef_list[list_pos] = 0; 828cabdff1aSopenharmony_ci mode_list[list_pos++] = 0; 829cabdff1aSopenharmony_ci masks_count--; 830cabdff1aSopenharmony_ci if (masks_count < 0) 831cabdff1aSopenharmony_ci return 0; 832cabdff1aSopenharmony_ci break; 833cabdff1aSopenharmony_ci } 834cabdff1aSopenharmony_ci } 835cabdff1aSopenharmony_ci } 836cabdff1aSopenharmony_ci 837cabdff1aSopenharmony_ci return 0; 838cabdff1aSopenharmony_ci} 839cabdff1aSopenharmony_ci 840cabdff1aSopenharmony_ci/** 841cabdff1aSopenharmony_ci * Copy 8x8 block from source to destination, where src and dst may be overlapped 842cabdff1aSopenharmony_ci */ 843cabdff1aSopenharmony_cistatic inline void put_pixels8x8_overlapped(uint8_t *dst, uint8_t *src, int stride) 844cabdff1aSopenharmony_ci{ 845cabdff1aSopenharmony_ci uint8_t tmp[64]; 846cabdff1aSopenharmony_ci int i; 847cabdff1aSopenharmony_ci for (i = 0; i < 8; i++) 848cabdff1aSopenharmony_ci memcpy(tmp + i*8, src + i*stride, 8); 849cabdff1aSopenharmony_ci for (i = 0; i < 8; i++) 850cabdff1aSopenharmony_ci memcpy(dst + i*stride, tmp + i*8, 8); 851cabdff1aSopenharmony_ci} 852cabdff1aSopenharmony_ci 853cabdff1aSopenharmony_cistatic int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, 854cabdff1aSopenharmony_ci int plane_idx, int is_key, int is_chroma) 855cabdff1aSopenharmony_ci{ 856cabdff1aSopenharmony_ci int blk, ret; 857cabdff1aSopenharmony_ci int i, j, bx, by; 858cabdff1aSopenharmony_ci uint8_t *dst, *ref, *ref_start, *ref_end; 859cabdff1aSopenharmony_ci int v, col[2]; 860cabdff1aSopenharmony_ci const uint8_t *scan; 861cabdff1aSopenharmony_ci int xoff, yoff; 862cabdff1aSopenharmony_ci LOCAL_ALIGNED_32(int16_t, block, [64]); 863cabdff1aSopenharmony_ci LOCAL_ALIGNED_16(int32_t, dctblock, [64]); 864cabdff1aSopenharmony_ci int coordmap[64]; 865cabdff1aSopenharmony_ci int ybias = is_key ? -15 : 0; 866cabdff1aSopenharmony_ci int qp, quant_idx, coef_count, coef_idx[64]; 867cabdff1aSopenharmony_ci 868cabdff1aSopenharmony_ci const int stride = frame->linesize[plane_idx]; 869cabdff1aSopenharmony_ci int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; 870cabdff1aSopenharmony_ci int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; 871cabdff1aSopenharmony_ci 872cabdff1aSopenharmony_ci binkb_init_bundles(c); 873cabdff1aSopenharmony_ci ref_start = frame->data[plane_idx]; 874cabdff1aSopenharmony_ci ref_end = frame->data[plane_idx] + ((bh - 1) * frame->linesize[plane_idx] + bw - 1) * 8; 875cabdff1aSopenharmony_ci 876cabdff1aSopenharmony_ci for (i = 0; i < 64; i++) 877cabdff1aSopenharmony_ci coordmap[i] = (i & 7) + (i >> 3) * stride; 878cabdff1aSopenharmony_ci 879cabdff1aSopenharmony_ci for (by = 0; by < bh; by++) { 880cabdff1aSopenharmony_ci for (i = 0; i < BINKB_NB_SRC; i++) { 881cabdff1aSopenharmony_ci if ((ret = binkb_read_bundle(c, gb, i)) < 0) 882cabdff1aSopenharmony_ci return ret; 883cabdff1aSopenharmony_ci } 884cabdff1aSopenharmony_ci 885cabdff1aSopenharmony_ci dst = frame->data[plane_idx] + 8*by*stride; 886cabdff1aSopenharmony_ci for (bx = 0; bx < bw; bx++, dst += 8) { 887cabdff1aSopenharmony_ci blk = binkb_get_value(c, BINKB_SRC_BLOCK_TYPES); 888cabdff1aSopenharmony_ci switch (blk) { 889cabdff1aSopenharmony_ci case 0: 890cabdff1aSopenharmony_ci break; 891cabdff1aSopenharmony_ci case 1: 892cabdff1aSopenharmony_ci scan = bink_patterns[get_bits(gb, 4)]; 893cabdff1aSopenharmony_ci i = 0; 894cabdff1aSopenharmony_ci do { 895cabdff1aSopenharmony_ci int mode, run; 896cabdff1aSopenharmony_ci 897cabdff1aSopenharmony_ci mode = get_bits1(gb); 898cabdff1aSopenharmony_ci run = get_bits(gb, binkb_runbits[i]) + 1; 899cabdff1aSopenharmony_ci 900cabdff1aSopenharmony_ci i += run; 901cabdff1aSopenharmony_ci if (i > 64) { 902cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); 903cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 904cabdff1aSopenharmony_ci } 905cabdff1aSopenharmony_ci if (mode) { 906cabdff1aSopenharmony_ci v = binkb_get_value(c, BINKB_SRC_COLORS); 907cabdff1aSopenharmony_ci for (j = 0; j < run; j++) 908cabdff1aSopenharmony_ci dst[coordmap[*scan++]] = v; 909cabdff1aSopenharmony_ci } else { 910cabdff1aSopenharmony_ci for (j = 0; j < run; j++) 911cabdff1aSopenharmony_ci dst[coordmap[*scan++]] = binkb_get_value(c, BINKB_SRC_COLORS); 912cabdff1aSopenharmony_ci } 913cabdff1aSopenharmony_ci } while (i < 63); 914cabdff1aSopenharmony_ci if (i == 63) 915cabdff1aSopenharmony_ci dst[coordmap[*scan++]] = binkb_get_value(c, BINKB_SRC_COLORS); 916cabdff1aSopenharmony_ci break; 917cabdff1aSopenharmony_ci case 2: 918cabdff1aSopenharmony_ci memset(dctblock, 0, sizeof(*dctblock) * 64); 919cabdff1aSopenharmony_ci dctblock[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC); 920cabdff1aSopenharmony_ci qp = binkb_get_value(c, BINKB_SRC_INTRA_Q); 921cabdff1aSopenharmony_ci if ((quant_idx = read_dct_coeffs(c, gb, dctblock, bink_scan, &coef_count, coef_idx, qp)) < 0) 922cabdff1aSopenharmony_ci return quant_idx; 923cabdff1aSopenharmony_ci unquantize_dct_coeffs(dctblock, binkb_intra_quant[quant_idx], coef_count, coef_idx, bink_scan); 924cabdff1aSopenharmony_ci c->binkdsp.idct_put(dst, stride, dctblock); 925cabdff1aSopenharmony_ci break; 926cabdff1aSopenharmony_ci case 3: 927cabdff1aSopenharmony_ci xoff = binkb_get_value(c, BINKB_SRC_X_OFF); 928cabdff1aSopenharmony_ci yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; 929cabdff1aSopenharmony_ci ref = dst + xoff + yoff * stride; 930cabdff1aSopenharmony_ci if (ref < ref_start || ref > ref_end) { 931cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); 932cabdff1aSopenharmony_ci } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { 933cabdff1aSopenharmony_ci c->put_pixels_tab(dst, ref, stride, 8); 934cabdff1aSopenharmony_ci } else { 935cabdff1aSopenharmony_ci put_pixels8x8_overlapped(dst, ref, stride); 936cabdff1aSopenharmony_ci } 937cabdff1aSopenharmony_ci c->bdsp.clear_block(block); 938cabdff1aSopenharmony_ci v = binkb_get_value(c, BINKB_SRC_INTER_COEFS); 939cabdff1aSopenharmony_ci read_residue(gb, block, v); 940cabdff1aSopenharmony_ci c->binkdsp.add_pixels8(dst, block, stride); 941cabdff1aSopenharmony_ci break; 942cabdff1aSopenharmony_ci case 4: 943cabdff1aSopenharmony_ci xoff = binkb_get_value(c, BINKB_SRC_X_OFF); 944cabdff1aSopenharmony_ci yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; 945cabdff1aSopenharmony_ci ref = dst + xoff + yoff * stride; 946cabdff1aSopenharmony_ci if (ref < ref_start || ref > ref_end) { 947cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); 948cabdff1aSopenharmony_ci } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { 949cabdff1aSopenharmony_ci c->put_pixels_tab(dst, ref, stride, 8); 950cabdff1aSopenharmony_ci } else { 951cabdff1aSopenharmony_ci put_pixels8x8_overlapped(dst, ref, stride); 952cabdff1aSopenharmony_ci } 953cabdff1aSopenharmony_ci memset(dctblock, 0, sizeof(*dctblock) * 64); 954cabdff1aSopenharmony_ci dctblock[0] = binkb_get_value(c, BINKB_SRC_INTER_DC); 955cabdff1aSopenharmony_ci qp = binkb_get_value(c, BINKB_SRC_INTER_Q); 956cabdff1aSopenharmony_ci if ((quant_idx = read_dct_coeffs(c, gb, dctblock, bink_scan, &coef_count, coef_idx, qp)) < 0) 957cabdff1aSopenharmony_ci return quant_idx; 958cabdff1aSopenharmony_ci unquantize_dct_coeffs(dctblock, binkb_inter_quant[quant_idx], coef_count, coef_idx, bink_scan); 959cabdff1aSopenharmony_ci c->binkdsp.idct_add(dst, stride, dctblock); 960cabdff1aSopenharmony_ci break; 961cabdff1aSopenharmony_ci case 5: 962cabdff1aSopenharmony_ci v = binkb_get_value(c, BINKB_SRC_COLORS); 963cabdff1aSopenharmony_ci c->bdsp.fill_block_tab[1](dst, v, stride, 8); 964cabdff1aSopenharmony_ci break; 965cabdff1aSopenharmony_ci case 6: 966cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) 967cabdff1aSopenharmony_ci col[i] = binkb_get_value(c, BINKB_SRC_COLORS); 968cabdff1aSopenharmony_ci for (i = 0; i < 8; i++) { 969cabdff1aSopenharmony_ci v = binkb_get_value(c, BINKB_SRC_PATTERN); 970cabdff1aSopenharmony_ci for (j = 0; j < 8; j++, v >>= 1) 971cabdff1aSopenharmony_ci dst[i*stride + j] = col[v & 1]; 972cabdff1aSopenharmony_ci } 973cabdff1aSopenharmony_ci break; 974cabdff1aSopenharmony_ci case 7: 975cabdff1aSopenharmony_ci xoff = binkb_get_value(c, BINKB_SRC_X_OFF); 976cabdff1aSopenharmony_ci yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; 977cabdff1aSopenharmony_ci ref = dst + xoff + yoff * stride; 978cabdff1aSopenharmony_ci if (ref < ref_start || ref > ref_end) { 979cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); 980cabdff1aSopenharmony_ci } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { 981cabdff1aSopenharmony_ci c->put_pixels_tab(dst, ref, stride, 8); 982cabdff1aSopenharmony_ci } else { 983cabdff1aSopenharmony_ci put_pixels8x8_overlapped(dst, ref, stride); 984cabdff1aSopenharmony_ci } 985cabdff1aSopenharmony_ci break; 986cabdff1aSopenharmony_ci case 8: 987cabdff1aSopenharmony_ci for (i = 0; i < 8; i++) 988cabdff1aSopenharmony_ci memcpy(dst + i*stride, c->bundle[BINKB_SRC_COLORS].cur_ptr + i*8, 8); 989cabdff1aSopenharmony_ci c->bundle[BINKB_SRC_COLORS].cur_ptr += 64; 990cabdff1aSopenharmony_ci break; 991cabdff1aSopenharmony_ci default: 992cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); 993cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 994cabdff1aSopenharmony_ci } 995cabdff1aSopenharmony_ci } 996cabdff1aSopenharmony_ci } 997cabdff1aSopenharmony_ci if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary 998cabdff1aSopenharmony_ci skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); 999cabdff1aSopenharmony_ci 1000cabdff1aSopenharmony_ci return 0; 1001cabdff1aSopenharmony_ci} 1002cabdff1aSopenharmony_ci 1003cabdff1aSopenharmony_cistatic int bink_put_pixels(BinkContext *c, 1004cabdff1aSopenharmony_ci uint8_t *dst, uint8_t *prev, int stride, 1005cabdff1aSopenharmony_ci uint8_t *ref_start, 1006cabdff1aSopenharmony_ci uint8_t *ref_end) 1007cabdff1aSopenharmony_ci{ 1008cabdff1aSopenharmony_ci int xoff = get_value(c, BINK_SRC_X_OFF); 1009cabdff1aSopenharmony_ci int yoff = get_value(c, BINK_SRC_Y_OFF); 1010cabdff1aSopenharmony_ci uint8_t *ref = prev + xoff + yoff * stride; 1011cabdff1aSopenharmony_ci if (ref < ref_start || ref > ref_end) { 1012cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", 1013cabdff1aSopenharmony_ci xoff, yoff); 1014cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1015cabdff1aSopenharmony_ci } 1016cabdff1aSopenharmony_ci c->put_pixels_tab(dst, ref, stride, 8); 1017cabdff1aSopenharmony_ci 1018cabdff1aSopenharmony_ci return 0; 1019cabdff1aSopenharmony_ci} 1020cabdff1aSopenharmony_ci 1021cabdff1aSopenharmony_cistatic int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, 1022cabdff1aSopenharmony_ci int plane_idx, int is_chroma) 1023cabdff1aSopenharmony_ci{ 1024cabdff1aSopenharmony_ci int blk, ret; 1025cabdff1aSopenharmony_ci int i, j, bx, by; 1026cabdff1aSopenharmony_ci uint8_t *dst, *prev, *ref_start, *ref_end; 1027cabdff1aSopenharmony_ci int v, col[2]; 1028cabdff1aSopenharmony_ci const uint8_t *scan; 1029cabdff1aSopenharmony_ci LOCAL_ALIGNED_32(int16_t, block, [64]); 1030cabdff1aSopenharmony_ci LOCAL_ALIGNED_16(uint8_t, ublock, [64]); 1031cabdff1aSopenharmony_ci LOCAL_ALIGNED_16(int32_t, dctblock, [64]); 1032cabdff1aSopenharmony_ci int coordmap[64], quant_idx, coef_count, coef_idx[64]; 1033cabdff1aSopenharmony_ci 1034cabdff1aSopenharmony_ci const int stride = frame->linesize[plane_idx]; 1035cabdff1aSopenharmony_ci int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; 1036cabdff1aSopenharmony_ci int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; 1037cabdff1aSopenharmony_ci int width = c->avctx->width >> is_chroma; 1038cabdff1aSopenharmony_ci int height = c->avctx->height >> is_chroma; 1039cabdff1aSopenharmony_ci 1040cabdff1aSopenharmony_ci if (c->version == 'k' && get_bits1(gb)) { 1041cabdff1aSopenharmony_ci int fill = get_bits(gb, 8); 1042cabdff1aSopenharmony_ci 1043cabdff1aSopenharmony_ci dst = frame->data[plane_idx]; 1044cabdff1aSopenharmony_ci 1045cabdff1aSopenharmony_ci for (i = 0; i < height; i++) 1046cabdff1aSopenharmony_ci memset(dst + i * stride, fill, width); 1047cabdff1aSopenharmony_ci goto end; 1048cabdff1aSopenharmony_ci } 1049cabdff1aSopenharmony_ci 1050cabdff1aSopenharmony_ci init_lengths(c, FFMAX(width, 8), bw); 1051cabdff1aSopenharmony_ci for (i = 0; i < BINK_NB_SRC; i++) { 1052cabdff1aSopenharmony_ci ret = read_bundle(gb, c, i); 1053cabdff1aSopenharmony_ci if (ret < 0) 1054cabdff1aSopenharmony_ci return ret; 1055cabdff1aSopenharmony_ci } 1056cabdff1aSopenharmony_ci 1057cabdff1aSopenharmony_ci ref_start = c->last->data[plane_idx] ? c->last->data[plane_idx] 1058cabdff1aSopenharmony_ci : frame->data[plane_idx]; 1059cabdff1aSopenharmony_ci ref_end = ref_start 1060cabdff1aSopenharmony_ci + (bw - 1 + c->last->linesize[plane_idx] * (bh - 1)) * 8; 1061cabdff1aSopenharmony_ci 1062cabdff1aSopenharmony_ci for (i = 0; i < 64; i++) 1063cabdff1aSopenharmony_ci coordmap[i] = (i & 7) + (i >> 3) * stride; 1064cabdff1aSopenharmony_ci 1065cabdff1aSopenharmony_ci for (by = 0; by < bh; by++) { 1066cabdff1aSopenharmony_ci if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES])) < 0) 1067cabdff1aSopenharmony_ci return ret; 1068cabdff1aSopenharmony_ci if ((ret = read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES])) < 0) 1069cabdff1aSopenharmony_ci return ret; 1070cabdff1aSopenharmony_ci if ((ret = read_colors(gb, &c->bundle[BINK_SRC_COLORS], c)) < 0) 1071cabdff1aSopenharmony_ci return ret; 1072cabdff1aSopenharmony_ci if ((ret = read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN])) < 0) 1073cabdff1aSopenharmony_ci return ret; 1074cabdff1aSopenharmony_ci if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF])) < 0) 1075cabdff1aSopenharmony_ci return ret; 1076cabdff1aSopenharmony_ci if ((ret = read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF])) < 0) 1077cabdff1aSopenharmony_ci return ret; 1078cabdff1aSopenharmony_ci if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0)) < 0) 1079cabdff1aSopenharmony_ci return ret; 1080cabdff1aSopenharmony_ci if ((ret = read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1)) < 0) 1081cabdff1aSopenharmony_ci return ret; 1082cabdff1aSopenharmony_ci if ((ret = read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN])) < 0) 1083cabdff1aSopenharmony_ci return ret; 1084cabdff1aSopenharmony_ci 1085cabdff1aSopenharmony_ci dst = frame->data[plane_idx] + 8*by*stride; 1086cabdff1aSopenharmony_ci prev = (c->last->data[plane_idx] ? c->last->data[plane_idx] 1087cabdff1aSopenharmony_ci : frame->data[plane_idx]) + 8*by*stride; 1088cabdff1aSopenharmony_ci for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) { 1089cabdff1aSopenharmony_ci blk = get_value(c, BINK_SRC_BLOCK_TYPES); 1090cabdff1aSopenharmony_ci // 16x16 block type on odd line means part of the already decoded block, so skip it 1091cabdff1aSopenharmony_ci if (((by & 1) || (bx & 1)) && blk == SCALED_BLOCK) { 1092cabdff1aSopenharmony_ci bx++; 1093cabdff1aSopenharmony_ci dst += 8; 1094cabdff1aSopenharmony_ci prev += 8; 1095cabdff1aSopenharmony_ci continue; 1096cabdff1aSopenharmony_ci } 1097cabdff1aSopenharmony_ci switch (blk) { 1098cabdff1aSopenharmony_ci case SKIP_BLOCK: 1099cabdff1aSopenharmony_ci c->put_pixels_tab(dst, prev, stride, 8); 1100cabdff1aSopenharmony_ci break; 1101cabdff1aSopenharmony_ci case SCALED_BLOCK: 1102cabdff1aSopenharmony_ci blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES); 1103cabdff1aSopenharmony_ci switch (blk) { 1104cabdff1aSopenharmony_ci case RUN_BLOCK: 1105cabdff1aSopenharmony_ci if (get_bits_left(gb) < 4) 1106cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1107cabdff1aSopenharmony_ci scan = bink_patterns[get_bits(gb, 4)]; 1108cabdff1aSopenharmony_ci i = 0; 1109cabdff1aSopenharmony_ci do { 1110cabdff1aSopenharmony_ci int run = get_value(c, BINK_SRC_RUN) + 1; 1111cabdff1aSopenharmony_ci 1112cabdff1aSopenharmony_ci i += run; 1113cabdff1aSopenharmony_ci if (i > 64) { 1114cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); 1115cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1116cabdff1aSopenharmony_ci } 1117cabdff1aSopenharmony_ci if (get_bits1(gb)) { 1118cabdff1aSopenharmony_ci v = get_value(c, BINK_SRC_COLORS); 1119cabdff1aSopenharmony_ci for (j = 0; j < run; j++) 1120cabdff1aSopenharmony_ci ublock[*scan++] = v; 1121cabdff1aSopenharmony_ci } else { 1122cabdff1aSopenharmony_ci for (j = 0; j < run; j++) 1123cabdff1aSopenharmony_ci ublock[*scan++] = get_value(c, BINK_SRC_COLORS); 1124cabdff1aSopenharmony_ci } 1125cabdff1aSopenharmony_ci } while (i < 63); 1126cabdff1aSopenharmony_ci if (i == 63) 1127cabdff1aSopenharmony_ci ublock[*scan++] = get_value(c, BINK_SRC_COLORS); 1128cabdff1aSopenharmony_ci break; 1129cabdff1aSopenharmony_ci case INTRA_BLOCK: 1130cabdff1aSopenharmony_ci memset(dctblock, 0, sizeof(*dctblock) * 64); 1131cabdff1aSopenharmony_ci dctblock[0] = get_value(c, BINK_SRC_INTRA_DC); 1132cabdff1aSopenharmony_ci if ((quant_idx = read_dct_coeffs(c, gb, dctblock, bink_scan, &coef_count, coef_idx, -1)) < 0) 1133cabdff1aSopenharmony_ci return quant_idx; 1134cabdff1aSopenharmony_ci unquantize_dct_coeffs(dctblock, bink_intra_quant[quant_idx], coef_count, coef_idx, bink_scan); 1135cabdff1aSopenharmony_ci c->binkdsp.idct_put(ublock, 8, dctblock); 1136cabdff1aSopenharmony_ci break; 1137cabdff1aSopenharmony_ci case FILL_BLOCK: 1138cabdff1aSopenharmony_ci v = get_value(c, BINK_SRC_COLORS); 1139cabdff1aSopenharmony_ci c->bdsp.fill_block_tab[0](dst, v, stride, 16); 1140cabdff1aSopenharmony_ci break; 1141cabdff1aSopenharmony_ci case PATTERN_BLOCK: 1142cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) 1143cabdff1aSopenharmony_ci col[i] = get_value(c, BINK_SRC_COLORS); 1144cabdff1aSopenharmony_ci for (j = 0; j < 8; j++) { 1145cabdff1aSopenharmony_ci v = get_value(c, BINK_SRC_PATTERN); 1146cabdff1aSopenharmony_ci for (i = 0; i < 8; i++, v >>= 1) 1147cabdff1aSopenharmony_ci ublock[i + j*8] = col[v & 1]; 1148cabdff1aSopenharmony_ci } 1149cabdff1aSopenharmony_ci break; 1150cabdff1aSopenharmony_ci case RAW_BLOCK: 1151cabdff1aSopenharmony_ci for (j = 0; j < 8; j++) 1152cabdff1aSopenharmony_ci for (i = 0; i < 8; i++) 1153cabdff1aSopenharmony_ci ublock[i + j*8] = get_value(c, BINK_SRC_COLORS); 1154cabdff1aSopenharmony_ci break; 1155cabdff1aSopenharmony_ci default: 1156cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk); 1157cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1158cabdff1aSopenharmony_ci } 1159cabdff1aSopenharmony_ci if (blk != FILL_BLOCK) 1160cabdff1aSopenharmony_ci c->binkdsp.scale_block(ublock, dst, stride); 1161cabdff1aSopenharmony_ci bx++; 1162cabdff1aSopenharmony_ci dst += 8; 1163cabdff1aSopenharmony_ci prev += 8; 1164cabdff1aSopenharmony_ci break; 1165cabdff1aSopenharmony_ci case MOTION_BLOCK: 1166cabdff1aSopenharmony_ci ret = bink_put_pixels(c, dst, prev, stride, 1167cabdff1aSopenharmony_ci ref_start, ref_end); 1168cabdff1aSopenharmony_ci if (ret < 0) 1169cabdff1aSopenharmony_ci return ret; 1170cabdff1aSopenharmony_ci break; 1171cabdff1aSopenharmony_ci case RUN_BLOCK: 1172cabdff1aSopenharmony_ci scan = bink_patterns[get_bits(gb, 4)]; 1173cabdff1aSopenharmony_ci i = 0; 1174cabdff1aSopenharmony_ci do { 1175cabdff1aSopenharmony_ci int run = get_value(c, BINK_SRC_RUN) + 1; 1176cabdff1aSopenharmony_ci 1177cabdff1aSopenharmony_ci i += run; 1178cabdff1aSopenharmony_ci if (i > 64) { 1179cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); 1180cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1181cabdff1aSopenharmony_ci } 1182cabdff1aSopenharmony_ci if (get_bits1(gb)) { 1183cabdff1aSopenharmony_ci v = get_value(c, BINK_SRC_COLORS); 1184cabdff1aSopenharmony_ci for (j = 0; j < run; j++) 1185cabdff1aSopenharmony_ci dst[coordmap[*scan++]] = v; 1186cabdff1aSopenharmony_ci } else { 1187cabdff1aSopenharmony_ci for (j = 0; j < run; j++) 1188cabdff1aSopenharmony_ci dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS); 1189cabdff1aSopenharmony_ci } 1190cabdff1aSopenharmony_ci } while (i < 63); 1191cabdff1aSopenharmony_ci if (i == 63) 1192cabdff1aSopenharmony_ci dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS); 1193cabdff1aSopenharmony_ci break; 1194cabdff1aSopenharmony_ci case RESIDUE_BLOCK: 1195cabdff1aSopenharmony_ci ret = bink_put_pixels(c, dst, prev, stride, 1196cabdff1aSopenharmony_ci ref_start, ref_end); 1197cabdff1aSopenharmony_ci if (ret < 0) 1198cabdff1aSopenharmony_ci return ret; 1199cabdff1aSopenharmony_ci c->bdsp.clear_block(block); 1200cabdff1aSopenharmony_ci v = get_bits(gb, 7); 1201cabdff1aSopenharmony_ci read_residue(gb, block, v); 1202cabdff1aSopenharmony_ci c->binkdsp.add_pixels8(dst, block, stride); 1203cabdff1aSopenharmony_ci break; 1204cabdff1aSopenharmony_ci case INTRA_BLOCK: 1205cabdff1aSopenharmony_ci memset(dctblock, 0, sizeof(*dctblock) * 64); 1206cabdff1aSopenharmony_ci dctblock[0] = get_value(c, BINK_SRC_INTRA_DC); 1207cabdff1aSopenharmony_ci if ((quant_idx = read_dct_coeffs(c, gb, dctblock, bink_scan, &coef_count, coef_idx, -1)) < 0) 1208cabdff1aSopenharmony_ci return quant_idx; 1209cabdff1aSopenharmony_ci unquantize_dct_coeffs(dctblock, bink_intra_quant[quant_idx], coef_count, coef_idx, bink_scan); 1210cabdff1aSopenharmony_ci c->binkdsp.idct_put(dst, stride, dctblock); 1211cabdff1aSopenharmony_ci break; 1212cabdff1aSopenharmony_ci case FILL_BLOCK: 1213cabdff1aSopenharmony_ci v = get_value(c, BINK_SRC_COLORS); 1214cabdff1aSopenharmony_ci c->bdsp.fill_block_tab[1](dst, v, stride, 8); 1215cabdff1aSopenharmony_ci break; 1216cabdff1aSopenharmony_ci case INTER_BLOCK: 1217cabdff1aSopenharmony_ci ret = bink_put_pixels(c, dst, prev, stride, 1218cabdff1aSopenharmony_ci ref_start, ref_end); 1219cabdff1aSopenharmony_ci if (ret < 0) 1220cabdff1aSopenharmony_ci return ret; 1221cabdff1aSopenharmony_ci memset(dctblock, 0, sizeof(*dctblock) * 64); 1222cabdff1aSopenharmony_ci dctblock[0] = get_value(c, BINK_SRC_INTER_DC); 1223cabdff1aSopenharmony_ci if ((quant_idx = read_dct_coeffs(c, gb, dctblock, bink_scan, &coef_count, coef_idx, -1)) < 0) 1224cabdff1aSopenharmony_ci return quant_idx; 1225cabdff1aSopenharmony_ci unquantize_dct_coeffs(dctblock, bink_inter_quant[quant_idx], coef_count, coef_idx, bink_scan); 1226cabdff1aSopenharmony_ci c->binkdsp.idct_add(dst, stride, dctblock); 1227cabdff1aSopenharmony_ci break; 1228cabdff1aSopenharmony_ci case PATTERN_BLOCK: 1229cabdff1aSopenharmony_ci for (i = 0; i < 2; i++) 1230cabdff1aSopenharmony_ci col[i] = get_value(c, BINK_SRC_COLORS); 1231cabdff1aSopenharmony_ci for (i = 0; i < 8; i++) { 1232cabdff1aSopenharmony_ci v = get_value(c, BINK_SRC_PATTERN); 1233cabdff1aSopenharmony_ci for (j = 0; j < 8; j++, v >>= 1) 1234cabdff1aSopenharmony_ci dst[i*stride + j] = col[v & 1]; 1235cabdff1aSopenharmony_ci } 1236cabdff1aSopenharmony_ci break; 1237cabdff1aSopenharmony_ci case RAW_BLOCK: 1238cabdff1aSopenharmony_ci for (i = 0; i < 8; i++) 1239cabdff1aSopenharmony_ci memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8); 1240cabdff1aSopenharmony_ci c->bundle[BINK_SRC_COLORS].cur_ptr += 64; 1241cabdff1aSopenharmony_ci break; 1242cabdff1aSopenharmony_ci default: 1243cabdff1aSopenharmony_ci av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); 1244cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1245cabdff1aSopenharmony_ci } 1246cabdff1aSopenharmony_ci } 1247cabdff1aSopenharmony_ci } 1248cabdff1aSopenharmony_ci 1249cabdff1aSopenharmony_ciend: 1250cabdff1aSopenharmony_ci if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary 1251cabdff1aSopenharmony_ci skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); 1252cabdff1aSopenharmony_ci 1253cabdff1aSopenharmony_ci return 0; 1254cabdff1aSopenharmony_ci} 1255cabdff1aSopenharmony_ci 1256cabdff1aSopenharmony_cistatic int decode_frame(AVCodecContext *avctx, AVFrame *frame, 1257cabdff1aSopenharmony_ci int *got_frame, AVPacket *pkt) 1258cabdff1aSopenharmony_ci{ 1259cabdff1aSopenharmony_ci BinkContext * const c = avctx->priv_data; 1260cabdff1aSopenharmony_ci GetBitContext gb; 1261cabdff1aSopenharmony_ci int plane, plane_idx, ret; 1262cabdff1aSopenharmony_ci int bits_count = pkt->size << 3; 1263cabdff1aSopenharmony_ci 1264cabdff1aSopenharmony_ci if (c->version > 'b') { 1265cabdff1aSopenharmony_ci if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) 1266cabdff1aSopenharmony_ci return ret; 1267cabdff1aSopenharmony_ci } else { 1268cabdff1aSopenharmony_ci if ((ret = ff_reget_buffer(avctx, c->last, 0)) < 0) 1269cabdff1aSopenharmony_ci return ret; 1270cabdff1aSopenharmony_ci if ((ret = av_frame_ref(frame, c->last)) < 0) 1271cabdff1aSopenharmony_ci return ret; 1272cabdff1aSopenharmony_ci } 1273cabdff1aSopenharmony_ci 1274cabdff1aSopenharmony_ci init_get_bits(&gb, pkt->data, bits_count); 1275cabdff1aSopenharmony_ci if (c->has_alpha) { 1276cabdff1aSopenharmony_ci if (c->version >= 'i') 1277cabdff1aSopenharmony_ci skip_bits_long(&gb, 32); 1278cabdff1aSopenharmony_ci if ((ret = bink_decode_plane(c, frame, &gb, 3, 0)) < 0) 1279cabdff1aSopenharmony_ci return ret; 1280cabdff1aSopenharmony_ci } 1281cabdff1aSopenharmony_ci if (c->version >= 'i') 1282cabdff1aSopenharmony_ci skip_bits_long(&gb, 32); 1283cabdff1aSopenharmony_ci 1284cabdff1aSopenharmony_ci c->frame_num++; 1285cabdff1aSopenharmony_ci 1286cabdff1aSopenharmony_ci for (plane = 0; plane < 3; plane++) { 1287cabdff1aSopenharmony_ci plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); 1288cabdff1aSopenharmony_ci 1289cabdff1aSopenharmony_ci if (c->version > 'b') { 1290cabdff1aSopenharmony_ci if ((ret = bink_decode_plane(c, frame, &gb, plane_idx, !!plane)) < 0) 1291cabdff1aSopenharmony_ci return ret; 1292cabdff1aSopenharmony_ci } else { 1293cabdff1aSopenharmony_ci if ((ret = binkb_decode_plane(c, frame, &gb, plane_idx, 1294cabdff1aSopenharmony_ci c->frame_num == 1, !!plane)) < 0) 1295cabdff1aSopenharmony_ci return ret; 1296cabdff1aSopenharmony_ci } 1297cabdff1aSopenharmony_ci if (get_bits_count(&gb) >= bits_count) 1298cabdff1aSopenharmony_ci break; 1299cabdff1aSopenharmony_ci } 1300cabdff1aSopenharmony_ci emms_c(); 1301cabdff1aSopenharmony_ci 1302cabdff1aSopenharmony_ci if (c->version > 'b') { 1303cabdff1aSopenharmony_ci av_frame_unref(c->last); 1304cabdff1aSopenharmony_ci if ((ret = av_frame_ref(c->last, frame)) < 0) 1305cabdff1aSopenharmony_ci return ret; 1306cabdff1aSopenharmony_ci } 1307cabdff1aSopenharmony_ci 1308cabdff1aSopenharmony_ci *got_frame = 1; 1309cabdff1aSopenharmony_ci 1310cabdff1aSopenharmony_ci /* always report that the buffer was completely consumed */ 1311cabdff1aSopenharmony_ci return pkt->size; 1312cabdff1aSopenharmony_ci} 1313cabdff1aSopenharmony_ci 1314cabdff1aSopenharmony_cistatic av_cold void bink_init_vlcs(void) 1315cabdff1aSopenharmony_ci{ 1316cabdff1aSopenharmony_ci for (int i = 0, offset = 0; i < 16; i++) { 1317cabdff1aSopenharmony_ci static VLCElem table[976]; 1318cabdff1aSopenharmony_ci const int maxbits = bink_tree_lens[i][15]; 1319cabdff1aSopenharmony_ci bink_trees[i].table = table + offset; 1320cabdff1aSopenharmony_ci bink_trees[i].table_allocated = 1 << maxbits; 1321cabdff1aSopenharmony_ci offset += bink_trees[i].table_allocated; 1322cabdff1aSopenharmony_ci init_vlc(&bink_trees[i], maxbits, 16, 1323cabdff1aSopenharmony_ci bink_tree_lens[i], 1, 1, 1324cabdff1aSopenharmony_ci bink_tree_bits[i], 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); 1325cabdff1aSopenharmony_ci } 1326cabdff1aSopenharmony_ci} 1327cabdff1aSopenharmony_ci 1328cabdff1aSopenharmony_ci/** 1329cabdff1aSopenharmony_ci * Calculate quantization tables for version b 1330cabdff1aSopenharmony_ci */ 1331cabdff1aSopenharmony_cistatic av_cold void binkb_calc_quant(void) 1332cabdff1aSopenharmony_ci{ 1333cabdff1aSopenharmony_ci uint8_t inv_bink_scan[64]; 1334cabdff1aSopenharmony_ci static const int s[64]={ 1335cabdff1aSopenharmony_ci 1073741824,1489322693,1402911301,1262586814,1073741824, 843633538, 581104888, 296244703, 1336cabdff1aSopenharmony_ci 1489322693,2065749918,1945893874,1751258219,1489322693,1170153332, 806015634, 410903207, 1337cabdff1aSopenharmony_ci 1402911301,1945893874,1832991949,1649649171,1402911301,1102260336, 759250125, 387062357, 1338cabdff1aSopenharmony_ci 1262586814,1751258219,1649649171,1484645031,1262586814, 992008094, 683307060, 348346918, 1339cabdff1aSopenharmony_ci 1073741824,1489322693,1402911301,1262586814,1073741824, 843633538, 581104888, 296244703, 1340cabdff1aSopenharmony_ci 843633538,1170153332,1102260336, 992008094, 843633538, 662838617, 456571181, 232757969, 1341cabdff1aSopenharmony_ci 581104888, 806015634, 759250125, 683307060, 581104888, 456571181, 314491699, 160326478, 1342cabdff1aSopenharmony_ci 296244703, 410903207, 387062357, 348346918, 296244703, 232757969, 160326478, 81733730, 1343cabdff1aSopenharmony_ci }; 1344cabdff1aSopenharmony_ci int i, j; 1345cabdff1aSopenharmony_ci#define C (1LL<<30) 1346cabdff1aSopenharmony_ci for (i = 0; i < 64; i++) 1347cabdff1aSopenharmony_ci inv_bink_scan[bink_scan[i]] = i; 1348cabdff1aSopenharmony_ci 1349cabdff1aSopenharmony_ci for (j = 0; j < 16; j++) { 1350cabdff1aSopenharmony_ci for (i = 0; i < 64; i++) { 1351cabdff1aSopenharmony_ci int k = inv_bink_scan[i]; 1352cabdff1aSopenharmony_ci binkb_intra_quant[j][k] = binkb_intra_seed[i] * (int64_t)s[i] * 1353cabdff1aSopenharmony_ci binkb_num[j]/(binkb_den[j] * (C>>12)); 1354cabdff1aSopenharmony_ci binkb_inter_quant[j][k] = binkb_inter_seed[i] * (int64_t)s[i] * 1355cabdff1aSopenharmony_ci binkb_num[j]/(binkb_den[j] * (C>>12)); 1356cabdff1aSopenharmony_ci } 1357cabdff1aSopenharmony_ci } 1358cabdff1aSopenharmony_ci} 1359cabdff1aSopenharmony_ci 1360cabdff1aSopenharmony_cistatic av_cold int decode_init(AVCodecContext *avctx) 1361cabdff1aSopenharmony_ci{ 1362cabdff1aSopenharmony_ci static AVOnce init_static_once = AV_ONCE_INIT; 1363cabdff1aSopenharmony_ci BinkContext * const c = avctx->priv_data; 1364cabdff1aSopenharmony_ci HpelDSPContext hdsp; 1365cabdff1aSopenharmony_ci int ret; 1366cabdff1aSopenharmony_ci int flags; 1367cabdff1aSopenharmony_ci 1368cabdff1aSopenharmony_ci c->version = avctx->codec_tag >> 24; 1369cabdff1aSopenharmony_ci if (avctx->extradata_size < 4) { 1370cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "Extradata missing or too short\n"); 1371cabdff1aSopenharmony_ci return AVERROR_INVALIDDATA; 1372cabdff1aSopenharmony_ci } 1373cabdff1aSopenharmony_ci flags = AV_RL32(avctx->extradata); 1374cabdff1aSopenharmony_ci c->has_alpha = flags & BINK_FLAG_ALPHA; 1375cabdff1aSopenharmony_ci c->swap_planes = c->version >= 'h'; 1376cabdff1aSopenharmony_ci c->avctx = avctx; 1377cabdff1aSopenharmony_ci 1378cabdff1aSopenharmony_ci if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) 1379cabdff1aSopenharmony_ci return ret; 1380cabdff1aSopenharmony_ci 1381cabdff1aSopenharmony_ci c->last = av_frame_alloc(); 1382cabdff1aSopenharmony_ci if (!c->last) 1383cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 1384cabdff1aSopenharmony_ci 1385cabdff1aSopenharmony_ci avctx->pix_fmt = c->has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P; 1386cabdff1aSopenharmony_ci avctx->color_range = c->version == 'k' ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; 1387cabdff1aSopenharmony_ci 1388cabdff1aSopenharmony_ci ff_blockdsp_init(&c->bdsp, avctx); 1389cabdff1aSopenharmony_ci ff_hpeldsp_init(&hdsp, avctx->flags); 1390cabdff1aSopenharmony_ci c->put_pixels_tab = hdsp.put_pixels_tab[1][0]; 1391cabdff1aSopenharmony_ci ff_binkdsp_init(&c->binkdsp); 1392cabdff1aSopenharmony_ci 1393cabdff1aSopenharmony_ci if ((ret = init_bundles(c)) < 0) 1394cabdff1aSopenharmony_ci return ret; 1395cabdff1aSopenharmony_ci 1396cabdff1aSopenharmony_ci if (c->version == 'b') { 1397cabdff1aSopenharmony_ci static AVOnce binkb_init_once = AV_ONCE_INIT; 1398cabdff1aSopenharmony_ci ff_thread_once(&binkb_init_once, binkb_calc_quant); 1399cabdff1aSopenharmony_ci } 1400cabdff1aSopenharmony_ci ff_thread_once(&init_static_once, bink_init_vlcs); 1401cabdff1aSopenharmony_ci 1402cabdff1aSopenharmony_ci return 0; 1403cabdff1aSopenharmony_ci} 1404cabdff1aSopenharmony_ci 1405cabdff1aSopenharmony_cistatic av_cold int decode_end(AVCodecContext *avctx) 1406cabdff1aSopenharmony_ci{ 1407cabdff1aSopenharmony_ci BinkContext * const c = avctx->priv_data; 1408cabdff1aSopenharmony_ci 1409cabdff1aSopenharmony_ci av_frame_free(&c->last); 1410cabdff1aSopenharmony_ci 1411cabdff1aSopenharmony_ci free_bundles(c); 1412cabdff1aSopenharmony_ci return 0; 1413cabdff1aSopenharmony_ci} 1414cabdff1aSopenharmony_ci 1415cabdff1aSopenharmony_cistatic void flush(AVCodecContext *avctx) 1416cabdff1aSopenharmony_ci{ 1417cabdff1aSopenharmony_ci BinkContext * const c = avctx->priv_data; 1418cabdff1aSopenharmony_ci 1419cabdff1aSopenharmony_ci c->frame_num = 0; 1420cabdff1aSopenharmony_ci} 1421cabdff1aSopenharmony_ci 1422cabdff1aSopenharmony_ciconst FFCodec ff_bink_decoder = { 1423cabdff1aSopenharmony_ci .p.name = "binkvideo", 1424cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Bink video"), 1425cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 1426cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_BINKVIDEO, 1427cabdff1aSopenharmony_ci .priv_data_size = sizeof(BinkContext), 1428cabdff1aSopenharmony_ci .init = decode_init, 1429cabdff1aSopenharmony_ci .close = decode_end, 1430cabdff1aSopenharmony_ci FF_CODEC_DECODE_CB(decode_frame), 1431cabdff1aSopenharmony_ci .flush = flush, 1432cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_DR1, 1433cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 1434cabdff1aSopenharmony_ci}; 1435