Coaxlink Programmer's Guide
Euresys::EGrabber
}
1. Create a
Euresys::EGrabber
object. The second and third arguments of the constructor are omitted here. The
grabber will use the first device of the first interface present in the system.
2. Allocate 3 buffers. The grabber automatically determines the required buffer size.
3. Start the grabber. Here, we ask the grabber to fill 10 buffers. If we don't want the grabber to stop aer a specific
number of buffers, we can do
grabber.start(GenTL::GENTL_INFINITE)
, or simply
grabber.start()
.
Starting the grabber involves the following operations:
• the
AcquisitionStart
command is executed on the camera;
• the
DSStartAcquisition
function is called to start the data stream.
In this example, we assume that the camera and frame grabber are properly configured. For a real application,
it would be safer to run a
configuration script
before starting acquisitions (and before allocating buffers for that
matter). This will be shown in another example.
4. Wait for a buffer filled by the grabber. The result is a
Euresys::ScopedBuffer
. The term
scoped
is used to
indicate that the lifetime of the buffer is the current scope (i.e., the current block).
5. Retrieve the buffer address. This is done by calling the
getInfo
method of the buffer. This method takes as
argument a
BUFFER_INFO_CMD
. In this case, we request the
BUFFER_INFO_BASE
, which is defined in the
standard
GenTL header file
:
enum BUFFER_INFO_CMD_LIST
{
BUFFER_INFO_BASE = 0, /* PTR Base address of the buffer memory. */
BUFFER_INFO_SIZE = 1, /* SIZET Size of the buffer in bytes. */
BUFFER_INFO_USER_PTR = 2, /* PTR Private data pointer of the GenTL Consumer. */
BUFFER_INFO_TIMESTAMP = 3, /* UINT64 Timestamp the buffer was acquired. */
// ...
// other BUFFER_INFO definitions omitted
// ...
BUFFER_INFO_CUSTOM_ID = 1000 /* Starting value for GenTL Producer custom IDs. */
};
typedef int32_t BUFFER_INFO_CMD;
Notice that
getInfo
is a template method, and when we call it we must specify the type of value we expect.
BUFFER_INFO_BASE
returns a pointer; this is why we use
getInfo<void *>
.
6. Do the same to retrieve the timestamp of the buffer. This time, we use the
uint64_t
version of
getInfo
to match
the type of
BUFFER_INFO_TIMESTAMP
.
Note that, for Coaxlink, timestamps are always 64-bit and expressed as the number of microseconds that have
elapsed since the computer was started.
7. We reach the end of the
for
block. The local variable
buf
gets out of scope and is destroyed: the
ScopedBuffer
destructor is called. This causes the GenTL buffer contained in
buf
to be re-queued (given back) to the data stream
of the grabber.
Example of program output:
buffer address: 0x7f3c32c54010, timestamp: 11247531003686 us
buffer address: 0x7f3c2c4bf010, timestamp: 11247531058080 us
buffer address: 0x7f3c2c37e010, timestamp: 11247531085003 us
buffer address: 0x7f3c32c54010, timestamp: 11247531111944 us
buffer address: 0x7f3c2c4bf010, timestamp: 11247531137956 us
buffer address: 0x7f3c2c37e010, timestamp: 11247531163306 us
buffer address: 0x7f3c32c54010, timestamp: 11247531188600 us
buffer address: 0x7f3c2c4bf010, timestamp: 11247531213807 us
buffer address: 0x7f3c2c37e010, timestamp: 11247531239158 us
buffer address: 0x7f3c32c54010, timestamp: 11247531265053 us
We can see that the three buffers that were allocated (let's call them A at
0x7f3c32c54010
, B at
0x7f3c2c4bf010
,
and C at
0x7f3c2c37e010
) are used in a round-robin fashion: A → B → C → A → B → C → ... This is the result of:
• the FIFO nature of input and output buffer queues:
14