Playback Status Display

This sample shows how to monitor playback status while replaying a saved .dvs file. It registers playback callback functions, stores the latest event count, frame count, and read-over state, then draws those values on top of the OpenCV preview window.

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 and overlay display.
5 setColorFormat() / setColor() Choose gray or RGB event visualization.
6 getColorFrameBufferSize() Get the required caller-owned frame buffer size.
7 setEventCountCallback() Receive total parsed event count updates.
8 setFrameCountCallback() Receive total parsed frame count updates.
9 setReadOverCallback() Detect when the playback file has been fully read.
10 startPlayback() Start reading events from the file.
11 pausePlayback() / resumePlayback() Pause or resume playback with keyboard input.
12 getColorFrame() Read generated frames and draw playback status on the preview.
13 stopPlayback() / closeFile() Stop playback and release the file handle.

Expected Result

Playback Status Display result

Events : Total number of events accumulated during playback

Frames : Total number of frames accumulated during playback

ReadOver : Indicates whether the playback file has been fully read

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 a placeholder file name. Replace it with the raw data file you want to monitor during playback.

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. The setReadOverCallback() callback can be used to detect when the file has been fully read.

(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.

Store Playback Status Values

The sample uses PlaybackStats to store the latest values received from SDK callbacks. Each value is atomic because callbacks may be called from an SDK internal thread while the main thread is reading frames and drawing the preview.

struct PlaybackStats
{
    std::atomic<std::uint64_t> totalEvents{0};
    std::atomic<std::uint64_t> totalFrames{0};
    std::atomic<bool> readOver{false};
};

Define Callback Functions

Each callback receives userData, converts it back to PlaybackStats, and stores only the latest value.

static void onEventCount(void* userData, std::uint64_t totalEvents)
{
    auto* stats = static_cast<PlaybackStats*>(userData);
    stats->totalEvents.store(totalEvents);
}

static void onFrameCount(void* userData, std::uint64_t totalFrames)
{
    auto* stats = static_cast<PlaybackStats*>(userData);
    stats->totalFrames.store(totalFrames);
}

static void onReadOver(void* userData)
{
    auto* stats = static_cast<PlaybackStats*>(userData);
    stats->readOver.store(true);
}

Note

Keep callback functions short and thread-safe. Do not call blocking SDK APIs from inside a callback.

Open the Playback File and Prepare ColorFrame Output

Playback setup, frame generation, output type, color format, and frame buffer preparation follow the same pattern as Playback. The sample enables ColorFrame because playback status values are drawn on top of the preview image.

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

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

status = delta::setPlaybackMode(fileHandle, delta::PlaybackMode::Once);
status = delta::setOutputType(fileHandle, delta::OutputType::ColorFrame);
status = delta::setColorFormat(fileHandle, delta::ColorFormat::Gray);
const std::uint32_t bufferSize =
    delta::getColorFrameBufferSize(fileHandle);

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

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

Register Playback Status Callbacks

Register the callback functions before starting playback. The same PlaybackStats instance is passed as userData to every callback.

PlaybackStats stats;

status = delta::setEventCountCallback(fileHandle, onEventCount, &stats);
status = delta::setFrameCountCallback(fileHandle, onFrameCount, &stats);
status = delta::setReadOverCallback(fileHandle, onReadOver, &stats);
Callback Value
setEventCountCallback() Total parsed event count during playback.
setFrameCountCallback() Total parsed frame count during playback.
setReadOverCallback() Whether the playback file has been fully read.

Start Playback

Start playback after the file, playback setup, frame buffer, and callbacks 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;
};

Handle Read Over

When no new frame is available, the sample checks the readOver flag. If the file has been fully read, the example exits the preview loop.

if (!hasFrame) {
    if (stats.readOver.load()) {
        std::cout << "Playback read over.\n";
        break;
    }
    if (!handleKey(cv::waitKey(1))) {
        break;
    }
    continue;
}

Display Playback Status with OpenCV

The preview loop reads the latest ColorFrame, converts it to a display image, loads the latest callback values, and draws them with cv::putText().

const std::string eventCountText =
    "Events: " + std::to_string(stats.totalEvents.load());
const std::string frameCountText =
    "Frames: " + std::to_string(stats.totalFrames.load());
const std::string readOverText =
    std::string("ReadOver: ") + (stats.readOver.load() ? "Yes" : "No");
const cv::Scalar overlayColor(0, 255, 0);

cv::putText(displayImage, eventCountText, cv::Point(20, 35),
            cv::FONT_HERSHEY_SIMPLEX, 0.8, overlayColor, 2, cv::LINE_AA);
cv::putText(displayImage, frameCountText, cv::Point(20, 70),
            cv::FONT_HERSHEY_SIMPLEX, 0.8, overlayColor, 2, cv::LINE_AA);
cv::putText(displayImage, readOverText, cv::Point(20, 105),
            cv::FONT_HERSHEY_SIMPLEX, 0.8, overlayColor, 2, cv::LINE_AA);

cv::imshow("DELTA Playback Callback Monitor", displayImage);

The callback functions do not draw to the window directly. The main loop owns the OpenCV display, which keeps the callback path lightweight.

Stop Playback

Stop playback and close the file before the application exits.

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