Skip to content

media sdk video source filter

Andre Lafleur edited this page Oct 8, 2026 · 7 revisions

About VideoSourceFilter

VideoSourceFilter is a headless playback component that delivers decoded video frames to your code instead of rendering them to a control. It exposes the same playback members as MediaPlayer (live, archive, seek, pause, capabilities, statistics) and adds the FrameDecoded event for frame-level access.

AudioVideoSourceFilter inherits from VideoSourceFilter and adds AudioDataPlayed for synchronized PCM audio. Use it when the workflow needs both decoded video and decoded audio aligned to the same stream.

VideoSourceFilter requires a Platform SDK Engine that is logged on to a Directory before you call Initialize. The Security Center license must include the Media SDK option; Initialize fails when it does not.

How frame delivery works

VideoSourceFilter opens a streaming session like MediaPlayer and decodes incoming frames in the background. For each decoded video frame, it raises FrameDecoded with a FrameDecodedEventArgs that carries the decoded buffer.

FrameDecodedEventArgs and the DecodedFrameContent it carries are tied to native buffers that the SDK owns. Your handler must dispose the event argument before returning. Calling Data, Y, U, V, Width, Height, or DataSize after disposal throws ObjectDisposedException. An IntPtr value read from Y, U, or V, or a Bitmap obtained from GetBitmap(), before disposal is different: the exception does not retroactively invalidate it. The native memory it points to can be freed or handed to a later frame, so using that captured value after disposal silently reads the wrong data. Copy what you need before disposing.

FrameDecoded can be raised many times per second. Slow handlers create back-pressure on decoding; copy what you need, enqueue work to a processing pipeline, and dispose the event payload before returning.

VideoSourceFilter

using Genetec.Sdk.Media;

VideoSourceFilter filter = new VideoSourceFilter();
filter.ForceYUVOutput = true;
filter.FrameDecoded += OnFrameDecoded;

filter.Initialize(engine, cameraGuid);
filter.PlayLive();

The constructor has an overload that accepts a WPF Panel for hardware-decoder workflows that require a video container.

Set ForceYUVOutput before Initialize. Once initialized, output format choices are fixed.

Handling FrameDecoded

private static void OnFrameDecoded(
    object sender,
    FrameDecodedEventArgs e)
{
    using (e)
    {
        if (e.IsBlocked || e.DecodedFrameContent == null)
        {
            return;
        }

        DecodedFrameContent frame = e.DecodedFrameContent;

        using RgbDecodedFrame rgbFrame = frame.GetBitmap();
        if (rgbFrame?.Bitmap == null)
        {
            return;
        }

        ProcessBitmap(rgbFrame.Bitmap, e.FrameTime);
    }
}
FrameDecodedEventArgs member Description
IsBlocked true when the frame is blocked by Security Center camera blocking. DecodedFrameContent is null in this case. Treat blocking as an access decision, not a missing frame.
IsKeyFrame true when this is a key frame. Use to align processing to key-frame boundaries (encoding, segment start).
FrameTime UTC timestamp of the decoded frame.
DecodedFrameContent The decoded frame buffer. Disposed when the event argument is disposed.

DecodedFrameContent

One decoded video frame. Implements IDisposable; disposal is driven by the parent FrameDecodedEventArgs.

Member Description
Format DecodedFrameFormat value: Rgb32, Nv12, Yuv420, Yuv422, or Unknown. Treat as read-only.
Width, Height Decoded picture dimensions in pixels.
Data, DataSize Raw decoded bytes and size. Format-dependent layout.
Rgb32Stride RGB32 row width in pixels. Multiply by 4 to get the stride in bytes. Valid when Format is Rgb32.
Y, U, V YUV plane pointers (IntPtr). Valid when Format is Yuv420, Yuv422, or Nv12.
StrideY Number of bytes between consecutive Y rows. For Nv12, also use this value between consecutive rows of the interleaved UV plane.
StrideUV Number of bytes between consecutive U rows or V rows for Yuv420 and Yuv422. For Nv12, use StrideY.
IsDisposed Defensive check before reading buffers. The parent event argument controls actual lifetime.
GetBitmap() Convert to an RgbDecodedFrame regardless of format. Returns null when the format is Unknown or unsupported.
GetBitmapFromRgbRawData() Get an RGB frame when Format is Rgb32 only.
GetRgbFrameFromYuvFrame() Get an RGB frame from Nv12, Yuv420, or Yuv422.

RgbDecodedFrame wraps a System.Drawing.Bitmap and implements IDisposable. Dispose it independently from the event argument; both must be disposed.

AudioVideoSourceFilter

AudioVideoSourceFilter inherits everything from VideoSourceFilter and adds AudioDataPlayed for decoded audio. Set IsAudioEnabled before Initialize.

AudioVideoSourceFilter avFilter = new AudioVideoSourceFilter();
avFilter.IsAudioEnabled = true;
avFilter.FrameDecoded += OnFrameDecoded;
avFilter.AudioDataPlayed += OnAudioDataPlayed;

avFilter.Initialize(engine, cameraGuid);
avFilter.PlayLive();

AudioFrameDecodedEventArgs and the DecodedAudioFrameContent it carries follow the same disposal rule as the video event argument.

private static void OnAudioDataPlayed(
    object sender,
    AudioFrameDecodedEventArgs e)
{
    using (e)
    {
        DecodedAudioFrameContent audio = e.DecodedAudioFrameContent;

        ProcessPcmAudio(
            audio.Data,
            audio.DataOffset,
            audio.DataSize,
            e.FrameTime);
    }
}

DecodedAudioFrameContent exposes PCM audio bytes through Data, DataOffset, and DataSize.

Live and archive playback

VideoSourceFilter and AudioVideoSourceFilter use the same playback commands as MediaPlayer: PlayLive, PlayArchive(DateTime), Pause, ResumePlaying, Seek(DateTime), Rewind, Stop. Use UTC for all time values, the same way you would with MediaPlayer.

For archive processing, decide on the time window and cancellation strategy before starting playback. Live playback runs until you call Stop or dispose the filter.

Capabilities and state

The filters expose FeatureCapabilities, EventCapabilities, StatisticsCapabilities, PlayerStateChanged, StreamingConnectionStatusChanged, and the same cache/buffering members as MediaPlayer. Use them to drive UI state, enable or disable optional behavior, and show stream issues. Capability flags reflect the current stream connection; before a stream connects, they are empty.

AllowSharedPlayback

The filters inherit AllowSharedPlayback from PublicMediaPlayerProxy (their abstract base). Default is false: the filter does not share its local playback cache with other source-filter components.

Set AllowSharedPlayback = true before Initialize when multiple source filters target the same camera in the same process and should share the playback cache. Changing the property after Initialize throws.

MediaPlayer does not expose AllowSharedPlayback; this property is specific to source-filter components.

Lifetime rules

These rules apply to every frame handler. Re-accessing a disposed DecodedFrameContent throws ObjectDisposedException. An IntPtr or Bitmap obtained before disposal is not invalidated by that exception; using it afterward can silently read stale or reused memory.

  • Dispose FrameDecodedEventArgs (or AudioFrameDecodedEventArgs) before the handler returns. Use using (e) so disposal happens even on exceptions.
  • Do not store DecodedFrameContent, DecodedAudioFrameContent, RgbDecodedFrame, or the event argument beyond the handler. Copy data into application-owned buffers if a later thread needs to process it.
  • Dispose RgbDecodedFrame returned by GetBitmap() independently from the event argument.
  • When e.IsBlocked is true, DecodedFrameContent is null. Branch on IsBlocked before accessing frame content.
  • Stop and dispose the filter when processing ends.

See also

Platform SDK

Plugin SDK

Workspace SDK

Media SDK

Macro SDK

Web SDK

Synergis RIO

Media Gateway

Genetec Web Player

Clone this wiki locally