[Ffmpeg-devel] [PATCH] Correctly parse headers of E-AC3 streams
Michael Niedermayer
michaelni
Fri Jan 19 00:04:35 CET 2007
Hi
On Thu, Jan 18, 2007 at 09:39:32AM +0000, Ian Caulfield wrote:
> Hi,
>
> This patch 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. If I can get hold of a sample stream
> containing these features, I'll try to add support for them.
>
> Patch is supplied in two parts - the first contains functional changes, the
> second re-indents code.
>
> Ian
> Index: libavcodec/parser.c
> ===================================================================
> --- libavcodec/parser.c (revision 7578)
> +++ libavcodec/parser.c (working copy)
> @@ -635,6 +635,11 @@
> static const int ac3_channels[8] = {
> 2, 1, 2, 3, 3, 4, 4, 5
> };
> +
> +static const int eac3_blocks[4] = {
> + 1, 2, 3, 6
> +};
a uint8_t table would safe 12 bytes ...
> +
> #endif /* CONFIG_AC3_PARSER */
>
> #ifdef CONFIG_AAC_PARSER
> @@ -653,6 +658,7 @@
> 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,6 +666,8 @@
> 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);
> @@ -667,9 +675,7 @@
> if(!ac3_sample_rates[fscod])
> 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 @@
> *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(!ac3_sample_rates[fscod2])
> + return 0;
why not if(fscod2 == 3) like above?
> +
> + *sample_rate = ac3_sample_rates[fscod2] / 2;
> + } else {
> + numblkscod = get_bits(&bits, 2);
> +
> + *sample_rate = ac3_sample_rates[fscod];
> + }
what about: ? (no iam not sure if its better ...)
fscod = get_bits(&bits, 2);
numblkscod = get_bits(&bits, 2);
if(fscod == 3){
if(numblkscod == 3)
return 0;
*sample_rate = ac3_sample_rates[numblkscod] / 2;
numblkscod = 3;
}else
*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;
> + }
also i was thinking about something like the following but again iam not
sure if its better, i hoped more could be merged ...
iam fine with your variant too
//the following 3 are a 16bit CRC in AC-3
strmtyp = get_bits(&bits, 2);
substreamid = get_bits(&bits, 3);
frmsiz = get_bits(&bits, 11) + 1;
fscod = get_bits(&bits, 2);
/* AC-3 */
frmsizecod = show_bits(&bits, 6);
/* Enhanced AC-3 */
numblkscod = get_bits(&bits, 2);
acmod = get_bits(&bits, 3);
lfeon = get_bits1(&bits);
bsid = get_bits(&bits, 5);
if(bsid <= 8){
if(fscod == 3)
return 0;
skip_bits(&bits, 3); /* bsmod */
acmod = get_bits(&bits, 3);
if(acmod & 1 && acmod != 1)
skip_bits(&bits, 2); /* cmixlev */
if(acmod & 4)
skip_bits(&bits, 2); /* surmixlev */
if(acmod & 2)
skip_bits(&bits, 2); /* dsurmod */
*sample_rate = ac3_sample_rates[fscod];
*bit_rate = ac3_bitrates[frmsizecod] * 1000;
*samples = 6 * 256;
frmsiz = ac3_frame_sizes[frmsizecod][fscod];
}else if (bsid >= 10 && bsid <= 16) { /* Enhanced AC-3 */
if (strmtyp != 0 || substreamid != 0)
return 0; /* Currently don't support additional streams */
if(fscod == 3){
if(numblkscod == 3)
return 0;
*sample_rate = ac3_sample_rates[numblkscod] / 2;
numblkscod = 3;
}else
*sample_rate = ac3_sample_rates[fscod];
acmod = get_bits(&bits, 3);
*samples = eac3_blocks[numblkscod] * 256;
*bit_rate = frmsiz * (*sample_rate) * 16 / (*samples);
}else
return 0;
lfeon = get_bits1(&bits);
*channels = ac3_channels[acmod] + lfeon;
return frmsiz * 2;
[...]
--
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB
Opposition brings concord. Out of discord comes the fairest harmony.
-- Heraclitus
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070119/fe9d0913/attachment.pgp>
More information about the ffmpeg-devel
mailing list