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 |
