
VCodecJetPack C++ library
v2.2.0
Table of contents
- Overview
- Versions
- VCodecJetPack class description
- Build and connect to your project
- Encoding example
- Decoding example
- Test application
Overview
The VCodecJetPack C++ library provides hardware video encoding and decoding for H264 and HEVC codecs for Jetson platforms. The VCodecJetPack class inherits interface and data structures from the open-source VCodec library (provides interface for video codecs, source code included, Apache 2.0 license) and also includes the Logger open-source library (provides functions for printing logs, source code included, Apache 2.0 license). The library uses the standard Linux V4L2 (Video4Linux2) API to access NVIDIA hardware encoder and decoder. The library provides a simple programming interface to be implemented in different C++ projects. The library was written with the C++17 standard. The library is supplied as source code only in the form of a CMake project. Encoding time on Jetson Orin NX:
| codec \ resolution | 1920x1080 | 1280x720 |
|---|---|---|
| H264 | ~1 msec | ~0.5 msec |
| HEVC | ~1 msec | ~0.5 msec |
Decoding time on Jetson Orin NX:
| codec \ resolution | 1920x1080 | 1280x720 |
|---|---|---|
| H264 | ~0.5 msec | ~0.3 msec |
| HEVC | ~0.5 msec | ~0.3 msec |
Versions
Table 1 - Library versions.
| Version | Release date | What’s new |
|---|---|---|
| 1.0.0 | 09.12.2022 | - First version. |
| 1.0.1 | 10.04.2023 | - Support for non-standard resolutions. |
| 2.0.0 | 19.09.2023 | - Interface changes to VCodec. - Test application updated. - Added example application. |
| 2.0.1 | 10.01.2024 | - VCodec interface updated. - Examples updated. - Documentation updated. |
| 2.0.2 | 17.05.2024 | - Documentation updated. - Submodules updated. |
| 2.0.3 | 06.08.2024 | - Submodules updated. |
| 2.0.4 | 06.08.2024 | - Updated VCodec interface with variable bitrate parameters. |
| 2.0.5 | 08.01.2025 | - Fixed bug in setParam method. |
| 2.1.0 | 21.02.2025 | - Added JetPack 6 support. |
| 2.1.1 | 03.04.2025 | - Logger submodule updated. |
| 2.1.2 | 02.11.2025 | - VCodec submodule update. - Documentation update. |
| 2.1.3 | 16.03.2026 | - Updated to JetPack v6.x.x. - Requires JetPack v6 or newer. |
| 2.1.4 | 20.03.2026 | - Switched from Jetson Multimedia API to V4L2. |
| 2.2.0 | 20.03.2026 | - Added hardware H264/HEVC decoding support. |
Library files
The library is supplied only as source code. The user is given a set of files in the form of a CMake project (repository). The repository structure is shown below:
CMakeLists.txt ----------------- Main CMake file of the library.
3rdparty ----------------------- Folder with third-party libraries.
CMakeLists.txt ------------- CMake file which includes third-party libraries.
Logger --------------------- Source code of Logger library.
VCodec --------------------- Source code of VCodec library.
src ---------------------------- Folder with source code of the library.
impl ----------------------- Folder with source code of implementation.
CMakeLists.txt ------------- CMake file of the library.
VCodecJetPack.cpp ---------- C++ implementation file.
VCodecJetPack.h ------------ Header file which includes the VCodecJetPack class declaration.
VCodecJetPackVersion.h ----- Header file which includes the version of the library.
VCodecJetPackVersion.h.in -- CMake service file to generate version file.
test --------------------------- Folder with codec test application.
CMakeLists.txt ------------- CMake file for codec test application.
main.cpp ------------------- Source code file of codec test application.
example ------------------------ Folder with simple example of VCodecJetPack usage.
CMakeLists.txt ------------- CMake file for example application.
main.cpp ------------------- Source code file of example application.
VCodecJetPack class description
VCodecJetPack class declaration
The VCodecJetPack class is declared in the VCodecJetPack.h file. Class declaration:
class VCodecJetPack : public VCodec
{
public:
/// Class constructor.
VCodecJetPack();
/// Class destructor.
~VCodecJetPack();
/// Get string of current library version.
static std::string getVersion();
/// Encode frame.
bool transcode(Frame& src, Frame& dst) override;
/// Set codec parameter.
bool setParam(VCodecParam id, float value) override;
/// Get parameter value.
float getParam(VCodecParam id) override;
/// Execute command.
bool executeCommand(VCodecCommand id) override;
};
getVersion method
The getVersion() method returns a string of the current version of the VCodecJetPack class. Method declaration:
static std::string getVersion();
This method can be used without a VCodecJetPack class instance:
cout << "VCodecJetPack class version: " << VCodecJetPack::getVersion() << endl;
Console output:
VCodecJetPack class version: 2.2.0
transcode method
The transcode(…) method is intended to encode or decode video frames (Frame class). The video codec processes video frames frame-by-frame. Method declaration:
bool transcode(Frame& src, Frame& dst) override;
Encoding (NV12 → H264/HEVC):
| Parameter | Value |
|---|---|
| src | Source video frame (see Frame class description). Must have NV12 pixel format. |
| dst | Result video frame (see Frame class description). Must have a compressed pixel format (field fourcc of Frame class): H264 or HEVC. |
Decoding (H264/HEVC → NV12):
| Parameter | Value |
|---|---|
| src | Source compressed frame. Must have H264 or HEVC pixel format. |
| dst | Result video frame. Must have NV12 pixel format. The width and height fields must be set to the expected resolution before calling. |
Note (encoder): The encoder requires 2 initial frames to prime the hardware pipeline. During this phase transcode returns TRUE with dst.size == 0. From the 3rd frame onward, encoded data is returned at full hardware throughput (~1 ms for 1080p).
Note (decoder): The decoder requires a few initial frames to prime the pipeline (resolution detection). During this phase transcode returns TRUE with dst.size == 0. Once the decoder is ready, decoded NV12 frames are returned.
Returns: TRUE if the frame was processed successfully or FALSE if not.
setParam method
The setParam(…) method is designed to set new video codec parameter values. Method declaration:
bool setParam(VCodecParam id, float value) override;
| Parameter | Description |
|---|---|
| id | Video codec parameter ID according to the VCodecParam enum. |
| value | Video codec parameter value. Valid values depend on the parameter ID. |
Returns: TRUE if the parameter was set successfully or FALSE if not.
The VCodec.h file of the VCodec library defines IDs for parameters (VCodecParam enum) and IDs for commands (VCodecCommand enum). VCodecParam declaration:
namespace cr
{
namespace video
{
enum class VCodecParam
{
/// [read/write] Log level: 0-Disable, 1-Console, 2-File, 3-Console and file.
LOG_LEVEL = 1,
/// [read/write] Bitrate, kbps. For H264 and H265 codecs.
BITRATE_KBPS,
/// [read/write] Minimum bitrate, kbps. For variable bitrate mode.
MIN_BITRATE_KBPS,
/// [read/write] Maximum bitrate, kbps. For variable bitrate mode.
MAX_BITRATE_KBPS,
/// [read/write] Bitrate mode: 0 - constant bitrate, 1 - variable bitrate.
BITRATE_MODE,
/// [read/write] Quality 0-100%. For JPEG codecs.
QUALITY,
/// [read/write] FPS. For H264 and H265 codecs.
FPS,
/// [read/write] GOP size. For H264 and H265 codecs.
GOP,
/// [read/write] H264 profile: 0 - Baseline, 1 - Main, 2 - High.
H264_PROFILE,
/// [read/write] Codec type. Depends on implementation.
TYPE,
/// Custom 1. Depends on implementation.
CUSTOM_1,
/// Custom 2. Depends on implementation.
CUSTOM_2,
/// Custom 3. Depends on implementation.
CUSTOM_3
};
}
}
Table 2 - Video codec parameters description. Some parameters are not supported by the particular VCodecJetPack library.
| Parameter | Access | Description |
|---|---|---|
| LOG_LEVEL | read / write | Logging mode. Values: 0 - Disable. 1 - Only file. 2 - Only terminal (console). 3 - File and terminal. |
| BITRATE_KBPS | read / write | Bitrate, kbps. Range: 0-1,000,000 kbps. Default: 2000 kbps. For H264 and H265(HEVC) hardware encoding. The encoder uses constant bitrate mode (CBR). |
| MIN_BITRATE_KBPS | read / write | Not supported by VCodecJetPack library. |
| MAX_BITRATE_KBPS | read / write | Not supported by VCodecJetPack library. |
| BITRATE_MODE | read / write | Not supported by VCodecJetPack library. The encoder uses constant bitrate mode (CBR) only. |
| QUALITY | read / write | Not supported by VCodecJetPack library. |
| FPS | read / write | Frames per second. Range: 1-240. Default: 30. For H264 and H265(HEVC) encoding. |
| GOP | read / write | GOP size (Group of Pictures). Range: 1-1000. Default: 30. Defines the period of key frames for H264 and H265(HEVC) encoding. Value 1 means each frame is a key frame, 30 means every 30th frame is a key frame. |
| H264_PROFILE | read / write | H264 profile for H264 encoding: 0 - Baseline (default). 1 - Main. 2 - High. Only applies to H264 codec. |
| TYPE | read / write | Not supported by VCodecJetPack library. Hardware encoding only. |
| CUSTOM_1 | read / write | Not supported by VCodecJetPack library. |
| CUSTOM_2 | read / write | Not supported by VCodecJetPack library. |
| CUSTOM_3 | read / write | Not supported by VCodecJetPack library. |
getParam method
The getParam(…) method is designed to obtain video codec parameter values. Method declaration:
float getParam(VCodecParam id) override;
| Parameter | Description |
|---|---|
| id | Video codec parameter ID according to the VCodecParam enum (see Table 2). |
Returns: Parameter value or -1 if the parameter doesn’t exist in the particular video codec class.
executeCommand method
The executeCommand(…) method is designed to execute video codec commands. Method declaration:
bool executeCommand(VCodecCommand id) override;
| Parameter | Description |
|---|---|
| id | Video codec command ID according to the VCodecCommand enum. |
Returns: TRUE if the command was executed successfully or FALSE if not supported or failed.
The VCodec.h file of the VCodec library defines IDs for parameters (VCodecParam enum) and IDs for commands (VCodecCommand enum). VCodecCommand declaration:
enum class VCodecCommand
{
/// Reset.
RESET = 1,
/// Generate key frame. For H264 and H265 codecs.
MAKE_KEY_FRAME
};
Table 3 - Video codec commands description. Some commands may be unsupported by particular video codec classes.
| Command | Description |
|---|---|
| RESET | Not supported by VCodecJetPack library. |
| MAKE_KEY_FRAME | Forces the next encoded frame to be a key frame (IDR frame). Supported for H264 and HEVC encoding. |
Build and connect to your project
The library uses the standard Linux V4L2 API and does not require the legacy jetson_multimedia_api package. Typical commands to build the VCodecJetPack library:
cd VCodecJetPack
git submodule update --init --recursive
mkdir build
cd build
cmake ..
make
If you want to connect the VCodecJetPack library to your CMake project as source code, you can follow these steps. For example, if your repository has the following structure:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
Create a 3rdparty folder in your repository. Copy the VCodecJetPack repository folder to the 3rdparty folder. The new structure of your repository:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
VCodecJetPack
Create a CMakeLists.txt file in the 3rdparty folder. The 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_VCODEC_JET_PACK ON CACHE BOOL "" FORCE)
if (${PARENT}_SUBMODULE_VCODEC_JET_PACK )
SET(${PARENT}_VCODEC_JET_PACK ON CACHE BOOL "" FORCE)
SET(${PARENT}_VCODEC_JET_PACK_TEST OFF CACHE BOOL "" FORCE)
SET(${PARENT}_VCODEC_JET_PACK_EXAMPLE OFF CACHE BOOL "" FORCE)
endif()
################################################################################
## INCLUDING SUBDIRECTORIES
## Adding subdirectories according to the 3rd-party configuration
################################################################################
if (${PARENT}_SUBMODULE_VCODEC_JET_PACK )
add_subdirectory(VCodecJetPack)
endif()
The file 3rdparty/CMakeLists.txt adds the VCodecJetPack folder to your project and will exclude the test application from compiling. Your repository’s new structure will be:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
VCodecJetPack
Next, you need to include the 3rdparty folder in the main CMakeLists.txt file of your repository. Add the following line at the end of your main CMakeLists.txt:
add_subdirectory(3rdparty)
Next, you have to include the VCodecJetPack library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} VCodecJetPack)
Done!
Encoding example
The example application generates an image color pattern with a moving rectangle and writes compressed data to a binary file “out.hevc”. The example shows how to create codec objects and how to encode video frames:
#include <iostream>
#include "VCodecJetPack.h"
int main(void)
{
// Create codec.
cr::video::VCodec* videoCodec = new cr::video::VCodecJetPack();
// Set codec parameters.
videoCodec->setParam(cr::video::VCodecParam::BITRATE_KBPS, 7500);
videoCodec->setParam(cr::video::VCodecParam::GOP, 30);
videoCodec->setParam(cr::video::VCodecParam::FPS, 30);
// Create NV12 frame.
const int width = 1280;
const int height = 720;
cr::video::Frame frameNv12(width, height, cr::video::Fourcc::NV12);
// Fill NV12 frame with random values.
for (uint32_t i = 0; i < frameNv12.size; ++i)
frameNv12.data[i] = (uint8_t)i;
// Create output HEVC frame.
cr::video::Frame frameHEVC(width, height, cr::video::Fourcc::HEVC);
// Create output file.
FILE *outputFile = fopen("out.hevc", "w+b");
// Parameters for moving object.
int objectWidth = 128;
int objectHeight = 128;
int directionX = 1;
int directionY = 1;
int objectX = width / 4;
int objectY = height / 2;
// Encode and record 200 frames.
for (uint32_t n = 0; n < 200; ++n)
{
// Draw moving object.
memset(frameNv12.data, 128, width * height);
for (int y = objectY; y < objectY + objectHeight; ++y)
for (int x = objectX; x < objectX + objectWidth; ++x)
frameNv12.data[y * width + x] = 255;
objectX += directionX;
objectY += directionY;
if (objectX >= width - objectWidth - 5 || objectX <= objectWidth + 5)
directionX = -directionX;
if (objectY >= height - objectHeight - 5 || objectY <= objectHeight + 5)
directionY = -directionY;
// Encode.
if (!videoCodec->transcode(frameNv12, frameHEVC))
{
std::cout << "Cannot encode frame" << std::endl;
continue;
}
// Write to file.
fwrite(frameHEVC.data, frameHEVC.size, 1, outputFile);
}
// Close file.
fclose(outputFile);
delete videoCodec;
return 0;
}
Decoding example
The following example shows how to decode a compressed H264 stream from a binary file back to NV12 frames:
#include <iostream>
#include "VCodecJetPack.h"
int main(void)
{
// Create codec.
cr::video::VCodec* videoCodec = new cr::video::VCodecJetPack();
// Open input file with compressed H264 data.
FILE* inputFile = fopen("out.h264", "rb");
if (!inputFile)
{
std::cout << "Cannot open input file" << std::endl;
return -1;
}
// Compressed frame buffer.
const int maxCompressedSize = 1024 * 1024;
uint8_t* compressedData = new uint8_t[maxCompressedSize];
// Create source H264 frame and destination NV12 frame.
const int width = 1920;
const int height = 1080;
cr::video::Frame frameH264(width, height, cr::video::Fourcc::H264);
cr::video::Frame frameNv12(width, height, cr::video::Fourcc::NV12);
// Read and decode frames.
while (true)
{
// Read compressed data (simplified: read fixed-size chunks).
size_t bytesRead = fread(compressedData, 1, maxCompressedSize, inputFile);
if (bytesRead == 0)
break;
// Set compressed data into source frame.
memcpy(frameH264.data, compressedData, bytesRead);
frameH264.size = bytesRead;
// Decode.
if (!videoCodec->transcode(frameH264, frameNv12))
{
std::cout << "Cannot decode frame" << std::endl;
break;
}
// dst.size == 0 means decoder is still priming the pipeline.
if (frameNv12.size == 0)
continue;
std::cout << "Decoded frame: " << frameNv12.width << "x"
<< frameNv12.height << std::endl;
}
// Cleanup.
delete[] compressedData;
fclose(inputFile);
delete videoCodec;
return 0;
}
Test application
The test application for the VCodecJetPack C++ library shows how the library works on Jetson platforms. The test application generates artificial video, compresses it according to the user’s parameters (codec type, bitrate, GOP size, and H264 profile), and writes results to binary files “out.h264” or “out.hevc”. The application shows encoding time for each video frame.
After starting, you will see the following output:
====================================
VCodecJetPack v2.2.0 test
====================================
Enter Encoder type (1 - H264, 2 - HEVC) : 1
Default params:
Bitrate, kbps 6000
FPS: 60
GOP size: 30
Video width 1920
Video height 1080
H264 Profile: 0
Use default params (0 - no, 1 - yes) : 1
Set number frames: 200
After the parameters are chosen, the test application encodes the requested number of frames and then decodes them back. The first 2 frames are used for hardware pipeline priming (dst.size == 0). From the 3rd frame onward, encoding and decoding times are shown:
=== ENCODING ===
ENC frame 0 accepted (pipeline priming)
ENC frame 1 accepted (pipeline priming)
ENC 3110400 -> 11364 12604 us
ENC 3110400 -> 9864 1224 us
ENC 3110400 -> 8881 1205 us
ENC 3110400 -> 2372 1183 us
...
=== DECODING ===
DEC 11364 -> 3110400 1876 us
DEC 9864 -> 3110400 1654 us
...
Encoded: 198/200 Decoded: 198/198