|
23 | 23 | #define CAPTURE_HEIGHT 480 |
24 | 24 | #define OUTPUT_WIDTH 240 // Resize to 240x240 |
25 | 25 | #define OUTPUT_HEIGHT 240 |
26 | | -#define NUM_BUFFERS 2 // Keep 2 buffers, stable for continuous captures |
| 26 | +#define NUM_BUFFERS 2 // Revert to 2 buffers, as it achieved 2 captures |
| 27 | +#define QUEUE_RETRIES 10 // Increase retries for robustness |
| 28 | +#define QUEUE_RETRY_DELAY_US 200000 // 200ms delay between retries |
27 | 29 |
|
28 | 30 | // Webcam object type |
29 | 31 | typedef struct _webcam_obj_t { |
@@ -96,28 +98,34 @@ static void webcam_reset_streaming(webcam_obj_t *self) { |
96 | 98 | static mp_obj_t webcam_capture_grayscale(mp_obj_t self_in) { |
97 | 99 | webcam_obj_t *self = MP_OBJ_TO_PTR(self_in); |
98 | 100 |
|
99 | | - // Try to queue a buffer |
| 101 | + // Try to queue a buffer with retries |
100 | 102 | struct v4l2_buffer buf = {0}; |
101 | 103 | bool queued = false; |
102 | | - for (size_t i = 0; i < self->num_buffers; i++) { |
103 | | - memset(&buf, 0, sizeof(buf)); |
104 | | - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
105 | | - buf.memory = V4L2_MEMORY_MMAP; |
106 | | - buf.index = i; |
| 104 | + for (int attempt = 0; attempt < QUEUE_RETRIES && !queued; attempt++) { |
| 105 | + for (size_t i = 0; i < self->num_buffers; i++) { |
| 106 | + memset(&buf, 0, sizeof(buf)); |
| 107 | + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
| 108 | + buf.memory = V4L2_MEMORY_MMAP; |
| 109 | + buf.index = i; |
107 | 110 |
|
108 | | - WEBCAM_DEBUG_PRINT("webcam: Attempting to queue buffer (index=%zu)\n", i); |
109 | | - if (ioctl(self->fd, VIDIOC_QBUF, &buf) == 0) { |
110 | | - WEBCAM_DEBUG_PRINT("webcam: Successfully queued buffer (index=%zu)\n", i); |
111 | | - queued = true; |
112 | | - break; |
| 111 | + WEBCAM_DEBUG_PRINT("webcam: Attempting to queue buffer (index=%zu, attempt=%d)\n", i, attempt + 1); |
| 112 | + if (ioctl(self->fd, VIDIOC_QBUF, &buf) == 0) { |
| 113 | + WEBCAM_DEBUG_PRINT("webcam: Successfully queued buffer (index=%zu)\n", i); |
| 114 | + queued = true; |
| 115 | + break; |
| 116 | + } |
| 117 | + WEBCAM_DEBUG_PRINT("webcam: Failed to queue buffer (index=%zu, errno=%d)\n", i, errno); |
| 118 | + } |
| 119 | + if (!queued && attempt < QUEUE_RETRIES - 1) { |
| 120 | + WEBCAM_DEBUG_PRINT("webcam: No buffers available, retrying after delay\n"); |
| 121 | + usleep(QUEUE_RETRY_DELAY_US); // Wait 200ms |
113 | 122 | } |
114 | | - WEBCAM_DEBUG_PRINT("webcam: Failed to queue buffer (index=%zu, errno=%d)\n", i, errno); |
115 | 123 | } |
116 | 124 |
|
117 | 125 | if (!queued) { |
118 | | - WEBCAM_DEBUG_PRINT("webcam: No buffers available, resetting streaming\n"); |
| 126 | + WEBCAM_DEBUG_PRINT("webcam: No buffers available after %d retries, resetting streaming\n", QUEUE_RETRIES); |
119 | 127 | webcam_reset_streaming(self); |
120 | | - // Try queuing again after reset |
| 128 | + // Retry queuing one more time after reset |
121 | 129 | for (size_t i = 0; i < self->num_buffers; i++) { |
122 | 130 | memset(&buf, 0, sizeof(buf)); |
123 | 131 | buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
|
0 commit comments