xiaoxiang781216 commented on code in PR #7798:
URL: https://github.com/apache/nuttx/pull/7798#discussion_r1040857456


##########
arch/sim/src/sim/sim_video_host.h:
##########
@@ -0,0 +1,50 @@
+/****************************************************************************
+ * arch/sim/src/sim/sim_video_host.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_SIM_SRC_SIM_UP_VIDEO_HOST_H
+#define __ARCH_SIM_SRC_SIM_UP_VIDEO_HOST_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <linux/videodev2.h>
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+bool video_host_is_available(const char *video_host_dev_path);
+int video_host_init(const char *video_host_dev_path);

Review Comment:
   change all video_host_ to host_video_



##########
arch/sim/src/sim/posix/sim_video_host.c:
##########
@@ -0,0 +1,350 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_video_host.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <linux/videodev2.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_video_host: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} video_host_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static video_host_dev_t priv;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int xioctl(int fd, int request, void *arg)

Review Comment:
   host_video_ioctl



##########
arch/sim/src/sim/posix/sim_video_host.c:
##########
@@ -0,0 +1,350 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_video_host.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <linux/videodev2.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_video_host: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} video_host_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static video_host_dev_t priv;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int xioctl(int fd, int request, void *arg)
+{
+  int r;
+  do
+    {
+      r = ioctl(fd, request, arg);
+    }
+  while (-1 == r && EINTR == errno);
+
+  return r;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool video_host_is_available(const char *video_host_dev_path)
+{
+  if (access(video_host_dev_path, F_OK) == 0)
+    {
+      return true;
+    }
+
+  return false;
+}
+
+int video_host_init(const char *video_host_dev_path)
+{
+  int fd = open(video_host_dev_path, O_RDWR | O_NONBLOCK);
+  if (fd < 0)
+    {
+      perror(video_host_dev_path);
+      return -errno;
+    }
+
+  memset(&priv, 0, sizeof(priv));
+  priv.fd = fd;
+  return 0;
+}
+
+int video_host_dq_buf(uint8_t *addr, uint32_t size)
+{
+  struct v4l2_buffer buf;
+
+  memset(&buf, 0, sizeof(buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buf.memory = V4L2_MEMORY_MMAP;
+
+  /* Dequeue a buffer */
+
+  if (-1 == xioctl(priv.fd, VIDIOC_DQBUF, &buf))
+    {
+      switch (errno)
+        {
+          case EAGAIN:
+
+            /* No buffer in the outgoing queue */
+
+            return 0;
+          case EIO:
+
+            /* fall through */
+
+          default:
+            perror("VIDIOC_DQBUF");
+            return -errno;
+        }
+    }
+
+  if (size > buf.bytesused)
+    {
+      size = buf.bytesused;
+    }
+
+  memcpy(addr, priv.addrs[buf.index], size);
+  if (-1 == ioctl(priv.fd, VIDIOC_QBUF, &buf))
+    {
+      perror("VIDIOC_QBUF");
+      return -errno;
+    }
+
+  return size;
+}
+
+int video_host_uninit(void)
+{
+  close(priv.fd);
+  return 0;
+}
+
+int video_host_data_init(void)
+{
+  return 0;
+}
+
+int video_host_start_capture(void)
+{
+  struct v4l2_buffer buf;
+  int i;
+
+  /* VIDIOC_REQBUFS initiate user pointer I/O */
+
+  priv.reqbuf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  priv.reqbuf.memory = V4L2_MEMORY_MMAP;
+  priv.reqbuf.count  = MAX_REQBUFS;
+
+  if (-1 == xioctl(priv.fd, VIDIOC_REQBUFS, &priv.reqbuf))
+    {
+      perror("VIDIOC_REQBUFS");
+      return -errno;
+    }
+
+  if (priv.reqbuf.count < 2)
+    {
+      errno = ENOMEM;
+      perror("Not enough buffers");
+      return -ENOMEM;
+    }
+
+  for (i = 0; i < priv.reqbuf.count; i++)
+    {
+      memset(&buf, 0, sizeof(buf));
+      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+      buf.memory = V4L2_MEMORY_MMAP;
+      buf.index = i;
+      if (-1 == xioctl(priv.fd, VIDIOC_QUERYBUF, &buf))
+        {
+          perror("VIDIOC_QUERYBUF");
+          return -errno;
+        }
+
+      priv.addrs[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
+                           MAP_SHARED, priv.fd, buf.m.offset);
+      priv.buflen[i] = buf.length;
+      if (priv.addrs[i] == MAP_FAILED)
+        {
+          perror("Mmap failed");
+          return -errno;
+        }
+
+      if (-1 == xioctl(priv.fd, VIDIOC_QBUF, &buf))
+        {
+          perror("VIDIOC_QBUF");
+          return -errno;
+        }
+    }
+
+  enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

Review Comment:
   move to the function beginning



##########
arch/sim/Kconfig:
##########
@@ -265,6 +265,33 @@ endchoice
 
 endif
 
+config SIM_VIDEO
+       bool "Simulated video support"
+       depends on VIDEO
+       default y
+
+if SIM_VIDEO
+
+choice
+       prompt "Simulated video device type"
+       default SIM_VIDEO_V4L2
+
+config SIM_VIDEO_V4L2
+       bool "V4L2 camera support on sim"
+       depends on HOST_LINUX
+
+endchoice
+
+config HOST_VIDEO_DEV_PATH
+       string "Host video device path"
+       default "/dev/video0"
+
+config VIDEO_DEV_PATH

Review Comment:
   no user



##########
arch/sim/src/Makefile:
##########
@@ -204,6 +204,12 @@ ifeq ($(CONFIG_SIM_SOUND_ALSA),y)
   STDLIBS += -lmad
 endif
 
+ifeq ($(CONFIG_SIM_VIDEO_V4L2),y)
+  HOSTSRCS += sim_video_host.c

Review Comment:
   sim_host_v4l2.c



##########
arch/sim/src/sim/sim_video.c:
##########
@@ -0,0 +1,354 @@
+/****************************************************************************
+ * arch/sim/src/sim/sim_video.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/signal.h>
+#include <nuttx/video/imgsensor.h>
+#include <nuttx/video/imgdata.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+#include "sim_video_host.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define HOST_VIDEO_DEV_PATH  CONFIG_HOST_VIDEO_DEV_PATH
+#define ENQUEUE(q, addr, size) (q).addr[q.num] = addr; \
+                               (q).size[q.num++] = size;
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+  imgdata_capture_t capture_cb;
+  uint32_t buf_size;
+  uintptr_t next_buf;
+  bool is_streaming;
+} video_priv_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* video image sensor operations */
+
+static bool sim_video_is_available(void);
+static int sim_video_init(void);
+static int sim_video_uninit(void);
+static FAR const char *sim_video_get_driver_name(void);
+static int sim_video_validate_frame_setting(imgsensor_stream_type_t type,
+                                         uint8_t nr_datafmt,
+                                         FAR imgsensor_format_t *datafmts,
+                                         FAR imgsensor_interval_t *interval);
+static int sim_video_start_capture(imgsensor_stream_type_t type,
+                                uint8_t nr_datafmt,
+                                FAR imgsensor_format_t *datafmts,
+                                FAR imgsensor_interval_t *interval);
+static int sim_video_stop_capture(imgsensor_stream_type_t type);
+static int sim_video_get_supported_value(uint32_t id,
+                                     FAR imgsensor_supported_value_t *value);
+static int sim_video_get_value(uint32_t id, uint32_t size,
+                            FAR imgsensor_value_t *value);
+static int sim_video_set_value(uint32_t id, uint32_t size,
+                            imgsensor_value_t value);
+
+/* video image data operations */
+
+static int sim_video_data_init(void);
+static int sim_video_data_uninit(void);
+static int sim_video_data_validate_frame_setting
+             (uint8_t nr_datafmt,
+              imgdata_format_t *datafmt,
+              imgdata_interval_t *interval);
+static int sim_video_data_start_capture
+             (uint8_t nr_datafmt,
+              imgdata_format_t *datafmt,
+              imgdata_interval_t *interval,
+              imgdata_capture_t callback);
+static int sim_video_data_stop_capture(void);
+static int sim_video_data_validate_buf(uint8_t *addr, uint32_t size);
+static int sim_video_data_set_buf(uint8_t *addr, uint32_t size);
+
+static uint32_t imgsensor_fmt_to_v4l2(uint32_t pixelformat);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imgsensor_ops_s g_sim_video_ops =
+{
+  .is_available             = sim_video_is_available,
+  .init                     = sim_video_init,
+  .uninit                   = sim_video_uninit,
+  .get_driver_name          = sim_video_get_driver_name,
+  .validate_frame_setting   = sim_video_validate_frame_setting,
+  .start_capture            = sim_video_start_capture,
+  .stop_capture             = sim_video_stop_capture,
+  .get_supported_value      = sim_video_get_supported_value,
+  .get_value                = sim_video_get_value,
+  .set_value                = sim_video_set_value,
+};
+
+static struct imgdata_ops_s g_sim_video_data_ops =
+  {
+    .init                   = sim_video_data_init,
+    .uninit                 = sim_video_data_uninit,
+    .validate_buf           = sim_video_data_validate_buf,
+    .set_buf                = sim_video_data_set_buf,
+    .validate_frame_setting = sim_video_data_validate_frame_setting,
+    .start_capture          = sim_video_data_start_capture,
+    .stop_capture           = sim_video_data_stop_capture,
+  };
+
+static video_priv_t priv;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static bool sim_video_is_available(void)
+{
+  return video_host_is_available(HOST_VIDEO_DEV_PATH);
+}
+
+static int sim_video_init(void)
+{
+  return video_host_init(HOST_VIDEO_DEV_PATH);
+}
+
+static int sim_video_uninit(void)
+{
+  return video_host_uninit();
+}
+
+static FAR const char *sim_video_get_driver_name(void)
+{
+  return "V4L2 NuttX Sim Driver";
+}
+
+static int sim_video_get_supported_value(uint32_t id,
+                                     FAR imgsensor_supported_value_t *value)
+{
+  return 0;
+}
+
+static int sim_video_get_value(uint32_t id, uint32_t size,
+                            FAR imgsensor_value_t *value)
+{
+  return 0;
+}
+
+static int sim_video_set_value(uint32_t id, uint32_t size,
+                            imgsensor_value_t value)
+{
+  return 0;
+}
+
+static int validate_format(imgsensor_stream_type_t type, int nr_fmt,
+    FAR imgsensor_format_t *fmt, FAR imgsensor_interval_t *interval)
+{
+  if (nr_fmt > 1)
+    {
+      return -ENOTSUP;
+    }
+
+  uint32_t v4l2_fmt = imgsensor_fmt_to_v4l2(fmt->pixelformat);
+  if (type == IMGSENSOR_STREAM_TYPE_VIDEO)
+    {
+      return video_host_try_fmt(fmt->width, fmt->height,
+        v4l2_fmt, interval->denominator, interval->numerator);
+    }
+  else
+    {
+      return video_host_try_fmt(fmt->width, fmt->height, v4l2_fmt, 0, 0);
+    }
+}
+
+static int sim_video_validate_frame_setting(imgsensor_stream_type_t type,
+                                         uint8_t nr_fmt,
+                                         FAR imgsensor_format_t *fmt,
+                                         FAR imgsensor_interval_t *interval)
+{
+  return validate_format(type, nr_fmt, fmt, interval);
+}
+
+static int sim_video_start_capture(imgsensor_stream_type_t type,
+                                uint8_t nr_fmt,
+                                FAR imgsensor_format_t *fmt,
+                                FAR imgsensor_interval_t *interval)
+{
+  return video_host_set_fmt(fmt[IMGDATA_FMT_MAIN].width,
+    fmt[IMGDATA_FMT_MAIN].height,
+    imgsensor_fmt_to_v4l2(fmt[IMGDATA_FMT_MAIN].pixelformat),
+    interval->denominator, interval->numerator);
+}
+
+static int sim_video_stop_capture(imgsensor_stream_type_t type)
+{
+  return 0;
+}
+
+static int sim_video_data_init()
+{
+  memset(&priv, 0, sizeof(priv));
+  return video_host_data_init();
+}
+
+static int sim_video_data_uninit()
+{
+  return 0;
+}
+
+static int sim_video_data_validate_frame_setting
+             (uint8_t nr_datafmt,
+              imgdata_format_t *datafmt,
+              imgdata_interval_t *interval)
+{
+  return 0;
+}
+
+static int sim_video_data_start_capture
+             (uint8_t nr_datafmt,
+              imgdata_format_t *datafmt,
+              imgdata_interval_t *interval,
+              imgdata_capture_t callback)
+{
+  int ret;
+
+  priv.capture_cb = callback;
+  ret = video_host_start_capture();
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  priv.is_streaming = true;
+  return 0;
+}
+
+static int sim_video_data_stop_capture()
+{
+  priv.is_streaming = false;
+  return video_host_stop_capture();
+}
+
+static int sim_video_data_validate_buf(uint8_t *addr, uint32_t size)
+{
+  if (!addr || (uintptr_t)(addr) & 0x1f)
+    {
+      return -EINVAL;
+    }
+
+  return 0;
+}
+
+static int sim_video_data_set_buf(uint8_t *addr, uint32_t size)
+{
+  priv.next_buf = (uintptr_t)addr;
+  priv.buf_size = size;
+  return 0;
+}
+
+static uint32_t imgsensor_fmt_to_v4l2(uint32_t pixelformat)
+{
+  uint32_t fourcc;
+  switch (pixelformat)
+    {
+      case IMGSENSOR_PIX_FMT_YUV420P:
+        fourcc = V4L2_PIX_FMT_YUV420;
+        break;
+
+      case IMGSENSOR_PIX_FMT_YUYV:
+        fourcc = V4L2_PIX_FMT_YUYV;
+        break;
+
+      case IMGSENSOR_PIX_FMT_JPEG_WITH_SUBIMG:
+        fourcc = V4L2_PIX_FMT_JPEG;
+        break;
+
+      case IMGSENSOR_PIX_FMT_JPEG:
+        fourcc = V4L2_PIX_FMT_JPEG;
+        break;
+
+      case IMGSENSOR_PIX_FMT_RGB565:
+        fourcc = V4L2_PIX_FMT_RGB565;
+        break;
+
+      case IMGSENSOR_PIX_FMT_UYVY:
+        fourcc = V4L2_PIX_FMT_UYVY;
+        break;
+
+      default:
+
+      /* Unsupported format */
+
+        fourcc = 0;
+    }
+
+  return fourcc;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int sim_video_initialize(void)
+{
+  imgsensor_register(&g_sim_video_ops);
+  imgdata_register(&g_sim_video_data_ops);
+  return 0;
+}
+
+int sim_video_uninitialize(void)
+{
+  return 0;
+}
+
+void sim_video_loop(void)
+{
+  int ret;
+
+  if (priv.is_streaming && priv.next_buf)

Review Comment:
   remove is_streaming, it's enough to check next_buf



##########
arch/sim/src/sim/sim_video.c:
##########
@@ -0,0 +1,354 @@
+/****************************************************************************
+ * arch/sim/src/sim/sim_video.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/signal.h>
+#include <nuttx/video/imgsensor.h>
+#include <nuttx/video/imgdata.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+#include "sim_video_host.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define HOST_VIDEO_DEV_PATH  CONFIG_HOST_VIDEO_DEV_PATH
+#define ENQUEUE(q, addr, size) (q).addr[q.num] = addr; \
+                               (q).size[q.num++] = size;
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+  imgdata_capture_t capture_cb;
+  uint32_t buf_size;
+  uintptr_t next_buf;
+  bool is_streaming;
+} video_priv_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* video image sensor operations */
+
+static bool sim_video_is_available(void);
+static int sim_video_init(void);
+static int sim_video_uninit(void);
+static FAR const char *sim_video_get_driver_name(void);
+static int sim_video_validate_frame_setting(imgsensor_stream_type_t type,
+                                         uint8_t nr_datafmt,
+                                         FAR imgsensor_format_t *datafmts,
+                                         FAR imgsensor_interval_t *interval);
+static int sim_video_start_capture(imgsensor_stream_type_t type,
+                                uint8_t nr_datafmt,
+                                FAR imgsensor_format_t *datafmts,
+                                FAR imgsensor_interval_t *interval);
+static int sim_video_stop_capture(imgsensor_stream_type_t type);
+static int sim_video_get_supported_value(uint32_t id,
+                                     FAR imgsensor_supported_value_t *value);
+static int sim_video_get_value(uint32_t id, uint32_t size,
+                            FAR imgsensor_value_t *value);
+static int sim_video_set_value(uint32_t id, uint32_t size,
+                            imgsensor_value_t value);
+
+/* video image data operations */
+
+static int sim_video_data_init(void);
+static int sim_video_data_uninit(void);
+static int sim_video_data_validate_frame_setting
+             (uint8_t nr_datafmt,
+              imgdata_format_t *datafmt,
+              imgdata_interval_t *interval);
+static int sim_video_data_start_capture
+             (uint8_t nr_datafmt,
+              imgdata_format_t *datafmt,
+              imgdata_interval_t *interval,
+              imgdata_capture_t callback);
+static int sim_video_data_stop_capture(void);
+static int sim_video_data_validate_buf(uint8_t *addr, uint32_t size);
+static int sim_video_data_set_buf(uint8_t *addr, uint32_t size);
+
+static uint32_t imgsensor_fmt_to_v4l2(uint32_t pixelformat);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imgsensor_ops_s g_sim_video_ops =

Review Comment:
   add const



##########
arch/sim/src/sim/sim_video.c:
##########
@@ -0,0 +1,354 @@
+/****************************************************************************
+ * arch/sim/src/sim/sim_video.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/signal.h>
+#include <nuttx/video/imgsensor.h>
+#include <nuttx/video/imgdata.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+#include "sim_video_host.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define HOST_VIDEO_DEV_PATH  CONFIG_HOST_VIDEO_DEV_PATH
+#define ENQUEUE(q, addr, size) (q).addr[q.num] = addr; \
+                               (q).size[q.num++] = size;
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+  imgdata_capture_t capture_cb;
+  uint32_t buf_size;
+  uintptr_t next_buf;
+  bool is_streaming;
+} video_priv_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* video image sensor operations */
+
+static bool sim_video_is_available(void);
+static int sim_video_init(void);
+static int sim_video_uninit(void);
+static FAR const char *sim_video_get_driver_name(void);
+static int sim_video_validate_frame_setting(imgsensor_stream_type_t type,
+                                         uint8_t nr_datafmt,
+                                         FAR imgsensor_format_t *datafmts,
+                                         FAR imgsensor_interval_t *interval);
+static int sim_video_start_capture(imgsensor_stream_type_t type,
+                                uint8_t nr_datafmt,
+                                FAR imgsensor_format_t *datafmts,
+                                FAR imgsensor_interval_t *interval);
+static int sim_video_stop_capture(imgsensor_stream_type_t type);
+static int sim_video_get_supported_value(uint32_t id,
+                                     FAR imgsensor_supported_value_t *value);
+static int sim_video_get_value(uint32_t id, uint32_t size,
+                            FAR imgsensor_value_t *value);
+static int sim_video_set_value(uint32_t id, uint32_t size,
+                            imgsensor_value_t value);
+
+/* video image data operations */
+
+static int sim_video_data_init(void);
+static int sim_video_data_uninit(void);
+static int sim_video_data_validate_frame_setting
+             (uint8_t nr_datafmt,
+              imgdata_format_t *datafmt,
+              imgdata_interval_t *interval);
+static int sim_video_data_start_capture
+             (uint8_t nr_datafmt,
+              imgdata_format_t *datafmt,
+              imgdata_interval_t *interval,
+              imgdata_capture_t callback);
+static int sim_video_data_stop_capture(void);
+static int sim_video_data_validate_buf(uint8_t *addr, uint32_t size);
+static int sim_video_data_set_buf(uint8_t *addr, uint32_t size);
+
+static uint32_t imgsensor_fmt_to_v4l2(uint32_t pixelformat);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct imgsensor_ops_s g_sim_video_ops =
+{
+  .is_available             = sim_video_is_available,
+  .init                     = sim_video_init,
+  .uninit                   = sim_video_uninit,
+  .get_driver_name          = sim_video_get_driver_name,
+  .validate_frame_setting   = sim_video_validate_frame_setting,
+  .start_capture            = sim_video_start_capture,
+  .stop_capture             = sim_video_stop_capture,
+  .get_supported_value      = sim_video_get_supported_value,
+  .get_value                = sim_video_get_value,
+  .set_value                = sim_video_set_value,
+};
+
+static struct imgdata_ops_s g_sim_video_data_ops =

Review Comment:
   add const



##########
arch/sim/src/sim/posix/sim_video_host.c:
##########
@@ -0,0 +1,350 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_video_host.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <linux/videodev2.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_video_host: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} video_host_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static video_host_dev_t priv;

Review Comment:
   let's return and accept video_host_dev_t pointer to support mutli-instance



##########
arch/sim/src/sim/sim_video.c:
##########
@@ -0,0 +1,354 @@
+/****************************************************************************
+ * arch/sim/src/sim/sim_video.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <assert.h>
+#include <debug.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arch/board/board.h>
+#include <nuttx/config.h>
+#include <nuttx/semaphore.h>
+#include <nuttx/signal.h>
+#include <nuttx/video/imgsensor.h>
+#include <nuttx/video/imgdata.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+#include "sim_video_host.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define HOST_VIDEO_DEV_PATH  CONFIG_HOST_VIDEO_DEV_PATH
+#define ENQUEUE(q, addr, size) (q).addr[q.num] = addr; \
+                               (q).size[q.num++] = size;
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+  imgdata_capture_t capture_cb;
+  uint32_t buf_size;
+  uintptr_t next_buf;
+  bool is_streaming;
+} video_priv_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* video image sensor operations */
+
+static bool sim_video_is_available(void);
+static int sim_video_init(void);
+static int sim_video_uninit(void);
+static FAR const char *sim_video_get_driver_name(void);
+static int sim_video_validate_frame_setting(imgsensor_stream_type_t type,
+                                         uint8_t nr_datafmt,
+                                         FAR imgsensor_format_t *datafmts,

Review Comment:
   remove FAR from all source code in arc/sim



##########
arch/sim/src/sim/posix/sim_video_host.c:
##########
@@ -0,0 +1,350 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_video_host.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <linux/videodev2.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_video_host: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} video_host_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static video_host_dev_t priv;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int xioctl(int fd, int request, void *arg)
+{
+  int r;
+  do
+    {
+      r = ioctl(fd, request, arg);
+    }
+  while (-1 == r && EINTR == errno);
+
+  return r;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool video_host_is_available(const char *video_host_dev_path)
+{
+  if (access(video_host_dev_path, F_OK) == 0)
+    {
+      return true;
+    }
+
+  return false;
+}
+
+int video_host_init(const char *video_host_dev_path)
+{
+  int fd = open(video_host_dev_path, O_RDWR | O_NONBLOCK);
+  if (fd < 0)
+    {
+      perror(video_host_dev_path);
+      return -errno;
+    }
+
+  memset(&priv, 0, sizeof(priv));
+  priv.fd = fd;
+  return 0;
+}
+
+int video_host_dq_buf(uint8_t *addr, uint32_t size)
+{
+  struct v4l2_buffer buf;
+
+  memset(&buf, 0, sizeof(buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buf.memory = V4L2_MEMORY_MMAP;
+
+  /* Dequeue a buffer */
+
+  if (-1 == xioctl(priv.fd, VIDIOC_DQBUF, &buf))
+    {
+      switch (errno)
+        {
+          case EAGAIN:
+
+            /* No buffer in the outgoing queue */
+
+            return 0;
+          case EIO:
+
+            /* fall through */
+
+          default:
+            perror("VIDIOC_DQBUF");
+            return -errno;
+        }
+    }
+
+  if (size > buf.bytesused)
+    {
+      size = buf.bytesused;
+    }
+
+  memcpy(addr, priv.addrs[buf.index], size);
+  if (-1 == ioctl(priv.fd, VIDIOC_QBUF, &buf))
+    {
+      perror("VIDIOC_QBUF");
+      return -errno;
+    }
+
+  return size;
+}
+
+int video_host_uninit(void)
+{
+  close(priv.fd);
+  return 0;
+}
+
+int video_host_data_init(void)
+{
+  return 0;
+}
+
+int video_host_start_capture(void)
+{
+  struct v4l2_buffer buf;
+  int i;
+
+  /* VIDIOC_REQBUFS initiate user pointer I/O */
+
+  priv.reqbuf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  priv.reqbuf.memory = V4L2_MEMORY_MMAP;
+  priv.reqbuf.count  = MAX_REQBUFS;
+
+  if (-1 == xioctl(priv.fd, VIDIOC_REQBUFS, &priv.reqbuf))
+    {
+      perror("VIDIOC_REQBUFS");
+      return -errno;
+    }
+
+  if (priv.reqbuf.count < 2)
+    {
+      errno = ENOMEM;
+      perror("Not enough buffers");
+      return -ENOMEM;
+    }
+
+  for (i = 0; i < priv.reqbuf.count; i++)
+    {
+      memset(&buf, 0, sizeof(buf));
+      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+      buf.memory = V4L2_MEMORY_MMAP;
+      buf.index = i;
+      if (-1 == xioctl(priv.fd, VIDIOC_QUERYBUF, &buf))
+        {
+          perror("VIDIOC_QUERYBUF");
+          return -errno;
+        }
+
+      priv.addrs[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
+                           MAP_SHARED, priv.fd, buf.m.offset);
+      priv.buflen[i] = buf.length;
+      if (priv.addrs[i] == MAP_FAILED)
+        {
+          perror("Mmap failed");
+          return -errno;
+        }
+
+      if (-1 == xioctl(priv.fd, VIDIOC_QBUF, &buf))
+        {
+          perror("VIDIOC_QBUF");
+          return -errno;
+        }
+    }
+
+  enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == xioctl(priv.fd, VIDIOC_STREAMON, &type))
+    {
+      perror("VIDIOC_STREAMON");
+      return -errno;
+    }
+
+  return 0;
+}
+
+int video_host_stop_capture(void)
+{
+  enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  int i;
+
+  if (-1 == xioctl(priv.fd, VIDIOC_STREAMOFF, &type))
+    {
+      perror("VIDIOC_STREAMOFF");
+      return -errno;
+    }
+
+  for (i = 0; i < priv.reqbuf.count; i++)
+    {
+      munmap(priv.addrs[i], priv.buflen[i]);
+    }
+
+  return 0;
+}
+
+int video_host_set_fmt(uint16_t width, uint16_t height, uint32_t fmt,
+    uint32_t denom, uint32_t numer)

Review Comment:
   a
   ```suggestion
                           uint32_t denom, uint32_t numer)
   ```



##########
arch/sim/src/sim/posix/sim_video_host.c:
##########
@@ -0,0 +1,350 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_video_host.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <linux/videodev2.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_video_host: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} video_host_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static video_host_dev_t priv;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int xioctl(int fd, int request, void *arg)
+{
+  int r;
+  do
+    {
+      r = ioctl(fd, request, arg);
+    }
+  while (-1 == r && EINTR == errno);
+
+  return r;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool video_host_is_available(const char *video_host_dev_path)
+{
+  if (access(video_host_dev_path, F_OK) == 0)
+    {
+      return true;
+    }
+
+  return false;
+}
+
+int video_host_init(const char *video_host_dev_path)
+{
+  int fd = open(video_host_dev_path, O_RDWR | O_NONBLOCK);
+  if (fd < 0)
+    {
+      perror(video_host_dev_path);
+      return -errno;
+    }
+
+  memset(&priv, 0, sizeof(priv));
+  priv.fd = fd;
+  return 0;
+}
+
+int video_host_dq_buf(uint8_t *addr, uint32_t size)
+{
+  struct v4l2_buffer buf;
+
+  memset(&buf, 0, sizeof(buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buf.memory = V4L2_MEMORY_MMAP;
+
+  /* Dequeue a buffer */
+
+  if (-1 == xioctl(priv.fd, VIDIOC_DQBUF, &buf))
+    {
+      switch (errno)
+        {
+          case EAGAIN:
+
+            /* No buffer in the outgoing queue */
+
+            return 0;
+          case EIO:
+
+            /* fall through */
+
+          default:
+            perror("VIDIOC_DQBUF");
+            return -errno;
+        }
+    }
+
+  if (size > buf.bytesused)
+    {
+      size = buf.bytesused;
+    }
+
+  memcpy(addr, priv.addrs[buf.index], size);
+  if (-1 == ioctl(priv.fd, VIDIOC_QBUF, &buf))
+    {
+      perror("VIDIOC_QBUF");
+      return -errno;
+    }
+
+  return size;
+}
+
+int video_host_uninit(void)
+{
+  close(priv.fd);
+  return 0;
+}
+
+int video_host_data_init(void)
+{
+  return 0;
+}
+
+int video_host_start_capture(void)
+{
+  struct v4l2_buffer buf;
+  int i;
+
+  /* VIDIOC_REQBUFS initiate user pointer I/O */
+
+  priv.reqbuf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  priv.reqbuf.memory = V4L2_MEMORY_MMAP;
+  priv.reqbuf.count  = MAX_REQBUFS;
+
+  if (-1 == xioctl(priv.fd, VIDIOC_REQBUFS, &priv.reqbuf))
+    {
+      perror("VIDIOC_REQBUFS");
+      return -errno;
+    }
+
+  if (priv.reqbuf.count < 2)
+    {
+      errno = ENOMEM;
+      perror("Not enough buffers");
+      return -ENOMEM;
+    }
+
+  for (i = 0; i < priv.reqbuf.count; i++)
+    {
+      memset(&buf, 0, sizeof(buf));
+      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+      buf.memory = V4L2_MEMORY_MMAP;
+      buf.index = i;
+      if (-1 == xioctl(priv.fd, VIDIOC_QUERYBUF, &buf))
+        {
+          perror("VIDIOC_QUERYBUF");
+          return -errno;
+        }
+
+      priv.addrs[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
+                           MAP_SHARED, priv.fd, buf.m.offset);
+      priv.buflen[i] = buf.length;
+      if (priv.addrs[i] == MAP_FAILED)
+        {
+          perror("Mmap failed");
+          return -errno;
+        }
+
+      if (-1 == xioctl(priv.fd, VIDIOC_QBUF, &buf))
+        {
+          perror("VIDIOC_QBUF");
+          return -errno;
+        }
+    }
+
+  enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == xioctl(priv.fd, VIDIOC_STREAMON, &type))
+    {
+      perror("VIDIOC_STREAMON");
+      return -errno;
+    }
+
+  return 0;
+}
+
+int video_host_stop_capture(void)
+{
+  enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  int i;
+
+  if (-1 == xioctl(priv.fd, VIDIOC_STREAMOFF, &type))
+    {
+      perror("VIDIOC_STREAMOFF");
+      return -errno;
+    }
+
+  for (i = 0; i < priv.reqbuf.count; i++)
+    {
+      munmap(priv.addrs[i], priv.buflen[i]);
+    }
+
+  return 0;
+}
+
+int video_host_set_fmt(uint16_t width, uint16_t height, uint32_t fmt,
+    uint32_t denom, uint32_t numer)
+{
+  struct v4l2_format v4l2_fmt =
+    {
+      0
+    };
+
+  v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+  v4l2_fmt.fmt.pix.width = width;
+  v4l2_fmt.fmt.pix.height = height;
+  v4l2_fmt.fmt.pix.pixelformat = fmt;
+  v4l2_fmt.fmt.pix.field = V4L2_FIELD_NONE;
+
+  if (-1 == xioctl(priv.fd, VIDIOC_S_FMT, &v4l2_fmt))
+    {
+      perror("VIDIOC_S_FMT");
+      return -errno;
+    }
+
+  struct v4l2_streamparm streamparm =
+    {
+      0
+    };
+
+  streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == xioctl(priv.fd, VIDIOC_G_PARM, &streamparm))
+    {
+      perror("VIDIOC_G_PARM");
+      return -errno;
+    }
+
+  streamparm.parm.capture.capturemode |= V4L2_CAP_TIMEPERFRAME;
+  streamparm.parm.capture.timeperframe.numerator = numer;
+  streamparm.parm.capture.timeperframe.denominator = denom;
+  if (-1 == xioctl(priv.fd, VIDIOC_S_PARM, &streamparm))
+    {
+      perror("VIDIOC_S_PARM");
+      return -errno;
+    }
+
+  return 0;
+}
+
+int video_host_try_fmt(uint16_t width, uint16_t height, uint32_t fmt,
+    uint32_t denom, uint32_t numer)

Review Comment:
   ```suggestion
                            uint32_t denom, uint32_t numer)
   ```



##########
arch/sim/src/sim/posix/sim_video_host.c:
##########
@@ -0,0 +1,350 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_video_host.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <linux/videodev2.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_video_host: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} video_host_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static video_host_dev_t priv;
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int xioctl(int fd, int request, void *arg)
+{
+  int r;
+  do
+    {
+      r = ioctl(fd, request, arg);
+    }
+  while (-1 == r && EINTR == errno);
+
+  return r;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool video_host_is_available(const char *video_host_dev_path)
+{
+  if (access(video_host_dev_path, F_OK) == 0)
+    {
+      return true;
+    }
+
+  return false;
+}
+
+int video_host_init(const char *video_host_dev_path)
+{
+  int fd = open(video_host_dev_path, O_RDWR | O_NONBLOCK);
+  if (fd < 0)
+    {
+      perror(video_host_dev_path);
+      return -errno;
+    }
+
+  memset(&priv, 0, sizeof(priv));
+  priv.fd = fd;
+  return 0;
+}
+
+int video_host_dq_buf(uint8_t *addr, uint32_t size)
+{
+  struct v4l2_buffer buf;
+
+  memset(&buf, 0, sizeof(buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buf.memory = V4L2_MEMORY_MMAP;
+
+  /* Dequeue a buffer */
+
+  if (-1 == xioctl(priv.fd, VIDIOC_DQBUF, &buf))
+    {
+      switch (errno)
+        {
+          case EAGAIN:
+
+            /* No buffer in the outgoing queue */
+
+            return 0;
+          case EIO:
+
+            /* fall through */
+
+          default:
+            perror("VIDIOC_DQBUF");
+            return -errno;
+        }
+    }
+
+  if (size > buf.bytesused)
+    {
+      size = buf.bytesused;
+    }
+
+  memcpy(addr, priv.addrs[buf.index], size);
+  if (-1 == ioctl(priv.fd, VIDIOC_QBUF, &buf))
+    {
+      perror("VIDIOC_QBUF");
+      return -errno;
+    }
+
+  return size;
+}
+
+int video_host_uninit(void)
+{
+  close(priv.fd);
+  return 0;
+}
+
+int video_host_data_init(void)
+{
+  return 0;
+}
+
+int video_host_start_capture(void)
+{
+  struct v4l2_buffer buf;
+  int i;
+
+  /* VIDIOC_REQBUFS initiate user pointer I/O */
+
+  priv.reqbuf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  priv.reqbuf.memory = V4L2_MEMORY_MMAP;
+  priv.reqbuf.count  = MAX_REQBUFS;
+
+  if (-1 == xioctl(priv.fd, VIDIOC_REQBUFS, &priv.reqbuf))
+    {
+      perror("VIDIOC_REQBUFS");
+      return -errno;
+    }
+
+  if (priv.reqbuf.count < 2)
+    {
+      errno = ENOMEM;
+      perror("Not enough buffers");
+      return -ENOMEM;
+    }
+
+  for (i = 0; i < priv.reqbuf.count; i++)
+    {
+      memset(&buf, 0, sizeof(buf));
+      buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+      buf.memory = V4L2_MEMORY_MMAP;
+      buf.index = i;
+      if (-1 == xioctl(priv.fd, VIDIOC_QUERYBUF, &buf))
+        {
+          perror("VIDIOC_QUERYBUF");
+          return -errno;
+        }
+
+      priv.addrs[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
+                           MAP_SHARED, priv.fd, buf.m.offset);
+      priv.buflen[i] = buf.length;
+      if (priv.addrs[i] == MAP_FAILED)
+        {
+          perror("Mmap failed");
+          return -errno;
+        }
+
+      if (-1 == xioctl(priv.fd, VIDIOC_QBUF, &buf))
+        {
+          perror("VIDIOC_QBUF");
+          return -errno;
+        }
+    }
+
+  enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == xioctl(priv.fd, VIDIOC_STREAMON, &type))
+    {
+      perror("VIDIOC_STREAMON");
+      return -errno;
+    }
+
+  return 0;
+}
+
+int video_host_stop_capture(void)
+{
+  enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  int i;
+
+  if (-1 == xioctl(priv.fd, VIDIOC_STREAMOFF, &type))
+    {
+      perror("VIDIOC_STREAMOFF");
+      return -errno;
+    }
+
+  for (i = 0; i < priv.reqbuf.count; i++)
+    {
+      munmap(priv.addrs[i], priv.buflen[i]);
+    }
+
+  return 0;
+}
+
+int video_host_set_fmt(uint16_t width, uint16_t height, uint32_t fmt,
+    uint32_t denom, uint32_t numer)
+{
+  struct v4l2_format v4l2_fmt =
+    {
+      0
+    };
+
+  v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+  v4l2_fmt.fmt.pix.width = width;
+  v4l2_fmt.fmt.pix.height = height;
+  v4l2_fmt.fmt.pix.pixelformat = fmt;
+  v4l2_fmt.fmt.pix.field = V4L2_FIELD_NONE;
+
+  if (-1 == xioctl(priv.fd, VIDIOC_S_FMT, &v4l2_fmt))
+    {
+      perror("VIDIOC_S_FMT");
+      return -errno;
+    }
+
+  struct v4l2_streamparm streamparm =
+    {
+      0
+    };
+
+  streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == xioctl(priv.fd, VIDIOC_G_PARM, &streamparm))
+    {
+      perror("VIDIOC_G_PARM");
+      return -errno;
+    }
+
+  streamparm.parm.capture.capturemode |= V4L2_CAP_TIMEPERFRAME;
+  streamparm.parm.capture.timeperframe.numerator = numer;
+  streamparm.parm.capture.timeperframe.denominator = denom;
+  if (-1 == xioctl(priv.fd, VIDIOC_S_PARM, &streamparm))
+    {
+      perror("VIDIOC_S_PARM");
+      return -errno;
+    }
+
+  return 0;
+}
+
+int video_host_try_fmt(uint16_t width, uint16_t height, uint32_t fmt,
+    uint32_t denom, uint32_t numer)
+{
+  struct v4l2_format v4l2_fmt =
+    {
+      0
+    };
+
+  v4l2_fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+
+  v4l2_fmt.fmt.pix.width = width;
+  v4l2_fmt.fmt.pix.height = height;
+  v4l2_fmt.fmt.pix.pixelformat = fmt;
+  v4l2_fmt.fmt.pix.field = V4L2_FIELD_NONE;
+
+  if (-1 == xioctl(priv.fd, VIDIOC_TRY_FMT, &v4l2_fmt))
+    {
+      perror("VIDIOC_TRY_FMT");
+      return -errno;
+    }
+
+  if (v4l2_fmt.fmt.pix.pixelformat != fmt)
+    {
+      WARN("Pixel format not supported");
+      return -EINVAL;
+    }
+
+  struct v4l2_frmivalenum v4l2_frmival =

Review Comment:
   move to beginning



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to