On Tue, 23 Oct 2012 17:43:34 -0400, Justin Ruggles <[email protected]> wrote: > Although the libFLAC decoder cannot handle such a change, it is allowed by the > spec and could potentially occur with live streams. > --- > libavcodec/flac.c | 19 +++++++++++++++++++ > libavcodec/flac.h | 3 +++ > libavcodec/flac_parser.c | 1 + > libavcodec/flacdec.c | 27 +++++++++------------------ > 4 files changed, 32 insertions(+), 18 deletions(-) > > diff --git a/libavcodec/flac.c b/libavcodec/flac.c > index d624beb..07da702 100644 > --- a/libavcodec/flac.c > +++ b/libavcodec/flac.c > @@ -19,6 +19,7 @@ > * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > */ > > +#include "libavutil/audioconvert.h" > #include "libavutil/crc.h" > #include "libavutil/log.h" > #include "bytestream.h" > @@ -28,6 +29,15 @@ > > static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 }; > > +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 int64_t get_utf8(GetBitContext *gb) > { > int64_t val; > @@ -181,6 +191,14 @@ int avpriv_flac_is_extradata_valid(AVCodecContext *avctx, > return 1; > } > > +void ff_flac_set_channel_layout(AVCodecContext *avctx) > +{ > + if (avctx->channels <= FF_ARRAY_ELEMS(flac_channel_layouts)) > + avctx->channel_layout = flac_channel_layouts[avctx->channels - 1]; > + else > + avctx->channel_layout = 0; > +} > + > void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, struct > FLACStreaminfo *s, > const uint8_t *buffer) > { > @@ -205,6 +223,7 @@ void avpriv_flac_parse_streaminfo(AVCodecContext *avctx, > struct FLACStreaminfo * > avctx->channels = s->channels; > avctx->sample_rate = s->samplerate; > avctx->bits_per_raw_sample = s->bps; > + ff_flac_set_channel_layout(avctx); > > s->samples = get_bits_long(&gb, 32) << 4; > s->samples |= get_bits(&gb, 4); > diff --git a/libavcodec/flac.h b/libavcodec/flac.h > index 55bacea..63f41c2 100644 > --- a/libavcodec/flac.h > +++ b/libavcodec/flac.h > @@ -137,4 +137,7 @@ int ff_flac_get_max_frame_size(int blocksize, int ch, int > bps); > */ > int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, > FLACFrameInfo *fi, int log_level_offset); > + > +void ff_flac_set_channel_layout(AVCodecContext *avctx); > + > #endif /* AVCODEC_FLAC_H */ > diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c > index 6c8c046..f0a37f3 100644 > --- a/libavcodec/flac_parser.c > +++ b/libavcodec/flac_parser.c > @@ -459,6 +459,7 @@ static int get_best_header(FLACParseContext* fpc, const > uint8_t **poutbuf, > > fpc->avctx->sample_rate = header->fi.samplerate; > fpc->avctx->channels = header->fi.channels; > + ff_flac_set_channel_layout(fpc->avctx); > fpc->pc->duration = header->fi.blocksize; > *poutbuf = flac_fifo_read_wrap(fpc, header->offset, *poutbuf_size, > &fpc->wrap_buf, > diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c > index 4ecf5f2..20af820 100644 > --- a/libavcodec/flacdec.c > +++ b/libavcodec/flacdec.c > @@ -66,15 +66,6 @@ typedef struct FLACContext { > 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 int allocate_buffers(FLACContext *s); > > static void flac_set_bps(FLACContext *s) > @@ -127,9 +118,6 @@ static av_cold int flac_decode_init(AVCodecContext *avctx) > 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; > } > > @@ -421,7 +409,7 @@ static inline int decode_subframe(FLACContext *s, int > channel) > > static int decode_frame(FLACContext *s) > { > - int i; > + int i, ret; > GetBitContext *gb = &s->gb; > FLACFrameInfo fi; > > @@ -430,12 +418,15 @@ static int decode_frame(FLACContext *s) > return -1; > } > > - 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 (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; > + ff_flac_set_channel_layout(s->avctx); > s->ch_mode = fi.ch_mode; > > if (!s->bps && !fi.bps) { > @@ -478,7 +469,7 @@ static int decode_frame(FLACContext *s) > s->samplerate = s->avctx->sample_rate = fi.samplerate; > > if (!s->got_streaminfo) { > - int ret = allocate_buffers(s); > + ret = allocate_buffers(s); > if (ret < 0) > return ret; > ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); > -- > 1.7.1 >
Looks ok -- Anton Khirnov _______________________________________________ libav-devel mailing list [email protected] https://lists.libav.org/mailman/listinfo/libav-devel
