diff options
author | Måns Rullgård <mans@mansr.com> | 2006-01-21 18:19:47 +0000 |
---|---|---|
committer | Måns Rullgård <mans@mansr.com> | 2006-01-21 18:19:47 +0000 |
commit | 62327e2852ffe1c3088feafa0dfbd4ddb6632064 (patch) | |
tree | d49effc534403cb70b3728155da8f3aae0116ac6 | |
parent | 13c71451350071888b5d690f9d48cd316e0d4aed (diff) | |
download | ffmpeg-62327e2852ffe1c3088feafa0dfbd4ddb6632064.tar.gz |
native ac3 parser
Originally committed as revision 4878 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/a52dec.c | 7 | ||||
-rw-r--r-- | libavcodec/allcodecs.c | 2 | ||||
-rw-r--r-- | libavcodec/parser.c | 122 |
3 files changed, 96 insertions, 35 deletions
diff --git a/libavcodec/a52dec.c b/libavcodec/a52dec.c index 182124f216..5226325ab6 100644 --- a/libavcodec/a52dec.c +++ b/libavcodec/a52dec.c @@ -76,13 +76,6 @@ static void* dlsymm(void* handle, const char* symbol) av_log( NULL, AV_LOG_ERROR, "A52 Decoder - function '%s' can't be resolved\n", symbol); return f; } - -int ff_a52_syncinfo( AVCodecContext * avctx, uint8_t * buf, int * flags, int * sample_rate, int * bit_rate ) -{ - AC3DecodeState *s = avctx->priv_data; - - return s->a52_syncinfo(buf, flags, sample_rate, bit_rate); -} #endif static int a52_decode_init(AVCodecContext *avctx) diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 811abd96cf..bef0373b73 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -614,9 +614,7 @@ PCM_CODEC(CODEC_ID_ADPCM_YAMAHA, adpcm_yamaha); av_register_codec_parser(&pnm_parser); av_register_codec_parser(&mpegaudio_parser); -#ifdef CONFIG_AC3 av_register_codec_parser(&ac3_parser); -#endif #ifdef CONFIG_DVDSUB_DECODER av_register_codec_parser(&dvdsub_parser); diff --git a/libavcodec/parser.c b/libavcodec/parser.c index a21c6cfe30..9d424e9438 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -748,24 +748,106 @@ static int mpegaudio_parse(AVCodecParserContext *s1, return buf_ptr - buf; } -#ifdef CONFIG_AC3 -#ifdef CONFIG_A52BIN -extern int ff_a52_syncinfo (AVCodecContext * avctx, const uint8_t * buf, - int * flags, int * sample_rate, int * bit_rate); -#else -extern int a52_syncinfo (const uint8_t * buf, int * flags, - int * sample_rate, int * bit_rate); -#endif - typedef struct AC3ParseContext { uint8_t inbuf[4096]; /* input buffer */ uint8_t *inbuf_ptr; int frame_size; - int flags; } AC3ParseContext; #define AC3_HEADER_SIZE 7 -#define A52_LFE 16 + +static const int ac3_sample_rates[4] = { + 48000, 44100, 32000, 0 +}; + +static const int ac3_frame_sizes[64][3] = { + { 64, 69, 96 }, + { 64, 70, 96 }, + { 80, 87, 120 }, + { 80, 88, 120 }, + { 96, 104, 144 }, + { 96, 105, 144 }, + { 112, 121, 168 }, + { 112, 122, 168 }, + { 128, 139, 192 }, + { 128, 140, 192 }, + { 160, 174, 240 }, + { 160, 175, 240 }, + { 192, 208, 288 }, + { 192, 209, 288 }, + { 224, 243, 336 }, + { 224, 244, 336 }, + { 256, 278, 384 }, + { 256, 279, 384 }, + { 320, 348, 480 }, + { 320, 349, 480 }, + { 384, 417, 576 }, + { 384, 418, 576 }, + { 448, 487, 672 }, + { 448, 488, 672 }, + { 512, 557, 768 }, + { 512, 558, 768 }, + { 640, 696, 960 }, + { 640, 697, 960 }, + { 768, 835, 1152 }, + { 768, 836, 1152 }, + { 896, 975, 1344 }, + { 896, 976, 1344 }, + { 1024, 1114, 1536 }, + { 1024, 1115, 1536 }, + { 1152, 1253, 1728 }, + { 1152, 1254, 1728 }, + { 1280, 1393, 1920 }, + { 1280, 1394, 1920 }, +}; + +static const int ac3_bitrates[64] = { + 32, 32, 40, 40, 48, 48, 56, 56, 64, 64, 80, 80, 96, 96, 112, 112, + 128, 128, 160, 160, 192, 192, 224, 224, 256, 256, 320, 320, 384, + 384, 448, 448, 512, 512, 576, 576, 640, 640, +}; + +static const int ac3_channels[8] = { + 2, 1, 2, 3, 3, 4, 4, 5 +}; + +static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, + int *bit_rate) +{ + unsigned int fscod, frmsizecod, acmod, bsid, lfeon; + GetBitContext bits; + + init_get_bits(&bits, buf, AC3_HEADER_SIZE * 8); + + if(get_bits(&bits, 16) != 0x0b77) + return 0; + + get_bits(&bits, 16); /* crc */ + fscod = get_bits(&bits, 2); + frmsizecod = get_bits(&bits, 6); + + if(!ac3_sample_rates[fscod]) + return 0; + + bsid = get_bits(&bits, 5); + if(bsid > 8) + return 0; + get_bits(&bits, 3); /* bsmod */ + acmod = get_bits(&bits, 3); + if(acmod & 1 && acmod != 1) + get_bits(&bits, 2); /* cmixlev */ + if(acmod & 4) + get_bits(&bits, 2); /* surmixlev */ + if(acmod & 2) + get_bits(&bits, 2); /* dsurmod */ + lfeon = get_bits(&bits, 1); + + *sample_rate = ac3_sample_rates[fscod]; + *bit_rate = ac3_bitrates[frmsizecod] * 1000; + *channels = ac3_channels[acmod] + lfeon; + + return ac3_frame_sizes[frmsizecod][fscod] * 2; +} static int ac3_parse_init(AVCodecParserContext *s1) { @@ -781,10 +863,7 @@ static int ac3_parse(AVCodecParserContext *s1, { AC3ParseContext *s = s1->priv_data; const uint8_t *buf_ptr; - int len, sample_rate, bit_rate; - static const int ac3_channels[8] = { - 2, 1, 2, 3, 3, 4, 4, 5 - }; + int len, sample_rate, bit_rate, channels; *poutbuf = NULL; *poutbuf_size = 0; @@ -802,11 +881,7 @@ static int ac3_parse(AVCodecParserContext *s1, s->inbuf_ptr += len; buf_size -= len; if ((s->inbuf_ptr - s->inbuf) == AC3_HEADER_SIZE) { -#ifdef CONFIG_A52BIN - len = ff_a52_syncinfo(avctx, s->inbuf, &s->flags, &sample_rate, &bit_rate); -#else - len = a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate); -#endif + len = ac3_sync(s->inbuf, &channels, &sample_rate, &bit_rate); if (len == 0) { /* no sync found : move by one byte (inefficient, but simple!) */ memmove(s->inbuf, s->inbuf + 1, AC3_HEADER_SIZE - 1); @@ -817,9 +892,7 @@ static int ac3_parse(AVCodecParserContext *s1, avctx->sample_rate = sample_rate; /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */ if(avctx->channels!=1 && avctx->channels!=2){ - avctx->channels = ac3_channels[s->flags & 7]; - if (s->flags & A52_LFE) - avctx->channels++; + avctx->channels = channels; } avctx->bit_rate = bit_rate; avctx->frame_size = 6 * 256; @@ -844,7 +917,6 @@ static int ac3_parse(AVCodecParserContext *s1, } return buf_ptr - buf; } -#endif AVCodecParser mpegvideo_parser = { { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, @@ -872,7 +944,6 @@ AVCodecParser mpegaudio_parser = { NULL, }; -#ifdef CONFIG_AC3 AVCodecParser ac3_parser = { { CODEC_ID_AC3 }, sizeof(AC3ParseContext), @@ -880,4 +951,3 @@ AVCodecParser ac3_parser = { ac3_parse, NULL, }; -#endif |