drivers/video: Add get frame interval API

This commit is contained in:
SPRESENSE 2022-10-24 21:00:40 +09:00 committed by Xiang Xiao
parent 8684814e09
commit 1332bdb9a7
5 changed files with 142 additions and 1 deletions

View File

@ -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 */

View File

@ -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)
{

View File

@ -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);

View File

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

View File

@ -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 */