From f3e9780d100d4b975ed3685c9d2a2b23daf56674 Mon Sep 17 00:00:00 2001 From: zhupengfei Date: Fri, 28 Feb 2020 16:40:13 +0800 Subject: [PATCH] ffmpeg: Avoid listing child classes for AVFormatContext and AVCodecContext As they actually have every encoder/format as their child classes, this will result in a lot of extra options being added. --- src/core/dumping/ffmpeg_backend.cpp | 32 +++++++++++------------------ 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/core/dumping/ffmpeg_backend.cpp b/src/core/dumping/ffmpeg_backend.cpp index 5a81bed78..17a2c4cd7 100644 --- a/src/core/dumping/ffmpeg_backend.cpp +++ b/src/core/dumping/ffmpeg_backend.cpp @@ -728,41 +728,33 @@ void GetOptionListSingle(std::vector& out, const AVClass* av_class) } } -void GetOptionList(std::vector& out, const AVClass* av_class) { +void GetOptionList(std::vector& out, const AVClass* av_class, bool search_children) { if (av_class == nullptr) { return; } GetOptionListSingle(out, av_class); + if (!search_children) { + return; + } + const AVClass* child_class = nullptr; while ((child_class = av_opt_child_class_next(av_class, child_class))) { GetOptionListSingle(out, child_class); } } -std::vector GetOptionList(const AVClass* av_class) { +std::vector GetOptionList(const AVClass* av_class, bool search_children) { std::vector out; - GetOptionList(out, av_class); - - // Filter out identical options (why do they exist in the first place?) - std::unordered_set option_name_set; - std::vector final_out; - for (auto& option : out) { - if (option_name_set.count(option.name)) { - continue; - } - option_name_set.emplace(option.name); - final_out.emplace_back(std::move(option)); - } - - return final_out; + GetOptionList(out, av_class, search_children); + return out; } std::vector ListEncoders(AVMediaType type) { InitializeFFmpegLibraries(); - const auto general_options = GetOptionList(avcodec_get_class()); + const auto general_options = GetOptionList(avcodec_get_class(), false); std::vector out; @@ -776,7 +768,7 @@ std::vector ListEncoders(AVMediaType type) { if (!av_codec_is_encoder(current) || current->type != type) { continue; } - auto options = GetOptionList(current->priv_class); + auto options = GetOptionList(current->priv_class, true); options.insert(options.end(), general_options.begin(), general_options.end()); out.push_back( {current->name, ToStdString(current->long_name), current->id, std::move(options)}); @@ -787,7 +779,7 @@ std::vector ListEncoders(AVMediaType type) { std::vector ListFormats() { InitializeFFmpegLibraries(); - const auto general_options = GetOptionList(avformat_get_class()); + const auto general_options = GetOptionList(avformat_get_class(), false); std::vector out; @@ -798,7 +790,7 @@ std::vector ListFormats() { void* data = nullptr; // For libavformat to save the iteration state while ((current = av_muxer_iterate(&data))) { #endif - auto options = GetOptionList(current->priv_class); + auto options = GetOptionList(current->priv_class, true); options.insert(options.end(), general_options.begin(), general_options.end()); std::vector extensions;