Video Recording

The ZED SDK allows you to record large video datasets using H.264, H.265 or lossless compression. The SDK uses Stereolabs SVO format to store videos along with additional metadata such as timestamp and sensor data.

When loading SVO files, the ZED API will behave as if a ZED was connected and live feed was available. Every module of the ZED API will be available: depth, tracking, spatial mapping and more. To record SVO videos, you can use the ZED Explorer application in GUI or command-line mode or build your own recording app using the ZED API.

Compression Modes

SVO videos can be recorded using various compression modes. We provide both lossless and compressed modes to preserve image quality or reduce file size.

Compression Mode Compression Ratio Quality (SSIM) CPU Load (%) GPU Load (%) Platform Required
H.265 (HEVC) 100:1 97.3 2.9 5.0 NVIDIA GPU (Pascal or above) for hardware encoding, NVIDIA Jetson
H.264 (AVCHD) 100:1 96.9 3.1 5.0 NVIDIA GPU for hardware encoding, NVIDIA Jetson
LOSSY
(JPG)
4:1 95.5 29.5 0.0 Any
LOSSLESS (PNG) 2:1 100 32.0 0.0 Any

Benefits of Hardware Encoding

For optimal performance, we recommend using the H.264 and H.265 recording modes. They have been designed to use the hardware-based encoder (referred to as NVENC) built into NVIDIA graphics cards. With encoding offloaded to NVENC, the GPU and the CPU are free for other operations. For example, in a compute-heavy scenario, it is now possible to record video at full frame rate with minimal impact on the main application.

Encoding Quality

At a given bitrate, hardware encoding quality can vary depending on your GPU generation. The updated NVENC encoder on Turing-based NVIDIA GPUs (RTX 20-Series, Jetson Xavier) will typically produce superior quality than encoders on older generation GPUs (GTX 10-Series, Jetson Nano).

Recording with Multiple Cameras

You can record videos with multiple cameras connected to the same PC. When using hardware encoding (H.264, H.265), make sure to check the NVENC support matrix or Jetson one which shows the maximum number of concurrent recording sessions that can be started on a single NVIDIA GPU. You can also add multiple GPUs in a single server to increase the number of recording sessions with hardware encoding.

Using the Recording API

Video Recording

To record SVO files, you need to enable the Recording module with enableRecording(). Specify an output file name (eg: output.svo) and SVO_COMPRESSION_MODE, then save each grabbed frame. SVO lets you record video and associated metadata (timestamp, IMU data and more if available).

// Create a ZED camera object
Camera zed;

// Enable recording with the filename specified in argument
String output_path(argv[1]);
RecordingParameters recordingParameters;
recordingParameters.compression_mode = SVO_COMPRESSION_MODE::H264;
recordingParameters.video_filename = output_path;
err = zed.enableRecording(recordingParameters);

while (!exit_app) {
    // Each new frame is added to the SVO file
    zed.grab();      
}
// Disable recording
zed.disableRecording();
# Create a ZED camera object
zed = sl.Camera()

# Enable recording with the filename specified in argument
output_path = sys.argv[0]
err = zed.enable_recording(output_path, sl.SVO_COMPRESSION_MODE.H264)

while not exit_app:
    # Each new frame is added to the SVO file
    zed.grab()

# Disable recording
zed.disable_recording()
// Create a ZED camera object
sl.Camera zed = new sl.Camera(0);
sl.RuntimeParameters runtimeParameters = new sl.RuntimeParameters();
// Enable recording with the filename specified in argument
string output_path = args[0];
err = zed.EnableRecording(output_path, sl.SVO_COMPRESSION_MODE.H264_BASED);

while (!exit_app) {
    // Each new frame is added to the SVO file
    zed.Grab(ref runtimeParameters);
}
// Disable recording
zed.DisableRecording();

Video Playback

To play SVO files, simply add the file path as argument in setFromSVOFile(). When loading SVO files, the ZED API will behave as if a ZED was connected and live feed was available. Every module of the ZED API will be available: depth, tracking, spatial mapping and more. When an SVO file is read entirely, END_OF_SVOFILE_REACHED error code is returned.

// Create a ZED camera object
Camera zed;

// Set SVO path for playback
String input_path(argv[1]);
InitParameters init_parameters;
init_parameters.input.setFromSVOFile(input_path);

// Open the ZED
err = zed.open(init_parameters);

sl::Mat svo_image;
while (!exit_app) {
    if (zed.grab() == SUCCESS) {
        // Read side by side frames stored in the SVO
        zed.retrieveImage(svo_image, VIEW::SIDE_BY_SIDE);
        // Get frame count      
        int svo_position = zed.getSVOPosition();
    }
    else if (zed.grab() == END_OF_SVOFILE_REACHED) {
        std::cout << "SVO end has been reached. Looping back to first frame" << std::endl;
        zed.setSVOPosition(0);
    }
}
# Create a ZED camera object
zed = sl.Camera()

# Set SVO path for playback
input_path = sys.argv[1]
init_parameters = sl.InitParameters()
init_parameters.set_from_svo_file(input_path)

# Open the ZED
zed = sl.Camera()
err = zed.open(init_parameters)

svo_image = sl.Mat()
while not exit_app:
  if zed.grab() == sl.ERROR_CODE.SUCCESS:
    # Read side by side frames stored in the SVO
    zed.retrieve_image(svo_image, sl.VIEW.SIDE_BY_SIDE)
    # Get frame count
    svo_position = zed.get_svo_position();
  elif zed.grab() == sl.ERROR_CODE.END_OF_SVOFILE_REACHED:
    print("SVO end has been reached. Looping back to first frame")
    zed.set_svo_position(0)
// Create a ZED camera object
sl.Camera zed = new sl.Camera(0);

sl.RuntimeParameters runtimeParameters = new sl.RuntimeParameters();

// Set SVO path for playback
string input_path = argv[0];
sl.InitParameters init_parameters = new sl.InitParameters();
init_parameters.inputType = sl.INPUT_TYPE.SVO;
init_parameters.pathSVO = input_path;

// Open the ZED
err = zed.Open(ref init_parameters);

sl.Mat svo_image = new sl.Mat();
while (!exit_app) {
    if (zed.Grab(ref runtimeParameters) == sl.ERROR_CODE.SUCCESS) {
        // Read side by side frames stored in the SVO
        zed.RetrieveImage(svoImage, sl.VIEW.SIDE_BY_SIDE, sl.MEM.CPU);
        // Get frame count      
        int svo_position = zed.GetSVOPosition();
    }
    if (zed.GetSVOPosition() >= zed.GetSVONumberOfFrames() - 1) {
        Console.WriteLine("SVO end has been reached. Looping back to first frame");
        zed.SetSVOPosition(0);
    }
}

Code Example

Check out the SVO Recording, SVO Playback and SVO Export samples on GitHub.