Skip to content

Commit 98202c8

Browse files
committed
Allow changing camera settings that require reinit
These can only be changed in a group, though any items to keep unchanged can be unspecified or specified as None.
1 parent 428fbcd commit 98202c8

File tree

3 files changed

+147
-30
lines changed

3 files changed

+147
-30
lines changed

ports/espressif/bindings/esp32_camera/Camera.c

Lines changed: 93 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777
//| :param pixel_format: The pixel format of the captured image
7878
//| :param frame_size: The size of captured image
7979
//| :param jpeg_quality: For `PixelFormat.JPEG`, the quality. Higher numbers increase quality. If the quality is too high, the JPEG data will be larger than the availalble buffer size and the image will be unusable or truncated. The exact range of appropriate values depends on the sensor and must be determined empirically.
80-
//| :param framebuffer_count: The number of framebuffers
80+
//| :param framebuffer_count: The number of framebuffers (1 for single-buffered and 2 for double-buffered)
8181
//| :param grab_mode: When to grab a new frame
8282
//| """
8383
//|
@@ -175,16 +175,17 @@ STATIC void check_for_deinit(esp32_camera_camera_obj_t *self) {
175175
//|
176176
STATIC mp_obj_t esp32_camera_camera_obj___exit__(size_t n_args, const mp_obj_t *args) {
177177
(void)n_args;
178-
common_hal_esp32_camera_camera_deinit(args[0]);
179-
return mp_const_none;
178+
return esp32_camera_camera_deinit(args[0]);
180179
}
181180
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp32_camera_camera___exit___obj, 4, 4, esp32_camera_camera_obj___exit__);
182181

183182
//| frame_available: bool
184183
//| """True if a frame is available, False otherwise"""
185184

186185
STATIC mp_obj_t esp32_camera_camera_frame_available_get(const mp_obj_t self_in) {
187-
return mp_obj_new_bool(false);
186+
esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in);
187+
check_for_deinit(self);
188+
return mp_obj_new_bool(esp_camera_fb_available());
188189
}
189190
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_frame_available_get_obj, esp32_camera_camera_frame_available_get);
190191

@@ -215,14 +216,66 @@ STATIC mp_obj_t esp32_camera_camera_take(size_t n_args, const mp_obj_t *args) {
215216
int height = common_hal_esp32_camera_camera_get_height(self);
216217
displayio_bitmap_t *bitmap = m_new_obj(displayio_bitmap_t);
217218
bitmap->base.type = &displayio_bitmap_type;
218-
mp_printf(&mp_plat_print, "construct bitmap %dx%d @%p\n", width, height, result->buf);
219219
common_hal_displayio_bitmap_construct_from_buffer(bitmap, width, height, (format == PIXFORMAT_RGB565) ? 16 : 8, (uint32_t *)(void *)result->buf, true);
220220
return bitmap;
221221
}
222222
}
223223
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp32_camera_camera_take_obj, 1, 2, esp32_camera_camera_take);
224224

225225

226+
//| def reconfigure(
227+
//| self,
228+
//| frame_size: Optional[FrameSize] = None,
229+
//| pixel_format: Optional[PixelFormat] = None,
230+
//| grab_mode: Optional[GrabMode] = None,
231+
//| framebuffer_count: Optional[int] = None,
232+
//| ) -> None:
233+
//| """Set the frame size and pixel format
234+
//|
235+
//| Because these settings interact in complex ways, and take longer than
236+
//| the other properties to set, they are set together in a single function call.
237+
//|
238+
//| If an argument is unspecified or None, then the setting is unchanged."""
239+
//|
240+
241+
STATIC mp_obj_t esp32_camera_camera_reconfigure(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
242+
esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
243+
check_for_deinit(self);
244+
245+
enum { ARG_frame_size, ARG_pixel_format, ARG_grab_mode, ARG_framebuffer_count };
246+
static const mp_arg_t allowed_args[] = {
247+
{ MP_QSTR_frame_size, MP_ARG_OBJ, {.u_obj = MP_ROM_NONE} },
248+
{ MP_QSTR_pixel_format, MP_ARG_OBJ, {.u_obj = MP_ROM_NONE} },
249+
{ MP_QSTR_grab_mode, MP_ARG_OBJ, {.u_obj = MP_ROM_NONE} },
250+
{ MP_QSTR_framebuffer_count, MP_ARG_OBJ, {.u_obj = MP_ROM_NONE} },
251+
};
252+
253+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
254+
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
255+
256+
framesize_t frame_size =
257+
args[ARG_frame_size].u_obj != MP_ROM_NONE
258+
? validate_frame_size(args[ARG_frame_size].u_obj, MP_QSTR_frame_size)
259+
: common_hal_esp32_camera_camera_get_frame_size(self);
260+
pixformat_t pixel_format =
261+
args[ARG_pixel_format].u_obj != MP_ROM_NONE
262+
? validate_pixel_format(args[ARG_pixel_format].u_obj, MP_QSTR_pixel_format)
263+
: common_hal_esp32_camera_camera_get_pixel_format(self);
264+
camera_grab_mode_t grab_mode =
265+
args[ARG_grab_mode].u_obj != MP_ROM_NONE
266+
? validate_grab_mode(args[ARG_grab_mode].u_obj, MP_QSTR_grab_mode)
267+
: common_hal_esp32_camera_camera_get_grab_mode(self);
268+
bool framebuffer_count =
269+
args[ARG_framebuffer_count].u_obj != MP_ROM_NONE
270+
? mp_obj_get_int(args[ARG_framebuffer_count].u_obj)
271+
: common_hal_esp32_camera_camera_get_framebuffer_count(self);
272+
273+
common_hal_esp32_camera_camera_reconfigure(self, frame_size, pixel_format, grab_mode, framebuffer_count);
274+
275+
return mp_const_none;
276+
}
277+
MP_DEFINE_CONST_FUN_OBJ_KW(esp32_camera_camera_reconfigure_obj, 1, esp32_camera_camera_reconfigure);
278+
226279
//| pixel_format: PixelFormat
227280
//| """The pixel format of captured frames"""
228281

@@ -233,16 +286,8 @@ STATIC mp_obj_t esp32_camera_camera_get_pixel_format(const mp_obj_t self_in) {
233286
}
234287
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_pixel_format_obj, esp32_camera_camera_get_pixel_format);
235288

236-
STATIC mp_obj_t esp32_camera_camera_set_pixel_format(const mp_obj_t self_in, const mp_obj_t arg) {
237-
esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in);
238-
check_for_deinit(self);
239-
common_hal_esp32_camera_camera_set_pixel_format(self, validate_pixel_format(arg, MP_QSTR_pixel_format));
240-
return mp_const_none;
241-
}
242-
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_pixel_format_obj, esp32_camera_camera_set_pixel_format);
243-
MP_PROPERTY_GETSET(esp32_camera_camera_pixel_format_obj,
244-
(mp_obj_t)&esp32_camera_camera_get_pixel_format_obj,
245-
(mp_obj_t)&esp32_camera_camera_set_pixel_format_obj);
289+
MP_PROPERTY_GETTER(esp32_camera_camera_pixel_format_obj,
290+
(mp_obj_t)&esp32_camera_camera_get_pixel_format_obj);
246291

247292

248293
//| frame_size: FrameSize
@@ -255,16 +300,8 @@ STATIC mp_obj_t esp32_camera_camera_get_frame_size(const mp_obj_t self_in) {
255300
}
256301
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_frame_size_obj, esp32_camera_camera_get_frame_size);
257302

258-
STATIC mp_obj_t esp32_camera_camera_set_frame_size(const mp_obj_t self_in, const mp_obj_t arg) {
259-
esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in);
260-
check_for_deinit(self);
261-
common_hal_esp32_camera_camera_set_frame_size(self, validate_frame_size(arg, MP_QSTR_frame_size));
262-
return mp_const_none;
263-
}
264-
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp32_camera_camera_set_frame_size_obj, esp32_camera_camera_set_frame_size);
265-
MP_PROPERTY_GETSET(esp32_camera_camera_frame_size_obj,
266-
(mp_obj_t)&esp32_camera_camera_get_frame_size_obj,
267-
(mp_obj_t)&esp32_camera_camera_set_frame_size_obj);
303+
MP_PROPERTY_GETTER(esp32_camera_camera_frame_size_obj,
304+
(mp_obj_t)&esp32_camera_camera_get_frame_size_obj);
268305

269306
//| contrast: int
270307
//| """Access the contrast property of the camera sensor"""
@@ -898,6 +935,33 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_width_obj, esp32_camera
898935
MP_PROPERTY_GETTER(esp32_camera_camera_width_obj,
899936
(mp_obj_t)&esp32_camera_camera_get_width_obj);
900937

938+
//| grab_mode: GrabMode
939+
//| """The grab mode of the camera"""
940+
//|
941+
STATIC mp_obj_t esp32_camera_camera_get_grab_mode(const mp_obj_t self_in) {
942+
esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in);
943+
check_for_deinit(self);
944+
return cp_enum_find(&esp32_camera_grab_mode_type, common_hal_esp32_camera_camera_get_grab_mode(self));
945+
}
946+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_grab_mode_obj, esp32_camera_camera_get_grab_mode);
947+
948+
MP_PROPERTY_GETTER(esp32_camera_camera_grab_mode_obj,
949+
(mp_obj_t)&esp32_camera_camera_get_grab_mode_obj);
950+
951+
952+
//| framebuffer_count: int
953+
//| """True if double buffering is used"""
954+
//|
955+
STATIC mp_obj_t esp32_camera_camera_get_framebuffer_count(const mp_obj_t self_in) {
956+
esp32_camera_camera_obj_t *self = MP_OBJ_TO_PTR(self_in);
957+
check_for_deinit(self);
958+
return MP_OBJ_NEW_SMALL_INT(common_hal_esp32_camera_camera_get_framebuffer_count(self));
959+
}
960+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_camera_camera_get_framebuffer_count_obj, esp32_camera_camera_get_framebuffer_count);
961+
962+
MP_PROPERTY_GETTER(esp32_camera_camera_framebuffer_count_obj,
963+
(mp_obj_t)&esp32_camera_camera_get_framebuffer_count_obj);
964+
901965

902966
STATIC const mp_rom_map_elem_t esp32_camera_camera_locals_table[] = {
903967
{ MP_ROM_QSTR(MP_QSTR_address), MP_ROM_PTR(&esp32_camera_camera_address_obj) },
@@ -913,20 +977,23 @@ STATIC const mp_rom_map_elem_t esp32_camera_camera_locals_table[] = {
913977
{ MP_ROM_QSTR(MP_QSTR_dcw), MP_ROM_PTR(&esp32_camera_camera_dcw_obj) },
914978
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&esp32_camera_camera_deinit_obj) },
915979
{ MP_ROM_QSTR(MP_QSTR_denoise), MP_ROM_PTR(&esp32_camera_camera_denoise_obj) },
980+
{ MP_ROM_QSTR(MP_QSTR_framebuffer_count), MP_ROM_PTR(&esp32_camera_camera_framebuffer_count_obj) },
916981
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&mp_identity_obj) },
917982
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&esp32_camera_camera___exit___obj) },
918983
{ MP_ROM_QSTR(MP_QSTR_exposure_ctrl), MP_ROM_PTR(&esp32_camera_camera_exposure_ctrl_obj) },
919984
{ MP_ROM_QSTR(MP_QSTR_frame_available), MP_ROM_PTR(&esp32_camera_camera_frame_available_obj) },
920985
{ MP_ROM_QSTR(MP_QSTR_frame_size), MP_ROM_PTR(&esp32_camera_camera_frame_size_obj) },
921986
{ MP_ROM_QSTR(MP_QSTR_gain_ceiling), MP_ROM_PTR(&esp32_camera_camera_gain_ceiling_obj) },
922987
{ MP_ROM_QSTR(MP_QSTR_gain_ctrl), MP_ROM_PTR(&esp32_camera_camera_gain_ctrl_obj) },
988+
{ MP_ROM_QSTR(MP_QSTR_grab_mode), MP_ROM_PTR(&esp32_camera_camera_grab_mode_obj) },
923989
{ MP_ROM_QSTR(MP_QSTR_height), MP_ROM_PTR(&esp32_camera_camera_height_obj) },
924990
{ MP_ROM_QSTR(MP_QSTR_hmirror), MP_ROM_PTR(&esp32_camera_camera_hmirror_obj) },
925991
{ MP_ROM_QSTR(MP_QSTR_lenc), MP_ROM_PTR(&esp32_camera_camera_lenc_obj) },
926992
{ MP_ROM_QSTR(MP_QSTR_max_frame_size), MP_ROM_PTR(&esp32_camera_camera_max_frame_size_obj) },
927993
{ MP_ROM_QSTR(MP_QSTR_pixel_format), MP_ROM_PTR(&esp32_camera_camera_pixel_format_obj) },
928994
{ MP_ROM_QSTR(MP_QSTR_quality), MP_ROM_PTR(&esp32_camera_camera_quality_obj) },
929995
{ MP_ROM_QSTR(MP_QSTR_raw_gma), MP_ROM_PTR(&esp32_camera_camera_raw_gma_obj) },
996+
{ MP_ROM_QSTR(MP_QSTR_reconfigure), MP_ROM_PTR(&esp32_camera_camera_reconfigure_obj) },
930997
{ MP_ROM_QSTR(MP_QSTR_saturation), MP_ROM_PTR(&esp32_camera_camera_saturation_obj) },
931998
{ MP_ROM_QSTR(MP_QSTR_sensor_name), MP_ROM_PTR(&esp32_camera_camera_sensor_name_obj) },
932999
{ MP_ROM_QSTR(MP_QSTR_sharpness), MP_ROM_PTR(&esp32_camera_camera_sharpness_obj) },
@@ -935,8 +1002,8 @@ STATIC const mp_rom_map_elem_t esp32_camera_camera_locals_table[] = {
9351002
{ MP_ROM_QSTR(MP_QSTR_take), MP_ROM_PTR(&esp32_camera_camera_take_obj) },
9361003
{ MP_ROM_QSTR(MP_QSTR_vflip), MP_ROM_PTR(&esp32_camera_camera_vflip_obj) },
9371004
{ MP_ROM_QSTR(MP_QSTR_wb_mode), MP_ROM_PTR(&esp32_camera_camera_wb_mode_obj) },
938-
{ MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&esp32_camera_camera_width_obj) },
9391005
{ MP_ROM_QSTR(MP_QSTR_whitebal), MP_ROM_PTR(&esp32_camera_camera_whitebal_obj) },
1006+
{ MP_ROM_QSTR(MP_QSTR_width), MP_ROM_PTR(&esp32_camera_camera_width_obj) },
9401007
{ MP_ROM_QSTR(MP_QSTR_wpc), MP_ROM_PTR(&esp32_camera_camera_wpc_obj) },
9411008
};
9421009

ports/espressif/bindings/esp32_camera/Camera.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ extern void common_hal_esp32_camera_camera_deinit(esp32_camera_camera_obj_t *sel
5757
extern bool common_hal_esp32_camera_camera_deinited(esp32_camera_camera_obj_t *self);
5858
extern bool common_hal_esp32_camera_camera_available(esp32_camera_camera_obj_t *self);
5959
extern camera_fb_t *common_hal_esp32_camera_camera_take(esp32_camera_camera_obj_t *self, int timeout_ms);
60+
extern void common_hal_esp32_camera_camera_reconfigure(esp32_camera_camera_obj_t *self, framesize_t frame_size, pixformat_t pixel_format, camera_grab_mode_t grab_mode, mp_int_t framebuffer_count);
6061

6162
#define DECLARE_SENSOR_GETSET(type, name, field_name, setter_function_name) \
6263
DECLARE_SENSOR_GET(type, name, field_name, setter_function_name) \
@@ -65,14 +66,17 @@ extern camera_fb_t *common_hal_esp32_camera_camera_take(esp32_camera_camera_obj_
6566
#define DECLARE_SENSOR_STATUS_GETSET(type, name, status_field_name, setter_function_name) \
6667
DECLARE_SENSOR_GETSET(type, name, status.status_field_name, setter_function_name)
6768

69+
#define DECLARE_SENSOR_STATUS_GET(type, name, status_field_name, setter_function_name) \
70+
DECLARE_SENSOR_GET(type, name, status.status_field_name, setter_function_name)
71+
6872
#define DECLARE_SENSOR_GET(type, name, status_field_name, setter_function_name) \
6973
extern type common_hal_esp32_camera_camera_get_##name(esp32_camera_camera_obj_t * self);
7074

7175
#define DECLARE_SENSOR_SET(type, name, setter_function_name) \
7276
extern void common_hal_esp32_camera_camera_set_##name(esp32_camera_camera_obj_t * self, type value);
7377

74-
DECLARE_SENSOR_GETSET(pixformat_t, pixel_format, pixformat, set_pixformat)
75-
DECLARE_SENSOR_STATUS_GETSET(framesize_t, frame_size, framesize, set_framesize)
78+
DECLARE_SENSOR_GET(pixformat_t, pixel_format, pixformat, set_pixformat)
79+
DECLARE_SENSOR_STATUS_GET(framesize_t, frame_size, framesize, set_framesize)
7680
DECLARE_SENSOR_STATUS_GETSET(int, contrast, contrast, set_contrast);
7781
DECLARE_SENSOR_STATUS_GETSET(int, brightness, brightness, set_brightness);
7882
DECLARE_SENSOR_STATUS_GETSET(int, saturation, saturation, set_saturation);
@@ -99,6 +103,10 @@ DECLARE_SENSOR_STATUS_GETSET(bool, wpc, wpc, set_wpc);
99103
DECLARE_SENSOR_STATUS_GETSET(bool, raw_gma, raw_gma, set_raw_gma);
100104
DECLARE_SENSOR_STATUS_GETSET(bool, lenc, lenc, set_lenc);
101105

106+
// From settings
107+
extern camera_grab_mode_t common_hal_esp32_camera_camera_get_grab_mode(esp32_camera_camera_obj_t *self);
108+
extern int common_hal_esp32_camera_camera_get_framebuffer_count(esp32_camera_camera_obj_t *self);
109+
102110
// From camera_sensor_info_t
103111
extern int common_hal_esp32_camera_camera_get_address(esp32_camera_camera_obj_t *self);
104112
extern const char *common_hal_esp32_camera_camera_get_sensor_name(esp32_camera_camera_obj_t *self);

ports/espressif/common-hal/esp32_camera/Camera.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
#include "shared-bindings/microcontroller/Pin.h"
3333
#include "common-hal/microcontroller/Pin.h"
3434

35+
#include "esp32-camera/driver/private_include/cam_hal.h"
36+
3537
static void maybe_claim_pin(const mcu_pin_obj_t *pin) {
3638
if (pin) {
3739
claim_pin(pin);
@@ -172,8 +174,40 @@ camera_fb_t *common_hal_esp32_camera_camera_take(esp32_camera_camera_obj_t *self
172174
} \
173175
}
174176

175-
SENSOR_GETSET(pixformat_t, pixel_format, pixformat, set_pixformat);
176-
SENSOR_STATUS_GETSET(framesize_t, frame_size, framesize, set_framesize);
177+
pixformat_t common_hal_esp32_camera_camera_get_pixel_format(esp32_camera_camera_obj_t *self) {
178+
return self->camera_config.pixel_format;
179+
}
180+
181+
framesize_t common_hal_esp32_camera_camera_get_frame_size(esp32_camera_camera_obj_t *self) {
182+
return self->camera_config.frame_size;
183+
}
184+
185+
#include "esp_log.h"
186+
187+
void common_hal_esp32_camera_camera_reconfigure(esp32_camera_camera_obj_t *self, framesize_t frame_size, pixformat_t pixel_format, camera_grab_mode_t grab_mode, mp_int_t framebuffer_count) {
188+
sensor_t *sensor = esp_camera_sensor_get();
189+
camera_sensor_info_t *sensor_info = esp_camera_sensor_get_info(&sensor->id);
190+
191+
if (PIXFORMAT_JPEG == pixel_format && (!sensor_info->support_jpeg)) {
192+
raise_esp_error(ESP_ERR_NOT_SUPPORTED);
193+
}
194+
195+
if (frame_size > sensor_info->max_size) {
196+
frame_size = sensor_info->max_size;
197+
}
198+
199+
cam_deinit();
200+
self->camera_config.pixel_format = pixel_format;
201+
self->camera_config.frame_size = frame_size;
202+
self->camera_config.grab_mode = grab_mode;
203+
self->camera_config.fb_count = framebuffer_count;
204+
sensor->set_pixformat(sensor, self->camera_config.pixel_format);
205+
sensor->set_framesize(sensor, self->camera_config.frame_size);
206+
cam_init(&self->camera_config);
207+
cam_config(&self->camera_config, frame_size, sensor_info->pid);
208+
cam_start();
209+
}
210+
177211
SENSOR_STATUS_GETSET(int, contrast, contrast, set_contrast);
178212
SENSOR_STATUS_GETSET(int, brightness, brightness, set_brightness);
179213
SENSOR_STATUS_GETSET(int, saturation, saturation, set_saturation);
@@ -235,3 +269,11 @@ const int common_hal_esp32_camera_camera_get_height(esp32_camera_camera_obj_t *s
235269
framesize_t framesize = sensor->status.framesize;
236270
return resolution[framesize].height;
237271
}
272+
273+
const camera_grab_mode_t common_hal_esp32_camera_camera_get_grab_mode(esp32_camera_camera_obj_t *self) {
274+
return self->camera_config.grab_mode;
275+
}
276+
277+
const int common_hal_esp32_camera_camera_get_framebuffer_count(esp32_camera_camera_obj_t *self) {
278+
return self->camera_config.fb_count;
279+
}

0 commit comments

Comments
 (0)