21 log_info(
"Test pattern mode enabled - not opening real webcam");
22 log_info(
"Test pattern resolution: 1280x720");
27 log_info(
"Initializing webcam with V4L2 (Linux)");
28 log_info(
"Attempting to open webcam with index %d using V4L2 (Linux)...", webcam_index);
29#elif defined(__APPLE__)
30 log_info(
"Initializing webcam with AVFoundation (macOS)");
31 log_info(
"Attempting to open webcam with index %d using AVFoundation (macOS)...", webcam_index);
33 log_info(
"Initializing webcam with Media Foundation (Windows)");
34 log_info(
"Attempting to open webcam with index %d using Media Foundation (Windows)...", webcam_index);
36 log_info(
"Initializing webcam with Unknown platform");
37 log_info(
"Attempting to open webcam with index %d using Unknown platform...", webcam_index);
42 SET_ERRNO(result,
"Failed to connect to webcam (error code: %d)", result);
49 log_info(
"Webcam opened successfully! Resolution: %dx%d", width, height);
62 static image_t *cached_pattern = NULL;
63 static int frame_counter = 0;
65 if (!cached_pattern) {
68 if (!cached_pattern) {
74 for (
int y = 0; y < cached_pattern->
h; y++) {
75 for (
int x = 0; x < cached_pattern->
w; x++) {
76 rgb_pixel_t *pixel = &cached_pattern->
pixels[y * cached_pattern->
w + x];
129 if (x % 160 == 0 || y % 120 == 0) {
150 (
size_t)cached_pattern->
w * cached_pattern->
h *
sizeof(rgb_pixel_t));
154 for (
int y = 0; y < test_frame->
h; y++) {
155 for (
int x = 0; x < test_frame->
w / 2; x++) {
156 rgb_pixel_t temp = test_frame->
pixels[y * test_frame->
w + x];
157 test_frame->
pixels[y * test_frame->
w + x] = test_frame->
pixels[y * test_frame->
w + (test_frame->
w - 1 - x)];
158 test_frame->
pixels[y * test_frame->
w + (test_frame->
w - 1 - x)] = temp;
166 if (!global_webcam_ctx) {
181 rgb_pixel_t *left = frame->
pixels;
182 rgb_pixel_t *right = frame->
pixels + frame->
w - 1;
184 for (
int y = 0; y < frame->
h; y++) {
185 rgb_pixel_t *row_left = left;
186 rgb_pixel_t *row_right = right;
189 for (
int x = 0; x < frame->
w / 2; x++) {
190 rgb_pixel_t temp = *row_left;
191 *row_left++ = *row_right;
206 log_info(
"Test pattern mode - no webcam resources to release");
210 if (global_webcam_ctx) {
212 global_webcam_ctx = NULL;
215 log_info(
"Webcam was not opened, nothing to release");
224 if (global_webcam_ctx) {
235 safe_fprintf(stderr,
"Webcam initialization failed on Linux.\n\n");
237 safe_fprintf(stderr,
" 1. Check if a camera is connected:\n");
239 safe_fprintf(stderr,
" 2. If no camera is available, use test pattern mode:\n");
240 safe_fprintf(stderr,
" ascii-chat client --test-pattern\n\n");
241 safe_fprintf(stderr,
" 3. Install V4L2 drivers if needed:\n");
242 safe_fprintf(stderr,
" sudo apt-get install v4l-utils\n");
246 safe_fprintf(stderr,
" sudo usermod -a -G video $USER\n");
247 safe_fprintf(stderr,
"Then log out and log back in for changes to take effect.\n");
249 safe_fprintf(stderr,
"Camera is already in use by another application.\n\n");
250 safe_fprintf(stderr,
"Try closing other camera apps or use test pattern mode:\n");
251 safe_fprintf(stderr,
" ascii-chat client --test-pattern\n");
255 safe_fprintf(stderr,
"* Check camera: ls /dev/video*\n");
256 safe_fprintf(stderr,
"* Check permissions: groups | grep video\n");
257 safe_fprintf(stderr,
"* Use test pattern: ascii-chat client --test-pattern\n");
259 (void)fflush(stderr);
260#elif defined(__APPLE__)
263 safe_fprintf(stderr,
"On macOS, you may need to grant camera permissions:\n");
265 "* Say \"yes\" to the popup about system camera access that you see when running this program for the "
268 stderr,
"* If you said \"no\" to the popup, go to System Preferences > Security & Privacy > Privacy > Camera.\n");
270 " Now flip the switch next to your terminal application in that privacy list to allow ascii-chat to "
271 "access your camera.\n");
272 safe_fprintf(stderr,
" Then just run this program again.\n");
273 (void)fflush(stderr);
278 safe_fprintf(stderr,
"Webcam is already in use by another application.\n");
279 safe_fprintf(stderr,
"Windows allows only one application to access the webcam at a time.\n");
281 safe_fprintf(stderr,
"To use ascii-chat with multiple clients, try these alternatives:\n");
282 safe_fprintf(stderr,
" --test-pattern Generate a colorful test pattern instead of using webcam\n");
283 safe_fprintf(stderr,
" --file VIDEO.mp4 Use a video file as input (to be implemented)\n");
285 safe_fprintf(stderr,
"Example: ascii-chat client --test-pattern\n");
286 (void)fflush(stderr);
290 safe_fprintf(stderr,
"On Windows, this might be because:\n");
291 safe_fprintf(stderr,
"* Camera permissions are not granted\n");
294 (void)fflush(stderr);
299 safe_fprintf(stderr,
"\nWebcam initialization failed on unsupported platform.\n");
300 (void)fflush(stderr);
305#if !defined(__linux__) && !defined(__APPLE__) && !defined(_WIN32)
315 log_warn(
"Webcam cleanup called on unsupported platform");
asciichat_error_t error_code
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it.
asciichat_error_t
Error and exit codes - unified status values (0-255)
@ ERROR_WEBCAM_PERMISSION
#define log_warn(...)
Log a WARN message.
#define log_info(...)
Log an INFO message.
#define GET_OPTION(field)
Safely get a specific option field (lock-free read)
image_t * image_new(size_t width, size_t height)
Create a new image with standard allocation.
asciichat_error_t webcam_init_context(webcam_context_t **ctx, unsigned short int device_index)
Initialize webcam context for advanced operations.
asciichat_error_t webcam_list_devices(webcam_device_info_t **out_devices, unsigned int *out_count)
Enumerate available webcam devices.
void webcam_free_device_list(webcam_device_info_t *devices)
Free device list returned by webcam_list_devices()
asciichat_error_t webcam_init(unsigned short int webcam_index)
Initialize global webcam interface.
void webcam_flush_context(webcam_context_t *ctx)
Flush/interrupt pending read operations on webcam context.
image_t * webcam_read(void)
Capture a frame from global webcam.
void webcam_print_init_error_help(asciichat_error_t error_code)
Print helpful error diagnostics for webcam initialization failures.
void webcam_flush(void)
Flush/interrupt any pending webcam read operations.
struct webcam_context_t webcam_context_t
Opaque webcam context structure.
asciichat_error_t webcam_get_dimensions(webcam_context_t *ctx, int *width, int *height)
Get webcam frame dimensions.
void webcam_cleanup(void)
Clean up global webcam interface.
image_t * webcam_read_context(webcam_context_t *ctx)
Capture a frame from webcam context.
void webcam_cleanup_context(webcam_context_t *ctx)
Clean up webcam context and release resources.
⚙️ Command-line options parsing and configuration management for ascii-chat
int w
Image width in pixels (must be > 0)
int h
Image height in pixels (must be > 0)
rgb_pixel_t * pixels
Pixel data array (width * height RGB pixels, row-major order)
Webcam device information structure.
Image Data Structures and Operations.