3838
3939#include <nuttx/video/video.h>
4040#include <nuttx/video/v4l2_cap.h>
41+ #include <nuttx/cache.h>
4142
4243#include "camera_fileutil.h"
4344#include "camera_bkgd.h"
@@ -85,7 +86,8 @@ static int camera_prepare(int fd, enum v4l2_buf_type type,
8586 uint16_t hsize , uint16_t vsize ,
8687 FAR struct v_buffer * * vbuf ,
8788 uint8_t buffernum , int buffersize ,
88- FAR uint32_t * memory );
89+ FAR uint32_t * memory ,
90+ FAR uint32_t * actual_fmt );
8991static void free_buffer (FAR struct v_buffer * buffers , uint8_t bufnum );
9092static int parse_arguments (int argc , FAR char * argv [],
9193 FAR int * capture_num ,
@@ -121,7 +123,8 @@ static int camera_prepare(int fd, enum v4l2_buf_type type,
121123 uint16_t hsize , uint16_t vsize ,
122124 FAR struct v_buffer * * vbuf ,
123125 uint8_t buffernum , int buffersize ,
124- FAR uint32_t * memory )
126+ FAR uint32_t * memory ,
127+ FAR uint32_t * actual_fmt )
125128{
126129 int ret ;
127130 int cnt ;
@@ -149,12 +152,27 @@ static int camera_prepare(int fd, enum v4l2_buf_type type,
149152 fmt .fmt .pix .pixelformat = pixformat ;
150153
151154 ret = ioctl (fd , VIDIOC_S_FMT , (uintptr_t )& fmt );
155+ if (ret < 0 && pixformat == V4L2_PIX_FMT_RGB565 )
156+ {
157+ /* Some sensors on 8-bit DVP output big-endian RGB565 (RGB565X).
158+ * Retry with RGB565X if RGB565 is not supported.
159+ */
160+
161+ fmt .fmt .pix .pixelformat = V4L2_PIX_FMT_RGB565X ;
162+ ret = ioctl (fd , VIDIOC_S_FMT , (uintptr_t )& fmt );
163+ }
164+
152165 if (ret < 0 )
153166 {
154167 printf ("Failed to VIDIOC_S_FMT: errno = %d\n" , errno );
155168 return ret ;
156169 }
157170
171+ if (actual_fmt )
172+ {
173+ * actual_fmt = fmt .fmt .pix .pixelformat ;
174+ }
175+
158176 /* VIDIOC_REQBUFS: try MMAP first (driver-managed DMA buffers).
159177 * Fall back to USERPTR if the driver does not support MMAP.
160178 */
@@ -518,6 +536,7 @@ int main(int argc, FAR char *argv[])
518536 FAR struct v_buffer * buffers_still = NULL ;
519537 uint32_t video_memory = V4L2_MEMORY_USERPTR ;
520538 uint32_t still_memory = V4L2_MEMORY_USERPTR ;
539+ uint32_t video_pixfmt = V4L2_PIX_FMT_RGB565 ;
521540
522541 /* ===== Parse and Check arguments ===== */
523542
@@ -607,7 +626,7 @@ int main(int argc, FAR char *argv[])
607626 V4L2_BUF_MODE_FIFO , V4L2_PIX_FMT_JPEG ,
608627 w , h ,
609628 & buffers_still , STILL_BUFNUM , IMAGE_JPG_SIZE ,
610- & still_memory );
629+ & still_memory , NULL );
611630 if (ret != OK )
612631 {
613632 goto exit_this_app ;
@@ -632,7 +651,7 @@ int main(int argc, FAR char *argv[])
632651 V4L2_BUF_MODE_RING , V4L2_PIX_FMT_RGB565 ,
633652 VIDEO_HSIZE_QVGA , VIDEO_VSIZE_QVGA ,
634653 & buffers_video , VIDEO_BUFNUM , IMAGE_RGB_SIZE ,
635- & video_memory );
654+ & video_memory , & video_pixfmt );
636655 if (ret != OK )
637656 {
638657 goto exit_this_app ;
@@ -704,13 +723,35 @@ int main(int argc, FAR char *argv[])
704723 case APP_STATE_BEFORE_CAPTURE :
705724 case APP_STATE_AFTER_CAPTURE :
706725 ret = get_camimage (v_fd , & v4l2_buf ,
707- V4L2_BUF_TYPE_VIDEO_CAPTURE , video_memory );
726+ V4L2_BUF_TYPE_VIDEO_CAPTURE , video_memory );
708727 if (ret != OK )
709728 {
710729 goto exit_this_app ;
711730 }
712731
713732#ifdef CONFIG_EXAMPLES_CAMERA_OUTPUT_LCD
733+ /* If the sensor outputs RGB565X (big-endian), invalidate
734+ * D-Cache so we read fresh DMA data from PSRAM, then
735+ * byte-swap in place for display and swap back before
736+ * returning the buffer to the driver.
737+ */
738+
739+ if (video_pixfmt == V4L2_PIX_FMT_RGB565X )
740+ {
741+ FAR uint16_t * p = (FAR uint16_t * )v4l2_buf .m .userptr ;
742+ uint32_t npixels = v4l2_buf .bytesused / 2 ;
743+ uint32_t i ;
744+
745+ up_invalidate_dcache ((uintptr_t )p ,
746+ (uintptr_t )p + v4l2_buf .bytesused );
747+
748+ for (i = 0 ; i < npixels ; i ++ )
749+ {
750+ uint16_t v = p [i ];
751+ p [i ] = (v >> 8 ) | (v << 8 );
752+ }
753+ }
754+
714755 nximage_draw ((FAR void * )v4l2_buf .m .userptr ,
715756 VIDEO_HSIZE_QVGA , VIDEO_VSIZE_QVGA );
716757#endif
0 commit comments