Skip to content

Source Filter Spout Sink

Xaymar edited this page Mar 25, 2025 · 13 revisions

Spout/Sink (Source, Filter)

The Spout/Sink feature is a new way to clone resources (like audio, video, and textures) that enables new and exciting effects that were previously impossible. Unlike its predecessor Source Mirror it properly deduplicates resources, handles sRGB and HDR, can support recursion properly, and even has built-in delay functionality. Even raw video can now be duplicated properly, allowing for effect chains to split prior to them being turned into video textures.

It is also now possible to clone from anywhere in the filter chain due to each Spout being a filter - before, during or after is now your choice! No need to plan out complex filter chains where each branch is carefully selected, just split it whenever by adding a Spout filter in the right place.

ℹ️ Notice: As of v1.0.0 Beta 678, all Source Mirrors are automatically migrated to Spout/Sink behind the scenes, adding new filters where needed.

Version Information
Status Version
🔴Added 1.0b557
🟠Unstable 1.0b596
🟢Stable 1.0b678
⚠️Deprecated N/A
❌Removed N/A

Features

  • Audio, Video Frame, and Video Texture cloning from anywhere in the filter chain.
  • Built-in Delay option, removing the need for an additional filter on cloned resources.
  • Out of the box support for sRGB rendering and HDR color.
  • Detection and handling of recursion with automatic delay insertion to resolve the issue.
  • Resource deduplication where possible, freeing up a significant chunk of CPU and GPU time and memory for complex effect chains.

Media

YouTube

Usage

It is imperative to understand that Spout/Sink works by cloning data instead of Sources, unlike Source Mirror which cloned Sources instead. This means that when you want to clone anything, you now have explicit control over what and when is being cloned, not just that it is being cloned. That means you will need to have an understanding of the three basic data types that OBS Studio (libOBS) deals with:

  • Audio: Your basic waveform audio on the CPU side. Always has the format that libOBS decided on when started.
  • Video Frame: Raw video frames after decoding and deinterlacing, but prior to upload to the GPU, and as such allows for CPU effects to be applied. This is what Video Capture Device and Media Source generates.
  • Video Texture: GPU video frames of any kind, including the uploaded Video data from raw video frames. Generated by Game Capture, Display Capture, Window Capture, and any raw video frame source.
  • There are additional internal formats that you do not need to worry about for now.

Audio Cloning

  1. Add a Spout (Audio) to the Source you want to clone. If you have already done this in the past, you do not need an additional filter and can reuse that one.
  2. Add a Sink (Audio & Video Texture) or Sink (Audio & Video Frame) to the Scene in which you want to clone it.
  3. Check the checkbox for Video Texture Sink, then select the correct Spout
  4. Click Ok/Apply, and you're done. You can now proceed as you would with Source Mirror or Source Clone.

Video Frame Cloning

  1. Add a Spout (Video Frame) to the Source you want to clone. If you have already done this in the past, you do not need an additional filter and can reuse that one.
  2. Add a Sink (Audio & Video Frame) to the Scene in which you want to clone it.
  3. Check the checkbox for Video Frame Sink, then select the correct Spout
  4. Click Ok/Apply, and you're done. You can now proceed as you would with Source Mirror or Source Clone.

Video Texture Cloning

  1. Add a Spout (Video Texture) to the Source you want to clone. If you have already done this in the past, you do not need an additional filter and can reuse that one.
  2. Add a Sink (Audio & Video Texture) to the Scene in which you want to clone it.
  3. Check the checkbox for Video Texture Sink, then select the correct Spout.
  4. Click Ok/Apply, and you're done. You can now proceed as you would with Source Mirror or Source Clone.

Filters

Spout (Audio)

Provides Audio data via the Producer component to the Spout/Sink network.

Settings

See Producer.

Name Tokens

  • ${source}: The name of the source this filter is attached to.
  • ${filter}: The name of the filter itself.

Spout (Video Frame)

Provides Video Frame data via the Producer component to the Spout/Sink network.

Settings

See Producer.

Name Tokens

  • ${source}: The name of the source this filter is attached to.
  • ${filter}: The name of the filter itself.
  • ${width}: Width of the video data at the point of the filter.
  • ${height}: Height of the video data at the point of the filter.
  • ${base_width}: Width of the original video data.
  • ${base_height}: Height of the original video data.

Spout (Video Texture)

Provides Video Texture data via the Producer component to the Spout/Sink network.

Settings

See Producer.

Name Tokens

  • ${source}: The name of the source this filter is attached to.
  • ${filter}: The name of the filter itself.
  • ${width}: Width of the video data at the point of the filter.
  • ${height}: Height of the video data at the point of the filter.
  • ${base_width}: Width of the original video data.
  • ${base_height}: Height of the original video data.

Sources

Sink (Audio & Video Frame)

Consumes Audio and/or Video Frame data via the Consumer component from the Spout/Sink network.

Settings

Audio Sink

See Consumer.

Video Frame Sink

See Consumer.

Sink (Audio & Video Texture)

Consumes Audio and/or Video Texture data via the Consumer component from the Spout/Sink network.

  • If the Video Texture Producer has yet to render an attempt will be made at forcing it to render, which may incur a tiny performance penalty similar to that of Source Mirror. This penalty can be avoided by ensuring the last filter in the filter chain is also a Spout.
  • Due to buggy code in built-in and third-party filters we had to limit the minimum size of this to 1x1 even though it is technically legal to have a size of 0x0.

Settings

Audio Sink

See Consumer.

Video Texture Sink

See Consumer.

Components

Spout Producer

Producers produce data to be consumed by a consumer.

Settings

Identifier

The unique identifier assigned to the Producer which may be identical to the UUID of the filter that contains this component. It is used to identify which Producer is being used by which Consumer, and is guaranteed to be locally unique within the scene collection.

Name

The human readable name that should be shown to the user in selection lists. It supports token replacements based on tokens provided to it by the feature that uses it in addition to the built in tokens.

Name Tokens

  • ${uuid}: The unique identifier this Producer has.
  • ${samplerate}: (Audio only) What sample rate does the audio data have? Always identical to the one provided by libOBS.
  • ${layout}: (Audio only) What channel layout does the audio data have? Always identical to the one provided by libOBS.

Sink Consumer

Consumers consume a specific type of data produced by a producer.

Settings

Spout

Which Producer should be cloned to here? This will only list producers with matching type.

Delay

How delayed should the cloned resource be? The accuracy of this is tied to the system clock resolution, which in most streaming cases will either be 1ms or 500µs.

Frequently Asked Questions

Why was Source Mirror replaced with Spout/Sink?

It is true that Source Mirror was a great system that was easy to use, but that ease-of-use brought with it many hidden issues. It was not possible to clone Scenes or Groups properly, you would always clone with all filters being rendered, audio cloning was barely functional with no possible stable fix. So a replacement needed to be made that could do what Source Mirror did with less issues while also being more versatile to enable even more complex effects.

The hell is a libOBS? I use OBS Studio!

libOBS is the library that all plugins and frontends use, including OBS Studio. It defines what is and isn't possible within the box that is OBS and is as such a critical part of every plugin. It's why plugins can't support all versions of OBS Studio, as the API we interface with changes over time to improve on problematic things.

Why do I need to know about data types?

While you don't need to know everything about them, it is important to be aware of what they are. Especially the difference between Video Frames and Video Textures is important, which is unfortunately unclear in the User Interface of OBS Studio.

Clone this wiki locally