Skip to content

Commit f95b53d

Browse files
JianyuWang0623acassis
authored andcommitted
examples/camera: add -m option for horizontal mirror preview
Add -m command line option to enable horizontal mirror on the camera sensor via VIDIOC_S_CTRL + V4L2_CID_HFLIP. This uses the sensor hardware mirror (e.g. GC0308 register 0x14 bit[0]) with zero CPU overhead. Also refactor parse_arguments to use a loop-based parser so options can appear in any order. Usage: camera 0 -m (mirror preview) camera -jpg -m (mirror still capture) Signed-off-by: wangjianyu3 <wangjianyu3@xiaomi.com>
1 parent 21dd308 commit f95b53d

1 file changed

Lines changed: 34 additions & 39 deletions

File tree

examples/camera/camera_main.c

Lines changed: 34 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ static int camera_prepare(int fd, enum v4l2_buf_type type,
9191
static void free_buffer(FAR struct v_buffer *buffers, uint8_t bufnum);
9292
static int parse_arguments(int argc, FAR char *argv[],
9393
FAR int *capture_num,
94-
FAR enum v4l2_buf_type *type);
94+
FAR enum v4l2_buf_type *type,
95+
FAR bool *mirror);
9596
static int get_camimage(int fd, FAR struct v4l2_buffer *v4l2_buf,
9697
enum v4l2_buf_type buf_type, uint32_t memory);
9798
static int release_camimage(int fd, FAR struct v4l2_buffer *v4l2_buf);
@@ -330,57 +331,35 @@ static void free_buffer(FAR struct v_buffer *buffers, uint8_t bufnum)
330331

331332
static int parse_arguments(int argc, FAR char *argv[],
332333
FAR int *capture_num,
333-
FAR enum v4l2_buf_type *type)
334+
FAR enum v4l2_buf_type *type,
335+
FAR bool *mirror)
334336
{
335-
if (argc == 1)
336-
{
337-
*capture_num = DEFAULT_CAPTURE_NUM;
338-
*type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
339-
}
340-
else if (argc == 2)
337+
int i;
338+
339+
*capture_num = DEFAULT_CAPTURE_NUM;
340+
*type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
341+
*mirror = false;
342+
343+
for (i = 1; i < argc; i++)
341344
{
342-
if (strncmp(argv[1], "-jpg", 5) == 0)
345+
if (strncmp(argv[i], "-jpg", 5) == 0)
343346
{
344-
*capture_num = DEFAULT_CAPTURE_NUM;
345347
*type = V4L2_BUF_TYPE_STILL_CAPTURE;
346348
}
347-
else
349+
else if (strncmp(argv[i], "-m", 3) == 0)
348350
{
349-
*capture_num = atoi(argv[1]);
350-
if (*capture_num < 0 || *capture_num > MAX_CAPTURE_NUM)
351-
{
352-
printf("Invalid capture num(%d). must be >=0 and <=%d\n",
353-
*capture_num, MAX_CAPTURE_NUM);
354-
return ERROR;
355-
}
356-
357-
*type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
351+
*mirror = true;
358352
}
359-
}
360-
else if (argc == 3)
361-
{
362-
if (strncmp(argv[1], "-jpg", 5) == 0)
353+
else
363354
{
364-
*capture_num = atoi(argv[2]);
355+
*capture_num = atoi(argv[i]);
365356
if (*capture_num < 0 || *capture_num > MAX_CAPTURE_NUM)
366357
{
367358
printf("Invalid capture num(%d). must be >=0 and <=%d\n",
368359
*capture_num, MAX_CAPTURE_NUM);
369360
return ERROR;
370361
}
371-
372-
*type = V4L2_BUF_TYPE_STILL_CAPTURE;
373362
}
374-
else
375-
{
376-
printf("Invalid argument 1 : %s\n", argv[1]);
377-
return ERROR;
378-
}
379-
}
380-
else
381-
{
382-
printf("Too many arguments\n");
383-
return ERROR;
384363
}
385364

386365
return OK;
@@ -537,13 +516,14 @@ int main(int argc, FAR char *argv[])
537516
uint32_t video_memory = V4L2_MEMORY_USERPTR;
538517
uint32_t still_memory = V4L2_MEMORY_USERPTR;
539518
uint32_t video_pixfmt = V4L2_PIX_FMT_RGB565;
519+
bool mirror = false;
540520

541521
/* ===== Parse and Check arguments ===== */
542522

543-
ret = parse_arguments(argc, argv, &capture_num, &capture_type);
523+
ret = parse_arguments(argc, argv, &capture_num, &capture_type, &mirror);
544524
if (ret != OK)
545525
{
546-
printf("usage: %s ([-jpg]) ([capture num])\n", argv[0]);
526+
printf("usage: %s [-jpg] [-m] [capture num]\n", argv[0]);
547527
return ERROR;
548528
}
549529

@@ -583,6 +563,21 @@ int main(int argc, FAR char *argv[])
583563
goto exit_without_cleaning_buffer;
584564
}
585565

566+
/* Set horizontal mirror if requested */
567+
568+
if (mirror)
569+
{
570+
struct v4l2_control ctrl;
571+
572+
ctrl.id = V4L2_CID_HFLIP;
573+
ctrl.value = 1;
574+
ret = ioctl(v_fd, VIDIOC_S_CTRL, (uintptr_t)&ctrl);
575+
if (ret < 0)
576+
{
577+
printf("WARNING: VIDIOC_S_CTRL HFLIP failed: %d\n", errno);
578+
}
579+
}
580+
586581
/* Prepare for STILL_CAPTURE stream.
587582
*
588583
* The video buffer mode is V4L2_BUF_MODE_FIFO mode.

0 commit comments

Comments
 (0)