@@ -31,21 +31,30 @@ uint32_t FrameBuffer::getBufferSize() {
3131 if (this ->vbuf ) {
3232 return this ->vbuf ->bytesused ;
3333 }
34+ return 0 ;
3435}
3536
3637uint8_t *FrameBuffer::getBuffer () {
3738 if (this ->vbuf ) {
3839 return this ->vbuf ->buffer ;
3940 }
41+ return nullptr ;
4042}
4143
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 ) {
4347 for (size_t i = 0 ; i < ARRAY_SIZE (this ->vbuf ); i++) {
4448 this ->vbuf [i] = NULL ;
4549 }
4650}
4751
4852bool 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) {
4958#if DT_HAS_CHOSEN(zephyr_camera)
5059 this ->vdev = DEVICE_DT_GET (DT_CHOSEN (zephyr_camera));
5160#endif
@@ -74,20 +83,21 @@ bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byt
7483 return false ;
7584 }
7685
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++) {
7887 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) {
8190 break ;
8291 }
83- if (caps.format_caps [i + 1 ].pixelformat == NULL ) {
92+ if (caps.format_caps [i + 1 ].pixelformat == 0 ) {
8493 Serial.println (" The specified format is not supported" );
8594 return false ;
8695 }
8796 }
8897
8998 // Set format.
9099 static struct video_format fmt = {
100+ .type = VIDEO_BUF_TYPE_OUTPUT,
91101 .pixelformat = pixformat,
92102 .width = width,
93103 .height = height,
@@ -99,6 +109,34 @@ bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byt
99109 return false ;
100110 }
101111
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+
102140 // Allocate video buffers.
103141 for (size_t i = 0 ; i < ARRAY_SIZE (this ->vbuf ); i++) {
104142 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
111149 }
112150
113151 // 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+ }
117157 }
118-
119158 return true ;
120159}
121160
122161bool Camera::grabFrame (FrameBuffer &fb, uint32_t timeout) {
123162 if (this ->vdev == NULL ) {
124163 return false ;
125164 }
126-
165+ // printk("Camera::grabFrame called\n");
127166 if (video_dequeue (this ->vdev , &fb.vbuf , K_MSEC (timeout))) {
128167 return false ;
129168 }
130-
169+ // printk("video_dequeue returned :%p\n", fb.vbuf->buffer);
131170 if (this ->byte_swap ) {
132171 uint16_t *pixels = (uint16_t *)fb.vbuf ->buffer ;
133172 for (size_t i = 0 ; i < fb.vbuf ->bytesused / 2 ; i++) {
@@ -151,6 +190,13 @@ bool Camera::releaseFrame(FrameBuffer &fb) {
151190 return false ;
152191 }
153192
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+
154200 if (video_enqueue (this ->vdev , fb.vbuf )) {
155201 return false ;
156202 }
@@ -167,3 +213,58 @@ bool Camera::setHorizontalMirror(bool mirror_enable) {
167213 struct video_control ctrl = {.id = VIDEO_CID_HFLIP, .val = mirror_enable};
168214 return video_set_ctrl (this ->vdev , &ctrl) == 0 ;
169215}
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