mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-01-08 10:30:50 +00:00
[media] media: davinci: vpif_capture: fix v4l-compliance issues
This patch does the following: 1: sets initial default format during probe. 2: removes spurious messages. 3: optimize vpif_s/try_fmt_vid_out code. Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com> Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
This commit is contained in:
parent
4015bef649
commit
a4965c592e
@ -498,10 +498,28 @@ static int vpif_update_std_info(struct channel_obj *ch)
|
||||
common->width = std_info->width;
|
||||
common->fmt.fmt.pix.height = std_info->height;
|
||||
common->height = std_info->height;
|
||||
common->fmt.fmt.pix.sizeimage = common->height * common->width * 2;
|
||||
common->fmt.fmt.pix.bytesperline = std_info->width;
|
||||
vpifparams->video_params.hpitch = std_info->width;
|
||||
vpifparams->video_params.storage_mode = std_info->frm_fmt;
|
||||
|
||||
if (vid_ch->stdid)
|
||||
common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
|
||||
else
|
||||
common->fmt.fmt.pix.colorspace = V4L2_COLORSPACE_REC709;
|
||||
|
||||
if (ch->vpifparams.std_info.frm_fmt)
|
||||
common->fmt.fmt.pix.field = V4L2_FIELD_NONE;
|
||||
else
|
||||
common->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
||||
|
||||
if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
|
||||
common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
|
||||
else
|
||||
common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
|
||||
|
||||
common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -577,24 +595,6 @@ static void vpif_calculate_offsets(struct channel_obj *ch)
|
||||
ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
|
||||
}
|
||||
|
||||
/**
|
||||
* vpif_config_format: configure default frame format in the device
|
||||
* ch : ptr to channel object
|
||||
*/
|
||||
static void vpif_config_format(struct channel_obj *ch)
|
||||
{
|
||||
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
|
||||
|
||||
vpif_dbg(2, debug, "vpif_config_format\n");
|
||||
|
||||
common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
|
||||
if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
|
||||
common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
|
||||
else
|
||||
common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
|
||||
common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* vpif_get_default_field() - Get default field type based on interface
|
||||
* @vpif_params - ptr to vpif params
|
||||
@ -606,112 +606,6 @@ static inline enum v4l2_field vpif_get_default_field(
|
||||
V4L2_FIELD_INTERLACED;
|
||||
}
|
||||
|
||||
/**
|
||||
* vpif_check_format() - check given pixel format for compatibility
|
||||
* @ch - channel ptr
|
||||
* @pixfmt - Given pixel format
|
||||
* @update - update the values as per hardware requirement
|
||||
*
|
||||
* Check the application pixel format for S_FMT and update the input
|
||||
* values as per hardware limits for TRY_FMT. The default pixel and
|
||||
* field format is selected based on interface type.
|
||||
*/
|
||||
static int vpif_check_format(struct channel_obj *ch,
|
||||
struct v4l2_pix_format *pixfmt,
|
||||
int update)
|
||||
{
|
||||
struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
|
||||
struct vpif_params *vpif_params = &ch->vpifparams;
|
||||
enum v4l2_field field = pixfmt->field;
|
||||
u32 sizeimage, hpitch, vpitch;
|
||||
int ret = -EINVAL;
|
||||
|
||||
vpif_dbg(2, debug, "vpif_check_format\n");
|
||||
/**
|
||||
* first check for the pixel format. If if_type is Raw bayer,
|
||||
* only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only
|
||||
* V4L2_PIX_FMT_YUV422P is supported
|
||||
*/
|
||||
if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
|
||||
if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) {
|
||||
if (!update) {
|
||||
vpif_dbg(2, debug, "invalid pix format\n");
|
||||
goto exit;
|
||||
}
|
||||
pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
|
||||
}
|
||||
} else {
|
||||
if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) {
|
||||
if (!update) {
|
||||
vpif_dbg(2, debug, "invalid pixel format\n");
|
||||
goto exit;
|
||||
}
|
||||
pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(VPIF_VALID_FIELD(field))) {
|
||||
if (!update) {
|
||||
vpif_dbg(2, debug, "invalid field format\n");
|
||||
goto exit;
|
||||
}
|
||||
/**
|
||||
* By default use FIELD_NONE for RAW Bayer capture
|
||||
* and FIELD_INTERLACED for other interfaces
|
||||
*/
|
||||
field = vpif_get_default_field(&vpif_params->iface);
|
||||
} else if (field == V4L2_FIELD_ANY)
|
||||
/* unsupported field. Use default */
|
||||
field = vpif_get_default_field(&vpif_params->iface);
|
||||
|
||||
/* validate the hpitch */
|
||||
hpitch = pixfmt->bytesperline;
|
||||
if (hpitch < vpif_params->std_info.width) {
|
||||
if (!update) {
|
||||
vpif_dbg(2, debug, "invalid hpitch\n");
|
||||
goto exit;
|
||||
}
|
||||
hpitch = vpif_params->std_info.width;
|
||||
}
|
||||
|
||||
sizeimage = pixfmt->sizeimage;
|
||||
|
||||
vpitch = sizeimage / (hpitch * 2);
|
||||
|
||||
/* validate the vpitch */
|
||||
if (vpitch < vpif_params->std_info.height) {
|
||||
if (!update) {
|
||||
vpif_dbg(2, debug, "Invalid vpitch\n");
|
||||
goto exit;
|
||||
}
|
||||
vpitch = vpif_params->std_info.height;
|
||||
}
|
||||
|
||||
/* Check for 8 byte alignment */
|
||||
if (!ALIGN(hpitch, 8)) {
|
||||
if (!update) {
|
||||
vpif_dbg(2, debug, "invalid pitch alignment\n");
|
||||
goto exit;
|
||||
}
|
||||
/* adjust to next 8 byte boundary */
|
||||
hpitch = (((hpitch + 7) / 8) * 8);
|
||||
}
|
||||
/* if update is set, modify the bytesperline and sizeimage */
|
||||
if (update) {
|
||||
pixfmt->bytesperline = hpitch;
|
||||
pixfmt->sizeimage = hpitch * vpitch * 2;
|
||||
}
|
||||
/**
|
||||
* Image width and height is always based on current standard width and
|
||||
* height
|
||||
*/
|
||||
pixfmt->width = common->fmt.fmt.pix.width;
|
||||
pixfmt->height = common->fmt.fmt.pix.height;
|
||||
return 0;
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* vpif_config_addr() - function to configure buffer address in vpif
|
||||
* @ch - channel ptr
|
||||
@ -922,9 +816,6 @@ static int vpif_s_std(struct file *file, void *priv, v4l2_std_id std_id)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Configure the default format information */
|
||||
vpif_config_format(ch);
|
||||
|
||||
/* set standard in the sub device */
|
||||
ret = v4l2_subdev_call(ch->sd, video, s_std, std_id);
|
||||
if (ret && ret != -ENOIOCTLCMD && ret != -ENODEV) {
|
||||
@ -951,10 +842,8 @@ static int vpif_enum_input(struct file *file, void *priv,
|
||||
|
||||
chan_cfg = &config->chan_config[ch->channel_id];
|
||||
|
||||
if (input->index >= chan_cfg->input_count) {
|
||||
vpif_dbg(1, debug, "Invalid input index\n");
|
||||
if (input->index >= chan_cfg->input_count)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(input, &chan_cfg->inputs[input->index].input,
|
||||
sizeof(*input));
|
||||
@ -1043,8 +932,34 @@ static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct channel_obj *ch = video_get_drvdata(vdev);
|
||||
struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
|
||||
struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
|
||||
struct vpif_params *vpif_params = &ch->vpifparams;
|
||||
|
||||
return vpif_check_format(ch, pixfmt, 1);
|
||||
/*
|
||||
* to supress v4l-compliance warnings silently correct
|
||||
* the pixelformat
|
||||
*/
|
||||
if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
|
||||
if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8)
|
||||
pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
|
||||
} else {
|
||||
if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
|
||||
pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
|
||||
}
|
||||
|
||||
common->fmt.fmt.pix.pixelformat = pixfmt->pixelformat;
|
||||
|
||||
vpif_update_std_info(ch);
|
||||
|
||||
pixfmt->field = common->fmt.fmt.pix.field;
|
||||
pixfmt->colorspace = common->fmt.fmt.pix.colorspace;
|
||||
pixfmt->bytesperline = common->fmt.fmt.pix.width;
|
||||
pixfmt->width = common->fmt.fmt.pix.width;
|
||||
pixfmt->height = common->fmt.fmt.pix.height;
|
||||
pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height * 2;
|
||||
pixfmt->priv = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1082,20 +997,17 @@ static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
|
||||
struct video_device *vdev = video_devdata(file);
|
||||
struct channel_obj *ch = video_get_drvdata(vdev);
|
||||
struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
|
||||
struct v4l2_pix_format *pixfmt;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
vpif_dbg(2, debug, "%s\n", __func__);
|
||||
|
||||
if (vb2_is_busy(&common->buffer_queue))
|
||||
return -EBUSY;
|
||||
|
||||
pixfmt = &fmt->fmt.pix;
|
||||
/* Check for valid field format */
|
||||
ret = vpif_check_format(ch, pixfmt, 0);
|
||||
|
||||
ret = vpif_try_fmt_vid_cap(file, priv, fmt);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* store the format in the channel object */
|
||||
common->fmt = *fmt;
|
||||
return 0;
|
||||
@ -1443,6 +1355,11 @@ static int vpif_probe_complete(void)
|
||||
if (err)
|
||||
goto probe_out;
|
||||
|
||||
/* set initial format */
|
||||
ch->video.stdid = V4L2_STD_525_60;
|
||||
memset(&ch->video.dv_timings, 0, sizeof(ch->video.dv_timings));
|
||||
vpif_update_std_info(ch);
|
||||
|
||||
/* Initialize vb2 queue */
|
||||
q = &common->buffer_queue;
|
||||
q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||
|
Loading…
Reference in New Issue
Block a user