ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
capture.h File Reference

ascii-chat Client Media Capture Management Interface More...

Go to the source code of this file.

Functions

int capture_init ()
 Initialize capture subsystem.
 
int capture_start_thread ()
 Start capture thread.
 
void capture_stop_thread ()
 Stop capture thread.
 
bool capture_thread_exited ()
 Check if capture thread has exited.
 
void capture_cleanup ()
 Cleanup capture subsystem.
 
void * capture_get_media_source (void)
 

Detailed Description

ascii-chat Client Media Capture Management Interface

Defines the interface for video capture and transmission management in the ascii-chat client. Abstracts over multiple media sources (webcam, files, stdin, test patterns) and handles frame processing, resizing, and FPS sync.

The capture subsystem:

  • Manages platform-specific webcam access via abstraction layer
  • Supports multiple media sources (webcam, local files, stdin, test patterns)
  • Performs frame resizing and format conversion for network efficiency
  • Synchronizes frame transmission with configurable FPS rates
  • Handles periodic frame transmission to the server

Media Source Types

The capture subsystem supports four media source types via the media_source_t abstraction (see Media):

  • WEBCAM: Hardware camera device (webcam/camera)
    • Platform-specific access (V4L2 on Linux, AVFoundation on macOS)
    • Real-time capture with variable frame rate
    • Selected via --webcam-index <N> (default: 0, first camera)
  • FILE: Local media file or network stream
    • Supported formats: mp4, avi, mkv, webm, mov, flv, wmv, gif
    • Specified via --file <path> option
    • Playback at configurable frame rate
    • Loop support via --media-loop option
  • STDIN: Piped or redirected media data
    • Specified via --file - (dash indicates stdin)
    • Any format supported by FFmpeg (detected automatically)
    • Useful for streaming pipes: ffmpeg ... | ascii-chat client --file -
    • Does not support seeking/rewinding
  • TEST: Procedural test pattern generator
    • Enabled via --test-pattern option
    • Generates animated test pattern without hardware
    • Useful for testing without webcam access
    • Always available (no hardware requirements)

Media source selection is automatic based on command-line options:

./ascii-chat client --test-pattern # Use test pattern
./ascii-chat client --file video.mp4 # Play file
./ascii-chat client --file - # Read from stdin
./ascii-chat client --webcam-index 0 # Use default camera
./ascii-chat client # Auto-detect (webcam or test)

Frame Format and Negotiation

All media sources are normalized to a common frame format:

  • Color Space: RGB (24-bit) - three bytes per pixel (R, G, B)
  • Byte Order: Platform-native (little-endian on x86/ARM)
  • Frame Dimensions: Variable (see Resize Behavior below)
  • Pixel Layout: Continuous row-major array (no padding between rows)

Frame format is opaque to the caller - the media source abstraction handles all conversions. Consumers always receive RGB frames ready to use:

// Get frame from any media source (format already normalized)
// Frame is guaranteed to be:
// - RGB format (8-bit per channel)
// - Dimensions: frame->width x frame->height pixels
// - Memory: frame->data[y * frame->width * 3 + x * 3 + channel]
image_t * media_source_read_video(media_source_t *source)
Read next video frame from media source.
Definition source.c:523
int frame
Definition splash.c:99
Image structure.

Different input types undergo conversion:

  • WEBCAM: V4L2/AVFoundation -> RGB (platform layer conversion)
  • FILE/STDIN: FFmpeg decoder -> RGB (FFmpeg handles all codecs)
  • TEST: Generated directly as RGB (no conversion needed)

Frame Resizing and Aspect Ratio

Captured frames are resized for network efficiency while preserving aspect ratio:

  • Maximum Dimensions: 800x600 pixels (default) - reasonable bandwidth
  • Aspect Ratio: Original aspect ratio preserved via fit-to-bounds
  • Scaling Algorithm: Letterboxing - frame fits within bounds with padding
  • Padding Color: Black (0, 0, 0) for empty regions

Resize process:

  1. Calculate scale factor to fit frame within 800x600
  2. Compute new dimensions maintaining aspect ratio
  3. Scale frame using resizing algorithm (maintains quality)
  4. Add black padding to fill remaining space (if needed)

Example resizes:

  • 1920x1440 (4:3) → 800x600 (fits exactly)
  • 1280x720 (16:9) → 800x450 (with 75px black bars top/bottom)
  • 640x480 (4:3) → 640x480 (no resize, smaller than max)
  • 3840x2160 (16:9) → 800x450 (same 16:9 aspect)

Frame resizing options (future):

  • --resize-width <W> - Custom max width (default: 800)
  • --resize-height <H> - Custom max height (default: 600)
  • --no-resize - Disable resizing (use original dimensions)

Frame Rate Synchronization (FPS Control)

The capture system implements frame rate limiting for bandwidth efficiency and smooth playback:

  • Capture Rate: Up to 144 FPS (high refresh rate support)
  • Target FPS: Configurable via --fps <rate> (default: 60)
  • Range: 1 to 144 FPS (1 = slowest, 144 = fastest)
  • Timing Method: Monotonic clock for accuracy
  • Adaptive Delay: Dynamic sleep adjustment for consistent frame intervals

FPS configuration:

./ascii-chat client --fps 30 # 30 FPS (slower, less bandwidth)
./ascii-chat client --fps 60 # 60 FPS (default, balanced)
./ascii-chat client --fps 144 # 144 FPS (max, high refresh)

FPS behavior by source type:

  • WEBCAM: Captures at hardware rate, then throttles to target FPS
  • FILE: Plays at media file's native FPS, then throttles to target
  • STDIN: Decodes frames, then throttles to target FPS
  • TEST: Generates at target FPS directly (no throttling needed)

Frame rate calculation:

  1. Calculate frame interval: interval_ms = 1000 / fps
  2. Record capture start time (monotonic clock)
  3. Capture and process frame
  4. Calculate elapsed time
  5. Sleep for remaining interval to achieve consistent rate

Example timing (60 FPS target = 16.67ms per frame):

  • Frame start: 0ms
  • Capture: 5ms
  • Process: 2ms
  • Elapsed: 7ms
  • Sleep: 9.67ms (to reach 16.67ms total)
  • Frame complete: 16.67ms ✓ (on schedule)

Capture Lifecycle

  1. Initialization (capture_init): Set up platform-specific webcam drivers
  2. Thread Start (capture_start_thread): Spawn capture thread in connection loop
  3. Capture Loop: Continuously grab frames and send to server
  4. Thread Stop (capture_stop_thread): Signal thread to exit and wait
  5. Cleanup (capture_cleanup): Release platform resources
Author
Zachary Fogg me@zf.nosp@m.o.gg
Date
2025
See also
topic_client_capture "Video Capture Architecture"
media/source.h "Media Source Abstraction"

Definition in file client/capture.h.

Function Documentation

◆ capture_get_media_source()

void * capture_get_media_source ( void  )

Definition at line 564 of file client/capture.c.

564 {
565 return session_capture_get_media_source(g_capture_capture_ctx);
566}
void * session_capture_get_media_source(session_capture_ctx_t *ctx)
Get the underlying media source from capture context.

References session_capture_get_media_source().

Referenced by protocol_start_connection().