# HG changeset patch # User jbr # Date 1199558395 0 # Node ID 01b1342e717bfbba3c35d15099dfa78f5b1490f0 # Parent 4f8fcb40bf2cd8b5082e454b611450f07532875e move E-AC3 header parsing to ff_ac3_parse_header() diff -r 4f8fcb40bf2c -r 01b1342e717b ac3_parser.c --- a/ac3_parser.c Sat Jan 05 17:04:57 2008 +0000 +++ b/ac3_parser.c Sat Jan 05 18:39:55 2008 +0000 @@ -38,6 +38,7 @@ { GetBitContext gbc; int frame_size_code; + int num_blocks; memset(hdr, 0, sizeof(*hdr)); @@ -47,11 +48,13 @@ 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 @@ 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 @@ 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 -r 4f8fcb40bf2c -r 01b1342e717b ac3dec.c --- a/ac3dec.c Sat Jan 05 17:04:57 2008 +0000 +++ b/ac3dec.c Sat Jan 05 18:39:55 2008 +0000 @@ -338,6 +338,9 @@ 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;