vsourcewmf_web_logo

VSourceWmf C++ library

v1.0.0

Table of contents

Overview

VSourceWmf C++ library provides video capture and video source control based on Microsoft Media Foundation (WMF) on Windows. It eliminates any OpenCV dependency from the library core and provides a clean, ultra-low-latency interface for video capture from:

  1. Physical Capture Devices: USB webcams, industrial cameras, and video capture cards.
  2. Virtual Cameras: Virtual video sources and software capture devices registered in Windows.
  3. Custom Media Sources & Files: Video files (*.mp4, *.avi, *.mov, *.wmv, *.flv, *.swf, *.f4v, *.webm, *.mkv) and network video streams via URL.

Key features:

  • Minimal Latency: Architected using IMFSourceReader with MF_LOW_LATENCY = TRUE and hardware-accelerated video transformation pipeline for minimum acquisition-to-application latency.
  • Optimal Multithreading: Single dedicated worker thread per video source instance ensures real-time capture without locking or frame queue buildup.
  • Resolution & FPS Control: For all sources, FPS and resolution can be determined by the source. For USB/hardware cameras, custom resolution can be selected via width and height properties (when both > 0).
  • Format Negotiation: The library attempts to set the requested format as a source reader property. If the requested format cannot be set, it delivers uncompressed RAW video in the native supported format.
  • Hardware RGB32 / BGR24 & ROI Support: Converts camera streams directly to BGR24 with dynamic Region of Interest (ROI) support.
  • Camera Controls: Direct hardware control of Exposure, Exposure Mode, Gain, Gain Mode, Focus, and Focus Mode via IAMCameraControl and IAMVideoProcAmp interfaces.
  • Auto-Reconnection: Automatically attempts reconnection if a video device or stream connection is interrupted.
  • Standard Interface: Inherits from the open-source VSource interface class.
  • Standard C++17: Pure C++17 implementation with zero external logger dependency.

Versions

Table 1 - Library versions.

Version Release date What’s new
1.0.0 28.09.2026 - First version based on Microsoft Media Foundation (WMF).

Library files

The library is supplied only by source code as a CMake project. The repository structure is shown below:

CMakeLists.txt -------------- Main CMake file of the library.
3rdparty -------------------- Folder with third-party libraries.
    CMakeLists.txt ---------- CMake file to include third-party libraries.
    VSource ----------------- Folder with VSource library interface.
src ------------------------- Folder with library source code.
    CMakeLists.txt ---------- CMake file of the library (verifies Windows & WMF).
    VSourceWmf.h ------------ Main library header file.
    VSourceWmfVersion.h ----- Header file with library version.
    VSourceWmfVersion.h.in -- Service CMake file to generate version header.
    VSourceWmf.cpp ---------- C++ implementation wrapper.
    Impl -------------------- Folder with internal Media Foundation implementation.
        VSourceWmfImpl.h ---- Header file of WMF video source implementation.
        VSourceWmfImpl.cpp -- C++ WMF video capture implementation.
test ------------------------ Folder for test application files (uses OpenCV for display).
    CMakeLists.txt ---------- CMake file for test application.
    main.cpp ---------------- Source C++ file of test application.
example --------------------- Folder for example application (uses OpenCV for display).
    CMakeLists.txt ---------- CMake file for example application.
    main.cpp ---------------- Source C++ file of example application.

VSourceWmf class description

VSourceWmf class declaration

VSourceWmf class is declared in VSourceWmf.h file:

namespace cr
{
namespace video
{
/// Video source class based on Windows Media Foundation (WMF).
class VSourceWmf : public VSource
{
public:

    /// Class constructor.
    VSourceWmf();

    /// Class destructor.
    ~VSourceWmf();

    /// Get string of current library version.
    static std::string getVersion();

    /// Open video source.
    bool openVSource(std::string& initString) override;

    /// Init video source.
    bool initVSource(VSourceParams& params) override;

    /// Get open status.
    bool isVSourceOpen() override;

    /// Close video source.
    void closeVSource() override;

    /// Get new video frame.
    bool getFrame(Frame& frame, int32_t timeoutMsec = 0) override;

    /// Set video source param.
    bool setParam(VSourceParam id, float value) override;

    /// Get video source param value.
    float getParam(VSourceParam id) override;

    /// Get video source params structure.
    void getParams(VSourceParams& params) override;

    /// Execute command.
    bool executeCommand(VSourceCommand id) override;

    /// Decode and execute command.
    bool decodeAndExecuteCommand(uint8_t* data, int size) override;
};
}
}

getVersion method

The getVersion() static method returns string of current version of VSourceWmf class:

static std::string getVersion();

Method can be used without VSourceWmf class instance:

std::cout << "VSourceWmf version: " << cr::video::VSourceWmf::getVersion() << std::endl;

Console output:

VSourceWmf version: 1.0.0

openVSource method

The openVSource(…) method initializes the video source using an initialization string. Video source parameters (VSourceParams class) will be initialized by default. Instead of openVSource(…) method, the user can call initVSource(…). This method checks the initialization string and starts the internal video capture thread. Method declarations:

bool openVSource(std::string& initString) override;
Parameter Value
initString Initialization string. The library can open physical capture devices, virtual cameras, video files (*.mp4, *.avi, *.mov, *.wmv, *.flv, *.swf, *.f4v, *.webm, *.mkv), and network video streams/URLs. Valid formats:
- "camera num" - camera index (e.g. "0", "1", "2").
- "camera num;width;height" - camera index and resolution (e.g. "0;640;480", "0;1280;720").
- "device name" - friendly device name or symbolic link (e.g. "Integrated Webcam").
- "device name;width;height" - device name and resolution.
- "file path" - video file path (e.g. "video.mp4").
- "file path;fps" - video file path and playback FPS (e.g. "video.mp4;30").
- "stream url" - video stream/source URL (e.g. "http://192.168.1.70:7031/video").
- "stream url;fourcc" - stream URL and fourcc format code (e.g. "http://...;BGR24", "...;NV12").

Returns: TRUE if the video source is initialized or FALSE if initialization failed.

initVSource method

The initVSource(…) method initializes the video source from a VSourceParams structure:

bool initVSource(VSourceParams& params) override;
Parameter Value
params VSourceParams object. Field source is the video source initialization string.
Supported fields:
- source - video source initialization string.
- fourcc - requested output video frame format (e.g. "BGR24", "NV12", "YUYV").
- width - frame width. Applied to hardware/USB devices if both width and height > 0.
- height - frame height. Applied to hardware/USB devices if both width and height > 0.
- fps - FPS for video files playback.
- roiX, roiY, roiWidth, roiHeight - Region of Interest applied to BGR24 frames.
- gain, gainMode - initial gain and gain mode.
- exposure, exposureMode - initial exposure and auto exposure mode.
- focusPos, focusMode - initial focus position and autofocus mode.

Returns: TRUE if the video source initialized or FALSE if not.

isVSourceOpen method

The isVSourceOpen() method returns video source open/receiving status:

bool isVSourceOpen() override;

Returns: TRUE if the video source is open and actively receiving video, or FALSE if not.

closeVSource method

The closeVSource() method stops the internal video capture thread, releases all Media Foundation resources, and resets the frame state:

void closeVSource() override;

getFrame method

The getFrame(…) method retrieves the latest video frame:

bool getFrame(Frame& frame, int32_t timeoutMsec = 0) override;
Parameter Value
frame Output video frame (see Frame class description). Output frame pixel format is typically Fourcc::BGR24 or raw uncompressed camera format (NV12, YUYV, UYVY).
timeoutMsec Timeout in milliseconds:
- timeoutMsec == -1: waits indefinitely until a new frame arrives.
- timeoutMsec == 0: checks if a new frame is immediately available without blocking.
- timeoutMsec > 0: waits up to the specified timeout in milliseconds.

Returns: TRUE if a new frame exists and was copied, or FALSE if timed out / source closed.

setParam method

The setParam(…) method updates video source parameters:

bool setParam(VSourceParam id, float value) override;
Parameter Description
id Parameter ID according to VSourceParam enum.
Supported parameters:
- VSourceParam::LOG_LEVEL - logging verbosity.
- VSourceParam::ROI_X, ROI_Y, ROI_WIDTH, ROI_HEIGHT - dynamic Region of Interest cropping.
- VSourceParam::FOCUS_MODE - camera autofocus (1 - Auto, 0 - Manual) via IAMCameraControl.
- VSourceParam::FOCUS_POS - camera focus position via IAMCameraControl.
- VSourceParam::GAIN_MODE - camera gain mode (1 - Auto, 0 - Manual) via IAMVideoProcAmp.
- VSourceParam::GAIN - camera gain value via IAMVideoProcAmp.
- VSourceParam::EXPOSURE_MODE - camera auto exposure (1 - Auto, 0 - Manual) via IAMCameraControl.
- VSourceParam::EXPOSURE - camera exposure value via IAMCameraControl.
value Value to set.

Returns: TRUE if the parameter was set or FALSE if not supported / rejected by hardware.

getParam method

The getParam(…) method queries a parameter value:

float getParam(VSourceParam id) override;
Parameter Description
id Parameter ID according to VSourceParam enum.
Supported parameters:
- VSourceParam::LOG_LEVEL
- VSourceParam::CYCLE_TIME_MKS - time interval between two captured frames (in microseconds).
- VSourceParam::WIDTH - current output frame width.
- VSourceParam::HEIGHT - current output frame height.
- VSourceParam::FPS - calculated real-time capture FPS.
- VSourceParam::IS_OPEN - 1.0f if open, 0.0f if not.
- VSourceParam::ROI_X, ROI_Y, ROI_WIDTH, ROI_HEIGHT
- VSourceParam::FOCUS_MODE, FOCUS_POS
- VSourceParam::GAIN_MODE, GAIN
- VSourceParam::EXPOSURE_MODE, EXPOSURE

Returns: Current parameter value, or -1.0f if not supported / unavailable.

getParams method

The getParams(…) method retrieves all current video source parameters:

void getParams(VSourceParams& params) override;
Parameter Description
params VSourceParams object to receive parameters.

executeCommand method

The executeCommand(…) method executes action commands:

bool executeCommand(VSourceCommand id) override;
Parameter Description
id Command ID according to VSourceCommand enum.
- VSourceCommand::RESTART - restarts the video source capture pipeline.

Returns: TRUE if the command was executed, or FALSE if not supported.

decodeAndExecuteCommand method

The decodeAndExecuteCommand(…) method decodes and executes remote commands received over a network channel:

bool decodeAndExecuteCommand(uint8_t* data, int size) override;
Parameter Description
data Pointer to command data buffer.
size Buffer size (11 bytes for SET_PARAM, 7 bytes for COMMAND).

Returns: TRUE if command decoded and executed, or FALSE if invalid.

encodeSetParamCommand method

The encodeSetParamCommand(…) static method designed to encode command to change any parameter in remote video source. To control video source remotely, the developer has to design his own protocol and according to it encode the command and deliver it over the communication channel. To simplify this, the VSource class contains static methods for encoding the control command. The VSource class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeSetParamCommand(…) designed to encode SET_PARAM command. Method declaration:

static void encodeSetParamCommand(uint8_t* data, int& size, VSourceParam id, float value);
Parameter Description
data Pointer to data buffer for encoded command. Must have size >= 11.
size Size of encoded data. Will be 11 bytes.
id Parameter ID according to VSourceParam enum.
value Parameter value.

encodeSetParamCommand(…) is static and used without VSource class instance. This method used on client side (control system). Command encoding example:

// Buffer for encoded data.
uint8_t data[11];
// Size of encoded data.
int size = 0;
// Random parameter value.
float outValue = (float)(rand() % 20);
// Encode command.
VSurce::encodeSetParamCommand(data, size, VSourceParam::EXPOSURE, outValue);

encodeCommand method

The encodeCommand(…) static method designed to encode command to perform action command in remote video source. To control a video source remotely, the developer has to design his own protocol and according to it encode the command and deliver it over the communication channel. To simplify this, the VSource class contains static methods for encoding the control command. The VSource class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeCommand(…) designed to encode COMMAND (action command). Method declaration:

static void encodeCommand(uint8_t* data, int& size, VSourceCommand id);
Parameter Description
data Pointer to data buffer for encoded command. Must have size >= 7 bytes.
size Size of encoded data. Will be 7 bytes.
id Command ID according to VSourceCommand enum.

encodeCommand(…) is static and used without VSource class instance. This method used on client side (control system). Command encoding example:

// Buffer for encoded data.
uint8_t data[11];
// Size of encoded data.
int size = 0;
// Encode command.
VSource::encodeCommand(data, size, VSourceCommand::RESTART);

decodeCommand method

The decodeCommand(…) static method designed to decode command on video source side (edge device). Method declaration:

static int decodeCommand(uint8_t* data, int size, VSourceParam& paramId, VSourceCommand& commandId, float& value);
Parameter Description
data Pointer to input command.
size Size of command. Should be 11 bytes for SET_PARAM and 7 bytes for COMMAND.
paramId Parameter ID according to VSourceParam enum. After decoding SET_PARAM command the method will return parameter ID.
commandId Command ID according to VSourceCommand enum. After decoding COMMAND the method will return command ID.
value Parameter value (after decoding SET_PARAM command).

Returns: 0 - in case decoding COMMAND, 1 - in case decoding SET_PARAM command or -1 in case errors.

decodeAndExecuteCommand method

The decodeAndExecuteCommand(…) method decodes and executes command on video source side. The particular implementation of the video source must provide thread-safe decodeAndExecuteCommand(…) method call. This means that the decodeAndExecuteCommand(…) method can be safely called from any thread. Method declaration:

virtual bool decodeAndExecuteCommand(uint8_t* data, int size) = 0;
Parameter Description
data Pointer to input command.
size Size of command. Must be 11 bytes for SET_PARAM and 7 bytes for COMMAND.

Returns: TRUE if command decoded (SET_PARAM or COMMAND) and executed (action command or set param command).

Data structures

VSource.h defines parameter IDs (VSourceParam enum) and action command IDs (VSourceCommand enum).

VSourceCommand enum

enum class VSourceCommand
{
    /// Restart video source.
    RESTART = 1
};

Table 2 - Video source commands.

Command Description
RESTART Restarts the video capture pipeline. Supported.

VSourceParam enum

enum class VSourceParam
{
    LOG_LEVEL = 1,
    WIDTH,
    HEIGHT,
    GAIN_MODE,
    GAIN,
    EXPOSURE_MODE,
    EXPOSURE,
    FOCUS_MODE,
    FOCUS_POS,
    CYCLE_TIME_MKS,
    FPS,
    IS_OPEN,
    ROI_X,
    ROI_Y,
    ROI_WIDTH,
    ROI_HEIGHT,
    CUSTOM_1,
    CUSTOM_2,
    CUSTOM_3
};

Table 3 - Video source parameters support in VSourceWmf.

Parameter Access Description
LOG_LEVEL read / write Logging mode: 0 - Disable, 1 - File, 2 - Console, 3 - Both.
WIDTH read only Current frame width. Configurable during device initialization via width property.
HEIGHT read only Current frame height. Configurable during device initialization via height property.
GAIN_MODE read / write Gain mode: 0 - Manual, 1 - Auto. Controlled via IAMVideoProcAmp.
GAIN read / write Gain value. Controlled via IAMVideoProcAmp.
EXPOSURE_MODE read / write Exposure mode: 0 - Manual, 1 - Auto. Controlled via IAMCameraControl.
EXPOSURE read / write Exposure value. Controlled via IAMCameraControl.
FOCUS_MODE read / write Focus mode: 0 - Manual, 1 - Auto. Controlled via IAMCameraControl.
FOCUS_POS read / write Focus position. Controlled via IAMCameraControl.
CYCLE_TIME_MKS read only Measured video capture cycle time in microseconds.
FPS read only Real-time measured capture FPS. For video files, sets playback speed during init.
IS_OPEN read only Open flag: 1.0f - open and receiving, 0.0f - closed.
ROI_X read / write Region of interest top-left corner horizontal coordinate.
ROI_Y read / write Region of interest top-left corner vertical coordinate.
ROI_WIDTH read / write Region of interest width in pixels.
ROI_HEIGHT read / write Region of interest height in pixels.
CUSTOM_1 read / write Not supported (-1.0f).
CUSTOM_2 read / write Not supported (-1.0f).
CUSTOM_3 read / write Not supported (-1.0f).

VSourceParams class description

VSourceParams class declaration

VSourceParams class is declared in VSource.h:

class VSourceParams
{
public:
    int logLevel{0};
    std::string source{"0"};
    std::string fourcc{"BGR24"};
    int width{0};
    int height{0};
    int gainMode{-1};
    int gain{-1};
    int exposureMode{-1};
    int exposure{-1};
    int focusMode{-1};
    int focusPos{-1};
    int cycleTimeMks{0};
    float fps{0.0f};
    bool isOpen{false};
    int roiX{0};
    int roiY{0};
    int roiWidth{0};
    int roiHeight{0};
    float custom1{-1.0f};
    float custom2{-1.0f};
    float custom3{-1.0f};

    JSON_READABLE(VSourceParams, logLevel, source, fourcc, width, height,
                  gainMode, exposureMode, focusMode, fps, roiX, roiY,
                  roiWidth, roiHeight, custom1, custom2, custom3);

    VSourceParams& operator= (const VSourceParams& src);
    bool encode(uint8_t* data, int bufferSize, int& size, VSourceParamsMask* mask = nullptr);
    bool decode(uint8_t* data, int dataSize);
};

Serialize video source params

Serialize params using encode(…):

VSourceParams in;
in.source = "0;640;480";
in.logLevel = 2;

uint8_t data[1024];
int size = 0;
in.encode(data, sizeof(data), size);

Deserialize video source params

Deserialize params using decode(…):

VSourceParams out;
if (!out.decode(data, size))
{
    std::cout << "Can't decode data" << std::endl;
}

Read params from JSON file and write to JSON file

// Write params to file
VSourceParams in;
cr::utils::ConfigReader inConfig;
inConfig.set(in, "vSourceParams");
inConfig.writeToFile("TestVSourceParams.json");

// Read params from file
cr::utils::ConfigReader outConfig;
if (!outConfig.readFromFile("TestVSourceParams.json"))
{
    std::cout << "Can't open config file" << std::endl;
}

Build and connect to your project

Prerequisites

  • Operating System: Windows 10 or Windows 11.
  • Compiler: Microsoft Visual C++ (MSVC) with C++17 support (Visual Studio 2017/2019/2022).
  • Build System: CMake 3.13 or newer.
  • Windows SDK: Windows 10/11 SDK (contains Windows Media Foundation libraries: Mfplat.lib, mf.lib, mfreadwrite.lib, mfuuid.lib).
  • OpenCV: Required only for compiling the example and test applications to display frames; the VSourceWmf library itself does not depend on OpenCV.

Building from Source

cd VSourceWmf
mkdir build
cd build
cmake .. -A x64
cmake --build . --config Release

Adding to Your Project as a Submodule / Subdirectory

In your project’s CMakeLists.txt:

add_subdirectory(3rdparty/VSourceWmf)
target_link_libraries(${PROJECT_NAME} PRIVATE VSourceWmf)

Simple example

#include <iostream>
#include <opencv2/opencv.hpp>
#include "VSourceWmf.h"

int main(void)
{
    // Create WMF video source instance.
    cr::video::VSource* source = new cr::video::VSourceWmf();

    // Open video source (e.g. camera 0 at 640x480 resolution).
    std::string initString = "0;640;480";
    if (!source->openVSource(initString))
    {
        std::cerr << "Failed to open video source: " << initString << std::endl;
        return -1;
    }

    cr::video::Frame frame;
    while (true)
    {
        // Wait up to 1000 ms for new frame.
        if (!source->getFrame(frame, 1000))
        {
            continue;
        }

        // Retrieve current parameters.
        cr::video::VSourceParams params;
        source->getParams(params);

        // Display captured frame using OpenCV.
        cv::Mat cvFrame(frame.height, frame.width, CV_8UC3, frame.data);
        cv::putText(cvFrame,
                    "Frame ID: " + std::to_string(frame.frameId) +
                    " | Cycle: " + std::to_string(params.cycleTimeMks / 1000) + " ms",
                    cv::Point(10, 30),
                    cv::FONT_HERSHEY_SIMPLEX,
                    0.6,
                    cv::Scalar(0, 255, 0),
                    2);

        cv::imshow("VSourceWmf Video Display", cvFrame);
        if (cv::waitKey(1) == 27) // ESC key to exit
        {
            break;
        }
    }

    delete source;
    return 0;
}

Table of contents