FLI libflipro API
SimpleStreamer.cpp

Simple Streaming Application Example Code.
This example shows you how to create a simple streaming application to write files to disk.

#include "stdint.h"
#include "stdlib.h"
#include "stdio.h"
#if defined(_WIN32) || defined(_WINDOWS)
#include "windows.h"
#else
#include "unistd.h"
#endif
#include "wchar.h"
#include "libflipro.h"
#define FLI_TEST_MAX_SUPPORTED_CAMERAS (4)
// Static Function declarations
static int32_t SetFrameInfo(int32_t iDeviceHandle);
// Static Data declarations
static int32_t s_iDeviceHandle;
uint32_t uiNumDetectedDevices;
static FPRODEVICEINFO s_camDeviceInfo[FLI_TEST_MAX_SUPPORTED_CAMERAS];
static FPROCAP s_camCapabilities;
#define STREAMER_PATH_MAX (1024)
static wchar_t s_wcStreamerPath[STREAMER_PATH_MAX];
static wchar_t s_wcStreamerPrefix[STREAMER_PATH_MAX];
int main()
{
int32_t iResult;
uint32_t uiFramSizeInBytes;
uint32_t uiNumFrames;
uint32_t uiCamCapSize;
FPROSTREAMSTATS streamStats;
// first get the list of available devices
uiNumDetectedDevices = FLI_TEST_MAX_SUPPORTED_CAMERAS;
iResult = FPROCam_GetCameraList(s_camDeviceInfo, &uiNumDetectedDevices);
if ((iResult >= 0) && (uiNumDetectedDevices > 0))
{
// Open the first device in the list
s_iDeviceHandle = -1;
iResult = FPROCam_Open(&s_camDeviceInfo[0], &s_iDeviceHandle);
if ((iResult >= 0) && (s_iDeviceHandle >= 0))
{
// Different camera models support a different set of capabilities.
// The API allows you to retrieve the capabilities so that you can obtain
// images properly and configure your applications accordingly. In all cases,
// you need to know the size of the Meta Data supplied by the camera that is
// prepended to every image. This size is contained in the capabilities structure.
uiCamCapSize = sizeof(FPROCAP);
iResult = FPROSensor_GetCapabilities(s_iDeviceHandle, &s_camCapabilities, &uiCamCapSize);
// Set up your exposure and frame parameters
if (iResult >= 0)
iResult = SetFrameInfo(s_iDeviceHandle);
if (iResult >= 0)
{
// Make sure we have space for the image frame.
// Calculating the byte size of the image that will be generated by the camera can become
// quite involved. The size depends not only on the image dimensions and pixel size, but
// also on the size of the meta data returned for each frame, the number of pre and post row
// reference pixels, the number of pre and post frame reference rows, as well as the
// horizontal and vertical binning factors. In the most simple case, with 12 bit pixels,
// you can use the FPRO_IMAGE_DIMENSIONS_TO_FRAMEBYTES() provided macro to calculate the
// byte size of the image data and then just add the meta data size. Note that this assumes no
// reference pixels and 1:1 binning:
//
// uiFramSizeInBytes = FPRO_IMAGE_DIMENSIONS_TO_FRAMEBYTES(2048, 2048) + s_camCapabilities.uiMetaDataSize;
//
// However, things get complicated quickly when applying the various settings described above.
// To facilitate calculating the actual byte size of the data you will receive for an image, the
// API provides the FPROFrame_ComputeFrameSize() function. Note that before you use this function,
// ALL imaging parameters and Hardware Merge configuration must be set. The reason is because this
// call uses the actual camera and Hardware Merge settings to determine the size of the resulting image data.
uiFramSizeInBytes = FPROFrame_ComputeFrameSize(s_iDeviceHandle);
if (iResult >= 0)
{
// all is well - Now you can get the streamer interface started
// First initialize the Streamer. You need to pass a path to where you want the
// streamed files stored, and optionally a prefix for each file. A time stamped
// directory will be created in the path directory you specify. The prefix will be prepended
// to each file that is stored.
uiNumFrames= 10;
#if defined(_WIN32) || defined(_WINDOWS)
wcscpy_s(s_wcStreamerPath, STREAMER_PATH_MAX, L"./StreamerFiles");
wcscpy_s(s_wcStreamerPrefix, STREAMER_PATH_MAX, L"myFiles");
#else
wcscpy(s_wcStreamerPath, L"./StreamerFiles");
wcscpy(s_wcStreamerPrefix, L"myFiles");
#endif
iResult= FPROFrame_StreamInitialize(s_iDeviceHandle, uiFramSizeInBytes, s_wcStreamerPath, s_wcStreamerPrefix);
if (iResult >= 0)
{
// Successful initialization
// Start the streamer
// Here you pass the number of images to stream (10 in this case).
// Passing 0 will run forever until you stop it.
// The Frame Interval works similarly to the timeout you specify in the
// FPROFrame_GetVideoFrame() call. The API needs to know when to expect frames.
// Typically you just set this to the exposure time + inter-frame delay you have set up.
iResult= FPROFrame_StreamStart(s_iDeviceHandle, 10, 50);
if (iResult >= 0)
{
// The streaming process has started, now you wait until it is done
// Checking for completion is a bit tricky- Checking for a status of FPRO_STREAMER_STOPPED
// is insufficient. There are underlying threads writing the files to the physical disk.
// You must make sure that all of the streamed files have been written before stopping the
// streamer.
iResult= FPROFrame_StreamGetStatistics(s_iDeviceHandle, &streamStats);
while ((iResult >= 0) &&
(!((streamStats.iStatus == FPRO_STREAMER_STOPPED) && (streamStats.uiDiskFramesWritten == uiNumFrames)) || (streamStats.iStatus == FPRO_STREAMER_STOPPED_ERROR)))
{
// Check the stats again- you can check as often as you like
#if defined(_WIN32) || defined(_WINDOWS)
Sleep(1000);
#else
sleep(1);
#endif
iResult= FPROFrame_StreamGetStatistics(s_iDeviceHandle, &streamStats);
printf("\rNum Written= %lld",streamStats.uiDiskFramesWritten);
fflush(stdout);
}
printf("\n");
// check the reasons for leaving the loop
if ((iResult < 0) || (streamStats.iStatus == FPRO_STREAMER_STOPPED_ERROR))
{
printf("Stream Error\n");
}
// stop the stream
FPROFrame_StreamStop(s_iDeviceHandle);
// You may start the stream up again without deinitializing.
// But if you want to change the frame size, path, or prefix,
// you must deinitialize and then re-initialize with the
// new settings.
}
// Deinitialize the stream
FPROFrame_StreamDeinitialize(s_iDeviceHandle);
}
}
}
// Close up shop
iResult = FPROCam_Close(s_iDeviceHandle);
}
}
return 0;
}
int32_t
SetFrameInfo(int32_t iDeviceHandle)
{
int32_t iResult;
// assume success
iResult = 0;
// Set the exposure time
// The default camera exposure time is 50msecs (for the GSENSE 400)
// The FPROCtrl_SetExposureTime() API expects the exposure time in
// nano seconds. The frameDelay parameter is also in nanoseconds
if (iResult >= 0)
iResult = FPROCtrl_SetExposure(iDeviceHandle, 50000000,10000000,false);
// Set the Image area
// By default, the camera sets its image area to its maximum values.
// For the GSENSE 4040 model, that is 4096 columns x 4096 rows
// But if you were to change the values this is how you would do it.
if (iResult >= 0)
iResult = FPROFrame_SetImageArea(iDeviceHandle, 0, 0, 4096, 4096);
// return our result
return(iResult);
}