Skip to content

SDK Architecture

andrestraker edited this page Dec 18, 2025 · 2 revisions

GENERATED BY COPILOT - REVIEW IS NEEDED.

libaditof SDK Architecture

This document describes the high‑level architecture of the libaditof SDK, focusing on the sdk directory and the main public classes exposed in sdk/include/aditof.
It is formatted to work correctly in a GitHub Wiki (no Mermaid or special rendering features required).


1. Directory Structure Overview

The core SDK lives under the sdk directory of the repository:

  • sdk/include/aditof/Public C++ API

    • Core API headers:
      • system.haditof::System
      • camera.haditof::Camera (abstract interface)
      • frame.haditof::Frame
      • frame_handler.haditof::FrameHandler
    • Supporting definitions and utilities:
      • camera_definitions.h, frame_definitions.h
      • sensor_definitions.h
      • sensor_enumerator_interface.h, sensor_enumerator_factory.h
      • depth_sensor_interface.h
      • status_definitions.h, adsd_errs.h, sdk_exports.h
      • connections.h, utils.h, log.h, version-kit.h, stb_image_write.h
  • sdk/src/Core implementation

    • Public API implementations and PIMPLs:
      • system.cpp, system_impl.cpp, system_impl.h
      • frame.cpp, frame_impl.h
      • frame_handler.cpp, frame_handler_impl.h
      • frame_operations.cpp
      • sensor_enumerator_factory.cpp
      • status_definitions.cpp
      • utils.cpp, utils_ini.cpp, utils_ini.h
    • Subdirectories:
      • sdk/src/cameras/ – Camera‑specific implementations of aditof::Camera and helpers.
      • sdk/src/connections/ – Transport backends (e.g., USB/Ethernet/other connections).
  • sdk/common/Common low‑level components

    • sdk/common/adi/ – ADI‑specific primitives and low‑level building blocks shared across cameras/platforms.
  • sdk/CMakeLists.txtBuild & integration

    • CMake configuration that composes include, src, and common into the libaditof SDK library.

2. Core Public API and Responsibilities

This section is grounded in the actual headers under sdk/include/aditof.

2.1 aditof::System

Header: sdk/include/aditof/system.h
Role: Entry point into the SDK; manages camera discovery.

Key characteristics:

  • Lives in namespace aditof.
  • Uses the PIMPL pattern:
    • Forward declares class SystemImpl; at global scope.
    • Holds std::unique_ptr<SystemImpl> m_impl;.

Main API:

  • System() / ~System() – Constructor and destructor.
  • Move‑only semantics: System(System &&) noexcept, System &operator=(System &&) noexcept.
  • Status getCameraList(std::vector<std::shared_ptr<Camera>> &cameraList, const std::string &uri = "") const
    • Populates a list of std::shared_ptr<aditof::Camera> corresponding to available cameras.
    • Accepts an optional URI to specify connectivity (e.g., network IP).

Conceptually:

  • System decouples application code from how cameras are enumerated and connected.
  • The actual enumeration logic lives in SystemImpl and underlying factories/connection backends in sdk/src.

2.2 aditof::Camera

Header: sdk/include/aditof/camera.h
Role: Abstract interface for a ToF camera instance.

Key characteristics:

  • class Camera is declared as SDK_API Camera and is abstract (pure virtual interface).
  • No public constructor; typically created and returned by aditof::System::getCameraList.

Selected responsibilities (non‑exhaustive):

  • Lifecycle & streaming

    • initialize(const std::string &configFilepath = {})
    • start(), stop()
    • setMode(const uint8_t &mode)
    • getAvailableModes(std::vector<uint8_t> &availableModes) const
  • Frame acquisition

    • requestFrame(Frame *frame, uint32_t index = 0)
      • Fills a user‑provided aditof::Frame instance with the latest data (or frame at index in playback mode).
  • Depth/AB processing configuration

    • getFrameProcessParams(std::map<std::string, std::string> &params)
    • setFrameProcessParams(std::map<std::string, std::string> &params, int32_t mode)
    • enableDepthCompute(bool enable)
    • saveDepthParamsToJsonFile(const std::string &savePathFile)
    • loadDepthParamsFromJsonFile(const std::string &path, const int16_t mode_in_use = -1)
    • resetDepthProcessParams()
  • AB normalization helpers

    • normalizeABBuffer(...)
    • normalizeABFrame(aditof::Frame *frame, ...)
  • Camera metadata & controls

    • getDetails(CameraDetails &details) const
    • getAvailableControls(std::vector<std::string> &controls) const
    • setControl(const std::string &control, const std::string &value)
    • getControl(const std::string &control, std::string &value) const
  • Low‑level sensor access

    • std::shared_ptr<DepthSensorInterface> getSensor()
    • Status getImagerType(ImagerType &imagerType) const
    • Status readSerialNumber(std::string &serialNumber, bool useCacheValue = false)
    • Status setSensorConfiguration(const std::string &sensorConf)
  • Module configuration and firmware management

    • saveModuleCFG(const std::string &filepath) const
    • saveModuleCCB(const std::string &filepath)
    • Many ADSD3500‑specific functions for firmware update, thresholds, filters, frame rate, metadata, generic register access, and diagnostics.
  • Recording & playback

    • dropFirstFrame(bool dropFrame)
    • startRecording(std::string &filePath)
    • stopRecording()
    • setPlaybackFile(std::string &filePath)
    • getDepthParamtersMap(uint16_t mode, std::map<std::string,std::string> &params)

Conceptually:

  • Camera aggregates:
    • A connection backend (in sdk/src/connections/).
    • One or more low‑level sensor interfaces (e.g., DepthSensorInterface).
    • Processing configuration and metadata control for depth/AB/XYZ outputs.
  • Concrete implementations live under sdk/src/cameras/ and implement all pure virtuals in this interface.

2.3 aditof::Frame

Header: sdk/include/aditof/frame.h
Role: Represents a frame of data from a camera (depth, AB, XYZ, confidence, metadata, etc.).

Key characteristics:

  • Value‑type wrapper that uses the PIMPL pattern:
    • Forward declares class FrameImpl; at global scope.
    • Holds std::unique_ptr<FrameImpl> m_impl;.
  • Fully copyable and movable:
    • Copy constructor/assignment.
    • Move constructor/assignment.

Main API:

  • Construction & lifecycle

    • Frame(), ~Frame()
    • Frame(const Frame &), Frame &operator=(const Frame &)
    • Frame(Frame &&) noexcept, Frame &operator=(Frame &&) noexcept
  • Configuration & querying

    • Status setDetails(const FrameDetails &details, const uint8_t &m_bitsInConf, const uint8_t &m_bitsInAB)
    • Status getDetails(FrameDetails &details) const
    • Status getDataDetails(const std::string &dataType, FrameDataDetails &details) const
  • Data access

    • Status getData(const std::string &dataType, uint16_t **dataPtr)
      • dataType examples: "depth", "ab", "xyz", "conf" (exact set depends on mode/config).
  • Metadata & capabilities

    • Status getMetadataStruct(Metadata &metadata) const
    • bool haveDataType(const std::string &dataType)

2.3.1 How Frame is meant to be used

Frame is the container for image data and metadata:

  • The camera fills it:
    • You create a Frame in your application.
    • You pass it to Camera::requestFrame(&frame).
    • Internally, FrameImpl manages buffers and layout.
  • Your application reads from it:
    • You use getDetails / getDataDetails to understand layout (width/height, stride, etc.).
    • You use getData("depth", &ptr) / getData("ab", &ptr) to obtain raw buffer pointers.
    • Optionally, you use getMetadataStruct to decode metadata embedded in the frame.

Conceptual snippet:

aditof::Frame frame;

// During streaming:
camera->requestFrame(&frame);

// Access depth data
uint16_t *depthData = nullptr;
frame.getData("depth", &depthData);

// Access AB data
uint16_t *abData = nullptr;
frame.getData("ab", &abData);

// Access metadata
aditof::Metadata md;
frame.getMetadataStruct(md);

Conceptually:

  • Ownership: Frame owns its storage through FrameImpl.
  • Direction:
    • Camera writes into Frame.
    • Your code reads from Frame.

2.4 aditof::FrameHandler

Header: sdk/include/aditof/frame_handler.h
Role: Helper for saving/loading frames to/from persistent storage (files), independent of live camera streaming.

Key characteristics:

  • Uses the PIMPL pattern:
    • Forward declares class FrameHandlerImpl; at global scope.
    • Holds std::unique_ptr<FrameHandlerImpl> m_impl;.

Main API:

  • Lifecycle

    • FrameHandler(), ~FrameHandler()
    • Move constructor and move assignment (copy is disabled).
  • Configuration

    • Status setOutputFilePath(const std::string &filePath)
    • Status setInputFileName(const std::string &fullFileName)
    • Status setCustomFormat(const std::string &format)
    • Status storeFramesToSingleFile(bool enable)
    • Status setFrameContent(const std::string &frameContent)
      • Used to specify which components are stored (e.g., "depth,ab,conf").
  • Frame I/O

    • Status saveFrameToFile(Frame &frame, const std::string &fileName = "")
    • Status saveFrameToFileMultithread(Frame &frame, const std::string &fileName = "")
    • Status readNextFrame(Frame &frame, const std::string &fullFileName = "")
  • Snapshot utility

    • Status SnapShotFrames(const char *baseFileName, Frame *frame, const uint8_t *ab, const uint8_t *depth)

2.4.1 How FrameHandler is meant to be used

FrameHandler is orthogonal to the camera:

  • It does not talk to the hardware.
  • It only operates on Frame objects and raw buffers.

Typical usage patterns:

  1. Record frames while streaming from a live camera
aditof::FrameHandler fh;
fh.setOutputFilePath("/tmp/recordings");
fh.setFrameContent("depth,ab");         // store only depth + AB
fh.storeFramesToSingleFile(true);      // optional: single container file

aditof::Frame frame;

// Streaming loop
for (...) {
    camera->requestFrame(&frame);      // Camera writes into Frame

    // Optional: process data here...

    // Save to file (blocking or multi-threaded)
    fh.saveFrameToFile(frame);
    // or:
    // fh.saveFrameToFileMultithread(frame);
}
  1. Replay frames from file without an attached camera
aditof::FrameHandler fh;
fh.setInputFileName("/tmp/recordings/session.dat");

aditof::Frame frame;

while (true) {
    aditof::Status status = fh.readNextFrame(frame);
    if (status != aditof::Status::OK) {
        break; // end of file or error
    }

    uint16_t *depth = nullptr;
    frame.getData("depth", &depth);

    // Process depth data ...
}
  1. One‑off snapshot
aditof::Frame frame;
camera->requestFrame(&frame);

uint16_t *ab = nullptr;
uint16_t *depth = nullptr;
frame.getData("ab", &ab);
frame.getData("depth", &depth);

aditof::FrameHandler fh;
fh.SnapShotFrames("snapshot_001", &frame,
                  reinterpret_cast<const uint8_t*>(ab),
                  reinterpret_cast<const uint8_t*>(depth));

Conceptually:

  • Frame is the data container, used both in live capture and playback.
  • FrameHandler is the persistence/utility layer that knows how to serialize and deserialize Frame contents to/from disk (with optional custom formats and threading).

3. Class Relationships (Text Diagram)

Because GitHub Wiki cannot render Mermaid reliably, this section uses a plain‑text diagram.

3.1 High‑level relationships

+-------------------+           +----------------------+
|   aditof::System  |           |   aditof::Camera     |
+-------------------+           +----------------------+
| - m_impl:         |           |  (abstract interface)|
|   std::unique_ptr |           +----------------------+
|   <SystemImpl>    |                    |  \
+-------------------+                    |   \
          |                               |    \
          | getCameraList(...)            |     \
          | fills                         |      \
          v                               |       \
  std::shared_ptr<Camera> ---------------+        \
                                                 uses getSensor()
                                                      \
                                                       v
                                              +---------------------------+
                                              | aditof::DepthSensorInterface |
                                              +---------------------------+
                                              |   (abstract interface)    |
                                              +---------------------------+


                      uses for frames
          +----------------------------------------------+
          v                                             
+----------------------+                      
|   aditof::Frame      |                      
+----------------------+                      
| - m_impl:           |                      
|   std::unique_ptr   |                      
|   <FrameImpl>       |                      
+----------------------+                      


+----------------------+                      
| aditof::FrameHandler |                      
+----------------------+                      
| - m_impl:           |                      
|   std::unique_ptr   |                      
|   <FrameHandlerImpl>|
+----------------------+
          |
          | operates on
          v
   aditof::Frame

3.2 Relationship summary

  • aditof::System

    • Owns a SystemImpl via std::unique_ptr<SystemImpl> m_impl.
    • Provides getCameraList(...) which populates a list of std::shared_ptr<aditof::Camera>.
  • aditof::Camera

    • Abstract interface; concrete implementations are provided in sdk/src/cameras/.
    • Uses aditof::Frame for frame acquisition via requestFrame(Frame *frame, uint32_t index = 0).
    • Uses aditof::DepthSensorInterface for low‑level sensor access via:
      • std::shared_ptr<DepthSensorInterface> getSensor();
  • aditof::Frame

    • Owns a FrameImpl via std::unique_ptr<FrameImpl> m_impl.
    • Provides methods to configure and query frame details, access data buffers, and read metadata.
    • Used by both live streaming (via Camera) and offline recording/playback (via FrameHandler).
  • aditof::FrameHandler

    • Owns a FrameHandlerImpl via std::unique_ptr<FrameHandlerImpl> m_impl.
    • Operates on aditof::Frame to save/load data to/from files.
    • Independent of hardware and System.
  • aditof::DepthSensorInterface

    • Abstract interface to low‑level sensor functionality.
    • Returned by Camera::getSensor() and implemented in the SDK’s internal sensor layer.

4. Layered Architecture and Typical Flow

From top to bottom, the SDK architecture can be viewed in layers:

  1. Application Layer

    • User applications and examples.
    • Use the public headers in sdk/include/aditof and link against the libaditof library.

    Typical live streaming + optional recording flow:

    aditof::System system;
    std::vector<std::shared_ptr<aditof::Camera>> cameras;
    system.getCameraList(cameras);
    
    auto camera = cameras.front();           // pick first camera
    camera->initialize();
    camera->setMode(mode);
    camera->start();
    
    aditof::Frame frame;
    aditof::FrameHandler recorder;
    recorder.setOutputFilePath("/tmp/frames");
    recorder.setFrameContent("depth,ab");
    
    for (...) {
        camera->requestFrame(&frame);        // Camera -> Frame
    
        // Read data from Frame
        uint16_t *depth = nullptr;
        frame.getData("depth", &depth);
    
        // Optional: record to file
        recorder.saveFrameToFile(frame);
    }
    
    camera->stop();

    Typical offline playback flow:

    aditof::FrameHandler player;
    player.setInputFileName("/tmp/frames/session.dat");
    
    aditof::Frame frame;
    
    while (player.readNextFrame(frame) == aditof::Status::OK) {
        uint16_t *depth = nullptr;
        frame.getData("depth", &depth);
    
        // Process playback frame...
    }

    Key idea:

    • Frame is the bridge between live capture and offline tools.
    • FrameHandler is the “storage engine” for Frame data.
  2. Public SDK API Layer (sdk/include/aditof)

    • aditof::System – discovery and camera list population.
    • aditof::Camera – hardware‑agnostic camera control and configuration.
    • aditof::Frame – generic container for depth/AB/XYZ/conf data and metadata.
    • aditof::FrameHandler – I/O utilities for storing and replaying frames.
    • Shared definitions and types for cameras, frames, sensors, and statuses.
  3. Core Implementation Layer (sdk/src)

    • PIMPLs:
      • SystemImpl – implements discovery, URI handling, and camera list population.
      • FrameImpl – manages internal buffer allocation, layout, and data access.
      • FrameHandlerImpl – handles file formats, threading, and I/O.
    • Concrete camera and sensor implementations (sdk/src/cameras/).
    • Connection backends (sdk/src/connections/).
    • Factories (sensor_enumerator_factory.*), frame operations (frame_operations.cpp), and common utilities (utils*.cpp, status_definitions.cpp).
  4. Common / Low‑Level Components (sdk/common/adi/)

    • ADI‑specific primitives and helpers shared across various cameras and platforms.
    • Provide low‑level access, calibration, and shared algorithms.
  5. Build & Integration (sdk/CMakeLists.txt)

    • Defines how all components are compiled and linked into the SDK.
    • Controls which cameras, connections, and features are enabled per platform.

5. Summary

  • System: How you discover and obtain cameras.
  • Camera: How you configure a camera, control streaming, and pull frames.
  • Frame: The data container used for both live capture and offline playback.
  • FrameHandler: The utility that knows how to serialize/deserialize Frame data to/from files.

Frame and FrameHandler are deliberately separated so that:

  • You can process frames without ever touching disk, using only Frame.
  • You can build tooling that replays or inspects recorded sessions, using FrameHandler + Frame, without needing a live device.