Transfer Monitoring
Here the focus is on the transfer “over the wire” and possible errors here. This is not connection monitoring: it’s about transfer statistics.
This topic is heavily transport technology dependent. That means that the available measurement points change from vin driver to vin driver. If the vin driver supports different transport technologies (like the GenICam.vin), some statistacs may not be available even though the driver itself supports them.
At the time of writing the GenICam.vin supports the following transfer related measurement points (descriptions are GenICam.vin specific):
-
NumBuffersAcquired
Counts all buffers seen by the acquisition engine since acquisition
.Start
including lost or corrupted ones (during transfer from camera to pc). -
NumBuffersLostTransfer
Buffers lost on the wire since
DeviceFactory.Open
. This is not be increased for USB3 Vision transfers as a reliable hardware protocol is used. That doesn’t mean that there will never be an error: you still should use connection monitoring (INotify
interface) and delays may occur. -
NumBuffersDelivered
The buffers handled by the app (returned by
.Wait
) sinceDeviceFactory.Open
. -
NumBuffersCorruptOnArrival
Only increased if PassCorruptFrames is
False
(feature of theNodeMapNames.DataStream
NodeMap
). Corruption is due to tranfer errors. -
NumBuffersCorruptOnDelivery
Only increased if PassCorruptFrames is
True
(feature of theNodeMapNames.DataStream
NodeMap
). IfFalse
the frames/buffers won’t be delivered, but simply requeued. Corruption is due to transfer errors. -
NumPacketsReceived
Number of packets received since
DeviceFactory.Open
(mostly GigE Vision related). A full image (or frame) buffer is normally transferred in smaller packets over the wire. If a transfer error occurs in a packet based protocol (like GigE Vision), the packet size defines the granularity of the affected region(s). If a buffer is corrupt at least one packet is not present. Du to the ring buffer this results in old image data being present in that region! -
NumResends
Number of initiated packet resends since
DeviceFactory.Open
(mostly GigE Vision related). A resend is issued if the acquisition engine is detecting missing packets. If this counter increases you have either cabling problems or too many transfers/too high data rate on the connection. In combination withNumPacketsReceived
you can determine the packet error rate.
How to get the PassCorruptFrames BooleanNode
var streamNodeMap = device.NodeMaps[NodeMapNames.DataStream];
var passCorruptFrames = streamNodeMap["PassCorruptFrames"] as BooleanNode;
passCorruptFrames.Value = false; // true is the default
If set to False
only fully valid image buffers are seen by the app on .Wait
calls. Bad buffers are simply requeued.
So for transfer monitoring regarding errors the important measurement points are:
NumBuffersLostTransfer
NumBuffersCorruptOnArrival
/NumBuffersCorruptOnDelivery
NumResends
An increased count of NumResends
needn’t necessarily directly result in corrupted buffers. It is just a hint that you have problems with your connection. Packet resends can alleviate the problem (resulting in increased transfer time). You should investigate your setup if that occurs:
- test/exchange cables if no additional devices were added
- use e.g. interpacket delay if many devices share bandwidth (GigE Vision)
In case of increased NumBuffersLostTransfer
/NumBuffersCorruptOnArrival
you actually lost buffers and you cannot do anything about it anymore. If NumBuffersCorruptOnDelivery
count increased since the last call, then the last image buffer returned by .Wait
contains errors (e.g. because of missing packets there are “holes” containing old buffer data).
Remember: Collect the statistics right after the .Wait
call to get correct information!
How to identify corrupted ranges
The easiest solution is to initialize the image buffer before unlocking it (by default via the next .Wait
call after you finished your processing). Use a value you don’t care about (no feature) or which is not present in your images, e.g.:
streamImage.Initialize(.0);