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


##########
arch/sim/src/sim/posix/sim_host_v4l2.c:
##########
@@ -0,0 +1,349 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_host_v4l2.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>
+
+#include "sim_hostvideo.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_host_video: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct host_video_dev_t
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} host_video_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int host_video_ioctl(int fd, int request, void *arg)
+{
+  int r;
+
+  do
+    {
+      r = ioctl(fd, request, arg);
+    }
+  while (-1 == r && EINTR == errno);
+
+  return r;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool host_video_is_available(const char *host_video_dev_path)
+{
+  return (access(host_video_dev_path, F_OK) == 0);

Review Comment:
   ```suggestion
     return access(host_video_dev_path, F_OK) == 0;
   ```



##########
arch/sim/src/sim/sim_hostvideo.h:
##########
@@ -0,0 +1,55 @@
+/****************************************************************************
+ * arch/sim/src/sim/sim_hostvideo.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_SIM_HOSTVIDEO_H
+#define __ARCH_SIM_SRC_SIM_SIM_HOSTVIDEO_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <errno.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+typedef struct host_video_dev_t * host_video_dev;

Review Comment:
   ```suggestion
   struct host_video_dev_s;
   ```
   and replace all `host_video_dev` to `struct host_video_dev_s` and cast



##########
arch/sim/src/sim/posix/sim_host_v4l2.c:
##########
@@ -0,0 +1,349 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_host_v4l2.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>
+
+#include "sim_hostvideo.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_host_video: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct host_video_dev_t
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} host_video_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int host_video_ioctl(int fd, int request, void *arg)
+{
+  int r;
+
+  do
+    {
+      r = ioctl(fd, request, arg);
+    }
+  while (-1 == r && EINTR == errno);
+
+  return r;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool host_video_is_available(const char *host_video_dev_path)
+{
+  return (access(host_video_dev_path, F_OK) == 0);
+}
+
+host_video_dev host_video_init(const char *host_video_dev_path)
+{
+  int fd;
+  host_video_dev vdev;
+
+  fd = open(host_video_dev_path, O_RDWR | O_NONBLOCK);
+  if (fd < 0)
+    {
+      perror(host_video_dev_path);
+      return NULL;
+    }
+
+  vdev = calloc(1, sizeof(*vdev));
+  vdev->fd = fd;
+  return vdev;
+}
+
+int host_video_dq_buf(host_video_dev vdev, uint8_t *addr, uint32_t size)
+{
+  struct v4l2_buffer buf;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  memset(&buf, 0, sizeof(buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buf.memory = V4L2_MEMORY_MMAP;
+
+  /* Dequeue a buffer */
+
+  if (-1 == host_video_ioctl(dev->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, dev->addrs[buf.index], size);
+  if (-1 == ioctl(dev->fd, VIDIOC_QBUF, &buf))
+    {
+      perror("VIDIOC_QBUF");
+      return -errno;
+    }
+
+  return size;
+}
+
+int host_video_uninit(host_video_dev vdev)
+{
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  if (dev != NULL)
+    {
+      close(dev->fd);
+    }
+
+  free(vdev);
+  return 0;
+}
+
+int host_video_start_capture(host_video_dev vdev)
+{
+  struct v4l2_buffer buf;
+  enum v4l2_buf_type type;
+  int i;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  /* VIDIOC_REQBUFS initiate user pointer I/O */
+
+  dev->reqbuf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  dev->reqbuf.memory = V4L2_MEMORY_MMAP;
+  dev->reqbuf.count  = MAX_REQBUFS;
+
+  if (-1 == host_video_ioctl(dev->fd, VIDIOC_REQBUFS, &dev->reqbuf))
+    {
+      perror("VIDIOC_REQBUFS");
+      return -errno;
+    }
+
+  if (dev->reqbuf.count < 2)
+    {
+      errno = ENOMEM;
+      perror("Not enough buffers");
+      return -ENOMEM;
+    }
+
+  for (i = 0; i < dev->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 == host_video_ioctl(dev->fd, VIDIOC_QUERYBUF, &buf))
+        {
+          perror("VIDIOC_QUERYBUF");
+          return -errno;
+        }
+
+      dev->addrs[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
+                           MAP_SHARED, dev->fd, buf.m.offset);
+      dev->buflen[i] = buf.length;
+      if (dev->addrs[i] == MAP_FAILED)
+        {
+          perror("Mmap failed");
+          return -errno;
+        }
+
+      if (-1 == host_video_ioctl(dev->fd, VIDIOC_QBUF, &buf))
+        {
+          perror("VIDIOC_QBUF");
+          return -errno;
+        }
+    }
+
+  type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == host_video_ioctl(dev->fd, VIDIOC_STREAMON, &type))
+    {
+      perror("VIDIOC_STREAMON");
+      return -errno;
+    }
+
+  return 0;
+}
+
+int host_video_stop_capture(host_video_dev vdev)
+{
+  enum v4l2_buf_type type;
+  int i;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == host_video_ioctl(dev->fd, VIDIOC_STREAMOFF, &type))
+    {
+      perror("VIDIOC_STREAMOFF");
+      return -errno;
+    }
+
+  for (i = 0; i < dev->reqbuf.count; i++)
+    {
+      munmap(dev->addrs[i], dev->buflen[i]);
+    }
+
+  return 0;
+}
+
+int host_video_set_fmt(host_video_dev vdev,

Review Comment:
   ```suggestion
   int host_video_set_fmt(struct host_video_dev_s *dev,
   ```
   apply all to host_video_xxx function and remove all cast like line 260



##########
arch/sim/src/sim/posix/sim_host_v4l2.c:
##########
@@ -0,0 +1,349 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_host_v4l2.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>
+
+#include "sim_hostvideo.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_host_video: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct host_video_dev_t
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} host_video_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int host_video_ioctl(int fd, int request, void *arg)
+{
+  int r;
+
+  do
+    {
+      r = ioctl(fd, request, arg);
+    }
+  while (-1 == r && EINTR == errno);
+
+  return r;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool host_video_is_available(const char *host_video_dev_path)
+{
+  return (access(host_video_dev_path, F_OK) == 0);
+}
+
+host_video_dev host_video_init(const char *host_video_dev_path)
+{
+  int fd;
+  host_video_dev vdev;
+
+  fd = open(host_video_dev_path, O_RDWR | O_NONBLOCK);
+  if (fd < 0)
+    {
+      perror(host_video_dev_path);
+      return NULL;
+    }
+
+  vdev = calloc(1, sizeof(*vdev));
+  vdev->fd = fd;
+  return vdev;
+}
+
+int host_video_dq_buf(host_video_dev vdev, uint8_t *addr, uint32_t size)
+{
+  struct v4l2_buffer buf;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  memset(&buf, 0, sizeof(buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buf.memory = V4L2_MEMORY_MMAP;
+
+  /* Dequeue a buffer */
+
+  if (-1 == host_video_ioctl(dev->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, dev->addrs[buf.index], size);
+  if (-1 == ioctl(dev->fd, VIDIOC_QBUF, &buf))
+    {
+      perror("VIDIOC_QBUF");
+      return -errno;
+    }
+
+  return size;
+}
+
+int host_video_uninit(host_video_dev vdev)
+{
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  if (dev != NULL)
+    {
+      close(dev->fd);
+    }
+
+  free(vdev);
+  return 0;
+}
+
+int host_video_start_capture(host_video_dev vdev)
+{
+  struct v4l2_buffer buf;
+  enum v4l2_buf_type type;
+  int i;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  /* VIDIOC_REQBUFS initiate user pointer I/O */
+
+  dev->reqbuf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  dev->reqbuf.memory = V4L2_MEMORY_MMAP;
+  dev->reqbuf.count  = MAX_REQBUFS;
+
+  if (-1 == host_video_ioctl(dev->fd, VIDIOC_REQBUFS, &dev->reqbuf))
+    {
+      perror("VIDIOC_REQBUFS");
+      return -errno;
+    }
+
+  if (dev->reqbuf.count < 2)
+    {
+      errno = ENOMEM;
+      perror("Not enough buffers");
+      return -ENOMEM;
+    }
+
+  for (i = 0; i < dev->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 == host_video_ioctl(dev->fd, VIDIOC_QUERYBUF, &buf))
+        {
+          perror("VIDIOC_QUERYBUF");
+          return -errno;
+        }
+
+      dev->addrs[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
+                           MAP_SHARED, dev->fd, buf.m.offset);
+      dev->buflen[i] = buf.length;
+      if (dev->addrs[i] == MAP_FAILED)
+        {
+          perror("Mmap failed");

Review Comment:
   need ummap



##########
arch/sim/src/sim/posix/sim_host_v4l2.c:
##########
@@ -0,0 +1,349 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_host_v4l2.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>
+
+#include "sim_hostvideo.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_host_video: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct host_video_dev_t
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} host_video_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int host_video_ioctl(int fd, int request, void *arg)
+{
+  int r;
+
+  do
+    {
+      r = ioctl(fd, request, arg);
+    }
+  while (-1 == r && EINTR == errno);
+
+  return r;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool host_video_is_available(const char *host_video_dev_path)
+{
+  return (access(host_video_dev_path, F_OK) == 0);
+}
+
+host_video_dev host_video_init(const char *host_video_dev_path)
+{
+  int fd;
+  host_video_dev vdev;
+
+  fd = open(host_video_dev_path, O_RDWR | O_NONBLOCK);
+  if (fd < 0)
+    {
+      perror(host_video_dev_path);
+      return NULL;
+    }
+
+  vdev = calloc(1, sizeof(*vdev));
+  vdev->fd = fd;
+  return vdev;
+}
+
+int host_video_dq_buf(host_video_dev vdev, uint8_t *addr, uint32_t size)
+{
+  struct v4l2_buffer buf;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  memset(&buf, 0, sizeof(buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buf.memory = V4L2_MEMORY_MMAP;
+
+  /* Dequeue a buffer */
+
+  if (-1 == host_video_ioctl(dev->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, dev->addrs[buf.index], size);
+  if (-1 == ioctl(dev->fd, VIDIOC_QBUF, &buf))
+    {
+      perror("VIDIOC_QBUF");
+      return -errno;
+    }
+
+  return size;
+}
+
+int host_video_uninit(host_video_dev vdev)
+{
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  if (dev != NULL)
+    {
+      close(dev->fd);
+    }
+
+  free(vdev);
+  return 0;
+}
+
+int host_video_start_capture(host_video_dev vdev)
+{
+  struct v4l2_buffer buf;
+  enum v4l2_buf_type type;
+  int i;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  /* VIDIOC_REQBUFS initiate user pointer I/O */
+
+  dev->reqbuf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  dev->reqbuf.memory = V4L2_MEMORY_MMAP;
+  dev->reqbuf.count  = MAX_REQBUFS;
+
+  if (-1 == host_video_ioctl(dev->fd, VIDIOC_REQBUFS, &dev->reqbuf))
+    {
+      perror("VIDIOC_REQBUFS");
+      return -errno;
+    }
+
+  if (dev->reqbuf.count < 2)
+    {
+      errno = ENOMEM;
+      perror("Not enough buffers");
+      return -ENOMEM;
+    }
+
+  for (i = 0; i < dev->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 == host_video_ioctl(dev->fd, VIDIOC_QUERYBUF, &buf))
+        {
+          perror("VIDIOC_QUERYBUF");
+          return -errno;
+        }
+
+      dev->addrs[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
+                           MAP_SHARED, dev->fd, buf.m.offset);
+      dev->buflen[i] = buf.length;
+      if (dev->addrs[i] == MAP_FAILED)
+        {
+          perror("Mmap failed");
+          return -errno;
+        }
+
+      if (-1 == host_video_ioctl(dev->fd, VIDIOC_QBUF, &buf))
+        {
+          perror("VIDIOC_QBUF");
+          return -errno;
+        }
+    }
+
+  type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == host_video_ioctl(dev->fd, VIDIOC_STREAMON, &type))
+    {
+      perror("VIDIOC_STREAMON");

Review Comment:
   ditto



##########
arch/sim/src/sim/sim_video.c:
##########
@@ -0,0 +1,322 @@
+/****************************************************************************
+ * 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 <nuttx/video/video.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+
+#include "sim_hostvideo.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+  imgdata_capture_t capture_cb;
+  uint32_t buf_size;
+  uint8_t  *next_buf;
+  host_video_dev vdev;
+} sim_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 const char *sim_video_get_driver_name(void);
+static int sim_video_validate_frame_setting(imgsensor_stream_type_t type,
+                                            uint8_t nr_datafmt,
+                                            imgsensor_format_t *datafmts,
+                                            imgsensor_interval_t *interval);
+static int sim_video_start_capture(imgsensor_stream_type_t type,
+                                   uint8_t nr_datafmt,
+                                   imgsensor_format_t *datafmts,
+                                   imgsensor_interval_t *interval);
+static int sim_video_stop_capture(imgsensor_stream_type_t type);
+
+/* 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 imgdata_fmt_to_v4l2(uint32_t pixelformat);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static const 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,
+};
+
+static const 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 sim_video_priv_t g_priv;

Review Comment:
   ```suggestion
   static sim_video_priv_t g_sim_video_priv;
   ```



##########
arch/sim/src/sim/posix/sim_host_v4l2.c:
##########
@@ -0,0 +1,349 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_host_v4l2.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>
+
+#include "sim_hostvideo.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_host_video: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct host_video_dev_t

Review Comment:
   ```suggestion
   typedef struct host_video_dev_s
   ```



##########
arch/sim/src/sim/posix/sim_host_v4l2.c:
##########
@@ -0,0 +1,349 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_host_v4l2.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>
+
+#include "sim_hostvideo.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_host_video: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct host_video_dev_t
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} host_video_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int host_video_ioctl(int fd, int request, void *arg)
+{
+  int r;
+
+  do
+    {
+      r = ioctl(fd, request, arg);
+    }
+  while (-1 == r && EINTR == errno);
+
+  return r;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool host_video_is_available(const char *host_video_dev_path)
+{
+  return (access(host_video_dev_path, F_OK) == 0);
+}
+
+host_video_dev host_video_init(const char *host_video_dev_path)
+{
+  int fd;
+  host_video_dev vdev;
+
+  fd = open(host_video_dev_path, O_RDWR | O_NONBLOCK);
+  if (fd < 0)
+    {
+      perror(host_video_dev_path);
+      return NULL;
+    }
+
+  vdev = calloc(1, sizeof(*vdev));
+  vdev->fd = fd;
+  return vdev;
+}
+
+int host_video_dq_buf(host_video_dev vdev, uint8_t *addr, uint32_t size)
+{
+  struct v4l2_buffer buf;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  memset(&buf, 0, sizeof(buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buf.memory = V4L2_MEMORY_MMAP;
+
+  /* Dequeue a buffer */
+
+  if (-1 == host_video_ioctl(dev->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, dev->addrs[buf.index], size);
+  if (-1 == ioctl(dev->fd, VIDIOC_QBUF, &buf))
+    {
+      perror("VIDIOC_QBUF");
+      return -errno;
+    }
+
+  return size;
+}
+
+int host_video_uninit(host_video_dev vdev)
+{
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  if (dev != NULL)
+    {
+      close(dev->fd);
+    }
+
+  free(vdev);
+  return 0;
+}
+
+int host_video_start_capture(host_video_dev vdev)
+{
+  struct v4l2_buffer buf;
+  enum v4l2_buf_type type;
+  int i;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  /* VIDIOC_REQBUFS initiate user pointer I/O */
+
+  dev->reqbuf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  dev->reqbuf.memory = V4L2_MEMORY_MMAP;
+  dev->reqbuf.count  = MAX_REQBUFS;
+
+  if (-1 == host_video_ioctl(dev->fd, VIDIOC_REQBUFS, &dev->reqbuf))
+    {
+      perror("VIDIOC_REQBUFS");
+      return -errno;
+    }
+
+  if (dev->reqbuf.count < 2)
+    {
+      errno = ENOMEM;
+      perror("Not enough buffers");
+      return -ENOMEM;
+    }
+
+  for (i = 0; i < dev->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 == host_video_ioctl(dev->fd, VIDIOC_QUERYBUF, &buf))
+        {
+          perror("VIDIOC_QUERYBUF");
+          return -errno;
+        }
+
+      dev->addrs[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
+                           MAP_SHARED, dev->fd, buf.m.offset);
+      dev->buflen[i] = buf.length;
+      if (dev->addrs[i] == MAP_FAILED)
+        {
+          perror("Mmap failed");
+          return -errno;
+        }
+
+      if (-1 == host_video_ioctl(dev->fd, VIDIOC_QBUF, &buf))
+        {
+          perror("VIDIOC_QBUF");

Review Comment:
   ditto



##########
arch/sim/src/sim/posix/sim_host_v4l2.c:
##########
@@ -0,0 +1,349 @@
+/****************************************************************************
+ * arch/sim/src/sim/posix/sim_host_v4l2.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>
+
+#include "sim_hostvideo.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define MAX_REQBUFS 3
+
+#define WARN(fmt, ...) \
+        syslog(LOG_WARNING, "sim_host_video: " fmt "\n", ##__VA_ARGS__)
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct host_video_dev_t
+{
+  int fd;
+  struct v4l2_requestbuffers reqbuf;
+  void *addrs[MAX_REQBUFS];
+  size_t buflen[MAX_REQBUFS];
+} host_video_dev_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int host_video_ioctl(int fd, int request, void *arg)
+{
+  int r;
+
+  do
+    {
+      r = ioctl(fd, request, arg);
+    }
+  while (-1 == r && EINTR == errno);
+
+  return r;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+bool host_video_is_available(const char *host_video_dev_path)
+{
+  return (access(host_video_dev_path, F_OK) == 0);
+}
+
+host_video_dev host_video_init(const char *host_video_dev_path)
+{
+  int fd;
+  host_video_dev vdev;
+
+  fd = open(host_video_dev_path, O_RDWR | O_NONBLOCK);
+  if (fd < 0)
+    {
+      perror(host_video_dev_path);
+      return NULL;
+    }
+
+  vdev = calloc(1, sizeof(*vdev));
+  vdev->fd = fd;
+  return vdev;
+}
+
+int host_video_dq_buf(host_video_dev vdev, uint8_t *addr, uint32_t size)
+{
+  struct v4l2_buffer buf;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  memset(&buf, 0, sizeof(buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  buf.memory = V4L2_MEMORY_MMAP;
+
+  /* Dequeue a buffer */
+
+  if (-1 == host_video_ioctl(dev->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, dev->addrs[buf.index], size);
+  if (-1 == ioctl(dev->fd, VIDIOC_QBUF, &buf))
+    {
+      perror("VIDIOC_QBUF");
+      return -errno;
+    }
+
+  return size;
+}
+
+int host_video_uninit(host_video_dev vdev)
+{
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  if (dev != NULL)
+    {
+      close(dev->fd);
+    }
+
+  free(vdev);
+  return 0;
+}
+
+int host_video_start_capture(host_video_dev vdev)
+{
+  struct v4l2_buffer buf;
+  enum v4l2_buf_type type;
+  int i;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  /* VIDIOC_REQBUFS initiate user pointer I/O */
+
+  dev->reqbuf.type   = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  dev->reqbuf.memory = V4L2_MEMORY_MMAP;
+  dev->reqbuf.count  = MAX_REQBUFS;
+
+  if (-1 == host_video_ioctl(dev->fd, VIDIOC_REQBUFS, &dev->reqbuf))
+    {
+      perror("VIDIOC_REQBUFS");
+      return -errno;
+    }
+
+  if (dev->reqbuf.count < 2)
+    {
+      errno = ENOMEM;
+      perror("Not enough buffers");
+      return -ENOMEM;
+    }
+
+  for (i = 0; i < dev->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 == host_video_ioctl(dev->fd, VIDIOC_QUERYBUF, &buf))
+        {
+          perror("VIDIOC_QUERYBUF");
+          return -errno;
+        }
+
+      dev->addrs[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE,
+                           MAP_SHARED, dev->fd, buf.m.offset);
+      dev->buflen[i] = buf.length;
+      if (dev->addrs[i] == MAP_FAILED)
+        {
+          perror("Mmap failed");
+          return -errno;
+        }
+
+      if (-1 == host_video_ioctl(dev->fd, VIDIOC_QBUF, &buf))
+        {
+          perror("VIDIOC_QBUF");
+          return -errno;
+        }
+    }
+
+  type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == host_video_ioctl(dev->fd, VIDIOC_STREAMON, &type))
+    {
+      perror("VIDIOC_STREAMON");
+      return -errno;
+    }
+
+  return 0;
+}
+
+int host_video_stop_capture(host_video_dev vdev)
+{
+  enum v4l2_buf_type type;
+  int i;
+  host_video_dev_t *dev = (host_video_dev_t *)vdev;
+
+  type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+  if (-1 == host_video_ioctl(dev->fd, VIDIOC_STREAMOFF, &type))
+    {
+      perror("VIDIOC_STREAMOFF");
+      return -errno;
+    }
+
+  for (i = 0; i < dev->reqbuf.count; i++)

Review Comment:
   change reqbuf to local variable in host_video_start_capture
   ```suggestion
     for (i = 0; i < MAX_REQBUFS;  i++)
       {
         if (dev->addrs[i], != NULL && dev->addr[i] != MAP_FAILED)
       }
   ```
   



-- 
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