[media] V4L: soc-camera: add a livecrop host operation
Add an soc-camera host livecrop operation to implement live zoom. If a host driver implements it, it should take care to preserve output frame format, then live crop doesn't break streaming. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
08a31b9605
commit
aee5c2f1fc
|
@ -41,6 +41,11 @@
|
|||
#define DEFAULT_WIDTH 640
|
||||
#define DEFAULT_HEIGHT 480
|
||||
|
||||
#define is_streaming(ici, icd) \
|
||||
(((ici)->ops->init_videobuf) ? \
|
||||
(icd)->vb_vidq.streaming : \
|
||||
vb2_is_streaming(&(icd)->vb2_vidq))
|
||||
|
||||
static LIST_HEAD(hosts);
|
||||
static LIST_HEAD(devices);
|
||||
static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
|
||||
|
@ -662,7 +667,7 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
|
|||
if (icd->streamer && icd->streamer != file)
|
||||
return -EBUSY;
|
||||
|
||||
if (icd->vb_vidq.bufs[0]) {
|
||||
if (is_streaming(to_soc_camera_host(icd->dev.parent), icd)) {
|
||||
dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
@ -903,14 +908,17 @@ static int soc_camera_s_crop(struct file *file, void *fh,
|
|||
if (ret < 0) {
|
||||
dev_err(&icd->dev,
|
||||
"S_CROP denied: getting current crop failed\n");
|
||||
} else if (icd->vb_vidq.bufs[0] &&
|
||||
(a->c.width != current_crop.c.width ||
|
||||
a->c.height != current_crop.c.height)) {
|
||||
} else if ((a->c.width == current_crop.c.width &&
|
||||
a->c.height == current_crop.c.height) ||
|
||||
!is_streaming(ici, icd)) {
|
||||
/* same size or not streaming - use .set_crop() */
|
||||
ret = ici->ops->set_crop(icd, a);
|
||||
} else if (ici->ops->set_livecrop) {
|
||||
ret = ici->ops->set_livecrop(icd, a);
|
||||
} else {
|
||||
dev_err(&icd->dev,
|
||||
"S_CROP denied: queue initialised and sizes differ\n");
|
||||
ret = -EBUSY;
|
||||
} else {
|
||||
ret = ici->ops->set_crop(icd, a);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -80,6 +80,11 @@ struct soc_camera_host_ops {
|
|||
int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *);
|
||||
int (*get_crop)(struct soc_camera_device *, struct v4l2_crop *);
|
||||
int (*set_crop)(struct soc_camera_device *, struct v4l2_crop *);
|
||||
/*
|
||||
* The difference to .set_crop() is, that .set_livecrop is not allowed
|
||||
* to change the output sizes
|
||||
*/
|
||||
int (*set_livecrop)(struct soc_camera_device *, struct v4l2_crop *);
|
||||
int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *);
|
||||
int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
|
||||
void (*init_videobuf)(struct videobuf_queue *,
|
||||
|
|
Loading…
Reference in New Issue