Encode video from a camera

Updated: April 19, 2023

The Camera library provides the necessary codecs to encode and decode image buffers to and from H.264 format and uncompressed formats.

To encode your video:
  1. Connect to the camera.
  2. Set the viewfinder mode for the camera.
  3. Set up Screen. See Connect Screen with the Camera API for more information.
  4. Start the viewfinder and configure camera settings.
  5. If you want to encode to H.264, validate it's supported. To do this, use camera_get_video_property() and CAMERA_IMGPROP_VIDEOCODEC as an argument.
  6. Start encoding video by calling camera_start_encode() and specifying a callback to handle the frames to encode. For information about the arguments to use for the callback, see Using callback mode in the Image Buffer Access chapter of this guide.
  7. When you're done encoding, call camera_stop_encode().
  8. Stop the viewfinder and close the camera. For more information, see Stop the viewfinder.”
Here's a code snippet that demonstrates how to encode video. For more information, see the Camera example application provided with this release:
...
...
bool maxMin;
int numSupported;
int *supportValues = NULL;
camera_handle_t cameraHandle;
camera_videocodec_t videoCodec;
int x=0;

// Connect to the camera, set the viewfinder mode for video encoding, and start the viewfinder
camera_open(CAMERA_UNIT_1, CAMERA_MODE_RW | CAMERA_MODE_ROLL, &cameraHandle);
camera_set_vf_mode(cameraHandle, CAMERA_VFMODE_VIDEO);
camera_start_viewfinder(cameraHandle, NULL, NULL, NULL);

// Check that the video encoder configuration supports H.264
camera_get_video_property(cameraHandle, CAMERA_IMGPROP_VIDEOCODEC, &videoCodec);
if (videoCodec != CAMERA_VIDEOCODEC_H264) {
    printf("No video encoder configuration supported for selected codec\n");
    return -1;
}

// Retrieve configured parameters on the camera
camera_get_videoencoder_parameter(cameraHandle,
                                  CAMERA_H264AVC_BITRATE, &bitrate,
                                  CAMERA_H264AVC_KEYFRAMEINTERVAL, &kfi,
                                  CAMERA_H264AVC_SLICETYPE, &sliceType,
                                  CAMERA_H264AVC_SLICESIZE, &sliceSize,
                                  CAMERA_H264AVC_PROFILE, &profile,
                                  CAMERA_H264AVC_LEVEL, &level,
                                  CAMERA_H264AVC_ENTROPYCODING, &entropy,
                                  CAMERA_H264AVC_RATECONTROL, &rateControl,
                                  CAMERA_H264AVC_QPI, &qpI,
                                  CAMERA_H264AVC_QPP, &qpP);

// Call it the first time to determine the number of supported bitrates
camera_get_supported_videoencoder_parameter_values(cameraHandle,
                                                   CAMERA_H264AVC_LEVEL, 0, 
                                                   &numSupported, NULL, 
                                                   &maxMin);

// Allocate memory to hold all supported bitrate values
supportedValues = (int*) malloc(sizeof(int) * numSupported);

// Call it a second time to retrieve the list of values
if (camera_get_supported_videoencoder_parameter_values(cameraHandle,
                                                       CAMERA_H264AVC_LEVEL, numSupported,
                                                       &numSupported, supportedValues,
                                                       &maxMin)!= EOK) {
    for(x=0; x < numSupported; ++x) {
        printf("\t Enumerator Value: %d", supportedValues[x]);
    }
}

// Pick some value and set it. For example, we'll pick the first one.
camera_set_videoencoder_parameter(cameraHandle, CAMERA_H264AVC_LEVEL, supportedValues[0]);

// Start encoding and use a callback function that keeps track of stats for the camera
camera_start_encode(cameraHandle[i], NULL, encodedVideoCallback, NULL, NULL, (void*)i);
...
...
// Do something while you are waiting
wait(2000);

camera_stop_encode(cameraHandle);

// Close the viewfinder and disconnect from the camera
wait(2000);
camera_stop_viewfinder(cameraHandle);
camera_close(cameraHandle);

/*
 * Encoded video callback - called with encoded video frames
 */
void encodedVideoCallback(camera_handle_t handle, camera_buffer_t* buffer, void *arg) {
    // Print first encoded frame received and keep stats
    int cameraInst = (int) arg;

    if (cameraInst < MAX_SIMULTANEOUS_CAMERAS) {
        if (encodingInfo[cameraInst].numFrames == 0) {
            printf("Camera %d: first encoded frame of %lld bytes key %d rate %lld\n", cameraInst + 1,
                   buffer->framedesc.compvid.bufsize, buffer->framedesc.compvid.keyframe,
                   buffer->framedesc.compvid.bitrate);
        }
        encodingInfo[cameraInst].numFrames++;
        if (buffer->framedesc.compvid.keyframe) {
            encodingInfo[cameraInst].numKeyFrames++;
        }
    }
}
...
...

Change the bitrate speed

By default, the Camera library uses an encoding bitrate that lets you record video at 720p at 30 fps at 8 Mbps. You can reduce the bitrate to help increase the frames per second (fps) that you capture on the camera. For instance, you may want to encode at 4 Mbps or 2 Mbps. To do this, use camera_set_videoencoder_parameter() and the CAMERA_H264AVC_BITRATE to modify the bitrate. To determine the valid values you can use, call camera_get_supported_videoencoder_parameter_values(). To determine the current bitrate set for the camera, call camera_get_videoencoder_parameter().

Here's a code snippet:
...
...
bool maxMin;
int numSupported;
int *supportValues = NULL;
camera_handle_t cameraHandle;
int x=0;

// Connect to the camera, set the viewfinder mode for video encoding, and start the viewfinder
camera_open(CAMERA_UNIT_1, CAMERA_MODE_RW | CAMERA_MODE_ROLL, &cameraHandle);
camera_set_vf_mode(cameraHandle, CAMERA_VFMODE_VIDEO);
camera_start_viewfinder(cameraHandle, NULL, NULL, NULL);

// Retrieve the current bitrate setting on the camera
camera_get_videoencoder_parameter(cameraHandle, CAMERA_H264AVC_BITRATE, &bitrate);

// Call it the first time to determine the number of supported bitrates
camera_get_supported_videoencoder_parameter_values(cameraHandle, 
                                                    CAMERA_H264AVC_BITRATE, 
                                                    0, 
                                                    &numSupported, 
                                                    NULL, 
                                                    &maxMin);

// Allocate memory to hold all supported bitrate values
supportedValues = (int*) malloc(sizeof(int) * numSupported);

// Call it a second time to retrieve the list of values
if (camera_get_supported_videoencoder_parameter_values(cameraHandle, 
                                                        CAMERA_H264AVC_BITRATE, 
                                                        numSupported,
                                                        &numSupported, 
                                                        supportedValues, 
                                                        &maxMin)!= EOK) {
    for(x=0; x < numSupported; ++x) {
        printf("\t Enumerator Value: %d", supportedValues[x]);
    }
}

// Pick some value and set it. For example, we'll pick the first one.
camera_set_videoencoder_parameter(cameraHandle, CAMERA_H264AVC_BITRATE, supportedValues[0]);

// Go encode your video
...
...