You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/10/25 19:57:33 UTC
[incubator-nuttx] 01/08: drivers/video: Add get frame interval API
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/incubator-nuttx.git
commit 1332bdb9a7aa1b97b384caf79082cc8d2f540f4e
Author: SPRESENSE <41...@users.noreply.github.com>
AuthorDate: Mon Oct 24 21:00:40 2022 +0900
drivers/video: Add get frame interval API
---
drivers/video/isx012.c | 1 +
drivers/video/isx019.c | 88 +++++++++++++++++++++++++++++++++++++++++
drivers/video/video.c | 45 +++++++++++++++++++++
include/nuttx/video/imgsensor.h | 3 +-
include/nuttx/video/video.h | 6 +++
5 files changed, 142 insertions(+), 1 deletion(-)
diff --git a/drivers/video/isx012.c b/drivers/video/isx012.c
index f05f28e1fd..8564df7703 100644
--- a/drivers/video/isx012.c
+++ b/drivers/video/isx012.c
@@ -628,6 +628,7 @@ static struct imgsensor_ops_s g_isx012_ops =
isx012_validate_frame_setting, /* validate_frame_setting */
isx012_start_capture, /* start_capture */
isx012_stop_capture, /* stop_capture */
+ NULL, /* get_frame_interval */
isx012_get_supported_value, /* get_supported_value */
isx012_get_value, /* get_value */
isx012_set_value /* set_value */
diff --git a/drivers/video/isx019.c b/drivers/video/isx019.c
index f4d4c53bd2..7ef9e15393 100644
--- a/drivers/video/isx019.c
+++ b/drivers/video/isx019.c
@@ -148,6 +148,11 @@
#define BW_COLORS_SATURATION (0x00)
+/* Definition for calculation of extended frame number */
+
+#define VTIME_PER_FRAME (30518)
+#define INTERVAL_PER_FRAME (33333)
+
/****************************************************************************
* Private Types
****************************************************************************/
@@ -267,6 +272,8 @@ static int isx019_start_capture(imgsensor_stream_type_t type,
FAR imgsensor_format_t *datafmts,
FAR imgsensor_interval_t *interval);
static int isx019_stop_capture(imgsensor_stream_type_t type);
+static int isx019_get_frame_interval(imgsensor_stream_type_t type,
+ FAR imgsensor_interval_t *interval);
static int isx019_get_supported_value(uint32_t id,
FAR imgsensor_supported_value_t *value);
static int isx019_get_value(uint32_t id, uint32_t size,
@@ -294,6 +301,7 @@ static struct imgsensor_ops_s g_isx019_ops =
isx019_validate_frame_setting,
isx019_start_capture,
isx019_stop_capture,
+ isx019_get_frame_interval,
isx019_get_supported_value,
isx019_get_value,
isx019_set_value,
@@ -1607,6 +1615,86 @@ static int isx019_stop_capture(imgsensor_stream_type_t type)
return OK;
}
+static int calc_gcm(int a, int b)
+{
+ int r;
+
+ DEBUGASSERT((a != 0) && (b != 0));
+
+ while ((r = a % b) != 0)
+ {
+ a = b;
+ b = r;
+ }
+
+ return b;
+}
+
+static int isx019_get_frame_interval(imgsensor_stream_type_t type,
+ FAR imgsensor_interval_t *interval)
+{
+ uint32_t vtime = VTIME_PER_FRAME;
+ uint32_t frame = 1;
+ uint8_t fps = FPGA_FPS_1_1;
+ int decimation = 1;
+ int gcm;
+
+ if (interval == NULL)
+ {
+ return -EINVAL;
+ }
+
+ /* ISX019's base frame interval = 1/30. */
+
+ interval->denominator = 30;
+ interval->numerator = 1;
+
+ /* ISX019 has the frame extension feature, which automatically
+ * exposes longer than one frame in dark environment.
+ * The number of extended frame is calculated from V_TIME register,
+ * which has the value
+ * VTIME_PER_FRAME + INTERVAL_PER_FRAME * (frame number - 1)
+ */
+
+ isx019_i2c_read(CAT_AESOUT, V_TIME, (FAR uint8_t *)&vtime, 4);
+ frame = 1 + (vtime - VTIME_PER_FRAME) / INTERVAL_PER_FRAME;
+ interval->numerator *= frame;
+
+ /* Also, consider frame decimation by FPGA.
+ * decimation amount is gotten from FPGA register.
+ */
+
+ fpga_i2c_read(FPGA_FPS_AND_THUMBNAIL, &fps, 1);
+ switch (fps & FPGA_FPS_BITS)
+ {
+ case FPGA_FPS_1_1:
+ decimation = 1;
+ break;
+
+ case FPGA_FPS_1_2:
+ decimation = 2;
+ break;
+
+ case FPGA_FPS_1_3:
+ decimation = 3;
+ break;
+
+ default: /* FPGA_FPS_1_4 */
+ decimation = 4;
+ break;
+ }
+
+ interval->numerator *= decimation;
+
+ /* Reduce the fraction. */
+
+ gcm = calc_gcm(30, frame * decimation);
+ interval->denominator /= gcm;
+ interval->numerator /= gcm;
+
+ return OK;
+}
+
static int isx019_get_supported_value(uint32_t id,
FAR imgsensor_supported_value_t *val)
{
diff --git a/drivers/video/video.c b/drivers/video/video.c
index f82992c6e4..b7c5d03793 100644
--- a/drivers/video/video.c
+++ b/drivers/video/video.c
@@ -1630,6 +1630,46 @@ static int video_s_parm(FAR struct video_mng_s *priv,
return ret;
}
+static int video_g_parm(FAR struct video_mng_s *vmng,
+ FAR struct v4l2_streamparm *parm)
+{
+ int ret = -EINVAL;
+ FAR video_type_inf_t *type_inf;
+
+ DEBUGASSERT(vmng && g_video_sensor_ops);
+
+ type_inf = get_video_type_inf(vmng, parm->type);
+ if (type_inf == NULL)
+ {
+ return -EINVAL;
+ }
+
+ if ((type_inf->state == VIDEO_STATE_CAPTURE) &&
+ (g_video_sensor_ops->get_frame_interval != NULL))
+ {
+ /* If capture is started and lower driver has the get_frame_interval(),
+ * query lower driver.
+ */
+
+ memset(&parm->parm, 0, sizeof(parm->parm));
+
+ ret = g_video_sensor_ops->get_frame_interval
+ (parm->type,
+ (imgsensor_interval_t *)&parm->parm.capture.timeperframe);
+ }
+
+ if (ret != OK)
+ {
+ /* In no capture state or error case, return stored value. */
+
+ memcpy(&parm->parm.capture.timeperframe,
+ &type_inf->frame_interval,
+ sizeof(struct v4l2_fract));
+ }
+
+ return OK;
+}
+
static int video_streamon(FAR struct video_mng_s *vmng,
FAR enum v4l2_buf_type *type)
{
@@ -2955,6 +2995,11 @@ static int video_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
break;
+ case VIDIOC_G_PARM:
+ ret = video_g_parm(priv, (FAR struct v4l2_streamparm *)arg);
+
+ break;
+
case VIDIOC_QUERYCTRL:
ret = video_queryctrl((FAR struct v4l2_queryctrl *)arg);
diff --git a/include/nuttx/video/imgsensor.h b/include/nuttx/video/imgsensor.h
index d40aa080f5..f31eb3b55f 100644
--- a/include/nuttx/video/imgsensor.h
+++ b/include/nuttx/video/imgsensor.h
@@ -333,7 +333,8 @@ struct imgsensor_ops_s
FAR imgsensor_format_t *datafmts,
FAR imgsensor_interval_t *interval);
CODE int (*stop_capture)(imgsensor_stream_type_t type);
-
+ CODE int (*get_frame_interval)(imgsensor_stream_type_t type,
+ FAR imgsensor_interval_t *interval);
CODE int (*get_supported_value)(uint32_t id,
FAR imgsensor_supported_value_t *value);
CODE int (*get_value)(uint32_t id,
diff --git a/include/nuttx/video/video.h b/include/nuttx/video/video.h
index bf35e88d9e..b7703e7749 100644
--- a/include/nuttx/video/video.h
+++ b/include/nuttx/video/video.h
@@ -190,6 +190,12 @@ extern "C"
#define VIDIOC_G_SELECTION _VIDIOC(0x001d)
+/* Get the frame interval.
+ * Address pointing to struct v4l2_streamparm
+ */
+
+#define VIDIOC_G_PARM _VIDIOC(0x001e)
+
#define VIDEO_HSIZE_QVGA (320) /* QVGA horizontal size */
#define VIDEO_VSIZE_QVGA (240) /* QVGA vertical size */
#define VIDEO_HSIZE_VGA (640) /* VGA horizontal size */