]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/flacdec.c
ivi_common: Initialize a variable at declaration in ff_ivi_decode_blocks().
[ffmpeg] / libavcodec / flacdec.c
index edb9e9d70fbba80ed58587a49ccefca7a6c50c89..cd2a69390a0151d4ebd3389495d243d235cddba6 100644 (file)
@@ -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
 
 #include <limits.h>
 
+#include "libavutil/audioconvert.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"
@@ -51,6 +50,7 @@ typedef struct FLACContext {
     FLACSTREAMINFO
 
     AVCodecContext *avctx;                  ///< parent AVCodecContext
+    AVFrame frame;
     GetBitContext gb;                       ///< GetBitContext initialized to start at the current frame
 
     int blocksize;                          ///< number of samples in the current frame
@@ -61,25 +61,20 @@ typedef struct FLACContext {
     int got_streaminfo;                     ///< indicates if the STREAMINFO has been read
 
     int32_t *decoded[FLAC_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_size_table[] =
-{ 0, 8, 12, 0, 16, 20, 24, 0 };
-
-static int64_t get_utf8(GetBitContext *gb)
-{
-    int64_t val;
-    GET_UTF8(val, get_bits(gb, 8), return -1;)
-    return val;
-}
+static const int64_t flac_channel_layouts[6] = {
+    AV_CH_LAYOUT_MONO,
+    AV_CH_LAYOUT_STEREO,
+    AV_CH_LAYOUT_SURROUND,
+    AV_CH_LAYOUT_QUAD,
+    AV_CH_LAYOUT_5POINT0,
+    AV_CH_LAYOUT_5POINT1
+};
 
 static void allocate_buffers(FLACContext *s);
 
-int ff_flac_is_extradata_valid(AVCodecContext *avctx,
+int avpriv_flac_is_extradata_valid(AVCodecContext *avctx,
                                enum FLACExtradataFormat *format,
                                uint8_t **streaminfo_start)
 {
@@ -113,21 +108,31 @@ static av_cold int flac_decode_init(AVCodecContext *avctx)
     FLACContext *s = avctx->priv_data;
     s->avctx = avctx;
 
-    avctx->sample_fmt = SAMPLE_FMT_S16;
+    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 (!ff_flac_is_extradata_valid(avctx, &format, &streaminfo))
+    if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo))
         return -1;
 
     /* initialize based on the demuxer-supplied streamdata header */
-    ff_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, streaminfo);
+    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;
 
+    avcodec_get_frame_defaults(&s->frame);
+    avctx->coded_frame = &s->frame;
+
+    if (avctx->channels <= FF_ARRAY_ELEMS(flac_channel_layouts))
+        avctx->channel_layout = flac_channel_layouts[avctx->channels - 1];
+
     return 0;
 }
 
@@ -146,23 +151,13 @@ static void allocate_buffers(FLACContext *s)
 
     assert(s->max_blocksize);
 
-    if (s->max_framesize == 0 && s->max_blocksize) {
-        s->max_framesize = ff_flac_get_max_frame_size(s->max_blocksize,
-                                                      s->channels, s->bps);
-    }
-
     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;
@@ -186,10 +181,6 @@ 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;
-    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);
@@ -200,7 +191,7 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s,
     dump_headers(avctx, s);
 }
 
-void ff_flac_parse_block_header(const uint8_t *block_header,
+void avpriv_flac_parse_block_header(const uint8_t *block_header,
                                 int *last, int *type, int *size)
 {
     int tmp = bytestream_get_byte(&block_header);
@@ -227,12 +218,12 @@ static int parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size)
         /* need more data */
         return 0;
     }
-    ff_flac_parse_block_header(&buf[4], NULL, &metadata_type, &metadata_size);
+    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;
     }
-    ff_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]);
+    avpriv_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]);
     allocate_buffers(s);
     s->got_streaminfo = 1;
 
@@ -252,9 +243,11 @@ static int get_metadata_size(const uint8_t *buf, int buf_size)
 
     buf += 4;
     do {
-        ff_flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size);
+        if (buf_end - buf < 4)
+            return 0;
+        avpriv_flac_parse_block_header(buf, &metadata_last, NULL, &metadata_size);
         buf += 4;
-        if (buf + metadata_size > buf_end) {
+        if (buf_end - buf < metadata_size) {
             /* need more data in order to read the complete header */
             return 0;
         }
@@ -308,7 +301,7 @@ static int decode_subframe_fixed(FLACContext *s, int channel, int pred_order)
 {
     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;
 
     /* warm up samples */
     for (i = 0; i < pred_order; i++) {
@@ -358,7 +351,7 @@ 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 */
@@ -442,13 +435,22 @@ static inline int decode_subframe(FLACContext *s, int channel)
     type = get_bits(&s->gb, 6);
 
     if (get_bits1(&s->gb)) {
+        int left = get_bits_left(&s->gb);
         wasted = 1;
+        if ( left < 0 ||
+            (left < s->curr_bps && !show_bits_long(&s->gb, left)) ||
+                                   !show_bits_long(&s->gb, s->curr_bps)) {
+            av_log(s->avctx, AV_LOG_ERROR,
+                   "Invalid number of wasted bits > available bits (%d) - left=%d\n",
+                   s->curr_bps, left);
+            return AVERROR_INVALIDDATA;
+        }
         while (!get_bits1(&s->gb))
             wasted++;
         s->curr_bps -= wasted;
     }
     if (s->curr_bps > 32) {
-        ff_log_missing_feature(s->avctx, "decorrelated bit depth > 32", 0);
+        av_log_missing_feature(s->avctx, "decorrelated bit depth > 32", 0);
         return -1;
     }
 
@@ -480,103 +482,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, i, crc8;
-    int ch_mode, bps, blocksize, samplerate;
+    int i;
     GetBitContext *gb = &s->gb;
+    FLACFrameInfo fi;
 
-    blocksize_code = get_bits(gb, 4);
-
-    sample_rate_code = get_bits(gb, 4);
-
-    ch_mode = get_bits(gb, 4); /* channel assignment */
-    if (ch_mode < FLAC_MAX_CHANNELS && s->channels == ch_mode+1) {
-        ch_mode = FLAC_CHMODE_INDEPENDENT;
-    } else if (ch_mode > FLAC_CHMODE_MID_SIDE || s->channels != 2) {
-        av_log(s->avctx, AV_LOG_ERROR, "unsupported channel assignment %d (channels=%d)\n",
-               ch_mode, 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(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;
     }
-    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;
-    }
-    s->bps = s->avctx->bits_per_raw_sample = bps;
+    s->channels = s->avctx->channels = fi.channels;
+    s->ch_mode = fi.ch_mode;
 
-    if (get_bits1(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(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) {
-        av_log(s->avctx, AV_LOG_ERROR, "reserved blocksize code: 0\n");
-        return -1;
-    } else if (blocksize_code == 6)
-        blocksize = get_bits(gb, 8)+1;
-    else if (blocksize_code == 7)
-        blocksize = get_bits(gb, 16)+1;
-    else
-        blocksize = ff_flac_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 * (s->is32 ? 4 : 2) > alloc_data_size)
-        return -1;
-
-    if (sample_rate_code == 0)
-        samplerate= s->samplerate;
-    else if (sample_rate_code < 12)
-        samplerate = ff_flac_sample_rate_table[sample_rate_code];
-    else if (sample_rate_code == 12)
-        samplerate = get_bits(gb, 8) * 1000;
-    else if (sample_rate_code == 13)
-        samplerate = get_bits(gb, 16);
-    else if (sample_rate_code == 14)
-        samplerate = get_bits(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(gb, 8);
-    crc8 = av_crc(av_crc_get_table(AV_CRC_8_ATM), 0,
-                  gb->buffer, get_bits_count(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->ch_mode      = ch_mode;
+    if (!s->got_streaminfo) {
+        allocate_buffers(s);
+        s->got_streaminfo = 1;
+        dump_headers(s->avctx, (FLACStreaminfo *)s);
+    }
 
 //    dump_headers(s->avctx, (FLACStreaminfo *)s);
 
@@ -594,55 +568,30 @@ static int decode_frame(FLACContext *s, int alloc_data_size)
     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)
 {
+    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 i, j = 0, bytes_read = 0;
+    int16_t *samples_16;
+    int32_t *samples_32;
+    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.
        FF F8 69 02 00 00 9A 00 00 34 46 */
-    if (buf_size < 11)
-        goto end;
+    if (buf_size < FLAC_MIN_FRAME_SIZE)
+        return buf_size;
 
     /* check for inline header */
     if (AV_RB32(buf) == MKBETAG('f','L','a','C')) {
@@ -650,32 +599,26 @@ static int flac_decode_frame(AVCodecContext *avctx,
             av_log(s->avctx, AV_LOG_ERROR, "invalid header\n");
             return -1;
         }
-        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 (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;
     }
-    *data_size = s->blocksize * s->channels * (s->is32 ? 4 : 2);
     bytes_read = (get_bits_count(&s->gb)+7)/8;
 
+    /* get output buffer */
+    s->frame.nb_samples = s->blocksize;
+    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
+    }
+    samples_16 = (int16_t *)s->frame.data[0];
+    samples_32 = (int32_t *)s->frame.data[0];
+
 #define DECORRELATE(left, right)\
             assert(s->channels == 2);\
             for (i = 0; i < s->blocksize; i++) {\
@@ -710,20 +653,19 @@ static int flac_decode_frame(AVCodecContext *avctx,
         DECORRELATE( (a-=b>>1) + b, a)
     }
 
-end:
     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;
     }
+    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;
+    *(AVFrame *)data = s->frame;
+
+    return bytes_read;
 }
 
 static av_cold int flac_decode_close(AVCodecContext *avctx)
@@ -734,29 +676,18 @@ 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,
-    .long_name= NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
+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,
+    .capabilities   = CODEC_CAP_DR1,
+    .long_name      = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
 };