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 551C14E63C
	for <ffmpegdev@gitmailbox.com>; Thu, 13 Mar 2025 12:20:19 +0000 (UTC)
Received: from [127.0.1.1] (localhost [127.0.0.1])
	by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id B59C368E84E;
	Thu, 13 Mar 2025 14:20:17 +0200 (EET)
Received: from mail-wm1-f48.google.com (mail-wm1-f48.google.com
 [209.85.128.48])
 by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 701CF68CA58
 for <ffmpeg-devel@ffmpeg.org>; Thu, 13 Mar 2025 14:20:11 +0200 (EET)
Received: by mail-wm1-f48.google.com with SMTP id
 5b1f17b1804b1-43cfebc343dso5280675e9.2
 for <ffmpeg-devel@ffmpeg.org>; Thu, 13 Mar 2025 05:20:11 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=gmail.com; s=20230601; t=1741868411; x=1742473211; darn=ffmpeg.org;
 h=content-transfer-encoding:in-reply-to:content-language:references
 :to:from:subject:user-agent:mime-version:date:message-id:from:to:cc
 :subject:date:message-id:reply-to;
 bh=Z26J/ztKMeNnd0e6WHn9ci/aQdrhVNq6/g6rj4/fukI=;
 b=aeJHDgMOsvQHicdjooCoNcWLfaw//bdBykOolDBu3W3qr2DJJbU+dSk5HtWYuGXmse
 a2mQVEiwbKDn/vJ5uyaCENbmrpKECAV0LztCW2xkzOUtMXl0Vpwx75HRP/YnN687ghhn
 sSyMhVk8SJvrqVpoG6mOAgaeK0L24T5bxEG8Li2YWhjw4UbX2o2+UtKe/RTLelLnFeaY
 qxHCnE3q6Hjmi3prDrly5yL/PbQvBpG5ICxDMYQMMOkd1xuHKJ6zqMfth55YW4JiD31m
 Az1fLN+FfmxdrjLAaxFe56OIXgt+dZY1aX072u+t8JFoIzMBXgq5Q9a9utd7rwvSPbLC
 dYLQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=1e100.net; s=20230601; t=1741868411; x=1742473211;
 h=content-transfer-encoding:in-reply-to:content-language:references
 :to:from:subject:user-agent:mime-version:date:message-id
 :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to;
 bh=Z26J/ztKMeNnd0e6WHn9ci/aQdrhVNq6/g6rj4/fukI=;
 b=LX5uhyxBEANkVxAqpW9tEnlDeX41xcx0VsOKuYn5cECEmQqNlOF02uNCxD6pUn+kCh
 m2KXbNg4ZBWhGjBaPOcibHGd5ozTj5E+rLcOX8F3OrFcp48YPSZXK/+Wq/wj9cnt41OH
 Lyt973mZuLadQvsfcXIoiVVxbyrAVnVmDIK0/rMKXqW8+2boQRiA2tG0uvO2kAazIPKI
 MRsOsQ43VtoOGBRyeRXoOVrUL8higdqCdk4wSTzwQ1i/V8BqIRc1RvRdE82Fgvc2bnbE
 IztQjpfj5CYAWLJDN+1a76mImXBicV/i8F/EgN+qmpxr+QDsmwGtiDuHv8bHi+w1sv5Q
 OYaw==
X-Gm-Message-State: AOJu0Yy4hR8Y/1fRFGORAqU87xffkKWutTRQGhDsPKGpqo65pzWbgN6w
 IzX6fBxm83I81Jpb/kSk44WBQWHtUdDzxSa/81PCgdL/WK3nCrd2aTm58w==
X-Gm-Gg: ASbGncsWp0HBeFG0eaeRVA4A5L1LV3KY5faM1iP4Z6utzp/lYd6u3P3cA788XzVskph
 bU2qL48BvHrMaTc6rjmt3WOHEGqLocqbar9BoSRQ2cq1DGZJyIlyZ69wso8DeTxz+Jmxpw8V3gk
 kHamsDJvecyucm9Q1x5CNqG9CVWXYxJyFtEhcyt9L1072n156p4Wk+UOU1q1y0XVdxKUmCnhqsC
 2Eb0V6+PzihYYpDDIgswD6q/qYExv5Hwz6ZbquiwJZDRmmys+X1vbE/EPb6R1gQ/dfgJhsQKafd
 oSfhS+wR3W3EVvFsvPCJ0f5/Jr0hF4YeueNbIQmQHyBpMjmbGEJ4DoIggUzBzhtdLbb7iFki1sc
 tzWewsjPOt7w3Iypvy3ANPTs=
X-Google-Smtp-Source: AGHT+IFDcy6zD3Il6FdBaPYyJSeZpcg+426LaiPH8MpJqiqFRvrEW9z1KV+yFDfvTFh1tMWFDAwWRw==
X-Received: by 2002:a05:600c:1c05:b0:43b:b756:f0a9 with SMTP id
 5b1f17b1804b1-43d01bdbea9mr129672885e9.11.1741868410540; 
 Thu, 13 Mar 2025 05:20:10 -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
 5b1f17b1804b1-43d188b0cc7sm19165035e9.3.2025.03.13.05.20.08
 for <ffmpeg-devel@ffmpeg.org>
 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128);
 Thu, 13 Mar 2025 05:20:09 -0700 (PDT)
Message-ID: <3cc63322-2419-4439-8de7-3e49a54dbcb8@gmail.com>
Date: Thu, 13 Mar 2025 13:20:08 +0100
MIME-Version: 1.0
User-Agent: Mozilla Thunderbird
From: Leandro Santiago <leandrosansilva@gmail.com>
To: ffmpeg-devel@ffmpeg.org
References: <6bef7ee3-6e0b-496a-9018-ce02d5e8cd63@gmail.com>
Content-Language: en-US
In-Reply-To: <6bef7ee3-6e0b-496a-9018-ce02d5e8cd63@gmail.com>
Subject: Re: [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/3cc63322-2419-4439-8de7-3e49a54dbcb8@gmail.com/>
List-Archive: <https://master.gitmailbox.com/ffmpegdev/>
List-Post: <mailto:ffmpegdev@gitmailbox.com>

This is a follow-up to the my previous message:

https://ffmpeg.org/pipermail/ffmpeg-devel/2025-March/340895.html

On 3/13/25 13:18, Leandro Santiago wrote:
> 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"
>  
>  
_______________________________________________
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".