
VSourceFile C++ library
v2.0.2
Table of contents
- Overview
- Versions
- Library files
- VSourceFile class description
- VSourceFile class declaration
- getVersion method
- openVSource method
- initVSource method
- isVSourceOpen method
- closeVSource method
- getFrame method
- setParam method
- getParam method
- getParams method
- executeCommand method
- encodeSetParamCommand method of VSource interface class
- encodeCommand method of VSource interface class
- decodeCommand method of VSource interface class
- decodeAndExecuteCommand method
- MP4 file support
- AVI file support
- Data structures
- VSourceParams class description
- Build and connect to your project
- Portability
- Simple example
Overview
VSourceFile C++ library provides video frame capture and full decoding from encoded H264, HEVC, JPEG and uncompressed BGR24 video files (encoded MP4V frames are captured but not decoded: the library has no MP4V decoder): raw elementary streams (.h264, *.hevc, *.mjpeg) as well as MP4 (.mp4, .mov, *.m4v) and AVI (.avi) containers. The library inherits its interface from VSource interface class. The library integrates built-in static decoders (VDecoderH264, VDecoderH265, VDecoderJPEG) and format converter (FormatConverter), enabling users to obtain fully decoded frames in any desired pixel format (such as NV12, BGR24, RGB24, YUYV, UYVY, GRAY, YUV24, NV21, YU12, YV12) or raw encoded bitstreams directly.
VSourceFile is general-purpose software: it is not tied to any sector or application, and the developer of a program decides what the program does with it.
Key Features
- Built-in video decoding: Built-in decoders for H.264, H.265 (HEVC), and JPEG/MJPEG video streams to NV12 and conversion to any supported pixel format.
- Output format flexibility: The desired output format is selected via the
frame.fourccfield passed togetFrame(...):- When set to a compressed format (
Fourcc::H264,Fourcc::HEVC,Fourcc::JPEG), the library delivers raw encoded packets matching the file’s native codec without decoding or conversion. - When set to any uncompressed format (
Fourcc::NV12,Fourcc::BGR24,Fourcc::RGB24,Fourcc::YUYV,Fourcc::UYVY,Fourcc::GRAY,Fourcc::YUV24,Fourcc::NV21,Fourcc::YU12,Fourcc::YV12), the library automatically decodes the video frame and converts it to the requested pixel format. - The
VSourceParams::fourccproperty automatically updates to reflect the delivered frame format and is ignored duringinitVSource(...).
- When set to a compressed format (
- No frame drop by the library: Acquisition and decoding run on a background worker thread with single-frame handoff. The worker thread waits for the consumer to consume the current ready frame before delivering the next, so a frame that was read and decoded is never replaced by a newer one.
- Accurate frame pacing: Automatic FPS detection and sleep-based drift compensation maintain precise frame delivery rate without busy waiting. If consumer processing is delayed, the next frame is delivered immediately and the following frames are paced from that moment (the lost time is not caught up).
- Fixed decoder thread pool: Static decoders and FormatConverter use 2 worker threads each; the user cannot change this.
- Forced full color range expansion: All decoders are forcibly configured (
CUSTOM_3 = 1.0f) to automatically convert limited color range input data to full color range upon decoding. - ROI (Region of Interest) cropping: Support for ROI parameters (
ROI_X,ROI_Y,ROI_WIDTH,ROI_HEIGHT).VSourceParams::widthandheightalways reflect the full native resolution of the video file, while ROI cropping is applied during output copying. - Container and stream support: Built-in container parsers for MP4/MOV/M4V and AVI, as well as raw elementary streams with automatic loopback on EOF.
Versions
Table 1 - Library versions.
| Version | Release date | What’s new |
|---|---|---|
| 1.0.0 | 29.11.2023 | First version |
| 1.0.1 | 15.01.2024 | - Submodules updated. |
| 1.0.2 | 20.03.2024 | - VSource class updated. - Logger class updated. - Documentation updated. |
| 1.0.3 | 20.05.2024 | - VSource class updated. - Logger class updated. - Documentation updated. |
| 1.0.4 | 15.07.2024 | - VSource class updated. - Logger class updated. - CMake updated. - Example added. |
| 1.0.5 | 03.04.2025 | - Logger submodule update. |
| 1.0.6 | 25.07.2025 | - Fix frame interval initialization in openVSource method. |
| 1.1.0 | 16.09.2025 | - Add JPEG support. |
| 1.1.1 | 18.03.2026 | - Fix H.265 frame boundary detection to handle all HEVC VCL NAL types (0-21), including CRA and BLA. |
| 2.0.0 | 30.09.2026 | - Removed Logger dependency. - Added full video decoding support (H264, H265/HEVC, JPEG). - Forcible conversion of limited color range to full color range for all decoders. - Dynamic output format selection via frame.fourcc in getFrame(...).- Added ROI cropping support ( ROI_X, ROI_Y, ROI_WIDTH, ROI_HEIGHT).- Zero frame drop background worker thread with single-frame handoff. - Added MP4 (*.mp4, *.mov, *.m4v, *.avi) file support. - Added automatic resolution and FPS detection from file content. - Accurate frame pacing and sleep drift compensation without busy waiting. |
| 2.0.1 | 06.10.2026 | - Fixed lost frames at the start of MP4 / AVI files whose first IDR sample is not marked as a sync sample. - Packet buffer limited to the largest packet of the file and frame area limited in all readers (a small file with a huge frame size in its header no longer allocates the memory of such a frame). - Windows: paths longer than 260 characters and file names containing ‘;’ can be opened. - The destructor does not throw, raw BGR24 AVI streams are validated, the example stops on undecodable files. - Security review (EU CRA): input validation, fuzzing and sanitizer runs, documentation of the hardening. |
| 2.0.2 | 18.10.2026 | - The repository does not contain sub-repositories: the libraries it depends on are expected in the folders next to it (build and connection instructions updated). - Fixed a heap buffer overflow in getFrame(...) when frame.fourcc changed to a format that needs more memory than the format the memory of the frame was allocated for.- Fixed the end of AVI files at the first empty frame (dropped frames are skipped now), AVI files without any frame data are rejected. - MP4: the box parsers the library does not use are removed, the number of tracks is limited to 256, the number of parameter set units of an avcC / hvcC box is checked against the box size. - The frame ID starts again from 0 after the biggest int value, the cycle time parameter is limited to the int range, no exception can leave the worker thread. - ROI parameters, AVI codec names, parameter encoding sizes, JSON example and build instructions corrected in the documentation. |
Library files
The library is supplied as source code only. The user will be given a set of files in the form of a CMake project (repository). The libraries VSourceFile depends on are separate repositories (see Build stand alone). The repository structure is shown below:
CMakeLists.txt --------------- Main CMake file of the library.
example ---------------------- Folder with example application.
CMakeLists.txt ----------- CMake file for example application.
main.cpp ----------------- Source code of example application.
src -------------------------- Folder with source code of the library.
CMakeLists.txt ----------- CMake file of the library.
Impl --------------------- Folder with implementation files.
AviParser.cpp -------- C++ implementation file of AVI parser.
AviParser.h ---------- Header file of AVI parser.
ElementaryStreamReader.cpp -- C++ implementation file of the raw H264 / H265 / MJPEG stream reader.
ElementaryStreamReader.h --- Header file of the raw stream reader.
FileUtils.cpp -------- C++ implementation file of file helper functions.
FileUtils.h ---------- Header file of file helper functions.
Mp4Node.cpp ---------- C++ implementation file of MP4 box nodes.
Mp4Node.h ------------ Header file with MP4 box node classes.
Mp4Parser.cpp -------- C++ implementation file of MP4 parser.
Mp4Parser.h ---------- Header file of MP4 parser.
VSourceFileImpl.cpp -- Implementation class source code.
VSourceFileImpl.h ---- Implementation class header file.
VSourceFile.cpp ---------- C++ interface wrapper implementation.
VSourceFile.h ------------ Main library header file.
VSourceFileVersion.h ----- Header file which includes version of the library.
VSourceFileVersion.h.in -- CMake service file to generate version header.
static ----------------------- Folder with the logo image.
VSourceFile class description
VSourceFile class declaration
VSourceFile class is declared in VSourceFile.h file. Class declaration:
namespace rapidpixel
{
/// Video capture from encoded video files class.
class VSourceFile : public VSource
{
public:
/// Class constructor.
VSourceFile();
/// Class destructor. Closes the video source.
~VSourceFile() override;
/// The object owns a worker thread: not copyable and not movable.
VSourceFile(const VSourceFile&) = delete;
VSourceFile& operator=(const VSourceFile&) = delete;
VSourceFile(VSourceFile&&) = delete;
VSourceFile& operator=(VSourceFile&&) = delete;
/// 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 parameter.
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() method returns string of current version of VSourceFile class. Method declaration:
static std::string getVersion();
Method can be used without VSourceFile class instance:
std::cout << "VSourceFile class version: " << VSourceFile::getVersion() << std::endl;
Console output:
VSourceFile class version: 2.0.2
openVSource method
The openVSource(…) method initializes video source. Instead of openVSource(…) method user can call initVSource(…) method. Video resolution (width, height) and frame rate (FPS) are automatically detected from the video file content (from SPS in H.264/H.265 streams, SOF markers in JPEG/MJPEG streams, container tracks in MP4/MOV files, and AVI headers). If FPS is not specified in the file or is invalid, a default value of 30.0 FPS is set. Method declaration:
bool openVSource(std::string& initString) override;
| Parameter | Value |
|---|---|
| initString | Initialization string specifying the video file name or path (e.g. video.mp4 or /path/to/stream.h264). Supported file extensions: .h264, .264, .h265, .hevc, .jpg, .jpeg, .mjpg, .mjpeg, .mp4, .mov, .m4v, .avi.Resolution and FPS are detected automatically from the file content. If the file does not specify FPS (e.g. raw MJPEG) or contains an invalid value, it defaults to 30.0 FPS. A string of the form <file name>;<width>;<height>;<fps> is also accepted (the extra fields are not used). The whole string is tried as the file path first, because a file name may contain ;; only if that file can not be opened, the part before the first ; is used. The file name is used as it is given (no search in other folders). A frame size outside 1 - 16384 pixels in each dimension or above 134,217,728 pixels (16384 x 8192) in total, and a file the library can not read (damaged, unsupported container or codec) are rejected. The frame size comes from the file: a file that declares the biggest accepted frame makes the decoders and the format converter allocate the memory for frames of that size (about 0.5 GB was measured for 16384 x 8192 pixels, even for a file of a few hundred bytes). |
Returns: TRUE if the video source open or FALSE if not.
initVSource method
The initVSource(…) method initializes video source by a set of parameters. Instead of initVSource(…) method user can call openVSource(…) method. Method declaration:
bool initVSource(VSourceParams& params) override;
| Parameter | Value |
|---|---|
| params | VSourceParams class object. Only the source field needs to be set with the video file path. The fourcc field in params is ignored during initialization. The library automatically detects resolution (width, height) and fps from the file content and updates the fields of the params object upon successful initialization. If FPS is not present or invalid, it defaults to 30.0 FPS. ROI parameters (roiX, roiY, roiWidth, roiHeight) and target fps can optionally be specified in params. |
Returns: TRUE if the video source initialized or FALSE if not.
isVSourceOpen method
The isVSourceOpen() method returns video source initialization status. The initialization status is also included in the VSourceParams class. Method declaration:
bool isVSourceOpen() override;
Returns: TRUE if the video source open (initialized) or FALSE if not.
closeVSource method
The closeVSource() method is intended to close the video source and terminate background worker threads. Method declaration:
void closeVSource() override;
getFrame method
The getFrame(…) method retrieves video frames. Acquisition and decoding run on a dedicated background worker thread with single-frame handoff (the worker thread waits until the consumer consumes the frame, guaranteeing zero frame drops). The video source automatically loops back to the beginning when reaching the end of the file. A frame of the file which can not be read or decoded (damaged, bigger than the packet buffer, no decoder for the codec, empty) is skipped. Method declaration:
bool getFrame(Frame& frame, int32_t timeoutMsec = 0) override;
| Parameter | Value |
|---|---|
| frame | Output video frame (see Frame class description). Output Format Selection: - Compressed formats ( Fourcc::H264, Fourcc::HEVC, Fourcc::JPEG): The library bypasses decoding and provides raw encoded packets matching the file’s native codec.- Uncompressed formats ( Fourcc::NV12, Fourcc::BGR24, Fourcc::RGB24, Fourcc::YUYV, Fourcc::UYVY, Fourcc::GRAY, Fourcc::YUV24, Fourcc::NV21, Fourcc::YU12, Fourcc::YV12): The library automatically decodes the video frame to NV12 using the appropriate static decoder (VDecoderH264, VDecoderH265, or VDecoderJPEG) and converts it to the requested pixel format using FormatConverter. If the conversion is not possible (unsupported format or odd frame size) the frame is delivered in the format it has before the conversion (NV12, or BGR24 for uncompressed AVI files): frame.fourcc tells which.VSourceParams::fourcc is automatically updated to reflect the delivered format. ROI Cropping: If ROI is configured ( ROI_X, ROI_Y, ROI_WIDTH, ROI_HEIGHT), the output frame is cropped to the specified ROI rectangle, while VSourceParams::width and height remain the full native video resolution. See the ROI_X - ROI_HEIGHT rows of Table 5.Memory of the frame: the same frame object can be used for every call. The method allocates new memory for the frame only if the memory the frame has is too small for the new data (a bigger pixel format or a bigger packet). The method takes the size of the usable memory from the frame.size field of the frame (the Frame class uses it in the same way): do not change data, size, width or height of the frame by hand. The format can be changed between two calls by setting frame.fourcc: the frames the worker thread has prepared in the previous format are dropped, so the frame delivered after a change is not necessarily the next frame of the file. The frame object must not be shared with another thread during the call.Frame ID: frame.frameId counts the delivered frames from 0 after the file is opened and starts again from 0 after the biggest int value. |
| timeoutMsec | Timeout to wait for new frame data: - timeoutMsec == -1 - Method will wait endlessly until new data arrives. - timeoutMsec == 0 - Method will only check if new data exists. - timeoutMsec > 0 - Method will wait for new data for the specified time in milliseconds. Frame rate pacing is maintained according to the detected or user-configured FPS using sleep-based drift compensation without busy waiting. If consumer processing takes longer than the frame interval, the next frame is delivered immediately without delay. |
Returns: TRUE if new data exists and is copied or FALSE if not (no file is open, no frame arrived within the timeout, or a whole pass over the file gave no frame in the requested format, for example for a codec the library has no decoder for). The frame is not changed if FALSE is returned.
Thread safety: getParams(…), getParam(…), setParam(…) and isVSourceOpen() can be called from any thread. openVSource(…), initVSource(…), closeVSource() and getFrame(…) must be called from one thread at a time.
setParam method
The setParam(…) method is designed to set new video source parameter values. The method can be used after video source initialization. Method declaration:
bool setParam(VSourceParam id, float value) override;
| Parameter | Description |
|---|---|
| id | Video source parameter ID according to VSourceParam enum. Supported: LOG_LEVEL, FPS, ROI_X, ROI_Y, ROI_WIDTH, ROI_HEIGHT. |
| value | Video source parameter value. |
Returns: TRUE if the parameter was set or FALSE if not.
getParam method
The getParam(…) method returns video source parameter values. Method declaration:
float getParam(VSourceParam id) override;
| Parameter | Description |
|---|---|
| id | Video source parameter ID according to the VSourceParam enum. Supported: LOG_LEVEL, WIDTH, HEIGHT, CYCLE_TIME_MKS, FPS, IS_OPEN, ROI_X, ROI_Y, ROI_WIDTH, ROI_HEIGHT. |
Returns: parameter value or -1 if the parameter is not supported.
getParams method
The getParams(…) method returns all video source parameters in the form of a VSourceParams class object. The method call is thread-safe and can be safely called from any thread. Method declaration:
void getParams(VSourceParams& params) override;
| Parameter | Description |
|---|---|
| params | VSourceParams class object. |
executeCommand method
The executeCommand(…) method is designed to execute video source action commands. The library does not support commands. Method declaration:
bool executeCommand(VSourceCommand id) override;
| Parameter | Description |
|---|---|
| id | Video source command ID according to VSourceCommand enum. |
Returns: always returns FALSE.
encodeSetParamCommand method of VSource interface class
The encodeSetParamCommand(…) static method is designed to encode commands to change any parameter in a 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 commands. The VSource class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeSetParamCommand(…) is designed to encode SET_PARAM commands. 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 bytes. |
| 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 a VSource class instance. This method is used on the client side (control system). Command encoding example:
// Buffer for encoded data.
uint8_t data[11];
// Size of encoded data.
int size = 0;
// Parameter value.
const float outValue = 12.0f;
// Encode command.
VSource::encodeSetParamCommand(data, size, VSourceParam::EXPOSURE, outValue);
encodeCommand method of VSource interface class
The encodeCommand(…) static method is designed to encode commands to perform action commands in a 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 commands. The VSource class provides two types of commands: a parameter change command (SET_PARAM) and an action command (COMMAND). encodeCommand(…) is designed to encode COMMAND (action commands). 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 a VSource class instance. This method is used on the client side (control system). Command encoding example:
// Buffer for encoded data.
uint8_t data[7];
// Size of encoded data.
int size = 0;
// Encode command.
VSource::encodeCommand(data, size, VSourceCommand::RESTART);
decodeCommand method of VSource interface class
The decodeCommand(…) static method is designed to decode action commands on the 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. Must be exactly 11 bytes for SET_PARAM and exactly 7 bytes for COMMAND (other sizes give -1). |
| paramId | Parameter ID according to VSourceParam enum. After decoding a SET_PARAM command the method will return the parameter ID. |
| commandId | Command ID according to VSourceCommand enum. After decoding a COMMAND the method will return the command ID. |
| value | Parameter value (after decoding a SET_PARAM command). |
Returns: 0 - in case of decoding a COMMAND, 1 - in case of decoding a SET_PARAM command or -1 in case of errors.
decodeAndExecuteCommand method
The decodeAndExecuteCommand(…) method decodes and executes commands on the video source side. The library doesn’t support decoding and executing commands. Method declaration:
bool decodeAndExecuteCommand(uint8_t* data, int size) override;
| Parameter | Description |
|---|---|
| data | Pointer to input command. |
| size | Size of command. Must be 11 bytes for SET_PARAM and 7 bytes for COMMAND. |
Returns: always returns FALSE.
MP4 file support
Besides raw elementary streams the library reads video from MP4 containers (*.mp4, *.mov and *.m4v files). MP4 files are parsed by the built-in Mp4Parser class, so no third-party demultiplexer is needed. The parser walks the box tree of the file, takes the first video track it can decode and gives its frames one by one. Frame data is read from the file only when the user asks for a frame: only the sample tables of the track are held in memory.
Supported MP4 files
Table 2 - Video sample entries the library reads.
| Sample entry | Output FOURCC | Notes |
|---|---|---|
| avc1, avc3 | H264 | Decoder configuration is taken from the avcC box. |
| hev1, hvc1 | HEVC | Decoder configuration is taken from the hvcC box. |
| jpeg, mjpa, mjpb | JPEG | Motion JPEG stored the QuickTime way. |
| mp4v | JPEG / MP4V | Motion JPEG when the esds box declares object type 0x6C (JPEG), or MPEG-4 Part 2 Visual (Simple/Advanced Simple Profile) when object type is 0x20 with decoderSpecificInfo prepended to keyframes (output FOURCC “MP4V”). |
Files with more than one track (video plus audio, for example) are supported: the library takes the first track with the vide handler and a supported sample entry, other tracks are ignored. Both 32-bit (stco) and 64-bit (co64) chunk offset tables are supported, so files bigger than 4 GB are read as well. Fragmented MP4 files (moof / traf boxes with tfhd / trun, no sample tables in moov) are supported too: the sample table is built from the movie fragments.
For MP4 files the frame size is taken from the sample entry of the track (or from the tkhd box if the sample entry carries no size) and the frame rate is calculated from the media time scale (mdhd box) and the total decoding time of the track (stts box). The pixel format of the output frames is taken from the sample entry as well, the file extension says nothing about it.
Output video frames
The library gives frames in the same form for MP4 files as for raw elementary stream files, so the same decoder can be used for both:
- H264 and HEVC frames are converted into an Annex-B elementary stream: the length prefix of every NAL unit is replaced with a 00 00 00 01 start code. The parameter sets from the avcC / hvcC box (SPS and PPS for H264, VPS, SPS and PPS for HEVC) are put in front of the first frame, of every frame the sample table (stss) marks as a key frame and of every frame that contains an IDR / IRAP picture, unless the frame carries a sequence parameter set itself. So a decoder can start from the beginning of the file and from any key frame, also if the sample table of the file does not list its first IDR picture (some camera files).
- JPEG frames are given as they are stored: each frame is a complete JPEG image.
- MP4V frames are MPEG-4 Part 2 elementary stream frames: decoder configuration from decoderSpecificInfo (VOL header) is prepended to key frames.
When the end of the file is reached the library starts again from the first frame of the track, the same way it loops raw elementary stream files.
Note: the Frame class allocates width * height * 4 bytes for compressed pixel formats. The library does not read a frame of a MP4 file that is bigger than that (a very high bitrate recording) or than the biggest frame of the file: such a frame is skipped and getFrame(…) does not deliver it.
AVI file support
Besides MP4 and raw elementary streams, the library reads video from AVI containers (*.avi files). AVI files are parsed by the built-in AviParser class, with zero third-party dependencies. The parser supports standard RIFF AVI 1.0 files as well as OpenDML / AVI 2.0 multi-RIFF (AVIX) extensions for files larger than 1-2 GB.
Supported AVI files
Table 3 - Video stream types and codecs supported in AVI files.
| Stream FOURCC / Compression | Output FOURCC | Notes |
|---|---|---|
| MJPG, mjpg, JPEG, jpeg | JPEG | Motion JPEG video frames. |
| H264, h264, X264, x264, AVC1, avc1 | H264 | H.264 / AVC video frames (Annex-B format). |
| HEVC, hevc, HVC1, hvc1 | H265 | HEVC / H.265 video frames (Annex-B format). |
| XVID, xvid, DIVX, divx, DX50, dx50, MP4V, mp4v, FMP4, fmp4 | MP4V | MPEG-4 Part 2 Visual elementary stream. |
| 0x00000000 (BI_RGB), DIB | BGR24 | Uncompressed 24-bit RGB/BGR video frames. Bottom-up bitmaps (biHeight > 0) are automatically flipped vertically so the output image orientation is top-down. A stream whose samples are smaller than one frame is not uncompressed video and is not accepted as such. |
- Index support: The parser supports both standard
idx1index tables (automatically detecting relative vs. absolute chunk offsets) and directmovichunk scanning (includingLIST recchunks) for indexless or live-stream recorded files. - Audio and auxiliary chunks: Non-video chunks (such as audio streams
01wb) and auxiliary metadata chunks (such asJUNK) are cleanly skipped. - Dropped frames: A video chunk of size 0 (a dropped frame) gives no data and is skipped. A file whose video chunks are all empty is not opened.
- Looping: When the end of the AVI file is reached, the library rewinds to the first video frame, so the file is played in a loop.
Output AVI video frames
The library delivers AVI video frames according to their compression format:
- JPEG: Each frame is delivered as an intact, independent JPEG image.
- H264 and H265: Annex-B format NAL units.
- MP4V: MPEG-4 Part 2 Visual elementary stream frames.
- BGR24: Uncompressed 24-bit BGR image data (
width * height * 3bytes), oriented top-down.
Data structures
The VSource.h file defines IDs for parameters (VSourceParam enum) and IDs for commands (VSourceCommand enum).
VSourceCommand enum
Enum declaration:
enum class VSourceCommand
{
/// Restart.
RESTART = 1
};
Table 4 - Video source commands description. Some commands may be unsupported by particular video source classes.
| Command | Description |
|---|---|
| RESTART | Not supported by the library. |
VSourceParam enum
Enum declaration:
enum class VSourceParam
{
/// [read/write] Logging mode. Values: 0 - Disable, 1 - Only file,
/// 2 - Only terminal, 3 - File and terminal.
LOG_LEVEL = 1,
/// [read/write] Frame width. User can set frame width before initialization
/// or after. Some video source classes may set width automatically.
WIDTH,
/// [read/write] Frame height. User can set frame height before
/// initialization or after. Some video source classes may set height
/// automatically.
HEIGHT,
/// [read/write] Gain mode. Value depends on implementation but it is
/// recommended to keep default values: 0 - Manual control, 1 - Auto.
GAIN_MODE,
/// [read/write] Gain value. Value: 0(min for particular video source class)
/// - 65535(max for particular video source class).
GAIN,
/// [read/write] Exposure mode. Value depends on implementation but it is
/// recommended to keep default values: 0 - Manual control, 1 - Auto.
EXPOSURE_MODE,
/// [read/write] Exposure value. Value: 0(min for particular video source
/// class) - 65535(max for particular video source class).
EXPOSURE,
/// [read/write] Focus mode. Value depends on implementation but it is
/// recommended to keep default values: 0 - Manual control, 1 - Auto.
FOCUS_MODE,
/// [read/write] Focus position. Value: 0(full near) - 65535(full far).
FOCUS_POS,
/// [read only] Video capture cycle time. **VSource** class sets this value
/// automatically. This parameter means time interval between two captured
/// video frame.
CYCLE_TIME_MKS,
/// [read/write] FPS. User can set frame FPS before initialization or after.
/// Some video source classes may set FPS automatically.
FPS,
/// [read only] Open flag. 0 - not open, 1 - open.
IS_OPEN,
/// [read/write] Region of interest upper left corner x coordinate.
ROI_X,
/// [read/write] Region of interest upper left corner y coordinate.
ROI_Y,
/// [read/write] Region of interest width.
ROI_WIDTH,
/// [read/write] Region of interest height.
ROI_HEIGHT,
/// [read/write] Custom parameter. Depends on implementation.
CUSTOM_1,
/// [read/write] Custom parameter. Depends on implementation.
CUSTOM_2,
/// [read/write] Custom parameter. Depends on implementation.
CUSTOM_3
};
Table 5 - Video source params description. Some params may be unsupported by particular video source classes.
| Parameter | Access | Description |
|---|---|---|
| LOG_LEVEL | read / write | Logging mode. Values: 0 - Disable, 1 - Only file, 2 - Only terminal, 3 - File and terminal. The library only stores the value (other values are rejected): it does not write any log. |
| WIDTH | read / write | Not supported by the library to set, only read. |
| HEIGHT | read / write | Not supported by the library to set, only read. |
| GAIN_MODE | read / write | Not supported by the library. |
| GAIN | read / write | Not supported by the library. |
| EXPOSURE_MODE | read / write | Not supported by the library. |
| EXPOSURE | read / write | Not supported by the library. |
| FOCUS_MODE | read / write | Not supported by the library. |
| FOCUS_POS | read / write | Not supported by the library. |
| CYCLE_TIME_MKS | read only | Frame cycle time, microseconds. The actual elapsed time between consecutive frame deliveries. Maintained in accordance with the fps parameter with automatic sleep drift compensation. |
| FPS | read / write | Frame rate in FPS. Automatically detected from the video file (or default 30.0 FPS). Can also be dynamically updated at runtime. |
| IS_OPEN | read only | Open flag. 0 - not open, 1 - open. |
| ROI_X | read / write | Region of interest upper-left X coordinate (pixels). setParam(…) accepts values from 0 to 16384, other values (and NaN) are rejected. When a frame is delivered the coordinate is limited to [0, width - 1]. Default: 0. |
| ROI_Y | read / write | Region of interest upper-left Y coordinate (pixels). setParam(…) accepts values from 0 to 16384, other values (and NaN) are rejected. When a frame is delivered the coordinate is limited to [0, height - 1]. Default: 0. |
| ROI_WIDTH | read / write | Region of interest width (pixels). setParam(…) accepts values from 0 to 16384. The ROI is applied only if ROI_WIDTH and ROI_HEIGHT are both greater than 0 and the rectangle is not the whole frame. The width is limited to the rest of the frame (to the right of ROI_X). Default: 0 (no ROI). |
| ROI_HEIGHT | read / write | Region of interest height (pixels). setParam(…) accepts values from 0 to 16384. The height is limited to the rest of the frame (below ROI_Y). Default: 0 (no ROI). |
| CUSTOM_1 | read / write | Not supported by the library. |
| CUSTOM_2 | read / write | Not supported by the library. |
| CUSTOM_3 | read / write | Not supported by the library. |
The ROI is not applied to compressed frames (H264, HEVC, JPEG, MP4V). For the formats NV12, NV21, YU12 and YV12 the ROI position and size are rounded down to even numbers (the smallest size is 2 x 2), for YUYV and UYVY the X coordinate and the width are rounded down to even numbers (the smallest width is 2), so the delivered frame can be a little smaller than the ROI.
VSourceParams class description
VSourceParams class declaration
VSourceParams class is used for video source initialization (initVSource(…) method) or to get all actual params (getParams(…) method). Also VSourceParams provides structure to write/read params from JSON files (JSON_READABLE macro, see ConfigReader class description) and provides methods to encode and decode params. Class declaration:
class VSourceParams
{
public:
/// Logging mode. Values: 0 - Disable, 1 - Only file,
/// 2 - Only terminal, 3 - File and terminal.
int logLevel{0};
/// Video source: file, video stream, video device, camera num, etc.
std::string source{"/dev/video0"};
/// FOURCC: RGB24, BGR24, YUYV, UYVY, GRAY, YUV24, NV12, NV21, YU12, YV12.
/// Value says to video source class which pixel format preferable for
/// output video frame. Particular video source class can ignore this params
/// during initialization. Parameters should be set before initialization.
std::string fourcc{"YUYV"};
/// Frame width. User can set frame width before initialization
/// or after. Some video source classes may set width automatically.
int width{1920};
/// Frame height. User can set frame height before
/// initialization or after. Some video source classes may set height
/// automatically.
int height{1080};
/// Gain mode. Value depends on implementation but it is
/// recommended to keep default values: 0 - Manual control, 1 - Auto.
int gainMode{1};
/// Gain value. Value: 0(min for particular video source class)
/// - 65535(max for particular video source class).
int gain{0};
/// Exposure mode. Value depends on implementation but it is
/// recommended to keep default values: 0 - Manual control, 1 - Auto.
int exposureMode{1};
/// Exposure value. Value: 0(min for particular video source
/// class) - 65535(max for particular video source class).
int exposure{1};
/// Focus mode. Value depends on implementation but it is
/// recommended to keep default values: 0 - Manual control, 1 - Auto.
int focusMode{1};
/// Focus position. Value: 0(full near) - 65535(full far).
int focusPos{0};
/// Video capture cycle time. **VSource** class sets this value
/// automatically. This parameter means time interval between two captured
/// video frame.
int cycleTimeMks{0};
/// FPS. User can set frame FPS before initialization or after.
/// Some video source classes may set FPS automatically.
float fps{0.0f};
/// Open flag. false - not open, true - open.
bool isOpen{false};
/// Region of interest upper left corner x coordinate.
int roiX{0};
/// Region of interest upper left corner y coordinate.
int roiY{0};
/// Region of interest width.
int roiWidth{0};
/// Region of interest height.
int roiHeight{0};
/// Custom parameter. Depends on implementation.
float custom1{0.0f};
/// Custom parameter. Depends on implementation.
float custom2{0.0f};
/// Custom parameter. Depends on implementation.
float custom3{0.0f};
JSON_READABLE(VSourceParams, logLevel, source, fourcc, width, height,
gainMode, exposureMode, focusMode, fps, roiX, roiY, roiWidth,
roiHeight, custom1, custom2, custom3)
/// Default constructor.
VSourceParams() = default;
/// Copy constructor.
VSourceParams(const VSourceParams& src) = default;
/// Move constructor.
VSourceParams(VSourceParams&& src) = default;
/// Copy assignment operator.
VSourceParams& operator= (const VSourceParams& src) = default;
/// Move assignment operator.
VSourceParams& operator= (VSourceParams&& src) = default;
/// Encode params.
bool encode(uint8_t* data, int bufferSize, int& size,
VSourceParamsMask* mask = nullptr);
/// Decode params.
bool decode(uint8_t* data, int dataSize);
};
Table 6 - VSourceParams class fields description.
| Field | type | Description |
|---|---|---|
| logLevel | int | Logging mode. Values: 0 - Disable, 1 - Only file, 2 - Only terminal, 3 - File and terminal. The library only stores the value: it does not write any log. |
| source | string | Video file name with extensions .h264, .264, .h265, .hevc, .jpg, .jpeg, .mjpg, .mjpeg, .mp4, .mov, .m4v, or .avi. |
| fourcc | string | Video data format. Values: “H264”, “H265”, “JPEG”, “MP4V”, or “BGR24”. Automatically set from video stream content upon opening. |
| width | int | Frame width. Automatically detected from the video file content upon opening. |
| height | int | Frame height. Automatically detected from the video file content upon opening. |
| gainMode | int | Not supported by the library. |
| gain | int | Not supported by the library. |
| exposureMode | int | Not supported by the library. |
| exposure | int | Not supported by the library. |
| focusMode | int | Not supported by the library. |
| focusPos | int | Not supported by the library. |
| cycleTimeMks | int | Frame cycle time, microseconds. Calculated based on the actual frame delivery timing according to the detected or default fps. |
| fps | float | FPS (frames per second). Automatically detected from the video file content (defaults to 30.0 if not present or invalid in file stream). The library uses this value to control frame delivery timing. |
| isOpen | bool | Open flag. false - not open, true - open. |
| roiX | int | Region of interest upper-left X coordinate (see ROI_X in Table 5). Used by initVSource(…) if roiWidth and roiHeight are greater than 0. |
| roiY | int | Region of interest upper-left Y coordinate (see ROI_Y in Table 5). Used by initVSource(…) if roiWidth and roiHeight are greater than 0. |
| roiWidth | int | Region of interest width (see ROI_WIDTH in Table 5). Used by initVSource(…). |
| roiHeight | int | Region of interest height (see ROI_HEIGHT in Table 5). Used by initVSource(…). |
| custom1 | float | Not supported by the library. |
| custom2 | float | Not supported by the library. |
| custom3 | float | Not supported by the library. |
Note: VSourceParams class fields listed in Table 6 must reflect params set/get by methods setParam(…) and getParam(…).
Serialize video source params
VSourceParams class provides method encode(…) to serialize video source params (fields of VSourceParams class, see Table 6). Serialization of video source params is necessary in case when you need to send video source params via communication channels. The method doesn’t encode fields: source and fourcc. The method provides options to exclude particular parameters from serialization. To do this the method inserts a binary mask (3 bytes) where each bit represents a particular parameter and the decode(…) method recognizes it. Method declaration:
bool encode(uint8_t* data, int bufferSize, int& size, VSourceParamsMask* mask = nullptr);
| Parameter | Value |
|---|---|
| data | Pointer to data buffer. |
| size | Size of encoded data. 79 bytes by default (all parameters), 6 bytes if all flags of the mask are cleared. |
| bufferSize | Data buffer size. If buffer size is smaller than required, the buffer will be filled with fewer parameters. |
| mask | Parameters mask - pointer to VSourceParamsMask structure. VSourceParamsMask (declared in VSource.h file) determines flags for each field (parameter) declared in VSourceParams class. If the user wants to exclude any parameters from serialization, he can put a pointer to the mask. If the user wants to exclude a particular parameter from serialization, he should set the corresponding flag in the VSourceParamsMask structure. |
VSourceParamsMask structure declaration:
struct VSourceParamsMask
{
bool logLevel{true};
bool width{true};
bool height{true};
bool gainMode{true};
bool gain{true};
bool exposureMode{true};
bool exposure{true};
bool focusMode{true};
bool focusPos{true};
bool cycleTimeMks{true};
bool fps{true};
bool isOpen{true};
bool roiX{true};
bool roiY{true};
bool roiWidth{true};
bool roiHeight{true};
bool custom1{true};
bool custom2{true};
bool custom3{true};
};
Example without parameters mask:
// Prepare params.
VSourceParams in;
in.source = "any string";
in.logLevel = 0;
// Encode data.
uint8_t data[1024];
int size = 0;
if (!in.encode(data, 1024, size))
{
std::cout << "Can't encode data" << std::endl;
return false;
}
std::cout << "Encoded data size: " << size << " bytes" << std::endl;
Example with parameters mask:
// Prepare params.
VSourceParams in;
in.source = "any string";
in.logLevel = 0;
// Prepare params mask.
VSourceParamsMask mask;
mask.logLevel = false; // Exclude logLevel. Others by default.
// Encode data.
uint8_t data[1024];
int size = 0;
if (!in.encode(data, 1024, size, &mask))
{
std::cout << "Can't encode data" << std::endl;
return false;
}
std::cout << "Encoded data size: " << size << " bytes" << std::endl;
Deserialize video source params
VSourceParams class provides method decode(…) to deserialize video source params (fields of VSourceParams class, see Table 6). Deserialization of video source params is necessary in case when you need to receive video source params via communication channels. The method doesn’t decode fields: source and fourcc. The method automatically recognizes which parameters were serialized by the encode(…) method. Method declaration:
bool decode(uint8_t* data, int dataSize);
| Parameter | Value |
|---|---|
| data | Pointer to data encoded by the encode(…) method. The data must be complete: 79 bytes if all parameters were encoded. |
| dataSize | Size of data. |
Returns: TRUE if data decoded (deserialized) or FALSE if not.
Example:
// Encode data.
VSourceParams in;
uint8_t data[1024];
int size = 0;
if (!in.encode(data, 1024, size))
{
std::cout << "Can't encode data" << std::endl;
return false;
}
std::cout << "Encoded data size: " << size << " bytes" << std::endl;
// Decode data.
VSourceParams out;
if (!out.decode(data, size))
{
std::cout << "Can't decode data" << std::endl;
return false;
}
Read params from JSON file and write to JSON file
VSource library depends on the ConfigReader library which provides methods to read params from JSON files and to write params to JSON files. Example of writing and reading params to JSON file:
// Write params to file.
VSourceParams in;
rapidpixel::ConfigReader inConfig;
if (!inConfig.set(in, "vSourceParams") || !inConfig.writeToFile("TestVSourceParams.json"))
{
std::cout << "Can't write config file" << std::endl;
return false;
}
// Read params from file.
rapidpixel::ConfigReader outConfig;
if (!outConfig.readFromFile("TestVSourceParams.json"))
{
std::cout << "Can't open config file" << std::endl;
return false;
}
TestVSourceParams.json will look like:
{
"vSourceParams": {
"logLevel": 0,
"source": "/dev/video0",
"fourcc": "YUYV",
"width": 1920,
"height": 1080,
"gainMode": 1,
"exposureMode": 1,
"focusMode": 1,
"fps": 0.0,
"roiX": 0,
"roiY": 0,
"roiWidth": 0,
"roiHeight": 0,
"custom1": 0.0,
"custom2": 0.0,
"custom3": 0.0
}
}
Build and connect to your project
Build stand alone
The repository does not contain sub-repositories. The libraries VSourceFile depends on (Frame, ConfigReader, VSource, VCodec, VDecoderH264, VDecoderH265, VDecoderJPEG, FormatConverter) and the libraries used by the example (SimpleUI, SimpleFileDialog) must be cloned into the same folder as VSourceFile. The folder structure must be:
<work folder>
VSourceFile
Frame
ConfigReader
VSource
VCodec
VDecoderH264
VDecoderH265
VDecoderJPEG
FormatConverter
SimpleUI
SimpleFileDialog
Typical commands to build the library and the example (use the URLs of the repositories provided to you):
git clone <VSourceFile repository URL>
git clone <Frame repository URL>
git clone <ConfigReader repository URL>
git clone <VSource repository URL>
git clone <VCodec repository URL>
git clone <VDecoderH264 repository URL>
git clone <VDecoderH265 repository URL>
git clone <VDecoderJPEG repository URL>
git clone <FormatConverter repository URL>
git clone <SimpleUI repository URL>
git clone <SimpleFileDialog repository URL>
cd VSourceFile
mkdir build
cd build
cmake ..
make
On Windows use cmake --build . --config Release instead of make. If VSourceFile is the top-level CMake project, the main CMakeLists.txt file adds the folders ../Frame, ../ConfigReader, ../VSource, ../VCodec, ../VDecoderH264, ../VDecoderH265, ../VDecoderJPEG and ../FormatConverter (in this order) before the library itself and the folders ../SimpleUI and ../SimpleFileDialog before the example. If a folder does not exist CMake stops with an error.
CMake options
Table 7 - CMake options of the repository. In the options below ${PARENT} is the prefix defined by the top-level project (empty if VSourceFile is the top-level project).
| Option | Default | Description |
|---|---|---|
| ${PARENT}_VSOURCE_FILE | ON | Build the library. |
| ${PARENT}_VSOURCE_FILE_EXAMPLE | ON (stand alone), OFF (included in other project) | Build the example application. |
| ${PARENT}_SUBMODULE_CACHE_OVERWRITE | ON | Forced rewriting of the options above in the CMake cache. The top-level project sets it to OFF when it includes VSourceFile as a sub-repository. |
| CMAKE_BUILD_TYPE | Release (if not specified) | Build type. |
The library has no options for instruction sets. The options of the libraries it depends on (for example the options of the decoders and of FormatConverter) are described in the documentation of these libraries.
Connect to your project
If you want to connect the VSourceFile library to your CMake project as source code you can do the following. For example, if your repository has structure:
CMakeLists.txt
src
CMakeLists.txt
yourLib.h
yourLib.cpp
Create 3rdparty folder in your repository and copy the repositories VSourceFile, Frame, ConfigReader, VSource, VCodec, VDecoderH264, VDecoderH265, VDecoderJPEG and FormatConverter there. New structure of your repository:
CMakeLists.txt
src
CMakeLists.txt
yourLib.h
yourLib.cpp
3rdparty
Frame
ConfigReader
VSource
VCodec
VDecoderH264
VDecoderH265
VDecoderJPEG
FormatConverter
VSourceFile
Create a CMakeLists.txt file in the 3rdparty folder. CMakeLists.txt should contain:
cmake_minimum_required(VERSION 3.13)
################################################################################
## 3RD-PARTY
## dependencies for the project
################################################################################
project(3rdparty LANGUAGES CXX)
################################################################################
## SETTINGS
## basic 3rd-party settings before use
################################################################################
# To inherit the top-level architecture when the project is used as a submodule.
SET(PARENT ${PARENT}_YOUR_PROJECT_3RDPARTY)
# Disable self-overwriting of parameters inside included subdirectories.
SET(${PARENT}_SUBMODULE_CACHE_OVERWRITE OFF CACHE BOOL "" FORCE)
################################################################################
## CONFIGURATION
## 3rd-party submodules configuration
################################################################################
SET(${PARENT}_SUBMODULE_FRAME ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_FRAME)
SET(${PARENT}_FRAME ON CACHE BOOL "" FORCE)
SET(${PARENT}_FRAME_TEST OFF CACHE BOOL "" FORCE)
endif()
SET(${PARENT}_SUBMODULE_CONFIG_READER ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_CONFIG_READER)
SET(${PARENT}_CONFIG_READER ON CACHE BOOL "" FORCE)
SET(${PARENT}_CONFIG_READER_EXAMPLES OFF CACHE BOOL "" FORCE)
SET(${PARENT}_CONFIG_READER_TESTS OFF CACHE BOOL "" FORCE)
endif()
SET(${PARENT}_SUBMODULE_VSOURCE ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_VSOURCE)
SET(${PARENT}_VSOURCE ON CACHE BOOL "" FORCE)
SET(${PARENT}_VSOURCE_TEST OFF CACHE BOOL "" FORCE)
SET(${PARENT}_VSOURCE_EXAMPLE OFF CACHE BOOL "" FORCE)
endif()
SET(${PARENT}_SUBMODULE_VCODEC ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_VCODEC)
SET(${PARENT}_VCODEC ON CACHE BOOL "" FORCE)
endif()
SET(${PARENT}_SUBMODULE_VDECODER_H264 ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_VDECODER_H264)
SET(${PARENT}_VDECODERH264 ON CACHE BOOL "" FORCE)
SET(${PARENT}_VDECODERH264_EXAMPLE OFF CACHE BOOL "" FORCE)
endif()
SET(${PARENT}_SUBMODULE_VDECODER_H265 ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_VDECODER_H265)
SET(${PARENT}_VDECODERH265 ON CACHE BOOL "" FORCE)
SET(${PARENT}_VDECODERH265_EXAMPLE OFF CACHE BOOL "" FORCE)
endif()
SET(${PARENT}_SUBMODULE_VDECODER_JPEG ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_VDECODER_JPEG)
SET(${PARENT}_VDECODERJPEG ON CACHE BOOL "" FORCE)
SET(${PARENT}_VDECODERJPEG_EXAMPLE OFF CACHE BOOL "" FORCE)
endif()
SET(${PARENT}_SUBMODULE_FORMAT_CONVERTER ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_FORMAT_CONVERTER)
SET(${PARENT}_FORMAT_CONVERTER ON CACHE BOOL "" FORCE)
SET(${PARENT}_FORMAT_CONVERTER_BENCHMARK OFF CACHE BOOL "" FORCE)
endif()
SET(${PARENT}_SUBMODULE_VSOURCE_FILE ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_VSOURCE_FILE)
SET(${PARENT}_VSOURCE_FILE ON CACHE BOOL "" FORCE)
SET(${PARENT}_VSOURCE_FILE_EXAMPLE OFF CACHE BOOL "" FORCE)
endif()
################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_FRAME)
add_subdirectory(Frame)
endif()
if (${PARENT}_SUBMODULE_CONFIG_READER)
add_subdirectory(ConfigReader)
endif()
if (${PARENT}_SUBMODULE_VSOURCE)
add_subdirectory(VSource)
endif()
if (${PARENT}_SUBMODULE_VCODEC)
add_subdirectory(VCodec)
endif()
if (${PARENT}_SUBMODULE_VDECODER_H264)
add_subdirectory(VDecoderH264)
endif()
if (${PARENT}_SUBMODULE_VDECODER_H265)
add_subdirectory(VDecoderH265)
endif()
if (${PARENT}_SUBMODULE_VDECODER_JPEG)
add_subdirectory(VDecoderJPEG)
endif()
if (${PARENT}_SUBMODULE_FORMAT_CONVERTER)
add_subdirectory(FormatConverter)
endif()
if (${PARENT}_SUBMODULE_VSOURCE_FILE)
add_subdirectory(VSourceFile)
endif()
File 3rdparty/CMakeLists.txt adds the dependencies of VSourceFile (in the order of their mutual dependencies) and then the VSourceFile folder to your project and excludes the example from compiling (by default the example is excluded from compiling if VSourceFile is included as a sub-repository). When VSourceFile is included in another project it does not add its dependencies: the project must add them. Your repository new structure will be:
CMakeLists.txt
src
CMakeLists.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
Frame
ConfigReader
VSource
VCodec
VDecoderH264
VDecoderH265
VDecoderJPEG
FormatConverter
VSourceFile
Next you need to include folder 3rdparty in the main CMakeLists.txt file of your repository. Add string at the end of your main CMakeLists.txt:
add_subdirectory(3rdparty)
Next you have to include the VSourceFile library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} VSourceFile)
If the dependencies are not added by your project, the compilation stops with an error like VSource.h: No such file or directory.
Done!
Portability
The library code does not depend on the byte order of the processor: the multi-byte fields of MP4 files (big-endian) and of AVI files (little-endian) are assembled from single bytes. The library has no processor specific code; the instruction sets used by the decoders and by FormatConverter are selected by these libraries. On Windows the library loads the system library winmm.dll at run time (from the system directory only, LoadLibraryExA / GetProcAddress) to set the 1 ms timer resolution (timeBeginPeriod) for the frame pacing while the video source is open; if it can not be loaded, the default timer resolution of Windows is used. The library was built and run (all video formats of this document) with MSVC 2022 on Windows x86-64, with GCC 12 and 13 and Clang 15 and 18 on Linux x86-64, and with GCC cross compiler for AArch64 on Linux (run under QEMU): the decoded and the encoded frames were identical.
Simple example
Example shows how to capture and display video frames in YUV24 format using SimpleUI in a loop:
#include <iostream>
#include <string>
#include "SimpleUi.h"
#include "VSourceFile.h"
/// Entry point.
int main(int argc, char* argv[])
{
// Print library version.
std::cout << "VSourceFile v" << rapidpixel::VSourceFile::getVersion() << std::endl;
// Get input video file path.
std::string videoPath;
if (argc > 1)
{
videoPath = argv[1];
}
else
{
std::cout << "Enter path to video file: ";
std::getline(std::cin, videoPath);
}
if (!videoPath.empty() && (videoPath.front() == '"' || videoPath.front() == '\''))
{
videoPath.erase(0, 1);
}
if (!videoPath.empty() && (videoPath.back() == '"' || videoPath.back() == '\''))
{
videoPath.pop_back();
}
if (videoPath.empty())
{
videoPath = "test.mp4";
}
// Create video source object and open video file.
rapidpixel::VSourceFile source;
if (!source.openVSource(videoPath))
{
std::cerr << "Failed to open video file: " << videoPath << std::endl;
return -1;
}
// Get and print video source parameters.
rapidpixel::VSourceParams params;
source.getParams(params);
std::cout << "Opened " << params.source << ": " << params.width << "x" << params.height
<< " @ " << params.fps << " fps data format: " << params.fourcc << std::endl;
// Initialize UI window.
rapidpixel::SimpleUiWindow window("VSourceFile - YUV24");
window.show();
// Frame object initialized to capture and render in YUV24 format.
rapidpixel::Frame frame(params.width, params.height, rapidpixel::Fourcc::YUV24);
// Main loop. The loop stops after a number of failed getFrame(...) calls
// in a row: the file can not be decoded to the requested format.
constexpr int MAX_FAILED_CALLS{10};
int failedCalls{0};
while (window.isOpen())
{
// Ensure the requested format is YUV24 for capture.
frame.fourcc = rapidpixel::Fourcc::YUV24;
// Capture frame (YUV24 format is requested).
if (!source.getFrame(frame, 1000))
{
std::cout << "No input frame" << std::endl;
if (++failedCalls >= MAX_FAILED_CALLS)
{
std::cerr << "The file can not be read in the requested format" << std::endl;
return -1;
}
continue;
}
failedCalls = 0;
std::cout << "New frame " << frame.frameId << " (" << frame.width << "x" << frame.height
<< ") " << frame.size << " bytes cycle time "
<< static_cast<int>(source.getParam(rapidpixel::VSourceParam::CYCLE_TIME_MKS))
<< " us" << std::endl;
// Render frame in YUV24 format.
window.render(frame);
// Process UI events and check for the ESC key (27).
if (window.getKey(1) == 27)
{
break;
}
}
return 0;
}