From 646800f79ca478309fcf741e840ba5b5e795e533 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 5 Jan 2008 18:39:55 +0000 Subject: [PATCH] move E-AC3 header parsing to ff_ac3_parse_header() Originally committed as revision 11420 to svn://svn.ffmpeg.org/ffmpeg/trunk --- libavcodec/ac3_parser.c | 84 ++++++++++++++++++----------------------- libavcodec/ac3dec.c | 3 ++ 2 files changed, 40 insertions(+), 47 deletions(-) diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index 1b396bf6ac..604dac186a 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -38,6 +38,7 @@ int ff_ac3_parse_header(const uint8_t buf[7], AC3HeaderInfo *hdr) { GetBitContext gbc; int frame_size_code; + int num_blocks; memset(hdr, 0, sizeof(*hdr)); @@ -47,11 +48,13 @@ int ff_ac3_parse_header(const uint8_t buf[7], AC3HeaderInfo *hdr) if(hdr->sync_word != 0x0B77) return AC3_PARSE_ERROR_SYNC; - /* read ahead to bsid to make sure this is AC-3, not E-AC-3 */ + /* read ahead to bsid to distinguish between AC-3 and E-AC-3 */ hdr->bitstream_id = show_bits_long(&gbc, 29) & 0x1F; - if(hdr->bitstream_id > 10) + if(hdr->bitstream_id > 16) return AC3_PARSE_ERROR_BSID; + if(hdr->bitstream_id <= 10) { + /* Normal AC-3 */ hdr->crc1 = get_bits(&gbc, 16); hdr->sr_code = get_bits(&gbc, 2); if(hdr->sr_code == 3) @@ -81,6 +84,37 @@ int ff_ac3_parse_header(const uint8_t buf[7], AC3HeaderInfo *hdr) hdr->bit_rate = (ff_ac3_bitrate_tab[frame_size_code>>1] * 1000) >> hdr->sr_shift; hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; hdr->frame_size = ff_ac3_frame_size_tab[frame_size_code][hdr->sr_code] * 2; + } else { + /* Enhanced AC-3 */ + hdr->crc1 = 0; + skip_bits(&gbc, 2); // skip stream type + skip_bits(&gbc, 3); // skip substream id + + hdr->frame_size = (get_bits(&gbc, 11) + 1) << 1; + if(hdr->frame_size < AC3_HEADER_SIZE) + return AC3_PARSE_ERROR_FRAME_SIZE; + + hdr->sr_code = get_bits(&gbc, 2); + if (hdr->sr_code == 3) { + int sr_code2 = get_bits(&gbc, 2); + if(sr_code2 == 3) + return AC3_PARSE_ERROR_SAMPLE_RATE; + hdr->sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2; + hdr->sr_shift = 1; + num_blocks = 6; + } else { + num_blocks = eac3_blocks[get_bits(&gbc, 2)]; + hdr->sample_rate = ff_ac3_sample_rate_tab[hdr->sr_code]; + hdr->sr_shift = 0; + } + + hdr->channel_mode = get_bits(&gbc, 3); + hdr->lfe_on = get_bits1(&gbc); + + hdr->bit_rate = (uint32_t)(8.0 * hdr->frame_size * hdr->sample_rate / + (num_blocks * 256.0)); + hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; + } return 0; } @@ -89,62 +123,18 @@ static int ac3_sync(const uint8_t *buf, int *channels, int *sample_rate, int *bit_rate, int *samples) { int err; - unsigned int sr_code, channel_mode, bitstream_id, lfe_on; - unsigned int stream_type, substream_id, frame_size, sr_code2, num_blocks_code; - GetBitContext bits; AC3HeaderInfo hdr; err = ff_ac3_parse_header(buf, &hdr); - if(err < 0 && err != -2) + if(err < 0) return 0; - bitstream_id = hdr.bitstream_id; - if(bitstream_id <= 10) { /* Normal AC-3 */ *sample_rate = hdr.sample_rate; *bit_rate = hdr.bit_rate; *channels = hdr.channels; *samples = AC3_FRAME_SIZE; return hdr.frame_size; - } else if (bitstream_id > 10 && bitstream_id <= 16) { /* Enhanced AC-3 */ - init_get_bits(&bits, &buf[2], (AC3_HEADER_SIZE-2) * 8); - stream_type = get_bits(&bits, 2); - substream_id = get_bits(&bits, 3); - - if (stream_type != 0 || substream_id != 0) - return 0; /* Currently don't support additional streams */ - - frame_size = get_bits(&bits, 11) + 1; - if(frame_size*2 < AC3_HEADER_SIZE) - return 0; - - sr_code = get_bits(&bits, 2); - if (sr_code == 3) { - sr_code2 = get_bits(&bits, 2); - num_blocks_code = 3; - - if(sr_code2 == 3) - return 0; - - *sample_rate = ff_ac3_sample_rate_tab[sr_code2] / 2; - } else { - num_blocks_code = get_bits(&bits, 2); - - *sample_rate = ff_ac3_sample_rate_tab[sr_code]; - } - - channel_mode = get_bits(&bits, 3); - lfe_on = get_bits1(&bits); - - *samples = eac3_blocks[num_blocks_code] * 256; - *bit_rate = frame_size * (*sample_rate) * 16 / (*samples); - *channels = ff_ac3_channels_tab[channel_mode] + lfe_on; - - return frame_size * 2; - } - - /* Unsupported bitstream version */ - return 0; } static int ac3_parse_init(AVCodecParserContext *s1) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 660d8f64d5..76cf1add0e 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -338,6 +338,9 @@ static int ac3_parse_header(AC3DecodeContext *s) if(err) return err; + if(hdr.bitstream_id > 10) + return AC3_PARSE_ERROR_BSID; + /* get decoding parameters from header info */ s->bit_alloc_params.sr_code = hdr.sr_code; s->channel_mode = hdr.channel_mode;