diff --git a/c_mpos/src/webcam.c b/c_mpos/src/webcam.c index 8f84fdcb..afa8af44 100644 --- a/c_mpos/src/webcam.c +++ b/c_mpos/src/webcam.c @@ -108,10 +108,11 @@ static void save_raw_rgb565(const char *filename, uint16_t *data, int width, int } static int init_webcam(webcam_obj_t *self, const char *device) { + //WEBCAM_DEBUG_PRINT("webcam.c: init_webcam\n"); self->fd = open(device, O_RDWR); if (self->fd < 0) { WEBCAM_DEBUG_PRINT("Cannot open device: %s\n", strerror(errno)); - return -1; + return -errno; } struct v4l2_format fmt = {0}; @@ -123,7 +124,7 @@ static int init_webcam(webcam_obj_t *self, const char *device) { if (ioctl(self->fd, VIDIOC_S_FMT, &fmt) < 0) { WEBCAM_DEBUG_PRINT("Cannot set format: %s\n", strerror(errno)); close(self->fd); - return -1; + return -errno; } struct v4l2_requestbuffers req = {0}; @@ -133,7 +134,7 @@ static int init_webcam(webcam_obj_t *self, const char *device) { if (ioctl(self->fd, VIDIOC_REQBUFS, &req) < 0) { WEBCAM_DEBUG_PRINT("Cannot request buffers: %s\n", strerror(errno)); close(self->fd); - return -1; + return -errno; } for (int i = 0; i < NUM_BUFFERS; i++) { @@ -144,14 +145,14 @@ static int init_webcam(webcam_obj_t *self, const char *device) { if (ioctl(self->fd, VIDIOC_QUERYBUF, &buf) < 0) { WEBCAM_DEBUG_PRINT("Cannot query buffer: %s\n", strerror(errno)); close(self->fd); - return -1; + return -errno; } self->buffer_length = buf.length; self->buffers[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, self->fd, buf.m.offset); if (self->buffers[i] == MAP_FAILED) { WEBCAM_DEBUG_PRINT("Cannot map buffer: %s\n", strerror(errno)); close(self->fd); - return -1; + return -errno; } } @@ -162,14 +163,14 @@ static int init_webcam(webcam_obj_t *self, const char *device) { buf.index = i; if (ioctl(self->fd, VIDIOC_QBUF, &buf) < 0) { WEBCAM_DEBUG_PRINT("Cannot queue buffer: %s\n", strerror(errno)); - return -1; + return -errno; } } enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(self->fd, VIDIOC_STREAMON, &type) < 0) { WEBCAM_DEBUG_PRINT("Cannot start streaming: %s\n", strerror(errno)); - return -1; + return -errno; } self->frame_count = 0; @@ -180,7 +181,7 @@ static int init_webcam(webcam_obj_t *self, const char *device) { free(self->gray_buffer); free(self->rgb565_buffer); close(self->fd); - return -1; + return -errno; } return 0; } @@ -215,12 +216,14 @@ static mp_obj_t free_buffer(webcam_obj_t *self) { } static mp_obj_t capture_frame(mp_obj_t self_in, mp_obj_t format) { + int res = 0; webcam_obj_t *self = MP_OBJ_TO_PTR(self_in); struct v4l2_buffer buf = {0}; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; - if (ioctl(self->fd, VIDIOC_DQBUF, &buf) < 0) { - mp_raise_OSError(MP_EIO); + res = ioctl(self->fd, VIDIOC_DQBUF, &buf); + if (res < 0) { + mp_raise_OSError(-res); } if (!self->gray_buffer) { @@ -243,8 +246,9 @@ static mp_obj_t capture_frame(mp_obj_t self_in, mp_obj_t format) { // snprintf(filename, sizeof(filename), "frame_%03d.raw", self->frame_count++); // save_raw(filename, self->gray_buffer, OUTPUT_WIDTH, OUTPUT_HEIGHT); mp_obj_t result = mp_obj_new_memoryview('B', OUTPUT_WIDTH * OUTPUT_HEIGHT, self->gray_buffer); - if (ioctl(self->fd, VIDIOC_QBUF, &buf) < 0) { - mp_raise_OSError(MP_EIO); + res = ioctl(self->fd, VIDIOC_QBUF, &buf); + if (res < 0) { + mp_raise_OSError(-res); } return result; } else { @@ -253,8 +257,9 @@ static mp_obj_t capture_frame(mp_obj_t self_in, mp_obj_t format) { // snprintf(filename, sizeof(filename), "frame_%03d.rgb565", self->frame_count++); // save_raw_rgb565(filename, self->rgb565_buffer, OUTPUT_WIDTH, OUTPUT_HEIGHT); mp_obj_t result = mp_obj_new_memoryview('H', OUTPUT_WIDTH * OUTPUT_HEIGHT, self->rgb565_buffer); - if (ioctl(self->fd, VIDIOC_QBUF, &buf) < 0) { - mp_raise_OSError(MP_EIO); + res = ioctl(self->fd, VIDIOC_QBUF, &buf); + if (res < 0) { + mp_raise_OSError(-res); } return result; } @@ -273,8 +278,9 @@ static mp_obj_t webcam_init(size_t n_args, const mp_obj_t *args) { self->gray_buffer = NULL; self->rgb565_buffer = NULL; - if (init_webcam(self, device) < 0) { - mp_raise_OSError(MP_EIO); + int res = init_webcam(self, device); + if (res < 0) { + mp_raise_OSError(-res); } return MP_OBJ_FROM_PTR(self); diff --git a/internal_filesystem/apps/com.example.camtest/assets/camtest.py b/internal_filesystem/apps/com.example.camtest/assets/camtest.py index 334d0608..2f216af7 100644 --- a/internal_filesystem/apps/com.example.camtest/assets/camtest.py +++ b/internal_filesystem/apps/com.example.camtest/assets/camtest.py @@ -7,9 +7,6 @@ import time -appscreen = lv.screen_active() -th.disable() - keepgoing = True keepliveqrdecoding = False width = 240 @@ -20,7 +17,11 @@ current_cam_buffer = None image_dsc = None image = None qr_label = None +status_label = None use_webcam = False +qr_button = None +snap_button = None + memview = None @@ -121,7 +122,7 @@ def try_capture(): def build_ui(): - global image, image_dsc,qr_label, cam + global image, image_dsc,qr_label, status_label, cam, use_webcam, qr_button, snap_button cont = lv.obj(appscreen) cont.set_style_pad_all(0, 0) cont.set_style_border_width(0, 0) @@ -137,12 +138,14 @@ def build_ui(): snap_button = lv.button(cont) snap_button.set_size(60, 60) snap_button.align(lv.ALIGN.RIGHT_MID, 0, 0) + snap_button.add_flag(lv.obj.FLAG.HIDDEN) snap_label = lv.label(snap_button) snap_label.set_text(lv.SYMBOL.OK) - snap_label.center() - snap_button.add_event_cb(snap_button_click,lv.EVENT.CLICKED,None) + snap_label.center() + snap_button.add_event_cb(snap_button_click,lv.EVENT.CLICKED,None) qr_button = lv.button(cont) qr_button.set_size(60, 60) + qr_button.add_flag(lv.obj.FLAG.HIDDEN) qr_button.align(lv.ALIGN.BOTTOM_RIGHT, 0, 0) qr_label = lv.label(qr_button) qr_label.set_text(lv.SYMBOL.EYE_OPEN) @@ -151,8 +154,6 @@ def build_ui(): # Initialize LVGL image widget image = lv.image(cont) image.align(lv.ALIGN.LEFT_MID, 0, 0) - if not use_webcam: - image.set_rotation(900) # Create image descriptor once image_dsc = lv.image_dsc_t({ "header": { @@ -167,6 +168,9 @@ def build_ui(): 'data': None # Will be updated per frame }) image.set_src(image_dsc) + status_label = lv.label(appscreen) + status_label.set_text("No camera found.") + status_label.center() def init_cam(): @@ -201,11 +205,13 @@ def init_cam(): - - +appscreen = lv.screen_active() +build_ui() cam = init_cam() -if not cam: +if cam: + image.set_rotation(900) +else: print("camtest.py: no internal camera found, trying webcam on /dev/video0") try: import webcam @@ -215,23 +221,28 @@ if not cam: print(f"camtest.py: webcam exception: {e}") if cam: - build_ui() - count=0 - while appscreen == lv.screen_active() and keepgoing is True: + status_label.set_text("") + qr_button.remove_flag(lv.obj.FLAG.HIDDEN) + snap_button.remove_flag(lv.obj.FLAG.HIDDEN) + +# Task handler needs to be updated from this app's thread, otherwise it causes concurrency issues +th.disable() + +while appscreen == lv.screen_active() and keepgoing is True: + if cam: try_capture() - # Task handler needs to be updated from the same thread, otherwise it causes concurrency issues: - lv.task_handler() - time.sleep_ms(1) - lv.tick_inc(1) - print("camtest.py: stopping...") - if use_webcam: - webcam.deinit(cam) # Deinitializes webcam - else: - cam.deinit() -else: - print("No camera found, exiting...") + lv.task_handler() + time.sleep_ms(5) + lv.tick_inc(5) -th.enable() +print("camtest.py: stopping...") + +if use_webcam: + webcam.deinit(cam) +elif cam: + cam.deinit() + + +print("camtest.py: showing launcher...") show_launcher() - - +th.enable()