mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-26 14:14:01 +08:00
media: staging/imx: Remove capture_device_set_format
Don't propagate the source pad format to the connected capture device. It's now the responsibility of userspace to call VIDIOC_S_FMT on the capture device to ensure the capture format and compose rectangle are compatible with the connected source. To check this, validate the capture format with the source before streaming starts. Signed-off-by: Steve Longerbeam <slongerbeam@gmail.com> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
225dc4909f
commit
523759c7bf
@ -902,9 +902,7 @@ static int prp_set_fmt(struct v4l2_subdev *sd,
|
|||||||
struct v4l2_subdev_format *sdformat)
|
struct v4l2_subdev_format *sdformat)
|
||||||
{
|
{
|
||||||
struct prp_priv *priv = sd_to_priv(sd);
|
struct prp_priv *priv = sd_to_priv(sd);
|
||||||
struct imx_media_video_dev *vdev = priv->vdev;
|
|
||||||
const struct imx_media_pixfmt *cc;
|
const struct imx_media_pixfmt *cc;
|
||||||
struct v4l2_pix_format vdev_fmt;
|
|
||||||
struct v4l2_mbus_framefmt *fmt;
|
struct v4l2_mbus_framefmt *fmt;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -941,19 +939,9 @@ static int prp_set_fmt(struct v4l2_subdev *sd,
|
|||||||
priv->cc[PRPENCVF_SRC_PAD] = outcc;
|
priv->cc[PRPENCVF_SRC_PAD] = outcc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY)
|
if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
|
||||||
goto out;
|
priv->cc[sdformat->pad] = cc;
|
||||||
|
|
||||||
priv->cc[sdformat->pad] = cc;
|
|
||||||
|
|
||||||
/* propagate output pad format to capture device */
|
|
||||||
imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt,
|
|
||||||
&priv->format_mbus[PRPENCVF_SRC_PAD],
|
|
||||||
priv->cc[PRPENCVF_SRC_PAD]);
|
|
||||||
mutex_unlock(&priv->lock);
|
|
||||||
imx_media_capture_device_set_format(vdev, &vdev_fmt);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&priv->lock);
|
mutex_unlock(&priv->lock);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -201,7 +201,9 @@ static int capture_g_fmt_vid_cap(struct file *file, void *fh,
|
|||||||
|
|
||||||
static int __capture_try_fmt_vid_cap(struct capture_priv *priv,
|
static int __capture_try_fmt_vid_cap(struct capture_priv *priv,
|
||||||
struct v4l2_subdev_format *fmt_src,
|
struct v4l2_subdev_format *fmt_src,
|
||||||
struct v4l2_format *f)
|
struct v4l2_format *f,
|
||||||
|
const struct imx_media_pixfmt **retcc,
|
||||||
|
struct v4l2_rect *compose)
|
||||||
{
|
{
|
||||||
const struct imx_media_pixfmt *cc, *cc_src;
|
const struct imx_media_pixfmt *cc, *cc_src;
|
||||||
|
|
||||||
@ -243,6 +245,16 @@ static int __capture_try_fmt_vid_cap(struct capture_priv *priv,
|
|||||||
|
|
||||||
imx_media_mbus_fmt_to_pix_fmt(&f->fmt.pix, &fmt_src->format, cc);
|
imx_media_mbus_fmt_to_pix_fmt(&f->fmt.pix, &fmt_src->format, cc);
|
||||||
|
|
||||||
|
if (retcc)
|
||||||
|
*retcc = cc;
|
||||||
|
|
||||||
|
if (compose) {
|
||||||
|
compose->left = 0;
|
||||||
|
compose->top = 0;
|
||||||
|
compose->width = fmt_src->format.width;
|
||||||
|
compose->height = fmt_src->format.height;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +271,7 @@ static int capture_try_fmt_vid_cap(struct file *file, void *fh,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
return __capture_try_fmt_vid_cap(priv, &fmt_src, f);
|
return __capture_try_fmt_vid_cap(priv, &fmt_src, f, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int capture_s_fmt_vid_cap(struct file *file, void *fh,
|
static int capture_s_fmt_vid_cap(struct file *file, void *fh,
|
||||||
@ -280,17 +292,12 @@ static int capture_s_fmt_vid_cap(struct file *file, void *fh,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = __capture_try_fmt_vid_cap(priv, &fmt_src, f);
|
ret = __capture_try_fmt_vid_cap(priv, &fmt_src, f, &priv->vdev.cc,
|
||||||
|
&priv->vdev.compose);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
priv->vdev.fmt.fmt.pix = f->fmt.pix;
|
priv->vdev.fmt.fmt.pix = f->fmt.pix;
|
||||||
priv->vdev.cc = imx_media_find_format(f->fmt.pix.pixelformat,
|
|
||||||
CS_SEL_ANY, true);
|
|
||||||
priv->vdev.compose.left = 0;
|
|
||||||
priv->vdev.compose.top = 0;
|
|
||||||
priv->vdev.compose.width = fmt_src.format.width;
|
|
||||||
priv->vdev.compose.height = fmt_src.format.height;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -520,6 +527,33 @@ static void capture_buf_queue(struct vb2_buffer *vb)
|
|||||||
spin_unlock_irqrestore(&priv->q_lock, flags);
|
spin_unlock_irqrestore(&priv->q_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int capture_validate_fmt(struct capture_priv *priv)
|
||||||
|
{
|
||||||
|
struct v4l2_subdev_format fmt_src;
|
||||||
|
const struct imx_media_pixfmt *cc;
|
||||||
|
struct v4l2_rect compose;
|
||||||
|
struct v4l2_format f;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
fmt_src.pad = priv->src_sd_pad;
|
||||||
|
fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
|
||||||
|
ret = v4l2_subdev_call(priv->src_sd, pad, get_fmt, NULL, &fmt_src);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
v4l2_fill_pix_format(&f.fmt.pix, &fmt_src.format);
|
||||||
|
|
||||||
|
ret = __capture_try_fmt_vid_cap(priv, &fmt_src, &f, &cc, &compose);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return (priv->vdev.fmt.fmt.pix.width != f.fmt.pix.width ||
|
||||||
|
priv->vdev.fmt.fmt.pix.height != f.fmt.pix.height ||
|
||||||
|
priv->vdev.cc->cs != cc->cs ||
|
||||||
|
priv->vdev.compose.width != compose.width ||
|
||||||
|
priv->vdev.compose.height != compose.height) ? -EINVAL : 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
|
static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
|
||||||
{
|
{
|
||||||
struct capture_priv *priv = vb2_get_drv_priv(vq);
|
struct capture_priv *priv = vb2_get_drv_priv(vq);
|
||||||
@ -527,6 +561,12 @@ static int capture_start_streaming(struct vb2_queue *vq, unsigned int count)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ret = capture_validate_fmt(priv);
|
||||||
|
if (ret) {
|
||||||
|
v4l2_err(priv->src_sd, "capture format not valid\n");
|
||||||
|
goto return_bufs;
|
||||||
|
}
|
||||||
|
|
||||||
ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity,
|
ret = imx_media_pipeline_set_stream(priv->md, &priv->src_sd->entity,
|
||||||
true);
|
true);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
@ -648,19 +688,6 @@ static struct video_device capture_videodev = {
|
|||||||
.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING,
|
.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING,
|
||||||
};
|
};
|
||||||
|
|
||||||
void imx_media_capture_device_set_format(struct imx_media_video_dev *vdev,
|
|
||||||
struct v4l2_pix_format *pix)
|
|
||||||
{
|
|
||||||
struct capture_priv *priv = to_capture_priv(vdev);
|
|
||||||
|
|
||||||
mutex_lock(&priv->mutex);
|
|
||||||
priv->vdev.fmt.fmt.pix = *pix;
|
|
||||||
priv->vdev.cc = imx_media_find_format(pix->pixelformat, CS_SEL_ANY,
|
|
||||||
true);
|
|
||||||
mutex_unlock(&priv->mutex);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(imx_media_capture_device_set_format);
|
|
||||||
|
|
||||||
struct imx_media_buffer *
|
struct imx_media_buffer *
|
||||||
imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev)
|
imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev)
|
||||||
{
|
{
|
||||||
|
@ -1502,10 +1502,8 @@ static int csi_set_fmt(struct v4l2_subdev *sd,
|
|||||||
struct v4l2_subdev_format *sdformat)
|
struct v4l2_subdev_format *sdformat)
|
||||||
{
|
{
|
||||||
struct csi_priv *priv = v4l2_get_subdevdata(sd);
|
struct csi_priv *priv = v4l2_get_subdevdata(sd);
|
||||||
struct imx_media_video_dev *vdev = priv->vdev;
|
|
||||||
struct v4l2_fwnode_endpoint upstream_ep = { .bus_type = 0 };
|
struct v4l2_fwnode_endpoint upstream_ep = { .bus_type = 0 };
|
||||||
const struct imx_media_pixfmt *cc;
|
const struct imx_media_pixfmt *cc;
|
||||||
struct v4l2_pix_format vdev_fmt;
|
|
||||||
struct v4l2_mbus_framefmt *fmt;
|
struct v4l2_mbus_framefmt *fmt;
|
||||||
struct v4l2_rect *crop, *compose;
|
struct v4l2_rect *crop, *compose;
|
||||||
int ret;
|
int ret;
|
||||||
@ -1557,19 +1555,9 @@ static int csi_set_fmt(struct v4l2_subdev *sd,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY)
|
if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
|
||||||
goto out;
|
priv->cc[sdformat->pad] = cc;
|
||||||
|
|
||||||
priv->cc[sdformat->pad] = cc;
|
|
||||||
|
|
||||||
/* propagate IDMAC output pad format to capture device */
|
|
||||||
imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt,
|
|
||||||
&priv->format_mbus[CSI_SRC_PAD_IDMAC],
|
|
||||||
priv->cc[CSI_SRC_PAD_IDMAC]);
|
|
||||||
mutex_unlock(&priv->lock);
|
|
||||||
imx_media_capture_device_set_format(vdev, &vdev_fmt);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
out:
|
out:
|
||||||
mutex_unlock(&priv->lock);
|
mutex_unlock(&priv->lock);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -274,8 +274,6 @@ int imx_media_capture_device_register(struct imx_media_video_dev *vdev);
|
|||||||
void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev);
|
void imx_media_capture_device_unregister(struct imx_media_video_dev *vdev);
|
||||||
struct imx_media_buffer *
|
struct imx_media_buffer *
|
||||||
imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev);
|
imx_media_capture_device_next_buf(struct imx_media_video_dev *vdev);
|
||||||
void imx_media_capture_device_set_format(struct imx_media_video_dev *vdev,
|
|
||||||
struct v4l2_pix_format *pix);
|
|
||||||
void imx_media_capture_device_error(struct imx_media_video_dev *vdev);
|
void imx_media_capture_device_error(struct imx_media_video_dev *vdev);
|
||||||
|
|
||||||
/* subdev group ids */
|
/* subdev group ids */
|
||||||
|
@ -1031,10 +1031,8 @@ static int imx7_csi_set_fmt(struct v4l2_subdev *sd,
|
|||||||
struct v4l2_subdev_format *sdformat)
|
struct v4l2_subdev_format *sdformat)
|
||||||
{
|
{
|
||||||
struct imx7_csi *csi = v4l2_get_subdevdata(sd);
|
struct imx7_csi *csi = v4l2_get_subdevdata(sd);
|
||||||
struct imx_media_video_dev *vdev = csi->vdev;
|
|
||||||
const struct imx_media_pixfmt *outcc;
|
const struct imx_media_pixfmt *outcc;
|
||||||
struct v4l2_mbus_framefmt *outfmt;
|
struct v4l2_mbus_framefmt *outfmt;
|
||||||
struct v4l2_pix_format vdev_fmt;
|
|
||||||
const struct imx_media_pixfmt *cc;
|
const struct imx_media_pixfmt *cc;
|
||||||
struct v4l2_mbus_framefmt *fmt;
|
struct v4l2_mbus_framefmt *fmt;
|
||||||
struct v4l2_subdev_format format;
|
struct v4l2_subdev_format format;
|
||||||
@ -1079,19 +1077,8 @@ static int imx7_csi_set_fmt(struct v4l2_subdev *sd,
|
|||||||
csi->cc[IMX7_CSI_PAD_SRC] = outcc;
|
csi->cc[IMX7_CSI_PAD_SRC] = outcc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdformat->which == V4L2_SUBDEV_FORMAT_TRY)
|
if (sdformat->which == V4L2_SUBDEV_FORMAT_ACTIVE)
|
||||||
goto out_unlock;
|
csi->cc[sdformat->pad] = cc;
|
||||||
|
|
||||||
csi->cc[sdformat->pad] = cc;
|
|
||||||
|
|
||||||
/* propagate output pad format to capture device */
|
|
||||||
imx_media_mbus_fmt_to_pix_fmt(&vdev_fmt,
|
|
||||||
&csi->format_mbus[IMX7_CSI_PAD_SRC],
|
|
||||||
csi->cc[IMX7_CSI_PAD_SRC]);
|
|
||||||
mutex_unlock(&csi->lock);
|
|
||||||
imx_media_capture_device_set_format(vdev, &vdev_fmt);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
out_unlock:
|
out_unlock:
|
||||||
mutex_unlock(&csi->lock);
|
mutex_unlock(&csi->lock);
|
||||||
|
Loading…
Reference in New Issue
Block a user