I've applied a few changes from your feedback, the following is how the feature looks like. ***Disclaimer*** this is still a proof of concept and for now I am looking for your feedback and help. There are lots of rough corners and stuff that does not work. I by no means intend to request the changes as they are to be merged. Call it an RFC if you will. Also, I am not sending the patch as an attachment, and leave the e-mail body for discussion only. I am not sure whether this is a good approach or goes against the mailing list policy. This is the time I wish we could really contribute using the Pull Request more on a nice web interface. If you folks want to experiment, I pushed my changes in this PR: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/13 ***Finish disclaimer*** I changed the name convention from "extra filters" to "external filters", as it sounds more natural. (Another possibility would be "extension filters", so please let me know what you think). The build system will automatically pick up any filters in the subdirectory `ext/libavfilter`, and ignore it if it does not exist. The rationale behind this directory structure is to reserve the possibility of extensions of other libraries as well. An external filter is composed by at least one Makefile, and this Makefile has some "metadata" encoded in its comments, used by the `./configure` script to generate some code. I'll show how they look like in an example. Although this way to encode metadata looks very ugly and I am pretty sure can be improved, this is the best I could for now, and I hope you folks can point me directions on how to improve it, as you have more knowledge of the build system than I do. Here are the metadata types: - check: this is a command used to check if 3rd party dependencies are available and enabling them within the build system. The command here is executed by `./configure`. This entry is optional and for now there can be only one of them, due to technical limitations of my implementation. - symbol: this entry can appear multiple times, and indicates the name of the FFFilter objects exported by the filter. There must be one entry per exported symbol. These entries are used by `./configure` to generate the list of enabled filters. - ldflags: those are extra LDFLAGS to be used to link libavfilter. I am not happy this this one at all, as such information ideally should be encoded as Makefile variables, but I confess I could not manage to do it. I'd be happy to get directions on where in the build system to look for the right "hook", but I'll continue looking for it as well. As an example, here is how one can create an empty filter. Just to exercise the build system, the example filter depends on an external library, json-c, which is found using pkg-config and will be dynamically linked to libavfilter. In case json-c is not found, `./configure` will fail, as expected. ``` mkdir -p ext/libavfilter/example ``` Then create the a file ext/libavfilter/example/Makefile with the content: ``` # check: require_pkg_config json json-c json-c/json.h json_c_version_num # symbol: ff_vf_example # ldflags: -ljson-c OBJS += vf_example.o CFLAGS += -DFOO=1234 libavfilter/vf_example.o: $(CC) $(EXTERNAL_FILTER_FLAGS) $(CPPFLAGS) $(CFLAGS) -c -o $@ $(EXTERNAL_FILTER_EXAMPLE_LOCATION)/vf_example.c ``` Then, create the file ext/libavfilter/example/Makefile/vf_example.c with the content: ``` #include "libavutil/internal.h" #include "avfilter.h" #include "filters.h" #include "video.h" #include <json.h> static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, char *res, int res_len, int flags) { // NOTE: I know this makes no sense, I just wanted to use some symbol from json-c // in a way the compiler cannot optimize it out return json_c_version_num(); } const FFFilter ff_vf_example = { .p.name = "example", .p.description = NULL_IF_CONFIG_SMALL("An external example filter"), .p.flags = AVFILTER_FLAG_METADATA_ONLY, FILTER_INPUTS(ff_video_default_filterpad), FILTER_OUTPUTS(ff_video_default_filterpad), .process_command = process_command, }; ``` (You can skip this manually creating those files by checking out this example filter from gitlab: https://gitlab.com/leandrosansilva/ffmpeg-extra-filter-example) Now you can compile ffmpeg as usual, with `./configure && make && make install` and use the filter. In my tests, building ffmpeg libraries either in static and shared mode work, with the extra dependencies properly linked. Explanation: - The .o files for the external filters will be generated in the same place as the built-in filters, in libavfilter/. That means that two external filters cannot generate the same .o files. - A new variable with the format EXTERNAL_FILTER_$(FILTER_SYMBOL_IN_UPPERCASE)_LOCATION will be generated for each FFFilter exported. More explanation about that below. - The build system offers now a variable `EXTERNAL_FILTER_FLAGS` which adds the paths of the libavfilter private headers to the compiler when building the external filters. The idea here is for code for an external filter to look exactly as if it was a built-in filter: the include paths should be the same. This will make it easier for external filters to be moved as built-in and the other way around, not requiring much code changes. TODO: - Find a way to remove the `ldflags` metadata entry to turn it into a Makefile variable. - Allow multiple `check` metadata entries, to make it easier to check for multiple 3rd party dependencies. - Better error handling on malformed/invalid filter metadata. - Find a way to encode conditional builds in the metadata. I am here thinking on filters like the `dnn` family, which can have multiple backends, which are now chosen using `--enable-openvino`, `--enable-libtorch`, `--enable-libtensorflow` or the drawtext filter that has optional dependencies. Maybe the external filters could hook new `--enable-*` options to `./configure`, but this smells like trouble when multiple filters specify the same optional dependencies. - You can see in the example Makefile that a new "magical" variable named `EXTERNAL_FILTER_EXAMPLE_LOCATION` was created by the build system. It looks ugly to me, but I could not find a way to obtain the path of the current Makefile via make, and I needed a way to specify the path of the filter source files. If you know a cleaner way to do it, please let me know. - Make it possible to link filters written in other languages. My "final" goal for is Rust, but it should not prevent the use of C++ or Zig, for instance. I believe this can be done in a further iteration. For now my focus is only supporting C. - Once the implementation and "spec" is agreed, document it. - Refactor the changes in the build system to improve legibility. Regards, Leandro