| @@ -1,6 +1,7 @@ |
| 1 | 1 | /* |
| 2 | 2 | * Bink video decoder |
| 3 | 3 | * Copyright (c) 2009 Konstantin Shishkov |
| 4 | + * Copyright (C) 2011 Peter Ross <pross@xvid.org> |
| 4 | 5 | * |
| 5 | 6 | * This file is part of FFmpeg. |
| 6 | 7 | * |
| @@ -33,6 +34,35 @@ · 26 unmodified lines |
| 33 | 34 | |
| 34 | 35 | static VLC bink_trees[16]; |
| 35 | 36 | |
| 37 | +/** |
| 38 | + * IDs for different data types used in old version of Bink video codec |
| 39 | + */ |
| 40 | +enum OldSources { |
| 41 | + BINKB_SRC_BLOCK_TYPES = 0, ///< 8x8 block types |
| 42 | + BINKB_SRC_COLORS, ///< pixel values used for different block types |
| 43 | + BINKB_SRC_PATTERN, ///< 8-bit values for 2-colour pattern fill |
| 44 | + BINKB_SRC_X_OFF, ///< X components of motion value |
| 45 | + BINKB_SRC_Y_OFF, ///< Y components of motion value |
| 46 | + BINKB_SRC_INTRA_DC, ///< DC values for intrablocks with DCT |
| 47 | + BINKB_SRC_INTER_DC, ///< DC values for interblocks with DCT |
| 48 | + BINKB_SRC_INTRA_Q, ///< quantizer values for intrablocks with DCT |
| 49 | + BINKB_SRC_INTER_Q, ///< quantizer values for interblocks with DCT |
| 50 | + BINKB_SRC_INTER_COEFS, ///< number of coefficients for residue blocks |
| 51 | + |
| 52 | + BINKB_NB_SRC |
| 53 | +}; |
| 54 | + |
| 55 | +static const int binkb_bundle_sizes[BINKB_NB_SRC] = { |
| 56 | + 4, 8, 8, 5, 5, 11, 11, 4, 4, 7 |
| 57 | +}; |
| 58 | + |
| 59 | +static const int binkb_bundle_signed[BINKB_NB_SRC] = { |
| 60 | + 0, 0, 0, 1, 1, 0, 1, 0, 0, 0 |
| 61 | +}; |
| 62 | + |
| 63 | +static uint32_t binkb_intra_quant[16][64]; |
| 64 | +static uint32_t binkb_inter_quant[16][64]; |
| 65 | + |
| 36 | 66 | /** |
| 37 | 67 | * IDs for different data types used in Bink video codec |
| 38 | 68 | */ |
| @@ -85,7 +115,7 @@ typedef struct BinkContext { · 46 unmodified lines |
| 85 | 115 | int swap_planes; |
| 86 | 116 | ScanTable scantable; ///< permutated scantable for DCT coeffs decoding |
| 87 | 117 | |
| 88 | | − Bundle bundle[BINK_NB_SRC]; ///< bundles for decoding all data types |
| 118 | + Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types |
| 89 | 119 | Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type |
| 90 | 120 | int col_lastval; ///< value of last decoded high nibble in "colours" data type |
| 91 | 121 | } BinkContext; |
| @@ -145,7 +175,7 @@ static av_cold void init_bundles(BinkContext *c) · 53 unmodified lines |
| 145 | 175 | bh = (c->avctx->height + 7) >> 3; |
| 146 | 176 | blocks = bw * bh; |
| 147 | 177 | |
| 148 | | − for (i = 0; i < BINK_NB_SRC; i++) { |
| 178 | + for (i = 0; i < BINKB_NB_SRC; i++) { |
| 149 | 179 | c->bundle[i].data = av_malloc(blocks * 64); |
| 150 | 180 | c->bundle[i].data_end = c->bundle[i].data + blocks * 64; |
| 151 | 181 | } |
| @@ -159,7 +189,7 @@ static av_cold void init_bundles(BinkContext *c) · 7 unmodified lines |
| 159 | 189 | static av_cold void free_bundles(BinkContext *c) |
| 160 | 190 | { |
| 161 | 191 | int i; |
| 162 | | − for (i = 0; i < BINK_NB_SRC; i++) |
| 192 | + for (i = 0; i < BINKB_NB_SRC; i++) |
| 163 | 193 | av_freep(&c->bundle[i].data); |
| 164 | 194 | } |
| 165 | 195 | |
| @@ -470,7 +500,7 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, · 304 unmodified lines |
| 470 | 500 | */ |
| 471 | 501 | static inline int get_value(BinkContext *c, int bundle) |
| 472 | 502 | { |
| 473 | | − int16_t ret; |
| 503 | + int ret; |
| 474 | 504 | |
| 475 | 505 | if (bundle < BINK_SRC_X_OFF || bundle == BINK_SRC_RUN) |
| 476 | 506 | return *c->bundle[bundle].cur_ptr++; |
| @@ -481,17 +511,84 @@ static inline int get_value(BinkContext *c, int bundle) · 4 unmodified lines |
| 481 | 511 | return ret; |
| 482 | 512 | } |
| 483 | 513 | |
| 514 | +static void binkb_init_bundle(BinkContext *c, int bundle_num) |
| 515 | +{ |
| 516 | + c->bundle[bundle_num].cur_dec = |
| 517 | + c->bundle[bundle_num].cur_ptr = c->bundle[bundle_num].data; |
| 518 | + c->bundle[bundle_num].len = 13; |
| 519 | +} |
| 520 | + |
| 521 | +static void binkb_init_bundles(BinkContext *c) |
| 522 | +{ |
| 523 | + int i; |
| 524 | + for (i = 0; i < BINKB_NB_SRC; i++) |
| 525 | + binkb_init_bundle(c, i); |
| 526 | +} |
| 527 | + |
| 528 | +static int binkb_read_bundle(BinkContext *c, GetBitContext *gb, int bundle_num) |
| 529 | +{ |
| 530 | + const int bits = binkb_bundle_sizes[bundle_num]; |
| 531 | + const int mask = 1 << (bits - 1); |
| 532 | + const int issigned = binkb_bundle_signed[bundle_num]; |
| 533 | + Bundle *b = &c->bundle[bundle_num]; |
| 534 | + int i, len; |
| 535 | + |
| 536 | + CHECK_READ_VAL(gb, b, len); |
| 537 | + if (bits <= 8) { |
| 538 | + if (!issigned) { |
| 539 | + for (i = 0; i < len; i++) |
| 540 | + *b->cur_dec++ = get_bits(gb, bits); |
| 541 | + } else { |
| 542 | + for (i = 0; i < len; i++) |
| 543 | + *b->cur_dec++ = get_bits(gb, bits) - mask; |
| 544 | + } |
| 545 | + } else { |
| 546 | + int16_t *dst = (int16_t*)b->cur_dec; |
| 547 | + |
| 548 | + if (!issigned) { |
| 549 | + for (i = 0; i < len; i++) |
| 550 | + *dst++ = get_bits(gb, bits); |
| 551 | + } else { |
| 552 | + for (i = 0; i < len; i++) |
| 553 | + *dst++ = get_bits(gb, bits) - mask; |
| 554 | + } |
| 555 | + b->cur_dec = (uint8_t*)dst; |
| 556 | + } |
| 557 | + return 0; |
| 558 | +} |
| 559 | + |
| 560 | +static inline int binkb_get_value(BinkContext *c, int bundle_num) |
| 561 | +{ |
| 562 | + int16_t ret; |
| 563 | + const int bits = binkb_bundle_sizes[bundle_num]; |
| 564 | + |
| 565 | + if (bits <= 8) { |
| 566 | + int val = *c->bundle[bundle_num].cur_ptr++; |
| 567 | + return binkb_bundle_signed[bundle_num] ? (int8_t)val : val; |
| 568 | + } |
| 569 | + ret = *(int16_t*)c->bundle[bundle_num].cur_ptr; |
| 570 | + c->bundle[bundle_num].cur_ptr += 2; |
| 571 | + return ret; |
| 572 | +} |
| 573 | + |
| 574 | +typedef const uint32_t quant_matrices[16][64]; |
| 575 | +static const quant_matrices * bink_quant_matrices[2][2] = { |
| 576 | + { &bink_inter_quant, &bink_intra_quant }, |
| 577 | + { &binkb_inter_quant, &binkb_intra_quant }, |
| 578 | +}; |
| 579 | + |
| 484 | 580 | /** |
| 485 | 581 | * Read 8x8 block of DCT coefficients. |
| 486 | 582 | * |
| 487 | 583 | * @param gb context for reading bits |
| 488 | 584 | * @param block place for storing coefficients |
| 489 | 585 | * @param scan scan order table |
| 586 | + * @param is_binkb use version 'b' quantizer matrices |
| 490 | 587 | * @param is_intra tells what set of quantizer matrices to use |
| 491 | 588 | * @return 0 for success, negative value in other cases |
| 492 | 589 | */ |
| 493 | 590 | static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t *scan, |
| 494 | | − int is_intra) |
| 591 | + int is_binkb, int is_intra, int q) |
| 495 | 592 | { |
| 496 | 593 | int coef_list[128]; |
| 497 | 594 | int mode_list[128]; |
| @@ -571,9 +668,14 @@ static int read_dct_coeffs(GetBitContext *gb, DCTELEM block[64], const uint8_t * · 73 unmodified lines |
| 571 | 668 | } |
| 572 | 669 | } |
| 573 | 670 | |
| 574 | | − quant_idx = get_bits(gb, 4); |
| 575 | | − quant = is_intra ? bink_intra_quant[quant_idx] |
| 576 | | − : bink_inter_quant[quant_idx]; |
| 671 | + if (q == -1) { |
| 672 | + quant_idx = get_bits(gb, 4); |
| 673 | + } else { |
| 674 | + quant_idx = q; |
| 675 | + } |
| 676 | + |
| 677 | + quant = (*bink_quant_matrices[is_binkb][is_intra])[quant_idx]; |
| 678 | + |
| 577 | 679 | block[0] = (block[0] * quant[0]) >> 11; |
| 578 | 680 | for (i = 0; i < coef_count; i++) { |
| 579 | 681 | int idx = coef_idx[i]; |
| @@ -673,6 +775,164 @@ static int read_residue(GetBitContext *gb, DCTELEM block[64], int masks_count) · 93 unmodified lines |
| 673 | 775 | return 0; |
| 674 | 776 | } |
| 675 | 777 | |
| 778 | +/** |
| 779 | + * Copy 8x8 block from source to destination, where src and dst may be overlapped |
| 780 | + */ |
| 781 | +static inline void put_pixels8x8_overlapped(uint8_t *dst, uint8_t *src, int stride) |
| 782 | +{ |
| 783 | + uint8_t tmp[64]; |
| 784 | + int i; |
| 785 | + for (i = 0; i < 8; i++) |
| 786 | + memcpy(tmp + i*8, src + i*stride, 8); |
| 787 | + for (i = 0; i < 8; i++) |
| 788 | + memcpy(dst + i*stride, tmp + i*8, 8); |
| 789 | +} |
| 790 | + |
| 791 | +static int binkb_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, |
| 792 | + int is_key, int is_chroma) |
| 793 | +{ |
| 794 | + int blk; |
| 795 | + int i, j, bx, by; |
| 796 | + uint8_t *dst, *ref, *ref_start, *ref_end; |
| 797 | + int v, col[2]; |
| 798 | + const uint8_t *scan; |
| 799 | + int xoff, yoff; |
| 800 | + DECLARE_ALIGNED(16, DCTELEM, block[64]); |
| 801 | + int coordmap[64]; |
| 802 | + int ybias = is_key ? -15 : 0; |
| 803 | + int qp; |
| 804 | + |
| 805 | + const int stride = c->pic.linesize[plane_idx]; |
| 806 | + int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; |
| 807 | + int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; |
| 808 | + |
| 809 | + binkb_init_bundles(c); |
| 810 | + ref_start = c->pic.data[plane_idx]; |
| 811 | + ref_end = c->pic.data[plane_idx] + (bh * c->pic.linesize[plane_idx] + bw) * 8; |
| 812 | + |
| 813 | + for (i = 0; i < 64; i++) |
| 814 | + coordmap[i] = (i & 7) + (i >> 3) * stride; |
| 815 | + |
| 816 | + for (by = 0; by < bh; by++) { |
| 817 | + for (i = 0; i < BINKB_NB_SRC; i++) { |
| 818 | + if (binkb_read_bundle(c, gb, i) < 0) |
| 819 | + return -1; |
| 820 | + } |
| 821 | + |
| 822 | + dst = c->pic.data[plane_idx] + 8*by*stride; |
| 823 | + for (bx = 0; bx < bw; bx++, dst += 8) { |
| 824 | + blk = binkb_get_value(c, BINKB_SRC_BLOCK_TYPES); |
| 825 | + switch (blk) { |
| 826 | + case 0: |
| 827 | + break; |
| 828 | + case 1: |
| 829 | + scan = bink_patterns[get_bits(gb, 4)]; |
| 830 | + i = 0; |
| 831 | + do { |
| 832 | + int mode, run; |
| 833 | + |
| 834 | + mode = get_bits1(gb); |
| 835 | + run = get_bits(gb, binkb_runbits[i]) + 1; |
| 836 | + |
| 837 | + i += run; |
| 838 | + if (i > 64) { |
| 839 | + av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); |
| 840 | + return -1; |
| 841 | + } |
| 842 | + if (mode) { |
| 843 | + v = binkb_get_value(c, BINKB_SRC_COLORS); |
| 844 | + for (j = 0; j < run; j++) |
| 845 | + dst[coordmap[*scan++]] = v; |
| 846 | + } else { |
| 847 | + for (j = 0; j < run; j++) |
| 848 | + dst[coordmap[*scan++]] = binkb_get_value(c, BINKB_SRC_COLORS); |
| 849 | + } |
| 850 | + } while (i < 63); |
| 851 | + if (i == 63) |
| 852 | + dst[coordmap[*scan++]] = binkb_get_value(c, BINKB_SRC_COLORS); |
| 853 | + break; |
| 854 | + case 2: |
| 855 | + c->dsp.clear_block(block); |
| 856 | + block[0] = binkb_get_value(c, BINKB_SRC_INTRA_DC); |
| 857 | + qp = binkb_get_value(c, BINKB_SRC_INTRA_Q); |
| 858 | + read_dct_coeffs(gb, block, c->scantable.permutated, 1, 1, qp); |
| 859 | + c->dsp.idct_put(dst, stride, block); |
| 860 | + break; |
| 861 | + case 3: |
| 862 | + xoff = binkb_get_value(c, BINKB_SRC_X_OFF); |
| 863 | + yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; |
| 864 | + ref = dst + xoff + yoff * stride; |
| 865 | + if (ref < ref_start || ref + 8*stride > ref_end) { |
| 866 | + av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); |
| 867 | + } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { |
| 868 | + c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); |
| 869 | + } else { |
| 870 | + put_pixels8x8_overlapped(dst, ref, stride); |
| 871 | + } |
| 872 | + c->dsp.clear_block(block); |
| 873 | + v = binkb_get_value(c, BINKB_SRC_INTER_COEFS); |
| 874 | + read_residue(gb, block, v); |
| 875 | + c->dsp.add_pixels8(dst, block, stride); |
| 876 | + break; |
| 877 | + case 4: |
| 878 | + xoff = binkb_get_value(c, BINKB_SRC_X_OFF); |
| 879 | + yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; |
| 880 | + ref = dst + xoff + yoff * stride; |
| 881 | + if (ref < ref_start || ref + 8 * stride > ref_end) { |
| 882 | + av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); |
| 883 | + } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { |
| 884 | + c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); |
| 885 | + } else { |
| 886 | + put_pixels8x8_overlapped(dst, ref, stride); |
| 887 | + } |
| 888 | + c->dsp.clear_block(block); |
| 889 | + block[0] = binkb_get_value(c, BINKB_SRC_INTER_DC); |
| 890 | + qp = binkb_get_value(c, BINKB_SRC_INTER_Q); |
| 891 | + read_dct_coeffs(gb, block, c->scantable.permutated, 1, 0, qp); |
| 892 | + c->dsp.idct_add(dst, stride, block); |
| 893 | + break; |
| 894 | + case 5: |
| 895 | + v = binkb_get_value(c, BINKB_SRC_COLORS); |
| 896 | + c->dsp.fill_block_tab[1](dst, v, stride, 8); |
| 897 | + break; |
| 898 | + case 6: |
| 899 | + for (i = 0; i < 2; i++) |
| 900 | + col[i] = binkb_get_value(c, BINKB_SRC_COLORS); |
| 901 | + for (i = 0; i < 8; i++) { |
| 902 | + v = binkb_get_value(c, BINKB_SRC_PATTERN); |
| 903 | + for (j = 0; j < 8; j++, v >>= 1) |
| 904 | + dst[i*stride + j] = col[v & 1]; |
| 905 | + } |
| 906 | + break; |
| 907 | + case 7: |
| 908 | + xoff = binkb_get_value(c, BINKB_SRC_X_OFF); |
| 909 | + yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; |
| 910 | + ref = dst + xoff + yoff * stride; |
| 911 | + if (ref < ref_start || ref + 8 * stride > ref_end) { |
| 912 | + av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); |
| 913 | + } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { |
| 914 | + c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); |
| 915 | + } else { |
| 916 | + put_pixels8x8_overlapped(dst, ref, stride); |
| 917 | + } |
| 918 | + break; |
| 919 | + case 8: |
| 920 | + for (i = 0; i < 8; i++) |
| 921 | + memcpy(dst + i*stride, c->bundle[BINKB_SRC_COLORS].cur_ptr + i*8, 8); |
| 922 | + c->bundle[BINKB_SRC_COLORS].cur_ptr += 64; |
| 923 | + break; |
| 924 | + default: |
| 925 | + av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); |
| 926 | + return -1; |
| 927 | + } |
| 928 | + } |
| 929 | + } |
| 930 | + if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary |
| 931 | + skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); |
| 932 | + |
| 933 | + return 0; |
| 934 | +} |
| 935 | + |
| 676 | 936 | static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, |
| 677 | 937 | int is_chroma) |
| 678 | 938 | { |
| @@ -768,7 +1028,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, · 89 unmodified lines |
| 768 | 1028 | case INTRA_BLOCK: |
| 769 | 1029 | c->dsp.clear_block(block); |
| 770 | 1030 | block[0] = get_value(c, BINK_SRC_INTRA_DC); |
| 771 | | − read_dct_coeffs(gb, block, c->scantable.permutated, 1); |
| 1031 | + read_dct_coeffs(gb, block, c->scantable.permutated, 0, 1, -1); |
| 772 | 1032 | c->dsp.idct(block); |
| 773 | 1033 | c->dsp.put_pixels_nonclamped(block, ublock, 8); |
| 774 | 1034 | break; |
| @@ -852,7 +1112,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, · 77 unmodified lines |
| 852 | 1112 | case INTRA_BLOCK: |
| 853 | 1113 | c->dsp.clear_block(block); |
| 854 | 1114 | block[0] = get_value(c, BINK_SRC_INTRA_DC); |
| 855 | | − read_dct_coeffs(gb, block, c->scantable.permutated, 1); |
| 1115 | + read_dct_coeffs(gb, block, c->scantable.permutated, 0, 1, -1); |
| 856 | 1116 | c->dsp.idct_put(dst, stride, block); |
| 857 | 1117 | break; |
| 858 | 1118 | case FILL_BLOCK: |
| @@ -866,7 +1126,7 @@ static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, · 7 unmodified lines |
| 866 | 1126 | c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); |
| 867 | 1127 | c->dsp.clear_block(block); |
| 868 | 1128 | block[0] = get_value(c, BINK_SRC_INTER_DC); |
| 869 | | − read_dct_coeffs(gb, block, c->scantable.permutated, 0); |
| 1129 | + read_dct_coeffs(gb, block, c->scantable.permutated, 0, 0, -1); |
| 870 | 1130 | c->dsp.idct_add(dst, stride, block); |
| 871 | 1131 | break; |
| 872 | 1132 | case PATTERN_BLOCK: |
| @@ -902,6 +1162,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac · 29 unmodified lines |
| 902 | 1162 | int plane, plane_idx; |
| 903 | 1163 | int bits_count = pkt->size << 3; |
| 904 | 1164 | |
| 1165 | + if (c->version > 'b') { |
| 905 | 1166 | if(c->pic.data[0]) |
| 906 | 1167 | avctx->release_buffer(avctx, &c->pic); |
| 907 | 1168 | |
| @@ -909,6 +1170,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac · 1 unmodified line |
| 909 | 1170 | av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
| 910 | 1171 | return -1; |
| 911 | 1172 | } |
| 1173 | + } else { |
| 1174 | + if(avctx->reget_buffer(avctx, &c->pic) < 0){ |
| 1175 | + av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); |
| 1176 | + return -1; |
| 1177 | + } |
| 1178 | + } |
| 912 | 1179 | |
| 913 | 1180 | init_get_bits(&gb, pkt->data, bits_count); |
| 914 | 1181 | if (c->has_alpha) { |
| @@ -923,8 +1190,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac · 8 unmodified lines |
| 923 | 1190 | for (plane = 0; plane < 3; plane++) { |
| 924 | 1191 | plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); |
| 925 | 1192 | |
| 926 | | − if (bink_decode_plane(c, &gb, plane_idx, !!plane) < 0) |
| 927 | | − return -1; |
| 1193 | + if (c->version > 'b') { |
| 1194 | + if (bink_decode_plane(c, &gb, plane_idx, !!plane) < 0) |
| 1195 | + return -1; |
| 1196 | + } else { |
| 1197 | + if (binkb_decode_plane(c, &gb, plane_idx, !pkt->pts, !!plane) < 0) |
| 1198 | + return -1; |
| 1199 | + } |
| 928 | 1200 | if (get_bits_count(&gb) >= bits_count) |
| 929 | 1201 | break; |
| 930 | 1202 | } |
| @@ -933,24 +1205,55 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac · 2 unmodified lines |
| 933 | 1205 | *data_size = sizeof(AVFrame); |
| 934 | 1206 | *(AVFrame*)data = c->pic; |
| 935 | 1207 | |
| 936 | | − FFSWAP(AVFrame, c->pic, c->last); |
| 1208 | + if (c->version > 'b') |
| 1209 | + FFSWAP(AVFrame, c->pic, c->last); |
| 937 | 1210 | |
| 938 | 1211 | /* always report that the buffer was completely consumed */ |
| 939 | 1212 | return pkt->size; |
| 940 | 1213 | } |
| 941 | 1214 | |
| 1215 | +/** |
| 1216 | + * Caclulate quantization tables for version b |
| 1217 | + */ |
| 1218 | +static av_cold void binkb_calc_quant() |
| 1219 | +{ |
| 1220 | + float s[64]; |
| 1221 | + int i, j; |
| 1222 | + |
| 1223 | + for (j = 0; j < 8; j++) { |
| 1224 | + for (i = 0; i < 8; i++) { |
| 1225 | + if (j && j != 4) |
| 1226 | + if (i && i != 4) |
| 1227 | + s[j*8 + i] = cos(j * M_PI/16.0f) * cos(i * M_PI/16.0f) * 2.0f; |
| 1228 | + else |
| 1229 | + s[j*8 + i] = cos(j * M_PI/16.0f) * sqrt(2.0f); |
| 1230 | + else |
| 1231 | + if (i && i != 4) |
| 1232 | + s[j*8 + i] = cos(i * M_PI/16.0f) * sqrt(2.0f); |
| 1233 | + else |
| 1234 | + s[j*8 + i] = 1.0f; |
| 1235 | + } |
| 1236 | + } |
| 1237 | + |
| 1238 | + for (j = 0; j < 16; j++) { |
| 1239 | + for (i = 0; i < 64; i++) { |
| 1240 | + binkb_intra_quant[j][i] = (1L << 12) * binkb_intra_seed[i] * s[i] * |
| 1241 | + binkb_num[j]/(float)binkb_den[j]; |
| 1242 | + binkb_inter_quant[j][i] = (1L << 12) * binkb_inter_seed[i] * s[i] * |
| 1243 | + binkb_num[j]/(float)binkb_den[j]; |
| 1244 | + } |
| 1245 | + } |
| 1246 | +} |
| 1247 | + |
| 942 | 1248 | static av_cold int decode_init(AVCodecContext *avctx) |
| 943 | 1249 | { |
| 944 | 1250 | BinkContext * const c = avctx->priv_data; |
| 945 | 1251 | static VLC_TYPE table[16 * 128][2]; |
| 1252 | + static int binkb_initialised = 0; |
| 946 | 1253 | int i; |
| 947 | 1254 | int flags; |
| 948 | 1255 | |
| 949 | 1256 | c->version = avctx->codec_tag >> 24; |
| 950 | | − if (c->version < 'c') { |
| 951 | | − av_log(avctx, AV_LOG_ERROR, "Too old version '%c'\n", c->version); |
| 952 | | − return -1; |
| 953 | | − } |
| 954 | 1257 | if (avctx->extradata_size < 4) { |
| 955 | 1258 | av_log(avctx, AV_LOG_ERROR, "Extradata missing or too short\n"); |
| 956 | 1259 | return -1; |
| @@ -984,6 +1287,13 @@ static av_cold int decode_init(AVCodecContext *avctx) · 27 unmodified lines |
| 984 | 1287 | |
| 985 | 1288 | init_bundles(c); |
| 986 | 1289 | |
| 1290 | + if (c->version == 'b') { |
| 1291 | + if (!binkb_initialised) { |
| 1292 | + binkb_calc_quant(); |
| 1293 | + binkb_initialised = 1; |
| 1294 | + } |
| 1295 | + } |
| 1296 | + |
| 987 | 1297 | return 0; |
| 988 | 1298 | } |
| 989 | 1299 | |