How harshit-dhanwalkar/asciicam works
Purpose and Entry Point
AsciiCam is a C99 terminal webcam viewer that captures live video, transforms frames into grayscale or RGB-derived terminal cells, and renders ASCII/Unicode/ANSI truecolor output in real time. The executable entry point and main control loop are in C/src/main.c; build orchestration is C/Makefile.
Capture Abstraction and Platform Boundary
Camera acquisition is selected at compile time behind a common capture interface. Linux uses V4L2, macOS uses AVFoundation, and Windows uses Media Foundation. Platform conditionals and shared declarations belong at the boundary rather than in rendering code.
• C/include/capture.h
• C/src/capture_linux.c
• C/src/capture_macos.c
• C/src/capture_windows.c
Linux additionally exposes live hardware exposure, contrast, and white-balance controls through V4L2 ioctls; the non-Linux backends retain capture but stub those controls.
Frame Processing and Terminal Rendering
The rendering subsystem converts camera-format frames (YUYV) to grayscale or RGB, applies selected visual processing, maps brightness to a character ramp, and writes terminal escape sequences/cells. It owns render modes including ASCII, braille, blocks, half-blocks, and dots, plus ANSI truecolor and dithering behavior.
• C/src/ascii.c
• C/include/ascii.h
• C/charsets/ascii.txt
Character ramps are external text assets, enabling runtime charset selection and reload. Built-in selectable ramps reside under C/charsets/, including line, dot, and shade-oriented mappings.
Filter and Plugin Pipeline
Filters are dynamically loaded shared objects and form a frame-processing pipeline before final rendering. The repository supplies invert, threshold, and edge-detection plugins; edge detection supports Sobel variants and Laplacian behavior. Plugin loading, invocation, change detection, unload/reload, and runtime parameter selection are centralized separately from individual filter implementations.
• C/src/plugins.c
• C/include/plugins.h
• C/filters/edge_detect.c
On Linux, live plugin and charset reload relies on inotify plus dlopen; plugins are compiled as .so files. This is a key runtime extension boundary: plugin code operates through the interface declared by plugins.h, while the host owns loading and lifecycle.
Main Loop, Input, and Timing
main.c coordinates command-line options, camera setup, terminal interaction, plugin/charset state, frame acquisition, processing, and shutdown. Runtime key commands change render mode, edge mode, charset, depth effect, plugin selection/parameters, and camera controls. Frame cadence is capped using monotonic-clock timing and sleep-based pacing.
• C/src/main.c
• C/src/timing.c
• C/include/timing.h
Concurrent Frame Exchange
A producer/consumer design provides double-buffered capture-to-render exchange. This isolates camera acquisition from terminal rendering and avoids handing partially written frames to the renderer. The README notes the active sharing implementation exists independently while integration in the primary loop is partial/stubbed.
• C/src/thread_sharing.c
• C/include/thread_sharing.h
• C/src/main.c
Runtime/Foundation Layer
Linux targets a bundled nolibc-style support layer for allocation, I/O, startup, syscall wrappers, signals, formatting, and option parsing; it reduces dependence on normal libc APIs. The build still materially depends on platform camera APIs and, on Linux, libdl and pthread.
• C/lib/nolibc.h
• C/lib/nl_alloc.c
• C/lib/nl_start.c
The operational flow is: startup/options → platform capture initialization → persistent frame/output buffer setup → capture and optional threaded handoff → plugin/filter processing → charset/render-mode mapping and terminal output → timing/input/reload polling → cleanup.
Main entry points: main.c Main loop · capture.h Capture interface · plugins.c Plugin host · Makefile C build
Components 19
Application
- Main loop · Coordinates startup, capture, processing, input, pacing, and cleanup.
C/src/main.c - Frame timing · Caps frame cadence with monotonic time and sleep.
C/src/timing.c - Timing API
C/include/timing.h - Double-buffer exchange · Separates capture writes from renderer reads; primary-loop integration is partial.
C/src/thread_sharing.c
Capture Boundary
- Capture interface · Common camera acquisition and control declarations.
C/include/capture.h - V4L2 capture · Captures frames and exposes live camera controls through ioctls.
C/src/capture_linux.c - AVFoundation capture · Camera backend with stubbed hardware controls.
C/src/capture_macos.c - Media Foundation capture · Camera backend with stubbed hardware controls.
C/src/capture_windows.c
Processing & Extensions
- Plugin host · Loads, invokes, watches, reloads, and configures filters.
C/src/plugins.c - Plugin interface · Extension contract implemented by filter shared objects.
C/include/plugins.h - Edge-detection filter · Supports Sobel variants and Laplacian behavior.
C/filters/edge_detect.c - Terminal renderer · Converts YUYV, applies visual modes, maps cells, and emits ANSI output.
C/src/ascii.c - Renderer API
C/include/ascii.h - Character ramps · Selectable and reloadable brightness mappings.
C/charsets/ascii.txt
Runtime Foundation
- C build · Builds executable and platform-specific components.
C/Makefile - nolibc support · Provides low-level allocation, I/O, syscalls, startup, and parsing.
C/lib/nolibc.h - Low-level allocation
C/lib/nl_alloc.c - Low-level startup
C/lib/nl_start.c
Other components
- Terminal output · ASCII, Unicode, and ANSI truecolor display.
Connections 23
- C build → Main loop: builds
- C build → V4L2 capture: Linux target
- C build → AVFoundation capture: macOS target
- C build → Media Foundation capture: Windows target
- Main loop → Capture interface: initializes
- Capture interface → V4L2 capture: compile-time backend
- Capture interface → AVFoundation capture: compile-time backend
- Capture interface → Media Foundation capture: compile-time backend
- V4L2 capture → Double-buffer exchange: captured frames
- Double-buffer exchange → Plugin host: frame handoff
- Capture interface → Plugin host: frames when handoff inactive
- Main loop → Plugin host: configures pipeline
- Plugin host → Plugin interface: hosts contract
- Edge-detection filter → Plugin interface: implements
- Plugin host → Terminal renderer: processed frame
- Character ramps → Terminal renderer: brightness ramp / reload
- Terminal renderer → Terminal output: ANSI cells
- Main loop → Frame timing: paces loop
- Frame timing → Timing API: implements
- Main loop → nolibc support: Linux foundation
- Low-level allocation → nolibc support: implements
- Low-level startup → nolibc support: implements
- Renderer API → Terminal renderer: declares