VCodecJetPack C++ library
v2.0.4
Table of contents
- Overview
- Versions
- VCodecJetPack class description
- Build and connect to your project
- Simple example
- Test application
Overview
VCodecJetPack C++ library provides hardware video encoding for H264 and HEVC codecs for Jetson platforms based on Jetson Multimedia API. VCodecJetPack class inherits interface and data structures from open source VCodec library (provides interface for video codecs, source code included, Apache 2.0 license) and also includes Logger open source library (provides function for print logs, source code included, Apache 2.0 license). VCodecJetPack uses Jetson Jetson Multimedia API. The library provides simple programming interface to be implemented in different C++ projects. The library was written with C++17 standard. The libraries are supplied as source code only in form of CMake project. Encoding time on Jetson Orin NX:
codec / resolution | 2560x1440 | 1920x1080 | 1280x720 | 640x512 |
---|---|---|---|---|
H264 | 14.4 msec | 8.6 msec | 4.2 msec | 2 msec |
HEVC | 13.8 msec | 8.4 msec | 4.2 msec | 2 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 resolution |
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 | - Update VCodec interface with variable bitrate params. |
Library files
The library is supplied only by 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.
CMakeLists.txt ------------- CMake file of the library.
VCodecJetPack.cpp ---------- C++ implementation file.
VCodecJetPack.h ------------ Header file which includes VCodecJetPack class declaration.
VCodecJetPackVersion.h ----- Header file which includes 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
VCodecJetPack class declared in 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 string of current version of VCodecJetPack class. Method declaration:
static std::string getVersion();
Method can be used without **VCodecJetPack ** class instance:
cout << "VCodecJetPack class version: " << VCodecJetPack::getVersion() << endl;
Console output:
VCodecJetPack class version: 2.0.4
transcode method
The transcode(…) method intended to encode video frame (Frame class). Video codec encodes video frames frame-by-frame. Method declaration:
bool transcode(Frame& src, Frame& dst) override;
Parameter | Value |
---|---|
src | Source video frame (see Frame class description). To encode video data src frame must have NV12 pixel format. |
dst | Result video frame (see Frame class description). To encode video data src frame must have compressed pixel format (field fourcc of Frame class): H264 or HEVC. |
Returns: TRUE if frame was encoded or FALSE if not.
setParam method
The setParam(…) method designed to set new video codec parameters value. Method declaration:
bool setParam(VCodecParam id, float value) override;
Parameter | Description |
---|---|
id | Video codec parameter ID according to VCodecParam enum. |
value | Video codec parameter value. Valid values depends on parameter ID. |
Returns: TRUE is the parameter was set or FALSE if not.
VCodec.h file of 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 params description. Some params not supported by particular VCodecLibav 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. Default 5000 kbps. For H264 and H265(HEVC) encoding. According to this value, FPS and GOP size video codec calculate parameter for H264 or H265(HEVC) encoding. - Sets special settings for noisy video if bitrate is 0 for hardware encoding. - For software JPEG encoding bitrate incising gives higher quality. |
MIN_BITRATE_KBPS | read / write | Minimum bitrate, kbps. Only for H264 and H265(HEVC) codecs. Default 2000 kbps. For variable bitrate mode. For H264 and H265(HEVC) encoding. |
MAX_BITRATE_KBPS | read / write | Maximum bitrate, kbps. Only for H264 and H265(HEVC) codecs. Default 8000 kbps. For variable bitrate mode. For H264 and H265(HEVC) encoding. |
BITRATE_MODE | read / write | Only for H264 and H265(HEVC) codecs. Bitrate mode: 0 - constant bitrate (default), 1 - variable bitrate. In variable bitrate mode for software encoder |
QUALITY | read / write | Quality 0(low quality)-100%(maximum quality). Only for hardware JPEG encoding. Not supported by JPEG SW encoding. |
FPS | read / write | FPS. For H264 and H265(HEVC) encoding only. According to this value, FPS and GOP size video codec calculate parameter for H264 and H265(HEVC) encoding. |
GOP | read / write | GOP size (Period of key frames) for H264 and H265(HEVC) encoding. Value: 1 - each output frame is key frame, 20 - each 20th frame is key frame etc. |
H264_PROFILE | read / write | H264 profile for H264 encoding: 0 - Baseline. 1 - Main. 2 - High. For hardware encoding only. |
TYPE | read / write | Type of encoder/decoder: 0 - hardware (default). 1 - software. |
CUSTOM_1 | read / write | Number of thread for software encoder/decoder. Thread’s count for software encoder\decoder H264 / HEVC(H265) (not for JPEG): 1 - 32, default value 1. Note: in case one thread software encoder produces only one slice per frame. In case multiple threads frame can have multiple slices which can effect on RTSP servers. |
CUSTOM_2 | read / write | Not supported by VCodecLibav library. |
CUSTOM_3 | read / write | Not supported by VCodecLibav library. |
getParam method
The getParam(…) method designed to obtain video codec parameter value. Method declaration:
float getParam(VCodecParam id) override;
Parameter | Description |
---|---|
id | Video codec parameter ID according to VCodecParam enum (see Table 2). |
Returns: parameter value or -1 of the parameters doesn’t exist in particular video codec class.
executeCommand method
The executeCommand(…) method designed to execute video codec command. Version 2.0.2 doesn’t support commands. Method will return FALSE. Method declaration:
bool executeCommand(VCodecCommand id) override;
Parameter | Description |
---|---|
id | Video codec command ID according to VCodecCommand enum. |
Returns: method returns FALSE in any case.
VCodec.h file of 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 maybe unsupported by particular video codec class.
Command | Description |
---|---|
RESET | Not supported by VCodecJetPack library. |
MAKE_KEY_FRAME | Not supported by VCodecJetPack library. |
Build and connect to your project
Before build install necessary libraries. In general, when installing JetPack on your Jetson platform via Nvidia SDK Manager, there should be a jetson_multimedia_api folder in the /usr/src directory. If it is missing, you need to copy the jetson_multimedia_api folder from the /_static/jetson_multimedia_api.zip to the /usr/src directory on your Jetson. Typical commands to build VCodecJetPack library:
cd VCodecJetPack
git submodule update --init --recursive
mkdir build
cd build
cmake ..
make
If you want connect VCodecJetPack library to your CMake project as source code you can make follow. For example, if your repository has structure:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
Create folder 3rdparty in your repository. Copy repository folder VCodecJetPack to 3rdparty folder. New structure of your repository:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
VCodecJetPack
Create CMakeLists.txt file in 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_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()
File 3rdparty/CMakeLists.txt adds folder VCodecJetPack to your project and will exclude test application from compiling. Your repository new structure will be:
CMakeLists.txt
src
CMakeList.txt
yourLib.h
yourLib.cpp
3rdparty
CMakeLists.txt
VCodecJetPack
Next you need include folder 3rdparty in 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 VCodecJetPack library in your src/CMakeLists.txt file:
target_link_libraries(${PROJECT_NAME} VCodecJetPack)
Done!
Simple example
Example application generates image color pattern with moving rectangle and writes compressed data to binary file “out.hevc”. 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 by 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");
// Params 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 + objectHeight; ++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 << "Can't encode frame" << std::endl;
continue;
}
// Write to file.
fwrite(frameHEVC.data, frameHEVC.size, 1, outputFile);
}
// Close file.
fclose(outputFile);
return 1;
}
Test application
Test application for VCodecJetPack C++ library shows how library works on Jetson platform. Test application generates artificial video, compresses it according to user’s parameters (codec type, bitrate , GOP size and H264 profile), writes results to binary file “out.h264” or “out.hevc” . The application shows encoding time for each video frame. To run application perform commands on Linux:
cd <application folder>
sudo chmod +x VCodecJetPackTest
./VCodecJetPackTest
After start you will see output:
====================================
VCodecJetPack v2.0.2 test
====================================
Enter Encoder type (1 - H264, 2 - HEVC) :
Chose codec type (1 - H264 , 2 - HEVC):
====================================
VCodecJetPack v2.0.2 test
====================================
Enter Encoder type (1 - H264, 2 - HEVC) : 1
Default params:
Bitrate, kbps 6000
FPS: 30
GOP size: 30
Video width 1920
Video height 1080
H264 Profile: 0
Use default params (0 - no, 1 - yes) : 1
Set number frames: 200
When params chosen test application will create out.h264 or out.hevc file and will start writing encoded frames until stop. User can set custom parameters (video resolution, bitrate, GOP size and H264 profile). When params chosen test application will start writing encoded frames until stop (if user set number of frames). During encoding the application shows encoded data size and encoding time:
Opening in BLOCKING MODE
NvMMLiteOpen : Block : BlockType = 4
===== NVMEDIA: NVENC =====
NvMMLiteBlockCreate : Block : BlockType = 4
875967048
842091854
H264: Profile = 66, Level = 40
NVMEDIA: Need to set EMC bandwidth : 846000
NVMEDIA_ENC: bBlitMode is set to TRUE
Data size 3110400 / 13404 encoding time 290755 us
Data size 3110400 / 1691 encoding time 12924 us
Data size 3110400 / 3460 encoding time 13089 us
Data size 3110400 / 17007 encoding time 12335 us
Data size 3110400 / 390 encoding time 8417 us
Data size 3110400 / 178 encoding time 8613 us
Data size 3110400 / 176 encoding time 8648 us