Skip to content

Commit ef06b58

Browse files
Camera app: more resolutions, less memory use
1 parent e8665d0 commit ef06b58

File tree

2 files changed

+49
-16
lines changed

2 files changed

+49
-16
lines changed

c_mpos/src/quirc_decode.c

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,33 @@ static mp_obj_t qrdecode_rgb565(mp_uint_t n_args, const mp_obj_t *args) {
151151
free(gray_buffer);
152152
} else {
153153
QRDECODE_DEBUG_PRINT("qrdecode_rgb565: Exception caught, freeing gray_buffer\n");
154-
free(gray_buffer);
154+
// Cleanup
155+
if (gray_buffer) {
156+
free(gray_buffer);
157+
gray_buffer = NULL;
158+
}
159+
//mp_raise_TypeError(MP_ERROR_TEXT("qrdecode_rgb565: failed to decode QR code"));
155160
// Re-raising the exception results in an Unhandled exception in thread started by <function qrdecode_live at 0x7f6f55af0680>
156161
// which isn't caught, even when catching Exception, so this looks like a bug in MicroPython...
157-
//nlr_pop();
158-
//nlr_raise(exception_handler.ret_val);
162+
nlr_pop();
163+
nlr_raise(exception_handler.ret_val);
164+
// Re-raise the original exception with optional additional message
165+
/*
166+
mp_raise_msg_and_obj(
167+
mp_obj_exception_get_type(exception_handler.ret_val),
168+
MP_OBJ_NEW_QSTR(qstr_from_str("qrdecode_rgb565: failed during processing")),
169+
exception_handler.ret_val
170+
);
171+
*/
172+
// Re-raise as new exception of same type, with message + original as arg
173+
// (embeds original for traceback chaining)
174+
// crashes:
175+
//const mp_obj_type_t *exc_type = mp_obj_get_type(exception_handler.ret_val);
176+
//mp_raise_msg_varg(exc_type, MP_ERROR_TEXT("qrdecode_rgb565: failed during processing: %q"), exception_handler.ret_val);
159177
}
160178

179+
//nlr_pop(); maybe it needs to be done after instead of before the re-raise?
180+
161181
return result;
162182
}
163183

internal_filesystem/apps/com.micropythonos.camera/assets/camera_app.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ def qrdecode_one(self):
227227
import qrdecode
228228
import utime
229229
before = utime.ticks_ms()
230-
result = qrdecode.qrdecode_rgb565(self.current_cam_buffer_copy, self.width, self.height)
230+
result = qrdecode.qrdecode_rgb565(self.current_cam_buffer, self.width, self.height)
231231
after = utime.ticks_ms()
232232
#result = bytearray("INSERT_QR_HERE", "utf-8")
233233
if not result:
@@ -263,12 +263,12 @@ def snap_button_click(self, e):
263263
os.mkdir("data/images")
264264
except OSError:
265265
pass
266-
if self.current_cam_buffer_copy is not None:
266+
if self.current_cam_buffer is not None:
267267
filename=f"data/images/camera_capture_{mpos.time.epoch_seconds()}_{self.width}x{self.height}_RGB565.raw"
268268
try:
269269
with open(filename, 'wb') as f:
270-
f.write(self.current_cam_buffer_copy)
271-
print(f"Successfully wrote current_cam_buffer_copy to {filename}")
270+
f.write(self.current_cam_buffer)
271+
print(f"Successfully wrote current_cam_buffer to {filename}")
272272
except OSError as e:
273273
print(f"Error writing to file: {e}")
274274

@@ -382,25 +382,30 @@ def try_capture(self, event):
382382
try:
383383
if self.use_webcam:
384384
self.current_cam_buffer = webcam.capture_frame(self.cam, "rgb565")
385-
self.current_cam_buffer_copy = bytes(self.current_cam_buffer)
385+
#self.current_cam_buffer_copy = bytes(self.current_cam_buffer)
386386
elif self.cam.frame_available():
387+
self.cam.free_buffer()
387388
self.current_cam_buffer = self.cam.capture()
388-
self.current_cam_buffer_copy = bytes(self.current_cam_buffer)
389+
#self.current_cam_buffer_copy = bytes(self.current_cam_buffer)
389390
self.cam.free_buffer()
390391

391-
if self.current_cam_buffer_copy and len(self.current_cam_buffer_copy):
392+
if self.current_cam_buffer and len(self.current_cam_buffer):
392393
# Defensive check: verify buffer size matches expected dimensions
393394
expected_size = self.width * self.height * 2 # RGB565 = 2 bytes per pixel
394-
actual_size = len(self.current_cam_buffer_copy)
395+
actual_size = len(self.current_cam_buffer)
395396

396397
if actual_size == expected_size:
397-
self.image_dsc.data = self.current_cam_buffer_copy
398+
#self.image_dsc.data = self.current_cam_buffer_copy
399+
self.image_dsc.data = self.current_cam_buffer
398400
#image.invalidate() # does not work so do this:
399401
self.image.set_src(self.image_dsc)
400402
if not self.use_webcam:
401403
self.cam.free_buffer() # Free the old buffer
402-
if self.keepliveqrdecoding:
403-
self.qrdecode_one()
404+
try:
405+
if self.keepliveqrdecoding:
406+
self.qrdecode_one()
407+
except Exception as qre:
408+
print(f"try_capture: qrdecode_one got exception: {qre}")
404409
else:
405410
print(f"Warning: Buffer size mismatch! Expected {expected_size} bytes, got {actual_size} bytes")
406411
print(f" Resolution: {self.width}x{self.height}, discarding frame")
@@ -433,8 +438,12 @@ def init_internal_cam(width, height):
433438
(480, 480): FrameSize.R480X480,
434439
(640, 480): FrameSize.VGA,
435440
(640, 640): FrameSize.R640X640,
441+
(720, 720): FrameSize.R720X720,
436442
(800, 600): FrameSize.SVGA,
443+
(800, 800): FrameSize.R800X800,
444+
(960, 960): FrameSize.R960X960,
437445
(1024, 768): FrameSize.XGA,
446+
(1024,1024): FrameSize.R1024X1024,
438447
(1280, 720): FrameSize.HD,
439448
(1280, 1024): FrameSize.SXGA,
440449
(1600, 1200): FrameSize.UXGA,
@@ -660,9 +669,13 @@ class CameraSettingsActivity(Activity):
660669
("480x480", "480x480"),
661670
("640x480", "640x480"),
662671
("640x640", "640x640"),
672+
("720x720", "720x720"),
663673
("800x600", "800x600"),
664-
("1024x768", "1024x768"),
665-
("1280x720", "1280x720"), # binned 2x2
674+
("800x800", "800x800"),
675+
("960x960", "960x960"),
676+
("1024x768", "1024x768"),
677+
("1024x1024","1024x1024"),
678+
("1280x720", "1280x720"), # binned 2x2 (in default ov5640.c)
666679
("1280x1024", "1280x1024"),
667680
("1600x1200", "1600x1200"),
668681
("1920x1080", "1920x1080"),

0 commit comments

Comments
 (0)