This is an automated email from the ASF dual-hosted git repository.
xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new ce9f40aeb6 drivers/video: add nuttx goldfish camera driver
ce9f40aeb6 is described below
commit ce9f40aeb6e6ea82a018e4f1d49977866676a7ba
Author: yangsen5 <[email protected]>
AuthorDate: Tue Jun 13 11:18:51 2023 +0800
drivers/video: add nuttx goldfish camera driver
Signed-off-by: yangsen5 <[email protected]>
---
drivers/video/Kconfig | 21 +
drivers/video/Make.defs | 4 +
drivers/video/goldfish_camera.c | 780 ++++++++++++++++++++++++++++++++++
include/nuttx/video/goldfish_camera.h | 63 +++
4 files changed, 868 insertions(+)
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 2e30e24957..fcb80547bd 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -321,6 +321,27 @@ config OV2640_REGDEBUG
endif
+config GOLDFISH_CAMERA
+ bool "Goldfish camera support"
+ depends on VIDEO
+ default n
+
+if GOLDFISH_CAMERA
+
+config GOLDFISH_CAMERA_PIPE_PATH
+ string "Goldfish camera pipe path"
+ default "/dev/goldfish_pipe"
+
+config GOLDFISH_CAMERA_PRIORITY
+ int "Goldfish camera thread priority"
+ default 224
+
+config GOLDFISH_CAMERA_STACKSIZE
+ int "Goldfish camera stack size"
+ default DEFAULT_TASK_STACKSIZE
+
+endif
+
source "drivers/video/vnc/Kconfig"
source "drivers/video/mipidsi/Kconfig"
diff --git a/drivers/video/Make.defs b/drivers/video/Make.defs
index ad41c026fa..b40305ee28 100644
--- a/drivers/video/Make.defs
+++ b/drivers/video/Make.defs
@@ -58,6 +58,10 @@ endif
endif
+ifeq ($(CONFIG_GOLDFISH_CAMERA),y)
+ CSRCS += goldfish_camera.c
+endif
+
include video/vnc/Make.defs
include video/mipidsi/Make.defs
diff --git a/drivers/video/goldfish_camera.c b/drivers/video/goldfish_camera.c
new file mode 100644
index 0000000000..55996c11af
--- /dev/null
+++ b/drivers/video/goldfish_camera.c
@@ -0,0 +1,780 @@
+/****************************************************************************
+ * drivers/video/goldfish_camera.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 <debug.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <nuttx/nuttx.h>
+#include <nuttx/kthread.h>
+#include <nuttx/video/imgsensor.h>
+#include <nuttx/video/imgdata.h>
+#include <nuttx/video/video.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define GOLDFISH_CAMERA_MAX_NUMBER 8
+#define GOLDFISH_CAMERA_SIZE_MAX_NUMBER 32
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+typedef struct
+{
+ uint16_t width;
+ uint16_t height;
+} goldfish_camera_size_t;
+
+typedef struct
+{
+ char name[32];
+ uint32_t channel;
+ uint32_t pix;
+ char dir[32];
+ goldfish_camera_size_t size[GOLDFISH_CAMERA_SIZE_MAX_NUMBER];
+} goldfish_camera_info_t;
+
+typedef struct
+{
+ struct imgdata_s data;
+ struct imgsensor_s sensor;
+ imgdata_capture_t capture_cb;
+ FAR void *capture_arg;
+ uint32_t buf_size;
+ FAR uint8_t *next_buf;
+ struct file file;
+ sem_t run;
+ goldfish_camera_info_t info;
+ bool streaming;
+ pid_t pid;
+} goldfish_camera_priv_t;
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/* Video image sensor operations */
+
+static bool goldfish_camera_is_available(FAR struct imgsensor_s *sensor);
+static int goldfish_camera_init(FAR struct imgsensor_s *sensor);
+static int goldfish_camera_uninit(FAR struct imgsensor_s *sensor);
+static FAR const char *
+goldfish_camera_get_driver_name(FAR struct imgsensor_s *sensor);
+static int
+goldfish_camera_validate_frame_setting(FAR struct imgsensor_s *sensor,
+ imgsensor_stream_type_t type,
+ uint8_t nr_datafmt,
+ FAR imgsensor_format_t *datafmts,
+ FAR imgsensor_interval_t *interval);
+static int goldfish_camera_start_capture(FAR struct imgsensor_s *sensor,
+ imgsensor_stream_type_t type,
+ uint8_t nr_datafmt,
+ FAR imgsensor_format_t *datafmts,
+ FAR imgsensor_interval_t *interval);
+static int goldfish_camera_stop_capture(FAR struct imgsensor_s *sensor,
+ imgsensor_stream_type_t type);
+
+/* Video image data operations */
+
+static int goldfish_camera_data_init(FAR struct imgdata_s *data);
+static int goldfish_camera_data_uninit(FAR struct imgdata_s *data);
+static int
+goldfish_camera_data_validate_frame_setting(FAR struct imgdata_s *data,
+ uint8_t nr_datafmt,
+ FAR imgdata_format_t *datafmt,
+ FAR imgdata_interval_t *interval);
+static int
+goldfish_camera_data_start_capture(FAR struct imgdata_s *data,
+ uint8_t nr_datafmt,
+ FAR imgdata_format_t *datafmt,
+ FAR imgdata_interval_t *interval,
+ imgdata_capture_t callback,
+ FAR void *arg);
+static int goldfish_camera_data_stop_capture(FAR struct imgdata_s *data);
+static int goldfish_camera_data_set_buf(FAR struct imgdata_s *data,
+ FAR uint8_t *addr,
+ uint32_t size);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/* Communication service for qemu-pipe */
+
+static const char g_qemudservice[] = "qemud";
+
+/* Camera service. */
+
+static const char g_cameraservice[] = "camera";
+
+static const struct imgsensor_ops_s g_goldfish_camera_ops =
+{
+ .is_available = goldfish_camera_is_available,
+ .init = goldfish_camera_init,
+ .uninit = goldfish_camera_uninit,
+ .get_driver_name = goldfish_camera_get_driver_name,
+ .validate_frame_setting = goldfish_camera_validate_frame_setting,
+ .start_capture = goldfish_camera_start_capture,
+ .stop_capture = goldfish_camera_stop_capture,
+};
+
+static const struct imgdata_ops_s g_goldfish_camera_data_ops =
+{
+ .init = goldfish_camera_data_init,
+ .uninit = goldfish_camera_data_uninit,
+ .set_buf = goldfish_camera_data_set_buf,
+ .validate_frame_setting = goldfish_camera_data_validate_frame_setting,
+ .start_capture = goldfish_camera_data_start_capture,
+ .stop_capture = goldfish_camera_data_stop_capture,
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static int goldfish_camera_read_fully(FAR struct file *file,
+ FAR void *buffer,
+ size_t size)
+{
+ FAR char *p = (FAR char *)buffer;
+
+ while (size > 0)
+ {
+ ssize_t n = file_read(file, p, size);
+ if (n < 0)
+ {
+ return n;
+ }
+
+ p += n;
+ size -= n;
+ }
+
+ return 0;
+}
+
+static int goldfish_camera_write_fully(FAR struct file *file,
+ FAR const void *buffer,
+ size_t size)
+{
+ FAR const char *p = (FAR const char *)buffer;
+
+ while (size > 0)
+ {
+ ssize_t n = file_write(file, p, size);
+ if (n < 0)
+ {
+ return n;
+ }
+
+ p += n;
+ size -= n;
+ }
+
+ return 0;
+}
+
+static int goldfish_camera_send(FAR struct file *file,
+ FAR const char *format,
+ ...)
+{
+ char buf[256];
+ va_list ap;
+ int len;
+
+ va_start(ap, format);
+ len = vsnprintf(buf, sizeof(buf), format, ap);
+ va_end(ap);
+
+ if (len < 0)
+ {
+ return len;
+ }
+
+ return goldfish_camera_write_fully(file, buf, len + 1);
+}
+
+static ssize_t goldfish_camera_recv(FAR struct file *file,
+ FAR void **data)
+{
+ char buf[9];
+ size_t payload_size;
+ bool empty = !*data;
+ int ret;
+
+ ret = goldfish_camera_read_fully(file, buf, 8);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ buf[8] = '\0';
+ payload_size = strtoul(buf, NULL, 16);
+
+ if (payload_size < 3)
+ {
+ return -EINVAL;
+ }
+
+ ret = goldfish_camera_read_fully(file, buf, 3);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ if (memcmp(buf, "ok", 2) != 0)
+ {
+ return -EINVAL;
+ }
+
+ if (buf[2] == '\0')
+ {
+ return 0;
+ }
+
+ payload_size -= 3;
+ if (payload_size == 0)
+ {
+ return 0;
+ }
+
+ if (empty)
+ {
+ *data = kmm_malloc(payload_size);
+ if (*data == NULL)
+ {
+ return -ENOMEM;
+ }
+ }
+
+ ret = goldfish_camera_read_fully(file, *data, payload_size);
+ if (ret < 0)
+ {
+ if (empty)
+ {
+ kmm_free(*data);
+ }
+
+ return ret;
+ }
+
+ return payload_size;
+}
+
+static ssize_t goldfish_camera_get_list(FAR goldfish_camera_priv_t **priv,
+ size_t size)
+{
+ FAR void *cameradata = NULL;
+ struct file file;
+ FAR char *data;
+ size_t count = 0;
+ int ret;
+
+ /* Queries list of cameras connected to the host. */
+
+ ret = file_open(&file,
+ CONFIG_GOLDFISH_CAMERA_PIPE_PATH,
+ O_RDWR);
+ if (ret < 0)
+ {
+ verr("Failed to open: %s: %d\n",
+ CONFIG_GOLDFISH_CAMERA_PIPE_PATH, ret);
+ return ret;
+ }
+
+ ret = goldfish_camera_send(&file,
+ "pipe:%s:%s",
+ g_qemudservice,
+ g_cameraservice);
+ if (ret < 0)
+ {
+ goto out;
+ }
+
+ ret = goldfish_camera_send(&file, "list");
+ if (ret < 0)
+ {
+ goto out;
+ }
+
+ ret = goldfish_camera_recv(&file, &cameradata);
+ if (ret < 0)
+ {
+ goto out;
+ }
+
+ /* Parse string
+ *
+ * For example:
+ * 'name=virtualscene channel=0 pix=876758866 dir=back framedims=640x480'
+ *
+ * Use the strstr function to parse name/channel/pix/dir/framedims
+ * of multiple devices by "name";
+ *
+ * Use the strchr function to parse multiple size by ',';
+ */
+
+ data = (FAR char *)cameradata;
+
+ while ((data = strstr(data, "name")) != NULL)
+ {
+ char sizelist[256];
+ FAR char *sizedata = sizelist;
+ size_t sizecount = 0;
+
+ priv[count] = kmm_zalloc(sizeof(goldfish_camera_priv_t));
+ if (priv[count] == NULL)
+ {
+ verr("Failed to allocate instance\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ sscanf(data,
+ "name=%s channel=%"SCNu32" pix=%"SCNu32" dir=%s framedims=%s",
+ priv[count]->info.name,
+ &priv[count]->info.channel,
+ &priv[count]->info.pix,
+ priv[count]->info.dir,
+ sizelist);
+
+ sscanf(sizedata,
+ "%"SCNu16"x%"SCNu16"",
+ &priv[count]->info.size[sizecount].width,
+ &priv[count]->info.size[sizecount].height);
+
+ while ((sizedata = strchr(sizedata, ',')) != NULL)
+ {
+ if (++sizecount >= GOLDFISH_CAMERA_SIZE_MAX_NUMBER)
+ {
+ ret = -E2BIG;
+ goto err;
+ }
+
+ sizedata++;
+ sscanf(sizedata,
+ "%"SCNu16"x%"SCNu16"",
+ &priv[count]->info.size[sizecount].width,
+ &priv[count]->info.size[sizecount].height);
+ }
+
+ if (++count >= size)
+ {
+ ret = -E2BIG;
+ goto err;
+ }
+
+ data++;
+ }
+
+ ret = count;
+ goto out;
+
+err:
+ do
+ {
+ if (priv[count])
+ {
+ kmm_free(priv[count]);
+ }
+ }
+ while (count--);
+
+out:
+ file_close(&file);
+
+ if (cameradata)
+ {
+ kmm_free(cameradata);
+ }
+
+ return ret;
+}
+
+static int goldfish_camera_thread(int argc, FAR char *argv[])
+{
+ FAR goldfish_camera_priv_t *priv = (FAR goldfish_camera_priv_t *)
+ ((uintptr_t)strtoul(argv[1], NULL, 16));
+ int ret;
+
+ while (1)
+ {
+ if (nxsem_wait(&priv->run) < 0)
+ {
+ continue;
+ }
+
+ if (!priv->streaming)
+ {
+ return 0;
+ }
+
+ ret = goldfish_camera_send(&priv->file,
+ "frame video=%"PRIu32" preview=0 "
+ "whiteb=1,1,1 expcomp=1 time=0",
+ priv->buf_size);
+
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+reload:
+ ret = goldfish_camera_recv(&priv->file,
+ (FAR void **)&priv->next_buf);
+ if (ret < 0)
+ {
+ return ret;
+ }
+ else if (ret == 0)
+ {
+ goto reload;
+ }
+ else
+ {
+ struct timespec ts;
+ struct timeval tv;
+
+ DEBUGASSERT(ret == priv->buf_size);
+
+ clock_systime_timespec(&ts);
+ TIMESPEC_TO_TIMEVAL(&tv, &ts);
+ priv->capture_cb(0, priv->buf_size, &tv, priv->capture_arg);
+ }
+ }
+}
+
+/* Helper functions */
+
+static uint32_t imgdata_fmt_to_v4l2(uint32_t pixelformat)
+{
+ switch (pixelformat)
+ {
+ case IMGDATA_PIX_FMT_YUV420P:
+ return V4L2_PIX_FMT_YUV420;
+
+ case IMGDATA_PIX_FMT_YUYV:
+ return V4L2_PIX_FMT_YUYV;
+
+ case IMGDATA_PIX_FMT_JPEG_WITH_SUBIMG:
+ return V4L2_PIX_FMT_JPEG;
+
+ case IMGDATA_PIX_FMT_JPEG:
+ return V4L2_PIX_FMT_JPEG;
+
+ case IMGDATA_PIX_FMT_RGB565:
+ return V4L2_PIX_FMT_RGB565;
+
+ case IMGDATA_PIX_FMT_UYVY:
+ return V4L2_PIX_FMT_UYVY;
+
+ default:
+
+ /* Unsupported format */
+
+ return 0;
+ }
+}
+
+/* Sensor op functions are mostly dummy */
+
+static bool goldfish_camera_is_available(FAR struct imgsensor_s *sensor)
+{
+ return access(CONFIG_GOLDFISH_CAMERA_PIPE_PATH, F_OK) == 0;
+}
+
+static int goldfish_camera_init(FAR struct imgsensor_s *sensor)
+{
+ return 0;
+}
+
+static int goldfish_camera_uninit(FAR struct imgsensor_s *sensor)
+{
+ return 0;
+}
+
+static FAR const char *
+goldfish_camera_get_driver_name(FAR struct imgsensor_s *sensor)
+{
+ FAR goldfish_camera_priv_t *priv = container_of(sensor,
+ goldfish_camera_priv_t,
+ sensor);
+ return priv->info.name;
+}
+
+static int
+goldfish_camera_validate_frame_setting(FAR struct imgsensor_s *sensor,
+ imgsensor_stream_type_t type,
+ uint8_t nr_fmt,
+ FAR imgsensor_format_t *fmt,
+ FAR imgsensor_interval_t *interval)
+{
+ return 0;
+}
+
+static int goldfish_camera_start_capture(FAR struct imgsensor_s *sensor,
+ imgsensor_stream_type_t type,
+ uint8_t nr_fmt,
+ FAR imgsensor_format_t *fmt,
+ FAR imgsensor_interval_t *interval)
+{
+ return 0;
+}
+
+static int goldfish_camera_stop_capture(FAR struct imgsensor_s *sensor,
+ imgsensor_stream_type_t type)
+{
+ return 0;
+}
+
+/* Data op functions do all the real work */
+
+static int goldfish_camera_data_init(FAR struct imgdata_s *data)
+{
+ FAR goldfish_camera_priv_t *priv = (FAR goldfish_camera_priv_t *)data;
+ FAR char *argv[2];
+ char arg1[32];
+ int ret;
+
+ ret = file_open(&priv->file,
+ CONFIG_GOLDFISH_CAMERA_PIPE_PATH,
+ O_RDWR);
+ if (ret < 0)
+ {
+ verr("Failed to open: %s: %d\n",
+ CONFIG_GOLDFISH_CAMERA_PIPE_PATH, ret);
+ return ret;
+ }
+
+ nxsem_init(&priv->run, 0, 0);
+ priv->streaming = true;
+
+ ret = goldfish_camera_send(&priv->file,
+ "pipe:%s:%s:name=%s",
+ g_qemudservice,
+ g_cameraservice,
+ priv->info.name);
+ if (ret < 0)
+ {
+ goto err;
+ }
+
+ ret = goldfish_camera_send(&priv->file, "connect");
+ if (ret < 0)
+ {
+ goto err;
+ }
+
+ snprintf(arg1, sizeof(arg1), "%p", priv);
+ argv[0] = arg1;
+ argv[1] = NULL;
+
+ ret = kthread_create("goldfish_camera_thread",
+ CONFIG_GOLDFISH_CAMERA_PRIORITY,
+ CONFIG_GOLDFISH_CAMERA_STACKSIZE,
+ goldfish_camera_thread, argv);
+ if (ret < 0)
+ {
+ goto err;
+ }
+
+ priv->pid = ret;
+ return 0;
+
+err:
+ nxsem_destroy(&priv->run);
+ priv->streaming = false;
+ file_close(&priv->file);
+ return ret;
+}
+
+static int goldfish_camera_data_uninit(FAR struct imgdata_s *data)
+{
+ FAR goldfish_camera_priv_t *priv = (FAR goldfish_camera_priv_t *)data;
+ int ret;
+
+ ret = goldfish_camera_send(&priv->file, "disconnect");
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ priv->streaming = false;
+ nxsem_post(&priv->run);
+ nxsched_waitpid(priv->pid, NULL, 0, 0);
+
+ nxsem_destroy(&priv->run);
+ file_close(&priv->file);
+
+ return 0;
+}
+
+static int goldfish_camera_data_validate_buf(FAR uint8_t *addr,
+ uint32_t size)
+{
+ if (!addr || ((uintptr_t)addr & 0x1f))
+ {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int goldfish_camera_data_set_buf(FAR struct imgdata_s *data,
+ FAR uint8_t *addr,
+ uint32_t size)
+{
+ FAR goldfish_camera_priv_t *priv = (FAR goldfish_camera_priv_t *)data;
+ int ret;
+
+ ret = goldfish_camera_data_validate_buf(addr, size);
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ priv->next_buf = addr;
+ priv->buf_size = size;
+
+ nxsem_post(&priv->run);
+
+ return 0;
+}
+
+static int
+goldfish_camera_data_validate_frame_setting(FAR struct imgdata_s *data,
+ uint8_t nr_datafmt,
+ FAR imgdata_format_t *datafmt,
+ FAR imgdata_interval_t *interval)
+{
+ FAR goldfish_camera_priv_t *priv = (FAR goldfish_camera_priv_t *)data;
+ int i;
+
+ for (i = 0; i < GOLDFISH_CAMERA_SIZE_MAX_NUMBER; i++)
+ {
+ if (datafmt[IMGDATA_FMT_MAIN].width == priv->info.size[i].width &&
+ datafmt[IMGDATA_FMT_MAIN].height == priv->info.size[i].height &&
+ imgdata_fmt_to_v4l2(datafmt[IMGDATA_FMT_MAIN].pixelformat)
+ == priv->info.pix)
+ {
+ return 0;
+ }
+ }
+
+ return -ENOTSUP;
+}
+
+static int
+goldfish_camera_data_start_capture(FAR struct imgdata_s *data,
+ uint8_t nr_datafmt,
+ FAR imgdata_format_t *datafmt,
+ FAR imgdata_interval_t *interval,
+ imgdata_capture_t callback,
+ FAR void *arg)
+{
+ FAR goldfish_camera_priv_t *priv = (FAR goldfish_camera_priv_t *)data;
+ int ret;
+
+ ret = goldfish_camera_send(&priv->file,
+ "start dim=%dx%d pix=%d",
+ datafmt[IMGDATA_FMT_MAIN].width,
+ datafmt[IMGDATA_FMT_MAIN].height,
+ imgdata_fmt_to_v4l2(
+ datafmt[IMGDATA_FMT_MAIN].pixelformat));
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ priv->capture_cb = callback;
+ priv->capture_arg = arg;
+
+ return 0;
+}
+
+static int goldfish_camera_data_stop_capture(FAR struct imgdata_s *data)
+{
+ FAR goldfish_camera_priv_t *priv = (FAR goldfish_camera_priv_t *)data;
+ int ret;
+
+ ret = goldfish_camera_send(&priv->file, "stop");
+ if (ret < 0)
+ {
+ return ret;
+ }
+
+ priv->capture_cb = NULL;
+ priv->capture_arg = NULL;
+
+ return 0;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int goldfish_camera_initialize(void)
+{
+ FAR goldfish_camera_priv_t *priv[GOLDFISH_CAMERA_MAX_NUMBER];
+ FAR struct imgsensor_s *sensor;
+ char devpath[32];
+ ssize_t number;
+ ssize_t i;
+
+ number = goldfish_camera_get_list(priv, GOLDFISH_CAMERA_MAX_NUMBER);
+ if (number < 0)
+ {
+ return number;
+ }
+
+ for (i = 0; i < number; i++)
+ {
+ priv[i]->sensor.ops = &g_goldfish_camera_ops;
+ priv[i]->data.ops = &g_goldfish_camera_data_ops;
+
+ sensor = &priv[i]->sensor;
+
+ if (i == 0)
+ {
+ snprintf(devpath, sizeof(devpath), "/dev/video");
+ }
+ else
+ {
+ snprintf(devpath, sizeof(devpath), "/dev/video%zd", i);
+ }
+
+ video_register(devpath,
+ &priv[i]->data,
+ &sensor,
+ 1);
+ }
+
+ return 0;
+}
diff --git a/include/nuttx/video/goldfish_camera.h
b/include/nuttx/video/goldfish_camera.h
new file mode 100644
index 0000000000..07a538edc9
--- /dev/null
+++ b/include/nuttx/video/goldfish_camera.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ * include/nuttx/video/goldfish_camera.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 __INCLUDE_NUTTX_VIDEO_GOLDFISH_CAMERA_H
+#define __INCLUDE_NUTTX_VIDEO_GOLDFISH_CAMERA_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C"
+{
+#else
+#define EXTERN extern
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_GOLDFISH_CAMERA
+int goldfish_camera_initialize(void);
+#endif
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __INCLUDE_NUTTX_VIDEO_GOLDFISH_CAMERA_H */