diff --git a/arch/sim/Kconfig b/arch/sim/Kconfig index 7ec46127189..1d42f1c83b6 100644 --- a/arch/sim/Kconfig +++ b/arch/sim/Kconfig @@ -283,18 +283,18 @@ endchoice endif -config SIM_VIDEO +config SIM_CAMERA bool "Simulated video support" depends on VIDEO default y -if SIM_VIDEO +if SIM_CAMERA choice prompt "Simulated video device type" - default SIM_VIDEO_V4L2 + default SIM_CAMERA_V4L2 -config SIM_VIDEO_V4L2 +config SIM_CAMERA_V4L2 bool "V4L2 camera support on sim" depends on HOST_LINUX @@ -304,7 +304,7 @@ config HOST_VIDEO_DEV_PATH string "Host video device path" default "/dev/video0" -config SIM_VIDEO_DEV_PATH +config SIM_CAMERA_DEV_PATH string "NuttX video device path" default "/dev/video" diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile index 574ecfff782..c21feae9f35 100644 --- a/arch/sim/src/Makefile +++ b/arch/sim/src/Makefile @@ -225,9 +225,9 @@ ifeq ($(CONFIG_SIM_SOUND_ALSA),y) STDLIBS += -lmp3lame endif -ifeq ($(CONFIG_SIM_VIDEO_V4L2),y) +ifeq ($(CONFIG_SIM_CAMERA_V4L2),y) HOSTSRCS += sim_host_v4l2.c - CSRCS += sim_video.c + CSRCS += sim_camera.c STDLIBS += -lv4l2 endif diff --git a/arch/sim/src/sim/posix/sim_host_v4l2.c b/arch/sim/src/sim/posix/sim_host_v4l2.c index 4094676e840..3c6b7568429 100644 --- a/arch/sim/src/sim/posix/sim_host_v4l2.c +++ b/arch/sim/src/sim/posix/sim_host_v4l2.c @@ -208,7 +208,7 @@ int host_video_start_capture(struct host_video_dev_s *vdev) } vdev->addrs[i] = mmap(NULL, buf.length, PROT_READ | PROT_WRITE, - MAP_SHARED, vdev->fd, buf.m.offset); + MAP_SHARED, vdev->fd, buf.m.offset); if (vdev->addrs[i] == MAP_FAILED) { perror("Mmap failed"); diff --git a/arch/sim/src/sim/sim_camera.c b/arch/sim/src/sim/sim_camera.c new file mode 100644 index 00000000000..5f774b1025c --- /dev/null +++ b/arch/sim/src/sim/sim_camera.c @@ -0,0 +1,355 @@ +/**************************************************************************** + * arch/sim/src/sim/sim_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 +#include +#include +#include +#include + +#include "sim_hostvideo.h" +#include "sim_internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +typedef struct +{ + struct imgdata_s data; + struct imgsensor_s sensor; + imgdata_capture_t capture_cb; + uint32_t buf_size; + uint8_t *next_buf; + struct timeval *next_ts; + struct host_video_dev_s *vdev; +} sim_camera_priv_t; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Video image sensor operations */ + +static bool sim_camera_is_available(struct imgsensor_s *sensor); +static int sim_camera_init(struct imgsensor_s *sensor); +static int sim_camera_uninit(struct imgsensor_s *sensor); +static const char *sim_camera_get_driver_name(struct imgsensor_s *sensor); +static int sim_camera_validate_frame_setting(struct imgsensor_s *sensor, + imgsensor_stream_type_t type, + uint8_t nr_datafmt, + imgsensor_format_t *datafmts, + imgsensor_interval_t *interval); +static int sim_camera_start_capture(struct imgsensor_s *sensor, + imgsensor_stream_type_t type, + uint8_t nr_datafmt, + imgsensor_format_t *datafmts, + imgsensor_interval_t *interval); +static int sim_camera_stop_capture(struct imgsensor_s *sensor, + imgsensor_stream_type_t type); + +/* Video image data operations */ + +static int sim_camera_data_init(struct imgdata_s *data); +static int sim_camera_data_uninit(struct imgdata_s *data); +static int +sim_camera_data_validate_frame_setting(struct imgdata_s *data, + uint8_t nr_datafmt, + imgdata_format_t *datafmt, + imgdata_interval_t *interv); +static int sim_camera_data_start_capture(struct imgdata_s *data, + uint8_t nr_datafmt, + imgdata_format_t *datafmt, + imgdata_interval_t *interval, + imgdata_capture_t callback); +static int sim_camera_data_stop_capture(struct imgdata_s *data); +static int sim_camera_data_set_buf(struct imgdata_s *data, + uint8_t *addr, uint32_t size); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct imgsensor_ops_s g_sim_camera_ops = +{ + .is_available = sim_camera_is_available, + .init = sim_camera_init, + .uninit = sim_camera_uninit, + .get_driver_name = sim_camera_get_driver_name, + .validate_frame_setting = sim_camera_validate_frame_setting, + .start_capture = sim_camera_start_capture, + .stop_capture = sim_camera_stop_capture, +}; + +static const struct imgdata_ops_s g_sim_camera_data_ops = +{ + .init = sim_camera_data_init, + .uninit = sim_camera_data_uninit, + .set_buf = sim_camera_data_set_buf, + .validate_frame_setting = sim_camera_data_validate_frame_setting, + .start_capture = sim_camera_data_start_capture, + .stop_capture = sim_camera_data_stop_capture, +}; + +static sim_camera_priv_t g_sim_camera_priv = +{ + .data = + { + &g_sim_camera_data_ops + }, + .sensor = + { + &g_sim_camera_ops + } +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/* Helper functions */ + +static uint32_t imgdata_fmt_to_v4l2(uint32_t pixelformat) +{ + uint32_t fourcc; + switch (pixelformat) + { + case IMGDATA_PIX_FMT_YUV420P: + fourcc = V4L2_PIX_FMT_YUV420; + break; + + case IMGDATA_PIX_FMT_YUYV: + fourcc = V4L2_PIX_FMT_YUYV; + break; + + case IMGDATA_PIX_FMT_JPEG_WITH_SUBIMG: + fourcc = V4L2_PIX_FMT_JPEG; + break; + + case IMGDATA_PIX_FMT_JPEG: + fourcc = V4L2_PIX_FMT_JPEG; + break; + + case IMGDATA_PIX_FMT_RGB565: + fourcc = V4L2_PIX_FMT_RGB565; + break; + + case IMGDATA_PIX_FMT_UYVY: + fourcc = V4L2_PIX_FMT_UYVY; + break; + + default: + + /* Unsupported format */ + + fourcc = 0; + } + + return fourcc; +} + +/* Sensor op functions are mostly dummy */ + +static bool sim_camera_is_available(struct imgsensor_s *sensor) +{ + return host_video_is_available(CONFIG_HOST_VIDEO_DEV_PATH); +} + +static int sim_camera_init(struct imgsensor_s *sensor) +{ + return 0; +} + +static int sim_camera_uninit(struct imgsensor_s *sensor) +{ + return 0; +} + +static const char *sim_camera_get_driver_name(struct imgsensor_s *sensor) +{ + return "V4L2 NuttX Sim Driver"; +} + +static int sim_camera_validate_frame_setting(struct imgsensor_s *sensor, + imgsensor_stream_type_t type, + uint8_t nr_fmt, + imgsensor_format_t *fmt, + imgsensor_interval_t *interval) +{ + return 0; +} + +static int sim_camera_start_capture(struct imgsensor_s *sensor, + imgsensor_stream_type_t type, + uint8_t nr_fmt, + imgsensor_format_t *fmt, + imgsensor_interval_t *interval) +{ + return 0; +} + +static int sim_camera_stop_capture(struct imgsensor_s *sensor, + imgsensor_stream_type_t type) +{ + return 0; +} + +/* Data op functions do all the real work */ + +static int sim_camera_data_init(struct imgdata_s *data) +{ + sim_camera_priv_t *priv = (sim_camera_priv_t *)data; + + priv->vdev = host_video_init(CONFIG_HOST_VIDEO_DEV_PATH); + if (priv->vdev == NULL) + { + return -ENODEV; + } + + return 0; +} + +static int sim_camera_data_uninit(struct imgdata_s *data) +{ + sim_camera_priv_t *priv = (sim_camera_priv_t *)data; + + return host_video_uninit(priv->vdev); +} + +static int sim_camera_data_validate_buf(uint8_t *addr, uint32_t size) +{ + if (!addr || ((uintptr_t)(addr) & 0x1f)) + { + return -EINVAL; + } + + return 0; +} + +static int sim_camera_data_set_buf(struct imgdata_s *data, + uint8_t *addr, uint32_t size) +{ + sim_camera_priv_t *priv = (sim_camera_priv_t *)data; + + if (sim_camera_data_validate_buf(addr, size) < 0) + { + return -EINVAL; + } + + priv->next_buf = addr; + priv->buf_size = size; + return 0; +} + +static int sim_camera_data_validate_frame_setting(struct imgdata_s *data, + uint8_t nr_datafmt, + imgdata_format_t *datafmt, + imgdata_interval_t *interv) +{ + sim_camera_priv_t *priv = (sim_camera_priv_t *)data; + uint32_t v4l2_fmt; + + if (nr_datafmt > 1) + { + return -ENOTSUP; + } + + v4l2_fmt = imgdata_fmt_to_v4l2(datafmt->pixelformat); + return host_video_try_fmt(priv->vdev, datafmt->width, + datafmt->height, v4l2_fmt, interv->denominator, + interv->numerator); +} + +static int sim_camera_data_start_capture(struct imgdata_s *data, + uint8_t nr_datafmt, + imgdata_format_t *datafmt, + imgdata_interval_t *interval, + imgdata_capture_t callback) +{ + sim_camera_priv_t *priv = (sim_camera_priv_t *)data; + int ret; + + ret = host_video_set_fmt(priv->vdev, + datafmt[IMGDATA_FMT_MAIN].width, + datafmt[IMGDATA_FMT_MAIN].height, + imgdata_fmt_to_v4l2( + datafmt[IMGDATA_FMT_MAIN].pixelformat), + interval->denominator, interval->numerator); + if (ret < 0 && ret != -EBUSY) + { + return ret; + } + + priv->capture_cb = callback; + return host_video_start_capture(priv->vdev); +} + +static int sim_camera_data_stop_capture(struct imgdata_s *data) +{ + sim_camera_priv_t *priv = (sim_camera_priv_t *)data; + + priv->next_buf = NULL; + return host_video_stop_capture(priv->vdev); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +int sim_camera_initialize(void) +{ + sim_camera_priv_t *priv = &g_sim_camera_priv; + + imgsensor_register(&priv->sensor); + imgdata_register(&priv->data); + return 0; +} + +int sim_camera_uninitialize(void) +{ + return 0; +} + +void sim_camera_loop(void) +{ + sim_camera_priv_t *priv = &g_sim_camera_priv; + struct timespec ts; + struct timeval tv; + int ret; + + if (priv->next_buf) + { + ret = host_video_dqbuf(priv->vdev, priv->next_buf, priv->buf_size); + if (ret > 0) + { + clock_gettime(CLOCK_MONOTONIC, &ts); + TIMESPEC_TO_TIMEVAL(&tv, &ts); + priv->capture_cb(0, ret, &tv); + } + } +} diff --git a/arch/sim/src/sim/sim_initialize.c b/arch/sim/src/sim/sim_initialize.c index 94416a787cf..a584d26da1a 100644 --- a/arch/sim/src/sim/sim_initialize.c +++ b/arch/sim/src/sim/sim_initialize.c @@ -199,8 +199,8 @@ static int sim_loop_task(int argc, char **argv) sim_audio_loop(); #endif -#ifdef CONFIG_SIM_VIDEO - sim_video_loop(); +#ifdef CONFIG_SIM_CAMERA + sim_camera_loop(); #endif #ifdef CONFIG_SIM_USB_DEV diff --git a/arch/sim/src/sim/sim_internal.h b/arch/sim/src/sim/sim_internal.h index d92285533db..b8cccd946ba 100644 --- a/arch/sim/src/sim/sim_internal.h +++ b/arch/sim/src/sim/sim_internal.h @@ -383,9 +383,9 @@ int sim_spi_uninitialize(struct spi_dev_s *dev); /* up_video.c ***************************************************************/ -#ifdef CONFIG_SIM_VIDEO -int sim_video_initialize(void); -void sim_video_loop(void); +#ifdef CONFIG_SIM_CAMERA +int sim_camera_initialize(void); +void sim_camera_loop(void); #endif /* sim_usbdev.c *************************************************************/ diff --git a/arch/sim/src/sim/sim_video.c b/arch/sim/src/sim/sim_video.c deleted file mode 100644 index 38dfea1eaf7..00000000000 --- a/arch/sim/src/sim/sim_video.c +++ /dev/null @@ -1,354 +0,0 @@ -/**************************************************************************** - * 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 -#include -#include -#include -#include - -#include "sim_hostvideo.h" -#include "sim_internal.h" - -/**************************************************************************** - * Pre-processor Definitions - ****************************************************************************/ - -/**************************************************************************** - * Private Types - ****************************************************************************/ - -typedef struct -{ - struct imgdata_s data; - struct imgsensor_s sensor; - imgdata_capture_t capture_cb; - uint32_t buf_size; - uint8_t *next_buf; - struct timeval *next_ts; - struct host_video_dev_s *vdev; -} sim_video_priv_t; - -/**************************************************************************** - * Private Function Prototypes - ****************************************************************************/ - -/* Video image sensor operations */ - -static bool sim_video_is_available(struct imgsensor_s *sensor); -static int sim_video_init(struct imgsensor_s *sensor); -static int sim_video_uninit(struct imgsensor_s *sensor); -static const char *sim_video_get_driver_name(struct imgsensor_s *sensor); -static int sim_video_validate_frame_setting(struct imgsensor_s *sensor, - imgsensor_stream_type_t type, - uint8_t nr_datafmt, - imgsensor_format_t *datafmts, - imgsensor_interval_t *interval); -static int sim_video_start_capture(struct imgsensor_s *sensor, - imgsensor_stream_type_t type, - uint8_t nr_datafmt, - imgsensor_format_t *datafmts, - imgsensor_interval_t *interval); -static int sim_video_stop_capture(struct imgsensor_s *sensor, - imgsensor_stream_type_t type); - -/* Video image data operations */ - -static int sim_video_data_init(struct imgdata_s *data); -static int sim_video_data_uninit(struct imgdata_s *data); -static int sim_video_data_validate_frame_setting(struct imgdata_s *data, - uint8_t nr_datafmt, - imgdata_format_t *datafmt, - imgdata_interval_t *interv); -static int sim_video_data_start_capture(struct imgdata_s *data, - uint8_t nr_datafmt, - imgdata_format_t *datafmt, - imgdata_interval_t *interval, - imgdata_capture_t callback); -static int sim_video_data_stop_capture(struct imgdata_s *data); -static int sim_video_data_set_buf(struct imgdata_s *data, - uint8_t *addr, uint32_t size); - -/**************************************************************************** - * 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, - .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_sim_video_priv = -{ - .data = - { - &g_sim_video_data_ops - }, - .sensor = - { - &g_sim_video_ops - } -}; - -/**************************************************************************** - * Private Functions - ****************************************************************************/ - -/* Helper functions */ - -static uint32_t imgdata_fmt_to_v4l2(uint32_t pixelformat) -{ - uint32_t fourcc; - switch (pixelformat) - { - case IMGDATA_PIX_FMT_YUV420P: - fourcc = V4L2_PIX_FMT_YUV420; - break; - - case IMGDATA_PIX_FMT_YUYV: - fourcc = V4L2_PIX_FMT_YUYV; - break; - - case IMGDATA_PIX_FMT_JPEG_WITH_SUBIMG: - fourcc = V4L2_PIX_FMT_JPEG; - break; - - case IMGDATA_PIX_FMT_JPEG: - fourcc = V4L2_PIX_FMT_JPEG; - break; - - case IMGDATA_PIX_FMT_RGB565: - fourcc = V4L2_PIX_FMT_RGB565; - break; - - case IMGDATA_PIX_FMT_UYVY: - fourcc = V4L2_PIX_FMT_UYVY; - break; - - default: - - /* Unsupported format */ - - fourcc = 0; - } - - return fourcc; -} - -/* Sensor op functions are mostly dummy */ - -static bool sim_video_is_available(struct imgsensor_s *sensor) -{ - return host_video_is_available(CONFIG_HOST_VIDEO_DEV_PATH); -} - -static int sim_video_init(struct imgsensor_s *sensor) -{ - return 0; -} - -static int sim_video_uninit(struct imgsensor_s *sensor) -{ - return 0; -} - -static const char *sim_video_get_driver_name(struct imgsensor_s *sensor) -{ - return "V4L2 NuttX Sim Driver"; -} - -static int sim_video_validate_frame_setting(struct imgsensor_s *sensor, - imgsensor_stream_type_t type, - uint8_t nr_fmt, - imgsensor_format_t *fmt, - imgsensor_interval_t *interval) -{ - return 0; -} - -static int sim_video_start_capture(struct imgsensor_s *sensor, - imgsensor_stream_type_t type, - uint8_t nr_fmt, - imgsensor_format_t *fmt, - imgsensor_interval_t *interval) -{ - return 0; -} - -static int sim_video_stop_capture(struct imgsensor_s *sensor, - imgsensor_stream_type_t type) -{ - return 0; -} - -/* Data op functions do all the real work */ - -static int sim_video_data_init(struct imgdata_s *data) -{ - sim_video_priv_t *priv = (sim_video_priv_t *)data; - - priv->vdev = host_video_init(CONFIG_HOST_VIDEO_DEV_PATH); - if (priv->vdev == NULL) - { - return -ENODEV; - } - - return 0; -} - -static int sim_video_data_uninit(struct imgdata_s *data) -{ - sim_video_priv_t *priv = (sim_video_priv_t *)data; - - return host_video_uninit(priv->vdev); -} - -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(struct imgdata_s *data, - uint8_t *addr, uint32_t size) -{ - sim_video_priv_t *priv = (sim_video_priv_t *)data; - - if (sim_video_data_validate_buf(addr, size) < 0) - { - return -EINVAL; - } - - priv->next_buf = addr; - priv->buf_size = size; - return 0; -} - -static int sim_video_data_validate_frame_setting(struct imgdata_s *data, - uint8_t nr_datafmt, - imgdata_format_t *datafmt, - imgdata_interval_t *interv) -{ - sim_video_priv_t *priv = (sim_video_priv_t *)data; - uint32_t v4l2_fmt; - - if (nr_datafmt > 1) - { - return -ENOTSUP; - } - - v4l2_fmt = imgdata_fmt_to_v4l2(datafmt->pixelformat); - return host_video_try_fmt(priv->vdev, datafmt->width, - datafmt->height, v4l2_fmt, interv->denominator, - interv->numerator); -} - -static int sim_video_data_start_capture(struct imgdata_s *data, - uint8_t nr_datafmt, - imgdata_format_t *datafmt, - imgdata_interval_t *interval, - imgdata_capture_t callback) -{ - sim_video_priv_t *priv = (sim_video_priv_t *)data; - int ret; - - ret = host_video_set_fmt(priv->vdev, - datafmt[IMGDATA_FMT_MAIN].width, - datafmt[IMGDATA_FMT_MAIN].height, - imgdata_fmt_to_v4l2( - datafmt[IMGDATA_FMT_MAIN].pixelformat), - interval->denominator, interval->numerator); - if (ret < 0 && ret != -EBUSY) - { - return ret; - } - - priv->capture_cb = callback; - return host_video_start_capture(priv->vdev); -} - -static int sim_video_data_stop_capture(struct imgdata_s *data) -{ - sim_video_priv_t *priv = (sim_video_priv_t *)data; - - priv->next_buf = NULL; - return host_video_stop_capture(priv->vdev); -} - -/**************************************************************************** - * Public Functions - ****************************************************************************/ - -int sim_video_initialize(void) -{ - sim_video_priv_t *priv = &g_sim_video_priv; - - imgsensor_register(&priv->sensor); - imgdata_register(&priv->data); - return 0; -} - -int sim_video_uninitialize(void) -{ - return 0; -} - -void sim_video_loop(void) -{ - sim_video_priv_t *priv = &g_sim_video_priv; - struct timespec ts; - struct timeval tv; - int ret; - - if (priv->next_buf) - { - ret = host_video_dqbuf(priv->vdev, priv->next_buf, priv->buf_size); - if (ret > 0) - { - clock_gettime(CLOCK_MONOTONIC, &ts); - TIMESPEC_TO_TIMEVAL(&tv, &ts); - priv->capture_cb(0, ret, &tv); - } - } -} diff --git a/boards/sim/sim/sim/src/sim_bringup.c b/boards/sim/sim/sim/src/sim_bringup.c index 7667e2237f8..a4b783258d0 100644 --- a/boards/sim/sim/sim/src/sim_bringup.c +++ b/boards/sim/sim/sim/src/sim_bringup.c @@ -294,16 +294,16 @@ int sim_bringup(void) } #endif -#ifdef CONFIG_SIM_VIDEO +#ifdef CONFIG_SIM_CAMERA /* Initialize and register the simulated video driver */ - ret = video_initialize(CONFIG_SIM_VIDEO_DEV_PATH); + ret = video_initialize(CONFIG_SIM_CAMERA_DEV_PATH); if (ret < 0) { syslog(LOG_ERR, "ERROR: video_initialize() failed: %d\n", ret); } - sim_video_initialize(); + sim_camera_initialize(); #endif #ifdef CONFIG_LCD