Frame Saving From Playback

This sample shows how to save generated ColorFrame output from a saved .dvs playback file as BMP image files. Use this sample when you want to extract image frames from recorded raw data.

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 frameEndBased() / timeBased() / eventCountBased() Create a frame generation setting for saved BMP frames.
4 setOutputType() Select ColorFrame output for frame image saving.
5 setColorFormat() / setColor() Choose gray or RGB event visualization.
6 setReadOverCallback() Detect when one-time playback reaches the end of the file.
7 startPlayback() Start reading events from the file.
8 startFrameSaving() / stopFrameSaving() Save frames continuously until playback ends or the user stops it.
9 saveFrameByTime() Save frame images for a fixed duration.
10 saveFrameByFrameCount() Save a fixed number of frame images.
11 stopPlayback() / closeFile() Stop playback and release the file handle.

Code Walkthrough

Edit the User Control Panel

Select a Playback File

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 .dvs file you want to use.

Select a Playback Mode

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

Once saves frames from the file one time. Loop repeats the file if needed, which is useful when targetFrames is larger than the number of frames available in a single playback pass.

Select a Frame Generation Mode

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

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

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

Only one selected_framemode line should be active at a time.

Select a Frame Saving Mode

(a) Continuous

const std::string selected_savemode = "Continuous";

When this mode is active, frame saving starts from the beginning of playback and continues until playback ends or the user presses q.

(b) FrameCount

// const std::string selected_savemode = "FrameCount";
const std::uint64_t targetFrames = 2000;

When this mode is active, the example calls saveFrameByFrameCount() and saves up to targetFrames images.

(c) Time

// const std::string selected_savemode = "Time";
const std::int32_t durationMs = 2000;

When this mode is active, the example calls saveFrameByTime().

Note

Keep only one selected_savemode definition active. If more than one selected_savemode line is uncommented, the example will not compile.

Select the Color Format and Save Directory

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

const std::filesystem::path saveDirectory =
    std::filesystem::path(DELTA_SAMPLE_ROOT) / "saved_data" / "frame_from_playback";

Gray saves single-channel rendered frames. RGB saves three-channel rendered frames and allows custom event colors with rgbColor.

Open the Playback File

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

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

Create the Frame Generation Setting

delta::FrameGeneration frameGeneration =
    delta::frameEndBased(frameEndCount);

if (selected_framemode == "FrameEndBased") {
    frameGeneration = delta::frameEndBased(frameEndCount);
}
else if (selected_framemode == "TimeBased") {
    frameGeneration = delta::timeBased(framePeriodMs);
}
else if (selected_framemode == "EventCountBased") {
    frameGeneration = delta::eventCountBased(eventsPerFrame);
}

Set Output Type and Color Format

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

Frame saving writes BMP images generated from ColorFrame output.

Detect End of Playback

When playback mode is Once, the example registers a read-over callback so it can stop saving when the file reaches the end.

std::atomic_bool playbackFinished = false;

status = delta::setReadOverCallback(
    fileHandle,
    [](void* userData)
    {
        auto* finished = static_cast<std::atomic_bool*>(userData);
        finished->store(true);
    },
    &playbackFinished
);

Start Playback

Frame image saving from playback requires playback to be active first.

status = delta::startPlayback(fileHandle);

Save Frame Images

Continuous mode uses startFrameSaving() and stops when playback ends or the user presses q.

status = delta::startFrameSaving(
    fileHandle,
    saveDirectoryString.c_str(),
    frameGeneration
);

if (status == delta::Status::Success) {
    // Wait until playbackFinished is true, or until the user presses 'q'.
    status = delta::stopFrameSaving(fileHandle);
}

Frame-count mode runs saveFrameByFrameCount() in a worker thread because the API blocks until saving completes.

std::thread frameSavingThread(
    [&]()
    {
        frameSavingStatus = delta::saveFrameByFrameCount(
            fileHandle,
            saveDirectoryString.c_str(),
            targetFrames,
            frameGeneration
        );
        frameSavingFinished.store(true);
    });

Time mode calls saveFrameByTime() directly.

status = delta::saveFrameByTime(
    fileHandle,
    saveDirectoryString.c_str(),
    durationMs,
    frameGeneration
);

Note

If PlaybackMode::Once is active and the file ends before the requested frame count is saved, the example stops frame saving early. Use PlaybackMode::Loop when you want to fill targetFrames by repeating the file.

Stop Playback

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