X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fflacdec.c;h=95cf2bccb45ee9efa122e13520cb54f0ed5da3b9;hb=29ae0565d98bb41e54fc74f74c330d3214825f47;hp=7ebf01595b5fbde69beceb96af87ca872364f715;hpb=ce7e82144f5cd063de0af04bb90996753bdb74e1;p=ffmpeg diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 7ebf01595b5..95cf2bccb45 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -2,30 +2,28 @@ * FLAC (Free Lossless Audio Codec) decoder * Copyright (c) 2003 Alex Beregszaszi * - * This file is part of FFmpeg. + * This file is part of Libav. * - * FFmpeg is free software; you can redistribute it and/or + * Libav is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * FFmpeg is distributed in the hope that it will be useful, + * Libav is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /** - * @file flacdec.c + * @file * FLAC (Free Lossless Audio Codec) decoder * @author Alex Beregszaszi - * - * For more information on the FLAC format, visit: - * http://flac.sourceforge.net/ + * @see http://flac.sourceforge.net/ * * This decoder can be used in 1 of 2 ways: Either raw FLAC data can be fed * through, starting from the initial 'fLaC' signature; or by passing the @@ -35,92 +33,95 @@ #include -#define ALT_BITSTREAM_READER #include "libavutil/crc.h" #include "avcodec.h" -#include "bitstream.h" +#include "internal.h" +#include "get_bits.h" +#include "bytestream.h" #include "golomb.h" #include "flac.h" +#include "flacdata.h" #undef NDEBUG #include -#define MAX_CHANNELS 8 -#define MAX_BLOCKSIZE 65535 - -enum decorrelation_type { - INDEPENDENT, - LEFT_SIDE, - RIGHT_SIDE, - MID_SIDE, -}; - typedef struct FLACContext { FLACSTREAMINFO - AVCodecContext *avctx; - GetBitContext gb; + AVCodecContext *avctx; ///< parent AVCodecContext + GetBitContext gb; ///< GetBitContext initialized to start at the current frame - int blocksize/*, last_blocksize*/; - int curr_bps; - enum decorrelation_type decorrelation; + int blocksize; ///< number of samples in the current frame + int curr_bps; ///< bps for current subframe, adjusted for channel correlation and wasted bits + int sample_shift; ///< shift required to make output samples 16-bit or 32-bit + int is32; ///< flag to indicate if output should be 32-bit instead of 16-bit + int ch_mode; ///< channel decorrelation type in the current frame + int got_streaminfo; ///< indicates if the STREAMINFO has been read - int32_t *decoded[MAX_CHANNELS]; - uint8_t *bitstream; - unsigned int bitstream_size; - unsigned int bitstream_index; - unsigned int allocated_bitstream_size; + int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples } FLACContext; -static const int sample_rate_table[] = -{ 0, - 88200, 176400, 192000, - 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, - 0, 0, 0, 0 }; - -static const int sample_size_table[] = -{ 0, 8, 12, 0, 16, 20, 24, 0 }; - -static const int blocksize_table[] = { - 0, 192, 576<<0, 576<<1, 576<<2, 576<<3, 0, 0, -256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7 -}; +static void allocate_buffers(FLACContext *s); -static int64_t get_utf8(GetBitContext *gb) +int avpriv_flac_is_extradata_valid(AVCodecContext *avctx, + enum FLACExtradataFormat *format, + uint8_t **streaminfo_start) { - int64_t val; - GET_UTF8(val, get_bits(gb, 8), return -1;) - return val; + if (!avctx->extradata || avctx->extradata_size < FLAC_STREAMINFO_SIZE) { + av_log(avctx, AV_LOG_ERROR, "extradata NULL or too small.\n"); + return 0; + } + if (AV_RL32(avctx->extradata) != MKTAG('f','L','a','C')) { + /* extradata contains STREAMINFO only */ + if (avctx->extradata_size != FLAC_STREAMINFO_SIZE) { + av_log(avctx, AV_LOG_WARNING, "extradata contains %d bytes too many.\n", + FLAC_STREAMINFO_SIZE-avctx->extradata_size); + } + *format = FLAC_EXTRADATA_FORMAT_STREAMINFO; + *streaminfo_start = avctx->extradata; + } else { + if (avctx->extradata_size < 8+FLAC_STREAMINFO_SIZE) { + av_log(avctx, AV_LOG_ERROR, "extradata too small.\n"); + return 0; + } + *format = FLAC_EXTRADATA_FORMAT_FULL_HEADER; + *streaminfo_start = &avctx->extradata[8]; + } + return 1; } -static void allocate_buffers(FLACContext *s); -static int metadata_parse(FLACContext *s); - static av_cold int flac_decode_init(AVCodecContext *avctx) { + enum FLACExtradataFormat format; + uint8_t *streaminfo; FLACContext *s = avctx->priv_data; s->avctx = avctx; - if (avctx->extradata_size > 4) { - /* initialize based on the demuxer-supplied streamdata header */ - if (avctx->extradata_size == FLAC_STREAMINFO_SIZE) { - ff_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, - avctx->extradata); - allocate_buffers(s); - } else { - init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size*8); - metadata_parse(s); - } - } + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + /* for now, the raw FLAC header is allowed to be passed to the decoder as + frame data instead of extradata. */ + if (!avctx->extradata) + return 0; + + if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo)) + return -1; + + /* initialize based on the demuxer-supplied streamdata header */ + avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo); + if (s->bps > 16) + avctx->sample_fmt = AV_SAMPLE_FMT_S32; + else + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + allocate_buffers(s); + s->got_streaminfo = 1; - avctx->sample_fmt = SAMPLE_FMT_S16; return 0; } static void dump_headers(AVCodecContext *avctx, FLACStreaminfo *s) { - av_log(avctx, AV_LOG_DEBUG, " Blocksize: %d .. %d\n", s->min_blocksize, - s->max_blocksize); + av_log(avctx, AV_LOG_DEBUG, " Max Blocksize: %d\n", s->max_blocksize); av_log(avctx, AV_LOG_DEBUG, " Max Framesize: %d\n", s->max_framesize); av_log(avctx, AV_LOG_DEBUG, " Samplerate: %d\n", s->samplerate); av_log(avctx, AV_LOG_DEBUG, " Channels: %d\n", s->channels); @@ -133,31 +134,25 @@ static void allocate_buffers(FLACContext *s) assert(s->max_blocksize); - if (s->max_framesize == 0 && s->max_blocksize) { - // FIXME header overhead - s->max_framesize= (s->channels * s->bps * s->max_blocksize + 7)/ 8; - } - for (i = 0; i < s->channels; i++) { s->decoded[i] = av_realloc(s->decoded[i], sizeof(int32_t)*s->max_blocksize); } - - if (s->allocated_bitstream_size < s->max_framesize) - s->bitstream= av_fast_realloc(s->bitstream, - &s->allocated_bitstream_size, - s->max_framesize); } -void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, +void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, const uint8_t *buffer) { GetBitContext gb; init_get_bits(&gb, buffer, FLAC_STREAMINFO_SIZE*8); - /* mandatory streaminfo */ - s->min_blocksize = get_bits(&gb, 16); + skip_bits(&gb, 16); /* skip min blocksize */ s->max_blocksize = get_bits(&gb, 16); + if (s->max_blocksize < FLAC_MIN_BLOCKSIZE) { + av_log(avctx, AV_LOG_WARNING, "invalid max blocksize: %d\n", + s->max_blocksize); + s->max_blocksize = 16; + } skip_bits(&gb, 24); /* skip min frame size */ s->max_framesize = get_bits_long(&gb, 24); @@ -168,59 +163,81 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, avctx->channels = s->channels; avctx->sample_rate = s->samplerate; + avctx->bits_per_raw_sample = s->bps; - skip_bits(&gb, 36); /* total num of samples */ + s->samples = get_bits_long(&gb, 32) << 4; + s->samples |= get_bits(&gb, 4); - skip_bits(&gb, 64); /* md5 sum */ - skip_bits(&gb, 64); /* md5 sum */ + skip_bits_long(&gb, 64); /* md5 sum */ + skip_bits_long(&gb, 64); /* md5 sum */ dump_headers(avctx, s); } +void avpriv_flac_parse_block_header(const uint8_t *block_header, + int *last, int *type, int *size) +{ + int tmp = bytestream_get_byte(&block_header); + if (last) + *last = tmp & 0x80; + if (type) + *type = tmp & 0x7F; + if (size) + *size = bytestream_get_be24(&block_header); +} + /** - * Parse a list of metadata blocks. This list of blocks must begin with - * the fLaC marker. - * @param s the flac decoding context containing the gb bit reader used to - * parse metadata - * @return 1 if some metadata was read, 0 if no fLaC marker was found + * Parse the STREAMINFO from an inline header. + * @param s the flac decoding context + * @param buf input buffer, starting with the "fLaC" marker + * @param buf_size buffer size + * @return non-zero if metadata is invalid */ -static int metadata_parse(FLACContext *s) +static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) { - int i, metadata_last, metadata_type, metadata_size, streaminfo_updated=0; - int initial_pos= get_bits_count(&s->gb); - - if (show_bits_long(&s->gb, 32) == MKBETAG('f','L','a','C')) { - skip_bits(&s->gb, 32); + int metadata_type, metadata_size; - do { - metadata_last = get_bits1(&s->gb); - metadata_type = get_bits(&s->gb, 7); - metadata_size = get_bits_long(&s->gb, 24); + if (buf_size < FLAC_STREAMINFO_SIZE+8) { + /* need more data */ + return 0; + } + avpriv_flac_parse_block_header(&buf[4], NULL, &metadata_type, &metadata_size); + if (metadata_type != FLAC_METADATA_TYPE_STREAMINFO || + metadata_size != FLAC_STREAMINFO_SIZE) { + return AVERROR_INVALIDDATA; + } + avpriv_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]); + allocate_buffers(s); + s->got_streaminfo = 1; - if (get_bits_count(&s->gb) + 8*metadata_size > s->gb.size_in_bits) { - skip_bits_long(&s->gb, initial_pos - get_bits_count(&s->gb)); - break; - } + return 0; +} - if (metadata_size) { - switch (metadata_type) { - case FLAC_METADATA_TYPE_STREAMINFO: - ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, - s->gb.buffer+get_bits_count(&s->gb)/8); - streaminfo_updated = 1; - - default: - for (i = 0; i < metadata_size; i++) - skip_bits(&s->gb, 8); - } - } - } while (!metadata_last); +/** + * Determine the size of an inline header. + * @param buf input buffer, starting with the "fLaC" marker + * @param buf_size buffer size + * @return number of bytes in the header, or 0 if more data is needed + */ +static int get_metadata_size(const uint8_t *buf, int buf_size) +{ + int metadata_last, metadata_size; + const uint8_t *buf_end = buf + buf_size; + + buf += 4; + do { + if (buf_end - buf < 4) + return 0; + avpriv_flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size); + buf += 4; + if (buf_end - buf < metadata_size) { + /* need more data in order to read the complete header */ + return 0; + } + buf += metadata_size; + } while (!metadata_last); - if (streaminfo_updated) - allocate_buffers(s); - return 1; - } - return 0; + return buf_size - (buf_end - buf); } static int decode_residuals(FLACContext *s, int channel, int pred_order) @@ -251,7 +268,7 @@ static int decode_residuals(FLACContext *s, int channel, int pred_order) if (tmp == (method_type == 0 ? 15 : 31)) { tmp = get_bits(&s->gb, 5); for (; i < samples; i++, sample++) - s->decoded[channel][sample] = get_sbits(&s->gb, tmp); + s->decoded[channel][sample] = get_sbits_long(&s->gb, tmp); } else { for (; i < samples; i++, sample++) { s->decoded[channel][sample] = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0); @@ -267,11 +284,11 @@ static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order) { const int blocksize = s->blocksize; int32_t *decoded = s->decoded[channel]; - int a, b, c, d, i; + int av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d), i; /* warm up samples */ for (i = 0; i < pred_order; i++) { - decoded[i] = get_sbits(&s->gb, s->curr_bps); + decoded[i] = get_sbits_long(&s->gb, s->curr_bps); } if (decode_residuals(s, channel, pred_order) < 0) @@ -317,12 +334,12 @@ static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order) { int i, j; int coeff_prec, qlevel; - int coeffs[pred_order]; + int coeffs[32]; int32_t *decoded = s->decoded[channel]; /* warm up samples */ for (i = 0; i < pred_order; i++) { - decoded[i] = get_sbits(&s->gb, s->curr_bps); + decoded[i] = get_sbits_long(&s->gb, s->curr_bps); } coeff_prec = get_bits(&s->gb, 4) + 1; @@ -387,10 +404,10 @@ static inline int decode_subframe(FLACContext *s, int channel) s->curr_bps = s->bps; if (channel == 0) { - if (s->decorrelation == RIGHT_SIDE) + if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE) s->curr_bps++; } else { - if (s->decorrelation == LEFT_SIDE || s->decorrelation == MID_SIDE) + if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_MID_SIDE) s->curr_bps++; } @@ -406,15 +423,19 @@ static inline int decode_subframe(FLACContext *s, int channel) wasted++; s->curr_bps -= wasted; } + if (s->curr_bps > 32) { + av_log_missing_feature(s->avctx, "decorrelated bit depth > 32", 0); + return -1; + } //FIXME use av_log2 for types if (type == 0) { - tmp = get_sbits(&s->gb, s->curr_bps); + tmp = get_sbits_long(&s->gb, s->curr_bps); for (i = 0; i < s->blocksize; i++) s->decoded[channel][i] = tmp; } else if (type == 1) { for (i = 0; i < s->blocksize; i++) - s->decoded[channel][i] = get_sbits(&s->gb, s->curr_bps); + s->decoded[channel][i] = get_sbits_long(&s->gb, s->curr_bps); } else if ((type >= 8) && (type <= 12)) { if (decode_subframe_fixed(s, channel, type & ~0x8) < 0) return -1; @@ -435,93 +456,75 @@ static inline int decode_subframe(FLACContext *s, int channel) return 0; } -static int decode_frame(FLACContext *s, int alloc_data_size) +static int decode_frame(FLACContext *s) { - int blocksize_code, sample_rate_code, sample_size_code, assignment, i, crc8; - int decorrelation, bps, blocksize, samplerate; - - blocksize_code = get_bits(&s->gb, 4); - - sample_rate_code = get_bits(&s->gb, 4); + int i; + GetBitContext *gb = &s->gb; + FLACFrameInfo fi; - assignment = get_bits(&s->gb, 4); /* channel assignment */ - if (assignment < 8 && s->channels == assignment+1) - decorrelation = INDEPENDENT; - else if (assignment >=8 && assignment < 11 && s->channels == 2) - decorrelation = LEFT_SIDE + assignment - 8; - else { - av_log(s->avctx, AV_LOG_ERROR, "unsupported channel assignment %d (channels=%d)\n", - assignment, s->channels); + if (ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) { + av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n"); return -1; } - sample_size_code = get_bits(&s->gb, 3); - if (sample_size_code == 0) - bps= s->bps; - else if ((sample_size_code != 3) && (sample_size_code != 7)) - bps = sample_size_table[sample_size_code]; - else { - av_log(s->avctx, AV_LOG_ERROR, "invalid sample size code (%d)\n", - sample_size_code); + if (s->channels && fi.channels != s->channels) { + av_log(s->avctx, AV_LOG_ERROR, "switching channel layout mid-stream " + "is not supported\n"); return -1; } + s->channels = s->avctx->channels = fi.channels; + s->ch_mode = fi.ch_mode; - if (get_bits1(&s->gb)) { - av_log(s->avctx, AV_LOG_ERROR, "broken stream, invalid padding\n"); + if (!s->bps && !fi.bps) { + av_log(s->avctx, AV_LOG_ERROR, "bps not found in STREAMINFO or frame header\n"); return -1; } - - if (get_utf8(&s->gb) < 0) { - av_log(s->avctx, AV_LOG_ERROR, "utf8 fscked\n"); + if (!fi.bps) { + fi.bps = s->bps; + } else if (s->bps && fi.bps != s->bps) { + av_log(s->avctx, AV_LOG_ERROR, "switching bps mid-stream is not " + "supported\n"); return -1; } + s->bps = s->avctx->bits_per_raw_sample = fi.bps; - if (blocksize_code == 0) - blocksize = s->min_blocksize; - else if (blocksize_code == 6) - blocksize = get_bits(&s->gb, 8)+1; - else if (blocksize_code == 7) - blocksize = get_bits(&s->gb, 16)+1; - else - blocksize = blocksize_table[blocksize_code]; + if (s->bps > 16) { + s->avctx->sample_fmt = AV_SAMPLE_FMT_S32; + s->sample_shift = 32 - s->bps; + s->is32 = 1; + } else { + s->avctx->sample_fmt = AV_SAMPLE_FMT_S16; + s->sample_shift = 16 - s->bps; + s->is32 = 0; + } - if (blocksize > s->max_blocksize) { - av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", blocksize, + if (!s->max_blocksize) + s->max_blocksize = FLAC_MAX_BLOCKSIZE; + if (fi.blocksize > s->max_blocksize) { + av_log(s->avctx, AV_LOG_ERROR, "blocksize %d > %d\n", fi.blocksize, s->max_blocksize); return -1; } + s->blocksize = fi.blocksize; - if (blocksize * s->channels * sizeof(int16_t) > alloc_data_size) - return -1; - - if (sample_rate_code == 0) - samplerate= s->samplerate; - else if (sample_rate_code < 12) - samplerate = sample_rate_table[sample_rate_code]; - else if (sample_rate_code == 12) - samplerate = get_bits(&s->gb, 8) * 1000; - else if (sample_rate_code == 13) - samplerate = get_bits(&s->gb, 16); - else if (sample_rate_code == 14) - samplerate = get_bits(&s->gb, 16) * 10; - else { - av_log(s->avctx, AV_LOG_ERROR, "illegal sample rate code %d\n", - sample_rate_code); + if (!s->samplerate && !fi.samplerate) { + av_log(s->avctx, AV_LOG_ERROR, "sample rate not found in STREAMINFO" + " or frame header\n"); return -1; } - - skip_bits(&s->gb, 8); - crc8 = av_crc(av_crc_get_table(AV_CRC_8_ATM), 0, - s->gb.buffer, get_bits_count(&s->gb)/8); - if (crc8) { - av_log(s->avctx, AV_LOG_ERROR, "header crc mismatch crc=%2X\n", crc8); - return -1; + if (fi.samplerate == 0) { + fi.samplerate = s->samplerate; + } else if (s->samplerate && fi.samplerate != s->samplerate) { + av_log(s->avctx, AV_LOG_WARNING, "sample rate changed from %d to %d\n", + s->samplerate, fi.samplerate); } + s->samplerate = s->avctx->sample_rate = fi.samplerate; - s->blocksize = blocksize; - s->samplerate = samplerate; - s->bps = bps; - s->decorrelation= decorrelation; + if (!s->got_streaminfo) { + allocate_buffers(s); + s->got_streaminfo = 1; + dump_headers(s->avctx, (FLACStreaminfo *)s); + } // dump_headers(s->avctx, (FLACStreaminfo *)s); @@ -531,119 +534,112 @@ static int decode_frame(FLACContext *s, int alloc_data_size) return -1; } - align_get_bits(&s->gb); + align_get_bits(gb); /* frame footer */ - skip_bits(&s->gb, 16); /* data crc */ + skip_bits(gb, 16); /* data crc */ return 0; } static int flac_decode_frame(AVCodecContext *avctx, void *data, int *data_size, - const uint8_t *buf, int buf_size) + AVPacket *avpkt) { + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; FLACContext *s = avctx->priv_data; - int tmp = 0, i, j = 0, input_buf_size = 0; - int16_t *samples = data; + int i, j = 0, bytes_read = 0; + int16_t *samples_16 = data; + int32_t *samples_32 = data; int alloc_data_size= *data_size; + int output_size; *data_size=0; if (s->max_framesize == 0) { - s->max_framesize= FFMAX(4, buf_size); // should hopefully be enough for the first header - s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize); + s->max_framesize = + ff_flac_get_max_frame_size(s->max_blocksize ? s->max_blocksize : FLAC_MAX_BLOCKSIZE, + FLAC_MAX_CHANNELS, 32); } - if (1 && s->max_framesize) { //FIXME truncated - if (s->bitstream_size < 4 || AV_RL32(s->bitstream) != MKTAG('f','L','a','C')) - buf_size= FFMIN(buf_size, s->max_framesize - FFMIN(s->bitstream_size, s->max_framesize)); - input_buf_size= buf_size; + /* check that there is at least the smallest decodable amount of data. + this amount corresponds to the smallest valid FLAC frame possible. + FF F8 69 02 00 00 9A 00 00 34 46 */ + if (buf_size < FLAC_MIN_FRAME_SIZE) + return buf_size; - if (s->bitstream_size + buf_size < buf_size || s->bitstream_index + s->bitstream_size + buf_size < s->bitstream_index) + /* check for inline header */ + if (AV_RB32(buf) == MKBETAG('f','L','a','C')) { + if (!s->got_streaminfo && parse_streaminfo(s, buf, buf_size)) { + av_log(s->avctx, AV_LOG_ERROR, "invalid header\n"); return -1; - - if (s->allocated_bitstream_size < s->bitstream_size + buf_size) - s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->bitstream_size + buf_size); - - if (s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size) { - memmove(s->bitstream, &s->bitstream[s->bitstream_index], - s->bitstream_size); - s->bitstream_index=0; - } - memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], - buf, buf_size); - buf= &s->bitstream[s->bitstream_index]; - buf_size += s->bitstream_size; - s->bitstream_size= buf_size; - - if (buf_size < s->max_framesize && input_buf_size) { - return input_buf_size; } + return get_metadata_size(buf, buf_size); } + /* decode frame */ init_get_bits(&s->gb, buf, buf_size*8); - - if (metadata_parse(s)) - goto end; - - tmp = show_bits(&s->gb, 16); - if ((tmp & 0xFFFE) != 0xFFF8) { - av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); - while (get_bits_count(&s->gb)/8+2 < buf_size && (show_bits(&s->gb, 16) & 0xFFFE) != 0xFFF8) - skip_bits(&s->gb, 8); - goto end; // we may not have enough bits left to decode a frame, so try next time - } - skip_bits(&s->gb, 16); - if (decode_frame(s, alloc_data_size) < 0) { + if (decode_frame(s) < 0) { av_log(s->avctx, AV_LOG_ERROR, "decode_frame() failed\n"); - s->bitstream_size=0; - s->bitstream_index=0; return -1; } + bytes_read = (get_bits_count(&s->gb)+7)/8; + + /* check if allocated data size is large enough for output */ + output_size = s->blocksize * s->channels * + av_get_bytes_per_sample(avctx->sample_fmt); + if (output_size > alloc_data_size) { + av_log(s->avctx, AV_LOG_ERROR, "output data size is larger than " + "allocated data size\n"); + return -1; + } + *data_size = output_size; #define DECORRELATE(left, right)\ assert(s->channels == 2);\ for (i = 0; i < s->blocksize; i++) {\ int a= s->decoded[0][i];\ int b= s->decoded[1][i];\ - *samples++ = ((left) << (24 - s->bps)) >> 8;\ - *samples++ = ((right) << (24 - s->bps)) >> 8;\ + if (s->is32) {\ + *samples_32++ = (left) << s->sample_shift;\ + *samples_32++ = (right) << s->sample_shift;\ + } else {\ + *samples_16++ = (left) << s->sample_shift;\ + *samples_16++ = (right) << s->sample_shift;\ + }\ }\ break; - switch (s->decorrelation) { - case INDEPENDENT: + switch (s->ch_mode) { + case FLAC_CHMODE_INDEPENDENT: for (j = 0; j < s->blocksize; j++) { - for (i = 0; i < s->channels; i++) - *samples++ = (s->decoded[i][j] << (24 - s->bps)) >> 8; + for (i = 0; i < s->channels; i++) { + if (s->is32) + *samples_32++ = s->decoded[i][j] << s->sample_shift; + else + *samples_16++ = s->decoded[i][j] << s->sample_shift; + } } break; - case LEFT_SIDE: + case FLAC_CHMODE_LEFT_SIDE: DECORRELATE(a,a-b) - case RIGHT_SIDE: + case FLAC_CHMODE_RIGHT_SIDE: DECORRELATE(a+b,b) - case MID_SIDE: + case FLAC_CHMODE_MID_SIDE: DECORRELATE( (a-=b>>1) + b, a) } - *data_size = (int8_t *)samples - (int8_t *)data; - -end: - i= (get_bits_count(&s->gb)+7)/8; - if (i > buf_size) { - av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size); - s->bitstream_size=0; - s->bitstream_index=0; + if (bytes_read > buf_size) { + av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); return -1; } + if (bytes_read < buf_size) { + av_log(s->avctx, AV_LOG_DEBUG, "underread: %d orig size: %d\n", + buf_size - bytes_read, buf_size); + } - if (s->bitstream_size) { - s->bitstream_index += i; - s->bitstream_size -= i; - return input_buf_size; - } else - return i; + return bytes_read; } static av_cold int flac_decode_close(AVCodecContext *avctx) @@ -654,29 +650,17 @@ static av_cold int flac_decode_close(AVCodecContext *avctx) for (i = 0; i < s->channels; i++) { av_freep(&s->decoded[i]); } - av_freep(&s->bitstream); return 0; } -static void flac_flush(AVCodecContext *avctx) -{ - FLACContext *s = avctx->priv_data; - - s->bitstream_size= - s->bitstream_index= 0; -} - -AVCodec flac_decoder = { - "flac", - CODEC_TYPE_AUDIO, - CODEC_ID_FLAC, - sizeof(FLACContext), - flac_decode_init, - NULL, - flac_decode_close, - flac_decode_frame, - CODEC_CAP_DELAY, - .flush= flac_flush, +AVCodec ff_flac_decoder = { + .name = "flac", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_FLAC, + .priv_data_size = sizeof(FLACContext), + .init = flac_decode_init, + .close = flac_decode_close, + .decode = flac_decode_frame, .long_name= NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), };