Skip to content

Commit fd1355b

Browse files
author
Dave Stevenson
committed
V4L2: Add option to disable enum_framesizes.
Gstreamer's handling of a driver that advertises V4L2_FRMSIZE_TYPE_STEPWISE to define the supported resolutions is broken. See bug https://bugzilla.gnome.org/show_bug.cgi?id=726521 Optional parameter of gst_v4l2src_is_broken added. If non-zero, the driver claims not to support that ioctl, and gstreamer should be happy again (it guesses a set of defaults for itself). Signed-off-by: Dave Stevenson <[email protected]>
1 parent dce1730 commit fd1355b

File tree

1 file changed

+59
-0
lines changed

1 file changed

+59
-0
lines changed

drivers/media/platform/bcm2835/bcm2835-camera.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,19 @@ MODULE_PARM_DESC(max_video_width, "Threshold for video mode");
6161
module_param(max_video_height, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
6262
MODULE_PARM_DESC(max_video_height, "Threshold for video mode");
6363

64+
/* Gstreamer bug https://bugzilla.gnome.org/show_bug.cgi?id=726521
65+
* v4l2src does bad (and actually wrong) things when the vidioc_enum_framesizes
66+
* function says type V4L2_FRMSIZE_TYPE_STEPWISE, which we do by default.
67+
* It's happier if we just don't say anything at all, when it then
68+
* sets up a load of defaults that it thinks might work.
69+
* If gst_v4l2src_is_broken is non-zero, then we remove the function from
70+
* our function table list (actually switch to an alternate set, but same
71+
* result).
72+
*/
73+
int gst_v4l2src_is_broken = 0;
74+
module_param(gst_v4l2src_is_broken, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
75+
MODULE_PARM_DESC(gst_v4l2src_is_broken, "If non-zero, enable workaround for Gstreamer");
76+
6477
static struct bm2835_mmal_dev *gdev; /* global device data */
6578

6679
#define FPS_MIN 1
@@ -1352,6 +1365,47 @@ static const struct v4l2_ioctl_ops camera0_ioctl_ops = {
13521365
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
13531366
};
13541367

1368+
static const struct v4l2_ioctl_ops camera0_ioctl_ops_gstreamer = {
1369+
/* overlay */
1370+
.vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay,
1371+
.vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay,
1372+
.vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay,
1373+
.vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay,
1374+
.vidioc_overlay = vidioc_overlay,
1375+
.vidioc_g_fbuf = vidioc_g_fbuf,
1376+
1377+
/* inputs */
1378+
.vidioc_enum_input = vidioc_enum_input,
1379+
.vidioc_g_input = vidioc_g_input,
1380+
.vidioc_s_input = vidioc_s_input,
1381+
1382+
/* capture */
1383+
.vidioc_querycap = vidioc_querycap,
1384+
.vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1385+
.vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1386+
.vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1387+
.vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1388+
1389+
/* buffer management */
1390+
.vidioc_reqbufs = vb2_ioctl_reqbufs,
1391+
.vidioc_create_bufs = vb2_ioctl_create_bufs,
1392+
.vidioc_prepare_buf = vb2_ioctl_prepare_buf,
1393+
.vidioc_querybuf = vb2_ioctl_querybuf,
1394+
.vidioc_qbuf = vb2_ioctl_qbuf,
1395+
.vidioc_dqbuf = vb2_ioctl_dqbuf,
1396+
/* Remove this function ptr to fix gstreamer bug
1397+
.vidioc_enum_framesizes = vidioc_enum_framesizes, */
1398+
.vidioc_enum_frameintervals = vidioc_enum_frameintervals,
1399+
.vidioc_g_parm = vidioc_g_parm,
1400+
.vidioc_s_parm = vidioc_s_parm,
1401+
.vidioc_streamon = vb2_ioctl_streamon,
1402+
.vidioc_streamoff = vb2_ioctl_streamoff,
1403+
1404+
.vidioc_log_status = v4l2_ctrl_log_status,
1405+
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1406+
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1407+
};
1408+
13551409
/* ------------------------------------------------------------------
13561410
Driver init/finalise
13571411
------------------------------------------------------------------*/
@@ -1598,6 +1652,11 @@ static int __init bm2835_mmal_init_device(struct bm2835_mmal_dev *dev,
15981652
int ret;
15991653

16001654
*vfd = vdev_template;
1655+
if (gst_v4l2src_is_broken) {
1656+
v4l2_info(&dev->v4l2_dev,
1657+
"Work-around for gstreamer issue is active.\n");
1658+
vfd->ioctl_ops = &camera0_ioctl_ops_gstreamer;
1659+
}
16011660

16021661
vfd->v4l2_dev = &dev->v4l2_dev;
16031662

0 commit comments

Comments
 (0)