diff mbox series

[FFmpeg-devel,7/9] avformat: Do not search for child metadata in every packet

Message ID 20201021223733.2563-7-michael@niedermayer.cc
State New
Headers show
Series [FFmpeg-devel,1/9] avformat/segafilm: Check that there is a stream
Related show

Checks

Context Check Description
andriy/x86_make success Make finished
andriy/x86_make_fate success Make fate finished

Commit Message

Michael Niedermayer Oct. 21, 2020, 10:37 p.m. UTC
Fixes: Timeout
Fixes: 26485/clusterfuzz-testcase-minimized-ffmpeg_dem_IFF_fuzzer-5126561373880320

Not tested due to lack of a testcase for the metadata transfer code

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavformat/internal.h |  5 +++++
 libavformat/utils.c    | 16 ++++++++++------
 2 files changed, 15 insertions(+), 6 deletions(-)
diff mbox series

Patch

diff --git a/libavformat/internal.h b/libavformat/internal.h
index f4174628e0..65fd2bddd0 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -142,6 +142,11 @@  struct AVFormatInternal {
      * Prefer the codec framerate for avg_frame_rate computation.
      */
     int prefer_codec_framerate;
+
+    /**
+     * no child has a metadata AVOption, this allows not redoing the very slow search
+     */
+    int no_child_metadata;
 };
 
 struct AVStreamInternal {
diff --git a/libavformat/utils.c b/libavformat/utils.c
index e8335a601f..a7148c8d05 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1678,12 +1678,16 @@  FF_ENABLE_DEPRECATION_WARNINGS
         }
     }
 
-    av_opt_get_dict_val(s, "metadata", AV_OPT_SEARCH_CHILDREN, &metadata);
-    if (metadata) {
-        s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
-        av_dict_copy(&s->metadata, metadata, 0);
-        av_dict_free(&metadata);
-        av_opt_set_dict_val(s, "metadata", NULL, AV_OPT_SEARCH_CHILDREN);
+    if (!s->internal->no_child_metadata) {
+        int ret = av_opt_get_dict_val(s, "metadata", AV_OPT_SEARCH_CHILDREN, &metadata);
+        if (metadata) {
+            s->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
+            av_dict_copy(&s->metadata, metadata, 0);
+            av_dict_free(&metadata);
+            av_opt_set_dict_val(s, "metadata", NULL, AV_OPT_SEARCH_CHILDREN);
+        }
+        if (ret == AVERROR_OPTION_NOT_FOUND)
+            s->internal->no_child_metadata = 1;
     }
 
 #if FF_API_LAVF_AVCTX