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();