# NNStreamer: neural networks as GStreamer filters

> NNStreamer is a set of GStreamer plugins that lets a pipeline treat a trained model as another media filter, so that inference, tensor conversion and model composition fit into the same pipe syntax as camera capture and playback. It is LGPL-2.1 licensed, hosted by the Linux Foundation as an incubation project, and it ships on Tizen, Ubuntu, Android, Yocto and macOS.

**nnstreamer/nnstreamer** — :twisted_rightwards_arrows: Neural Network (NN) Streamer, Stream Processing Paradigm for Neural Network Apps/Devices.

- Repository: https://github.com/nnstreamer/nnstreamer
- Website: https://nnstreamer.ai
- Stars: 800 · Forks: 189
- Language: C++
- License: LGPL-2.1
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/nnstreamer-nnstreamer

## A model as a media filter

NNStreamer is a set of GStreamer plugins that allow Gstreamer developers to adopt neural network models easily and efficiently and neural network developers to manage neural network pipelines and their filters easily and efficiently. The one line summary in the repository is Neural Network Support as Gstreamer Plugins.

That framing is the whole idea, and it is easier to grasp as a change of vocabulary than as a feature. In GStreamer, a pipeline is a graph of elements connected by pads: a source element produces buffers, filter elements transform them, a sink consumes them. NNStreamer adds elements that take a tensor stream and run inference on it, so a model stops being a separate subsystem you call from application code and becomes a box in the pipe, wired to the source and the sink like any other.

For a GStreamer developer, the payoff is that everything they already know applies. The model is a filter, so it takes a stream in and produces a stream out, and it sits in the same pipe as the camera, the encoder and the display. For a neural network developer, the payoff is that the plumbing around the model, the frame conversion, the tensor formats and the buffering, is handled by a framework designed for it rather than hand written.

The objectives section spells out the consequences. Provide neural network framework connectivities, with tensorflow and caffe given as examples, so that an efficient stream pipeline can be applied to neural networks. Use a neural network model as a media filter or converter. Support composite models, meaning multiple neural network models in a single stream pipeline instance. And support multi modal intelligence, with multiple sources and stream paths for models.

The stated method is to provide easy methods to construct media streams with neural network models using the de-facto-standard media stream framework, GStreamer. The summary of who benefits is exactly as you would expect: Gstreamer users use neural network models as if they are yet another media filter, and neural network developers manage media streams easily and efficiently.

## What the plugin set is made of

The README points to a component description page that categorises the nnstreamer components into three groups, and the shape of the repository matches.

There is the gst directory, which holds the GStreamer elements themselves, the plugins. There is ext, which is where the framework integrations live, the connectivities to tensorflow, caffe and the other backends. There is jni, the Java native interface layer that lets the Android build reach the C implementation, since the Android entry point is Java. There is a tests directory and a tools directory, plus the packaging directories: debian for the Debian and Ubuntu packages, and packaging for the other targets.

The build is Meson. There is a meson.build at the root with a meson_options.txt alongside, and the pkg-config templates come in three flavours, nnstreamer.pc.in, nnstreamer-single.pc.in and nnstreamer-internal.pc.in, which tells you that the project is consumable three different ways by a C build. The ext directory is a separate build, because a GStreamer plugin that pulls in TensorFlow has a very different dependency set from a core element, and a system package manager would not accept one package with both sets of requirements.

There is also a .clang-format file, which is what you would expect in a C++ project with a large contributor base, and an AGENTS.md and a CLAUDE.md at the root, which are the newer conventions for instructing coding assistants working in a repository.

The component description is worth calling out because the README is candid about its state. It says this project has just started and that many of the components are in design phase. That is a strange sentence to find in a project with a decade of releases, and the honest reading is that the core pipeline and the mainstream backends are settled while the wider component catalogue is still growing.

## Where NNStreamer runs and what that means for you

The official releases table is the most useful part of the README, because the support matrix is genuinely uneven and knowing it up front saves an afternoon.

Tizen is the strongest target, with versions 5.5M2 and later, and the API is offered in C and C# as official. Ubuntu support runs through a PPA with 18.04, 20.04 and 22.04 listed as available, 16.04 struck through, and the API in C. Android is at version 13 with a Java API. Yocto has a Kirkstone layer with a C API. macOS has a Brew Tap with a C API and a documentation page for getting started.

The table also distinguishes two build states, and the legend matters. Ready means the CI system ensures build-ability and unit-testing and users may easily build and execute, but there is no automated release and deployment system for that instance. Available means binary packages are released and deployed automatically and periodically along with the CI tests. Most of the arm and arm64 Linux and Tizen entries are Ready, while the x64 entries and the Android and Yocto rows are marked Available, which tells you the release automation exists for most targets but is patchy in a few places.

The architecture coverage follows the same pattern. armv7l, aarch64 and x86_64 are all covered on Tizen, and the Android, Yocto and Ubuntu builds cover arm, arm64 and x64 to varying degrees. macOS is x64 only in the table, with no arm64 row, which on a modern Apple machine is a detail to confirm rather than assume.

The packaging entry points are named: a Tizen repo, a PPA for Ubuntu, a daily build for Android, a Yocto layer, and a Brew Tap for macOS. The daily build site is also where the CI logs are published per architecture, which is a useful thing to look at when you are evaluating whether a target is genuinely maintained.

## Getting started, and where the documentation lives

The README keeps the getting started section deliberately short and sends you to the manuals.

For Linux-like systems such as Tizen, Debian and Ubuntu, there is a getting started manual in the Documentation directory, and there is a separate page for macOS. A per distribution page lists the enabled features of the official releases, which is the file to read before you design a pipeline: a filter that is not enabled in your distribution's build is a filter you do not have, and the feature matrix varies by target.

For SDK users there is more. Tizen Studio from 5.5 M2 onward is supported, and for Android Studio the SDK is the nnstreamer.aar file from the daily release. The API language differs by platform, C and C# on Tizen, C on Ubuntu, Java on Android, C on Yocto and C on macOS.

The project is a Linux Foundation incubation project, and the badge is in the README title, which is a signal about governance rather than about code. The CII Best Practices badge and the Coverity Scan defect badge sit next to it, and the daily build badge plus a code coverage badge are there too. The CII badge is the one worth noting, because it certifies that the project follows a documented set of development practices across releases, and the release history in the repository shows a long-term-stable line with named maintenance releases.

The academic record is also part of the repository. There is a technical report on arXiv, papers at IEEE/ACM ICSE 2021 and 2022, and a GStreamer Conference 2018 talk with slides, plus a Naver Tech Talk and a Samsung Developer Conference appearance. For a project that has existed this long, that publication trail is a reasonable substitute for a marketing page.

## The trade-offs of putting inference in the pipe

The first limitation is that the plugin model only pays off if you already have GStreamer in your stack. A service written in Python that loads a model and calls it from a request handler has no use for a media pipeline, and adopting NNStreamer there means rewriting your architecture around a framework whose main strength is media transport. The GStreamer users who benefit are those who wanted a model to be a filter and were previously writing custom elements to do it.

The second is that a plugin's capability is bounded by its backend, and the backends differ by distribution. The objective is framework connectivity for tensorflow and caffe, but which of those are compiled into your distribution's package is a per-target question, and the feature matrix answers it per distribution. Building from source gives you more of them, and costs you the packaging work.

The third is that inference inside a streaming pipeline has different engineering characteristics from inference in a request path. A model filter adds latency inside a pipeline that has its own latency budget, and the pipeline will apply backpressure when the model is slower than the source, which is usually the correct behaviour but changes how you reason about throughput. Buffers flowing between elements are also a memory concern when a model emits large tensors.

The fourth is the maturity of the component catalogue. The README says many components are still in design phase, so the set of filters you can rely on is smaller than the set the project aspires to, and the extension work may land in a later release than your deadline.

The alternative approaches differ in what they cost you. A direct inference call from application code is the simplest and gives you the most control, and it duplicates the plumbing that NNStreamer exists to provide. A dedicated inference service reached over HTTP keeps the model out of the media path and is easy to scale independently, at the cost of a network hop per frame. And a different plugin architecture, with a filter for the same job, would still be a media framework underneath; the difference is which one, not whether.

The honest summary is that NNStreamer is a strong answer to a specific question, namely how to put a model into an existing GStreamer graph, and a poor answer to the general question of how to run inference.

## Conclusion

Adopt NNStreamer if your team already builds media pipelines in GStreamer and needs a trained model to sit inside one, especially on Tizen or Android where on-device inference matters. Do not adopt it if your application is a plain Python or C service with no existing GStreamer infrastructure, since the plugin model adds a lot of surface for no benefit. Verify first which inference backends your distribution build actually ships, since the framework connectivity depends on the platform package, and check the enabled features list for your distribution before you plan a pipeline around a specific filter.

## FAQ

### What is NNStreamer?

It is a set of GStreamer plugins that provide neural network support as GStreamer elements, so a trained model can be used as a media filter inside a normal stream pipeline. The repository describes it as a stream processing paradigm for neural network applications and devices.

### Which platforms does NNStreamer ship on?

Tizen from 5.5M2 onward with C and C# APIs, Ubuntu through a PPA with a C API, Android 13 with a Java API, a Yocto layer named Kirkstone with a C API, and a macOS Brew Tap with a C API. The README table also marks each target as Ready, meaning CI verified but without an automated release, or Available, meaning packages are released automatically.

### Which neural network frameworks does NNStreamer connect to?

The objectives list tensorflow and caffe as the example framework connectivities, provided through the plugins so that a model can be used as a media filter or converter inside a GStreamer pipeline.

### How do I start using NNStreamer?

The README sends you to the manuals in the Documentation directory, with a getting started page for Linux-like systems such as Tizen, Debian and Ubuntu and a separate macOS page. There is also a per distribution page listing the enabled features of the official releases, which is the file to check before designing a pipeline.

### What license is NNStreamer released under?

LGPL-2.1, with the LICENSE file at the repository root. The project is a Linux Foundation incubation project, with MyungJoo Ham listed as the maintainer.

## Sources

- [License: LGPL-2.1](https://github.com/nnstreamer/nnstreamer/blob/main/LICENSE)
- [nnstreamer/nnstreamer on GitHub](https://github.com/nnstreamer/nnstreamer)
- [Project website](https://nnstreamer.ai)
- [README](https://github.com/nnstreamer/nnstreamer/blob/main/README.md)
- [Releases](https://github.com/nnstreamer/nnstreamer/releases)

---

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