Originally committed as revision 21980 to svn://svn.ffmpeg.org/ffmpeg/trunk
Kostya Shishkov authored on 2010/02/23 16:00:46... | ... |
@@ -672,12 +672,11 @@ static int read_residue(GetBitContext *gb, DCTELEM block[64], int masks_count) |
672 | 672 |
return 0; |
673 | 673 |
} |
674 | 674 |
|
675 |
-static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt) |
|
675 |
+static int bink_decode_plane(BinkContext *c, GetBitContext *gb, int plane_idx, |
|
676 |
+ int is_chroma) |
|
676 | 677 |
{ |
677 |
- BinkContext * const c = avctx->priv_data; |
|
678 |
- GetBitContext gb; |
|
679 | 678 |
int blk; |
680 |
- int i, j, plane, plane_idx, bx, by; |
|
679 |
+ int i, j, bx, by; |
|
681 | 680 |
uint8_t *dst, *prev, *ref, *ref_start, *ref_end; |
682 | 681 |
int v, col[2]; |
683 | 682 |
const uint8_t *scan; |
... | ... |
@@ -685,39 +684,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac |
685 | 685 |
DECLARE_ALIGNED_16(DCTELEM, block[64]); |
686 | 686 |
DECLARE_ALIGNED_16(uint8_t, ublock[64]); |
687 | 687 |
int coordmap[64]; |
688 |
- int bits_count = pkt->size << 3; |
|
689 |
- |
|
690 |
- if(c->pic.data[0]) |
|
691 |
- avctx->release_buffer(avctx, &c->pic); |
|
692 |
- |
|
693 |
- if(avctx->get_buffer(avctx, &c->pic) < 0){ |
|
694 |
- av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
|
695 |
- return -1; |
|
696 |
- } |
|
697 |
- |
|
698 |
- init_get_bits(&gb, pkt->data, bits_count); |
|
699 |
- if (c->has_alpha) { |
|
700 |
- int aplane_bits = get_bits_long(&gb, 32) << 3; |
|
701 |
- if (aplane_bits <= 32 || (aplane_bits & 0x1F)) { |
|
702 |
- av_log(avctx, AV_LOG_ERROR, "Incorrect alpha plane size %d\n", aplane_bits); |
|
703 |
- return -1; |
|
704 |
- } |
|
705 |
- skip_bits_long(&gb, aplane_bits - 32); |
|
706 |
- } |
|
707 |
- if (c->version >= 'i') |
|
708 |
- skip_bits_long(&gb, 32); |
|
709 | 688 |
|
710 |
- for (plane = 0; plane < 3; plane++) { |
|
711 |
- const int stride = c->pic.linesize[plane]; |
|
712 |
- int bw = plane ? (avctx->width + 15) >> 4 : (avctx->width + 7) >> 3; |
|
713 |
- int bh = plane ? (avctx->height + 15) >> 4 : (avctx->height + 7) >> 3; |
|
714 |
- int width = avctx->width >> !!plane; |
|
689 |
+ const int stride = c->pic.linesize[plane_idx]; |
|
690 |
+ int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; |
|
691 |
+ int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; |
|
692 |
+ int width = c->avctx->width >> is_chroma; |
|
715 | 693 |
|
716 | 694 |
init_lengths(c, FFMAX(width, 8), bw); |
717 | 695 |
for (i = 0; i < BINK_NB_SRC; i++) |
718 |
- read_bundle(&gb, c, i); |
|
696 |
+ read_bundle(gb, c, i); |
|
719 | 697 |
|
720 |
- plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); |
|
721 | 698 |
ref_start = c->last.data[plane_idx]; |
722 | 699 |
ref_end = c->last.data[plane_idx] |
723 | 700 |
+ (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8; |
... | ... |
@@ -726,23 +702,23 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac |
726 | 726 |
coordmap[i] = (i & 7) + (i >> 3) * stride; |
727 | 727 |
|
728 | 728 |
for (by = 0; by < bh; by++) { |
729 |
- if (read_block_types(avctx, &gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0) |
|
729 |
+ if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0) |
|
730 | 730 |
return -1; |
731 |
- if (read_block_types(avctx, &gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0) |
|
731 |
+ if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0) |
|
732 | 732 |
return -1; |
733 |
- if (read_colors(&gb, &c->bundle[BINK_SRC_COLORS], c) < 0) |
|
733 |
+ if (read_colors(gb, &c->bundle[BINK_SRC_COLORS], c) < 0) |
|
734 | 734 |
return -1; |
735 |
- if (read_patterns(avctx, &gb, &c->bundle[BINK_SRC_PATTERN]) < 0) |
|
735 |
+ if (read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN]) < 0) |
|
736 | 736 |
return -1; |
737 |
- if (read_motion_values(avctx, &gb, &c->bundle[BINK_SRC_X_OFF]) < 0) |
|
737 |
+ if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF]) < 0) |
|
738 | 738 |
return -1; |
739 |
- if (read_motion_values(avctx, &gb, &c->bundle[BINK_SRC_Y_OFF]) < 0) |
|
739 |
+ if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF]) < 0) |
|
740 | 740 |
return -1; |
741 |
- if (read_dcs(avctx, &gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0) |
|
741 |
+ if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0) |
|
742 | 742 |
return -1; |
743 |
- if (read_dcs(avctx, &gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0) |
|
743 |
+ if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0) |
|
744 | 744 |
return -1; |
745 |
- if (read_runs(avctx, &gb, &c->bundle[BINK_SRC_RUN]) < 0) |
|
745 |
+ if (read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN]) < 0) |
|
746 | 746 |
return -1; |
747 | 747 |
|
748 | 748 |
if (by == bh) |
... | ... |
@@ -766,17 +742,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac |
766 | 766 |
blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES); |
767 | 767 |
switch (blk) { |
768 | 768 |
case RUN_BLOCK: |
769 |
- scan = bink_patterns[get_bits(&gb, 4)]; |
|
769 |
+ scan = bink_patterns[get_bits(gb, 4)]; |
|
770 | 770 |
i = 0; |
771 | 771 |
do { |
772 | 772 |
int run = get_value(c, BINK_SRC_RUN) + 1; |
773 | 773 |
|
774 | 774 |
i += run; |
775 | 775 |
if (i > 64) { |
776 |
- av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); |
|
776 |
+ av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); |
|
777 | 777 |
return -1; |
778 | 778 |
} |
779 |
- if (get_bits1(&gb)) { |
|
779 |
+ if (get_bits1(gb)) { |
|
780 | 780 |
v = get_value(c, BINK_SRC_COLORS); |
781 | 781 |
for (j = 0; j < run; j++) |
782 | 782 |
ublock[*scan++] = v; |
... | ... |
@@ -791,7 +767,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac |
791 | 791 |
case INTRA_BLOCK: |
792 | 792 |
c->dsp.clear_block(block); |
793 | 793 |
block[0] = get_value(c, BINK_SRC_INTRA_DC); |
794 |
- read_dct_coeffs(&gb, block, c->scantable.permutated, 1); |
|
794 |
+ read_dct_coeffs(gb, block, c->scantable.permutated, 1); |
|
795 | 795 |
c->dsp.idct(block); |
796 | 796 |
c->dsp.put_pixels_nonclamped(block, ublock, 8); |
797 | 797 |
break; |
... | ... |
@@ -814,7 +790,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac |
814 | 814 |
ublock[i + j*8] = get_value(c, BINK_SRC_COLORS); |
815 | 815 |
break; |
816 | 816 |
default: |
817 |
- av_log(avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk); |
|
817 |
+ av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk); |
|
818 | 818 |
return -1; |
819 | 819 |
} |
820 | 820 |
if (blk != FILL_BLOCK) |
... | ... |
@@ -828,24 +804,24 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac |
828 | 828 |
yoff = get_value(c, BINK_SRC_Y_OFF); |
829 | 829 |
ref = prev + xoff + yoff * stride; |
830 | 830 |
if (ref < ref_start || ref > ref_end) { |
831 |
- av_log(avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", |
|
831 |
+ av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", |
|
832 | 832 |
bx*8 + xoff, by*8 + yoff); |
833 | 833 |
return -1; |
834 | 834 |
} |
835 | 835 |
c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); |
836 | 836 |
break; |
837 | 837 |
case RUN_BLOCK: |
838 |
- scan = bink_patterns[get_bits(&gb, 4)]; |
|
838 |
+ scan = bink_patterns[get_bits(gb, 4)]; |
|
839 | 839 |
i = 0; |
840 | 840 |
do { |
841 | 841 |
int run = get_value(c, BINK_SRC_RUN) + 1; |
842 | 842 |
|
843 | 843 |
i += run; |
844 | 844 |
if (i > 64) { |
845 |
- av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); |
|
845 |
+ av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); |
|
846 | 846 |
return -1; |
847 | 847 |
} |
848 |
- if (get_bits1(&gb)) { |
|
848 |
+ if (get_bits1(gb)) { |
|
849 | 849 |
v = get_value(c, BINK_SRC_COLORS); |
850 | 850 |
for (j = 0; j < run; j++) |
851 | 851 |
dst[coordmap[*scan++]] = v; |
... | ... |
@@ -862,20 +838,20 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac |
862 | 862 |
yoff = get_value(c, BINK_SRC_Y_OFF); |
863 | 863 |
ref = prev + xoff + yoff * stride; |
864 | 864 |
if (ref < ref_start || ref > ref_end) { |
865 |
- av_log(avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", |
|
865 |
+ av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", |
|
866 | 866 |
bx*8 + xoff, by*8 + yoff); |
867 | 867 |
return -1; |
868 | 868 |
} |
869 | 869 |
c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); |
870 | 870 |
c->dsp.clear_block(block); |
871 |
- v = get_bits(&gb, 7); |
|
872 |
- read_residue(&gb, block, v); |
|
871 |
+ v = get_bits(gb, 7); |
|
872 |
+ read_residue(gb, block, v); |
|
873 | 873 |
c->dsp.add_pixels8(dst, block, stride); |
874 | 874 |
break; |
875 | 875 |
case INTRA_BLOCK: |
876 | 876 |
c->dsp.clear_block(block); |
877 | 877 |
block[0] = get_value(c, BINK_SRC_INTRA_DC); |
878 |
- read_dct_coeffs(&gb, block, c->scantable.permutated, 1); |
|
878 |
+ read_dct_coeffs(gb, block, c->scantable.permutated, 1); |
|
879 | 879 |
c->dsp.idct_put(dst, stride, block); |
880 | 880 |
break; |
881 | 881 |
case FILL_BLOCK: |
... | ... |
@@ -889,7 +865,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac |
889 | 889 |
c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); |
890 | 890 |
c->dsp.clear_block(block); |
891 | 891 |
block[0] = get_value(c, BINK_SRC_INTER_DC); |
892 |
- read_dct_coeffs(&gb, block, c->scantable.permutated, 0); |
|
892 |
+ read_dct_coeffs(gb, block, c->scantable.permutated, 0); |
|
893 | 893 |
c->dsp.idct_add(dst, stride, block); |
894 | 894 |
break; |
895 | 895 |
case PATTERN_BLOCK: |
... | ... |
@@ -907,13 +883,49 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac |
907 | 907 |
c->bundle[BINK_SRC_COLORS].cur_ptr += 64; |
908 | 908 |
break; |
909 | 909 |
default: |
910 |
- av_log(avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); |
|
910 |
+ av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); |
|
911 | 911 |
return -1; |
912 | 912 |
} |
913 | 913 |
} |
914 | 914 |
} |
915 |
- if (get_bits_count(&gb) & 0x1F) //next plane data starts at 32-bit boundary |
|
916 |
- skip_bits_long(&gb, 32 - (get_bits_count(&gb) & 0x1F)); |
|
915 |
+ if (get_bits_count(gb) & 0x1F) //next plane data starts at 32-bit boundary |
|
916 |
+ skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); |
|
917 |
+ |
|
918 |
+ return 0; |
|
919 |
+} |
|
920 |
+ |
|
921 |
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt) |
|
922 |
+{ |
|
923 |
+ BinkContext * const c = avctx->priv_data; |
|
924 |
+ GetBitContext gb; |
|
925 |
+ int plane, plane_idx; |
|
926 |
+ int bits_count = pkt->size << 3; |
|
927 |
+ |
|
928 |
+ if(c->pic.data[0]) |
|
929 |
+ avctx->release_buffer(avctx, &c->pic); |
|
930 |
+ |
|
931 |
+ if(avctx->get_buffer(avctx, &c->pic) < 0){ |
|
932 |
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); |
|
933 |
+ return -1; |
|
934 |
+ } |
|
935 |
+ |
|
936 |
+ init_get_bits(&gb, pkt->data, bits_count); |
|
937 |
+ if (c->has_alpha) { |
|
938 |
+ int aplane_bits = get_bits_long(&gb, 32) << 3; |
|
939 |
+ if (aplane_bits <= 32 || (aplane_bits & 0x1F)) { |
|
940 |
+ av_log(avctx, AV_LOG_ERROR, "Incorrect alpha plane size %d\n", aplane_bits); |
|
941 |
+ return -1; |
|
942 |
+ } |
|
943 |
+ skip_bits_long(&gb, aplane_bits - 32); |
|
944 |
+ } |
|
945 |
+ if (c->version >= 'i') |
|
946 |
+ skip_bits_long(&gb, 32); |
|
947 |
+ |
|
948 |
+ for (plane = 0; plane < 3; plane++) { |
|
949 |
+ plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); |
|
950 |
+ |
|
951 |
+ if (bink_decode_plane(c, &gb, plane_idx, !!plane) < 0) |
|
952 |
+ return -1; |
|
917 | 953 |
if (get_bits_count(&gb) >= bits_count) |
918 | 954 |
break; |
919 | 955 |
} |