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