VisioForge

Last updated: January 2026

DirectShow.NET Alternative: Migration Guide to VisioForge .Net SDK

Step-by-step guide to migrate from DirectShow.NET (abandoned) to VisioForge .NET SDK for video capture, playback, and processing on .NET 6-10.

C# developers migrating from DirectShow.NET (directshowlib) to a modern .NET 6-10 video capture, playback, and processing SDK

Why Replace DirectShow.NET?

DirectShow.NET has been abandoned since February 2010 — 15+ years without updates. It provides raw COM interface definitions for Microsoft's DirectShow API, which Microsoft itself has deprecated in favor of Media Foundation.

RiskImpact
DirectShow deprecated by MicrosoftNo new features, codecs, or platform support
Library unmaintained.NET Framework 2.0, no .NET 6+ support
COM complexityHundreds of lines for basic tasks, manual memory management
Codec huntingMust find, install, and register third-party DirectShow filters
Filter graph debuggingOpaque pipeline failures, no diagnostic tools
Windows-onlyCOM/DirectShow cannot run on macOS, Linux, or mobile
No modern codecsNo native H.265, AV1, VP9 without third-party filters
Registry issuesFilter registration problems on modern Windows

DirectShow Concepts Explained

Understanding how DirectShow architecture maps to VisioForge SDKs helps you plan your migration. The table below shows how each core DirectShow concept translates to the modern .NET equivalent.

DirectShow Architecture to VisioForge Equivalents

DirectShow ConceptVisioForge Equivalent
Filter Graph (IGraphBuilder)Pipeline — managed automatically by SDK, or explicit MediaBlocksPipeline
Source Filter (device/file)Source settings: VideoCaptureDeviceSourceSettings, RTSPSourceSettings, etc.
Transform Filter (effects/encoder)Built-in video/audio effects + encoder classes (H264EncoderSettings, etc.)
Renderer Filter (video window)VideoView control (WinForms, WPF, MAUI, Avalonia)
Mux Filter (AVI/MP4 mux)Output format classes: MP4Output, AVIOutput, MKVOutput, WebMOutput
Pin connectionsAutomatic — or explicit Block.Connect() in Media Blocks SDK
Media Types (AM_MEDIA_TYPE)Handled automatically — no manual format negotiation
Filter Categories (device enumeration)DeviceEnumerator.Shared.VideoSourcesAsync() / AudioSourcesAsync()
DirectShow filter registration (regsvr32)NuGet packages — no system registration needed
GraphEdit debugging toolPipeline events, logging, typed exceptions

Which VisioForge SDK Replaces What?

DirectShow.NET Usage to VisioForge Replacement

DirectShow.NET UsageVisioForge Replacement
C# webcam capture via filter graphVideo Capture SDK .Net — `VideoCaptureCoreX`
C# IP camera capture (RTSP/MJPEG)Video Capture SDK .Net — `RTSPSourceSettings`
C# screen capture and recordingVideo Capture SDK .Net — `ScreenCaptureSourceSettings`
File playback via `IGraphBuilder`Media Player SDK .Net — `MediaPlayerCoreX`
DVD playback via `IDvdControl2`Media Player SDK .Net — DVD navigation API
TV tuner via `IAMTVTuner`Video Capture SDK .Net — `VideoCaptureCore`
File transcodingVideo Edit SDK .Net — `VideoEditCoreX`
Custom filter graphsMedia Blocks SDK .Net — modular pipeline (400+ blocks)
`ISampleGrabber` frame access`OnVideoFrameBuffer` event on any SDK

C# DirectShow Interface Mapping

C# DirectShow Interface Mapping

DirectShow.NET InterfaceVisioForge Equivalent
`IGraphBuilder`Pipeline built automatically by SDK
`ICaptureGraphBuilder2``VideoCaptureCoreX` constructor
`IMediaControl` (Run/Stop/Pause)`StartAsync()` / `StopAsync()` / `PauseAsync()`
`IMediaEvent`SDK events (`OnError`, `OnStop`, etc.)
`IVideoWindow``VideoView` control (WinForms/WPF/MAUI/Avalonia)
`ISampleGrabber``OnVideoFrameBuffer` event
`IBaseFilter`Not needed — SDK manages filters internally
`IPin` / pin connectionsNot needed — SDK connects pipeline automatically
`DsDevice.GetDevicesOfCat()``DeviceEnumerator.Shared.VideoSourcesAsync()`
`FilterCategory.VideoInputDevice``DeviceEnumerator.Shared.VideoSourcesAsync()`
`FilterCategory.AudioInputDevice``DeviceEnumerator.Shared.AudioSourcesAsync()`
`IAMTVTuner``VideoCaptureCore.TVTuner` property
`IDvdControl2``MediaPlayerCore.DVD_*` methods
`Marshal.ReleaseComObject()``await sdk.DisposeAsync()`

C# Webcam Capture with Preview

DirectShow.NET — webcam capture (before)

C#
// 80+ lines of COM interop
var graphBuilder = (IGraphBuilder)new FilterGraph();
var captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
int hr = captureGraph.SetFiltergraph(graphBuilder);
DsError.ThrowExceptionForHR(hr);

// Find video device
var devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
IBaseFilter sourceFilter;
hr = graphBuilder.AddSourceFilterForMoniker(
    devices[0].Mon, null, devices[0].Name, out sourceFilter);
DsError.ThrowExceptionForHR(hr);

// Render preview
hr = captureGraph.RenderStream(
    PinCategory.Preview, MediaType.Video, sourceFilter, null, null);
DsError.ThrowExceptionForHR(hr);

// Set video window
var videoWindow = (IVideoWindow)graphBuilder;
videoWindow.put_Owner(panelHandle);
videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings);
videoWindow.SetWindowPosition(0, 0, panel.Width, panel.Height);

// Start
var mediaControl = (IMediaControl)graphBuilder;
hr = mediaControl.Run();
DsError.ThrowExceptionForHR(hr);

// Cleanup (must release EVERY COM object)
Marshal.ReleaseComObject(sourceFilter);
Marshal.ReleaseComObject(captureGraph);
Marshal.ReleaseComObject(graphBuilder);

VisioForge — C# webcam capture (after)

C#
var capture = new VideoCaptureCoreX(videoView);
var devices = await DeviceEnumerator.Shared.VideoSourcesAsync();
capture.Video_Source = new VideoCaptureDeviceSourceSettings(devices[0]);
await capture.StartAsync();

// Cleanup
await capture.StopAsync();
await capture.DisposeAsync();

C# Webcam Recording to MP4

DirectShow.NET — webcam to MP4 (before)

C#
// Must find H.264 encoder filter, MP4 mux filter, file writer
// Each requires separate COM object management
var graphBuilder = (IGraphBuilder)new FilterGraph();
var captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
captureGraph.SetFiltergraph(graphBuilder);

// Add source
var devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
IBaseFilter sourceFilter;
graphBuilder.AddSourceFilterForMoniker(
    devices[0].Mon, null, devices[0].Name, out sourceFilter);

// Find and add H.264 encoder (must be installed on system!)
// This varies by system — no guarantee the filter exists
Guid h264Clsid = new Guid("some-encoder-guid");
IBaseFilter encoder = (IBaseFilter)Activator.CreateInstance(
    Type.GetTypeFromCLSID(h264Clsid));
graphBuilder.AddFilter(encoder, "H.264 Encoder");

// Find and add MP4 mux
// Find and add file writer
// Connect source → encoder → mux → writer pins manually
// Each pin connection can fail silently or throw cryptic COM errors

// Configure encoder properties via ICodecAPI or IPropertyBag
// Different for every encoder filter...

var mediaControl = (IMediaControl)graphBuilder;
mediaControl.Run();

// Cleanup: release 5+ COM objects

VisioForge — C# webcam recording to MP4 (after)

C#
var capture = new VideoCaptureCoreX(videoView);
var devices = await DeviceEnumerator.Shared.VideoSourcesAsync();
capture.Video_Source = new VideoCaptureDeviceSourceSettings(devices[0]);
capture.Outputs_Add(new MP4Output("recording.mp4"), true);
await capture.StartAsync();

C# Video File Playback

DirectShow.NET — video playback (before)

C#
var graphBuilder = (IGraphBuilder)new FilterGraph();
int hr = graphBuilder.RenderFile("video.mp4", null);
DsError.ThrowExceptionForHR(hr);

var videoWindow = (IVideoWindow)graphBuilder;
videoWindow.put_Owner(panelHandle);
videoWindow.put_WindowStyle(WindowStyle.Child);
videoWindow.SetWindowPosition(0, 0, panel.Width, panel.Height);

var mediaControl = (IMediaControl)graphBuilder;
mediaControl.Run();

// Seeking
var mediaSeeking = (IMediaSeeking)graphBuilder;
long position = 50000000; // 5 seconds in 100ns units
mediaSeeking.SetPositions(
    ref position, AMSeekingSeekingFlags.AbsolutePositioning,
    null, AMSeekingSeekingFlags.NoPositioning);

VisioForge — C# video player (after)

C#
var player = new MediaPlayerCoreX(videoView);
await player.OpenAsync(new Uri("video.mp4"));
await player.PlayAsync();

// Seeking
await player.SeekAsync(TimeSpan.FromSeconds(5));

C# Video Frame Grabbing

DirectShow.NET — ISampleGrabber frame capture (before)

C#
// Must insert ISampleGrabber into filter graph
var sampleGrabber = (ISampleGrabber)new SampleGrabber();
var mediaType = new AMMediaType();
mediaType.majorType = MediaType.Video;
mediaType.subType = MediaSubType.RGB24;
sampleGrabber.SetMediaType(mediaType);

graphBuilder.AddFilter((IBaseFilter)sampleGrabber, "Grabber");
// Connect pins...
sampleGrabber.SetBufferSamples(true);

// In callback: manually read buffer, create Bitmap from raw bytes
sampleGrabber.GetCurrentBuffer(ref bufferSize, buffer);
// Manual pixel format conversion, stride calculation, etc.

VisioForge — C# video frame capture (after)

C#
capture.OnVideoFrameBuffer += (s, e) =>
{
    // Frame data available as managed buffer
    // Or convert to SKBitmap/Bitmap directly
    var bitmap = e.Frame.ToBitmap();
    ProcessFrame(bitmap);
};

C# IP Camera (RTSP) Capture

DirectShow.NET — RTSP capture (before)

C#
// Must find and install RTSP source filter (e.g., LAV, ffdshow)
// No standard DirectShow RTSP filter ships with Windows
var graphBuilder = (IGraphBuilder)new FilterGraph();

// Add RTSP source filter (if installed)
Guid rtspFilterClsid = new Guid("some-rtsp-filter-guid");
IBaseFilter rtspSource = (IBaseFilter)Activator.CreateInstance(
    Type.GetTypeFromCLSID(rtspFilterClsid));
graphBuilder.AddFilter(rtspSource, "RTSP Source");

// Configure URL via IFileSourceFilter or custom interface
var fileSource = (IFileSourceFilter)rtspSource;
fileSource.Load("rtsp://camera-ip:554/stream", null);

// Must manually connect pins to decoder, renderer
// No reconnection logic — if stream drops, graph stops
// No authentication helpers
// No ONVIF support

VisioForge — RTSP capture (after)

C#
var capture = new VideoCaptureCoreX(videoView);
capture.Video_Source = new RTSPSourceSettings(
    new Uri("rtsp://camera-ip:554/stream"))
{
    Login = "admin",
    Password = "password",
    ReconnectOnDrop = true
};
capture.Outputs_Add(new MP4Output("recording.mp4"), true);
await capture.StartAsync();

C# Screen Capture and Recording

DirectShow.NET — screen capture (before)

C#
// DirectShow has no built-in screen capture filter
// Must use third-party filter or custom push source
// Common approach: manually capture GDI/BitBlt in a thread,
// feed frames through a custom IBaseFilter implementation

// 200+ lines of custom filter code:
// - Implement IBaseFilter, IPin, IMediaSample
// - Manual frame rate timing with Thread.Sleep
// - Manual pixel format conversion
// - No GPU acceleration
// - No mouse cursor rendering
// - No multi-monitor support

VisioForge — screen capture (after)

C#
var capture = new VideoCaptureCoreX(videoView);
capture.Video_Source = new ScreenCaptureSourceSettings()
{
    FrameRate = new VideoFrameRate(30),
    Rectangle = new Rect(0, 0, 1920, 1080),
    CaptureCursor = true
};
capture.Outputs_Add(new MP4Output("screen.mp4"), true);
await capture.StartAsync();

C# Audio Recording from Microphone

DirectShow.NET — audio capture (before)

C#
var graphBuilder = (IGraphBuilder)new FilterGraph();
var captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
captureGraph.SetFiltergraph(graphBuilder);

// Find audio device
var audioDevices = DsDevice.GetDevicesOfCat(
    FilterCategory.AudioInputDevice);
IBaseFilter audioSource;
graphBuilder.AddSourceFilterForMoniker(
    audioDevices[0].Mon, null, audioDevices[0].Name,
    out audioSource);

// Must find WAV/MP3 encoder filter
// Must find file writer filter
// Must connect pins manually
// Configure sample rate/channels via IAMStreamConfig

var mediaControl = (IMediaControl)graphBuilder;
mediaControl.Run();

// Manual COM cleanup for all objects

VisioForge — audio capture (after)

C#
var capture = new VideoCaptureCoreX();
var audioDevices = await DeviceEnumerator.Shared
    .AudioSourcesAsync();
capture.Audio_Source = new AudioCaptureDeviceSourceSettings(
    audioDevices[0]);
capture.Audio_Record = true;
capture.Video_Record = false;
capture.Outputs_Add(new MP4Output("audio.mp4"), true);
await capture.StartAsync();

C# Custom Processing Pipeline

DirectShow.NET — custom filter graph (before)

C#
// Building a custom graph: source > resize > overlay > encode > mux > write
// Each step requires finding/creating a filter, adding to graph,
// connecting pins with compatible media types

var graphBuilder = (IGraphBuilder)new FilterGraph();
// Add source filter...
// Add resize filter (must find one that's installed)...
// Add overlay filter (must write custom or find one)...
// Add H.264 encoder (system-dependent)...
// Add MP4 mux (system-dependent)...
// Add file writer...
// Connect each pair of pins manually...
// Handle format negotiation failures...
// Total: 150-300 lines, fragile, system-dependent

VisioForge Media Blocks — custom pipeline (after)

C#
var pipeline = new MediaBlocksPipeline();

var source = new SystemVideoSourceBlock(
    new VideoCaptureDeviceSourceSettings(device));
var resize = new ResizeBlock(1920, 1080);
var overlay = new TextOverlayBlock("Recording...");
var encoder = new H264EncoderBlock();
var sink = new MP4SinkBlock("output.mp4");

pipeline.Connect(source.Output, resize.Input);
pipeline.Connect(resize.Output, overlay.Input);
pipeline.Connect(overlay.Output, encoder.Input);
pipeline.Connect(encoder.Output, sink.Input);

await pipeline.StartAsync();

Migration Checklist

  • Audit DirectShow.NET usage — Find all `using DirectShowLib` references
  • Identify filter graph purpose — Capture, playback, transcoding, or custom processing
  • Choose VisioForge SDK — Video Capture, Media Player, Video Edit, or Media Blocks
  • Install NuGet packages — Replace DirectShowLib NuGet with VisioForge packages
  • Replace filter graph code
  • Remove COM cleanup code — VisioForge uses `IAsyncDisposable`
  • Remove third-party DirectShow filter dependencies — VisioForge includes codecs
  • Target modern .NET — .NET 6-10
  • Test cross-platform
  • Remove DirectShow filter registration — No longer needed

What You Gain After Migration

AspectDirectShow.NETAfter Migration
Lines of code100+ per feature5-10 per feature
Framework.NET Framework 2.0.NET 6-10
PlatformsWindows onlyWindows, macOS, Linux, iOS, Android
API styleRaw COM, manual pin connectionsTyped async C# API
CodecsMust find and install DirectShow filtersBuilt-in (H.264, H.265, AV1, VP9)
Memory managementManual `Marshal.ReleaseComObject``IAsyncDisposable`
DebuggingOpaque COM errors (HRESULT)Typed exceptions, events
Video effectsMust find effect filters40+ built-in (GPU + CPU)
Audio effectsNone40+ (EQ, reverb, chorus, 3D)
StreamingNot availableRTMP, HLS, SRT, NDI
DetectionNot availableMotion (MOG2), face (Haar/DNN/DLib), pedestrian (HOG+SVM), barcode
Hardware encodingMust find encoder filtersNVENC, QSV, AMF, VideoToolbox
IP camerasManual filter graphRTSP, RTMP, HLS, ONVIF with auto-reconnection
MaintenanceAbandoned (2010)Active development

Frequently Asked Questions

Is DirectShow.NET still maintained?
No. DirectShow.NET has been abandoned since February 2010. Microsoft has also deprecated the underlying DirectShow API in favor of Media Foundation.
What is the best DirectShow.NET alternative for C# video capture?
VisioForge Video Capture SDK .Net replaces DirectShow filter graphs with a typed async API. Webcam capture that required 80+ lines of COM interop becomes 5 lines of C# code, with built-in recording, hardware encoding, and cross-platform support.
Can VisioForge replace custom DirectShow filter graphs?
Yes. The VisioForge Media Blocks SDK provides a modular pipeline with 400+ blocks that replaces custom filter graph construction.
Does VisioForge support .NET 6, .NET 8, .NET 9, and .NET 10?
Yes. All VisioForge .Net SDK packages support .NET 6 through .NET 10, including cross-platform deployment.
Do I still need DirectShow filters installed on the system?
No. VisioForge bundles its own codecs and decoders. H.264, H.265, AV1, VP9, AAC, and other codecs work out of the box.
Can I migrate from DirectShow.NET incrementally?
Yes. VisioForge SDKs can coexist with DirectShow.NET in the same project. Replace one filter graph at a time.

Start Your Migration

Related Migration Guides