Skip to main content

uvcConfiguration()

Configures the UVC (USB Video Class) streaming parameters including frame resolution, frame interval (FPS), and buffer allocation for video data transfer.

Signature

void uvcConfiguration(
    uint16_t width, 
    uint16_t height, 
    uint32_t frameInterval, 
    uint32_t transferBufferSize, 
    uint8_t *transferBufferA, 
    uint8_t *transferBufferB, 
    uint32_t frameBufferSize, 
    uint8_t *frameBuffer
);

Parameters

width
uint16_t
required
Width of the video frame in pixels. Use FRAME_RESOLUTION_ANY to accept any width supported by the camera.
height
uint16_t
required
Height of the video frame in pixels. Use FRAME_RESOLUTION_ANY to accept any height supported by the camera.
frameInterval
uint32_t
required
Frame interval in 100-nanosecond units. Use the predefined constants for common frame rates:
  • FRAME_INTERVAL_FPS_5 - 5 FPS
  • FRAME_INTERVAL_FPS_10 - 10 FPS
  • FRAME_INTERVAL_FPS_15 - 15 FPS
  • FRAME_INTERVAL_FPS_20 - 20 FPS
  • FRAME_INTERVAL_FPS_30 - 25 FPS (note: actually 25 FPS)
Or calculate custom values using FPS2INTERVAL(fps) macro.
transferBufferSize
uint32_t
required
Size of each transfer buffer in bytes. Must be larger than one frame size. Used for double buffering during USB payload transfer.
transferBufferA
uint8_t*
required
Pointer to the first transfer buffer. This buffer is used as part of the double buffering mechanism for USB payload transfer.
transferBufferB
uint8_t*
required
Pointer to the second transfer buffer. This buffer is used as part of the double buffering mechanism for USB payload transfer.
frameBufferSize
uint32_t
required
Size of the frame buffer in bytes. Must be larger than one complete frame size.
frameBuffer
uint8_t*
required
Pointer to the frame buffer where complete assembled frames will be stored.

Frame Resolution Constants

FRAME_RESOLUTION_ANY
uint16_t
Constant value (__UINT16_MAX__) that indicates any resolution should be accepted. Use for both width and height parameters when you want the library to accept any camera resolution.

Frame Interval Constants

Frame intervals are specified in 100-nanosecond units. The library provides convenient constants:
ConstantFPSValue
FRAME_INTERVAL_FPS_55 FPSFPS2INTERVAL(5)
FRAME_INTERVAL_FPS_1010 FPSFPS2INTERVAL(10)
FRAME_INTERVAL_FPS_1515 FPSFPS2INTERVAL(15)
FRAME_INTERVAL_FPS_2020 FPSFPS2INTERVAL(20)
FRAME_INTERVAL_FPS_3025 FPS*FPS2INTERVAL(25)
The FRAME_INTERVAL_FPS_30 constant actually sets 25 FPS, not 30 FPS. This appears to be intentional in the library.

FPS2INTERVAL Macro

Convert frames per second to frame interval:
#define FPS2INTERVAL(fps) (10000000ul / fps)
Example:
uint32_t interval = FPS2INTERVAL(24); // 24 FPS custom frame rate

Buffer Sizing Guidelines

Calculating Buffer Sizes

For uncompressed formats like MJPEG, estimate buffer sizes based on:
// Conservative estimate for MJPEG
size_t frameSize = width * height * 2; // 2 bytes per pixel

// Transfer buffers (double buffering)
size_t transferBufferSize = frameSize + 1024; // Add margin

// Frame buffer
size_t frameBufferSize = frameSize + 1024; // Add margin

Memory Allocation

  • Allocate buffers in PSRAM for larger resolutions (e.g., 640x480 and above)
  • Ensure sufficient heap memory is available
  • Consider using DMA-capable memory if required by your platform

Example

Complete Configuration

#include <USB_STREAM.h>

// Define resolution
const uint16_t FRAME_WIDTH = 320;
const uint16_t FRAME_HEIGHT = 240;

// Calculate buffer sizes
const size_t FRAME_SIZE = FRAME_WIDTH * FRAME_HEIGHT * 2;
const size_t XFER_BUFFER_SIZE = FRAME_SIZE + 1024;
const size_t FRAME_BUFFER_SIZE = FRAME_SIZE + 1024;

// Allocate buffers
uint8_t *xferBufferA = (uint8_t *)malloc(XFER_BUFFER_SIZE);
uint8_t *xferBufferB = (uint8_t *)malloc(XFER_BUFFER_SIZE);
uint8_t *frameBuffer = (uint8_t *)malloc(FRAME_BUFFER_SIZE);

void setup() {
    Serial.begin(115200);
    
    // Configure UVC streaming
    USBStream.uvcConfiguration(
        FRAME_WIDTH,                // width
        FRAME_HEIGHT,               // height
        FRAME_INTERVAL_FPS_15,      // 15 FPS
        XFER_BUFFER_SIZE,           // transfer buffer size
        xferBufferA,                // transfer buffer A
        xferBufferB,                // transfer buffer B
        FRAME_BUFFER_SIZE,          // frame buffer size
        frameBuffer                 // frame buffer
    );
    
    Serial.println("UVC configured: 320x240 @ 15 FPS");
}

void loop() {
    // Your application code
}

Using Any Resolution

void setup() {
    Serial.begin(115200);
    
    // Allocate generous buffers for any resolution
    size_t largeBufferSize = 640 * 480 * 2 + 1024;
    uint8_t *xferA = (uint8_t *)malloc(largeBufferSize);
    uint8_t *xferB = (uint8_t *)malloc(largeBufferSize);
    uint8_t *frame = (uint8_t *)malloc(largeBufferSize);
    
    // Accept any resolution and frame rate from camera
    USBStream.uvcConfiguration(
        FRAME_RESOLUTION_ANY,       // any width
        FRAME_RESOLUTION_ANY,       // any height
        FRAME_INTERVAL_FPS_15,      // 15 FPS
        largeBufferSize,
        xferA,
        xferB,
        largeBufferSize,
        frame
    );
    
    Serial.println("UVC configured for any resolution");
}

Custom Frame Rate

void setup() {
    Serial.begin(115200);
    
    // Configure for 24 FPS (cinematic frame rate)
    uint32_t fps24Interval = FPS2INTERVAL(24);
    
    size_t bufferSize = 640 * 480 * 2 + 1024;
    uint8_t *xferA = (uint8_t *)malloc(bufferSize);
    uint8_t *xferB = (uint8_t *)malloc(bufferSize);
    uint8_t *frame = (uint8_t *)malloc(bufferSize);
    
    USBStream.uvcConfiguration(
        640,                        // width
        480,                        // height
        fps24Interval,              // 24 FPS custom
        bufferSize,
        xferA,
        xferB,
        bufferSize,
        frame
    );
    
    Serial.println("UVC configured: 640x480 @ 24 FPS");
}

Notes

Call uvcConfiguration() before starting USB streaming. Configuration cannot be changed while streaming is active.
Ensure buffer sizes are adequate for your resolution. Insufficient buffer sizes will cause frame drops and corruption.
Transfer buffers use double buffering to improve performance. While one buffer is being filled by USB transfer, the other can be processed.

Build docs developers (and LLMs) love