Playback

This sample shows how to open a saved .dvs raw data file, replay it through the DELTA SDK processing pipeline, and display generated ColorFrame output with OpenCV. Use this sample when you want to inspect data that was previously saved from a DELTA Series camera.

Back to Code Samples.

Example Overview

Step SDK API Purpose
1 openFile() Open a saved .dvs raw data file.
2 setPlaybackMode() Select one-time playback or loop playback.
3 setFrameGeneration() Choose how recorded event data is converted into generated frames.
4 setOutputType() Select ColorFrame output for OpenCV preview.
5 setColorFormat() / setColor() Choose gray or RGB event visualization.
6 getColorFrameBufferSize() Get the required caller-owned frame buffer size.
7 startPlayback() Start reading events from the file.
8 pausePlayback() / resumePlayback() Pause or resume playback with keyboard input.
9 getColorFrame() Read generated frames from the playback source.
10 stopPlayback() / closeFile() Stop playback and release the file handle.

Code Walkthrough

Edit the User Control Panel

The USER CONTROL PANEL section is the only part you normally need to edit. Each option group has one active line and one or more commented alternatives. To use a different mode, comment out the current active line and uncomment the mode you want to use.

Select a Playback File

playbackFilePath points to the .dvs raw data file that will be opened.

const std::filesystem::path playbackFilePath =
    std::filesystem::path(DELTA_SAMPLE_ROOT) / "saved_data" / "raw_data" / "sample.dvs";

sample.dvs is only a placeholder file name. Replace it with the name of the raw data file you want to play.

Note

Use Raw Data Saving to create a .dvs file from a live camera stream.

Select a Playback Mode

Only one selected_playbackmode line should be active at a time.

(a) Once

This is the default mode used by the example.

const std::string selected_playbackmode = "Once";

When this mode is active, the SDK plays the .dvs file one time.

(b) Loop

To use loop playback, uncomment the Loop line in the example and comment out the currently active Once line.

// const std::string selected_playbackmode = "Loop";

When this mode is active, playback restarts from the beginning after reaching the end of the file.

Note

Keep only one selected_playbackmode definition active. If both Once and Loop are uncommented, the example will not compile because the same variable is defined multiple times.

Select a Frame Generation Mode

Frame generation controls how raw event data is grouped into display frames. Only one selected_framemode line should be active at a time.

(a) FrameEndBased This is the default mode used by the example.

const std::string selected_framemode = "FrameEndBased";
const std::int32_t frameEndCount = 1;

When this mode is active, the SDK generates one output frame after the selected number of frame-end markers. This is a good default for playback preview because it follows the recorded stream structure directly.

(b) TimeBased To use time-based frame generation, uncomment the TimeBased line in the example and comment out the currently active FrameEndBased line.

// const std::string selected_framemode = "TimeBased";
const std::int32_t framePeriodMs = 16;

When this mode is active, the SDK generates one output frame at a fixed time interval. For example, framePeriodMs = 16 is about 60 Hz.

(c) EventCountBased To use event-count-based frame generation, uncomment the EventCountBased line in the example and comment out the currently active FrameEndBased line.

// const std::string selected_framemode = "EventCountBased";
const std::int32_t eventsPerFrame = 150000;

When this mode is active, the SDK generates one output frame after the selected number of events. If eventsPerFrame is too small, event activity can be split across too many frames and the preview may look clipped.

Note

Keep only one selected_framemode definition active. If more than one selected_framemode line is uncommented, the example will not compile because the same variable is defined multiple times.

Select the Color Format

The color format controls how the generated ColorFrame is stored and shown in OpenCV.

(a) Gray This is the default mode used by the example.

const std::string selected_colorformat = "Gray";

When Gray is active, the SDK generates a single-channel grayscale image. The default grayscale rendering is:

Event State Display Color
ON event White
OFF event Black
No event Gray

(b) RGB To use RGB output, uncomment the RGB line in the example and comment out the currently active Gray line.

// const std::string selected_colorformat = "RGB";

When RGB is active, the SDK generates a three-channel RGB image. You can customize the ON event, OFF event, and no-event colors with rgbColor.

const delta::EventColor rgbColor = {
    {255, 0, 0},     // ON event color
    {0, 0, 255},     // OFF event color
    {255, 255, 255}  // No event (background) color
};

The values are written in RGB order. In the default example above:

Event State RGB Value Display Color
ON event {255, 0, 0} Red
OFF event {0, 0, 255} Blue
No event {255, 255, 255} White

Note

Keep only one selected_colorformat definition active. If both Gray and RGB are uncommented, the example will not compile because the same variable is defined multiple times.

Open the Playback File

This sample uses a saved raw data file instead of a live camera. First, check that the file exists, then open it with openFile().

if (!std::filesystem::exists(playbackFilePath)) {
    std::cout << "Playback file not found: "
              << playbackFilePath.generic_string() << "\n";
    return 1;
}

delta::FileHandle fileHandle = nullptr;
const std::string playbackFileString = playbackFilePath.generic_string();

delta::Status status =
    delta::openFile(playbackFileString.c_str(), &fileHandle);

Set Playback Mode

The selected playback mode is applied to the opened file handle.

if (selected_playbackmode == "Once") {
    status = delta::setPlaybackMode(fileHandle, delta::PlaybackMode::Once);
}
else if (selected_playbackmode == "Loop") {
    status = delta::setPlaybackMode(fileHandle, delta::PlaybackMode::Loop);
}

Set Frame Generation, Output Type, and Color Format

Playback uses the same processing pipeline as live streaming. The example selects ColorFrame output so the generated frames can be displayed with OpenCV.

status = delta::setFrameGeneration(
    fileHandle,
    delta::frameEndBased(frameEndCount)
);

status = delta::setOutputType(fileHandle, delta::OutputType::ColorFrame);
status = delta::setColorFormat(fileHandle, delta::ColorFormat::Gray);

Prepare the Frame Buffer

Before reading frames, allocate a caller-owned buffer and attach it to delta::ColorFrame.

const std::uint32_t bufferSize =
    delta::getColorFrameBufferSize(fileHandle);

if (bufferSize == 0) {
    std::cout << "getColorFrameBufferSize failed.\n";
    delta::closeFile(fileHandle);
    return 1;
}

std::vector<std::uint8_t> frameBuffer(bufferSize);

delta::ColorFrame frame{};
frame.startAddress = frameBuffer.data();
frame.bufferSize = bufferSize;

Note

Call getColorFrameBufferSize() after setting the color format. RGB output requires a larger buffer than gray output.

Start Playback

Start playback after the file, playback mode, frame generation, output type, color format, and frame buffer are ready.

status = delta::startPlayback(fileHandle);

if (status != delta::Status::Success) {
    std::cout << "startPlayback failed: "
              << delta::getStatusMessage(status) << "\n";
    delta::closeFile(fileHandle);
    return 1;
}

Pause and Resume Playback

The example uses keyboard input to control playback.

Key Action
Space Pause playback if running, resume playback if paused.
P / p Pause playback if running, resume playback if paused.
ESC Exit the example.
bool isPaused = false;

auto handleKey = [&](int key) -> bool
{
    if (key == 27) {
        return false;
    }
    if (key == ' ' || key == 'p' || key == 'P') {
        if (!isPaused) {
            const delta::Status pauseStatus =
                delta::pausePlayback(fileHandle);
            if (pauseStatus == delta::Status::Success) {
                isPaused = true;
            }
        }
        else {
            const delta::Status resumeStatus =
                delta::resumePlayback(fileHandle);
            if (resumeStatus == delta::Status::Success) {
                isPaused = false;
            }
        }
    }
    return true;
};

When playback is paused, the loop waits for keyboard input and does not read new frames.

if (isPaused) {
    if (!handleKey(cv::waitKey(30))) {
        break;
    }
    continue;
}

Display Frames with OpenCV

The preview loop reads generated frames from the playback source and displays them with OpenCV.

bool hasFrame = false;
for (int drainCount = 0; drainCount < 8; ++drainCount) {
    status = delta::getColorFrame(fileHandle, &frame, 0);

    if (status != delta::Status::Success) {
        break;
    }

    hasFrame = true;
}

If a frame is available, the sample displays it as either RGB or grayscale output.

if (frame.colorFormat == delta::ColorFormat::RGB) {
    cv::Mat rgbImage(
        frame.header.height,
        frame.header.width,
        CV_8UC3,
        frame.startAddress
    );

    cv::Mat bgrImage;
    cv::cvtColor(rgbImage, bgrImage, cv::COLOR_RGB2BGR);
    cv::imshow("DELTA Playback", bgrImage);
}
else {
    cv::Mat grayImage(
        frame.header.height,
        frame.header.width,
        CV_8UC1,
        frame.startAddress
    );

    cv::imshow("DELTA Playback", grayImage);
}

The inner loop calls getColorFrame() several times to drain older generated frames and keep the preview close to the latest playback output.

Stop Playback

Stop playback and close the file before the application exits.

delta::stopPlayback(fileHandle);
delta::closeFile(fileHandle);
cv::destroyAllWindows();