AxsunOCTCapture  3.6.0.0
Captures and buffers streamed imaged data from the Axsun Ethernet/PCIe DAQ and displays or retrieves images to a client application on request.
AxsunOCTCapture_Cpp_example_NewImageCallback.cpp

This is example source code showing how to use the callback-based image capture functionality of AxsunOCTCapture in a C++ client application (Windows OS).

// AxsunOCTCapture_Cpp_example_NewImageCallback.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include "AxsunOCTCapture.h" // for all AxsunOCTCapture functions, structs, enums, typedefs
#include <iostream> // for std::cout; not related to AxsunOCTCapture functionality
#include <chrono> // for loop timer sleep function; not related to AxsunOCTCapture functionality
#include <thread> // for loop timer sleep function; not related to AxsunOCTCapture functionality
#include <conio.h> // for console keyboard interaction; not related to AxsunOCTCapture functionality
#include <windows.h> // for Win32 event handling
#include <vector> // for memory allocation... could new(), malloc(), array[], or whatever you prefer
using namespace std::chrono_literals;
#define PCIEMODE // comment this line out for Ethernet interface, leave uncommented for PCIe interface
// Define AxsunOCTCapture class to wrap axStartSession(), axStopSession(), and the session handle in RAII fashion.
// (This will conveniently call axStopSession() automatically in the destructor so that resources are cleaned up.)
class AxsunOCTCapture {
private:
AOChandle session_{ nullptr };
public:
AxsunOCTCapture(int32_t capacity) { if (auto retval = axStartSession(&session_, capacity); retval != AxErr::NO_AxERROR) throw retval; } // C++17
~AxsunOCTCapture() { axStopSession(session_); }
AOChandle operator()() { if (session_) return session_; else throw AxErr::CAPTURE_SESSION_NOT_SETUP; }
};
void NewImageArrived(new_image_callback_data_t data, void* user_ptr) {
// Use the 'void* user_ptr' argument to send this callback a pointer to your preallocated
// buffer if you are retrieving the image data rather than only directly displaying it, as well as
// any other client resources needed in this callback (log handles, etc).
//
// Calling AxsunOCTCapture functions other than axRequestImage(), axGetImageInfo(), & axGetStatus()
// in this callback may result in undefined behavior, due to the nature of this callback's
// execution in a concurrent thread with the application's other calls to the AxsunOCTCapture API.
//
// New Image Arrived events are stored in a FIFO queue within the AxsunOCTCapture library.
// If the time spent in this callback exceeds the period of new images enqueued in the Main Image
// Buffer, unprocessed callback events will stack up indefinitely as indicated by the value of
// data.waiting_callbacks.
//
// Force-triggered images will also invoke this callback, with data.image_number = 0.
std::cout << data.image_number << "\t";
// get Main Image Buffer status (check on dropped_packets, etc)
uint32_t imaging, last_packet, last_frame, last_image, dropped_packets, frames_since_sync;
axGetStatus(data.session, &imaging, &last_packet, &last_frame, &last_image, &dropped_packets, &frames_since_sync);
// convert user_ptr from void back into a std::vector<uint8_t>
auto& image_vector = *(static_cast<std::vector<uint8_t>*>(user_ptr));
if (auto bytes_allocated = image_vector.size(); bytes_allocated >= data.required_buffer_size) { // insure memory allocation large enough
auto prefs = request_prefs_t{ .request_mode = AxRequestMode::DISPLAY_ONLY, .which_window = 1 };
auto info = image_info_t{};
auto retval = axRequestImage(data.session, data.image_number, prefs, bytes_allocated, image_vector.data(), &info);
if (retval == AxErr::NO_AxERROR) {
std::cout << info.image_number << "\tWidth: " << info.width;
if (info.force_trig)
std::cout << "\tForce triggered mode.";
else
std::cout << "\tBacklog: " << data.waiting_callbacks << "\tDrop: " << dropped_packets;
std::cout << '\n';
// sleep timer to simulate additional client tasks in callback
// if (data.waiting_callbacks < 10) std::this_thread::sleep_for(20ms);
}
else {
char error_message[512];
axGetErrorString(retval, error_message);
std::cout << "axRequestImage reported: " << static_cast<int>(retval) << ' ' << error_message << '\n';
}
}
else
std::cout << "Memory allocation too small for retrieval of image " << data.image_number << '\n';
}
void ImagingModeChanged(uint32_t state, void* user_ptr) {
// Use the 'void* user_ptr' argument to send this callback any application state
// synchronization objects as well as any other client resources needed in this callback
// (log handles, etc).
switch (static_cast<AxDAQEvent>(state)) {
std::cout << "DAQ/buffer state -> STOPPED\n";
break;
std::cout << "DAQ/buffer state -> IMAGING\n";
break;
std::cout << "DAQ/buffer state -> RECORD COMPLETE\n";
break;
std::cout << "DAQ/buffer state -> RECORDING\n";
break;
std::cout << "DAQ/buffer state -> LOADING COMPLETE\n";
break;
std::cout << "DAQ/buffer state -> LOADING FROM DISK\n";
break;
}
}
int main() {
char message[512]; // variable for getting string output from axGetMessage() and axGetErrorString()
try {
std::cout << "Welcome to the AxsunOCTCapture Example Console Application (C++ version).\n";
// allocate some user memory in which to fetch the image
auto bytes_allocated = uint32_t{ sizeof(int16_t) * 1024 * 40000 };
auto image_vector = std::vector<uint8_t>(bytes_allocated);
std::cout << "Bytes allocated: " << bytes_allocated << '\n';
{
// create a capture session with 500 MB main image buffer
AxsunOCTCapture AOC(500);
// set trigger timeout
if (auto retval = axSetTrigTimeout(AOC(), 30); retval != AxErr::NO_AxERROR) throw retval;
// register callbacks
if (auto retval = axRegisterNewImageCallback(AOC(), NewImageArrived, static_cast<void*>(&image_vector)); retval != AxErr::NO_AxERROR) throw retval;
if (auto retval = axRegisterDAQCallback(AOC(), ImagingModeChanged, NULL); retval != AxErr::NO_AxERROR) throw retval;
// select capture interface for this session
#ifdef PCIEMODE
if (auto retval = axSelectInterface(AOC(), AxInterface::PCI_EXPRESS); retval != AxErr::NO_AxERROR) throw retval;
#else
if (auto retval = axSelectInterface(AOC(), AxInterface::GIGABIT_ETHERNET); retval != AxErr::NO_AxERROR) throw retval;
#endif
// print message describing current capture interface status
if (auto retval = axGetMessage(AOC(), message); retval != AxErr::NO_AxERROR) throw retval;
std::cout << message << '\n';
// setup OpenGL-based rendering with auto-scaled contrast & brightness
if (auto retval = axSetupDisplay(AOC(), 0, 0, 0, 512, 256, 0); retval != AxErr::NO_AxERROR) throw retval;
if (auto retval = axAdjustBrightnessContrast(AOC(), 1, 0, 0); retval != AxErr::NO_AxERROR) throw retval;
// NOTE: before proceeding with this program:
// TURN ON LASER EMISSION using AxsunOCTControl or AxsunOCTControl_LW API, or OCT Host or Hardware Control Tool GUI
// FOR GIGABIT_ETHERNET INTERFACE, need to set DAQ Imaging On mode using AxsunOCTControl or AxsunOCTControl_LW API, or OCT Host or Hardware Control Tool GUI
#ifdef PCIEMODE
if (auto retval = axPipelineMode(AOC(), AxPipelineMode::LOG, AxChannelMode::CHAN_1); retval != AxErr::NO_AxERROR) throw retval;
// set DAQ Imaging On mode (e.g. 400 for burst record, -1 for indefinite live mode)
if (auto retval = axImagingCntrlPCIe(AOC(), -1); retval != AxErr::NO_AxERROR) throw retval;
#endif
// declare local variables
uint32_t imaging, last_packet, last_frame, last_image, dropped_packets, frames_since_sync; // for axGetStatus()
int32_t counter = 0;
while (!_kbhit()) { // loop until a key is pressed (this function in conio.h)
// handle Win32 events in the OpenGL rendering window
MSG msg;
if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessage(&msg);
// get Main Image Buffer status
if (auto retval = axGetStatus(AOC(), &imaging, &last_packet, &last_frame, &last_image, &dropped_packets, &frames_since_sync); retval != AxErr::NO_AxERROR) throw retval;
if (!imaging && !(++counter % 50)) // print message every 50th iteration if imaging is off
std::cout << "Imaging mode is off. Turn it on or press a key to exit.\n";
// loop timer
std::this_thread::sleep_for(50ms);
}
#ifdef PCIEMODE
// FOR PCIe INTERFACE, set DAQ Imaging Off mode (idle)
if (auto retval = axImagingCntrlPCIe(AOC(), 0); retval != AxErr::NO_AxERROR) throw retval;
#endif
} // AOC and Capture session goes out of scope and axStopSession() is called here
} // std::vector allocated for image goes out of scope and is destoyed here
catch (const AxErr& e) {
axGetErrorString(e, message);
std::cout << "ERROR: " << message << '\n';
}
catch (...) {
std::cout << "***** UNKNOWN ERROR. Program terminating.\n";
}
std::cout << "Quitting...\n\n";
}
axSetupDisplay
AxErr axSetupDisplay(AOChandle session, uint8_t window_style, int32_t w_left, int32_t w_top, int32_t w_width, int32_t w_height, uintptr_t parent_window_handle)
Setup an OpenGL display window for direct rendering of image data. (WINDOWS ONLY)
AOChandle
struct CaptureSession * AOChandle
Axsun OCT Capture handle - a pointer to the opaque structure used to manage created capture sessions.
Definition: AxsunOCTCapture.h:132
IMAGING_START
@ IMAGING_START
Definition: AxsunOCTCapture.h:205
new_image_callback_data_t::required_buffer_size
uint32_t required_buffer_size
Definition: AxsunOCTCapture.h:432
axRegisterNewImageCallback
AxErr axRegisterNewImageCallback(AOChandle session, AxNewImageCallbackFunction_t callback_function, void *user_data)
Registers a callback function to be executed each time a new image is enqueued in the Main Image Buff...
CHAN_1
@ CHAN_1
Definition: AxsunCommonEnums.h:212
new_image_callback_data_t::image_number
uint32_t image_number
Definition: AxsunOCTCapture.h:430
LOAD_START
@ LOAD_START
Definition: AxsunOCTCapture.h:217
axPipelineMode
AxErr axPipelineMode(AOChandle session, AxPipelineMode mode, AxChannelMode channels)
Configures FPGA registers to output the desired data type & location from the processing pipeline via...
axStopSession
AxErr axStopSession(AOChandle session)
Stop a capture session and deallocate all resources, including Main Image Buffer and interfaces.
AxDAQEvent
AxDAQEvent
Types of transitions in DAQ's operational mode, conveyed via user callback function....
Definition: AxsunOCTCapture.h:201
LOG
@ LOG
Definition: AxsunCommonEnums.h:200
axAdjustBrightnessContrast
AxErr axAdjustBrightnessContrast(AOChandle session, int32_t which_window, float brightness, float contrast)
Change the brightness and contrast of images displayed in an OpenGL window. (WINDOWS ONLY)
RECORD_START
@ RECORD_START
Definition: AxsunOCTCapture.h:209
request_prefs_t::request_mode
AxRequestMode request_mode
Definition: AxsunOCTCapture.h:329
IMAGING_STOP
@ IMAGING_STOP
Definition: AxsunOCTCapture.h:203
RECORD_DONE
@ RECORD_DONE
Definition: AxsunOCTCapture.h:207
axGetErrorString
void axGetErrorString(AxErr errorcode, char *message_out)
Get a description of a specific AxErr error code.
new_image_callback_data_t::session
AOChandle session
Definition: AxsunOCTCapture.h:428
LOAD_DONE
@ LOAD_DONE
Definition: AxsunOCTCapture.h:215
axRegisterDAQCallback
AxErr axRegisterDAQCallback(AOChandle session, AxCallbackFunction_t callback_function, void *user_data)
Registers a callback function to be executed upon a change in the DAQ imaging state (e....
axGetMessage
AxErr axGetMessage(AOChandle session, char *message_out)
Get a description of the capture session's interface status.
axGetStatus
AxErr axGetStatus(AOChandle session, uint32_t *imaging, uint32_t *last_packet_in, uint32_t *last_frame_in, uint32_t *last_image_in, uint32_t *dropped_packets, uint32_t *frames_since_sync)
Get imaging mode status and Main Image Buffer statistics.
image_info_t
Structure for conveying metadata information about an image.
Definition: AxsunOCTCapture.h:392
new_image_callback_data_t
Structure for data made available to user in a new image callback event via registered AxNewImageCall...
Definition: AxsunOCTCapture.h:426
new_image_callback_data_t::waiting_callbacks
uint32_t waiting_callbacks
Definition: AxsunOCTCapture.h:434
axRequestImage
AxErr axRequestImage(AOChandle session, uint32_t requested_image, request_prefs_t prefs, uint32_t output_buf_len, uint8_t *image_data_out, image_info_t *image_info)
Retrieve and/or display an image from the Main Image Buffer.
AxErr
AxErr
Error codes returned from AxsunOCTCapture or AxsunOCTControl_LW functions. Use axGetErrorString() in ...
Definition: AxsunCommonEnums.h:34
axSelectInterface
AxErr axSelectInterface(AOChandle session, AxInterface which_interface)
Select the data interface (Ethernet, PCIe, or none) for the capture session.
DISPLAY_ONLY
@ DISPLAY_ONLY
Definition: AxsunOCTCapture.h:189
AxsunOCTCapture.h
This header file contains all exported function prototypes, structures, and enums necessary for integ...
axStartSession
AxErr axStartSession(AOChandle *session, float capacity_MB)
Start an Axsun DAQ imaging session by allocating memory for the Main Image Buffer.
PCI_EXPRESS
@ PCI_EXPRESS
Definition: AxsunOCTCapture.h:229
axImagingCntrlPCIe
AxErr axImagingCntrlPCIe(AOChandle session, int16_t number_of_images)
Control the image streaming behavior of the Axsun PCIe DAQ between Live Imaging, Burst Recording,...
request_prefs_t
Structure for image request preferences.
Definition: AxsunOCTCapture.h:326
axSetTrigTimeout
AxErr axSetTrigTimeout(AOChandle session, uint32_t framesUntilForceTrig)
Control the behavior of Force Trigger mode.
GIGABIT_ETHERNET
@ GIGABIT_ETHERNET
Definition: AxsunOCTCapture.h:227