From 98dad29ea4d1d571d5782f5ee3219b215528456f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esben=20S=C3=B8rig?= Date: Fri, 16 Jan 2026 21:00:36 +0000 Subject: [PATCH 1/2] Camera initialization: extend timeout and add retry mechanism --- builtin-programs/camera/usb.folk | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/builtin-programs/camera/usb.folk b/builtin-programs/camera/usb.folk index ac55989b..08488ae8 100644 --- a/builtin-programs/camera/usb.folk +++ b/builtin-programs/camera/usb.folk @@ -203,17 +203,25 @@ $camc code { } $camc proc cameraFrameJpeg {Camera* camera} CameraBuffer { - struct timeval timeout; - timeout.tv_sec = 1; - timeout.tv_usec = 0; - fd_set fds; - FD_ZERO(&fds); - FD_SET(camera->fd, &fds); - int r = select(camera->fd + 1, &fds, 0, 0, &timeout); - // printf("r: %d\n", r); - if (r == -1) quit("select"); + // Retry select() up to 5 times with 2 second timeout each + // Some cameras need time to start streaming + int r = 0; + for (int attempt = 0; attempt < 5 && r == 0; attempt++) { + struct timeval timeout; + timeout.tv_sec = 2; + timeout.tv_usec = 0; + fd_set fds; + FD_ZERO(&fds); + FD_SET(camera->fd, &fds); + r = select(camera->fd + 1, &fds, 0, 0, &timeout); + if (r == -1) quit("select"); + if (r == 0 && attempt < 4) { + fprintf(stderr, "camera/usb: select timeout on fd %d, retry %d/4\n", + camera->fd, attempt + 1); + } + } if (r == 0) { - FOLK_ERROR("selection failed of fd %d\n", camera->fd); + FOLK_ERROR("selection failed of fd %d after 5 attempts\n", camera->fd); } FOLK_ENSURE(camera_capture(camera) != 0); From 45ecbf79f55358d8a51a2c8e1cb5a4baf6a0a6b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esben=20S=C3=B8rig?= Date: Fri, 16 Jan 2026 21:02:43 +0000 Subject: [PATCH 2/2] image-lib: allow decompression warnings --- builtin-programs/image-lib.folk | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/builtin-programs/image-lib.folk b/builtin-programs/image-lib.folk index b0920d1a..408c3d7c 100644 --- a/builtin-programs/image-lib.folk +++ b/builtin-programs/image-lib.folk @@ -369,8 +369,15 @@ $cc proc jpegDecompressGray {Jpeg jpeg int width int height int uniq} Image { int ret = tjDecompress2(handle, jpeg.start, jpeg.length, dest.data, width, 0, height, TJPF_GRAY, 0); if (ret != 0) { - tjDestroy(handle); - FOLK_ERROR("cameraDecompressGray: Decompression failed: %s\n", tjGetErrorStr()); + // Check if this is just a warning (e.g., "extraneous bytes before marker") + // or a fatal error. Warnings are common with webcam MJPEG streams. + int errCode = tjGetErrorCode(handle); + if (errCode == TJERR_FATAL) { + tjDestroy(handle); + FOLK_ERROR("cameraDecompressGray: Decompression failed: %s\n", tjGetErrorStr()); + } + // For warnings, continue with the (possibly partially corrupted) image + // fprintf(stderr, "cameraDecompressGray: Warning: %s\n", tjGetErrorStr()); } tjDestroy(handle);