Skip to content

Commit c2fc592

Browse files
committed
camera: Change API
1 parent 143a1ff commit c2fc592

File tree

10 files changed

+242
-331
lines changed

10 files changed

+242
-331
lines changed

ports/cxd56/common-hal/camera/Camera.c

Lines changed: 62 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -35,49 +35,43 @@
3535

3636
#include "shared-bindings/camera/Camera.h"
3737

38-
#define JPG_COMPRESS_RATIO (9)
39-
#define SPRESENSE_CAMIMAGE_MEM_ALIGN (32)
40-
4138
typedef struct {
4239
const char* devpath;
4340
int fd;
4441
} camera_dev_t;
4542

4643
STATIC camera_dev_t camera_dev = {"/dev/video", -1};
4744

48-
static void camera_size_to_width_and_height(camera_imagesize_t size, uint16_t *width, uint16_t *height) {
49-
switch (size) {
50-
case IMAGESIZE_320x240:
51-
*height = VIDEO_VSIZE_QVGA;
52-
*width = VIDEO_HSIZE_QVGA;
53-
break;
54-
case IMAGESIZE_640x320:
55-
*height = VIDEO_VSIZE_VGA;
56-
*width = VIDEO_HSIZE_VGA;
57-
break;
58-
case IMAGESIZE_1280x720:
59-
*height = VIDEO_VSIZE_HD;
60-
*width = VIDEO_HSIZE_HD;
61-
break;
62-
case IMAGESIZE_1280x960:
63-
*height = VIDEO_VSIZE_QUADVGA;
64-
*width = VIDEO_HSIZE_QUADVGA;
65-
break;
66-
case IMAGESIZE_1920x1080:
67-
*height = VIDEO_VSIZE_FULLHD;
68-
*width = VIDEO_HSIZE_FULLHD;
69-
break;
70-
case IMAGESIZE_2048x1536:
71-
*height = VIDEO_VSIZE_3M;
72-
*width = VIDEO_HSIZE_3M;
73-
break;
74-
case IMAGESIZE_2560x1920:
75-
*height = VIDEO_VSIZE_5M;
76-
*width = VIDEO_HSIZE_5M;
77-
break;
78-
default:
79-
mp_raise_ValueError(translate("Size not supported"));
80-
break;
45+
static bool camera_check_width_and_height(uint16_t width, uint16_t height) {
46+
if ((width == VIDEO_HSIZE_QVGA && height == VIDEO_VSIZE_QVGA) ||
47+
(width == VIDEO_HSIZE_VGA && height == VIDEO_VSIZE_VGA) ||
48+
(width == VIDEO_HSIZE_HD && height == VIDEO_VSIZE_HD) ||
49+
(width == VIDEO_HSIZE_QUADVGA && height == VIDEO_VSIZE_QUADVGA) ||
50+
(width == VIDEO_HSIZE_FULLHD && height == VIDEO_VSIZE_FULLHD) ||
51+
(width == VIDEO_HSIZE_3M && height == VIDEO_VSIZE_3M) ||
52+
(width == VIDEO_HSIZE_5M && height == VIDEO_VSIZE_5M)) {
53+
return true;
54+
} else {
55+
return false;
56+
}
57+
}
58+
59+
static bool camera_check_buffer_length(uint16_t width, uint16_t height, camera_imageformat_t format, size_t length) {
60+
if (format == IMAGEFORMAT_JPG) {
61+
// In SPRESENSE SDK, JPEG compression quality=80 by default.
62+
// In such setting, the maximum actual measured size of JPEG image
63+
// is about width * height * 2 / 9.
64+
return length >= (size_t)(width * height * 2 / 9) ? true : false;
65+
} else {
66+
return false;
67+
}
68+
}
69+
70+
static bool camera_check_format(camera_imageformat_t format) {
71+
if (format == IMAGEFORMAT_JPG) {
72+
return true;
73+
} else {
74+
return false;
8175
}
8276
}
8377

@@ -118,7 +112,9 @@ static void camera_start_preview() {
118112
camera_start_streaming(V4L2_BUF_TYPE_VIDEO_CAPTURE);
119113
}
120114

121-
void common_hal_camera_construct(camera_obj_t *self, camera_imagesize_t size) {
115+
extern uint32_t _ebss;
116+
extern uint32_t _stext;
117+
void common_hal_camera_construct(camera_obj_t *self, uint16_t width, uint16_t height) {
122118
if (camera_dev.fd < 0) {
123119
if (video_initialize(camera_dev.devpath) < 0) {
124120
mp_raise_ValueError(translate("Could not initialize Camera"));
@@ -129,25 +125,13 @@ void common_hal_camera_construct(camera_obj_t *self, camera_imagesize_t size) {
129125
}
130126
}
131127

132-
uint16_t width, height;
133-
134-
camera_size_to_width_and_height(size, &width, &height);
135-
136-
self->size = size;
137-
138-
// In SPRESENSE SDK, JPEG compression quality=80 by default.
139-
// In such setting, the maximum actual measured size of JPEG image
140-
// is about width * height * 2 / 9.
141-
self->buffer_size = (size_t)(width * height * 2 / JPG_COMPRESS_RATIO);;
142-
self->buffer = m_malloc(self->buffer_size, true);
143-
if (self->buffer == NULL) {
144-
mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate picture buffer"));
145-
}
146-
self->picture_buffer = self->buffer;
147-
while ((uint32_t)self->picture_buffer % SPRESENSE_CAMIMAGE_MEM_ALIGN != 0) {
148-
self->picture_buffer++;
128+
if (!camera_check_width_and_height(width, height)) {
129+
mp_raise_ValueError(translate("Size not supported"));
149130
}
150131

132+
self->width = width;
133+
self->height = height;
134+
151135
camera_start_preview();
152136

153137
camera_set_format(V4L2_BUF_TYPE_STILL_CAPTURE, V4L2_PIX_FMT_JPEG, width, height);
@@ -164,8 +148,6 @@ void common_hal_camera_deinit(camera_obj_t *self) {
164148

165149
video_uninitialize();
166150

167-
m_free(self->buffer);
168-
169151
close(camera_dev.fd);
170152
camera_dev.fd = -1;
171153
}
@@ -174,14 +156,26 @@ bool common_hal_camera_deinited(camera_obj_t *self) {
174156
return camera_dev.fd < 0;
175157
}
176158

177-
void common_hal_camera_take_picture(camera_obj_t *self) {
159+
size_t common_hal_camera_take_picture(camera_obj_t *self, uint8_t *buffer, size_t len, camera_imageformat_t format) {
160+
if (!camera_check_width_and_height(self->width, self->height)) {
161+
mp_raise_ValueError(translate("Size not supported"));
162+
}
163+
if (!camera_check_buffer_length(self->width, self->height, format, len)) {
164+
mp_raise_ValueError(translate("Buffer is too small"));
165+
}
166+
if (!camera_check_format(format)) {
167+
mp_raise_ValueError(translate("Format not supported"));
168+
}
169+
170+
camera_set_format(V4L2_BUF_TYPE_STILL_CAPTURE, V4L2_PIX_FMT_JPEG, self->width, self->height);
171+
178172
v4l2_buffer_t buf;
179173

180174
memset(&buf, 0, sizeof(v4l2_buffer_t));
181175
buf.type = V4L2_BUF_TYPE_STILL_CAPTURE;
182176
buf.memory = V4L2_MEMORY_USERPTR;
183-
buf.m.userptr = (unsigned long)self->picture_buffer;
184-
buf.length = self->buffer_size - SPRESENSE_CAMIMAGE_MEM_ALIGN;
177+
buf.m.userptr = (unsigned long)buffer;
178+
buf.length = len;
185179
ioctl(camera_dev.fd, VIDIOC_QBUF, (unsigned long)&buf);
186180

187181
ioctl(camera_dev.fd, VIDIOC_TAKEPICT_START, 0);
@@ -190,35 +184,21 @@ void common_hal_camera_take_picture(camera_obj_t *self) {
190184

191185
ioctl(camera_dev.fd, VIDIOC_TAKEPICT_STOP, false);
192186

193-
self->picture_size = (size_t)buf.bytesused;
187+
return (size_t)buf.bytesused;
194188
}
195189

196-
uint8_t *common_hal_camera_get_picture_buffer(camera_obj_t *self) {
197-
return self->picture_buffer;
190+
uint16_t common_hal_camera_get_width(camera_obj_t *self) {
191+
return self->width;
198192
}
199193

200-
size_t common_hal_camera_get_picture_size(camera_obj_t *self) {
201-
return self->picture_size;
194+
void common_hal_camera_set_width(camera_obj_t *self, uint16_t width) {
195+
self->width = width;
202196
}
203197

204-
camera_imagesize_t common_hal_camera_get_size(camera_obj_t *self) {
205-
return self->size;
198+
uint16_t common_hal_camera_get_height(camera_obj_t *self) {
199+
return self->height;
206200
}
207201

208-
void common_hal_camera_set_size(camera_obj_t *self, camera_imagesize_t size) {
209-
uint16_t width, height;
210-
211-
camera_size_to_width_and_height(size, &width, &height);
212-
213-
self->buffer_size = (size_t)(width * height * 2 / JPG_COMPRESS_RATIO);;
214-
self->buffer = m_realloc(self->buffer, self->buffer_size);
215-
if (self->buffer == NULL) {
216-
mp_raise_msg(&mp_type_MemoryError, translate("Couldn't allocate picture buffer"));
217-
}
218-
self->picture_buffer = self->buffer;
219-
while ((uint32_t)self->picture_buffer % SPRESENSE_CAMIMAGE_MEM_ALIGN != 0) {
220-
self->picture_buffer++;
221-
}
222-
223-
camera_set_format(V4L2_BUF_TYPE_STILL_CAPTURE, V4L2_PIX_FMT_JPEG, width, height);
202+
void common_hal_camera_set_height(camera_obj_t *self, uint16_t height) {
203+
self->height = height;
224204
}

ports/cxd56/common-hal/camera/Camera.h

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,10 @@
2929

3030
#include "py/obj.h"
3131

32-
#include "shared-bindings/camera/ImageSize.h"
33-
3432
typedef struct {
3533
mp_obj_base_t base;
36-
uint8_t *buffer;
37-
size_t buffer_size;
38-
uint8_t *picture_buffer;
39-
size_t picture_size;
40-
camera_imagesize_t size;
34+
uint16_t width;
35+
uint16_t height;
4136
} camera_obj_t;
4237

4338
#endif // MICROPY_INCLUDED_CXD56_COMMON_HAL_CAMERA_CAMERA_H

ports/cxd56/common-hal/camera/ImageSize.c

Whitespace-only changes.

py/circuitpy_defns.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,6 @@ SRC_COMMON_HAL_ALL = \
315315
busio/__init__.c \
316316
camera/__init__.c \
317317
camera/Camera.c \
318-
camera/ImageSize.c \
319318
countio/Counter.c \
320319
countio/__init__.c \
321320
digitalio/DigitalInOut.c \
@@ -386,6 +385,7 @@ $(filter $(SRC_PATTERNS), \
386385
_bleio/Attribute.c \
387386
_bleio/ScanEntry.c \
388387
_eve/__init__.c \
388+
camera/ImageFormat.c \
389389
digitalio/Direction.c \
390390
digitalio/DriveMode.c \
391391
digitalio/Pull.c \

0 commit comments

Comments
 (0)