Libav 0.7.1
|
00001 /* 00002 * Bink video decoder 00003 * Copyright (c) 2009 Konstantin Shishkov 00004 * Copyright (C) 2011 Peter Ross <pross@xvid.org> 00005 * 00006 * This file is part of Libav. 00007 * 00008 * Libav is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * Libav is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with Libav; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 #include "libavutil/imgutils.h" 00024 #include "avcodec.h" 00025 #include "dsputil.h" 00026 #include "binkdata.h" 00027 #include "mathops.h" 00028 00029 #define ALT_BITSTREAM_READER_LE 00030 #include "get_bits.h" 00031 00032 #define BINK_FLAG_ALPHA 0x00100000 00033 #define BINK_FLAG_GRAY 0x00020000 00034 00035 static VLC bink_trees[16]; 00036 00040 enum OldSources { 00041 BINKB_SRC_BLOCK_TYPES = 0, 00042 BINKB_SRC_COLORS, 00043 BINKB_SRC_PATTERN, 00044 BINKB_SRC_X_OFF, 00045 BINKB_SRC_Y_OFF, 00046 BINKB_SRC_INTRA_DC, 00047 BINKB_SRC_INTER_DC, 00048 BINKB_SRC_INTRA_Q, 00049 BINKB_SRC_INTER_Q, 00050 BINKB_SRC_INTER_COEFS, 00051 00052 BINKB_NB_SRC 00053 }; 00054 00055 static const int binkb_bundle_sizes[BINKB_NB_SRC] = { 00056 4, 8, 8, 5, 5, 11, 11, 4, 4, 7 00057 }; 00058 00059 static const int binkb_bundle_signed[BINKB_NB_SRC] = { 00060 0, 0, 0, 1, 1, 0, 1, 0, 0, 0 00061 }; 00062 00063 static uint32_t binkb_intra_quant[16][64]; 00064 static uint32_t binkb_inter_quant[16][64]; 00065 00069 enum Sources { 00070 BINK_SRC_BLOCK_TYPES = 0, 00071 BINK_SRC_SUB_BLOCK_TYPES, 00072 BINK_SRC_COLORS, 00073 BINK_SRC_PATTERN, 00074 BINK_SRC_X_OFF, 00075 BINK_SRC_Y_OFF, 00076 BINK_SRC_INTRA_DC, 00077 BINK_SRC_INTER_DC, 00078 BINK_SRC_RUN, 00079 00080 BINK_NB_SRC 00081 }; 00082 00086 typedef struct Tree { 00087 int vlc_num; 00088 uint8_t syms[16]; 00089 } Tree; 00090 00091 #define GET_HUFF(gb, tree) (tree).syms[get_vlc2(gb, bink_trees[(tree).vlc_num].table,\ 00092 bink_trees[(tree).vlc_num].bits, 1)] 00093 00097 typedef struct Bundle { 00098 int len; 00099 Tree tree; 00100 uint8_t *data; 00101 uint8_t *data_end; 00102 uint8_t *cur_dec; 00103 uint8_t *cur_ptr; 00104 } Bundle; 00105 00106 /* 00107 * Decoder context 00108 */ 00109 typedef struct BinkContext { 00110 AVCodecContext *avctx; 00111 DSPContext dsp; 00112 AVFrame pic, last; 00113 int version; 00114 int has_alpha; 00115 int swap_planes; 00116 ScanTable scantable; 00117 00118 Bundle bundle[BINKB_NB_SRC]; 00119 Tree col_high[16]; 00120 int col_lastval; 00121 } BinkContext; 00122 00126 enum BlockTypes { 00127 SKIP_BLOCK = 0, 00128 SCALED_BLOCK, 00129 MOTION_BLOCK, 00130 RUN_BLOCK, 00131 RESIDUE_BLOCK, 00132 INTRA_BLOCK, 00133 FILL_BLOCK, 00134 INTER_BLOCK, 00135 PATTERN_BLOCK, 00136 RAW_BLOCK, 00137 }; 00138 00146 static void init_lengths(BinkContext *c, int width, int bw) 00147 { 00148 c->bundle[BINK_SRC_BLOCK_TYPES].len = av_log2((width >> 3) + 511) + 1; 00149 00150 c->bundle[BINK_SRC_SUB_BLOCK_TYPES].len = av_log2((width >> 4) + 511) + 1; 00151 00152 c->bundle[BINK_SRC_COLORS].len = av_log2(bw*64 + 511) + 1; 00153 00154 c->bundle[BINK_SRC_INTRA_DC].len = 00155 c->bundle[BINK_SRC_INTER_DC].len = 00156 c->bundle[BINK_SRC_X_OFF].len = 00157 c->bundle[BINK_SRC_Y_OFF].len = av_log2((width >> 3) + 511) + 1; 00158 00159 c->bundle[BINK_SRC_PATTERN].len = av_log2((bw << 3) + 511) + 1; 00160 00161 c->bundle[BINK_SRC_RUN].len = av_log2(bw*48 + 511) + 1; 00162 } 00163 00169 static av_cold void init_bundles(BinkContext *c) 00170 { 00171 int bw, bh, blocks; 00172 int i; 00173 00174 bw = (c->avctx->width + 7) >> 3; 00175 bh = (c->avctx->height + 7) >> 3; 00176 blocks = bw * bh; 00177 00178 for (i = 0; i < BINKB_NB_SRC; i++) { 00179 c->bundle[i].data = av_malloc(blocks * 64); 00180 c->bundle[i].data_end = c->bundle[i].data + blocks * 64; 00181 } 00182 } 00183 00189 static av_cold void free_bundles(BinkContext *c) 00190 { 00191 int i; 00192 for (i = 0; i < BINKB_NB_SRC; i++) 00193 av_freep(&c->bundle[i].data); 00194 } 00195 00204 static void merge(GetBitContext *gb, uint8_t *dst, uint8_t *src, int size) 00205 { 00206 uint8_t *src2 = src + size; 00207 int size2 = size; 00208 00209 do { 00210 if (!get_bits1(gb)) { 00211 *dst++ = *src++; 00212 size--; 00213 } else { 00214 *dst++ = *src2++; 00215 size2--; 00216 } 00217 } while (size && size2); 00218 00219 while (size--) 00220 *dst++ = *src++; 00221 while (size2--) 00222 *dst++ = *src2++; 00223 } 00224 00231 static void read_tree(GetBitContext *gb, Tree *tree) 00232 { 00233 uint8_t tmp1[16], tmp2[16], *in = tmp1, *out = tmp2; 00234 int i, t, len; 00235 00236 tree->vlc_num = get_bits(gb, 4); 00237 if (!tree->vlc_num) { 00238 for (i = 0; i < 16; i++) 00239 tree->syms[i] = i; 00240 return; 00241 } 00242 if (get_bits1(gb)) { 00243 len = get_bits(gb, 3); 00244 memset(tmp1, 0, sizeof(tmp1)); 00245 for (i = 0; i <= len; i++) { 00246 tree->syms[i] = get_bits(gb, 4); 00247 tmp1[tree->syms[i]] = 1; 00248 } 00249 for (i = 0; i < 16; i++) 00250 if (!tmp1[i]) 00251 tree->syms[++len] = i; 00252 } else { 00253 len = get_bits(gb, 2); 00254 for (i = 0; i < 16; i++) 00255 in[i] = i; 00256 for (i = 0; i <= len; i++) { 00257 int size = 1 << i; 00258 for (t = 0; t < 16; t += size << 1) 00259 merge(gb, out + t, in + t, size); 00260 FFSWAP(uint8_t*, in, out); 00261 } 00262 memcpy(tree->syms, in, 16); 00263 } 00264 } 00265 00273 static void read_bundle(GetBitContext *gb, BinkContext *c, int bundle_num) 00274 { 00275 int i; 00276 00277 if (bundle_num == BINK_SRC_COLORS) { 00278 for (i = 0; i < 16; i++) 00279 read_tree(gb, &c->col_high[i]); 00280 c->col_lastval = 0; 00281 } 00282 if (bundle_num != BINK_SRC_INTRA_DC && bundle_num != BINK_SRC_INTER_DC) 00283 read_tree(gb, &c->bundle[bundle_num].tree); 00284 c->bundle[bundle_num].cur_dec = 00285 c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data; 00286 } 00287 00295 #define CHECK_READ_VAL(gb, b, t) \ 00296 if (!b->cur_dec || (b->cur_dec > b->cur_ptr)) \ 00297 return 0; \ 00298 t = get_bits(gb, b->len); \ 00299 if (!t) { \ 00300 b->cur_dec = NULL; \ 00301 return 0; \ 00302 } \ 00303 00304 static int read_runs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 00305 { 00306 int t, v; 00307 const uint8_t *dec_end; 00308 00309 CHECK_READ_VAL(gb, b, t); 00310 dec_end = b->cur_dec + t; 00311 if (dec_end > b->data_end) { 00312 av_log(avctx, AV_LOG_ERROR, "Run value went out of bounds\n"); 00313 return -1; 00314 } 00315 if (get_bits1(gb)) { 00316 v = get_bits(gb, 4); 00317 memset(b->cur_dec, v, t); 00318 b->cur_dec += t; 00319 } else { 00320 while (b->cur_dec < dec_end) 00321 *b->cur_dec++ = GET_HUFF(gb, b->tree); 00322 } 00323 return 0; 00324 } 00325 00326 static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 00327 { 00328 int t, sign, v; 00329 const uint8_t *dec_end; 00330 00331 CHECK_READ_VAL(gb, b, t); 00332 dec_end = b->cur_dec + t; 00333 if (dec_end > b->data_end) { 00334 av_log(avctx, AV_LOG_ERROR, "Too many motion values\n"); 00335 return -1; 00336 } 00337 if (get_bits1(gb)) { 00338 v = get_bits(gb, 4); 00339 if (v) { 00340 sign = -get_bits1(gb); 00341 v = (v ^ sign) - sign; 00342 } 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) { 00349 sign = -get_bits1(gb); 00350 v = (v ^ sign) - sign; 00351 } 00352 *b->cur_dec++ = v; 00353 } while (b->cur_dec < dec_end); 00354 } 00355 return 0; 00356 } 00357 00358 static const uint8_t bink_rlelens[4] = { 4, 8, 12, 32 }; 00359 00360 static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 00361 { 00362 int t, v; 00363 int last = 0; 00364 const uint8_t *dec_end; 00365 00366 CHECK_READ_VAL(gb, b, t); 00367 dec_end = b->cur_dec + t; 00368 if (dec_end > b->data_end) { 00369 av_log(avctx, AV_LOG_ERROR, "Too many block type values\n"); 00370 return -1; 00371 } 00372 if (get_bits1(gb)) { 00373 v = get_bits(gb, 4); 00374 memset(b->cur_dec, v, t); 00375 b->cur_dec += t; 00376 } else { 00377 do { 00378 v = GET_HUFF(gb, b->tree); 00379 if (v < 12) { 00380 last = v; 00381 *b->cur_dec++ = v; 00382 } else { 00383 int run = bink_rlelens[v - 12]; 00384 00385 memset(b->cur_dec, last, run); 00386 b->cur_dec += run; 00387 } 00388 } while (b->cur_dec < dec_end); 00389 } 00390 return 0; 00391 } 00392 00393 static int read_patterns(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) 00394 { 00395 int t, v; 00396 const uint8_t *dec_end; 00397 00398 CHECK_READ_VAL(gb, b, t); 00399 dec_end = b->cur_dec + t; 00400 if (dec_end > b->data_end) { 00401 av_log(avctx, AV_LOG_ERROR, "Too many pattern values\n"); 00402 return -1; 00403 } 00404 while (b->cur_dec < dec_end) { 00405 v = GET_HUFF(gb, b->tree); 00406 v |= GET_HUFF(gb, b->tree) << 4; 00407 *b->cur_dec++ = v; 00408 } 00409 00410 return 0; 00411 } 00412 00413 static int read_colors(GetBitContext *gb, Bundle *b, BinkContext *c) 00414 { 00415 int t, sign, v; 00416 const uint8_t *dec_end; 00417 00418 CHECK_READ_VAL(gb, b, t); 00419 dec_end = b->cur_dec + t; 00420 if (dec_end > b->data_end) { 00421 av_log(c->avctx, AV_LOG_ERROR, "Too many color values\n"); 00422 return -1; 00423 } 00424 if (get_bits1(gb)) { 00425 c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); 00426 v = GET_HUFF(gb, b->tree); 00427 v = (c->col_lastval << 4) | v; 00428 if (c->version < 'i') { 00429 sign = ((int8_t) v) >> 7; 00430 v = ((v & 0x7F) ^ sign) - sign; 00431 v += 0x80; 00432 } 00433 memset(b->cur_dec, v, t); 00434 b->cur_dec += t; 00435 } else { 00436 while (b->cur_dec < dec_end) { 00437 c->col_lastval = GET_HUFF(gb, c->col_high[c->col_lastval]); 00438 v = GET_HUFF(gb, b->tree); 00439 v = (c->col_lastval << 4) | v; 00440 if (c->version < 'i') { 00441 sign = ((int8_t) v) >> 7; 00442 v = ((v & 0x7F) ^ sign) - sign; 00443 v += 0x80; 00444 } 00445 *b->cur_dec++ = v; 00446 } 00447 } 00448 return 0; 00449 } 00450 00452 #define DC_START_BITS 11 00453 00454 static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, 00455 int start_bits, int has_sign) 00456 { 00457 int i, j, len, len2, bsize, sign, v, v2; 00458 int16_t *dst = (int16_t*)b->cur_dec; 00459 00460 CHECK_READ_VAL(gb, b, len); 00461 v = get_bits(gb, start_bits - has_sign); 00462 if (v && has_sign) { 00463 sign = -get_bits1(gb); 00464 v = (v ^ sign) - sign; 00465 } 00466 *dst++ = v; 00467 len--; 00468 for (i = 0; i < len; i += 8) { 00469 len2 = FFMIN(len - i, 8); 00470 bsize = get_bits(gb, 4); 00471 if (bsize) { 00472 for (j = 0; j < len2; j++) { 00473 v2 = get_bits(gb, bsize); 00474 if (v2) { 00475 sign = -get_bits1(gb); 00476 v2 = (v2 ^ sign) - sign; 00477 } 00478 v += v2; 00479 *dst++ = v; 00480 if (v < -32768 || v > 32767) { 00481 av_log(avctx, AV_LOG_ERROR, "DC value went out of bounds: %d\n", v); 00482 return -1; 00483 } 00484 } 00485 } else { 00486 for (j = 0; j < len2; j++) 00487 *dst++ = v; 00488 } 00489 } 00490 00491 b->cur_dec = (uint8_t*)dst; 00492 return 0; 00493 } 00494 00501 static inline int get_value(BinkContext *c, int bundle) 00502 { 00503 int ret; 00504 00505 if (bundle < BINK_SRC_X_OFF || bundle == BINK_SRC_RUN) 00506 return *c->bundle[bundle].cur_ptr++; 00507 if (bundle == BINK_SRC_X_OFF || bundle == BINK_SRC_Y_OFF) 00508 return (int8_t)*c->bundle[bundle].cur_ptr++; 00509 ret = *(int16_t*)c->bundle[bundle].cur_ptr; 00510 c->bundle[bundle].cur_ptr += 2; 00511 return ret; 00512 } 00513 00514 static void binkb_init_bundle(BinkContext *c, int bundle_num) 00515 { 00516 c->bundle[bundle_num].cur_dec = 00517 c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data; 00518 c->bundle[bundle_num].len = 13; 00519 } 00520 00521 static void binkb_init_bundles(BinkContext *c) 00522 { 00523 int i; 00524 for (i = 0; i < BINKB_NB_SRC; i++) 00525 binkb_init_bundle(c, i); 00526 } 00527 00528 static int binkb_read_bundle(BinkContext *c, GetBitContext *gb, int bundle_num) 00529 { 00530 const int bits = binkb_bundle_sizes[bundle_num]; 00531 const int mask = 1 << (bits - 1); 00532 const int issigned = binkb_bundle_signed[bundle_num]; 00533 Bundle *b = &c->bundle[bundle_num]; 00534 int i, len; 00535 00536 CHECK_READ_VAL(gb, b, len); 00537 if (bits <= 8) { 00538 if (!issigned) { 00539 for (i = 0; i < len; i++) 00540 *b->cur_dec++ = get_bits(gb, bits); 00541 } else { 00542 for (i = 0; i < len; i++) 00543 *b->cur_dec++ = get_bits(gb, bits) - mask; 00544 } 00545 } else { 00546 int16_t *dst = (int16_t*)b->cur_dec; 00547 00548 if (!issigned) { 00549 for (i = 0; i < len; i++) 00550 *dst++ = get_bits(gb, bits); 00551 } else { 00552 for (i = 0; i < len; i++) 00553 *dst++ = get_bits(gb, bits) - mask; 00554 } 00555 b->cur_dec = (uint8_t*)dst; 00556 } 00557 return 0; 00558 } 00559 00560 static inline int binkb_get_value(BinkContext *c, int bundle_num) 00561 { 00562 int16_t ret; 00563 const int bits = binkb_bundle_sizes[bundle_num]; 00564 00565 if (bits <= 8) { 00566 int val = *c->bundle[bundle_num].cur_ptr++; 00567 return binkb_bundle_signed[bundle_num] ? (int8_t)val : val; 00568 } 00569 ret = *(int16_t*)c->bundle[bundle_num].cur_ptr; 00570 c->bundle[bundle_num].cur_ptr += 2; 00571 return ret; 00572 } 00573 00583 static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *scan, 00584 const uint32_t quant_matrices[16][64], int q) 00585 { 00586 int coef_list[128]; 00587 int mode_list[128]; 00588 int i, t, mask, bits, ccoef, mode, sign; 00589 int list_start = 64, list_end = 64, list_pos; 00590 int coef_count = 0; 00591 int coef_idx[64]; 00592 int quant_idx; 00593 const uint32_t *quant; 00594 00595 coef_list[list_end] = 4; mode_list[list_end++] = 0; 00596 coef_list[list_end] = 24; mode_list[list_end++] = 0; 00597 coef_list[list_end] = 44; mode_list[list_end++] = 0; 00598 coef_list[list_end] = 1; mode_list[list_end++] = 3; 00599 coef_list[list_end] = 2; mode_list[list_end++] = 3; 00600 coef_list[list_end] = 3; mode_list[list_end++] = 3; 00601 00602 bits = get_bits(gb, 4) - 1; 00603 for (mask = 1 << bits; bits >= 0; mask >>= 1, bits--) { 00604 list_pos = list_start; 00605 while (list_pos < list_end) { 00606 if (!(mode_list[list_pos] | coef_list[list_pos]) || !get_bits1(gb)) { 00607 list_pos++; 00608 continue; 00609 } 00610 ccoef = coef_list[list_pos]; 00611 mode = mode_list[list_pos]; 00612 switch (mode) { 00613 case 0: 00614 coef_list[list_pos] = ccoef + 4; 00615 mode_list[list_pos] = 1; 00616 case 2: 00617 if (mode == 2) { 00618 coef_list[list_pos] = 0; 00619 mode_list[list_pos++] = 0; 00620 } 00621 for (i = 0; i < 4; i++, ccoef++) { 00622 if (get_bits1(gb)) { 00623 coef_list[--list_start] = ccoef; 00624 mode_list[ list_start] = 3; 00625 } else { 00626 int t; 00627 if (!bits) { 00628 t = 1 - (get_bits1(gb) << 1); 00629 } else { 00630 t = get_bits(gb, bits) | mask; 00631 sign = -get_bits1(gb); 00632 t = (t ^ sign) - sign; 00633 } 00634 block[scan[ccoef]] = t; 00635 coef_idx[coef_count++] = ccoef; 00636 } 00637 } 00638 break; 00639 case 1: 00640 mode_list[list_pos] = 2; 00641 for (i = 0; i < 3; i++) { 00642 ccoef += 4; 00643 coef_list[list_end] = ccoef; 00644 mode_list[list_end++] = 2; 00645 } 00646 break; 00647 case 3: 00648 if (!bits) { 00649 t = 1 - (get_bits1(gb) << 1); 00650 } else { 00651 t = get_bits(gb, bits) | mask; 00652 sign = -get_bits1(gb); 00653 t = (t ^ sign) - sign; 00654 } 00655 block[scan[ccoef]] = t; 00656 coef_idx[coef_count++] = ccoef; 00657 coef_list[list_pos] = 0; 00658 mode_list[list_pos++] = 0; 00659 break; 00660 } 00661 } 00662 } 00663 00664 if (q == -1) { 00665 quant_idx = get_bits(gb, 4); 00666 } else { 00667 quant_idx = q; 00668 } 00669 00670 quant = quant_matrices[quant_idx]; 00671 00672 block[0] = (block[0] * quant[0]) >> 11; 00673 for (i = 0; i < coef_count; i++) { 00674 int idx = coef_idx[i]; 00675 block[scan[idx]] = (block[scan[idx]] * quant[idx]) >> 11; 00676 } 00677 00678 return 0; 00679 } 00680 00689 static int read_residue(GetBitContext *gb, DCTELEM block[64], int masks_count) 00690 { 00691 int coef_list[128]; 00692 int mode_list[128]; 00693 int i, sign, mask, ccoef, mode; 00694 int list_start = 64, list_end = 64, list_pos; 00695 int nz_coeff[64]; 00696 int nz_coeff_count = 0; 00697 00698 coef_list[list_end] = 4; mode_list[list_end++] = 0; 00699 coef_list[list_end] = 24; mode_list[list_end++] = 0; 00700 coef_list[list_end] = 44; mode_list[list_end++] = 0; 00701 coef_list[list_end] = 0; mode_list[list_end++] = 2; 00702 00703 for (mask = 1 << get_bits(gb, 3); mask; mask >>= 1) { 00704 for (i = 0; i < nz_coeff_count; i++) { 00705 if (!get_bits1(gb)) 00706 continue; 00707 if (block[nz_coeff[i]] < 0) 00708 block[nz_coeff[i]] -= mask; 00709 else 00710 block[nz_coeff[i]] += mask; 00711 masks_count--; 00712 if (masks_count < 0) 00713 return 0; 00714 } 00715 list_pos = list_start; 00716 while (list_pos < list_end) { 00717 if (!(coef_list[list_pos] | mode_list[list_pos]) || !get_bits1(gb)) { 00718 list_pos++; 00719 continue; 00720 } 00721 ccoef = coef_list[list_pos]; 00722 mode = mode_list[list_pos]; 00723 switch (mode) { 00724 case 0: 00725 coef_list[list_pos] = ccoef + 4; 00726 mode_list[list_pos] = 1; 00727 case 2: 00728 if (mode == 2) { 00729 coef_list[list_pos] = 0; 00730 mode_list[list_pos++] = 0; 00731 } 00732 for (i = 0; i < 4; i++, ccoef++) { 00733 if (get_bits1(gb)) { 00734 coef_list[--list_start] = ccoef; 00735 mode_list[ list_start] = 3; 00736 } else { 00737 nz_coeff[nz_coeff_count++] = bink_scan[ccoef]; 00738 sign = -get_bits1(gb); 00739 block[bink_scan[ccoef]] = (mask ^ sign) - sign; 00740 masks_count--; 00741 if (masks_count < 0) 00742 return 0; 00743 } 00744 } 00745 break; 00746 case 1: 00747 mode_list[list_pos] = 2; 00748 for (i = 0; i < 3; i++) { 00749 ccoef += 4; 00750 coef_list[list_end] = ccoef; 00751 mode_list[list_end++] = 2; 00752 } 00753 break; 00754 case 3: 00755 nz_coeff[nz_coeff_count++] = bink_scan[ccoef]; 00756 sign = -get_bits1(gb); 00757 block[bink_scan[ccoef]] = (mask ^ sign) - sign; 00758 coef_list[list_pos] = 0; 00759 mode_list[list_pos++] = 0; 00760 masks_count--; 00761 if (masks_count < 0) 00762 return 0; 00763 break; 00764 } 00765 } 00766 } 00767 00768 return 0; 00769 } 00770 00774 static inline void put_pixels8x8_overlapped(uint8_t *dst, uint8_t *src, int stride) 00775 { 00776 uint8_t tmp[64]; 00777 int i; 00778 for (i = 0; i < 8; i++) 00779 memcpy(tmp + i*8, src + i*stride, 8); 00780 for (i = 0; i < 8; i++) 00781 memcpy(dst + i*stride, tmp + i*8, 8); 00782 } 00783 00784 static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, 00785 int is_key, int is_chroma) 00786 { 00787 int blk; 00788 int i, j, bx, by; 00789 uint8_t *dst, *ref, *ref_start, *ref_end; 00790 int v, col[2]; 00791 const uint8_t *scan; 00792 int xoff, yoff; 00793 LOCAL_ALIGNED_16(DCTELEM, block, [64]); 00794 int coordmap[64]; 00795 int ybias = is_key ? -15 : 0; 00796 int qp; 00797 00798 const int stride = c->pic.linesize[plane_idx]; 00799 int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; 00800 int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; 00801 00802 binkb_init_bundles(c); 00803 ref_start = c->pic.data[plane_idx]; 00804 ref_end = c->pic.data[plane_idx] + (bh * c->pic.linesize[plane_idx] + bw) * 8; 00805 00806 for (i = 0; i < 64; i++) 00807 coordmap[i] = (i & 7) + (i >> 3) * stride; 00808 00809 for (by = 0; by < bh; by++) { 00810 for (i = 0; i < BINKB_NB_SRC; i++) { 00811 if (binkb_read_bundle(c, gb, i) < 0) 00812 return -1; 00813 } 00814 00815 dst = c->pic.data[plane_idx] + 8*by*stride; 00816 for (bx = 0; bx < bw; bx++, dst += 8) { 00817 blk = binkb_get_value(c, BINKB_SRC_BLOCK_TYPES); 00818 switch (blk) { 00819 case 0: 00820 break; 00821 case 1: 00822 scan = bink_patterns[get_bits(gb, 4)]; 00823 i = 0; 00824 do { 00825 int mode, run; 00826 00827 mode = get_bits1(gb); 00828 run = get_bits(gb, binkb_runbits[i]) + 1; 00829 00830 i += run; 00831 if (i > 64) { 00832 av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); 00833 return -1; 00834 } 00835 if (mode) { 00836 v = binkb_get_value(c, BINKB_SRC_COLORS); 00837 for (j = 0; j < run; j++) 00838 dst[coordmap[*scan++]] = v; 00839 } else { 00840 for (j = 0; j < run; j++) 00841 dst[coordmap[*scan++]] = binkb_get_value(c, BINKB_SRC_COLORS); 00842 } 00843 } while (i < 63); 00844 if (i == 63) 00845 dst[coordmap[*scan++]] = binkb_get_value(c, BINKB_SRC_COLORS); 00846 break; 00847 case 2: 00848 c->dsp.clear_block(block); 00849 block[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC); 00850 qp = binkb_get_value(c, BINKB_SRC_INTRA_Q); 00851 read_dct_coeffs(gb, block, c->scantable.permutated, binkb_intra_quant, qp); 00852 c->dsp.idct_put(dst, stride, block); 00853 break; 00854 case 3: 00855 xoff = binkb_get_value(c, BINKB_SRC_X_OFF); 00856 yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; 00857 ref = dst + xoff + yoff * stride; 00858 if (ref < ref_start || ref + 8*stride > ref_end) { 00859 av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); 00860 } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { 00861 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); 00862 } else { 00863 put_pixels8x8_overlapped(dst, ref, stride); 00864 } 00865 c->dsp.clear_block(block); 00866 v = binkb_get_value(c, BINKB_SRC_INTER_COEFS); 00867 read_residue(gb, block, v); 00868 c->dsp.add_pixels8(dst, block, stride); 00869 break; 00870 case 4: 00871 xoff = binkb_get_value(c, BINKB_SRC_X_OFF); 00872 yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; 00873 ref = dst + xoff + yoff * stride; 00874 if (ref < ref_start || ref + 8 * stride > ref_end) { 00875 av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); 00876 } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { 00877 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); 00878 } else { 00879 put_pixels8x8_overlapped(dst, ref, stride); 00880 } 00881 c->dsp.clear_block(block); 00882 block[0] = binkb_get_value(c, BINKB_SRC_INTER_DC); 00883 qp = binkb_get_value(c, BINKB_SRC_INTER_Q); 00884 read_dct_coeffs(gb, block, c->scantable.permutated, binkb_inter_quant, qp); 00885 c->dsp.idct_add(dst, stride, block); 00886 break; 00887 case 5: 00888 v = binkb_get_value(c, BINKB_SRC_COLORS); 00889 c->dsp.fill_block_tab[1](dst, v, stride, 8); 00890 break; 00891 case 6: 00892 for (i = 0; i < 2; i++) 00893 col[i] = binkb_get_value(c, BINKB_SRC_COLORS); 00894 for (i = 0; i < 8; i++) { 00895 v = binkb_get_value(c, BINKB_SRC_PATTERN); 00896 for (j = 0; j < 8; j++, v >>= 1) 00897 dst[i*stride + j] = col[v & 1]; 00898 } 00899 break; 00900 case 7: 00901 xoff = binkb_get_value(c, BINKB_SRC_X_OFF); 00902 yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; 00903 ref = dst + xoff + yoff * stride; 00904 if (ref < ref_start || ref + 8 * stride > ref_end) { 00905 av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); 00906 } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { 00907 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); 00908 } else { 00909 put_pixels8x8_overlapped(dst, ref, stride); 00910 } 00911 break; 00912 case 8: 00913 for (i = 0; i < 8; i++) 00914 memcpy(dst + i*stride, c->bundle[BINKB_SRC_COLORS].cur_ptr + i*8, 8); 00915 c->bundle[BINKB_SRC_COLORS].cur_ptr += 64; 00916 break; 00917 default: 00918 av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); 00919 return -1; 00920 } 00921 } 00922 } 00923 if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary 00924 skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); 00925 00926 return 0; 00927 } 00928 00929 static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, 00930 int is_chroma) 00931 { 00932 int blk; 00933 int i, j, bx, by; 00934 uint8_t *dst, *prev, *ref, *ref_start, *ref_end; 00935 int v, col[2]; 00936 const uint8_t *scan; 00937 int xoff, yoff; 00938 LOCAL_ALIGNED_16(DCTELEM, block, [64]); 00939 LOCAL_ALIGNED_16(uint8_t, ublock, [64]); 00940 int coordmap[64]; 00941 00942 const int stride = c->pic.linesize[plane_idx]; 00943 int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; 00944 int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; 00945 int width = c->avctx->width >> is_chroma; 00946 00947 init_lengths(c, FFMAX(width, 8), bw); 00948 for (i = 0; i < BINK_NB_SRC; i++) 00949 read_bundle(gb, c, i); 00950 00951 ref_start = c->last.data[plane_idx]; 00952 ref_end = c->last.data[plane_idx] 00953 + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8; 00954 00955 for (i = 0; i < 64; i++) 00956 coordmap[i] = (i & 7) + (i >> 3) * stride; 00957 00958 for (by = 0; by < bh; by++) { 00959 if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0) 00960 return -1; 00961 if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0) 00962 return -1; 00963 if (read_colors(gb, &c->bundle[BINK_SRC_COLORS], c) < 0) 00964 return -1; 00965 if (read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN]) < 0) 00966 return -1; 00967 if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF]) < 0) 00968 return -1; 00969 if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF]) < 0) 00970 return -1; 00971 if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0) 00972 return -1; 00973 if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0) 00974 return -1; 00975 if (read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN]) < 0) 00976 return -1; 00977 00978 if (by == bh) 00979 break; 00980 dst = c->pic.data[plane_idx] + 8*by*stride; 00981 prev = c->last.data[plane_idx] + 8*by*stride; 00982 for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) { 00983 blk = get_value(c, BINK_SRC_BLOCK_TYPES); 00984 // 16x16 block type on odd line means part of the already decoded block, so skip it 00985 if ((by & 1) && blk == SCALED_BLOCK) { 00986 bx++; 00987 dst += 8; 00988 prev += 8; 00989 continue; 00990 } 00991 switch (blk) { 00992 case SKIP_BLOCK: 00993 c->dsp.put_pixels_tab[1][0](dst, prev, stride, 8); 00994 break; 00995 case SCALED_BLOCK: 00996 blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES); 00997 switch (blk) { 00998 case RUN_BLOCK: 00999 scan = bink_patterns[get_bits(gb, 4)]; 01000 i = 0; 01001 do { 01002 int run = get_value(c, BINK_SRC_RUN) + 1; 01003 01004 i += run; 01005 if (i > 64) { 01006 av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); 01007 return -1; 01008 } 01009 if (get_bits1(gb)) { 01010 v = get_value(c, BINK_SRC_COLORS); 01011 for (j = 0; j < run; j++) 01012 ublock[*scan++] = v; 01013 } else { 01014 for (j = 0; j < run; j++) 01015 ublock[*scan++] = get_value(c, BINK_SRC_COLORS); 01016 } 01017 } while (i < 63); 01018 if (i == 63) 01019 ublock[*scan++] = get_value(c, BINK_SRC_COLORS); 01020 break; 01021 case INTRA_BLOCK: 01022 c->dsp.clear_block(block); 01023 block[0] = get_value(c, BINK_SRC_INTRA_DC); 01024 read_dct_coeffs(gb, block, c->scantable.permutated, bink_intra_quant, -1); 01025 c->dsp.idct(block); 01026 c->dsp.put_pixels_nonclamped(block, ublock, 8); 01027 break; 01028 case FILL_BLOCK: 01029 v = get_value(c, BINK_SRC_COLORS); 01030 c->dsp.fill_block_tab[0](dst, v, stride, 16); 01031 break; 01032 case PATTERN_BLOCK: 01033 for (i = 0; i < 2; i++) 01034 col[i] = get_value(c, BINK_SRC_COLORS); 01035 for (j = 0; j < 8; j++) { 01036 v = get_value(c, BINK_SRC_PATTERN); 01037 for (i = 0; i < 8; i++, v >>= 1) 01038 ublock[i + j*8] = col[v & 1]; 01039 } 01040 break; 01041 case RAW_BLOCK: 01042 for (j = 0; j < 8; j++) 01043 for (i = 0; i < 8; i++) 01044 ublock[i + j*8] = get_value(c, BINK_SRC_COLORS); 01045 break; 01046 default: 01047 av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk); 01048 return -1; 01049 } 01050 if (blk != FILL_BLOCK) 01051 c->dsp.scale_block(ublock, dst, stride); 01052 bx++; 01053 dst += 8; 01054 prev += 8; 01055 break; 01056 case MOTION_BLOCK: 01057 xoff = get_value(c, BINK_SRC_X_OFF); 01058 yoff = get_value(c, BINK_SRC_Y_OFF); 01059 ref = prev + xoff + yoff * stride; 01060 if (ref < ref_start || ref > ref_end) { 01061 av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", 01062 bx*8 + xoff, by*8 + yoff); 01063 return -1; 01064 } 01065 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); 01066 break; 01067 case RUN_BLOCK: 01068 scan = bink_patterns[get_bits(gb, 4)]; 01069 i = 0; 01070 do { 01071 int run = get_value(c, BINK_SRC_RUN) + 1; 01072 01073 i += run; 01074 if (i > 64) { 01075 av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); 01076 return -1; 01077 } 01078 if (get_bits1(gb)) { 01079 v = get_value(c, BINK_SRC_COLORS); 01080 for (j = 0; j < run; j++) 01081 dst[coordmap[*scan++]] = v; 01082 } else { 01083 for (j = 0; j < run; j++) 01084 dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS); 01085 } 01086 } while (i < 63); 01087 if (i == 63) 01088 dst[coordmap[*scan++]] = get_value(c, BINK_SRC_COLORS); 01089 break; 01090 case RESIDUE_BLOCK: 01091 xoff = get_value(c, BINK_SRC_X_OFF); 01092 yoff = get_value(c, BINK_SRC_Y_OFF); 01093 ref = prev + xoff + yoff * stride; 01094 if (ref < ref_start || ref > ref_end) { 01095 av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", 01096 bx*8 + xoff, by*8 + yoff); 01097 return -1; 01098 } 01099 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); 01100 c->dsp.clear_block(block); 01101 v = get_bits(gb, 7); 01102 read_residue(gb, block, v); 01103 c->dsp.add_pixels8(dst, block, stride); 01104 break; 01105 case INTRA_BLOCK: 01106 c->dsp.clear_block(block); 01107 block[0] = get_value(c, BINK_SRC_INTRA_DC); 01108 read_dct_coeffs(gb, block, c->scantable.permutated, bink_intra_quant, -1); 01109 c->dsp.idct_put(dst, stride, block); 01110 break; 01111 case FILL_BLOCK: 01112 v = get_value(c, BINK_SRC_COLORS); 01113 c->dsp.fill_block_tab[1](dst, v, stride, 8); 01114 break; 01115 case INTER_BLOCK: 01116 xoff = get_value(c, BINK_SRC_X_OFF); 01117 yoff = get_value(c, BINK_SRC_Y_OFF); 01118 ref = prev + xoff + yoff * stride; 01119 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); 01120 c->dsp.clear_block(block); 01121 block[0] = get_value(c, BINK_SRC_INTER_DC); 01122 read_dct_coeffs(gb, block, c->scantable.permutated, bink_inter_quant, -1); 01123 c->dsp.idct_add(dst, stride, block); 01124 break; 01125 case PATTERN_BLOCK: 01126 for (i = 0; i < 2; i++) 01127 col[i] = get_value(c, BINK_SRC_COLORS); 01128 for (i = 0; i < 8; i++) { 01129 v = get_value(c, BINK_SRC_PATTERN); 01130 for (j = 0; j < 8; j++, v >>= 1) 01131 dst[i*stride + j] = col[v & 1]; 01132 } 01133 break; 01134 case RAW_BLOCK: 01135 for (i = 0; i < 8; i++) 01136 memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8); 01137 c->bundle[BINK_SRC_COLORS].cur_ptr += 64; 01138 break; 01139 default: 01140 av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); 01141 return -1; 01142 } 01143 } 01144 } 01145 if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary 01146 skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); 01147 01148 return 0; 01149 } 01150 01151 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt) 01152 { 01153 BinkContext * const c = avctx->priv_data; 01154 GetBitContext gb; 01155 int plane, plane_idx; 01156 int bits_count = pkt->size << 3; 01157 01158 if (c->version > 'b') { 01159 if(c->pic.data[0]) 01160 avctx->release_buffer(avctx, &c->pic); 01161 01162 if(avctx->get_buffer(avctx, &c->pic) < 0){ 01163 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); 01164 return -1; 01165 } 01166 } else { 01167 if(avctx->reget_buffer(avctx, &c->pic) < 0){ 01168 av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); 01169 return -1; 01170 } 01171 } 01172 01173 init_get_bits(&gb, pkt->data, bits_count); 01174 if (c->has_alpha) { 01175 if (c->version >= 'i') 01176 skip_bits_long(&gb, 32); 01177 if (bink_decode_plane(c, &gb, 3, 0) < 0) 01178 return -1; 01179 } 01180 if (c->version >= 'i') 01181 skip_bits_long(&gb, 32); 01182 01183 for (plane = 0; plane < 3; plane++) { 01184 plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); 01185 01186 if (c->version > 'b') { 01187 if (bink_decode_plane(c, &gb, plane_idx, !!plane) < 0) 01188 return -1; 01189 } else { 01190 if (binkb_decode_plane(c, &gb, plane_idx, !pkt->pts, !!plane) < 0) 01191 return -1; 01192 } 01193 if (get_bits_count(&gb) >= bits_count) 01194 break; 01195 } 01196 emms_c(); 01197 01198 *data_size = sizeof(AVFrame); 01199 *(AVFrame*)data = c->pic; 01200 01201 if (c->version > 'b') 01202 FFSWAP(AVFrame, c->pic, c->last); 01203 01204 /* always report that the buffer was completely consumed */ 01205 return pkt->size; 01206 } 01207 01211 static av_cold void binkb_calc_quant(void) 01212 { 01213 uint8_t inv_bink_scan[64]; 01214 double s[64]; 01215 int i, j; 01216 01217 for (j = 0; j < 8; j++) { 01218 for (i = 0; i < 8; i++) { 01219 if (j && j != 4) 01220 if (i && i != 4) 01221 s[j*8 + i] = cos(j * M_PI/16.0) * cos(i * M_PI/16.0) * 2.0; 01222 else 01223 s[j*8 + i] = cos(j * M_PI/16.0) * sqrt(2.0); 01224 else 01225 if (i && i != 4) 01226 s[j*8 + i] = cos(i * M_PI/16.0) * sqrt(2.0); 01227 else 01228 s[j*8 + i] = 1.0; 01229 } 01230 } 01231 01232 for (i = 0; i < 64; i++) 01233 inv_bink_scan[bink_scan[i]] = i; 01234 01235 for (j = 0; j < 16; j++) { 01236 for (i = 0; i < 64; i++) { 01237 int k = inv_bink_scan[i]; 01238 if (s[i] == 1.0) { 01239 binkb_intra_quant[j][k] = (1L << 12) * binkb_intra_seed[i] * 01240 binkb_num[j]/binkb_den[j]; 01241 binkb_inter_quant[j][k] = (1L << 12) * binkb_inter_seed[i] * 01242 binkb_num[j]/binkb_den[j]; 01243 } else { 01244 binkb_intra_quant[j][k] = (1L << 12) * binkb_intra_seed[i] * s[i] * 01245 binkb_num[j]/(double)binkb_den[j]; 01246 binkb_inter_quant[j][k] = (1L << 12) * binkb_inter_seed[i] * s[i] * 01247 binkb_num[j]/(double)binkb_den[j]; 01248 } 01249 } 01250 } 01251 } 01252 01253 static av_cold int decode_init(AVCodecContext *avctx) 01254 { 01255 BinkContext * const c = avctx->priv_data; 01256 static VLC_TYPE table[16 * 128][2]; 01257 static int binkb_initialised = 0; 01258 int i; 01259 int flags; 01260 01261 c->version = avctx->codec_tag >> 24; 01262 if (avctx->extradata_size < 4) { 01263 av_log(avctx, AV_LOG_ERROR, "Extradata missing or too short\n"); 01264 return -1; 01265 } 01266 flags = AV_RL32(avctx->extradata); 01267 c->has_alpha = flags & BINK_FLAG_ALPHA; 01268 c->swap_planes = c->version >= 'h'; 01269 if (!bink_trees[15].table) { 01270 for (i = 0; i < 16; i++) { 01271 const int maxbits = bink_tree_lens[i][15]; 01272 bink_trees[i].table = table + i*128; 01273 bink_trees[i].table_allocated = 1 << maxbits; 01274 init_vlc(&bink_trees[i], maxbits, 16, 01275 bink_tree_lens[i], 1, 1, 01276 bink_tree_bits[i], 1, 1, INIT_VLC_USE_NEW_STATIC | INIT_VLC_LE); 01277 } 01278 } 01279 c->avctx = avctx; 01280 01281 c->pic.data[0] = NULL; 01282 01283 if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) { 01284 return 1; 01285 } 01286 01287 avctx->pix_fmt = c->has_alpha ? PIX_FMT_YUVA420P : PIX_FMT_YUV420P; 01288 01289 avctx->idct_algo = FF_IDCT_BINK; 01290 dsputil_init(&c->dsp, avctx); 01291 ff_init_scantable(c->dsp.idct_permutation, &c->scantable, bink_scan); 01292 01293 init_bundles(c); 01294 01295 if (c->version == 'b') { 01296 if (!binkb_initialised) { 01297 binkb_calc_quant(); 01298 binkb_initialised = 1; 01299 } 01300 } 01301 01302 return 0; 01303 } 01304 01305 static av_cold int decode_end(AVCodecContext *avctx) 01306 { 01307 BinkContext * const c = avctx->priv_data; 01308 01309 if (c->pic.data[0]) 01310 avctx->release_buffer(avctx, &c->pic); 01311 if (c->last.data[0]) 01312 avctx->release_buffer(avctx, &c->last); 01313 01314 free_bundles(c); 01315 return 0; 01316 } 01317 01318 AVCodec ff_bink_decoder = { 01319 "binkvideo", 01320 AVMEDIA_TYPE_VIDEO, 01321 CODEC_ID_BINKVIDEO, 01322 sizeof(BinkContext), 01323 decode_init, 01324 NULL, 01325 decode_end, 01326 decode_frame, 01327 .long_name = NULL_IF_CONFIG_SMALL("Bink video"), 01328 };