@@ -32,21 +32,29 @@ uint32_t FrameBuffer::getBufferSize() {
3232 if (this ->vbuf ) {
3333 return this ->vbuf ->bytesused ;
3434 }
35+ return 0 ;
3536}
3637
3738uint8_t * FrameBuffer::getBuffer () {
3839 if (this ->vbuf ) {
3940 return this ->vbuf ->buffer ;
4041 }
42+ return nullptr ;
4143}
4244
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 ) {
4447 for (size_t i = 0 ; i < ARRAY_SIZE (this ->vbuf ); i++) {
4548 this ->vbuf [i] = NULL ;
4649 }
4750}
4851
52+
4953bool 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) {
5058 #if DT_HAS_CHOSEN(zephyr_camera)
5159 this ->vdev = DEVICE_DT_GET (DT_CHOSEN (zephyr_camera));
5260 #endif
@@ -75,21 +83,22 @@ bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byt
7583 return false ;
7684 }
7785
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++) {
7987 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 &&
8290 fcap->pixelformat == pixformat) {
8391 break ;
8492 }
85- if (caps.format_caps [i+1 ].pixelformat == NULL ) {
93+ if (caps.format_caps [i+1 ].pixelformat == 0 ) {
8694 Serial.println (" The specified format is not supported" );
8795 return false ;
8896 }
8997 }
9098
9199 // Set format.
92100 static struct video_format fmt = {
101+ .type = VIDEO_BUF_TYPE_OUTPUT,
93102 .pixelformat = pixformat,
94103 .width = width,
95104 .height = height,
@@ -101,6 +110,34 @@ bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byt
101110 return false ;
102111 }
103112
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+
104141 // Allocate video buffers.
105142 for (size_t i = 0 ; i < ARRAY_SIZE (this ->vbuf ); i++) {
106143 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
114151 }
115152
116153 // 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+ }
122160 return true ;
123161}
124162
125163bool Camera::grabFrame (FrameBuffer &fb, uint32_t timeout) {
126164 if (this ->vdev == NULL ) {
127165 return false ;
128166 }
129-
167+ // printk("Camera::grabFrame called\n");
130168 if (video_dequeue (this ->vdev , &fb.vbuf , K_MSEC (timeout))) {
131169 return false ;
132170 }
133-
171+ // printk("video_dequeue returned :%p\n", fb.vbuf->buffer);
134172 if (this ->byte_swap ) {
135173 uint16_t *pixels = (uint16_t *) fb.vbuf ->buffer ;
136174 for (size_t i=0 ; i<fb.vbuf ->bytesused / 2 ; i++) {
@@ -154,7 +192,10 @@ bool Camera::releaseFrame(FrameBuffer &fb) {
154192 return false ;
155193 }
156194
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);
158199 return false ;
159200 }
160201
@@ -170,3 +211,58 @@ bool Camera::setHorizontalMirror(bool mirror_enable) {
170211 struct video_control ctrl = {.id = VIDEO_CID_HFLIP, .val = mirror_enable};
171212 return video_set_ctrl (this ->vdev , &ctrl) == 0 ;
172213}
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