diff options
author | Ian Caulfield <ian.caulfield@gmx.at> | 2007-01-24 15:31:48 +0000 |
---|---|---|
committer | Guillaume Poirier <gpoirier@mplayerhq.hu> | 2007-01-24 15:31:48 +0000 |
commit | 44a39bd7701e71e0713e67efcc27f3aa0b456417 (patch) | |
tree | bb8ad1c895889b94ee8e5d71468e17c28f9f780f | |
parent | 6ad7cd0469989529e4bb0d469ab5f1978dd1c201 (diff) | |
download | ffmpeg-44a39bd7701e71e0713e67efcc27f3aa0b456417.tar.gz |
Allows the AC3 parser to read the frame size and codec parameters from E-AC3 streams,
allowing them to be correctly demuxed.
Currently it only identifies the primary substream, and will skip over any additional
dependent or independent substreams.
Patch by Ian Caulfield % ian P caulfield A gmail P com %
Original thread:
date: Jan 19, 2007 9:55 AM
subject: Re: [Ffmpeg-devel] [PATCH] Correctly parse headers of E-AC3 streams
Originally committed as revision 7687 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavcodec/parser.c | 51 |
1 files changed, 46 insertions, 5 deletions
diff --git a/libavcodec/parser.c b/libavcodec/parser.c index 740ad855c4..faeb5ff815 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -632,9 +632,14 @@ static const int ac3_bitrates[64] = { 384, 448, 448, 512, 512, 576, 576, 640, 640, }; -static const int ac3_channels[8] = { +static const uint8_t ac3_channels[8] = { 2, 1, 2, 3, 3, 4, 4, 5 }; + +static const uint8_t eac3_blocks[4] = { + 1, 2, 3, 6 +}; + #endif /* CONFIG_AC3_PARSER */ #ifdef CONFIG_AAC_PARSER @@ -653,6 +658,7 @@ static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, int *bit_rate, int *samples) { unsigned int fscod, frmsizecod, acmod, bsid, lfeon; + unsigned int strmtyp, substreamid, frmsiz, fscod2, numblkscod; GetBitContext bits; init_get_bits(&bits, buf, AC3_HEADER_SIZE * 8); @@ -660,16 +666,16 @@ static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, if(get_bits(&bits, 16) != 0x0b77) return 0; + bsid = show_bits_long(&bits, 29) & 0x1f; + if(bsid <= 8) { /* Normal AC-3 */ skip_bits(&bits, 16); /* crc */ fscod = get_bits(&bits, 2); frmsizecod = get_bits(&bits, 6); - if(!ac3_sample_rates[fscod]) + if(fscod == 3) return 0; - bsid = get_bits(&bits, 5); - if(bsid > 8) - return 0; + skip_bits(&bits, 5); /* bsid */ skip_bits(&bits, 3); /* bsmod */ acmod = get_bits(&bits, 3); if(acmod & 1 && acmod != 1) @@ -686,6 +692,41 @@ static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, *samples = 6 * 256; return ac3_frame_sizes[frmsizecod][fscod] * 2; + } else if (bsid >= 10 && bsid <= 16) { /* Enhanced AC-3 */ + strmtyp = get_bits(&bits, 2); + substreamid = get_bits(&bits, 3); + + if (strmtyp != 0 || substreamid != 0) + return 0; /* Currently don't support additional streams */ + + frmsiz = get_bits(&bits, 11) + 1; + fscod = get_bits(&bits, 2); + if (fscod == 3) { + fscod2 = get_bits(&bits, 2); + numblkscod = 3; + + if(fscod2 == 3) + return 0; + + *sample_rate = ac3_sample_rates[fscod2] / 2; + } else { + numblkscod = get_bits(&bits, 2); + + *sample_rate = ac3_sample_rates[fscod]; + } + + acmod = get_bits(&bits, 3); + lfeon = get_bits1(&bits); + + *samples = eac3_blocks[numblkscod] * 256; + *bit_rate = frmsiz * (*sample_rate) * 16 / (*samples); + *channels = ac3_channels[acmod] + lfeon; + + return frmsiz * 2; + } + + /* Unsupported bitstream version */ + return 0; } #endif /* CONFIG_AC3_PARSER */ |