ccap (CameraCapture)

repository·main·Indexed 41 days ago

https://github.com/wysaid/cameracapture

A high-performance, lightweight, cross-platform library for camera capture and video playback. It features hardware-accelerated pixel format conversion and supports Windows (DirectShow/Media Foundation), macOS/iOS (AVFoundation), and Linux (V4L2). Provides C++ and C interfaces, as well as Rust bindings via ccap-rs v1.7.4. Supports video file input/playback and recording on Windows and macOS.

Tokens
50.5K
Snippets
153
Records
216
Agent score
44%

What's inside ccap

  1. Core concepts of the ccap C interface

    main

    The ccap C interface provides full camera capture functionality using an opaque pointer pattern to hide C++ implementation details.

    Opaque Pointers

    • CcapProvider*: Encapsulates the ccap::Provider object for device management and control.
    • CcapVideoFrame*: Encapsulates a ccap::VideoFrame shared pointer.

    Memory Management Principles

    1. Creation and Destruction: Every object created via ccap_xxx_create() must be released using its corresponding ccap_xxx_destroy() function.
    2. Array Release: Use specialized release functions for arrays of strings or structures returned by the API.
    3. Frame Management: Frames obtained via ccap_provider_grab() must be released using ccap_video_frame_release() to prevent memory leaks.
  2. Platform-specific backend notes

    main

    Windows

    • DirectShow: The default backend. Stable and widely compatible. If certain VR headsets cause crashes during enumeration, build with -DCCAP_WIN_NO_DEVICE_VERIFY=ON.
    • Media Foundation (msmf): Supported via explicit selection. Uses Source Reader for frame acquisition.
    • Virtual Cameras: Supports OBS Virtual Camera, ManyCam, and NDI Virtual Input.

    macOS / iOS

    • AVFoundation: The modern, high-performance backend. Supports native formats like NV12 and BGRA.
    • Permissions: Ensure NSCameraUsageDescription is set in your Info.plist.

    Linux

    • V4L2: Direct kernel interface with low overhead and wide format support.
    • Permissions: Users must be in the video group to access devices (sudo usermod -a -G video $USER).
  3. Understand Camera vs File Mode strategies

    main

    ccap automatically switches its frame delivery strategy based on the source provided to provider.open():

    • Camera Mode: Optimized for real-time/low latency. It prioritizes the latest frames. If your processing loop is slower than the camera's frame rate, old frames are automatically dropped to keep the stream current.
    • File Mode: Optimized for completeness. It ensures every single frame is preserved. It uses a backpressure mechanism where the decoder pauses reading when the internal buffer is full and resumes only when you call grab(). This allows you to process extremely long videos with constant, bounded memory usage and zero frame loss.
    // Camera Mode (prioritizes latest, drops old)
    ccap::Provider provider;
    provider.open(0, true); 
    
    // File Mode (preserves all, uses backpressure)
    ccap::Provider provider;
    provider.open("video.mp4", true);
  4. Differences between C and C++ interfaces

    main

    The ccap library provides two distinct interfaces:

    • C Interface: Uses opaque pointers and manual memory management. It is designed for pure C projects and for creating language bindings (e.g., for Python, Go, or Rust) because it provides a stable ABI.
    • C++ Interface: Uses smart pointers and RAII (Resource Acquisition Is Initialization) for a more modern and safer developer experience.

    Warning: Do not mix C and C++ interfaces within the same program. They manage different internal states, and mixing them may lead to undefined behavior or errors.

  5. How standalone skills are structured

    main

    Standalone skills in this repository are designed to be reusable general agent skills. To ensure compatibility and portability, every standalone skill must adhere to the following structural rules:

    • Location: Each skill must reside in its own dedicated folder under the skills/ directory.
    • Documentation: The skill folder must contain a top-level SKILL.md file.
    • File Types: All supporting files within the skill folder must be text-based.
    • Metadata: Frontmatter used for configuration or metadata must remain concise and machine-parseable.
    • Packaging: When publishing or packaging a skill, commands must target the specific skill folder rather than the repository root.

    Currently, the repository includes the following standalone skill:

    • ccap (located in ./ccap)
  6. Select Windows Backends (DirectShow vs Media Foundation)

    main

    On Windows, ccap defaults to DirectShow for maximum compatibility with virtual cameras (like OBS Virtual Camera). Media Foundation (MSMF) is also supported.

    • auto mode (Default): Merges both backends. It routes devices to the most compatible backend automatically.
    • Explicit Selection: You can force a backend via the constructor or an environment variable.

    Environment Variable: Set CCAP_WINDOWS_BACKEND to auto, msmf, or dshow.

    C++ Explicit Selection:

    // Force Media Foundation
    ccap::Provider msmfProvider("", "msmf");
    
    // Force DirectShow
    ccap::Provider dshowProvider("", "dshow");
    # PowerShell: opt into Media Foundation for the current process
    $env:CCAP_WINDOWS_BACKEND = "msmf"
    .\ccap --list-devices
  7. Select the Windows camera backend

    main

    On Windows, you can choose between dshow (DirectShow) and msmf (Media Foundation). DirectShow is the default and offers better compatibility with virtual cameras like OBS Virtual Camera.

    To select a backend, you can:

    1. Set the CCAP_WINDOWS_BACKEND environment variable to auto, msmf, or dshow.
    2. Use one of the following Rust API methods and pass the backend string (e.g., "msmf" or "dshow") as part of the extra info:
      • Provider::with_device_name_and_extra_info
      • Provider::with_device_and_extra_info
      • Provider::open_device_with_extra_info
      • Provider::open_with_index_and_extra_info
  8. Using C callbacks to control frame capture

    main
    When using the C interface with callback functions for frame capture, the return value of the callback determines whether capture continues. Returning false from the callback function will stop the execution of subsequent frame callbacks, effectively halting the capture process.
  9. Understand Camera vs File modes in ccap

    main

    ccap operates in two primary modes with different memory and frame handling behaviors:

    1. Camera Mode: Optimized for live streaming and real-time use. It uses bounded memory and employs a frame-dropping strategy (keeping only the latest frame) to maintain low latency.
    2. File Mode: Optimized for video analysis and processing. It uses bounded memory but employs a backpressure mechanism instead of dropping frames, ensuring every frame is processed.

    To use File Mode in C++, pass true to the open method to enable playback/file behavior.

    // File mode: process all frames without dropping
    ccap::Provider provider;
    provider.open("video.mp4", true); // true enables file/playback mode
    
    while (auto frame = provider.grab(1000)) {
        // Backpressure ensures no frames are lost
        // Memory remains constant (approx 25-30MB for HD)
        processFrame(frame);
    }
  10. Operational cautions for ccap

    main

    When using ccap, keep the following operational constraints in mind:

    • Permissions: Do not assume camera permissions are automatically granted.
    • Headless Environments: Avoid defaulting to preview modes in headless environments.
    • Platform Differences: Video playback feature support varies; do not assume Linux supports the same features as macOS or Windows.
    • Parsing: Always prefer JSON parsing via the --json flag over text scraping for reliability.
  11. How Camera Mode vs File Mode affects frame handling and memory

    main

    ccap automatically switches between two strategies based on whether you are opening a camera device or a video file:

    Camera Mode (Real-time Optimization)

    Used when opening a camera device (e.g., provider.open(0, true)).

    • Behavior: Prioritizes the latest frames. If your processing loop is slower than the camera's frame rate, older frames are automatically discarded to minimize latency.
    • Use Case: Live streaming, real-time previews.
    • Frame Integrity: frameIndex may have gaps due to dropped frames.

    File Mode (Integrity Optimization)

    Used when opening a video file (e.g., provider.open("video.mp4", true)).

    • Behavior: Uses a backpressure mechanism to ensure every single frame is preserved. When the internal buffer is full, the decoder pauses reading until you call grab().
    • Use Case: Video processing, frame-by-frame analysis, dataset processing.
    • Frame Integrity: frameIndex is always continuous (0, 1, 2, ...).

    Memory Usage

    Both modes use bounded memory. For a 1080p RGBA stream, memory usage remains constant at approximately 25-30MB regardless of the video length or processing speed.

    // Camera Mode: Drops frames to stay real-time
    ccap::Provider provider;
    provider.open(0, true);
    
    // File Mode: Uses backpressure to keep all frames
    ccap::Provider provider;
    provider.open("video.mp4", true);
  12. How the ccap C interface works

    main

    The ccap C interface provides a way to perform camera capture tasks in pure C. It uses opaque pointers to manage underlying C++ objects, ensuring implementation details are hidden from the user.

    Core Abstractions

    • CcapProvider*: Encapsulates the ccap::Provider object for device management and capture control.
    • CcapVideoFrame*: Encapsulates a ccap::VideoFrame shared pointer for accessing image data.
    • CcapVideoWriter*: Encapsulates a ccap::VideoWriter object for saving video files.

    Memory Management Principles

    To avoid memory leaks, you must follow these rules:

    1. Manual Destruction: Every object created with a ccap_xxx_create() function must be released using its corresponding ccap_xxx_destroy() function.
    2. Frame Release: Frames acquired via ccap_provider_grab() must be released using ccap_video_frame_release().
    3. Array Release: Use dedicated release functions for string or struct arrays returned by the API.
    4. Writer Release: Writers created via ccap_video_writer_create() must be released via ccap_video_writer_destroy().