Skip to content

Commit 8f68232

Browse files
committed
Merge pull request #604 from 6by9/rpi-3.12.y-PR-140527
V4L2: Fix regression, and gstreamer workaround
2 parents a57d4fd + fd1355b commit 8f68232

File tree

1 file changed

+63
-2
lines changed

1 file changed

+63
-2
lines changed

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

Lines changed: 63 additions & 2 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
------------------------------------------------------------------*/
@@ -1382,8 +1436,10 @@ static int set_camera_parameters(struct vchiq_mmal_instance *instance,
13821436
.max_stills_h = MAX_HEIGHT,
13831437
.stills_yuv422 = 1,
13841438
.one_shot_stills = 1,
1385-
.max_preview_video_w = max_video_width,
1386-
.max_preview_video_h = max_video_height,
1439+
.max_preview_video_w = (max_video_width > 1920) ?
1440+
max_video_width : 1920,
1441+
.max_preview_video_h = (max_video_height > 1088) ?
1442+
max_video_height : 1088,
13871443
.num_preview_video_frames = 3,
13881444
.stills_capture_circular_buffer_height = 0,
13891445
.fast_preview_resume = 0,
@@ -1596,6 +1652,11 @@ static int __init bm2835_mmal_init_device(struct bm2835_mmal_dev *dev,
15961652
int ret;
15971653

15981654
*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+
}
15991660

16001661
vfd->v4l2_dev = &dev->v4l2_dev;
16011662

0 commit comments

Comments
 (0)