X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fflacdec.c;h=9ca55cc1dedeb7ff2b4b99e3fd8a781928ba9f06;hb=4fbb62a21bd04bf261da2382d5ba6c249c702af8;hp=4563329e5aba1afbddeaf1472c700c45e35ef364;hpb=5756bc7b025d305a2b5461b9865ff69fd913d546;p=ffmpeg diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 4563329e5ab..9ca55cc1ded 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 libavcodec/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,26 +33,16 @@ #include +#include "libavutil/channel_layout.h" #include "libavutil/crc.h" #include "avcodec.h" #include "internal.h" -#include "bitstream.h" +#include "get_bits.h" #include "bytestream.h" #include "golomb.h" #include "flac.h" - -#undef NDEBUG -#include - -#define MAX_CHANNELS 8 -#define MAX_BLOCKSIZE 65535 - -enum decorrelation_type { - INDEPENDENT, - LEFT_SIDE, - RIGHT_SIDE, - MID_SIDE, -}; +#include "flacdata.h" +#include "flacdsp.h" typedef struct FLACContext { FLACSTREAMINFO @@ -63,89 +51,64 @@ typedef struct FLACContext { GetBitContext gb; ///< GetBitContext initialized to start at the current frame 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 - enum decorrelation_type decorrelation; ///< channel decorrelation type in the current frame + 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]; ///< decoded samples - uint8_t *bitstream; - unsigned int bitstream_size; - unsigned int bitstream_index; - unsigned int allocated_bitstream_size; -} 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 -}; + int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples + uint8_t *decoded_buffer; + unsigned int decoded_buffer_size; -static int64_t get_utf8(GetBitContext *gb) -{ - int64_t val; - GET_UTF8(val, get_bits(gb, 8), return -1;) - return val; -} + FLACDSPContext dsp; +} FLACContext; -static void allocate_buffers(FLACContext *s); +static int allocate_buffers(FLACContext *s); -int ff_flac_is_extradata_valid(AVCodecContext *avctx, - enum FLACExtradataFormat *format, - uint8_t **streaminfo_start) +static void flac_set_bps(FLACContext *s) { - 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; + enum AVSampleFormat req = s->avctx->request_sample_fmt; + int need32 = s->bps > 16; + int want32 = av_get_bytes_per_sample(req) > 2; + int planar = av_sample_fmt_is_planar(req); + + if (need32 || want32) { + if (planar) + s->avctx->sample_fmt = AV_SAMPLE_FMT_S32P; + else + s->avctx->sample_fmt = AV_SAMPLE_FMT_S32; + s->sample_shift = 32 - s->bps; } 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]; + if (planar) + s->avctx->sample_fmt = AV_SAMPLE_FMT_S16P; + else + s->avctx->sample_fmt = AV_SAMPLE_FMT_S16; + s->sample_shift = 16 - s->bps; } - return 1; } static av_cold int flac_decode_init(AVCodecContext *avctx) { enum FLACExtradataFormat format; uint8_t *streaminfo; + int ret; FLACContext *s = avctx->priv_data; s->avctx = avctx; - avctx->sample_fmt = 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 (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo)) - return -1; + if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo)) + return AVERROR_INVALIDDATA; /* initialize based on the demuxer-supplied streamdata header */ - ff_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo); - allocate_buffers(s); + avpriv_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo); + ret = allocate_buffers(s); + if (ret < 0) + return ret; + flac_set_bps(s); + ff_flacdsp_init(&s->dsp, avctx->sample_fmt, s->bps); s->got_streaminfo = 1; return 0; @@ -160,64 +123,22 @@ static void dump_headers(AVCodecContext *avctx, FLACStreaminfo *s) av_log(avctx, AV_LOG_DEBUG, " Bits: %d\n", s->bps); } -static void allocate_buffers(FLACContext *s) +static int allocate_buffers(FLACContext *s) { - int i; + int buf_size; - assert(s->max_blocksize); + buf_size = av_samples_get_buffer_size(NULL, s->channels, s->max_blocksize, + AV_SAMPLE_FMT_S32P, 0); + if (buf_size < 0) + return buf_size; - if (s->max_framesize == 0 && s->max_blocksize) { - // FIXME header overhead - s->max_framesize= (s->channels * s->bps * s->max_blocksize + 7)/ 8; - } + av_fast_malloc(&s->decoded_buffer, &s->decoded_buffer_size, buf_size); + if (!s->decoded_buffer) + return AVERROR(ENOMEM); - 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, - const uint8_t *buffer) -{ - GetBitContext gb; - init_get_bits(&gb, buffer, FLAC_STREAMINFO_SIZE*8); - - skip_bits(&gb, 16); /* skip min blocksize */ - s->max_blocksize = get_bits(&gb, 16); - if (s->max_blocksize < 16) { - 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); - - s->samplerate = get_bits_long(&gb, 20); - s->channels = get_bits(&gb, 3) + 1; - s->bps = get_bits(&gb, 5) + 1; - - avctx->channels = s->channels; - avctx->sample_rate = s->samplerate; - avctx->bits_per_raw_sample = s->bps; - if (s->bps > 16) - avctx->sample_fmt = SAMPLE_FMT_S32; - else - avctx->sample_fmt = SAMPLE_FMT_S16; - - s->samples = get_bits_long(&gb, 32) << 4; - s->samples |= get_bits(&gb, 4); - - skip_bits_long(&gb, 64); /* md5 sum */ - skip_bits_long(&gb, 64); /* md5 sum */ - - dump_headers(avctx, s); + return av_samples_fill_arrays((uint8_t **)s->decoded, NULL, + s->decoded_buffer, s->channels, + s->max_blocksize, AV_SAMPLE_FMT_S32P, 0); } /** @@ -229,21 +150,23 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, */ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) { - int metadata_type, metadata_size; + int metadata_type, metadata_size, ret; if (buf_size < FLAC_STREAMINFO_SIZE+8) { /* need more data */ return 0; } - buf += 4; - metadata_type = bytestream_get_byte(&buf) & 0x7F; - metadata_size = bytestream_get_be24(&buf); + 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; } - ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, buf); - allocate_buffers(s); + avpriv_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]); + ret = allocate_buffers(s); + if (ret < 0) + return ret; + flac_set_bps(s); + ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); s->got_streaminfo = 1; return 0; @@ -262,9 +185,11 @@ static int get_metadata_size(const uint8_t *buf, int buf_size) buf += 4; do { - metadata_last = bytestream_get_byte(&buf) & 0x80; - metadata_size = bytestream_get_be24(&buf); - if (buf + metadata_size > buf_end) { + if (buf_end - buf < 4) + return 0; + 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; } @@ -274,16 +199,17 @@ static int get_metadata_size(const uint8_t *buf, int buf_size) return buf_size - (buf_end - buf); } -static int decode_residuals(FLACContext *s, int channel, int pred_order) +static int decode_residuals(FLACContext *s, int32_t *decoded, int pred_order) { int i, tmp, partition, method_type, rice_order; - int sample = 0, samples; + int rice_bits, rice_esc; + int samples; method_type = get_bits(&s->gb, 2); if (method_type > 1) { av_log(s->avctx, AV_LOG_ERROR, "illegal residual coding method %d\n", method_type); - return -1; + return AVERROR_INVALIDDATA; } rice_order = get_bits(&s->gb, 4); @@ -292,20 +218,23 @@ static int decode_residuals(FLACContext *s, int channel, int pred_order) if (pred_order > samples) { av_log(s->avctx, AV_LOG_ERROR, "invalid predictor order: %i > %i\n", pred_order, samples); - return -1; + return AVERROR_INVALIDDATA; } - sample= + rice_bits = 4 + method_type; + rice_esc = (1 << rice_bits) - 1; + + decoded += pred_order; i= pred_order; for (partition = 0; partition < (1 << rice_order); partition++) { - tmp = get_bits(&s->gb, method_type == 0 ? 4 : 5); - if (tmp == (method_type == 0 ? 15 : 31)) { + tmp = get_bits(&s->gb, rice_bits); + if (tmp == rice_esc) { tmp = get_bits(&s->gb, 5); - for (; i < samples; i++, sample++) - s->decoded[channel][sample] = get_sbits_long(&s->gb, tmp); + for (; i < samples; i++) + *decoded++ = 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); + for (; i < samples; i++) { + *decoded++ = get_sr_golomb_flac(&s->gb, tmp, INT_MAX, 0); } } i= 0; @@ -314,19 +243,19 @@ static int decode_residuals(FLACContext *s, int channel, int pred_order) return 0; } -static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order) +static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, + int pred_order, int bps) { const int blocksize = s->blocksize; - int32_t *decoded = s->decoded[channel]; - int av_uninit(a), av_uninit(b), av_uninit(c), av_uninit(d), i; + int a, b, c, d, i, ret; /* warm up samples */ for (i = 0; i < pred_order; i++) { - decoded[i] = get_sbits_long(&s->gb, s->curr_bps); + decoded[i] = get_sbits_long(&s->gb, bps); } - if (decode_residuals(s, channel, pred_order) < 0) - return -1; + if ((ret = decode_residuals(s, decoded, pred_order)) < 0) + return ret; if (pred_order > 0) a = decoded[pred_order-1]; @@ -358,415 +287,287 @@ static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order) break; default: av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order); - return -1; + return AVERROR_INVALIDDATA; } return 0; } -static int decode_subframe_lpc(FLACContext *s, int channel, int pred_order) +static int decode_subframe_lpc(FLACContext *s, int32_t *decoded, int pred_order, + int bps) { - int i, j; + int i, ret; int coeff_prec, qlevel; - int coeffs[pred_order]; - int32_t *decoded = s->decoded[channel]; + int coeffs[32]; /* warm up samples */ for (i = 0; i < pred_order; i++) { - decoded[i] = get_sbits_long(&s->gb, s->curr_bps); + decoded[i] = get_sbits_long(&s->gb, bps); } coeff_prec = get_bits(&s->gb, 4) + 1; if (coeff_prec == 16) { av_log(s->avctx, AV_LOG_ERROR, "invalid coeff precision\n"); - return -1; + return AVERROR_INVALIDDATA; } qlevel = get_sbits(&s->gb, 5); if (qlevel < 0) { av_log(s->avctx, AV_LOG_ERROR, "qlevel %d not supported, maybe buggy stream\n", qlevel); - return -1; + return AVERROR_INVALIDDATA; } for (i = 0; i < pred_order; i++) { - coeffs[i] = get_sbits(&s->gb, coeff_prec); + coeffs[pred_order - i - 1] = get_sbits(&s->gb, coeff_prec); } - if (decode_residuals(s, channel, pred_order) < 0) - return -1; + if ((ret = decode_residuals(s, decoded, pred_order)) < 0) + return ret; - if (s->bps > 16) { - int64_t sum; - for (i = pred_order; i < s->blocksize; i++) { - sum = 0; - for (j = 0; j < pred_order; j++) - sum += (int64_t)coeffs[j] * decoded[i-j-1]; - decoded[i] += sum >> qlevel; - } - } else { - for (i = pred_order; i < s->blocksize-1; i += 2) { - int c; - int d = decoded[i-pred_order]; - int s0 = 0, s1 = 0; - for (j = pred_order-1; j > 0; j--) { - c = coeffs[j]; - s0 += c*d; - d = decoded[i-j]; - s1 += c*d; - } - c = coeffs[0]; - s0 += c*d; - d = decoded[i] += s0 >> qlevel; - s1 += c*d; - decoded[i+1] += s1 >> qlevel; - } - if (i < s->blocksize) { - int sum = 0; - for (j = 0; j < pred_order; j++) - sum += coeffs[j] * decoded[i-j-1]; - decoded[i] += sum >> qlevel; - } - } + s->dsp.lpc(decoded, coeffs, pred_order, qlevel, s->blocksize); return 0; } static inline int decode_subframe(FLACContext *s, int channel) { + int32_t *decoded = s->decoded[channel]; int type, wasted = 0; - int i, tmp; + int bps = s->bps; + int i, tmp, ret; - s->curr_bps = s->bps; if (channel == 0) { - if (s->decorrelation == RIGHT_SIDE) - s->curr_bps++; + if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE) + bps++; } else { - if (s->decorrelation == LEFT_SIDE || s->decorrelation == MID_SIDE) - s->curr_bps++; + if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_MID_SIDE) + bps++; } if (get_bits1(&s->gb)) { av_log(s->avctx, AV_LOG_ERROR, "invalid subframe padding\n"); - return -1; + return AVERROR_INVALIDDATA; } type = get_bits(&s->gb, 6); if (get_bits1(&s->gb)) { + int left = get_bits_left(&s->gb); wasted = 1; + if ( left < 0 || + (left < bps && !show_bits_long(&s->gb, left)) || + !show_bits_long(&s->gb, bps)) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid number of wasted bits > available bits (%d) - left=%d\n", + bps, left); + return AVERROR_INVALIDDATA; + } while (!get_bits1(&s->gb)) wasted++; - s->curr_bps -= wasted; + bps -= wasted; } - if (s->curr_bps > 32) { - ff_log_missing_feature(s->avctx, "decorrelated bit depth > 32", 0); - return -1; + if (bps > 32) { + avpriv_report_missing_feature(s->avctx, "Decorrelated bit depth > 32"); + return AVERROR_PATCHWELCOME; } //FIXME use av_log2 for types if (type == 0) { - tmp = get_sbits_long(&s->gb, s->curr_bps); + tmp = get_sbits_long(&s->gb, bps); for (i = 0; i < s->blocksize; i++) - s->decoded[channel][i] = tmp; + decoded[i] = tmp; } else if (type == 1) { for (i = 0; i < s->blocksize; i++) - s->decoded[channel][i] = get_sbits_long(&s->gb, s->curr_bps); + decoded[i] = get_sbits_long(&s->gb, bps); } else if ((type >= 8) && (type <= 12)) { - if (decode_subframe_fixed(s, channel, type & ~0x8) < 0) - return -1; + if ((ret = decode_subframe_fixed(s, decoded, type & ~0x8, bps)) < 0) + return ret; } else if (type >= 32) { - if (decode_subframe_lpc(s, channel, (type & ~0x20)+1) < 0) - return -1; + if ((ret = decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps)) < 0) + return ret; } else { av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n"); - return -1; + return AVERROR_INVALIDDATA; } if (wasted) { int i; for (i = 0; i < s->blocksize; i++) - s->decoded[channel][i] <<= wasted; + decoded[i] <<= wasted; } 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); - - 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); - 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); - return -1; - } - if (bps > 16) { - s->avctx->sample_fmt = SAMPLE_FMT_S32; - s->sample_shift = 32 - bps; - s->is32 = 1; - } else { - s->avctx->sample_fmt = SAMPLE_FMT_S16; - s->sample_shift = 16 - bps; - s->is32 = 0; + int i, ret; + GetBitContext *gb = &s->gb; + FLACFrameInfo fi; + + if ((ret = ff_flac_decode_frame_header(s->avctx, gb, &fi, 0)) < 0) { + av_log(s->avctx, AV_LOG_ERROR, "invalid frame header\n"); + return ret; } - s->bps = s->avctx->bits_per_raw_sample = bps; - if (get_bits1(&s->gb)) { - av_log(s->avctx, AV_LOG_ERROR, "broken stream, invalid padding\n"); - return -1; + if (s->channels && fi.channels != s->channels && s->got_streaminfo) { + s->channels = s->avctx->channels = fi.channels; + ff_flac_set_channel_layout(s->avctx); + ret = allocate_buffers(s); + if (ret < 0) + return ret; } + s->channels = s->avctx->channels = fi.channels; + if (!s->avctx->channel_layout) + ff_flac_set_channel_layout(s->avctx); + s->ch_mode = fi.ch_mode; - if (get_utf8(&s->gb) < 0) { - av_log(s->avctx, AV_LOG_ERROR, "utf8 fscked\n"); - return -1; + if (!s->bps && !fi.bps) { + av_log(s->avctx, AV_LOG_ERROR, "bps not found in STREAMINFO or frame header\n"); + return AVERROR_INVALIDDATA; + } + 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 AVERROR_INVALIDDATA; } - if (blocksize_code == 0) { - av_log(s->avctx, AV_LOG_ERROR, "reserved blocksize code: 0\n"); - return -1; - } 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) { + s->bps = s->avctx->bits_per_raw_sample = fi.bps; + flac_set_bps(s); + } - 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; + return AVERROR_INVALIDDATA; } + s->blocksize = fi.blocksize; - if (blocksize * s->channels * (s->is32 ? 4 : 2) > 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); - return -1; + if (!s->samplerate && !fi.samplerate) { + av_log(s->avctx, AV_LOG_ERROR, "sample rate not found in STREAMINFO" + " or frame header\n"); + return AVERROR_INVALIDDATA; } + if (fi.samplerate == 0) + fi.samplerate = s->samplerate; + s->samplerate = s->avctx->sample_rate = fi.samplerate; - 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 (!s->got_streaminfo) { + ret = allocate_buffers(s); + if (ret < 0) + return ret; + ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); + s->got_streaminfo = 1; + dump_headers(s->avctx, (FLACStreaminfo *)s); } - s->blocksize = blocksize; - s->samplerate = samplerate; - s->bps = bps; - s->decorrelation= decorrelation; - // dump_headers(s->avctx, (FLACStreaminfo *)s); /* subframes */ for (i = 0; i < s->channels; i++) { - if (decode_subframe(s, i) < 0) - return -1; + if ((ret = decode_subframe(s, i)) < 0) + return ret; } - 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) +static int flac_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) { + AVFrame *frame = data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; FLACContext *s = avctx->priv_data; - int i, j = 0, input_buf_size = 0, bytes_read = 0; - int16_t *samples_16 = data; - int32_t *samples_32 = data; - int alloc_data_size= *data_size; + int bytes_read = 0; + int ret; - *data_size=0; + *got_frame_ptr = 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); - } - - 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; - - if (s->bitstream_size + buf_size < buf_size || s->bitstream_index + s->bitstream_size + buf_size < s->bitstream_index) - 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; - } + s->max_framesize = + ff_flac_get_max_frame_size(s->max_blocksize ? s->max_blocksize : FLAC_MAX_BLOCKSIZE, + FLAC_MAX_CHANNELS, 32); } /* check that there is at least the smallest decodable amount of data. - this amount corresponds to the smallest valid FLAC frame possible. */ - if (buf_size < 16) - goto end; + 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; /* check for inline header */ if (AV_RB32(buf) == MKBETAG('f','L','a','C')) { - if (!s->got_streaminfo && parse_streaminfo(s, buf, buf_size)) { + if (!s->got_streaminfo && (ret = parse_streaminfo(s, buf, buf_size))) { av_log(s->avctx, AV_LOG_ERROR, "invalid header\n"); - return -1; + return ret; } - bytes_read = get_metadata_size(buf, buf_size); - goto end; - } - - /* check for frame sync code and resync stream if necessary */ - if ((AV_RB16(buf) & 0xFFFE) != 0xFFF8) { - const uint8_t *buf_end = buf + buf_size; - av_log(s->avctx, AV_LOG_ERROR, "FRAME HEADER not here\n"); - while (buf+2 < buf_end && (AV_RB16(buf) & 0xFFFE) != 0xFFF8) - buf++; - bytes_read = buf_size - (buf_end - buf); - goto end; // we may not have enough bits left to decode a frame, so try next time + return get_metadata_size(buf, buf_size); } /* decode frame */ init_get_bits(&s->gb, buf, buf_size*8); - skip_bits(&s->gb, 16); - if (decode_frame(s, alloc_data_size) < 0) { + if ((ret = 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; + return ret; } - *data_size = s->blocksize * s->channels * (s->is32 ? 4 : 2); bytes_read = (get_bits_count(&s->gb)+7)/8; -#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];\ - 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: - for (j = 0; j < s->blocksize; j++) { - 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: - DECORRELATE(a,a-b) - case RIGHT_SIDE: - DECORRELATE(a+b,b) - case MID_SIDE: - DECORRELATE( (a-=b>>1) + b, a) + /* get output buffer */ + frame->nb_samples = s->blocksize; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; } -end: + s->dsp.decorrelate[s->ch_mode](frame->data, s->decoded, s->channels, + s->blocksize, s->sample_shift); + if (bytes_read > buf_size) { av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", bytes_read - buf_size); - s->bitstream_size=0; - s->bitstream_index=0; - return -1; + return AVERROR_INVALIDDATA; + } + 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 += bytes_read; - s->bitstream_size -= bytes_read; - return input_buf_size; - } else - return bytes_read; + *got_frame_ptr = 1; + + return bytes_read; } static av_cold int flac_decode_close(AVCodecContext *avctx) { FLACContext *s = avctx->priv_data; - int i; - for (i = 0; i < s->channels; i++) { - av_freep(&s->decoded[i]); - } - av_freep(&s->bitstream); + av_freep(&s->decoded_buffer); 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, - .long_name= NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), +AVCodec ff_flac_decoder = { + .name = "flac", + .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_FLAC, + .priv_data_size = sizeof(FLACContext), + .init = flac_decode_init, + .close = flac_decode_close, + .decode = flac_decode_frame, + .capabilities = CODEC_CAP_DR1, + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_S32, + AV_SAMPLE_FMT_S32P, + -1 }, };