#include <limits.h>
+#include "libavutil/audioconvert.h"
#include "libavutil/crc.h"
#include "avcodec.h"
#include "internal.h"
#include "golomb.h"
#include "flac.h"
#include "flacdata.h"
+#include "flacdsp.h"
#undef NDEBUG
#include <assert.h>
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
int ch_mode; ///< channel decorrelation type in the current frame
int got_streaminfo; ///< indicates if the STREAMINFO has been read
int32_t *decoded[FLAC_MAX_CHANNELS]; ///< decoded samples
+
+ FLACDSPContext dsp;
} FLACContext;
+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 avpriv_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)
FLACContext *s = avctx->priv_data;
s->avctx = avctx;
- 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)
/* 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);
+ flac_set_bps(s);
+ ff_flacdsp_init(&s->dsp, avctx->sample_fmt, s->bps);
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;
}
assert(s->max_blocksize);
for (i = 0; i < s->channels; i++) {
- s->decoded[i] = av_realloc(s->decoded[i],
- sizeof(int32_t)*s->max_blocksize);
+ s->decoded[i] = av_malloc(sizeof(int32_t)*s->max_blocksize);
}
}
-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);
-
- 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);
-
- 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;
-
- 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);
-}
-
-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 the STREAMINFO from an inline header.
* @param s the flac decoding context
}
avpriv_flac_parse_streaminfo(s->avctx, (FLACStreaminfo *)s, &buf[8]);
allocate_buffers(s);
+ flac_set_bps(s);
+ ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps);
s->got_streaminfo = 1;
return 0;
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) {
return -1;
}
- 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;
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 a, b, c, d, i;
/* 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)
+ if (decode_residuals(s, decoded, pred_order) < 0)
return -1;
if (pred_order > 0)
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;
int coeff_prec, qlevel;
int coeffs[32];
- int32_t *decoded = s->decoded[channel];
/* 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;
}
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)
+ if (decode_residuals(s, decoded, pred_order) < 0)
return -1;
- 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 bps = s->bps;
int i, tmp;
- s->curr_bps = s->bps;
if (channel == 0) {
if (s->ch_mode == FLAC_CHMODE_RIGHT_SIDE)
- s->curr_bps++;
+ bps++;
} else {
if (s->ch_mode == FLAC_CHMODE_LEFT_SIDE || s->ch_mode == FLAC_CHMODE_MID_SIDE)
- s->curr_bps++;
+ bps++;
}
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)) {
+ (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",
- s->curr_bps, left);
+ bps, left);
return AVERROR_INVALIDDATA;
}
while (!get_bits1(&s->gb))
wasted++;
- s->curr_bps -= wasted;
+ bps -= wasted;
}
- if (s->curr_bps > 32) {
+ if (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_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)
+ if (decode_subframe_fixed(s, decoded, type & ~0x8, bps) < 0)
return -1;
} else if (type >= 32) {
- if (decode_subframe_lpc(s, channel, (type & ~0x20)+1) < 0)
+ if (decode_subframe_lpc(s, decoded, (type & ~0x20)+1, bps) < 0)
return -1;
} else {
av_log(s->avctx, AV_LOG_ERROR, "invalid coding type\n");
if (wasted) {
int i;
for (i = 0; i < s->blocksize; i++)
- s->decoded[channel][i] <<= wasted;
+ decoded[i] <<= wasted;
}
return 0;
"supported\n");
return -1;
}
- s->bps = s->avctx->bits_per_raw_sample = fi.bps;
- 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 (!s->bps) {
+ s->bps = s->avctx->bits_per_raw_sample = fi.bps;
+ flac_set_bps(s);
}
if (!s->max_blocksize)
if (!s->got_streaminfo) {
allocate_buffers(s);
+ ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps);
s->got_streaminfo = 1;
dump_headers(s->avctx, (FLACStreaminfo *)s);
}
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
FLACContext *s = avctx->priv_data;
- int i, j = 0, bytes_read = 0;
- int16_t *samples_16;
- int32_t *samples_32;
+ int bytes_read = 0;
int ret;
*got_frame_ptr = 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++) {\
- 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->ch_mode) {
- case FLAC_CHMODE_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 FLAC_CHMODE_LEFT_SIDE:
- DECORRELATE(a,a-b)
- case FLAC_CHMODE_RIGHT_SIDE:
- DECORRELATE(a+b,b)
- case FLAC_CHMODE_MID_SIDE:
- DECORRELATE( (a-=b>>1) + b, a)
- }
+
+ s->dsp.decorrelate[s->ch_mode](s->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);
AVCodec ff_flac_decoder = {
.name = "flac",
.type = AVMEDIA_TYPE_AUDIO,
- .id = CODEC_ID_FLAC,
+ .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,
- .long_name= NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
+ .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
+ .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16,
+ AV_SAMPLE_FMT_S16P,
+ AV_SAMPLE_FMT_S32,
+ AV_SAMPLE_FMT_S32P,
+ -1 },
};