PXL_RETURN_CODE PxLGetNextFrame ( HANDLE hCamera, U32 bufferSize, void* pFrame, FRAME_DESC* pFrameDesc );
This function returns a frame of image data and the feature descriptor for that frame from the video stream. The image data in the frame will be in a format defined by the pixel format the camera is using. The pixel format can be found by querying the PixelFormat element of the frame descriptor structure that is returned by PxLGetNextFrame. A detailed description of the possible image data formats can be found in Image Data Formats.
If the camera has a trigger feature (see PxLGetCameraFeatures) and the trigger mode is set to TRIGGER_TYPE_SOFTWARE, then this function also causes a software trigger. Trigger types are defined in the file PixeLINKTypes.h.
- hCamera is the camera handle. This value is returned by PxLInitialize.
- bufferSize is the number of bytes of memory allocated for the frame. This value is used as a check to prevent memory overflow.
- pFrame is the pointer to the array receiving the frame of image data.
- pFrameDesc is the pointer to a frame descriptor (see FRAME_DESC structure). The structure is also defined in the file PixeLINKTypes.h.
- N.B. The uSize member of the FRAME_DESC structure MUST be filled in before each and every call to PxLGetNextFrame. Otherwise the API will assume that an older version (smaller size) of the structure is being used, and consequently some members of the structure will not be populated with data.
Comments, Restrictions and Limitations
Before this function is called, memory space should be allocated for the image data pFrame (width × height × number of bytes per pixel, where width and height take the pixel addressing value into account), and the FRAME_DESC structure for pFrameDesc. The C/C++ demo application 'getsnapshot' demonstrates one technique to determine the image size.
Before this function is called, the camera defined by the handle hCamera must be streaming. Use PxLSetStreamState START_STREAM to start streaming.
First and foremost to keep in mind is the fact that PxLGetNextFrame gets the next frame available after the function is called; it will block until the next frame becomes available. If your application must not miss a frame, PxLGetNextFrame must be called at a rate greater than the frame rate.
Note that it is possible for PxLGetNextFrame to return an error code because of a temporary timeout condition during times of high CPU usage or high bus utilization. To account for this, it is suggested that calls to PxLGetNextFrame for non-triggered cameras be wrapped by a retry loop which detects this temporary timeout condition.
The demonstration application 'getnextframe' demonstrates a suggested approach.
Dropping a Frame
As of PixeLINK Release 7.0, it is possible to drop a frame, or retrieve information about a frame without requiring that the frame data be copied. This is done by passing in a frame buffer size of -1.
// Drop a frame. i.e. Throw away the next frame PXL_RETURN_CODE rc = PxLGetNextFrame(hCamera, (U32)-1, NULL, NULL);
// Throw away the next frame, but return the information for that frame. FRAME_DESC frameDesc; frameDesc.uSize = sizeof(frameDesc); PXL_RETURN_CODE rc = PxLGetNextFrame(hCamera, (U32)-1, NULL, &frameDesc);
The latter call is useful if you want to ensure that you're receiving images that have recent feature changes applied. For example, after changing the exposure from X to Y, you may want to ensure that all the images with exposure X have been received by the host, and that images with exposure Y are now being received.
When the camera is configured for free-running triggering (that is, frames are output continuously, driven by an internal trigger that occurs as frequently as possible), this function returns the next available frame from the camera.
When in software trigger mode, PxLGetNextFrame:
- generates the trigger
- blocks until the frame is received from the camera.
When in hardware trigger mode, PxLGetNextFrame blocks until the next triggered frame is received from the camera. Triggered frames delivered to the host while a thread is not blocked in PxLGetNextFrame will be missed.
Emulating Hardware Triggering With Software
PxLGetNextFrame is normally a blocking call. i.e. it will not return until a frame becomes available (or an error occurs). However, as of PixeLINK API 6.21, it is possible to make it a non-blocking call by:
- Enabling software triggering (see TRIGGER_TYPE_SOFTWARE)
- Registering a callback function (see PxLSetCallback) for callback type CALLBACK_FRAME.
- Starting streaming (as usual, via PxLSetStream)
- Calling PxLGetNextFrame with a NULL frame data pointer, e.g.
PXL_RETURN_CODE rc = PxLGetNextFrame(hCamera, bufferSize, NULL, &frameDesc);
This will cause a software trigger to be sent to the camera, and PxLGetNextFrame will immediately return. When the frame is received, the CALLBACK_FRAME callback function will be called with the frame data and frame descriptor.
Using this technique, it's possible to approximate hardware triggering in software. For example, to rapidly 'trigger' several cameras at once via software, configure all cameras as described as above and then call PxLGetNextFrame (as described above) on each and every cameras of interest as quickly as possible.
The demonstration application 'softwaretriggering' demonstrates how to do this.
For .NET applications, PxLGetNextFrame is called using Api.GetNextFrame. The syntax is as follows:
ReturnCode rc = Api.GetNextFrame(int cameraHandle, int bufferSize, byte data, ref FrameDescriptor frameDescriptor);
The GetSnapShot sample application (found in the WPF folder of the SDK) shows the use of GetNextFrame. This sample app also demonstrates using a retry loop to handle timeout conditions.