eGrabber Recorder Reference
23.04.1.37
|
eGrabber Recorder is a dynamic library that enables image acquisition applications, such as eGrabber-based applications, to write acquired buffers to disk efficiently.
For the Recorder library, a buffer is made of two parts: the metadata (grouped in the buffer info) and the actual image pixels (component values). When a buffer is written to disk, those two parts are saved together as one entity into a Recorder container. A Recorder container is located in a user-supplied directory, its capacity is defined upfront by the user but can be further increased or reduced according to application needs or disk constraints.
Prior to recording buffers, an application needs to open a container in write mode and set its capacity (known as the container size). When this is done the application can write one or more buffers to the container.
Prior to reading buffers from a container, an application needs to open the container in read mode and set the buffer cursor (known as the record index) to the desired position. Afterwards, the application can read one or more buffers from the container.
The Recorder library also handles chapters inside a container. A chapter groups a set of buffers belonging to the same recording session. A recording application can create new chapters at any moment before writing buffers. A chapter also provides a synchronization point between system and UTC timestamps. This allows a reading application to get record buffer timestamps in UTC.
Note: this product requires a license to work; if you consider using the product, please contact Euresys.
The Recorder library exposes two programming interfaces:
In this guide, we will focus on the C++ API. Here are a few of its key assets:
Here is a typical code for creating a container and recording a few buffers:
Typical code for reading a few buffers from a container:
And code for exporting images from a container:
In the following sections, we will further explain the recorder functionalities.
A recorder container can be opened in 3 exclusive open modes. In this document we will call session the time during which a container is opened.
The available open modes are:
Please note that the modes are exclusive: it is not possible to open more than one session on the same container path. Moreover when a container is opened in write or append mode, it's not possible to read data from the container until it is closed; and when a container is opened in read mode, it's not possible to write data to the container until it is closed. However the library can manage several recording or playback sessions on distinct containers concurrently.
When a recording session is opened and no chapter has been explicitly created, a chapter is automatically created when the first buffer is written so that each recording session has at least its own chapter (see Creating chapters for more information).
When a recording session is closed (explicitly using Recorder::close or implicitly when a Recorder object goes out of scope), the user can decide how the container is closed by specifying one of the close modes. Such close mode may be defined upfront when the Recorder object is created with openRecorder.
The available close modes are:
The following flag can be optionally added to the chosen close mode:
When a recording session is opened (whatever its open mode), information or parameters of the container can be queried or modified. Two types of parameters are supported: integer (int64_t) and string; depending on the parameter, one or both types are available.
The complete list of parameters is available here.
The most important parameters are:
The parameters can be queried or modified using these functions:
Before using a recording session (either in write or append mode), the container size must be set to reserve the container space on disk upfront.
For example, to reserve one MiB (1024^2 bytes)
To achieve high write throughput, the buffer data (pixels) to record in a container must meet some alignment constraints. Those constraints are not mandatory for the library to work properly but aligned buffers will offer better performance than unaligned ones.
The alignment constraint is given by the recorder parameter RECORDER_PARAMETER_BUFFER_OPTIMAL_ALIGNMENT. Please note that the alignment value depends on the characteristics of the disk where the container is stored therefore this value should not be assumed or reused between recorder sessions.
For better performance, both the address and the size of the buffers must be aligned on that value. Aligned memory can be allocated using
For Coaxlink and Gigelink users, the data stream module can be configured from eGrabber so that allocated GenTL buffers meet those constraints. Prior to allocating and announcing buffers, the data stream module can be configured as follows:
Writing to the container is a synchronous operation that blocks the caller until the buffer is effectively written. For example, to write the metadata info
and its buffer
of pixel values:
When the write
function is done, both the metadata and the buffer data are saved to disk and both the record index and record count are incremented.
Please note that the function blocks the current thread until the I/O operations are finished. The duration will depend on the size of the buffer to write as well as on the disk speed and its current load.
During a recording session, an application may need to mark the beginning of a sequence of buffers. The application can do so as follows:
This will mark the beginning of a new chapter called "Sequence01"
and all subsequent buffer writes will be associated to that chapter until another chapter is created or the container is closed. It is also possible to provide a description for the chapter (as the optional second parameter of the function).
Alternatively, the chapter name can be omitted and in that case, the name will be set automatically to Chapter<xx>
where <xx>
is the index of the new chapter.
As already explained in the introduction, a chapter also captures an accurate synchronization point between the system time (in nanosecond since the computer booted) and the current UTC time. This synchronization point will be used while reading back from the container to convert automatically record buffer system timestamps into UTC timestamps using the corresponding chapter synchronization point.
When a container is opened in read mode, the record index is automatically set to 0
so that buffers can be read immediately from the first record.
Reading from the container is a synchronous operation. It's possible to read
In the following example we read the buffer metadata into info
and we get the buffer data without explicitly allocating memory.
The Recorder class provides two read
functions:
std::vector<char>
with the buffer data, and optionally returns the buffer info in the provided structure (info
can be set to nullptr
if the info is not needed)When the read
function is done, the record index is incremented only if buffer data was read successfully. Please note that reading buffer info only does not move the record index.
When a buffer is written to the container, its timestamp
is given by the application in the metadata. This timestamp must be expressed in nanoseconds since the computer booted. In the buffer metadata, there is also a field called utc
where the application may provide the UTC timestamp of the buffer. The application can also set the utc
field to 0
; this is the recommended value.
While reading buffer metadata info from the container, all the metadata fields are retrieved as they were saved except the field utc
, which may have a different value.
utc
was different from 0
when written: its value is returned as is when readingutc
was 0
when written: the library computes the buffer UTC timestamp by converting the buffer system timestamp (expressed in nanoseconds since the computer booted) to UTC using the pair of synchronized timestamps of the buffer chapterAn application can walk through the collection of chapters stored in a container. For each chapter, the application can get details such as the chapter name, description, creation time (in system time as well as in UTC) and the number of records. These operations are done by setting and getting the chapter-related recorder parameters.
The following code gets the list of available chapter names of a container opened in read mode:
Whereas this sample shows how to get the UTC timestamps of all the buffers stored in the last chapter of a container:
Images can also be exported from a container opened in read mode. For example, to export one image:
The record index is incremented by exportImages
. This is similar to the read
function.
The first argument to exportImages
(the output path) can include one or more @
patterns. For example, to export three images named image.0.tiff
, image.1.tiff
, and image.2.tiff
:
Optionally, images can be converted by exportImages
. For example:
Please refer to the documentation of RecorderExport of the C API for more details.
Exporting a complete container into chapters as .mkv
(Matroska video) files can be achieved in one operation (assuming the record index is set to the beginning of the container, i.e. 0
):
This will produce one .mkv
file for each chapter. Each file will be named @c-@C.mkv
where
@c
will be replaced by the chapter index@C
will be replaced by the chapter nameeGrabber is a set of Euresys C++ classes that provide a high-level interface on top of GenTL. eGrabber classes expose a grabber-oriented interface that hides the complexity of the underlying hierarchical structure of GenTL modules; it's the recommended API to use Coaxlink frame grabbers.
The buffer metadata are all the buffer information except the actual pixel component values; they include the buffer width, height and pixel format; please refer to RECORDER_BUFFER_INFO for an exhaustive list of metadata supported by the recorder library.