@@ -84,13 +84,14 @@ static int camera_prepare(int fd, enum v4l2_buf_type type,
8484 uint32_t buf_mode , uint32_t pixformat ,
8585 uint16_t hsize , uint16_t vsize ,
8686 FAR struct v_buffer * * vbuf ,
87- uint8_t buffernum , int buffersize );
87+ uint8_t buffernum , int buffersize ,
88+ FAR uint32_t * memory );
8889static void free_buffer (FAR struct v_buffer * buffers , uint8_t bufnum );
8990static int parse_arguments (int argc , FAR char * argv [],
9091 FAR int * capture_num ,
9192 FAR enum v4l2_buf_type * type );
9293static int get_camimage (int fd , FAR struct v4l2_buffer * v4l2_buf ,
93- enum v4l2_buf_type buf_type );
94+ enum v4l2_buf_type buf_type , uint32_t memory );
9495static int release_camimage (int fd , FAR struct v4l2_buffer * v4l2_buf );
9596static int start_stillcapture (int v_fd , enum v4l2_buf_type capture_type );
9697static int stop_stillcapture (int v_fd , enum v4l2_buf_type capture_type );
@@ -119,7 +120,8 @@ static int camera_prepare(int fd, enum v4l2_buf_type type,
119120 uint32_t buf_mode , uint32_t pixformat ,
120121 uint16_t hsize , uint16_t vsize ,
121122 FAR struct v_buffer * * vbuf ,
122- uint8_t buffernum , int buffersize )
123+ uint8_t buffernum , int buffersize ,
124+ FAR uint32_t * memory )
123125{
124126 int ret ;
125127 int cnt ;
@@ -153,21 +155,30 @@ static int camera_prepare(int fd, enum v4l2_buf_type type,
153155 return ret ;
154156 }
155157
156- /* VIDIOC_REQBUFS initiate user pointer I/O */
158+ /* VIDIOC_REQBUFS: try MMAP first (driver-managed DMA buffers).
159+ * Fall back to USERPTR if the driver does not support MMAP.
160+ */
157161
158162 req .type = type ;
159- req .memory = V4L2_MEMORY_USERPTR ;
163+ req .memory = V4L2_MEMORY_MMAP ;
160164 req .count = buffernum ;
161165 req .mode = buf_mode ;
162166
163167 ret = ioctl (fd , VIDIOC_REQBUFS , (uintptr_t )& req );
164168 if (ret < 0 )
165169 {
166- printf ("Failed to VIDIOC_REQBUFS: errno = %d\n" , errno );
167- return ret ;
170+ req .memory = V4L2_MEMORY_USERPTR ;
171+ ret = ioctl (fd , VIDIOC_REQBUFS , (uintptr_t )& req );
172+ if (ret < 0 )
173+ {
174+ printf ("Failed to VIDIOC_REQBUFS: errno = %d\n" , errno );
175+ return ret ;
176+ }
168177 }
169178
170- /* Prepare video memory to store images */
179+ * memory = req .memory ;
180+
181+ /* Prepare v_buffer array to track buffer metadata */
171182
172183 * vbuf = malloc (sizeof (v_buffer_t ) * buffernum );
173184 if (!(* vbuf ))
@@ -178,29 +189,54 @@ static int camera_prepare(int fd, enum v4l2_buf_type type,
178189
179190 for (cnt = 0 ; cnt < buffernum ; cnt ++ )
180191 {
181- (* vbuf )[cnt ].length = buffersize ;
192+ if (req .memory == V4L2_MEMORY_MMAP )
193+ {
194+ /* VIDIOC_QUERYBUF: get driver-allocated buffer metadata */
182195
183- /* Note:
184- * VIDIOC_QBUF set buffer pointer.
185- * Buffer pointer must be 32bytes aligned.
186- */
196+ memset (& buf , 0 , sizeof (v4l2_buffer_t ));
197+ buf .type = type ;
198+ buf .memory = V4L2_MEMORY_MMAP ;
199+ buf .index = cnt ;
200+
201+ ret = ioctl (fd , VIDIOC_QUERYBUF , (uintptr_t )& buf );
202+ if (ret < 0 )
203+ {
204+ printf ("Failed to VIDIOC_QUERYBUF %d: errno = %d\n" ,
205+ cnt , errno );
206+ free (* vbuf );
207+ * vbuf = NULL ;
208+ return ret ;
209+ }
187210
188- (* vbuf )[cnt ].start = memalign (32 , buffersize );
189- if (!(* vbuf )[cnt ].start )
211+ (* vbuf )[cnt ].start = NULL ;
212+ (* vbuf )[cnt ].length = buf .length ;
213+ }
214+ else
190215 {
191- printf ("Out of memory for image buffer of %d/%d\n" ,
192- cnt , buffernum );
216+ (* vbuf )[cnt ].length = buffersize ;
193217
194- /* Release allocated memory. */
218+ /* Note:
219+ * VIDIOC_QBUF set buffer pointer.
220+ * Buffer pointer must be 32bytes aligned.
221+ */
195222
196- while (cnt -- )
223+ (* vbuf )[cnt ].start = memalign (32 , buffersize );
224+ if (!(* vbuf )[cnt ].start )
197225 {
198- free (( * vbuf )[ cnt ]. start );
199- }
226+ printf ( "Out of memory for image buffer of %d/%d\n" ,
227+ cnt , buffernum );
200228
201- free (* vbuf );
202- * vbuf = NULL ;
203- return ERROR ;
229+ /* Release allocated memory. */
230+
231+ while (cnt -- )
232+ {
233+ free ((* vbuf )[cnt ].start );
234+ }
235+
236+ free (* vbuf );
237+ * vbuf = NULL ;
238+ return ERROR ;
239+ }
204240 }
205241 }
206242
@@ -210,11 +246,15 @@ static int camera_prepare(int fd, enum v4l2_buf_type type,
210246 {
211247 memset (& buf , 0 , sizeof (v4l2_buffer_t ));
212248 buf .type = type ;
213- buf .memory = V4L2_MEMORY_USERPTR ;
249+ buf .memory = req . memory ;
214250 buf .index = cnt ;
215- buf .m .userptr = (uintptr_t )(* vbuf )[cnt ].start ;
216251 buf .length = (* vbuf )[cnt ].length ;
217252
253+ if (req .memory == V4L2_MEMORY_USERPTR )
254+ {
255+ buf .m .userptr = (uintptr_t )(* vbuf )[cnt ].start ;
256+ }
257+
218258 ret = ioctl (fd , VIDIOC_QBUF , (uintptr_t )& buf );
219259 if (ret )
220260 {
@@ -336,15 +376,15 @@ static int parse_arguments(int argc, FAR char *argv[],
336376 ****************************************************************************/
337377
338378static int get_camimage (int fd , FAR struct v4l2_buffer * v4l2_buf ,
339- enum v4l2_buf_type buf_type )
379+ enum v4l2_buf_type buf_type , uint32_t memory )
340380{
341381 int ret ;
342382
343383 /* VIDIOC_DQBUF acquires captured data. */
344384
345385 memset (v4l2_buf , 0 , sizeof (v4l2_buffer_t ));
346386 v4l2_buf -> type = buf_type ;
347- v4l2_buf -> memory = V4L2_MEMORY_USERPTR ;
387+ v4l2_buf -> memory = memory ;
348388
349389 ret = ioctl (fd , VIDIOC_DQBUF , (uintptr_t )v4l2_buf );
350390 if (ret )
@@ -476,6 +516,8 @@ int main(int argc, FAR char *argv[])
476516
477517 FAR struct v_buffer * buffers_video = NULL ;
478518 FAR struct v_buffer * buffers_still = NULL ;
519+ uint32_t video_memory = V4L2_MEMORY_USERPTR ;
520+ uint32_t still_memory = V4L2_MEMORY_USERPTR ;
479521
480522 /* ===== Parse and Check arguments ===== */
481523
@@ -564,7 +606,8 @@ int main(int argc, FAR char *argv[])
564606 ret = camera_prepare (v_fd , V4L2_BUF_TYPE_STILL_CAPTURE ,
565607 V4L2_BUF_MODE_FIFO , V4L2_PIX_FMT_JPEG ,
566608 w , h ,
567- & buffers_still , STILL_BUFNUM , IMAGE_JPG_SIZE );
609+ & buffers_still , STILL_BUFNUM , IMAGE_JPG_SIZE ,
610+ & still_memory );
568611 if (ret != OK )
569612 {
570613 goto exit_this_app ;
@@ -588,7 +631,8 @@ int main(int argc, FAR char *argv[])
588631 ret = camera_prepare (v_fd , V4L2_BUF_TYPE_VIDEO_CAPTURE ,
589632 V4L2_BUF_MODE_RING , V4L2_PIX_FMT_RGB565 ,
590633 VIDEO_HSIZE_QVGA , VIDEO_VSIZE_QVGA ,
591- & buffers_video , VIDEO_BUFNUM , IMAGE_RGB_SIZE );
634+ & buffers_video , VIDEO_BUFNUM , IMAGE_RGB_SIZE ,
635+ & video_memory );
592636 if (ret != OK )
593637 {
594638 goto exit_this_app ;
@@ -659,7 +703,8 @@ int main(int argc, FAR char *argv[])
659703
660704 case APP_STATE_BEFORE_CAPTURE :
661705 case APP_STATE_AFTER_CAPTURE :
662- ret = get_camimage (v_fd , & v4l2_buf , V4L2_BUF_TYPE_VIDEO_CAPTURE );
706+ ret = get_camimage (v_fd , & v4l2_buf ,
707+ V4L2_BUF_TYPE_VIDEO_CAPTURE , video_memory );
663708 if (ret != OK )
664709 {
665710 goto exit_this_app ;
@@ -712,7 +757,10 @@ int main(int argc, FAR char *argv[])
712757
713758 while (capture_num )
714759 {
715- ret = get_camimage (v_fd , & v4l2_buf , capture_type );
760+ ret = get_camimage (v_fd , & v4l2_buf , capture_type ,
761+ capture_type ==
762+ V4L2_BUF_TYPE_STILL_CAPTURE ?
763+ still_memory : video_memory );
716764 if (ret != OK )
717765 {
718766 goto exit_this_app ;
0 commit comments