summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2009-02-26 02:29:24 +0000
committerJustin Ruggles <justin.ruggles@gmail.com>2009-02-26 02:29:24 +0000
commit59c6178a54c414fd19e064f0077d00b82a1eb812 (patch)
tree69bc8f09fc89959005fa8527d6822cc2eeea96c0 /libavcodec
parentcaee91f7d038f80893b3c1ccdcd1bc44a9a19351 (diff)
Use a shared function to validate FLAC extradata.
Originally committed as revision 17602 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/Makefile7
-rw-r--r--libavcodec/flac.h16
-rw-r--r--libavcodec/flacdec.c47
3 files changed, 58 insertions, 12 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index afb1ede3fe..afa5fac152 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -345,15 +345,16 @@ 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_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
diff --git a/libavcodec/flac.h b/libavcodec/flac.h
index 9a4f820831..8af79f2bd8 100644
--- a/libavcodec/flac.h
+++ b/libavcodec/flac.h
@@ -42,6 +42,11 @@ enum {
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 @@ typedef struct FLACStreaminfo {
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 */
diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c
index d6e0c8620f..42310b24a0 100644
--- a/libavcodec/flacdec.c
+++ b/libavcodec/flacdec.c
@@ -96,26 +96,55 @@ static int64_t get_utf8(GetBitContext *gb)
}
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;
}