From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: <ffmpeg-devel-bounces@ffmpeg.org> Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id C494C4E5F0 for <ffmpegdev@gitmailbox.com>; Thu, 13 Mar 2025 12:19:02 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 249B868E789; Thu, 13 Mar 2025 14:18:59 +0200 (EET) Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 1802568C8BB for <ffmpeg-devel@ffmpeg.org>; Thu, 13 Mar 2025 14:18:53 +0200 (EET) Received: by mail-wr1-f41.google.com with SMTP id ffacd0b85a97d-3913fdd0120so502042f8f.0 for <ffmpeg-devel@ffmpeg.org>; Thu, 13 Mar 2025 05:18:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1741868332; x=1742473132; darn=ffmpeg.org; h=content-transfer-encoding:content-language:to:subject:from :user-agent:mime-version:date:message-id:from:to:cc:subject:date :message-id:reply-to; bh=a9nSAFr+LRlyyioU39NvKlQtAtnlpPcvNdr7XWZXSEY=; b=ZlDof47pafkh6PYJ66IjUAB/+kVgX85FWb+eMx6lNEvECYFhBMiKkotd24yuq12WuK JLLq/ACdnyKQCC2NCDg9ypVN7vT3WQEosvzI+0jL7hIo1awkEbuxIkVxqFgJe39iGx/s 7GoNQUeQNUfAJm3/LX5i32Qdrk/MccCdRrfK1PB+hTwdR6DvaD0bf+LXdfxcbNzt5PEZ KT8TUw1WGwGev3EfjDmh45sJrBGgExIp57e0VWGrbIffv0G/2bFdbB2o9ICiG+0pdmnp hiEf6CivPp6AGOK/hKLqKn8bui5iOFicl+jDcpsVruXfQUWiTTrPBA/pExDd0GEpofJk e9pw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741868332; x=1742473132; h=content-transfer-encoding:content-language:to:subject:from :user-agent:mime-version:date:message-id:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=a9nSAFr+LRlyyioU39NvKlQtAtnlpPcvNdr7XWZXSEY=; b=xHXF5wh4/4dkC078QAYMZYWo+9/0qXlfhuvmxp0gRAyBnv4uenSOb/KoUvD6rA9kQ3 Rr8oMYxBr3Jf+9g0esqGawOwQznCA0MAEvgawVVrLsL+R8+IYT1fg2ALvz+tkZITvsO3 xfj6s8iu9gokv3C2Ihkt3+HPGVf46HHQiEUlHN7Hi4P1qnMO5aEpZZvzy/X4kBtpt21O 7ydktrUEkybRma7b5HTLYKo7X6AiCS9ueStzYEZplGohK5HqPLrNSVrm9ZjqYpis3oGl f0xrJF73kTinLzM+zKZ3YQ3wbIwBVI4tDlfOP+6yBwekyHzoBBHqNm1tolfKM5oBMuiG AhZA== X-Gm-Message-State: AOJu0YwJCwCx8R+8Iqyw6FRGe3VyyCJ8GhVl0pBeCkW1aIdgZmSdmecu 4ei/eMW7p6yiUgJdnEjAzOgMR4juJ2DbZGHGdEew/nFXDYYdXo8oFRiOag== X-Gm-Gg: ASbGnctXBcS+fg+7NVY1/OZ0GG8JaupI5WKQj+0uAlCwAAve/VKlMro8s7zOZmhTQKj OiWQo/8kR1Fgn5gXlfZveCffqSCAz207JEIsK6PC6GsZIy3S8O+UHhfQkKW000TSw+63PUOvn0W QwYVcezsKVmD2QHNrOSWh/baQgd91MyA3duZ9AySPdekjoxgv38A4KeoR5D1q5hZIPmfaQitClQ 8Qb9s/AKAgJWG/VtcfaE77Wt/h3wX1RW6kUgi9fqUo1kQZ8lRs0GAoEusbArxiWU0QBcvS7eJXI 3JwLHL1v71qIHb9kgSze9GwQHlxI5lwOf5gSwSutHnEY19vNyAumQDOpJCBszKcyp/umCnE4X6n EuSqhkn9hddJFj0iPsP6n9Ug= X-Google-Smtp-Source: AGHT+IE9Wh3p9THu1J/bk0UcrkRc/ZvSS0odSPm2/G5RUQx3Hw1avFp7ADbR3jndQGBKKm0qWEChMg== X-Received: by 2002:a05:6000:144d:b0:391:2e58:f085 with SMTP id ffacd0b85a97d-39132dab192mr20348986f8f.54.1741868332241; Thu, 13 Mar 2025 05:18:52 -0700 (PDT) Received: from ?IPV6:2001:9e8:1da4:1900:cde4:ff8d:50cc:75e6? ([2001:9e8:1da4:1900:cde4:ff8d:50cc:75e6]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-395c888117csm1931769f8f.44.2025.03.13.05.18.51 for <ffmpeg-devel@ffmpeg.org> (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 13 Mar 2025 05:18:51 -0700 (PDT) Message-ID: <6bef7ee3-6e0b-496a-9018-ce02d5e8cd63@gmail.com> Date: Thu, 13 Mar 2025 13:18:49 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird From: Leandro Santiago <leandrosansilva@gmail.com> To: ffmpeg-devel@ffmpeg.org Content-Language: en-US Subject: [FFmpeg-devel] [PATCH] avfilter: POC: enable out-of-tree filters X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches <ffmpeg-devel.ffmpeg.org> List-Unsubscribe: <https://ffmpeg.org/mailman/options/ffmpeg-devel>, <mailto:ffmpeg-devel-request@ffmpeg.org?subject=unsubscribe> List-Archive: <https://ffmpeg.org/pipermail/ffmpeg-devel> List-Post: <mailto:ffmpeg-devel@ffmpeg.org> List-Help: <mailto:ffmpeg-devel-request@ffmpeg.org?subject=help> List-Subscribe: <https://ffmpeg.org/mailman/listinfo/ffmpeg-devel>, <mailto:ffmpeg-devel-request@ffmpeg.org?subject=subscribe> Reply-To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" <ffmpeg-devel-bounces@ffmpeg.org> Archived-At: <https://master.gitmailbox.com/ffmpegdev/6bef7ee3-6e0b-496a-9018-ce02d5e8cd63@gmail.com/> List-Archive: <https://master.gitmailbox.com/ffmpegdev/> List-Post: <mailto:ffmpegdev@gitmailbox.com> This is a POC/prototype that aims to enable out of tree filters on FFmpeg. Here I name them "extra filters". It introduces the program `jq` as a new build dependency. To test it, create a directory, for instance, /tmp/my-shiny-filter/ and inside it, create the following files: `filter.json`, with the content: ``` { "check": "require_pkg_config json json-c json-c/json.h json_c_version_num", "symbols": ["ff_vf_foo", "ff_vf_bar"] } ``` `filter.mak`, with the content: ``` OBJS += vf_shiny.o LIBOBJS += vf_shiny.o libavfilter/vf_shiny.o: $(CC) $(EXTRA_FILTER_FLAGS) -c -o $@ $(EXTRA_FILTER_FOO_LOCATION)/vf_shiny.c ``` `vf_shiny.c` file, with the content: ``` #include "libavutil/internal.h" #include "avfilter.h" #include "filters.h" #include "video.h" const FFFilter ff_vf_bar = { .p.name = "bar", .p.description = NULL_IF_CONFIG_SMALL("Example filter Baz"), .p.flags = AVFILTER_FLAG_METADATA_ONLY, FILTER_INPUTS(ff_video_default_filterpad), FILTER_OUTPUTS(ff_video_default_filterpad), }; const FFFilter ff_vf_foo = { .p.name = "foo", .p.description = NULL_IF_CONFIG_SMALL("Another foo filter"), .p.flags = AVFILTER_FLAG_METADATA_ONLY, FILTER_INPUTS(ff_video_default_filterpad), FILTER_OUTPUTS(ff_video_default_filterpad), }; ``` Then, from the ffmpeg source tree, run configure specifying where the extra filter is located: ``` ./configure --extra-filter=/tmp/my-shiny-filter make ffplay ``` Now you can use the filters: ``` ./ffplay /path/to/file.webm -vf 'foo,baz' ``` What works: - Building C based filters with no extra dependencies. - Multiple filters in the same object file. What does not work: - The extra filters will not use the same CC flags used to build the built-in filters as I could get it to work yet. - Due to the above limitation, you cannot include headers of extra dependencies, for instance, `json.h` in the example. - You can pass arbitrary CFLAGS or LDFLAGS in the filter.json file, but they should be passed only then building/linking `libavfilter`, instead of other libraries. What was not implemented: - I believe it would be useful to check if the license of the filter is compatible with the license used to build FFmpeg. - Only extra filters written in C (maybe C++?) are supported for now. One of my goals is to enable Rust as well. Signed-off-by: Leandro Santiago <leandrosansilva@gmail.com> --- .gitignore | 3 ++ configure | 61 ++++++++++++++++++++++++++++++++++++++++ libavfilter/Makefile | 4 +++ libavfilter/allfilters.c | 1 + 4 files changed, 69 insertions(+) diff --git a/.gitignore b/.gitignore index 9cfc78b414..4963e90191 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,6 @@ /tools/python/__pycache__/ /libavcodec/vulkan/*.c /libavfilter/vulkan/*.c +/ffbuild/extra-filters.txt +/ffbuild/extra-filters.mak +/libavfilter/extra_filters_extern.h diff --git a/configure b/configure index 750c99e3b9..6a2adc6c05 100755 --- a/configure +++ b/configure @@ -179,6 +179,7 @@ Individual component options: --enable-filter=NAME enable filter NAME --disable-filter=NAME disable filter NAME --disable-filters disable all filters + --extra-filter=/foo/bar add extra filter from directory. This option can be used multiple times External library support: @@ -1798,6 +1799,7 @@ AVDEVICE_COMPONENTS=" AVFILTER_COMPONENTS=" filters + extra_filters " AVFORMAT_COMPONENTS=" @@ -4382,6 +4384,8 @@ do_random(){ $action $(rand_list "$@" | awk "BEGIN { srand($random_seed) } \$1 == \"prob\" { prob = \$2; next } rand() < prob { print }") } +rm -f ffbuild/extra-filters.txt + # deprecated components (disabled by default) disable sonic_encoder sonic_ls_encoder @@ -4457,6 +4461,10 @@ for opt do die_unknown $opt fi ;; + --extra-filter=*) + filter_path="${opt#--extra-filter=}" + echo "$filter_path" >> ffbuild/extra-filters.txt + ;; --list-*) NAME="${opt#--list-}" is_in $NAME $COMPONENT_LIST || die_unknown $opt @@ -4487,6 +4495,36 @@ for opt do esac done +find_extra_filters_extern() { + # TODO: handle invalid filter + while read f; do + jq -r '.symbols[]' < "$f/filter.json" | sed 's/^ff_[avfsinkrc]\{2,5\}_\([[:alnum:]_]\{1,\}\)/\1_filter/' + done < ffbuild/extra-filters.txt +} + +EXTRA_FILTER_LIST=$(find_extra_filters_extern) + +for n in extra_filters; do + v=$(toupper ${n%s})_LIST + eval enable \$$v + eval ${n}_if_any="\$$v" +done + +FILTER_LIST=" + $FILTER_LIST + $EXTRA_FILTER_LIST +" + +AVFILTER_COMPONENTS_LIST=" + $AVFILTER_COMPONENTS_LIST + $EXTRA_FILTER_LIST +" + +ALL_COMPONENTS=" + $ALL_COMPONENTS + $EXTRA_FILTER_LIST +" + for e in $env; do eval "export $e" done @@ -7165,6 +7203,10 @@ enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/r } enabled vapoursynth && require_headers "vapoursynth/VSScript4.h vapoursynth/VapourSynth4.h" +while read f; do + # NOTE: this eval is dangerous, as it allows arbitrary code execution! + eval $(jq -r '.check // true' < "$f/filter.json") +done < ffbuild/extra-filters.txt if enabled gcrypt; then GCRYPT_CONFIG="${cross_prefix}libgcrypt-config" @@ -8243,6 +8285,12 @@ for entry in $LIBRARY_LIST $PROGRAM_LIST $EXTRALIBS_LIST; do eval echo "EXTRALIBS-${entry}=\$${entry}_extralibs" >> ffbuild/config.mak done +echo "" > ffbuild/extra-filters.mak + +while read f; do + echo "include $f/filter.mak" >> ffbuild/extra-filters.mak +done < ffbuild/extra-filters.txt + cat > $TMPH <<EOF /* Automatically generated by configure - do not modify! */ #ifndef FFMPEG_CONFIG_H @@ -8330,6 +8378,19 @@ cp_if_changed $TMPH libavutil/avconfig.h # ... eval "$(sed -n "s/^extern const FFFilter ff_\([avfsinkrc]\{2,5\}\)_\(.*\);/full_filter_name_\2=\1_\2/p" $source_path/libavfilter/allfilters.c)" +rm -f libavfilter/extra_filters_extern.h + +# Handle extra filters +while read f; do + eval "$(jq -r '.symbols[]' < "$f/filter.json" | sed 's/^ff_\([avfsinkrc]\{2,5\}\)_\([[:alnum:]]\{1,\}\)$/full_filter_name_\2=\1_\2/')" + jq -r '.symbols[]' < "$f/filter.json" | while read symbol; do + echo "extern const FFFilter $symbol;" >> libavfilter/extra_filters_extern.h + echo "EXTRA_FILTER_$(echo $symbol | sed 's/^ff_[avfsinkrc]\{2,5\}_\([[:alnum:]]\{1,\}\)$/\1/' | tr a-z A-Z)_LOCATION = $f" >> ffbuild/extra-filters.mak + echo "LDFLAGS += $(jq -r '.ldflags // ""' < "$f/filter.json")" >> ffbuild/extra-filters.mak + echo "CFLAGS += $(jq -r '.cflags // ""' < "$f/filter.json")" >> ffbuild/extra-filters.mak + done +done < ffbuild/extra-filters.txt + # generate the lists of enabled components print_enabled_components(){ file=$1 diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 7c0d879ec9..9b22aece3a 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -27,6 +27,10 @@ OBJS = allfilters.o \ include $(SRC_PATH)/libavfilter/dnn/Makefile include $(SRC_PATH)/libavfilter/vulkan/Makefile +# extra filters handling +include $(SRC_PATH)/ffbuild/extra-filters.mak +EXTRA_FILTER_FLAGS = -I$(PWD) -I$(PWD)/libavfilter $(CPPFLAGS) $(CC_DEPFLAGS) + OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o OBJS-$(HAVE_THREADS) += pthread.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 740d9ab265..e8565de5b0 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -621,6 +621,7 @@ extern const FFFilter ff_vsrc_buffer; extern const FFFilter ff_asink_abuffer; extern const FFFilter ff_vsink_buffer; +#include "libavfilter/extra_filters_extern.h" #include "libavfilter/filter_list.c" -- 2.48.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".