Start the viewfinder and configure camera settings

Updated: April 19, 2023

After you set the viewfinder mode for your camera, you can start the viewfinder. This entails starting the imaging datapath (i.e., streaming data from the camera). We refer to access to the imaging datapath as image buffers.

You can choose whether you want to start the viewfinder with the default configuration settings that are enabled after you call camera_set_vf_mode(), or whether you want to configure certain settings before you call camera_start_viewfinder().

For your application, you might want to configure default settings for the viewfinder window before you call camera_start_viewfinder(), such as the rotation of viewfinder, framerates, width, or height. These preconfigured settings are used to help ensure that the video shown is acceptable. For that reason, you should specify the viewfinder window settings that are optimal under most situations before the image buffers are created. Experimentation is often necessary to determine the appropriate settings. For information on how to set viewfinder window attributes, see Modify viewfinder window attributes.”

There are also manual settings that you can modify, such as ISO and aperture. For more information that can help to improve the video, see the Settings on the Camera chapter. Notably, there are some manual settings that can't be set until after you call camera_start_viewfinder(). These settings, such as contrast or brightness, give more granular control over certain features that aren't possible until the imaging datapath has been started.

If you modify the configuration settings after you start the viewfinder, there's a slight delay before the changes get applied to the image buffers from the camera. For example, you can start the viewfinder, show the image buffers from the camera on a display, and then provide settings for the user to adjust them in your application.

When you start the imaging datapath using camera_start_viewfinder(), you can optionally pass these arguments to have read-only access to the image buffers: If you don't need to handle the availability of an image buffer or status events, you can set the associated argument to NULL. For more information about using callbacks, see Using callback mode.”
Note: If you want read/write access, you must use event mode. For more information, see Using event mode.”
The following code snippet shows how to use callbacks when you start the imaging datapath. For context, we include the initial Camera API calls of setting the viewfinder mode and connecting to the camera, and also the call of setting the window group ID and window ID:
...
...
void statusCallback(camera_handle_t handle, 
                    camera_devstatus_t devstatus, 
                    uint16_t extra, 
                    void *arg)
{
    // You would normally handle asynchronous events here, but for this example, do nothing
    printf("Message:%s", (char*)arg);
}
...
...
int main()
{
    char groupId[64];
    char windowId[64];
    camera_handle_t cameraHandle;
    int err;

    err = camera_open(CAMERA_UNIT_1, CAMERA_MODE_RW | CAMERA_MODE_ROLL, &cameraHandle);
    if (err != CAMERA_EOK) {
        // Error-handling goes here
    }
    err = camera_set_vf_mode(cameraHandle, CAMERA_VFMODE_VIDEO);
    if (err != CAMERA_EOK) {
        // Error-handling goes here
    }
    ...
    err = camera_set_vf_property(cameraHandle, 
                                 CAMERA_IMGPROP_WIN_GROUPID, groupId, 
                                 CAMERA_IMGPROP_WIN_ID, windowId);
    if (err != CAMERA_EOK) {
        // Error-handling goes here
    }

    // Start the viewfinder
    char mymessage[]="hello\n";

    err = camera_start_viewfinder(cameraHandle, NULL, statusCallback, (void*)&mymessage);
    if (err != CAMERA_EOK) {
        // Error-handling goes here
    }
    ...
}
...
...

Modify viewfinder window attributes

Some viewfinder window attributes should be set before you start the viewfinder. These settings are usually configured using camera_set_vf_property(). You can retrieve the current values using camera_get_vf_property() and supported values using the camera_get_supported_*() functions. For example, to get the supported framerates for the camera, call camera_get_supported_vf_framerates().

Here's a snippet of how to get the current framerate, retrieve the supported framerates from the camera, and set the framerate to one of the supported rates:
...
camera_frametype_t format;
camera_handle_t cameraHandle;
double* supportedFramerates;
double framerate;
bool maxMin;
uint32_t numSupported;
int err=0;
...
err = camera_get_vf_property(cameraHandle, CAMERA_IMGPROP_FRAMERATE, &framerate);
if (err != EOK) {
    printf("Failed to get the image sequence frame rate: err = %d\n", err);
    return err;
}
printf("The current framerate is %3.2f\n", framerate);

// Get three supported rates for illustrative purposes
supportedFramerates = (double*) malloc(sizeof(double) * 3);
err = camera_get_supported_vf_framerates(cameraHandle, 
                                         format, 
                                         numSupported, 
                                         &numSupported, 
                                         supportedFramerates,
                                         &maxMin);
if (err != EOK) {
    printf("Failed to get list of supported framerates: err = %d\n", err);
    free(supportedFramerates);
    return err;
}

// Set the framerate to the first framerate that was retrieved in the array
err = camera_set_vf_property(cameraHandle, CAMERA_IMGPROP_FRAMERATE, supportedFramerates[0]);
if (err != EOK) {
    printf("Failed to set vf properties: err = %d\n", err);
    return err;
} 

Modify image attributes

In addition to the viewfinder window attributes, you can modify the image attributes, such as contrast, brightness, and hue. These settings can be set before or after you start the viewfinder.

First you should call camera_get_supported_contrast() to determine the contrast settings available on the camera. Then, using the available contrast settings, call camera_set_contrast() to change the contrast value before you call camera_start_viewfinder(). Changes made for image attributes take effect immediately.

Here's a code snippet of what your code can look like. For brevity, we've omitted error checking and handling, but in your production application code, be sure to perform the appropriate error handling.
...
camera_handle_t cameraHandle;
uint32_t numSupported;
int32_t* supportedValues;
bool maxMin;
int32_t contrast;
uint32_t i;
int userValue;
char userString[80];

// Connect to the camera and set the viewfinder mode
camera_open(CAMERA_UNIT_1, CAMERA_MODE_RW | CAMERA_MODE_ROLL, &cameraHandle);
camera_set_vf_mode(cameraHandle, CAMERA_VFMODE_VIDEO);

// Call the function with the numask parameter set to zero to get the number of
// supported contrast modes available on the camera
camera_get_supported_contrast(cameraHandle, 0, &numSupported, NULL, &maxMin);

// Allocate an array based on the number of supported contrast modes.
// The number of modes is put into the numSupported variable.
supportedValues = (int32_t*) malloc(sizeof(int32_t) * numSupported);

// Call the function again to get the number of supported modes
camera_get_supported_contrast(cameraHandle, 
                              numSupported, &numSupported, 
                              supportedValues, &maxMin);

// Do something to let the user choose
printf("Select which of the following contrast values you want to use:\n");
for (i = 0; i < numSupported; i++) {
    printf("\t%d) %d\n", i + 1, supportedValues[i]);
}
fgets(userString, sizeof(userString), stdin);
userValue = atoi(userString);
// Because we added one to present the options to the user
contrast = supportedValues[userValue - 1];
 
// Clean up memory allocated
free(supportedValues);
camera_set_contrast(cameraHandle, contrast);

// Now start the viewfinder
camera_start_viewfinder(cameraHandle, NULL, NULL, NULL);
...
...