@@ -31,21 +31,30 @@ uint32_t FrameBuffer::getBufferSize() {
31
31
if (this ->vbuf ) {
32
32
return this ->vbuf ->bytesused ;
33
33
}
34
+ return 0 ;
34
35
}
35
36
36
37
uint8_t *FrameBuffer::getBuffer () {
37
38
if (this ->vbuf ) {
38
39
return this ->vbuf ->buffer ;
39
40
}
41
+ return nullptr ;
40
42
}
41
43
42
- Camera::Camera () : vdev(NULL ), byte_swap(false ), yuv_to_gray(false ) {
44
+ Camera::Camera ()
45
+ : vdev(NULL ), byte_swap(false ), yuv_to_gray(false ),
46
+ snapshot_mode(CONFIG_VIDEO_BUFFER_POOL_NUM_MAX <= 1 ) {
43
47
for (size_t i = 0 ; i < ARRAY_SIZE (this ->vbuf ); i++) {
44
48
this ->vbuf [i] = NULL ;
45
49
}
46
50
}
47
51
48
52
bool Camera::begin (uint32_t width, uint32_t height, uint32_t pixformat, bool byte_swap) {
53
+ return begin (width, height, width, height, pixformat, byte_swap);
54
+ }
55
+
56
+ bool Camera::begin (uint32_t width, uint32_t height, uint32_t crop_width, uint32_t crop_height,
57
+ uint32_t pixformat, bool byte_swap) {
49
58
#if DT_HAS_CHOSEN(zephyr_camera)
50
59
this ->vdev = DEVICE_DT_GET (DT_CHOSEN (zephyr_camera));
51
60
#endif
@@ -74,20 +83,21 @@ bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byt
74
83
return false ;
75
84
}
76
85
77
- for (size_t i = 0 ; caps.format_caps [i].pixelformat != NULL ; i++) {
86
+ for (size_t i = 0 ; caps.format_caps [i].pixelformat != 0 ; i++) {
78
87
const struct video_format_cap *fcap = &caps.format_caps [i];
79
- if (fcap->width_min = = width && fcap->height_min = = height &&
80
- fcap->pixelformat == pixformat) {
88
+ if (fcap->width_min <= width && fcap-> width_max > = width && fcap->height_min < = height &&
89
+ fcap->height_max >= height && fcap-> pixelformat == pixformat) {
81
90
break ;
82
91
}
83
- if (caps.format_caps [i + 1 ].pixelformat == NULL ) {
92
+ if (caps.format_caps [i + 1 ].pixelformat == 0 ) {
84
93
Serial.println (" The specified format is not supported" );
85
94
return false ;
86
95
}
87
96
}
88
97
89
98
// Set format.
90
99
static struct video_format fmt = {
100
+ .type = VIDEO_BUF_TYPE_OUTPUT,
91
101
.pixelformat = pixformat,
92
102
.width = width,
93
103
.height = height,
@@ -99,6 +109,34 @@ bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byt
99
109
return false ;
100
110
}
101
111
112
+ // optionally set the crop values
113
+ if (width != crop_width || height != crop_height) {
114
+ struct video_selection vselCrop;
115
+ vselCrop.type = VIDEO_BUF_TYPE_OUTPUT;
116
+ vselCrop.target = VIDEO_SEL_TGT_CROP;
117
+ vselCrop.rect .left = (width - crop_width) / 2 ;
118
+ vselCrop.rect .top = (height - crop_height) / 2 ;
119
+ vselCrop.rect .width = crop_width;
120
+ vselCrop.rect .height = crop_height;
121
+ ;
122
+
123
+ int ret;
124
+ if ((ret = setSelection (&vselCrop)) != 0 ) {
125
+ printk (" ERROR: %d\n " , ret);
126
+ }
127
+ }
128
+ // this should compute the sizes needed.
129
+ video_get_format (this ->vdev , &fmt);
130
+
131
+ // If we are in snapshot mode, try starting the video stream with no buffers
132
+ // to tell it that we want snapshot...
133
+ if (snapshot_mode) {
134
+ if (video_stream_start (this ->vdev , VIDEO_BUF_TYPE_OUTPUT)) {
135
+ Serial.println (" Snapshot mode Failed to start capture" );
136
+ // return false;
137
+ }
138
+ }
139
+
102
140
// Allocate video buffers.
103
141
for (size_t i = 0 ; i < ARRAY_SIZE (this ->vbuf ); i++) {
104
142
this ->vbuf [i] = video_buffer_aligned_alloc (fmt.pitch * fmt.height ,
@@ -111,23 +149,24 @@ bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byt
111
149
}
112
150
113
151
// Start video capture
114
- if (video_stream_start (this ->vdev , VIDEO_BUF_TYPE_OUTPUT)) {
115
- Serial.println (" Failed to start capture" );
116
- return false ;
152
+ if (!snapshot_mode) {
153
+ if (video_stream_start (this ->vdev , VIDEO_BUF_TYPE_OUTPUT)) {
154
+ Serial.println (" Failed to start capture" );
155
+ return false ;
156
+ }
117
157
}
118
-
119
158
return true ;
120
159
}
121
160
122
161
bool Camera::grabFrame (FrameBuffer &fb, uint32_t timeout) {
123
162
if (this ->vdev == NULL ) {
124
163
return false ;
125
164
}
126
-
165
+ // printk("Camera::grabFrame called\n");
127
166
if (video_dequeue (this ->vdev , &fb.vbuf , K_MSEC (timeout))) {
128
167
return false ;
129
168
}
130
-
169
+ // printk("video_dequeue returned :%p\n", fb.vbuf->buffer);
131
170
if (this ->byte_swap ) {
132
171
uint16_t *pixels = (uint16_t *)fb.vbuf ->buffer ;
133
172
for (size_t i = 0 ; i < fb.vbuf ->bytesused / 2 ; i++) {
@@ -151,6 +190,13 @@ bool Camera::releaseFrame(FrameBuffer &fb) {
151
190
return false ;
152
191
}
153
192
193
+ int ret;
194
+ // printk("Camera::ReleaseFrame called\n");
195
+ if ((ret = video_enqueue (this ->vdev , fb.vbuf )) != 0 ) {
196
+ printk (" Failed to enqueue buffer %d\n " , ret);
197
+ return false ;
198
+ }
199
+
154
200
if (video_enqueue (this ->vdev , fb.vbuf )) {
155
201
return false ;
156
202
}
@@ -167,3 +213,58 @@ bool Camera::setHorizontalMirror(bool mirror_enable) {
167
213
struct video_control ctrl = {.id = VIDEO_CID_HFLIP, .val = mirror_enable};
168
214
return video_set_ctrl (this ->vdev , &ctrl) == 0 ;
169
215
}
216
+
217
+ int Camera::setSelection (struct video_selection *sel) {
218
+ return video_set_selection (vdev, sel);
219
+ }
220
+
221
+ /* *
222
+ * @brief Get video selection (crop/compose).
223
+ *
224
+ * Retrieve the current settings related to the crop and compose of the video device.
225
+ * This can also be used to read the native size of the input stream of the video
226
+ * device.
227
+ * This function can be used to read crop / compose capabilities of the device prior
228
+ * to performing configuration via the @ref video_set_selection api.
229
+ *
230
+ * @param sel Pointer to a video selection structure, @c type and @c target set by the caller
231
+ *
232
+ * @retval 0 Is successful.
233
+ * @retval -EINVAL If parameters are invalid.
234
+ * @retval -ENOTSUP If format is not supported.
235
+ * @retval -EIO General input / output error.
236
+ */
237
+ int Camera::getSelection (struct video_selection *sel) {
238
+ return video_get_selection (vdev, sel);
239
+ }
240
+
241
+ /* *
242
+ * @brief returns if snapshot mode is turned on or off.
243
+ *
244
+ * @param snapshot_mode pointer to Turn Snaphsot mode on or off..
245
+ */
246
+ bool Camera::getSnapshotMode () {
247
+ return snapshot_mode;
248
+ }
249
+
250
+ /* *
251
+ * @brief returns if snapshot mode is turned on or off.
252
+ *
253
+ * Must be called before begin to take effect.
254
+ *
255
+ * @param snap_shot mode if true.
256
+ *
257
+ * @retval 0 is successful.
258
+ */
259
+ int Camera::setSnapshotMode (bool snap_shot) {
260
+ if (snap_shot) {
261
+ snapshot_mode = snap_shot;
262
+ return 0 ;
263
+ } else {
264
+ #if CONFIG_VIDEO_BUFFER_POOL_NUM_MAX <= 1
265
+ return -EINVAL;
266
+ #endif
267
+ snapshot_mode = snap_shot;
268
+ return 0 ;
269
+ }
270
+ }
0 commit comments