# frei0r: a shared plugin standard for free video effects

> frei0r is a GPL-2.0 collection of more than a hundred free video effect plugins built on a deliberately thin C and C++ header, used by hosts such as GStreamer, MLT, Shotcut, FFmpeg and Pure Data. It is a plugin standard rather than a framework, and the header is the specification.

**dyne/frei0r** — A large collection of free and portable video plugins

- Repository: https://github.com/dyne/frei0r
- Website: https://dyne.org/frei0r/
- Stars: 595 · Forks: 116
- Language: C
- License: GPL-2.0
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/dyne-frei0r

## A common standard so one effect works in many hosts

frei0r is a collection of free and open source video effects plugins that can be used with a variety of video editing and processing software. The collection consists of more than 100 plugins made to work on any target platform, GNU/Linux, Apple/OSX and MS/Win, without the need for special video hardware, and the effects cover the usual ground of colour correction, blurring and distortion.

The idea underneath the collection is an interface agreement. The project describes itself as the result of a collective effort in coordination with several software developers meeting to find a common standard for video effect plugins to be used among their applications. An effect written once against that standard can then be loaded by any host that speaks it.

The list of hosts is the evidence that the standard took. MLT, LiquidSoap, KDenLive, Shotcut, FFmpeg, Pure Data, Open Movie Editor, Gephex, LiVES, FreeJ, VeeJay and Flowblade are all named as applications using frei0r, sorted by most recent activity. For a plugin author that list is the difference between writing one effect and writing a dozen ports, and for a host maintainer it is a catalogue of effects that arrived for free.

The project also positions itself as a resource for anyone interested in the algorithms for video transformation, pointing at the open source formulas as something that can be read, adapted and integrated into other software. That is a different value from the plugin distribution itself, and for a researcher or a student it is often the more useful half.

## The API is one header and a frame in, a frame out

The project is unusually explicit about what it is not. Frei0r itself is just a C/C++ header and a collection of small programs using it to accept an input frame, change it in any possible way and return an output frame. It is not meant as a generic API for all kinds of video applications, as it does not provide things like an extensive parameter mechanism or event handling.

That single paragraph is the whole design brief, and it explains the rest of the project. There is one header, `include/frei0r.h`, and the documentation says that header is the API specification, with a generated API reference browsable online. A plugin is a small program that gets an input frame, transforms it and returns an output frame. Nothing else is required of it, and nothing else is offered.

The consequence is that frei0r is a lowest common denominator by construction. A host that wants rich parameter handling, or events, or anything beyond frame transformation, has to build that itself. The project anticipates this and describes the intended arrangement: the frei0r API can be wrapped by higher level APIs expanding its functionalities, and GStreamer, MLT, FFmpeg and Pure Data do exactly that.

For a plugin author, that is a workable deal. You write a small, portable, self-contained effect with no dependency beyond a C compiler, and you get it into a dozen applications. For a host author, it is a deal with a hard limit: you can offer a hundred effects, and every one of them will look and behave like the simplest effect you can imagine, because the interface has nowhere to put a curve editor.

## Writing a filter against the header

The C++ example in the README is the shortest useful description of the plugin model, and a tutorial filter ships in the source tree at `src/filter/tutorial`.

The geometry of a frame is a plain struct, and the comment in the example makes the pixel format assumption explicit:

```c++
  typedef struct {
    int16_t w, h;
    uint8_t bpp;
    uint32_t size;
  } ScreenGeometry;
```

The filter itself derives from `frei0r::filter`, and the interface is two virtual methods, `update()` for the work and a private `_init` for setup:

```c++
  class MyExample: public frei0r::filter {
  public:
    MyExample(int wdt, int hgt);
    ~MyExample();
    virtual void update();
  private:
    ScreenGeometry geo;
    void _init(int wdt, int hgt);
  }
```

The registration at the end is what makes the plugin visible to a host, and it is where the metadata lives:

```c++
  frei0r::construct<MyExample>
          plugin("MyExample", "short and simple description for my example",
                 "Who did it", 1, 0);
```

The name, the description and the author go in the registration, along with two version numbers, and the instance carries the frame size and pixel format into `_init`, where the example sets `geo.bpp = 32` with the comment that this filter works only in RGBA 32bit, and computes the byte size from width, height and bytes per pixel.

The `update()` method is where the transformation happens, and the example shows the data flow precisely: the input arrives as a `void*` buffer that is cast to `uint32_t*`, the output buffer is cast the same way, and a `memcpy` copies one to the other. The comments name the two buffer pointers and note that the example does just a copy of input to output. Any real effect replaces that copy with its own arithmetic, and nothing else about the shape of the plugin changes.

## Building and testing with CMake and ctest

The project builds with CMake and tests with ctest, and the quick build sequence is short enough to be worth quoting exactly:

```sh
cmake -S . -B build -G Ninja
cmake --build build
ctest --test-dir build --output-on-failure
```

The three commands configure with Ninja, build, and run the test suite with failure output enabled. The build details are in the `BUILD.md` file at the repository root, and the project notes that frei0r can be built on GNU/Linux, M$/Windows and Apple/OSX platforms, possibly in even more environments such as embedded devices.

There is a second build step that is worth knowing about, because it is what makes a plugin discoverable by a host. The metadata scanner binary is `build/test/frei0r-meta`, previously called `frei0r-info`, and metadata for every built plugin is generated with the CMake target:

```sh
cmake --build build --target generate-metadata
```

The repository layout supports all of this: a `CMakeLists.txt` at the root, a `CMakePresets.json` for editor and CI configuration, a `cmake/` directory for the build modules, `include/` for the public header, `src/` for the plugins, `test/` and `tests/` for the test suites, and `examples/browser-demo/` for a browser demo. There is also a `frei0r.pc.in` file, which is the template for the pkg-config metadata, a `DESIGN.md`, a `msvc/` directory for the Windows build, and an `AGENTS.md`.

The `generate-metadata` step is a detail that bites people. The scanner reads the plugin binaries and produces the metadata a host uses to list what is available, so a plugin that builds but is not scanned is a plugin the host never sees.

## Packaging for Linux, macOS, Windows and the BSDs

The project distributes in several ways, and the differences between them matter when you decide which artefact to depend on.

Stable releases are built by a manually triggered release workflow and made available on the project's GitHub releases page. That is the source of truth for a version, and the source of the official Windows builds, which are distributed as .dll files for the Win64 platform from the same page, and of the official macOS release artifacts. For macOS there is also a Brew formula.

For the BSDs, ports of frei0r are included in all the major BSD distributions, with FreeBSD, OpenBSD and NetBSD through pkgsrc named in the README. On GNU/Linux, binary packages are maintained on various distributions, but the README warns that they may not be completely up to date with the latest release, and a repology badge is used to track the packaging status across repositories.

That warning is the practical point. A distribution package of frei0r can be several releases behind, and for a plugin collection the interesting effects often arrive in the newest version. A project that needs a specific plugin can end up with a distribution package that does not contain it, which is the usual reason to build from source instead.

The licence is the GNU General Public License and, eventually, other compatible Free Software licences. The source is released under those terms, and the `COPYING` file at the repository root carries it, with `AUTHORS.md` and a `ChangeLog` alongside it for the project history.

The documentation for a new user starts at the project documentation site, and the generated API reference is browsable online for anyone who wants to browse the symbols rather than read the header.

## What the collection is not, and who should use it

The clearest way to describe frei0r is as a plugin standard with a catalogue attached, and everything in the project follows from that. The header is the specification, the plugins are small portable programs, and the applications that consume them add the parameter handling and eventing that frei0r deliberately leaves out.

That makes it the right tool for a particular kind of effect. A filter that maps pixels to pixels, works on any frame size, needs no special hardware and wants to exist in a dozen editors at once, is a good frei0r citizen. The colour correction, blur and distortion categories in the collection are exactly that kind of effect.

It is the wrong tool when the effect needs a user interface. There is no extensive parameter mechanism, so a plugin has limited means to expose a curve, a slider or a dropdown to the host, and a host that wants to present controls has to build that layer itself around a plugin that has nothing to say. A generative or timeline-aware effect, or one that needs to know about the clip it is working on rather than just the frame, is out of scope for the interface as it stands.

It is also the wrong tool for a team that needs a permissive licence. The GPL and compatible free software terms mean a plugin that ships inside a proprietary application has obligations that a permissive licence would not, and a project with a commercial plugin in its catalogue needs to think about that before it starts.

On upkeep, the repository is not archived, the last push was on 2026-10-06, and the release cadence is quick: v3.6.0 on 2026-09-27, v3.5.0 on 2026-08-26 and v3.4.0 on 2026-08-19. For a plugin author, contributing means opening a pull request, with the issue tracker for bugs, the Telegram chat for day to day discussion, and an older mailing list that is still open to subscription and has public archives.

## Conclusion

frei0r suits a developer writing a video effect who wants one implementation to run in several hosts, or a host maintainer who wants a catalogue of free effects without maintaining them, and it is the right choice for effects that need no special video hardware. It does not suit a project that needs a rich parameter system, event handling or a general video API, since the project states plainly that frei0r does not provide those, and it does not suit a team unwilling to accept the GPL terms. Before writing a plugin, read include/frei0r.h, which is the API specification, and build the collection with the CMake and ctest commands the project documents so your effect can be tested against the existing suite.

## FAQ

### What is frei0r and what does the API actually provide?

It is a collection of more than 100 free video effect plugins built on a single C/C++ header. The API is a program that accepts an input frame, changes it and returns an output frame, and the project states plainly that it does not provide an extensive parameter mechanism or event handling.

### Which applications use frei0r plugins?

The README lists MLT, LiquidSoap, KDenLive, Shotcut, FFmpeg, Pure Data, Open Movie Editor, Gephex, LiVES, FreeJ, VeeJay and Flowblade, sorted by most recent activity. GStreamer, MLT, FFmpeg and Pure Data are also named as higher level APIs that wrap and extend the frei0r interface.

### How do I build frei0r and run its tests?

Configure with `cmake -S . -B build -G Ninja`, build with `cmake --build build`, and run the suite with `ctest --test-dir build --output-on-failure`. Further build details are in the BUILD.md file at the repository root.

### What is the frei0r meta scanner for?

The scanner binary is `build/test/frei0r-meta`, previously `frei0r-info`, and it generates metadata for every built plugin. You run it with the CMake target `cmake --build build --target generate-metadata`, and the metadata is what a host uses to list the available effects.

### How do I get frei0r on my system?

Stable releases are on the GitHub releases page, official Windows builds are distributed as Win64 .dll files and official macOS artifacts are released the same way, with a Brew formula also available. Ports exist for FreeBSD, OpenBSD and NetBSD, and Linux distribution packages are maintained but may lag behind the latest release.

## Sources

- [dyne/frei0r on GitHub](https://github.com/dyne/frei0r)
- [License: GPL-2.0](https://github.com/dyne/frei0r/blob/master/LICENSE)
- [Project website](https://dyne.org/frei0r/)
- [README](https://github.com/dyne/frei0r/blob/master/README.md)
- [Releases](https://github.com/dyne/frei0r/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/dyne-frei0r
