diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 7683402f56..4843e0933a 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -83,8 +83,8 @@ OBJS-$(CONFIG_FFV1_DECODER) += ffv1.o rangecoder.o OBJS-$(CONFIG_FFV1_ENCODER) += ffv1.o rangecoder.o OBJS-$(CONFIG_FFVHUFF_DECODER) += huffyuv.o OBJS-$(CONFIG_FFVHUFF_ENCODER) += huffyuv.o -OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o -OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o lpc.o +OBJS-$(CONFIG_FLAC_DECODER) += flacdec.o flacdata.o flac.o +OBJS-$(CONFIG_FLAC_ENCODER) += flacenc.o flacdata.o flac.o lpc.o OBJS-$(CONFIG_FLASHSV_DECODER) += flashsv.o OBJS-$(CONFIG_FLASHSV_ENCODER) += flashsvenc.o OBJS-$(CONFIG_FLIC_DECODER) += flicvideo.o @@ -346,17 +346,17 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcm.o # libavformat dependencies OBJS-$(CONFIG_EAC3_DEMUXER) += ac3_parser.o ac3tab.o aac_ac3_parser.o -OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o flacdata.o -OBJS-$(CONFIG_FLAC_MUXER) += flacdec.o flacdata.o +OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o flacdata.o flac.o +OBJS-$(CONFIG_FLAC_MUXER) += flacdec.o flacdata.o flac.o OBJS-$(CONFIG_GXF_DEMUXER) += mpeg12data.o -OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += xiph.o mpeg4audio.o flacdec.o flacdata.o +OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += xiph.o mpeg4audio.o flacdec.o flacdata.o flac.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio.o -OBJS-$(CONFIG_MATROSKA_MUXER) += xiph.o mpeg4audio.o flacdec.o flacdata.o +OBJS-$(CONFIG_MATROSKA_MUXER) += xiph.o mpeg4audio.o flacdec.o flacdata.o flac.o OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o OBJS-$(CONFIG_MPEGTS_MUXER) += mpegvideo.o OBJS-$(CONFIG_NUT_MUXER) += mpegaudiodata.o -OBJS-$(CONFIG_OGG_DEMUXER) += flacdec.o flacdata.o -OBJS-$(CONFIG_OGG_MUXER) += xiph.o flacdec.o flacdata.o +OBJS-$(CONFIG_OGG_DEMUXER) += flacdec.o flacdata.o flac.o +OBJS-$(CONFIG_OGG_MUXER) += xiph.o flacdec.o flacdata.o flac.o OBJS-$(CONFIG_RTP_MUXER) += mpegvideo.o # external codec libraries diff --git a/libavcodec/flac.c b/libavcodec/flac.c new file mode 100644 index 0000000000..a649e08732 --- /dev/null +++ b/libavcodec/flac.c @@ -0,0 +1,43 @@ +/* + * FLAC common code + * Copyright (c) 2009 Justin Ruggles + * + * This file is part of FFmpeg. + * + * FFmpeg 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, + * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "flac.h" + +int ff_flac_get_max_frame_size(int blocksize, int ch, int bps) +{ + /* Technically, there is no limit to FLAC frame size, but an encoder + should not write a frame that is larger than if verbatim encoding mode + were to be used. */ + + int count; + + count = 16; /* frame header */ + count += ch * ((7+bps+7)/8); /* subframe headers */ + if (ch == 2) { + /* for stereo, need to account for using decorrelation */ + count += (( 2*bps+1) * blocksize + 7) / 8; + } else { + count += ( ch*bps * blocksize + 7) / 8; + } + count += 2; /* frame footer */ + + return count; +} diff --git a/libavcodec/flac.h b/libavcodec/flac.h index 1e44a3b394..2728905b79 100644 --- a/libavcodec/flac.h +++ b/libavcodec/flac.h @@ -103,4 +103,12 @@ int ff_flac_is_extradata_valid(AVCodecContext *avctx, void ff_flac_parse_block_header(const uint8_t *block_header, int *last, int *type, int *size); +/** + * Calculate an estimate for the maximum frame size based on verbatim mode. + * @param blocksize block size, in samples + * @param ch number of channels + * @param bps bits-per-sample + */ +int ff_flac_get_max_frame_size(int blocksize, int ch, int bps); + #endif /* AVCODEC_FLAC_H */ diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index ec1ace4aee..8dbe8c91b4 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -147,7 +147,8 @@ static void allocate_buffers(FLACContext *s) assert(s->max_blocksize); if (s->max_framesize == 0 && s->max_blocksize) { - s->max_framesize = 23 + (s->channels * s->bps * s->max_blocksize + 7) / 8; + s->max_framesize = ff_flac_get_max_frame_size(s->max_blocksize, + s->channels, s->bps); } for (i = 0; i < s->channels; i++) { diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index f51a4ee58b..b517cfa720 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -345,11 +345,8 @@ static av_cold int flac_encode_init(AVCodecContext *avctx) s->options.lpc_coeff_precision); /* set maximum encoded frame size in verbatim mode */ - if(s->channels == 2) { - s->max_framesize = 14 + ((s->avctx->frame_size * 33 + 7) >> 3); - } else { - s->max_framesize = 14 + (s->avctx->frame_size * s->channels * 2); - } + s->max_framesize = ff_flac_get_max_frame_size(s->avctx->frame_size, + s->channels, 16); /* initialize MD5 context */ s->md5ctx = av_malloc(av_md5_size);