Libav
|
00001 /* 00002 * Bink video decoder 00003 * Copyright (c) 2009 Konstantin Shishkov 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "avcodec.h" 00023 #include "dsputil.h" 00024 #include "binkdata.h" 00025 #include "mathops.h" 00026 00027 #define ALT_BITSTREAM_READER_LE 00028 #include "get_bits.h" 00029 00030 #define BINK_FLAG_ALPHA 0x00100000 00031 #define BINK_FLAG_GRAY 0x00020000 00032 00033 static VLC bink_trees[16]; 00034 00038 enum Sources { 00039 BINK_SRC_BLOCK_TYPES = 0, 00040 BINK_SRC_SUB_BLOCK_TYPES, 00041 BINK_SRC_COLORS, 00042 BINK_SRC_PATTERN, 00043 BINK_SRC_X_OFF, 00044 BINK_SRC_Y_OFF, 00045 BINK_SRC_INTRA_DC, 00046 BINK_SRC_INTER_DC, 00047 BINK_SRC_RUN, 00048 00049 BINK_NB_SRC 00050 }; 00051 00055 typedef struct Tree { 00056 int vlc_num; 00057 uint8_t syms[16]; 00058 } Tree; 00059 00060 #define GET_HUFF(gb, tree) (tree).syms[get_vlc2(gb, bink_trees[(tree).vlc_num].table,\ 00061 bink_trees[(tree).vlc_num].bits, 1)] 00062 00066 typedef struct Bundle { 00067 int len; 00068 Tree tree; 00069 uint8_t *data; 00070 uint8_t *data_end; 00071 uint8_t *cur_dec; 00072 uint8_t *cur_ptr; 00073 } Bundle; 00074 00075 /* 00076 * Decoder context 00077 */ 00078 typedef struct BinkContext { 00079 AVCodecContext *avctx; 00080 DSPContext dsp; 00081 AVFrame pic, last; 00082 int version; 00083 int has_alpha; 00084 int swap_planes; 00085 ScanTable scantable; 00086 00087 Bundle bundle[BINK_NB_SRC]; 00088 Tree col_high[16]; 00089 int col_lastval; 00090 } BinkContext; 00091 00095 enum BlockTypes { 00096 SKIP_BLOCK = 0, 00097 SCALED_BLOCK, 00098 MOTION_BLOCK, 00099 RUN_BLOCK, 00100 RESIDUE_BLOCK, 00101 INTRA_BLOCK, 00102 FILL_BLOCK, 00103 INTER_BLOCK, 00104 PATTERN_BLOCK, 00105 RAW_BLOCK, 00106 }; 00107 00115 static void init_lengths(BinkContext *c, int width, int bw) 00116 { 00117 c->bundle[BINK_SRC_BLOCK_TYPES].len = av_log2((width >> 3) + 511) + 1; 00118 00119 c->bundle[BINK_SRC_SUB_BLOCK_TYPES].len = av_log2((width >> 4) + 511) + 1; 00120 00121 c->bundle[BINK_SRC_COLORS].len = av_log2((width >> 3)*64 + 511) + 1; 00122 00123 c->bundle[BINK_SRC_INTRA_DC].len = 00124 c->bundle[BINK_SRC_INTER_DC].len = 00125 c->bundle[BINK_SRC_X_OFF].len = 00126 c->bundle[BINK_SRC_Y_OFF].len = av_log2((width >> 3) + 511) + 1; 00127 00128 c->bundle[BINK_SRC_PATTERN].len = av_log2((bw << 3) + 511) + 1; 00129 00130 c->bundle[BINK_SRC_RUN].len = av_log2((width >> 3)*48 + 511) + 1; 00131 } 00132 00138 static av_cold void init_bundles(BinkContext *c) 00139 { 00140 int bw, bh, blocks; 00141 int i; 00142 00143 bw = (c->avctx->width + 7) >> 3; 00144 bh = (c->avctx->height + 7) >> 3; 00145 blocks = bw * bh; 00146 00147 for (i = 0; i < BINK_NB_SRC; i++) { 00148 c->bundle[i].data = av_malloc(blocks * 64); 00149 c->bundle[i].data_end = c->bundle[i].data + blocks * 64; 00150 } 00151 } 00152 00158 static av_cold void free_bundles(BinkContext *c) 00159 { 00160 int i; 00161 for (i = 0; i < BINK_NB_SRC; i++) 00162 av_freep(&c->bundle[i].data); 00163 } 00164 00173 static void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size) 00174 { 00175 uint8_t *src2 = src + size; 00176 int size2 = size; 00177 00178 do { 00179 if (!get_bits1(gb)) { 00180 *dst++ = *src++; 00181 size--; 00182 } else { 00183 *dst++ = *src2++; 00184 size2--; 00185 } 00186 } while (size && size2); 00187 00188 while (size--) 00189 *dst++ = *src++; 00190 while (size2--) 00191 *dst++ = *src2++; 00192 } 00193 00200 static void read_tree(GetBitContext *gb, Tree *tree) 00201 { 00202 uint8_t tmp1[16], tmp2[16], *in = tmp1, *out = tmp2; 00203 int i, t, len; 00204 00205 tree->vlc_num = get_bits(gb, 4); 00206 if (!tree->vlc_num) { 00207 for (i = 0; i < 16; i++) 00208 tree->syms[i] = i; 00209 return; 00210 } 00211 if (get_bits1(gb)) { 00212 len = get_bits(gb, 3); 00213 memset(tmp1, 0, sizeof(tmp1)); 00214 for (i = 0; i <= len; i++) { 00215 tree->syms[i] = get_bits(gb, 4); 00216 tmp1[tree->syms[i]] = 1; 00217 } 00218 for (i = 0; i < 16; i++) 00219 if (!tmp1[i]) 00220 tree->syms[++len] = i; 00221 } else { 00222 len = get_bits(gb, 2); 00223 for (i = 0; i < 16; i++) 00224 in[i] = i; 00225 for (i = 0; i <= len; i++) { 00226 int size = 1 << i; 00227 for (t = 0; t < 16; t += size << 1) 00228 merge(gb, out + t, in + t, size); 00229 FFSWAP(uint8_t*, in, out); 00230 } 00231 memcpy(tree->syms, in, 16); 00232 } 00233 } 00234 00242 static void read_bundle(GetBitContext *gb, BinkContext *c, int bundle_num) 00243 { 00244 int i; 00245 00246 if (bundle_num == BINK_SRC_COLORS) { 00247 for (i = 0; i < 16; i++) 00248 read_tree(gb, &c->col_high[i]); 00249 c->col_lastval = 0; 00250 } 00251 if (bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC) 00252 read_tree(gb, &c->bundle[bundle_num].tree); 00253 c->bundle[bundle_num].cur_dec = 00254 c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data; 00255 } 00256 00264 #define CHECK_READ_VAL(gb, b, t) \ 00265 if (!b->cur_dec || (b->cur_dec > b->cur_ptr)) \ 00266 return 0; \ 00267 t = get_bits(gb, b->len); \ 00268 if (!t) { \ 00269 b->cur_dec = NULL; \ 00270 return 0; \ 00271 } \ 00272 00273 static int read_runs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 00274 { 00275 int t, v; 00276 const uint8_t *dec_end; 00277 00278 CHECK_READ_VAL(gb, b, t); 00279 dec_end = b->cur_dec + t; 00280 if (dec_end > b->data_end) { 00281 av_log(avctx, AV_LOG_ERROR, "Run value went out of bounds\n"); 00282 return -1; 00283 } 00284 if (get_bits1(gb)) { 00285 v = get_bits(gb, 4); 00286 memset(b->cur_dec, v, t); 00287 b->cur_dec += t; 00288 } else { 00289 while (b->cur_dec < dec_end) 00290 *b->cur_dec++ = GET_HUFF(gb, b->tree); 00291 } 00292 return 0; 00293 } 00294 00295 static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 00296 { 00297 int t, sign, v; 00298 const uint8_t *dec_end; 00299 00300 CHECK_READ_VAL(gb, b, t); 00301 dec_end = b->cur_dec + t; 00302 if (dec_end > b->data_end) { 00303 av_log(avctx, AV_LOG_ERROR, "Too many motion values\n"); 00304 return -1; 00305 } 00306 if (get_bits1(gb)) { 00307 v = get_bits(gb, 4); 00308 if (v) { 00309 sign = -get_bits1(gb); 00310 v = (v ^ sign) - sign; 00311 } 00312 memset(b->cur_dec, v, t); 00313 b->cur_dec += t; 00314 } else { 00315 do { 00316 v = GET_HUFF(gb, b->tree); 00317 if (v) { 00318 sign = -get_bits1(gb); 00319 v = (v ^ sign) - sign; 00320 } 00321 *b->cur_dec++ = v; 00322 } while (b->cur_dec < dec_end); 00323 } 00324 return 0; 00325 } 00326 00327 const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 }; 00328 00329 static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 00330 { 00331 int t, v; 00332 int last = 0; 00333 const uint8_t *dec_end; 00334 00335 CHECK_READ_VAL(gb, b, t); 00336 dec_end = b->cur_dec + t; 00337 if (dec_end > b->data_end) { 00338 av_log(avctx, AV_LOG_ERROR, "Too many block type values\n"); 00339 return -1; 00340 } 00341 if (get_bits1(gb)) { 00342 v = get_bits(gb, 4); 00343 memset(b->cur_dec, v, t); 00344 b->cur_dec += t; 00345 } else { 00346 do { 00347 v = GET_HUFF(gb, b->tree); 00348 if (v < 12) { 00349 last = v; 00350 *b->cur_dec++ = v; 00351 } else { 00352 int run = bink_rlelens[v - 12]; 00353 00354 memset(b->cur_dec, last, run); 00355 b->cur_dec += run; 00356 } 00357 } while (b->cur_dec < dec_end); 00358 } 00359 return 0; 00360 } 00361 00362 static int read_patterns(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 00363 { 00364 int t, v; 00365 const uint8_t *dec_end; 00366 00367 CHECK_READ_VAL(gb, b, t); 00368 dec_end = b->cur_dec + t; 00369 if (dec_end > b->data_end) { 00370 av_log(avctx, AV_LOG_ERROR, "Too many pattern values\n"); 00371 return -1; 00372 } 00373 while (b->cur_dec < dec_end) { 00374 v = GET_HUFF(gb, b->tree); 00375 v |= GET_HUFF(gb, b->tree) << 4; 00376 *b->cur_dec++ = v; 00377 } 00378 00379 return 0; 00380 } 00381 00382 static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c) 00383 { 00384 int t, sign, v; 00385 const uint8_t *dec_end; 00386 00387 CHECK_READ_VAL(gb, b, t); 00388 dec_end = b->cur_dec + t; 00389 if (dec_end > b->data_end) { 00390 av_log(c->avctx, AV_LOG_ERROR, "Too many color values\n"); 00391 return -1; 00392 } 00393 if (get_bits1(gb)) { 00394 c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); 00395 v = GET_HUFF(gb, b->tree); 00396 v = (c->col_lastval << 4) | v; 00397 if (c->version < 'i') { 00398 sign = ((int8_t) v) >> 7; 00399 v = ((v & 0x7F) ^ sign) - sign; 00400 v += 0x80; 00401 } 00402 memset(b->cur_dec, v, t); 00403 b->cur_dec += t; 00404 } else { 00405 while (b->cur_dec < dec_end) { 00406 c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); 00407 v = GET_HUFF(gb, b->tree); 00408 v = (c->col_lastval << 4) | v; 00409 if (c->version < 'i') { 00410 sign = ((int8_t) v) >> 7; 00411 v = ((v & 0x7F) ^ sign) - sign; 00412 v += 0x80; 00413 } 00414 *b->cur_dec++ = v; 00415 } 00416 } 00417 return 0; 00418 } 00419 00421 #define DC_START_BITS 11 00422 00423 static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, 00424 int start_bits, int has_sign) 00425 { 00426 int i, j, len, len2, bsize, sign, v, v2; 00427 int16_t *dst = (int16_t*)b->cur_dec; 00428 00429 CHECK_READ_VAL(gb, b, len); 00430 v = get_bits(gb, start_bits - has_sign); 00431 if (v && has_sign) { 00432 sign = -get_bits1(gb); 00433 v = (v ^ sign) - sign; 00434 } 00435 *dst++ = v; 00436 len--; 00437 for (i = 0; i < len; i += 8) { 00438 len2 = FFMIN(len - i, 8); 00439 bsize = get_bits(gb, 4); 00440 if (bsize) { 00441 for (j = 0; j < len2; j++) { 00442 v2 = get_bits(gb, bsize); 00443 if (v2) { 00444 sign = -get_bits1(gb); 00445 v2 = (v2 ^ sign) - sign; 00446 } 00447 v += v2; 00448 *dst++ = v; 00449 if (v < -32768 || v > 32767) { 00450 av_log(avctx, AV_LOG_ERROR, "DC value went out of bounds: %d\n", v); 00451 return -1; 00452 } 00453 } 00454 } else { 00455 for (j = 0; j < len2; j++) 00456 *dst++ = v; 00457 } 00458 } 00459 00460 b->cur_dec = (uint8_t*)dst; 00461 return 0; 00462 } 00463 00470 static inline int get_value(BinkContext *c, int bundle) 00471 { 00472 int16_t ret; 00473 00474 if (bundle < BINK_SRC_X_OFF || bundle == BINK_SRC_RUN) 00475 return *c->bundle[bundle].cur_ptr++; 00476 if (bundle == BINK_SRC_X_OFF || bundle == BINK_SRC_Y_OFF) 00477 return (int8_t)*c->bundle[bundle].cur_ptr++; 00478 ret = *(int16_t*)c->bundle[bundle].cur_ptr; 00479 c->bundle[bundle].cur_ptr += 2; 00480 return ret; 00481 } 00482 00492 static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *scan, 00493 int is_intra) 00494 { 00495 int coef_list[128]; 00496 int mode_list[128]; 00497 int i, t, mask, bits, ccoef, mode, sign; 00498 int list_start = 64, list_end = 64, list_pos; 00499 int coef_count = 0; 00500 int coef_idx[64]; 00501 int quant_idx; 00502 const uint32_t *quant; 00503 00504 coef_list[list_end] = 4; mode_list[list_end++] = 0; 00505 coef_list[list_end] = 24; mode_list[list_end++] = 0; 00506 coef_list[list_end] = 44; mode_list[list_end++] = 0; 00507 coef_list[list_end] = 1; mode_list[list_end++] = 3; 00508 coef_list[list_end] = 2; mode_list[list_end++] = 3; 00509 coef_list[list_end] = 3; mode_list[list_end++] = 3; 00510 00511 bits = get_bits(gb, 4) - 1; 00512 for (mask = 1 << bits; bits >= 0; mask >>= 1, bits--) { 00513 list_pos = list_start; 00514 while (list_pos < list_end) { 00515 if (!(mode_list[list_pos] | coef_list[list_pos]) || !get_bits1(gb)) { 00516 list_pos++; 00517 continue; 00518 } 00519 ccoef = coef_list[list_pos]; 00520 mode = mode_list[list_pos]; 00521 switch (mode) { 00522 case 0: 00523 coef_list[list_pos] = ccoef + 4; 00524 mode_list[list_pos] = 1; 00525 case 2: 00526 if (mode == 2) { 00527 coef_list[list_pos] = 0; 00528 mode_list[list_pos++] = 0; 00529 } 00530 for (i = 0; i < 4; i++, ccoef++) { 00531 if (get_bits1(gb)) { 00532 coef_list[--list_start] = ccoef; 00533 mode_list[ list_start] = 3; 00534 } else { 00535 int t; 00536 if (!bits) { 00537 t = 1 - (get_bits1(gb) << 1); 00538 } else { 00539 t = get_bits(gb, bits) | mask; 00540 sign = -get_bits1(gb); 00541 t = (t ^ sign) - sign; 00542 } 00543 block[scan[ccoef]] = t; 00544 coef_idx[coef_count++] = ccoef; 00545 } 00546 } 00547 break; 00548 case 1: 00549 mode_list[list_pos] = 2; 00550 for (i = 0; i < 3; i++) { 00551 ccoef += 4; 00552 coef_list[list_end] = ccoef; 00553 mode_list[list_end++] = 2; 00554 } 00555 break; 00556 case 3: 00557 if (!bits) { 00558 t = 1 - (get_bits1(gb) << 1); 00559 } else { 00560 t = get_bits(gb, bits) | mask; 00561 sign = -get_bits1(gb); 00562 t = (t ^ sign) - sign; 00563 } 00564 block[scan[ccoef]] = t; 00565 coef_idx[coef_count++] = ccoef; 00566 coef_list[list_pos] = 0; 00567 mode_list[list_pos++] = 0; 00568 break; 00569 } 00570 } 00571 } 00572 00573 quant_idx = get_bits(gb, 4); 00574 quant = is_intra ? bink_intra_quant[quant_idx] 00575 : bink_inter_quant[quant_idx]; 00576 block[0] = (block[0] * quant[0]) >> 11; 00577 for (i = 0; i < coef_count; i++) { 00578 int idx = coef_idx[i]; 00579 block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11; 00580 } 00581 00582 return 0; 00583 } 00584 00593 static int read_residue(GetBitContext *gb, DCTELEM block[64], int masks_count) 00594 { 00595 int coef_list[128]; 00596 int mode_list[128]; 00597 int i, sign, mask, ccoef, mode; 00598 int list_start = 64, list_end = 64, list_pos; 00599 int nz_coeff[64]; 00600 int nz_coeff_count = 0; 00601 00602 coef_list[list_end] = 4; mode_list[list_end++] = 0; 00603 coef_list[list_end] = 24; mode_list[list_end++] = 0; 00604 coef_list[list_end] = 44; mode_list[list_end++] = 0; 00605 coef_list[list_end] = 0; mode_list[list_end++] = 2; 00606 00607 for (mask = 1 << get_bits(gb, 3); mask; mask >>= 1) { 00608 for (i = 0; i < nz_coeff_count; i++) { 00609 if (!get_bits1(gb)) 00610 continue; 00611 if (block[nz_coeff[i]] < 0) 00612 block[nz_coeff[i]] -= mask; 00613 else 00614 block[nz_coeff[i]] += mask; 00615 masks_count--; 00616 if (masks_count < 0) 00617 return 0; 00618 } 00619 list_pos = list_start; 00620 while (list_pos < list_end) { 00621 if (!(coef_list[list_pos] | mode_list[list_pos]) || !get_bits1(gb)) { 00622 list_pos++; 00623 continue; 00624 } 00625 ccoef = coef_list[list_pos]; 00626 mode = mode_list[list_pos]; 00627 switch (mode) { 00628 case 0: 00629 coef_list[list_pos] = ccoef + 4; 00630 mode_list[list_pos] = 1; 00631 case 2: 00632 if (mode == 2) { 00633 coef_list[list_pos] = 0; 00634 mode_list[list_pos++] = 0; 00635 } 00636 for (i = 0; i < 4; i++, ccoef++) { 00637 if (get_bits1(gb)) { 00638 coef_list[--list_start] = ccoef; 00639 mode_list[ list_start] = 3; 00640 } else { 00641 nz_coeff[nz_coeff_count++] = bink_scan[ccoef]; 00642 sign = -get_bits1(gb); 00643 block[bink_scan[ccoef]] = (mask ^ sign) - sign; 00644 masks_count--; 00645 if (masks_count < 0) 00646 return 0; 00647 } 00648 } 00649 break; 00650 case 1: 00651 mode_list[list_pos] = 2; 00652 for (i = 0; i < 3; i++) { 00653 ccoef += 4; 00654 coef_list[list_end] = ccoef; 00655 mode_list[list_end++] = 2; 00656 } 00657 break; 00658 case 3: 00659 nz_coeff[nz_coeff_count++] = bink_scan[ccoef]; 00660 sign = -get_bits1(gb); 00661 block[bink_scan[ccoef]] = (mask ^ sign) - sign; 00662 coef_list[list_pos] = 0; 00663 mode_list[list_pos++] = 0; 00664 masks_count--; 00665 if (masks_count < 0) 00666 return 0; 00667 break; 00668 } 00669 } 00670 } 00671 00672 return 0; 00673 } 00674 00675 static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, 00676 int is_chroma) 00677 { 00678 int blk; 00679 int i, j, bx, by; 00680 uint8_t *dst, *prev, *ref, *ref_start, *ref_end; 00681 int v, col[2]; 00682 const uint8_t *scan; 00683 int xoff, yoff; 00684 DECLARE_ALIGNED(16, DCTELEM, block[64]); 00685 DECLARE_ALIGNED(16, uint8_t, ublock[64]); 00686 int coordmap[64]; 00687 00688 const int stride = c->pic.linesize[plane_idx]; 00689 int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; 00690 int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; 00691 int width = c->avctx->width >> is_chroma; 00692 00693 init_lengths(c, FFMAX(width, 8), bw); 00694 for (i = 0; i < BINK_NB_SRC; i++) 00695 read_bundle(gb, c, i); 00696 00697 ref_start = c->last.data[plane_idx]; 00698 ref_end = c->last.data[plane_idx] 00699 + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8; 00700 00701 for (i = 0; i < 64; i++) 00702 coordmap[i] = (i & 7) + (i >> 3) * stride; 00703 00704 for (by = 0; by < bh; by++) { 00705 if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0) 00706 return -1; 00707 if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0) 00708 return -1; 00709 if (read_colors(gb, &c->bundle[BINK_SRC_COLORS], c) < 0) 00710 return -1; 00711 if (read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN]) < 0) 00712 return -1; 00713 if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF]) < 0) 00714 return -1; 00715 if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF]) < 0) 00716 return -1; 00717 if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0) 00718 return -1; 00719 if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0) 00720 return -1; 00721 if (read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN]) < 0) 00722 return -1; 00723 00724 if (by == bh) 00725 break; 00726 dst = c->pic.data[plane_idx] + 8*by*stride; 00727 prev = c->last.data[plane_idx] + 8*by*stride; 00728 for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) { 00729 blk = get_value(c, BINK_SRC_BLOCK_TYPES); 00730 // 16x16 block type on odd line means part of the already decoded block, so skip it 00731 if ((by & 1) && blk == SCALED_BLOCK) { 00732 bx++; 00733 dst += 8; 00734 prev += 8; 00735 continue; 00736 } 00737 switch (blk) { 00738 case SKIP_BLOCK: 00739 c->dsp.put_pixels_tab[1][0](dst, prev, stride, 8); 00740 break; 00741 case SCALED_BLOCK: 00742 blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES); 00743 switch (blk) { 00744 case RUN_BLOCK: 00745 scan = bink_patterns[get_bits(gb, 4)]; 00746 i = 0; 00747 do { 00748 int run = get_value(c, BINK_SRC_RUN) + 1; 00749 00750 i += run; 00751 if (i > 64) { 00752 av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); 00753 return -1; 00754 } 00755 if (get_bits1(gb)) { 00756 v = get_value(c, BINK_SRC_COLORS); 00757 for (j = 0; j < run; j++) 00758 ublock[*scan++] = v; 00759 } else { 00760 for (j = 0; j < run; j++) 00761 ublock[*scan++] = get_value(c, BINK_SRC_COLORS); 00762 } 00763 } while (i < 63); 00764 if (i == 63) 00765 ublock[*scan++] = get_value(c, BINK_SRC_COLORS); 00766 break; 00767 case INTRA_BLOCK: 00768 c->dsp.clear_block(block); 00769 block[0] = get_value(c, BINK_SRC_INTRA_DC); 00770 read_dct_coeffs(gb, block, c->scantable.permutated, 1); 00771 c->dsp.idct(block); 00772 c->dsp.put_pixels_nonclamped(block, ublock, 8); 00773 break; 00774 case FILL_BLOCK: 00775 v = get_value(c, BINK_SRC_COLORS); 00776 c->dsp.fill_block_tab[0](dst, v, stride, 16); 00777 break; 00778 case PATTERN_BLOCK: 00779 for (i = 0; i < 2; i++) 00780 col[i] = get_value(c, BINK_SRC_COLORS); 00781 for (j = 0; j < 8; j++) { 00782 v = get_value(c, BINK_SRC_PATTERN); 00783 for (i = 0; i < 8; i++, v >>= 1) 00784 ublock[i + j*8] = col[v & 1]; 00785 } 00786 break; 00787 case RAW_BLOCK: 00788 for (j = 0; j < 8; j++) 00789 for (i = 0; i < 8; i++) 00790 ublock[i + j*8] = get_value(c, BINK_SRC_COLORS); 00791 break; 00792 default: 00793 av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk); 00794 return -1; 00795 } 00796 if (blk != FILL_BLOCK) 00797 c->dsp.scale_block(ublock, dst, stride); 00798 bx++; 00799 dst += 8; 00800 prev += 8; 00801 break; 00802 case MOTION_BLOCK: 00803 xoff = get_value(c, BINK_SRC_X_OFF); 00804 yoff = get_value(c, BINK_SRC_Y_OFF); 00805 ref = prev + xoff + yoff * stride; 00806 if (ref < ref_start || ref > ref_end) { 00807 av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", 00808 bx*8 + xoff, by*8 + yoff); 00809 return -1; 00810 } 00811 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); 00812 break; 00813 case RUN_BLOCK: 00814 scan = bink_patterns[get_bits(gb, 4)]; 00815 i = 0; 00816 do { 00817 int run = get_value(c, BINK_SRC_RUN) + 1; 00818 00819 i += run; 00820 if (i > 64) { 00821 av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); 00822 return -1; 00823 } 00824 if (get_bits1(gb)) { 00825 v = get_value(c, BINK_SRC_COLORS); 00826 for (j = 0; j < run; j++) 00827 dst[coordmap[*scan++]] = v; 00828 } else { 00829 for (j = 0; j < run; j++) 00830 dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS); 00831 } 00832 } while (i < 63); 00833 if (i == 63) 00834 dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS); 00835 break; 00836 case RESIDUE_BLOCK: 00837 xoff = get_value(c, BINK_SRC_X_OFF); 00838 yoff = get_value(c, BINK_SRC_Y_OFF); 00839 ref = prev + xoff + yoff * stride; 00840 if (ref < ref_start || ref > ref_end) { 00841 av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", 00842 bx*8 + xoff, by*8 + yoff); 00843 return -1; 00844 } 00845 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); 00846 c->dsp.clear_block(block); 00847 v = get_bits(gb, 7); 00848 read_residue(gb, block, v); 00849 c->dsp.add_pixels8(dst, block, stride); 00850 break; 00851 case INTRA_BLOCK: 00852 c->dsp.clear_block(block); 00853 block[0] = get_value(c, BINK_SRC_INTRA_DC); 00854 read_dct_coeffs(gb, block, c->scantable.permutated, 1); 00855 c->dsp.idct_put(dst, stride, block); 00856 break; 00857 case FILL_BLOCK: 00858 v = get_value(c, BINK_SRC_COLORS); 00859 c->dsp.fill_block_tab[1](dst, v, stride, 8); 00860 break; 00861 case INTER_BLOCK: 00862 xoff = get_value(c, BINK_SRC_X_OFF); 00863 yoff = get_value(c, BINK_SRC_Y_OFF); 00864 ref = prev + xoff + yoff * stride; 00865 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); 00866 c->dsp.clear_block(block); 00867 block[0] = get_value(c, BINK_SRC_INTER_DC); 00868 read_dct_coeffs(gb, block, c->scantable.permutated, 0); 00869 c->dsp.idct_add(dst, stride, block); 00870 break; 00871 case PATTERN_BLOCK: 00872 for (i = 0; i < 2; i++) 00873 col[i] = get_value(c, BINK_SRC_COLORS); 00874 for (i = 0; i < 8; i++) { 00875 v = get_value(c, BINK_SRC_PATTERN); 00876 for (j = 0; j < 8; j++, v >>= 1) 00877 dst[i*stride + j] = col[v & 1]; 00878 } 00879 break; 00880 case RAW_BLOCK: 00881 for (i = 0; i < 8; i++) 00882 memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8); 00883 c->bundle[BINK_SRC_COLORS].cur_ptr += 64; 00884 break; 00885 default: 00886 av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); 00887 return -1; 00888 } 00889 } 00890 } 00891 if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary 00892 skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); 00893 00894 return 0; 00895 } 00896 00897 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt) 00898 { 00899 BinkContext * const c = avctx->priv_data; 00900 GetBitContext gb; 00901 int plane, plane_idx; 00902 int bits_count = pkt->size << 3; 00903 00904 if(c->pic.data[0]) 00905 avctx->release_buffer(avctx, &c->pic); 00906 00907 if(avctx->get_buffer(avctx, &c->pic) < 0){ 00908 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 00909 return -1; 00910 } 00911 00912 init_get_bits(&gb, pkt->data, bits_count); 00913 if (c->has_alpha) { 00914 if (c->version >= 'i') 00915 skip_bits_long(&gb, 32); 00916 if (bink_decode_plane(c, &gb, 3, 0) < 0) 00917 return -1; 00918 } 00919 if (c->version >= 'i') 00920 skip_bits_long(&gb, 32); 00921 00922 for (plane = 0; plane < 3; plane++) { 00923 plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); 00924 00925 if (bink_decode_plane(c, &gb, plane_idx, !!plane) < 0) 00926 return -1; 00927 if (get_bits_count(&gb) >= bits_count) 00928 break; 00929 } 00930 emms_c(); 00931 00932 *data_size = sizeof(AVFrame); 00933 *(AVFrame*)data = c->pic; 00934 00935 FFSWAP(AVFrame, c->pic, c->last); 00936 00937 /* always report that the buffer was completely consumed */ 00938 return pkt->size; 00939 } 00940 00941 static av_cold int decode_init(AVCodecContext *avctx) 00942 { 00943 BinkContext * const c = avctx->priv_data; 00944 static VLC_TYPE table[16 * 128][2]; 00945 int i; 00946 int flags; 00947 00948 c->version = avctx->codec_tag >> 24; 00949 if (c->version < 'c') { 00950 av_log(avctx, AV_LOG_ERROR, "Too old version '%c'\n", c->version); 00951 return -1; 00952 } 00953 if (avctx->extradata_size < 4) { 00954 av_log(avctx, AV_LOG_ERROR, "Extradata missing or too short\n"); 00955 return -1; 00956 } 00957 flags = AV_RL32(avctx->extradata); 00958 c->has_alpha = flags & BINK_FLAG_ALPHA; 00959 c->swap_planes = c->version >= 'h'; 00960 if (!bink_trees[15].table) { 00961 for (i = 0; i < 16; i++) { 00962 const int maxbits = bink_tree_lens[i][15]; 00963 bink_trees[i].table = table + i*128; 00964 bink_trees[i].table_allocated = 1 << maxbits; 00965 init_vlc(&bink_trees[i], maxbits, 16, 00966 bink_tree_lens[i], 1, 1, 00967 bink_tree_bits[i], 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); 00968 } 00969 } 00970 c->avctx = avctx; 00971 00972 c->pic.data[0] = NULL; 00973 00974 if (avcodec_check_dimensions(avctx, avctx->width, avctx->height) < 0) { 00975 return 1; 00976 } 00977 00978 avctx->pix_fmt = c->has_alpha ? PIX_FMT_YUVA420P : PIX_FMT_YUV420P; 00979 00980 avctx->idct_algo = FF_IDCT_BINK; 00981 dsputil_init(&c->dsp, avctx); 00982 ff_init_scantable(c->dsp.idct_permutation, &c->scantable, bink_scan); 00983 00984 init_bundles(c); 00985 00986 return 0; 00987 } 00988 00989 static av_cold int decode_end(AVCodecContext *avctx) 00990 { 00991 BinkContext * const c = avctx->priv_data; 00992 00993 if (c->pic.data[0]) 00994 avctx->release_buffer(avctx, &c->pic); 00995 if (c->last.data[0]) 00996 avctx->release_buffer(avctx, &c->last); 00997 00998 free_bundles(c); 00999 return 0; 01000 } 01001 01002 AVCodec bink_decoder = { 01003 "binkvideo", 01004 AVMEDIA_TYPE_VIDEO, 01005 CODEC_ID_BINKVIDEO, 01006 sizeof(BinkContext), 01007 decode_init, 01008 NULL, 01009 decode_end, 01010 decode_frame, 01011 .long_name = NULL_IF_CONFIG_SMALL("Bink video"), 01012 };