Mercurial > libavcodec.hg
changeset 9054:7eedb5796dd8 libavcodec
Use a shared function to validate FLAC extradata.
author | jbr |
---|---|
date | Thu, 26 Feb 2009 02:29:24 +0000 |
parents | c6bd71120376 |
children | 15515243f476 |
files | Makefile flac.h flacdec.c |
diffstat | 3 files changed, 58 insertions(+), 12 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Thu Feb 26 01:54:16 2009 +0000 +++ b/Makefile Thu Feb 26 02:29:24 2009 +0000 @@ -345,15 +345,16 @@ # libavformat dependencies OBJS-$(CONFIG_EAC3_DEMUXER) += ac3_parser.o ac3tab.o aac_ac3_parser.o +OBJS-$(CONFIG_FLAC_MUXER) += flacdec.o OBJS-$(CONFIG_GXF_DEMUXER) += mpeg12data.o -OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += xiph.o mpeg4audio.o +OBJS-$(CONFIG_MATROSKA_AUDIO_MUXER) += xiph.o mpeg4audio.o flacdec.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio.o -OBJS-$(CONFIG_MATROSKA_MUXER) += xiph.o mpeg4audio.o +OBJS-$(CONFIG_MATROSKA_MUXER) += xiph.o mpeg4audio.o flacdec.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 -OBJS-$(CONFIG_OGG_MUXER) += xiph.o +OBJS-$(CONFIG_OGG_MUXER) += xiph.o flacdec.o OBJS-$(CONFIG_RTP_MUXER) += mpegvideo.o # external codec libraries
--- a/flac.h Thu Feb 26 01:54:16 2009 +0000 +++ b/flac.h Thu Feb 26 02:29:24 2009 +0000 @@ -42,6 +42,11 @@ FLAC_METADATA_TYPE_INVALID = 127 }; +enum FLACExtradataFormat { + FLAC_EXTRADATA_FORMAT_STREAMINFO = 0, + FLAC_EXTRADATA_FORMAT_FULL_HEADER = 1 +}; + /** * Data needed from the Streaminfo header for use by the raw FLAC demuxer * and/or the FLAC decoder. @@ -68,4 +73,15 @@ void ff_flac_parse_streaminfo(AVCodecContext *avctx, struct FLACStreaminfo *s, const uint8_t *buffer); +/** + * Validate the FLAC extradata. + * @param[in] avctx codec context containing the extradata. + * @param[out] format extradata format. + * @param[out] streaminfo_start pointer to start of 34-byte STREAMINFO data. + * @return 1 if valid, 0 if not valid. + */ +int ff_flac_is_extradata_valid(AVCodecContext *avctx, + enum FLACExtradataFormat *format, + uint8_t **streaminfo_start); + #endif /* AVCODEC_FLAC_H */
--- a/flacdec.c Thu Feb 26 01:54:16 2009 +0000 +++ b/flacdec.c Thu Feb 26 02:29:24 2009 +0000 @@ -96,26 +96,55 @@ } static void allocate_buffers(FLACContext *s); -static int metadata_parse(FLACContext *s); + +int ff_flac_is_extradata_valid(AVCodecContext *avctx, + enum FLACExtradataFormat *format, + uint8_t **streaminfo_start) +{ + 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; + } 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]; + } + return 1; +} static av_cold int flac_decode_init(AVCodecContext *avctx) { + enum FLACExtradataFormat format; + uint8_t *streaminfo; FLACContext *s = avctx->priv_data; s->avctx = avctx; avctx->sample_fmt = SAMPLE_FMT_S16; - if (avctx->extradata_size > 4) { + /* 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 -1; + /* initialize based on the demuxer-supplied streamdata header */ - if (avctx->extradata_size == FLAC_STREAMINFO_SIZE) { ff_flac_parse_streaminfo(avctx, (FLACStreaminfo *)s, - avctx->extradata); + streaminfo); allocate_buffers(s); - } else { - init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size*8); - metadata_parse(s); - } - } return 0; }