]> git.sesse.net Git - ffmpeg/blobdiff - tools/target_dec_fuzzer.c
Merge commit '89725a8512721fffd190021ded2d3f5b42e20e2a'
[ffmpeg] / tools / target_dec_fuzzer.c
index dc72fd8b5dbb3d32d755121bbb81a4b27a03b352..5a0b53e546a55e4ed3576ec9110b6715707b3464 100644 (file)
@@ -66,7 +66,7 @@ static AVCodec *c = NULL;
 static AVCodec *AVCodecInitialize(enum AVCodecID codec_id)
 {
     AVCodec *res;
-    av_register_all();
+
     av_log_set_level(AV_LOG_PANIC);
     res = avcodec_find_decoder(codec_id);
     if (!res)
@@ -74,11 +74,6 @@ static AVCodec *AVCodecInitialize(enum AVCodecID codec_id)
     return res;
 }
 
-#if defined(FUZZ_FFMPEG_VIDEO)
-#define decode_handler avcodec_decode_video2
-#elif defined(FUZZ_FFMPEG_AUDIO)
-#define decode_handler avcodec_decode_audio4
-#elif defined(FUZZ_FFMPEG_SUBTITLE)
 static int subtitle_handler(AVCodecContext *avctx, void *frame,
                             int *got_sub_ptr, AVPacket *avpkt)
 {
@@ -89,11 +84,6 @@ static int subtitle_handler(AVCodecContext *avctx, void *frame,
     return ret;
 }
 
-#define decode_handler subtitle_handler
-#else
-#error "Specify encoder type"  // To catch mistakes
-#endif
-
 // Class to handle buffer allocation and resize for each frame
 typedef struct FuzzDataBuffer {
     size_t size_;
@@ -146,9 +136,30 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
     const uint8_t *last = data;
     const uint8_t *end = data + size;
     uint32_t it = 0;
-
-    if (!c)
+    int (*decode_handler)(AVCodecContext *avctx, AVFrame *picture,
+                          int *got_picture_ptr,
+                          const AVPacket *avpkt) = NULL;
+
+    if (!c) {
+#ifdef FFMPEG_DECODER
+#define DECODER_SYMBOL0(CODEC) ff_##CODEC##_decoder
+#define DECODER_SYMBOL(CODEC) DECODER_SYMBOL0(CODEC)
+        extern AVCodec DECODER_SYMBOL(FFMPEG_DECODER);
+        avcodec_register(&DECODER_SYMBOL(FFMPEG_DECODER));
+        int codec_id = DECODER_SYMBOL(FFMPEG_DECODER).id;
+
+        c = AVCodecInitialize(codec_id);  // Done once.
+#else
+        avcodec_register_all();
         c = AVCodecInitialize(FFMPEG_CODEC);  // Done once.
+#endif
+    }
+
+    switch (c->type) {
+    case AVMEDIA_TYPE_AUDIO   : decode_handler = avcodec_decode_audio4; break;
+    case AVMEDIA_TYPE_VIDEO   : decode_handler = avcodec_decode_video2; break;
+    case AVMEDIA_TYPE_SUBTITLE: decode_handler = subtitle_handler     ; break;
+    }
 
     AVCodecContext* ctx = avcodec_alloc_context3(NULL);
     if (!ctx)
@@ -169,8 +180,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
     }
 
     int res = avcodec_open2(ctx, c, NULL);
-    if (res < 0)
-        return res;
+    if (res < 0) {
+        av_free(ctx);
+        return 0; // Failure of avcodec_open2() does not imply that a issue was found
+    }
 
     FDBCreate(&buffer);
     int got_frame;