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; /* 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 AVERROR_INVALIDDATA; /* initialize based on the demuxer-supplied streamdata header */ ff_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; }
static av_cold int flac_decode_init(AVCodecContext *avctx) { enum FLACExtradataFormat format; uint8_t *streaminfo; FLACContext *s = avctx->priv_data; s->avctx = avctx; /* 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); 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; }
/** * 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 parse_streaminfo(FLACContext *s, const uint8_t *buf, int buf_size) { int metadata_type, metadata_size; 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); flac_set_bps(s); ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); s->got_streaminfo = 1; return 0; }
static int decode_frame(FLACContext *s) { 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; } 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 (!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 (!s->bps) { s->bps = s->avctx->bits_per_raw_sample = fi.bps; flac_set_bps(s); } 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 AVERROR_INVALIDDATA; } s->blocksize = fi.blocksize; 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; 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); } // dump_headers(s->avctx, (FLACStreaminfo *)s); /* subframes */ for (i = 0; i < s->channels; i++) { if ((ret = decode_subframe(s, i)) < 0) return ret; } align_get_bits(gb); /* frame footer */ skip_bits(gb, 16); /* data crc */ return 0; }