Stream Status Display
This sample shows how to monitor a live DELTA stream while displaying generated
ColorFrame output with OpenCV. It registers stream callback functions, stores
the latest stream status values, and draws those values on top of the preview
window.
Back to Code Samples.
Example Overview
| Step | SDK API | Purpose |
|---|---|---|
| 1 | scanDevices() / openDevice() |
Find and open a connected DELTA Series camera. |
| 2 | applySensorSetting() |
Apply the recommended sensor setting file. |
| 3 | setFrameGeneration() |
Choose how 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 | setDataRateCallback() |
Receive USB data rate updates in KB/s. |
| 8 | setFrameRateCallback() |
Receive generated frame rate updates in FPS. |
| 9 | setEventCountCallback() |
Receive total parsed event count updates. |
| 10 | setFrameCountCallback() |
Receive total parsed frame count updates. |
| 11 | startStream() |
Start live USB streaming. |
| 12 | getColorFrame() |
Read generated frames and draw status values on the preview. |
| 13 | stopStream() / closeDevice() |
Stop streaming and release the device. |
Expected Result
When the sample runs successfully, an OpenCV preview window appears and shows the live camera output with stream status values displayed in green.

USB : Current data rate received over USB during streaming
FPS : FPS calculated using Frame End packets received from the sensor
Events : Total number of events accumulated during streaming
Frames : Total number of frames accumulated during streaming
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 Camera
selectDeviceIndex selects which camera from the latest scanDevices() result
will be opened.
const std::int32_t selectDeviceIndex = 0;
selectDeviceIndex = 0 selects the first detected camera. If multiple cameras
are connected, use 1, 2, and so on to choose another detected camera.
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 = 20;
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 live preview because it follows the camera 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 Stream Status Values
The sample uses StreamStats to store the latest values received from SDK
callbacks. Each value is atomic because the callbacks may be called from an SDK
internal thread while the main thread is drawing the preview.
struct StreamStats
{
std::atomic<double> dataRateKBps{0.0};
std::atomic<std::int32_t> frameRateFPS{0};
std::atomic<std::uint64_t> totalEvents{0};
std::atomic<std::uint64_t> totalFrames{0};
};
Define Callback Functions
Each callback receives userData, converts it back to StreamStats, and stores
only the latest value.
static void onDataRate(void* userData, double kilobytesPerSecond)
{
auto* stats = static_cast<StreamStats*>(userData);
stats->dataRateKBps.store(kilobytesPerSecond);
}
static void onFrameRate(void* userData, std::int32_t framesPerSecond)
{
auto* stats = static_cast<StreamStats*>(userData);
stats->frameRateFPS.store(framesPerSecond);
}
The event and frame count callbacks use the same pattern.
static void onEventCount(void* userData, std::uint64_t totalEvents)
{
auto* stats = static_cast<StreamStats*>(userData);
stats->totalEvents.store(totalEvents);
}
static void onFrameCount(void* userData, std::uint64_t totalFrames)
{
auto* stats = static_cast<StreamStats*>(userData);
stats->totalFrames.store(totalFrames);
}
Note
Keep callback functions short and thread-safe. Do not call blocking SDK APIs
such as saveRawByTime() from inside a callback.
Open the Device and Prepare ColorFrame Output
Device setup, frame generation, output type, color format, and frame buffer
preparation follow the same pattern as Single Streaming.
The sample enables ColorFrame because the stream status values are drawn on
top of the preview image.
status = delta::setOutputType(cameraHandle, delta::OutputType::ColorFrame);
status = delta::setColorFormat(cameraHandle, delta::ColorFormat::Gray);
const std::uint32_t bufferSize =
delta::getColorFrameBufferSize(cameraHandle);
std::vector<std::uint8_t> frameBuffer(bufferSize);
delta::ColorFrame frame{};
frame.startAddress = frameBuffer.data();
frame.bufferSize = bufferSize;
Register Stream Status Callbacks
Register the callback functions before starting the stream. The same
StreamStats instance is passed as userData to every callback.
StreamStats stats;
status = delta::setDataRateCallback(cameraHandle, onDataRate, &stats);
status = delta::setFrameRateCallback(cameraHandle, onFrameRate, &stats);
status = delta::setEventCountCallback(cameraHandle, onEventCount, &stats);
status = delta::setFrameCountCallback(cameraHandle, onFrameCount, &stats);
| Callback | Value |
|---|---|
setDataRateCallback() |
USB receive data rate in KB/s. |
setFrameRateCallback() |
Generated frame rate in FPS. |
setEventCountCallback() |
Total parsed event count. |
setFrameCountCallback() |
Total parsed frame count. |
Start Live Streaming
Start the stream after the device setup, output setup, frame buffer, and callbacks are ready.
status = delta::startStream(cameraHandle);
if (status != delta::Status::Success) {
std::cout << "startStream failed: "
<< delta::getStatusMessage(status) << "\n";
delta::closeDevice(cameraHandle);
return 1;
}
Display Stream 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().
std::ostringstream dataRateText;
dataRateText << "USB: " << std::fixed << std::setprecision(1)
<< stats.dataRateKBps.load() << " KB/s";
const std::string frameRateText =
"FPS: " + std::to_string(stats.frameRateFPS.load());
const std::string eventCountText =
"Events: " + std::to_string(stats.totalEvents.load());
const std::string frameCountText =
"Frames: " + std::to_string(stats.totalFrames.load());
const cv::Scalar overlayColor(0, 255, 0);
cv::putText(displayImage, dataRateText.str(), cv::Point(20, 35),
cv::FONT_HERSHEY_SIMPLEX, 0.8, overlayColor, 2, cv::LINE_AA);
cv::putText(displayImage, frameRateText, cv::Point(20, 70),
cv::FONT_HERSHEY_SIMPLEX, 0.8, overlayColor, 2, cv::LINE_AA);
cv::putText(displayImage, eventCountText, cv::Point(20, 105),
cv::FONT_HERSHEY_SIMPLEX, 0.8, overlayColor, 2, cv::LINE_AA);
cv::putText(displayImage, frameCountText, cv::Point(20, 140),
cv::FONT_HERSHEY_SIMPLEX, 0.8, overlayColor, 2, cv::LINE_AA);
cv::imshow("DELTA 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 Streaming
Stop the stream and close the camera before the application exits.
delta::stopStream(cameraHandle);
delta::closeDevice(cameraHandle);
cv::destroyAllWindows();