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