Mercurial > libavcodec.hg
comparison parser.c @ 3059:61b4cc042988 libavcodec
native ac3 parser
author | mru |
---|---|
date | Sat, 21 Jan 2006 18:19:47 +0000 |
parents | 0b546eab515d |
children | f02d0b59279c |
comparison
equal
deleted
inserted
replaced
3058:8936371f5a5c | 3059:61b4cc042988 |
---|---|
746 } | 746 } |
747 } | 747 } |
748 return buf_ptr - buf; | 748 return buf_ptr - buf; |
749 } | 749 } |
750 | 750 |
751 #ifdef CONFIG_AC3 | |
752 #ifdef CONFIG_A52BIN | |
753 extern int ff_a52_syncinfo (AVCodecContext * avctx, const uint8_t * buf, | |
754 int * flags, int * sample_rate, int * bit_rate); | |
755 #else | |
756 extern int a52_syncinfo (const uint8_t * buf, int * flags, | |
757 int * sample_rate, int * bit_rate); | |
758 #endif | |
759 | |
760 typedef struct AC3ParseContext { | 751 typedef struct AC3ParseContext { |
761 uint8_t inbuf[4096]; /* input buffer */ | 752 uint8_t inbuf[4096]; /* input buffer */ |
762 uint8_t *inbuf_ptr; | 753 uint8_t *inbuf_ptr; |
763 int frame_size; | 754 int frame_size; |
764 int flags; | |
765 } AC3ParseContext; | 755 } AC3ParseContext; |
766 | 756 |
767 #define AC3_HEADER_SIZE 7 | 757 #define AC3_HEADER_SIZE 7 |
768 #define A52_LFE 16 | 758 |
759 static const int ac3_sample_rates[4] = { | |
760 48000, 44100, 32000, 0 | |
761 }; | |
762 | |
763 static const int ac3_frame_sizes[64][3] = { | |
764 { 64, 69, 96 }, | |
765 { 64, 70, 96 }, | |
766 { 80, 87, 120 }, | |
767 { 80, 88, 120 }, | |
768 { 96, 104, 144 }, | |
769 { 96, 105, 144 }, | |
770 { 112, 121, 168 }, | |
771 { 112, 122, 168 }, | |
772 { 128, 139, 192 }, | |
773 { 128, 140, 192 }, | |
774 { 160, 174, 240 }, | |
775 { 160, 175, 240 }, | |
776 { 192, 208, 288 }, | |
777 { 192, 209, 288 }, | |
778 { 224, 243, 336 }, | |
779 { 224, 244, 336 }, | |
780 { 256, 278, 384 }, | |
781 { 256, 279, 384 }, | |
782 { 320, 348, 480 }, | |
783 { 320, 349, 480 }, | |
784 { 384, 417, 576 }, | |
785 { 384, 418, 576 }, | |
786 { 448, 487, 672 }, | |
787 { 448, 488, 672 }, | |
788 { 512, 557, 768 }, | |
789 { 512, 558, 768 }, | |
790 { 640, 696, 960 }, | |
791 { 640, 697, 960 }, | |
792 { 768, 835, 1152 }, | |
793 { 768, 836, 1152 }, | |
794 { 896, 975, 1344 }, | |
795 { 896, 976, 1344 }, | |
796 { 1024, 1114, 1536 }, | |
797 { 1024, 1115, 1536 }, | |
798 { 1152, 1253, 1728 }, | |
799 { 1152, 1254, 1728 }, | |
800 { 1280, 1393, 1920 }, | |
801 { 1280, 1394, 1920 }, | |
802 }; | |
803 | |
804 static const int ac3_bitrates[64] = { | |
805 32, 32, 40, 40, 48, 48, 56, 56, 64, 64, 80, 80, 96, 96, 112, 112, | |
806 128, 128, 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, | |
807 384, 448, 448, 512, 512, 576, 576, 640, 640, | |
808 }; | |
809 | |
810 static const int ac3_channels[8] = { | |
811 2, 1, 2, 3, 3, 4, 4, 5 | |
812 }; | |
813 | |
814 static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, | |
815 int *bit_rate) | |
816 { | |
817 unsigned int fscod, frmsizecod, acmod, bsid, lfeon; | |
818 GetBitContext bits; | |
819 | |
820 init_get_bits(&bits, buf, AC3_HEADER_SIZE * 8); | |
821 | |
822 if(get_bits(&bits, 16) != 0x0b77) | |
823 return 0; | |
824 | |
825 get_bits(&bits, 16); /* crc */ | |
826 fscod = get_bits(&bits, 2); | |
827 frmsizecod = get_bits(&bits, 6); | |
828 | |
829 if(!ac3_sample_rates[fscod]) | |
830 return 0; | |
831 | |
832 bsid = get_bits(&bits, 5); | |
833 if(bsid > 8) | |
834 return 0; | |
835 get_bits(&bits, 3); /* bsmod */ | |
836 acmod = get_bits(&bits, 3); | |
837 if(acmod & 1 && acmod != 1) | |
838 get_bits(&bits, 2); /* cmixlev */ | |
839 if(acmod & 4) | |
840 get_bits(&bits, 2); /* surmixlev */ | |
841 if(acmod & 2) | |
842 get_bits(&bits, 2); /* dsurmod */ | |
843 lfeon = get_bits(&bits, 1); | |
844 | |
845 *sample_rate = ac3_sample_rates[fscod]; | |
846 *bit_rate = ac3_bitrates[frmsizecod] * 1000; | |
847 *channels = ac3_channels[acmod] + lfeon; | |
848 | |
849 return ac3_frame_sizes[frmsizecod][fscod] * 2; | |
850 } | |
769 | 851 |
770 static int ac3_parse_init(AVCodecParserContext *s1) | 852 static int ac3_parse_init(AVCodecParserContext *s1) |
771 { | 853 { |
772 AC3ParseContext *s = s1->priv_data; | 854 AC3ParseContext *s = s1->priv_data; |
773 s->inbuf_ptr = s->inbuf; | 855 s->inbuf_ptr = s->inbuf; |
779 uint8_t **poutbuf, int *poutbuf_size, | 861 uint8_t **poutbuf, int *poutbuf_size, |
780 const uint8_t *buf, int buf_size) | 862 const uint8_t *buf, int buf_size) |
781 { | 863 { |
782 AC3ParseContext *s = s1->priv_data; | 864 AC3ParseContext *s = s1->priv_data; |
783 const uint8_t *buf_ptr; | 865 const uint8_t *buf_ptr; |
784 int len, sample_rate, bit_rate; | 866 int len, sample_rate, bit_rate, channels; |
785 static const int ac3_channels[8] = { | |
786 2, 1, 2, 3, 3, 4, 4, 5 | |
787 }; | |
788 | 867 |
789 *poutbuf = NULL; | 868 *poutbuf = NULL; |
790 *poutbuf_size = 0; | 869 *poutbuf_size = 0; |
791 | 870 |
792 buf_ptr = buf; | 871 buf_ptr = buf; |
800 memcpy(s->inbuf_ptr, buf_ptr, len); | 879 memcpy(s->inbuf_ptr, buf_ptr, len); |
801 buf_ptr += len; | 880 buf_ptr += len; |
802 s->inbuf_ptr += len; | 881 s->inbuf_ptr += len; |
803 buf_size -= len; | 882 buf_size -= len; |
804 if ((s->inbuf_ptr - s->inbuf) == AC3_HEADER_SIZE) { | 883 if ((s->inbuf_ptr - s->inbuf) == AC3_HEADER_SIZE) { |
805 #ifdef CONFIG_A52BIN | 884 len = ac3_sync(s->inbuf, &channels, &sample_rate, &bit_rate); |
806 len = ff_a52_syncinfo(avctx, s->inbuf, &s->flags, &sample_rate, &bit_rate); | |
807 #else | |
808 len = a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate); | |
809 #endif | |
810 if (len == 0) { | 885 if (len == 0) { |
811 /* no sync found : move by one byte (inefficient, but simple!) */ | 886 /* no sync found : move by one byte (inefficient, but simple!) */ |
812 memmove(s->inbuf, s->inbuf + 1, AC3_HEADER_SIZE - 1); | 887 memmove(s->inbuf, s->inbuf + 1, AC3_HEADER_SIZE - 1); |
813 s->inbuf_ptr--; | 888 s->inbuf_ptr--; |
814 } else { | 889 } else { |
815 s->frame_size = len; | 890 s->frame_size = len; |
816 /* update codec info */ | 891 /* update codec info */ |
817 avctx->sample_rate = sample_rate; | 892 avctx->sample_rate = sample_rate; |
818 /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */ | 893 /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */ |
819 if(avctx->channels!=1 && avctx->channels!=2){ | 894 if(avctx->channels!=1 && avctx->channels!=2){ |
820 avctx->channels = ac3_channels[s->flags & 7]; | 895 avctx->channels = channels; |
821 if (s->flags & A52_LFE) | |
822 avctx->channels++; | |
823 } | 896 } |
824 avctx->bit_rate = bit_rate; | 897 avctx->bit_rate = bit_rate; |
825 avctx->frame_size = 6 * 256; | 898 avctx->frame_size = 6 * 256; |
826 } | 899 } |
827 } | 900 } |
842 break; | 915 break; |
843 } | 916 } |
844 } | 917 } |
845 return buf_ptr - buf; | 918 return buf_ptr - buf; |
846 } | 919 } |
847 #endif | |
848 | 920 |
849 AVCodecParser mpegvideo_parser = { | 921 AVCodecParser mpegvideo_parser = { |
850 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, | 922 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, |
851 sizeof(ParseContext1), | 923 sizeof(ParseContext1), |
852 NULL, | 924 NULL, |
870 mpegaudio_parse_init, | 942 mpegaudio_parse_init, |
871 mpegaudio_parse, | 943 mpegaudio_parse, |
872 NULL, | 944 NULL, |
873 }; | 945 }; |
874 | 946 |
875 #ifdef CONFIG_AC3 | |
876 AVCodecParser ac3_parser = { | 947 AVCodecParser ac3_parser = { |
877 { CODEC_ID_AC3 }, | 948 { CODEC_ID_AC3 }, |
878 sizeof(AC3ParseContext), | 949 sizeof(AC3ParseContext), |
879 ac3_parse_init, | 950 ac3_parse_init, |
880 ac3_parse, | 951 ac3_parse, |
881 NULL, | 952 NULL, |
882 }; | 953 }; |
883 #endif |