Mercurial > libavcodec.hg
comparison bink.c @ 11252:d6513f6a949e libavcodec
Move plane decoding code into separate function in Bink decoder
author | kostya |
---|---|
date | Tue, 23 Feb 2010 07:00:46 +0000 |
parents | 56e65f21e9c5 |
children | 100ca092ac34 |
comparison
equal
deleted
inserted
replaced
11251:56e65f21e9c5 | 11252:d6513f6a949e |
---|---|
670 } | 670 } |
671 | 671 |
672 return 0; | 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 { | 676 int is_chroma) |
677 BinkContext * const c = avctx->priv_data; | 677 { |
678 GetBitContext gb; | |
679 int blk; | 678 int blk; |
680 int i, j, plane, plane_idx, bx, by; | 679 int i, j, bx, by; |
681 uint8_t *dst, *prev, *ref, *ref_start, *ref_end; | 680 uint8_t *dst, *prev, *ref, *ref_start, *ref_end; |
682 int v, col[2]; | 681 int v, col[2]; |
683 const uint8_t *scan; | 682 const uint8_t *scan; |
684 int xoff, yoff; | 683 int xoff, yoff; |
685 DECLARE_ALIGNED_16(DCTELEM, block[64]); | 684 DECLARE_ALIGNED_16(DCTELEM, block[64]); |
686 DECLARE_ALIGNED_16(uint8_t, ublock[64]); | 685 DECLARE_ALIGNED_16(uint8_t, ublock[64]); |
687 int coordmap[64]; | 686 int coordmap[64]; |
688 int bits_count = pkt->size << 3; | 687 |
689 | 688 const int stride = c->pic.linesize[plane_idx]; |
690 if(c->pic.data[0]) | 689 int bw = is_chroma ? (c->avctx->width + 15) >> 4 : (c->avctx->width + 7) >> 3; |
691 avctx->release_buffer(avctx, &c->pic); | 690 int bh = is_chroma ? (c->avctx->height + 15) >> 4 : (c->avctx->height + 7) >> 3; |
692 | 691 int width = c->avctx->width >> is_chroma; |
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 | |
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; | |
715 | 692 |
716 init_lengths(c, FFMAX(width, 8), bw); | 693 init_lengths(c, FFMAX(width, 8), bw); |
717 for (i = 0; i < BINK_NB_SRC; i++) | 694 for (i = 0; i < BINK_NB_SRC; i++) |
718 read_bundle(&gb, c, i); | 695 read_bundle(gb, c, i); |
719 | 696 |
720 plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); | |
721 ref_start = c->last.data[plane_idx]; | 697 ref_start = c->last.data[plane_idx]; |
722 ref_end = c->last.data[plane_idx] | 698 ref_end = c->last.data[plane_idx] |
723 + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8; | 699 + (bw - 1 + c->last.linesize[plane_idx] * (bh - 1)) * 8; |
724 | 700 |
725 for (i = 0; i < 64; i++) | 701 for (i = 0; i < 64; i++) |
726 coordmap[i] = (i & 7) + (i >> 3) * stride; | 702 coordmap[i] = (i & 7) + (i >> 3) * stride; |
727 | 703 |
728 for (by = 0; by < bh; by++) { | 704 for (by = 0; by < bh; by++) { |
729 if (read_block_types(avctx, &gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0) | 705 if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_BLOCK_TYPES]) < 0) |
730 return -1; | 706 return -1; |
731 if (read_block_types(avctx, &gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0) | 707 if (read_block_types(c->avctx, gb, &c->bundle[BINK_SRC_SUB_BLOCK_TYPES]) < 0) |
732 return -1; | 708 return -1; |
733 if (read_colors(&gb, &c->bundle[BINK_SRC_COLORS], c) < 0) | 709 if (read_colors(gb, &c->bundle[BINK_SRC_COLORS], c) < 0) |
734 return -1; | 710 return -1; |
735 if (read_patterns(avctx, &gb, &c->bundle[BINK_SRC_PATTERN]) < 0) | 711 if (read_patterns(c->avctx, gb, &c->bundle[BINK_SRC_PATTERN]) < 0) |
736 return -1; | 712 return -1; |
737 if (read_motion_values(avctx, &gb, &c->bundle[BINK_SRC_X_OFF]) < 0) | 713 if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_X_OFF]) < 0) |
738 return -1; | 714 return -1; |
739 if (read_motion_values(avctx, &gb, &c->bundle[BINK_SRC_Y_OFF]) < 0) | 715 if (read_motion_values(c->avctx, gb, &c->bundle[BINK_SRC_Y_OFF]) < 0) |
740 return -1; | 716 return -1; |
741 if (read_dcs(avctx, &gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0) | 717 if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTRA_DC], DC_START_BITS, 0) < 0) |
742 return -1; | 718 return -1; |
743 if (read_dcs(avctx, &gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0) | 719 if (read_dcs(c->avctx, gb, &c->bundle[BINK_SRC_INTER_DC], DC_START_BITS, 1) < 0) |
744 return -1; | 720 return -1; |
745 if (read_runs(avctx, &gb, &c->bundle[BINK_SRC_RUN]) < 0) | 721 if (read_runs(c->avctx, gb, &c->bundle[BINK_SRC_RUN]) < 0) |
746 return -1; | 722 return -1; |
747 | 723 |
748 if (by == bh) | 724 if (by == bh) |
749 break; | 725 break; |
750 dst = c->pic.data[plane_idx] + 8*by*stride; | 726 dst = c->pic.data[plane_idx] + 8*by*stride; |
764 break; | 740 break; |
765 case SCALED_BLOCK: | 741 case SCALED_BLOCK: |
766 blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES); | 742 blk = get_value(c, BINK_SRC_SUB_BLOCK_TYPES); |
767 switch (blk) { | 743 switch (blk) { |
768 case RUN_BLOCK: | 744 case RUN_BLOCK: |
769 scan = bink_patterns[get_bits(&gb, 4)]; | 745 scan = bink_patterns[get_bits(gb, 4)]; |
770 i = 0; | 746 i = 0; |
771 do { | 747 do { |
772 int run = get_value(c, BINK_SRC_RUN) + 1; | 748 int run = get_value(c, BINK_SRC_RUN) + 1; |
773 | 749 |
774 i += run; | 750 i += run; |
775 if (i > 64) { | 751 if (i > 64) { |
776 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); | 752 av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); |
777 return -1; | 753 return -1; |
778 } | 754 } |
779 if (get_bits1(&gb)) { | 755 if (get_bits1(gb)) { |
780 v = get_value(c, BINK_SRC_COLORS); | 756 v = get_value(c, BINK_SRC_COLORS); |
781 for (j = 0; j < run; j++) | 757 for (j = 0; j < run; j++) |
782 ublock[*scan++] = v; | 758 ublock[*scan++] = v; |
783 } else { | 759 } else { |
784 for (j = 0; j < run; j++) | 760 for (j = 0; j < run; j++) |
789 ublock[*scan++] = get_value(c, BINK_SRC_COLORS); | 765 ublock[*scan++] = get_value(c, BINK_SRC_COLORS); |
790 break; | 766 break; |
791 case INTRA_BLOCK: | 767 case INTRA_BLOCK: |
792 c->dsp.clear_block(block); | 768 c->dsp.clear_block(block); |
793 block[0] = get_value(c, BINK_SRC_INTRA_DC); | 769 block[0] = get_value(c, BINK_SRC_INTRA_DC); |
794 read_dct_coeffs(&gb, block, c->scantable.permutated, 1); | 770 read_dct_coeffs(gb, block, c->scantable.permutated, 1); |
795 c->dsp.idct(block); | 771 c->dsp.idct(block); |
796 c->dsp.put_pixels_nonclamped(block, ublock, 8); | 772 c->dsp.put_pixels_nonclamped(block, ublock, 8); |
797 break; | 773 break; |
798 case FILL_BLOCK: | 774 case FILL_BLOCK: |
799 v = get_value(c, BINK_SRC_COLORS); | 775 v = get_value(c, BINK_SRC_COLORS); |
812 for (j = 0; j < 8; j++) | 788 for (j = 0; j < 8; j++) |
813 for (i = 0; i < 8; i++) | 789 for (i = 0; i < 8; i++) |
814 ublock[i + j*8] = get_value(c, BINK_SRC_COLORS); | 790 ublock[i + j*8] = get_value(c, BINK_SRC_COLORS); |
815 break; | 791 break; |
816 default: | 792 default: |
817 av_log(avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk); | 793 av_log(c->avctx, AV_LOG_ERROR, "Incorrect 16x16 block type %d\n", blk); |
818 return -1; | 794 return -1; |
819 } | 795 } |
820 if (blk != FILL_BLOCK) | 796 if (blk != FILL_BLOCK) |
821 c->dsp.scale_block(ublock, dst, stride); | 797 c->dsp.scale_block(ublock, dst, stride); |
822 bx++; | 798 bx++; |
826 case MOTION_BLOCK: | 802 case MOTION_BLOCK: |
827 xoff = get_value(c, BINK_SRC_X_OFF); | 803 xoff = get_value(c, BINK_SRC_X_OFF); |
828 yoff = get_value(c, BINK_SRC_Y_OFF); | 804 yoff = get_value(c, BINK_SRC_Y_OFF); |
829 ref = prev + xoff + yoff * stride; | 805 ref = prev + xoff + yoff * stride; |
830 if (ref < ref_start || ref > ref_end) { | 806 if (ref < ref_start || ref > ref_end) { |
831 av_log(avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", | 807 av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", |
832 bx*8 + xoff, by*8 + yoff); | 808 bx*8 + xoff, by*8 + yoff); |
833 return -1; | 809 return -1; |
834 } | 810 } |
835 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); | 811 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); |
836 break; | 812 break; |
837 case RUN_BLOCK: | 813 case RUN_BLOCK: |
838 scan = bink_patterns[get_bits(&gb, 4)]; | 814 scan = bink_patterns[get_bits(gb, 4)]; |
839 i = 0; | 815 i = 0; |
840 do { | 816 do { |
841 int run = get_value(c, BINK_SRC_RUN) + 1; | 817 int run = get_value(c, BINK_SRC_RUN) + 1; |
842 | 818 |
843 i += run; | 819 i += run; |
844 if (i > 64) { | 820 if (i > 64) { |
845 av_log(avctx, AV_LOG_ERROR, "Run went out of bounds\n"); | 821 av_log(c->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); |
846 return -1; | 822 return -1; |
847 } | 823 } |
848 if (get_bits1(&gb)) { | 824 if (get_bits1(gb)) { |
849 v = get_value(c, BINK_SRC_COLORS); | 825 v = get_value(c, BINK_SRC_COLORS); |
850 for (j = 0; j < run; j++) | 826 for (j = 0; j < run; j++) |
851 dst[coordmap[*scan++]] = v; | 827 dst[coordmap[*scan++]] = v; |
852 } else { | 828 } else { |
853 for (j = 0; j < run; j++) | 829 for (j = 0; j < run; j++) |
860 case RESIDUE_BLOCK: | 836 case RESIDUE_BLOCK: |
861 xoff = get_value(c, BINK_SRC_X_OFF); | 837 xoff = get_value(c, BINK_SRC_X_OFF); |
862 yoff = get_value(c, BINK_SRC_Y_OFF); | 838 yoff = get_value(c, BINK_SRC_Y_OFF); |
863 ref = prev + xoff + yoff * stride; | 839 ref = prev + xoff + yoff * stride; |
864 if (ref < ref_start || ref > ref_end) { | 840 if (ref < ref_start || ref > ref_end) { |
865 av_log(avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", | 841 av_log(c->avctx, AV_LOG_ERROR, "Copy out of bounds @%d, %d\n", |
866 bx*8 + xoff, by*8 + yoff); | 842 bx*8 + xoff, by*8 + yoff); |
867 return -1; | 843 return -1; |
868 } | 844 } |
869 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); | 845 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); |
870 c->dsp.clear_block(block); | 846 c->dsp.clear_block(block); |
871 v = get_bits(&gb, 7); | 847 v = get_bits(gb, 7); |
872 read_residue(&gb, block, v); | 848 read_residue(gb, block, v); |
873 c->dsp.add_pixels8(dst, block, stride); | 849 c->dsp.add_pixels8(dst, block, stride); |
874 break; | 850 break; |
875 case INTRA_BLOCK: | 851 case INTRA_BLOCK: |
876 c->dsp.clear_block(block); | 852 c->dsp.clear_block(block); |
877 block[0] = get_value(c, BINK_SRC_INTRA_DC); | 853 block[0] = get_value(c, BINK_SRC_INTRA_DC); |
878 read_dct_coeffs(&gb, block, c->scantable.permutated, 1); | 854 read_dct_coeffs(gb, block, c->scantable.permutated, 1); |
879 c->dsp.idct_put(dst, stride, block); | 855 c->dsp.idct_put(dst, stride, block); |
880 break; | 856 break; |
881 case FILL_BLOCK: | 857 case FILL_BLOCK: |
882 v = get_value(c, BINK_SRC_COLORS); | 858 v = get_value(c, BINK_SRC_COLORS); |
883 c->dsp.fill_block_tab[1](dst, v, stride, 8); | 859 c->dsp.fill_block_tab[1](dst, v, stride, 8); |
887 yoff = get_value(c, BINK_SRC_Y_OFF); | 863 yoff = get_value(c, BINK_SRC_Y_OFF); |
888 ref = prev + xoff + yoff * stride; | 864 ref = prev + xoff + yoff * stride; |
889 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); | 865 c->dsp.put_pixels_tab[1][0](dst, ref, stride, 8); |
890 c->dsp.clear_block(block); | 866 c->dsp.clear_block(block); |
891 block[0] = get_value(c, BINK_SRC_INTER_DC); | 867 block[0] = get_value(c, BINK_SRC_INTER_DC); |
892 read_dct_coeffs(&gb, block, c->scantable.permutated, 0); | 868 read_dct_coeffs(gb, block, c->scantable.permutated, 0); |
893 c->dsp.idct_add(dst, stride, block); | 869 c->dsp.idct_add(dst, stride, block); |
894 break; | 870 break; |
895 case PATTERN_BLOCK: | 871 case PATTERN_BLOCK: |
896 for (i = 0; i < 2; i++) | 872 for (i = 0; i < 2; i++) |
897 col[i] = get_value(c, BINK_SRC_COLORS); | 873 col[i] = get_value(c, BINK_SRC_COLORS); |
905 for (i = 0; i < 8; i++) | 881 for (i = 0; i < 8; i++) |
906 memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8); | 882 memcpy(dst + i*stride, c->bundle[BINK_SRC_COLORS].cur_ptr + i*8, 8); |
907 c->bundle[BINK_SRC_COLORS].cur_ptr += 64; | 883 c->bundle[BINK_SRC_COLORS].cur_ptr += 64; |
908 break; | 884 break; |
909 default: | 885 default: |
910 av_log(avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); | 886 av_log(c->avctx, AV_LOG_ERROR, "Unknown block type %d\n", blk); |
911 return -1; | 887 return -1; |
912 } | 888 } |
913 } | 889 } |
914 } | 890 } |
915 if (get_bits_count(&gb) & 0x1F) //next plane data starts at 32-bit boundary | 891 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)); | 892 skip_bits_long(gb, 32 - (get_bits_count(gb) & 0x1F)); |
893 | |
894 return 0; | |
895 } | |
896 | |
897 static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *pkt) | |
898 { | |
899 BinkContext * const c = avctx->priv_data; | |
900 GetBitContext gb; | |
901 int plane, plane_idx; | |
902 int bits_count = pkt->size << 3; | |
903 | |
904 if(c->pic.data[0]) | |
905 avctx->release_buffer(avctx, &c->pic); | |
906 | |
907 if(avctx->get_buffer(avctx, &c->pic) < 0){ | |
908 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); | |
909 return -1; | |
910 } | |
911 | |
912 init_get_bits(&gb, pkt->data, bits_count); | |
913 if (c->has_alpha) { | |
914 int aplane_bits = get_bits_long(&gb, 32) << 3; | |
915 if (aplane_bits <= 32 || (aplane_bits & 0x1F)) { | |
916 av_log(avctx, AV_LOG_ERROR, "Incorrect alpha plane size %d\n", aplane_bits); | |
917 return -1; | |
918 } | |
919 skip_bits_long(&gb, aplane_bits - 32); | |
920 } | |
921 if (c->version >= 'i') | |
922 skip_bits_long(&gb, 32); | |
923 | |
924 for (plane = 0; plane < 3; plane++) { | |
925 plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); | |
926 | |
927 if (bink_decode_plane(c, &gb, plane_idx, !!plane) < 0) | |
928 return -1; | |
917 if (get_bits_count(&gb) >= bits_count) | 929 if (get_bits_count(&gb) >= bits_count) |
918 break; | 930 break; |
919 } | 931 } |
920 emms_c(); | 932 emms_c(); |
921 | 933 |