diff flacdec.c @ 9054:7eedb5796dd8 libavcodec

Use a shared function to validate FLAC extradata.
author jbr
date Thu, 26 Feb 2009 02:29:24 +0000
parents 49817775b44f
children 15515243f476
line wrap: on
line diff
--- 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;
 }