#
VLC Source Filter Interface Reference
#
Overview
The VLC Source DirectShow filter exposes three progressive interfaces (IVlcSrc
, IVlcSrc2
, IVlcSrc3
) that provide comprehensive control over media playback, audio/subtitle track selection, and VLC configuration. These interfaces enable developers to leverage VLC's powerful media framework within DirectShow applications.
#
Interface Hierarchy
IUnknown
└── IVlcSrc
└── IVlcSrc2
└── IVlcSrc3
Each interface extends the previous one, adding new capabilities while maintaining backward compatibility.
#
IVlcSrc Interface
The base interface providing essential file loading and track selection capabilities.
#
Interface Definition
- Interface Name:
IVlcSrc
- GUID:
{77493EB7-6D00-41C5-9535-7C593824E892}
- Inherits From:
IUnknown
- Header File:
ivlcsrc.h
(C++),IVlcSrc.cs
(.NET)
#
Methods
#
SetFile
Sets the media file or URL to play.
Syntax (C++):
HRESULT SetFile(WCHAR *file);
Syntax (C#):
[PreserveSig]
int SetFile([MarshalAs(UnmanagedType.LPWStr)] string file);
Parameters:
file
: Wide-character string containing the file path or URL.
Returns: S_OK
(0) on success, error code otherwise.
Supported Sources:
- Local files:
C:\Videos\movie.mp4
- HTTP streams:
http://example.com/stream.m3u8
- RTSP streams:
rtsp://example.com/live
- HLS playlists:
https://example.com/playlist.m3u8
- DASH streams:
https://example.com/manifest.mpd
- DVB-T/C/S broadcasts
- Network shares:
\\server\share\video.mkv
Example (C++):
IVlcSrc* pVlcSrc = nullptr;
pFilter->QueryInterface(IID_IVlcSrc, (void**)&pVlcSrc);
pVlcSrc->SetFile(L"C:\\Videos\\movie.mkv");
pVlcSrc->Release();
Example (C#):
var vlcSrc = filter as IVlcSrc;
if (vlcSrc != null)
{
vlcSrc.SetFile(@"C:\Videos\movie.mkv");
}
#
Audio Track Management
#
GetAudioTracksCount
Retrieves the total number of available audio tracks.
Syntax (C++):
HRESULT GetAudioTracksCount(int *count);
Syntax (C#):
[PreserveSig]
int GetAudioTracksCount(out int count);
Parameters:
count
: [out] Receives the number of audio tracks.
Returns: S_OK
(0) on success.
Usage Notes:
- Call after the file is loaded and the filter graph is built
- Returns 0 if no audio tracks are available or file not loaded
Example (C++):
int audioCount = 0;
pVlcSrc->GetAudioTracksCount(&audioCount);
printf("Audio tracks: %d\n", audioCount);
#
GetAudioTrackInfo
Retrieves information about a specific audio track.
Syntax (C++):
HRESULT GetAudioTrackInfo(int number, int *id, WCHAR *name);
Syntax (C#):
[PreserveSig]
int GetAudioTrackInfo(int number, out int id,
[MarshalAs(UnmanagedType.LPWStr)] StringBuilder name);
Parameters:
number
: Zero-based track index (0 to count-1).id
: [out] Receives the track ID.name
: [out] Buffer to receive the track name (must be pre-allocated, minimum 256 characters).
Returns: S_OK
(0) on success.
Usage Notes:
- Pre-allocate name buffer with at least 256 wide characters
- Track names typically include language and codec information
- Track ID is used with SetAudioTrack()
Example (C++):
int audioCount = 0;
pVlcSrc->GetAudioTracksCount(&audioCount);
for (int i = 0; i < audioCount; i++)
{
int id = 0;
WCHAR name[256] = {0};
pVlcSrc->GetAudioTrackInfo(i, &id, name);
wprintf(L"Track %d - ID: %d, Name: %s\n", i, id, name);
}
Example (C#):
int count = 0;
vlcSrc.GetAudioTracksCount(out count);
for (int i = 0; i < count; i++)
{
int id;
var name = new StringBuilder(256);
vlcSrc.GetAudioTrackInfo(i, out id, name);
Console.WriteLine($"Track {i} - ID: {id}, Name: {name}");
}
#
GetAudioTrack
Retrieves the ID of the currently active audio track.
Syntax (C++):
HRESULT GetAudioTrack(int *id);
Syntax (C#):
[PreserveSig]
int GetAudioTrack(out int id);
Parameters:
id
: [out] Receives the current audio track ID.
Returns: S_OK
(0) on success.
Example (C++):
int currentTrack = 0;
pVlcSrc->GetAudioTrack(¤tTrack);
printf("Current audio track ID: %d\n", currentTrack);
#
SetAudioTrack
Sets the active audio track by ID.
Syntax (C++):
HRESULT SetAudioTrack(int id);
Syntax (C#):
[PreserveSig]
int SetAudioTrack(int id);
Parameters:
id
: The track ID to activate (obtained from GetAudioTrackInfo).
Returns: S_OK
(0) on success, error code if track ID is invalid.
Usage Notes:
- Can be called during playback to switch tracks dynamically
- Use -1 to disable all audio tracks
- Track switching may cause brief audio interruption
Example (C++):
// Switch to second audio track
int trackId = 0;
pVlcSrc->GetAudioTrackInfo(1, &trackId, nullptr);
pVlcSrc->SetAudioTrack(trackId);
Example (C#):
// Switch to first audio track
int trackId;
var name = new StringBuilder(256);
vlcSrc.GetAudioTrackInfo(0, out trackId, name);
vlcSrc.SetAudioTrack(trackId);
#
Subtitle Track Management
#
GetSubtitlesCount
Retrieves the total number of available subtitle tracks.
Syntax (C++):
HRESULT GetSubtitlesCount(int *count);
Syntax (C#):
[PreserveSig]
int GetSubtitlesCount(out int count);
Parameters:
count
: [out] Receives the number of subtitle tracks.
Returns: S_OK
(0) on success.
Example (C++):
int subtitleCount = 0;
pVlcSrc->GetSubtitlesCount(&subtitleCount);
printf("Subtitle tracks: %d\n", subtitleCount);
#
GetSubtitleInfo
Retrieves information about a specific subtitle track.
Syntax (C++):
HRESULT GetSubtitleInfo(int number, int *id, WCHAR *name);
Syntax (C#):
[PreserveSig]
int GetSubtitleInfo(int number, out int id,
[MarshalAs(UnmanagedType.LPWStr)] StringBuilder name);
Parameters:
number
: Zero-based track index (0 to count-1).id
: [out] Receives the subtitle track ID.name
: [out] Buffer to receive the subtitle track name (minimum 256 characters).
Returns: S_OK
(0) on success.
Example (C++):
int subCount = 0;
pVlcSrc->GetSubtitlesCount(&subCount);
for (int i = 0; i < subCount; i++)
{
int id = 0;
WCHAR name[256] = {0};
pVlcSrc->GetSubtitleInfo(i, &id, name);
wprintf(L"Subtitle %d - ID: %d, Name: %s\n", i, id, name);
}
#
GetSubtitle
Retrieves the ID of the currently active subtitle track.
Syntax (C++):
HRESULT GetSubtitle(int *id);
Syntax (C#):
[PreserveSig]
int GetSubtitle(out int id);
Parameters:
id
: [out] Receives the current subtitle track ID.
Returns: S_OK
(0) on success.
#
SetSubtitle
Sets the active subtitle track by ID.
Syntax (C++):
HRESULT SetSubtitle(int id);
Syntax (C#):
[PreserveSig]
int SetSubtitle(int id);
Parameters:
id
: The subtitle track ID to activate.
Returns: S_OK
(0) on success.
Usage Notes:
- Use -1 to disable subtitles
- Subtitle rendering is performed by VLC's internal renderer
- Can be switched during playback
Example (C++):
// Enable first subtitle track
int subtitleId = 0;
pVlcSrc->GetSubtitleInfo(0, &subtitleId, nullptr);
pVlcSrc->SetSubtitle(subtitleId);
// Disable subtitles
pVlcSrc->SetSubtitle(-1);
#
IVlcSrc2 Interface
Extends IVlcSrc
with custom VLC command-line parameter support.
#
Interface Definition
- Interface Name:
IVlcSrc2
- GUID:
{CCE122C0-172C-4626-B4B6-42B039E541CB}
- Inherits From:
IVlcSrc
- Header File:
ivlcsrc.h
(C++),IVlcSrc.cs
(.NET)
#
Methods
#
SetCustomCommandLine
Sets custom VLC command-line parameters.
Syntax (C++):
HRESULT SetCustomCommandLine(char* params[], int length);
Syntax (C#):
[PreserveSig]
int SetCustomCommandLine([MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[] parameters,
int length);
Parameters:
params
: Array of ASCII strings containing VLC command-line parameters.length
: Number of parameters in the array.
Returns: S_OK
(0) on success.
Usage Notes:
- Must be called before loading the media file with SetFile()
- Parameters are passed directly to libVLC initialization
- Invalid parameters are ignored with warnings in VLC log
- Use standard VLC command-line syntax (see VLC documentation)
Common VLC Parameters:
Example (C++):
IVlcSrc2* pVlcSrc2 = nullptr;
pFilter->QueryInterface(IID_IVlcSrc2, (void**)&pVlcSrc2);
// Configure for low-latency RTSP
char* params[] = {
"--network-caching=300",
"--rtsp-tcp",
"--avcodec-hw=d3d11va",
"--verbose=2"
};
pVlcSrc2->SetCustomCommandLine(params, 4);
pVlcSrc2->SetFile(L"rtsp://192.168.1.100/stream");
pVlcSrc2->Release();
Example (C#):
var vlcSrc2 = filter as IVlcSrc2;
if (vlcSrc2 != null)
{
// Enable hardware acceleration and adjust caching
string[] parameters = new string[]
{
"--avcodec-hw=any",
"--network-caching=1000",
"--file-caching=300"
};
vlcSrc2.SetCustomCommandLine(parameters, parameters.Length);
vlcSrc2.SetFile(@"C:\Videos\movie.mkv");
}
Example (Delphi):
var
VlcSrc2: IVlcSrc2;
Params: array[0..2] of PAnsiChar;
begin
if Succeeded(Filter.QueryInterface(IID_IVlcSrc2, VlcSrc2)) then
begin
Params[0] := '--network-caching=500';
Params[1] := '--rtsp-tcp';
Params[2] := '--avcodec-hw=dxva2';
VlcSrc2.SetCustomCommandLine(@Params, 3);
VlcSrc2.SetFile('rtsp://example.com/stream');
end;
end;
#
IVlcSrc3 Interface
Extends IVlcSrc2
with frame rate override capability.
#
Interface Definition
- Interface Name:
IVlcSrc3
- GUID:
{3DFBED0C-E4A8-401C-93EF-CBBFB65223DD}
- Inherits From:
IVlcSrc2
- Header File:
ivlcsrc.h
(C++),IVlcSrc.cs
(.NET)
#
Methods
#
SetDefaultFrameRate
Sets a default frame rate for media without frame rate information.
Syntax (C++):
HRESULT SetDefaultFrameRate(double frameRate);
Syntax (C#):
[PreserveSig]
int SetDefaultFrameRate(double frameRate);
Parameters:
frameRate
: Frame rate in frames per second (e.g., 29.97, 30.0, 25.0, 60.0).
Returns: S_OK
(0) on success.
Usage Notes:
- Must be called before loading the media file
- Used when source media doesn't specify frame rate
- Particularly useful for network streams without timing information
- Common values: 23.976, 24.0, 25.0, 29.97, 30.0, 50.0, 59.94, 60.0
Example (C++):
IVlcSrc3* pVlcSrc3 = nullptr;
pFilter->QueryInterface(IID_IVlcSrc3, (void**)&pVlcSrc3);
// Set default frame rate for MJPEG IP camera stream
pVlcSrc3->SetDefaultFrameRate(30.0);
pVlcSrc3->SetFile(L"http://192.168.1.50/video.mjpg");
pVlcSrc3->Release();
Example (C#):
var vlcSrc3 = filter as IVlcSrc3;
if (vlcSrc3 != null)
{
// Set PAL frame rate for DV stream
vlcSrc3.SetDefaultFrameRate(25.0);
vlcSrc3.SetFile(@"dv://0");
}
#
Complete Usage Examples
#
Example 1: Multi-Language Movie Playback (C++)
#include <dshow.h>
#include "ivlcsrc.h"
void PlayMovieWithAudioSelection(IBaseFilter* pVlcFilter)
{
HRESULT hr;
IVlcSrc* pVlcSrc = nullptr;
hr = pVlcFilter->QueryInterface(IID_IVlcSrc, (void**)&pVlcSrc);
if (FAILED(hr))
return;
// Load movie
pVlcSrc->SetFile(L"C:\\Movies\\multilang_movie.mkv");
// Build and run the graph here...
// (IGraphBuilder::RenderFile, IMediaControl::Run, etc.)
// Enumerate audio tracks
int audioCount = 0;
pVlcSrc->GetAudioTracksCount(&audioCount);
wprintf(L"Available audio tracks:\n");
for (int i = 0; i < audioCount; i++)
{
int id = 0;
WCHAR name[256] = {0};
pVlcSrc->GetAudioTrackInfo(i, &id, name);
wprintf(L" [%d] %s (ID: %d)\n", i, name, id);
}
// Select English audio track (assuming it's track 1)
int englishTrackId = 0;
pVlcSrc->GetAudioTrackInfo(1, &englishTrackId, nullptr);
pVlcSrc->SetAudioTrack(englishTrackId);
// Enable subtitles
int subCount = 0;
pVlcSrc->GetSubtitlesCount(&subCount);
if (subCount > 0)
{
int subId = 0;
pVlcSrc->GetSubtitleInfo(0, &subId, nullptr);
pVlcSrc->SetSubtitle(subId);
}
pVlcSrc->Release();
}
#
Example 2: Low-Latency RTSP Stream (C#)
using System;
using System.Text;
using DirectShowLib;
using VisioForge.DirectShowAPI;
public class VLCRTSPPlayer
{
public void SetupLowLatencyRTSP(IBaseFilter vlcFilter)
{
// Get IVlcSrc3 interface (highest version)
var vlcSrc3 = vlcFilter as IVlcSrc3;
if (vlcSrc3 == null)
throw new NotSupportedException("IVlcSrc3 not available");
// Configure VLC for minimal latency
string[] params = new string[]
{
"--network-caching=50", // Minimal network buffer
"--live-caching=50", // Minimal live buffer
"--rtsp-tcp", // Use TCP transport
"--no-audio-time-stretch", // Disable audio stretching
"--avcodec-hw=d3d11va", // Hardware decoding
"--verbose=0" // Reduce logging
};
int hr = vlcSrc3.SetCustomCommandLine(params, params.Length);
DsError.ThrowExceptionForHR(hr);
// Set frame rate for IP camera
hr = vlcSrc3.SetDefaultFrameRate(25.0);
DsError.ThrowExceptionForHR(hr);
// Load RTSP stream
hr = vlcSrc3.SetFile("rtsp://admin:password@192.168.1.100:554/stream1");
DsError.ThrowExceptionForHR(hr);
// Build filter graph and start playback...
}
}
#
Example 3: Subtitle Track Switching UI (Delphi)
unit VLCSubtitles;
interface
uses
Winapi.Windows, System.Classes, Vcl.Controls, Vcl.StdCtrls,
DSPack, ivlcsrc;
type
TSubtitleForm = class(TForm)
ComboBoxSubtitles: TComboBox;
procedure FormCreate(Sender: TObject);
procedure ComboBoxSubtitlesChange(Sender: TObject);
private
FVlcSrc: IVlcSrc;
FSubtitleIDs: TArray<Integer>;
procedure LoadSubtitleTracks;
public
procedure SetVLCFilter(Filter: IBaseFilter);
end;
implementation
procedure TSubtitleForm.SetVLCFilter(Filter: IBaseFilter);
begin
if Succeeded(Filter.QueryInterface(IID_IVlcSrc, FVlcSrc)) then
begin
LoadSubtitleTracks;
end;
end;
procedure TSubtitleForm.LoadSubtitleTracks;
var
Count, I, ID: Integer;
Name: array[0..255] of WideChar;
begin
ComboBoxSubtitles.Clear;
ComboBoxSubtitles.Items.Add('Disabled');
if FVlcSrc.GetSubtitlesCount(Count) = S_OK then
begin
SetLength(FSubtitleIDs, Count + 1);
FSubtitleIDs[0] := -1; // Disabled
for I := 0 to Count - 1 do
begin
if FVlcSrc.GetSubtitleInfo(I, ID, Name) = S_OK then
begin
FSubtitleIDs[I + 1] := ID;
ComboBoxSubtitles.Items.Add(Name);
end;
end;
end;
ComboBoxSubtitles.ItemIndex := 0;
end;
procedure TSubtitleForm.ComboBoxSubtitlesChange(Sender: TObject);
var
Index: Integer;
begin
Index := ComboBoxSubtitles.ItemIndex;
if (Index >= 0) and (Index < Length(FSubtitleIDs)) then
begin
FVlcSrc.SetSubtitle(FSubtitleIDs[Index]);
end;
end;
end.
#
Best Practices
#
Track Management
- Always enumerate tracks after building the filter graph - Track information is not available until the source is loaded
- Handle files with no audio/subtitles gracefully - Check count before accessing tracks
- Pre-allocate name buffers with 256 characters - Prevents buffer overruns
- Cache track IDs - Don't repeatedly call GetAudioTrackInfo/GetSubtitleInfo
#
VLC Configuration
- Use IVlcSrc3 when available - Provides full feature set
- Set custom parameters before loading file - Parameters only apply at initialization
- Test VLC parameters independently - Use VLC command-line to verify parameters work
- Use appropriate caching values:
- Local files: 300ms
- Network streams: 1000-3000ms
- Low-latency streams: 50-300ms
#
Hardware Acceleration
Enable hardware decoding for H.264/H.265:
"--avcodec-hw=any" // Auto-detect best method
Platform-specific options:
- Windows:
d3d11va
,dxva2
- All platforms:
any
(auto-detect)
- Windows:
#
Performance
- Minimize network caching for live streams - Reduces latency
- Use RTSP over TCP when UDP fails - More reliable through firewalls
- Enable verbose logging for debugging only - Reduces performance overhead
#
Related Interfaces
- IFileSourceFilter - Alternative standard DirectShow interface for loading files
- IAMStreamSelect - DirectShow standard for stream selection (also supported by VLC filter)
- IMediaSeeking - Seek control in media
- IBasicVideo - Video window control