Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980#ifndef AC_CAMERA_H#define AC_CAMERA_H
#include <stdint.h>#include <pthread.h>
// Forward declare graph for camera_blitstruct ACGraph;
typedef struct { int fd; // V4L2 device fd (-1 = closed) int width, height; // capture resolution uint32_t pixfmt; // negotiated V4L2 pixel format (YUYV or MJPEG) uint8_t *buffers[4]; // mmap'd V4L2 buffers int buffer_count; int streaming; // 1 = V4L2 streaming active
// Grayscale frame for QR detection (width * height) uint8_t *gray; int gray_ready; // 1 = new frame available
// Display frame: mutex-protected copy for main thread rendering uint8_t *display; // copy of gray for rendering (width * height) pthread_mutex_t display_mu; // protects display buffers volatile int display_ready; // 1 = new display frame available
// Color display frame (ARGB32, width * height) — filled from YUYV (or // decoded MJPEG when ffmpeg is available); the 'cap' piece renders this. // Guarded by display_mu alongside the grayscale copy. uint32_t *display_rgb; volatile int display_rgb_ready;
// display_mu is initialized once and survives open/close cycles so a // renderer holding the lock never races a plug-and-play reopen. int display_mu_init;
// MJPEG decode state (libavcodec/libswscale, only under HAVE_AVCODEC). // void* keeps ffmpeg headers out of this file. void *av_ctx; // AVCodecContext* void *av_frame; // AVFrame* void *av_pkt; // AVPacket* void *sws; // SwsContext*
// QR scan results volatile int scan_pending; // 1 = scan requested volatile int scan_done; // 1 = scan complete (check scan_result) char scan_result[2048]; // decoded QR text (empty = no QR found) char scan_error[256]; // error message if open/capture fails} ACCamera;
// Enumerate capture-capable V4L2 devices (/dev/video0-9, skipping UVC// metadata nodes). Fills paths[] in device order (built-in first, USB cams// after — they enumerate above it). Returns the count.int camera_list(char paths[][16], int max);
// Open a specific V4L2 device by path ("/dev/video0", ...).// Returns 0 on success, -1 on failure (check cam->scan_error)int camera_open_path(ACCamera *cam, const char *devpath);
// Open the default V4L2 camera: the highest-numbered capture device, so a// freshly plugged USB cam wins over the built-in. (QR scan uses this; the// cap stream thread enumerates with camera_list and picks its own.)// Returns 0 on success, -1 on failure (check cam->scan_error)int camera_open(ACCamera *cam);
// Close camera and free resources (safe to reopen afterwards)void camera_close(ACCamera *cam);
// Grab one frame into the gray + display buffers.// Returns 0 on success, -1 if no frame is ready yet (EAGAIN),// -2 on a fatal device error (unplugged) — close and rescan.int camera_grab(ACCamera *cam);
// Scan the current grayscale frame for QR codes using quirc// Result stored in cam->scan_result (empty string = no QR found)// Returns number of QR codes detectedint camera_scan_qr(ACCamera *cam);
#endif