1 // SPDX-License-Identifier: GPL-2.0-only
3 * vivid-vid-cap.c - video capture support functions.
5 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
8 #include <linux/errno.h>
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/vmalloc.h>
12 #include <linux/videodev2.h>
13 #include <linux/v4l2-dv-timings.h>
14 #include <media/v4l2-common.h>
15 #include <media/v4l2-event.h>
16 #include <media/v4l2-dv-timings.h>
17 #include <media/v4l2-rect.h>
19 #include "vivid-core.h"
20 #include "vivid-vid-common.h"
21 #include "vivid-kthread-cap.h"
22 #include "vivid-vid-cap.h"
24 static const struct vivid_fmt formats_ovl
[] = {
26 .fourcc
= V4L2_PIX_FMT_RGB565
, /* gggbbbbb rrrrrggg */
27 .vdownsampling
= { 1 },
33 .fourcc
= V4L2_PIX_FMT_XRGB555
, /* gggbbbbb arrrrrgg */
34 .vdownsampling
= { 1 },
40 .fourcc
= V4L2_PIX_FMT_ARGB555
, /* gggbbbbb arrrrrgg */
41 .vdownsampling
= { 1 },
48 /* The number of discrete webcam framesizes */
49 #define VIVID_WEBCAM_SIZES 6
50 /* The number of discrete webcam frameintervals */
51 #define VIVID_WEBCAM_IVALS (VIVID_WEBCAM_SIZES * 2)
53 /* Sizes must be in increasing order */
54 static const struct v4l2_frmsize_discrete webcam_sizes
[VIVID_WEBCAM_SIZES
] = {
64 * Intervals must be in increasing order and there must be twice as many
65 * elements in this array as there are in webcam_sizes.
67 static const struct v4l2_fract webcam_intervals
[VIVID_WEBCAM_IVALS
] = {
82 static int vid_cap_queue_setup(struct vb2_queue
*vq
,
83 unsigned *nbuffers
, unsigned *nplanes
,
84 unsigned sizes
[], struct device
*alloc_devs
[])
86 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
87 unsigned buffers
= tpg_g_buffers(&dev
->tpg
);
88 unsigned h
= dev
->fmt_cap_rect
.height
;
91 if (dev
->field_cap
== V4L2_FIELD_ALTERNATE
) {
93 * You cannot use read() with FIELD_ALTERNATE since the field
94 * information (TOP/BOTTOM) cannot be passed back to the user.
96 if (vb2_fileio_is_active(vq
))
100 if (dev
->queue_setup_error
) {
102 * Error injection: test what happens if queue_setup() returns
105 dev
->queue_setup_error
= false;
110 * Check if the number of requested planes match
111 * the number of buffers in the current format. You can't mix that.
113 if (*nplanes
!= buffers
)
115 for (p
= 0; p
< buffers
; p
++) {
116 if (sizes
[p
] < tpg_g_line_width(&dev
->tpg
, p
) * h
+
117 dev
->fmt_cap
->data_offset
[p
])
121 for (p
= 0; p
< buffers
; p
++)
122 sizes
[p
] = (tpg_g_line_width(&dev
->tpg
, p
) * h
) /
123 dev
->fmt_cap
->vdownsampling
[p
] +
124 dev
->fmt_cap
->data_offset
[p
];
127 if (vq
->num_buffers
+ *nbuffers
< 2)
128 *nbuffers
= 2 - vq
->num_buffers
;
132 dprintk(dev
, 1, "%s: count=%d\n", __func__
, *nbuffers
);
133 for (p
= 0; p
< buffers
; p
++)
134 dprintk(dev
, 1, "%s: size[%u]=%u\n", __func__
, p
, sizes
[p
]);
139 static int vid_cap_buf_prepare(struct vb2_buffer
*vb
)
141 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
143 unsigned buffers
= tpg_g_buffers(&dev
->tpg
);
146 dprintk(dev
, 1, "%s\n", __func__
);
148 if (WARN_ON(NULL
== dev
->fmt_cap
))
151 if (dev
->buf_prepare_error
) {
153 * Error injection: test what happens if buf_prepare() returns
156 dev
->buf_prepare_error
= false;
159 for (p
= 0; p
< buffers
; p
++) {
160 size
= (tpg_g_line_width(&dev
->tpg
, p
) *
161 dev
->fmt_cap_rect
.height
) /
162 dev
->fmt_cap
->vdownsampling
[p
] +
163 dev
->fmt_cap
->data_offset
[p
];
165 if (vb2_plane_size(vb
, p
) < size
) {
166 dprintk(dev
, 1, "%s data will not fit into plane %u (%lu < %lu)\n",
167 __func__
, p
, vb2_plane_size(vb
, p
), size
);
171 vb2_set_plane_payload(vb
, p
, size
);
172 vb
->planes
[p
].data_offset
= dev
->fmt_cap
->data_offset
[p
];
178 static void vid_cap_buf_finish(struct vb2_buffer
*vb
)
180 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
181 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
182 struct v4l2_timecode
*tc
= &vbuf
->timecode
;
184 unsigned seq
= vbuf
->sequence
;
186 if (!vivid_is_sdtv_cap(dev
))
190 * Set the timecode. Rarely used, so it is interesting to
193 vbuf
->flags
|= V4L2_BUF_FLAG_TIMECODE
;
194 if (dev
->std_cap
[dev
->input
] & V4L2_STD_525_60
)
196 tc
->type
= (fps
== 30) ? V4L2_TC_TYPE_30FPS
: V4L2_TC_TYPE_25FPS
;
198 tc
->frames
= seq
% fps
;
199 tc
->seconds
= (seq
/ fps
) % 60;
200 tc
->minutes
= (seq
/ (60 * fps
)) % 60;
201 tc
->hours
= (seq
/ (60 * 60 * fps
)) % 24;
204 static void vid_cap_buf_queue(struct vb2_buffer
*vb
)
206 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
207 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
208 struct vivid_buffer
*buf
= container_of(vbuf
, struct vivid_buffer
, vb
);
210 dprintk(dev
, 1, "%s\n", __func__
);
212 spin_lock(&dev
->slock
);
213 list_add_tail(&buf
->list
, &dev
->vid_cap_active
);
214 spin_unlock(&dev
->slock
);
217 static int vid_cap_start_streaming(struct vb2_queue
*vq
, unsigned count
)
219 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
223 if (vb2_is_streaming(&dev
->vb_vid_out_q
))
224 dev
->can_loop_video
= vivid_vid_can_loop(dev
);
226 dev
->vid_cap_seq_count
= 0;
227 dprintk(dev
, 1, "%s\n", __func__
);
228 for (i
= 0; i
< VIDEO_MAX_FRAME
; i
++)
229 dev
->must_blank
[i
] = tpg_g_perc_fill(&dev
->tpg
) < 100;
230 if (dev
->start_streaming_error
) {
231 dev
->start_streaming_error
= false;
234 err
= vivid_start_generating_vid_cap(dev
, &dev
->vid_cap_streaming
);
237 struct vivid_buffer
*buf
, *tmp
;
239 list_for_each_entry_safe(buf
, tmp
, &dev
->vid_cap_active
, list
) {
240 list_del(&buf
->list
);
241 vb2_buffer_done(&buf
->vb
.vb2_buf
,
242 VB2_BUF_STATE_QUEUED
);
248 /* abort streaming and wait for last buffer */
249 static void vid_cap_stop_streaming(struct vb2_queue
*vq
)
251 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
253 dprintk(dev
, 1, "%s\n", __func__
);
254 vivid_stop_generating_vid_cap(dev
, &dev
->vid_cap_streaming
);
255 dev
->can_loop_video
= false;
258 static void vid_cap_buf_request_complete(struct vb2_buffer
*vb
)
260 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
262 v4l2_ctrl_request_complete(vb
->req_obj
.req
, &dev
->ctrl_hdl_vid_cap
);
265 const struct vb2_ops vivid_vid_cap_qops
= {
266 .queue_setup
= vid_cap_queue_setup
,
267 .buf_prepare
= vid_cap_buf_prepare
,
268 .buf_finish
= vid_cap_buf_finish
,
269 .buf_queue
= vid_cap_buf_queue
,
270 .start_streaming
= vid_cap_start_streaming
,
271 .stop_streaming
= vid_cap_stop_streaming
,
272 .buf_request_complete
= vid_cap_buf_request_complete
,
273 .wait_prepare
= vb2_ops_wait_prepare
,
274 .wait_finish
= vb2_ops_wait_finish
,
278 * Determine the 'picture' quality based on the current TV frequency: either
279 * COLOR for a good 'signal', GRAY (grayscale picture) for a slightly off
280 * signal or NOISE for no signal.
282 void vivid_update_quality(struct vivid_dev
*dev
)
284 unsigned freq_modulus
;
286 if (dev
->loop_video
&& (vivid_is_svid_cap(dev
) || vivid_is_hdmi_cap(dev
))) {
288 * The 'noise' will only be replaced by the actual video
289 * if the output video matches the input video settings.
291 tpg_s_quality(&dev
->tpg
, TPG_QUAL_NOISE
, 0);
294 if (vivid_is_hdmi_cap(dev
) &&
295 VIVID_INVALID_SIGNAL(dev
->dv_timings_signal_mode
[dev
->input
])) {
296 tpg_s_quality(&dev
->tpg
, TPG_QUAL_NOISE
, 0);
299 if (vivid_is_sdtv_cap(dev
) &&
300 VIVID_INVALID_SIGNAL(dev
->std_signal_mode
[dev
->input
])) {
301 tpg_s_quality(&dev
->tpg
, TPG_QUAL_NOISE
, 0);
304 if (!vivid_is_tv_cap(dev
)) {
305 tpg_s_quality(&dev
->tpg
, TPG_QUAL_COLOR
, 0);
310 * There is a fake channel every 6 MHz at 49.25, 55.25, etc.
311 * From +/- 0.25 MHz around the channel there is color, and from
312 * +/- 1 MHz there is grayscale (chroma is lost).
313 * Everywhere else it is just noise.
315 freq_modulus
= (dev
->tv_freq
- 676 /* (43.25-1) * 16 */) % (6 * 16);
316 if (freq_modulus
> 2 * 16) {
317 tpg_s_quality(&dev
->tpg
, TPG_QUAL_NOISE
,
318 next_pseudo_random32(dev
->tv_freq
^ 0x55) & 0x3f);
321 if (freq_modulus
< 12 /*0.75 * 16*/ || freq_modulus
> 20 /*1.25 * 16*/)
322 tpg_s_quality(&dev
->tpg
, TPG_QUAL_GRAY
, 0);
324 tpg_s_quality(&dev
->tpg
, TPG_QUAL_COLOR
, 0);
328 * Get the current picture quality and the associated afc value.
330 static enum tpg_quality
vivid_get_quality(struct vivid_dev
*dev
, s32
*afc
)
332 unsigned freq_modulus
;
336 if (tpg_g_quality(&dev
->tpg
) == TPG_QUAL_COLOR
||
337 tpg_g_quality(&dev
->tpg
) == TPG_QUAL_NOISE
)
338 return tpg_g_quality(&dev
->tpg
);
341 * There is a fake channel every 6 MHz at 49.25, 55.25, etc.
342 * From +/- 0.25 MHz around the channel there is color, and from
343 * +/- 1 MHz there is grayscale (chroma is lost).
344 * Everywhere else it is just gray.
346 freq_modulus
= (dev
->tv_freq
- 676 /* (43.25-1) * 16 */) % (6 * 16);
348 *afc
= freq_modulus
- 1 * 16;
349 return TPG_QUAL_GRAY
;
352 enum tpg_video_aspect
vivid_get_video_aspect(const struct vivid_dev
*dev
)
354 if (vivid_is_sdtv_cap(dev
))
355 return dev
->std_aspect_ratio
[dev
->input
];
357 if (vivid_is_hdmi_cap(dev
))
358 return dev
->dv_timings_aspect_ratio
[dev
->input
];
360 return TPG_VIDEO_ASPECT_IMAGE
;
363 static enum tpg_pixel_aspect
vivid_get_pixel_aspect(const struct vivid_dev
*dev
)
365 if (vivid_is_sdtv_cap(dev
))
366 return (dev
->std_cap
[dev
->input
] & V4L2_STD_525_60
) ?
367 TPG_PIXEL_ASPECT_NTSC
: TPG_PIXEL_ASPECT_PAL
;
369 if (vivid_is_hdmi_cap(dev
) &&
370 dev
->src_rect
.width
== 720 && dev
->src_rect
.height
<= 576)
371 return dev
->src_rect
.height
== 480 ?
372 TPG_PIXEL_ASPECT_NTSC
: TPG_PIXEL_ASPECT_PAL
;
374 return TPG_PIXEL_ASPECT_SQUARE
;
378 * Called whenever the format has to be reset which can occur when
379 * changing inputs, standard, timings, etc.
381 void vivid_update_format_cap(struct vivid_dev
*dev
, bool keep_controls
)
383 struct v4l2_bt_timings
*bt
= &dev
->dv_timings_cap
[dev
->input
].bt
;
387 switch (dev
->input_type
[dev
->input
]) {
390 dev
->src_rect
.width
= webcam_sizes
[dev
->webcam_size_idx
].width
;
391 dev
->src_rect
.height
= webcam_sizes
[dev
->webcam_size_idx
].height
;
392 dev
->timeperframe_vid_cap
= webcam_intervals
[dev
->webcam_ival_idx
];
393 dev
->field_cap
= V4L2_FIELD_NONE
;
394 tpg_s_rgb_range(&dev
->tpg
, V4L2_DV_RGB_RANGE_AUTO
);
398 dev
->field_cap
= dev
->tv_field_cap
;
399 dev
->src_rect
.width
= 720;
400 if (dev
->std_cap
[dev
->input
] & V4L2_STD_525_60
) {
401 dev
->src_rect
.height
= 480;
402 dev
->timeperframe_vid_cap
= (struct v4l2_fract
) { 1001, 30000 };
403 dev
->service_set_cap
= V4L2_SLICED_CAPTION_525
;
405 dev
->src_rect
.height
= 576;
406 dev
->timeperframe_vid_cap
= (struct v4l2_fract
) { 1000, 25000 };
407 dev
->service_set_cap
= V4L2_SLICED_WSS_625
| V4L2_SLICED_TELETEXT_B
;
409 tpg_s_rgb_range(&dev
->tpg
, V4L2_DV_RGB_RANGE_AUTO
);
412 dev
->src_rect
.width
= bt
->width
;
413 dev
->src_rect
.height
= bt
->height
;
414 size
= V4L2_DV_BT_FRAME_WIDTH(bt
) * V4L2_DV_BT_FRAME_HEIGHT(bt
);
415 if (dev
->reduced_fps
&& can_reduce_fps(bt
)) {
416 pixelclock
= div_u64(bt
->pixelclock
* 1000, 1001);
417 bt
->flags
|= V4L2_DV_FL_REDUCED_FPS
;
419 pixelclock
= bt
->pixelclock
;
420 bt
->flags
&= ~V4L2_DV_FL_REDUCED_FPS
;
422 dev
->timeperframe_vid_cap
= (struct v4l2_fract
) {
423 size
/ 100, (u32
)pixelclock
/ 100
426 dev
->field_cap
= V4L2_FIELD_ALTERNATE
;
428 dev
->field_cap
= V4L2_FIELD_NONE
;
431 * We can be called from within s_ctrl, in that case we can't
432 * set/get controls. Luckily we don't need to in that case.
434 if (keep_controls
|| !dev
->colorspace
)
436 if (bt
->flags
& V4L2_DV_FL_IS_CE_VIDEO
) {
437 if (bt
->width
== 720 && bt
->height
<= 576)
438 v4l2_ctrl_s_ctrl(dev
->colorspace
, VIVID_CS_170M
);
440 v4l2_ctrl_s_ctrl(dev
->colorspace
, VIVID_CS_709
);
441 v4l2_ctrl_s_ctrl(dev
->real_rgb_range_cap
, 1);
443 v4l2_ctrl_s_ctrl(dev
->colorspace
, VIVID_CS_SRGB
);
444 v4l2_ctrl_s_ctrl(dev
->real_rgb_range_cap
, 0);
446 tpg_s_rgb_range(&dev
->tpg
, v4l2_ctrl_g_ctrl(dev
->rgb_range_cap
));
449 vfree(dev
->bitmap_cap
);
450 dev
->bitmap_cap
= NULL
;
451 vivid_update_quality(dev
);
452 tpg_reset_source(&dev
->tpg
, dev
->src_rect
.width
, dev
->src_rect
.height
, dev
->field_cap
);
453 dev
->crop_cap
= dev
->src_rect
;
454 dev
->crop_bounds_cap
= dev
->src_rect
;
455 dev
->compose_cap
= dev
->crop_cap
;
456 if (V4L2_FIELD_HAS_T_OR_B(dev
->field_cap
))
457 dev
->compose_cap
.height
/= 2;
458 dev
->fmt_cap_rect
= dev
->compose_cap
;
459 tpg_s_video_aspect(&dev
->tpg
, vivid_get_video_aspect(dev
));
460 tpg_s_pixel_aspect(&dev
->tpg
, vivid_get_pixel_aspect(dev
));
461 tpg_update_mv_step(&dev
->tpg
);
464 /* Map the field to something that is valid for the current input */
465 static enum v4l2_field
vivid_field_cap(struct vivid_dev
*dev
, enum v4l2_field field
)
467 if (vivid_is_sdtv_cap(dev
)) {
469 case V4L2_FIELD_INTERLACED_TB
:
470 case V4L2_FIELD_INTERLACED_BT
:
471 case V4L2_FIELD_SEQ_TB
:
472 case V4L2_FIELD_SEQ_BT
:
474 case V4L2_FIELD_BOTTOM
:
475 case V4L2_FIELD_ALTERNATE
:
477 case V4L2_FIELD_INTERLACED
:
479 return V4L2_FIELD_INTERLACED
;
482 if (vivid_is_hdmi_cap(dev
))
483 return dev
->dv_timings_cap
[dev
->input
].bt
.interlaced
?
484 V4L2_FIELD_ALTERNATE
: V4L2_FIELD_NONE
;
485 return V4L2_FIELD_NONE
;
488 static unsigned vivid_colorspace_cap(struct vivid_dev
*dev
)
490 if (!dev
->loop_video
|| vivid_is_webcam(dev
) || vivid_is_tv_cap(dev
))
491 return tpg_g_colorspace(&dev
->tpg
);
492 return dev
->colorspace_out
;
495 static unsigned vivid_xfer_func_cap(struct vivid_dev
*dev
)
497 if (!dev
->loop_video
|| vivid_is_webcam(dev
) || vivid_is_tv_cap(dev
))
498 return tpg_g_xfer_func(&dev
->tpg
);
499 return dev
->xfer_func_out
;
502 static unsigned vivid_ycbcr_enc_cap(struct vivid_dev
*dev
)
504 if (!dev
->loop_video
|| vivid_is_webcam(dev
) || vivid_is_tv_cap(dev
))
505 return tpg_g_ycbcr_enc(&dev
->tpg
);
506 return dev
->ycbcr_enc_out
;
509 static unsigned int vivid_hsv_enc_cap(struct vivid_dev
*dev
)
511 if (!dev
->loop_video
|| vivid_is_webcam(dev
) || vivid_is_tv_cap(dev
))
512 return tpg_g_hsv_enc(&dev
->tpg
);
513 return dev
->hsv_enc_out
;
516 static unsigned vivid_quantization_cap(struct vivid_dev
*dev
)
518 if (!dev
->loop_video
|| vivid_is_webcam(dev
) || vivid_is_tv_cap(dev
))
519 return tpg_g_quantization(&dev
->tpg
);
520 return dev
->quantization_out
;
523 int vivid_g_fmt_vid_cap(struct file
*file
, void *priv
,
524 struct v4l2_format
*f
)
526 struct vivid_dev
*dev
= video_drvdata(file
);
527 struct v4l2_pix_format_mplane
*mp
= &f
->fmt
.pix_mp
;
530 mp
->width
= dev
->fmt_cap_rect
.width
;
531 mp
->height
= dev
->fmt_cap_rect
.height
;
532 mp
->field
= dev
->field_cap
;
533 mp
->pixelformat
= dev
->fmt_cap
->fourcc
;
534 mp
->colorspace
= vivid_colorspace_cap(dev
);
535 mp
->xfer_func
= vivid_xfer_func_cap(dev
);
536 if (dev
->fmt_cap
->color_enc
== TGP_COLOR_ENC_HSV
)
537 mp
->hsv_enc
= vivid_hsv_enc_cap(dev
);
539 mp
->ycbcr_enc
= vivid_ycbcr_enc_cap(dev
);
540 mp
->quantization
= vivid_quantization_cap(dev
);
541 mp
->num_planes
= dev
->fmt_cap
->buffers
;
542 for (p
= 0; p
< mp
->num_planes
; p
++) {
543 mp
->plane_fmt
[p
].bytesperline
= tpg_g_bytesperline(&dev
->tpg
, p
);
544 mp
->plane_fmt
[p
].sizeimage
=
545 (tpg_g_line_width(&dev
->tpg
, p
) * mp
->height
) /
546 dev
->fmt_cap
->vdownsampling
[p
] +
547 dev
->fmt_cap
->data_offset
[p
];
552 int vivid_try_fmt_vid_cap(struct file
*file
, void *priv
,
553 struct v4l2_format
*f
)
555 struct v4l2_pix_format_mplane
*mp
= &f
->fmt
.pix_mp
;
556 struct v4l2_plane_pix_format
*pfmt
= mp
->plane_fmt
;
557 struct vivid_dev
*dev
= video_drvdata(file
);
558 const struct vivid_fmt
*fmt
;
559 unsigned bytesperline
, max_bpl
;
564 fmt
= vivid_get_format(dev
, mp
->pixelformat
);
566 dprintk(dev
, 1, "Fourcc format (0x%08x) unknown.\n",
568 mp
->pixelformat
= V4L2_PIX_FMT_YUYV
;
569 fmt
= vivid_get_format(dev
, mp
->pixelformat
);
572 mp
->field
= vivid_field_cap(dev
, mp
->field
);
573 if (vivid_is_webcam(dev
)) {
574 const struct v4l2_frmsize_discrete
*sz
=
575 v4l2_find_nearest_size(webcam_sizes
,
576 VIVID_WEBCAM_SIZES
, width
,
577 height
, mp
->width
, mp
->height
);
581 } else if (vivid_is_sdtv_cap(dev
)) {
583 h
= (dev
->std_cap
[dev
->input
] & V4L2_STD_525_60
) ? 480 : 576;
585 w
= dev
->src_rect
.width
;
586 h
= dev
->src_rect
.height
;
588 if (V4L2_FIELD_HAS_T_OR_B(mp
->field
))
590 if (vivid_is_webcam(dev
) ||
591 (!dev
->has_scaler_cap
&& !dev
->has_crop_cap
&& !dev
->has_compose_cap
)) {
593 mp
->height
= h
/ factor
;
595 struct v4l2_rect r
= { 0, 0, mp
->width
, mp
->height
* factor
};
597 v4l2_rect_set_min_size(&r
, &vivid_min_rect
);
598 v4l2_rect_set_max_size(&r
, &vivid_max_rect
);
599 if (dev
->has_scaler_cap
&& !dev
->has_compose_cap
) {
600 struct v4l2_rect max_r
= { 0, 0, MAX_ZOOM
* w
, MAX_ZOOM
* h
};
602 v4l2_rect_set_max_size(&r
, &max_r
);
603 } else if (!dev
->has_scaler_cap
&& dev
->has_crop_cap
&& !dev
->has_compose_cap
) {
604 v4l2_rect_set_max_size(&r
, &dev
->src_rect
);
605 } else if (!dev
->has_scaler_cap
&& !dev
->has_crop_cap
) {
606 v4l2_rect_set_min_size(&r
, &dev
->src_rect
);
609 mp
->height
= r
.height
/ factor
;
612 /* This driver supports custom bytesperline values */
614 mp
->num_planes
= fmt
->buffers
;
615 for (p
= 0; p
< fmt
->buffers
; p
++) {
616 /* Calculate the minimum supported bytesperline value */
617 bytesperline
= (mp
->width
* fmt
->bit_depth
[p
]) >> 3;
618 /* Calculate the maximum supported bytesperline value */
619 max_bpl
= (MAX_ZOOM
* MAX_WIDTH
* fmt
->bit_depth
[p
]) >> 3;
621 if (pfmt
[p
].bytesperline
> max_bpl
)
622 pfmt
[p
].bytesperline
= max_bpl
;
623 if (pfmt
[p
].bytesperline
< bytesperline
)
624 pfmt
[p
].bytesperline
= bytesperline
;
626 pfmt
[p
].sizeimage
= (pfmt
[p
].bytesperline
* mp
->height
) /
627 fmt
->vdownsampling
[p
] + fmt
->data_offset
[p
];
629 memset(pfmt
[p
].reserved
, 0, sizeof(pfmt
[p
].reserved
));
631 for (p
= fmt
->buffers
; p
< fmt
->planes
; p
++)
632 pfmt
[0].sizeimage
+= (pfmt
[0].bytesperline
* mp
->height
*
633 (fmt
->bit_depth
[p
] / fmt
->vdownsampling
[p
])) /
634 (fmt
->bit_depth
[0] / fmt
->vdownsampling
[0]);
636 mp
->colorspace
= vivid_colorspace_cap(dev
);
637 if (fmt
->color_enc
== TGP_COLOR_ENC_HSV
)
638 mp
->hsv_enc
= vivid_hsv_enc_cap(dev
);
640 mp
->ycbcr_enc
= vivid_ycbcr_enc_cap(dev
);
641 mp
->xfer_func
= vivid_xfer_func_cap(dev
);
642 mp
->quantization
= vivid_quantization_cap(dev
);
643 memset(mp
->reserved
, 0, sizeof(mp
->reserved
));
647 int vivid_s_fmt_vid_cap(struct file
*file
, void *priv
,
648 struct v4l2_format
*f
)
650 struct v4l2_pix_format_mplane
*mp
= &f
->fmt
.pix_mp
;
651 struct vivid_dev
*dev
= video_drvdata(file
);
652 struct v4l2_rect
*crop
= &dev
->crop_cap
;
653 struct v4l2_rect
*compose
= &dev
->compose_cap
;
654 struct vb2_queue
*q
= &dev
->vb_vid_cap_q
;
655 int ret
= vivid_try_fmt_vid_cap(file
, priv
, f
);
663 if (vb2_is_busy(q
)) {
664 dprintk(dev
, 1, "%s device busy\n", __func__
);
668 if (dev
->overlay_cap_owner
&& dev
->fb_cap
.fmt
.pixelformat
!= mp
->pixelformat
) {
669 dprintk(dev
, 1, "overlay is active, can't change pixelformat\n");
673 dev
->fmt_cap
= vivid_get_format(dev
, mp
->pixelformat
);
674 if (V4L2_FIELD_HAS_T_OR_B(mp
->field
))
677 /* Note: the webcam input doesn't support scaling, cropping or composing */
679 if (!vivid_is_webcam(dev
) &&
680 (dev
->has_scaler_cap
|| dev
->has_crop_cap
|| dev
->has_compose_cap
)) {
681 struct v4l2_rect r
= { 0, 0, mp
->width
, mp
->height
};
683 if (dev
->has_scaler_cap
) {
684 if (dev
->has_compose_cap
)
685 v4l2_rect_map_inside(compose
, &r
);
688 if (dev
->has_crop_cap
&& !dev
->has_compose_cap
) {
689 struct v4l2_rect min_r
= {
692 factor
* r
.height
/ MAX_ZOOM
694 struct v4l2_rect max_r
= {
697 factor
* r
.height
* MAX_ZOOM
700 v4l2_rect_set_min_size(crop
, &min_r
);
701 v4l2_rect_set_max_size(crop
, &max_r
);
702 v4l2_rect_map_inside(crop
, &dev
->crop_bounds_cap
);
703 } else if (dev
->has_crop_cap
) {
704 struct v4l2_rect min_r
= {
706 compose
->width
/ MAX_ZOOM
,
707 factor
* compose
->height
/ MAX_ZOOM
709 struct v4l2_rect max_r
= {
711 compose
->width
* MAX_ZOOM
,
712 factor
* compose
->height
* MAX_ZOOM
715 v4l2_rect_set_min_size(crop
, &min_r
);
716 v4l2_rect_set_max_size(crop
, &max_r
);
717 v4l2_rect_map_inside(crop
, &dev
->crop_bounds_cap
);
719 } else if (dev
->has_crop_cap
&& !dev
->has_compose_cap
) {
721 v4l2_rect_set_size_to(crop
, &r
);
722 v4l2_rect_map_inside(crop
, &dev
->crop_bounds_cap
);
725 v4l2_rect_set_size_to(compose
, &r
);
726 } else if (!dev
->has_crop_cap
) {
727 v4l2_rect_map_inside(compose
, &r
);
730 v4l2_rect_set_max_size(crop
, &r
);
731 v4l2_rect_map_inside(crop
, &dev
->crop_bounds_cap
);
732 compose
->top
*= factor
;
733 compose
->height
*= factor
;
734 v4l2_rect_set_size_to(compose
, crop
);
735 v4l2_rect_map_inside(compose
, &r
);
736 compose
->top
/= factor
;
737 compose
->height
/= factor
;
739 } else if (vivid_is_webcam(dev
)) {
740 /* Guaranteed to be a match */
741 for (i
= 0; i
< ARRAY_SIZE(webcam_sizes
); i
++)
742 if (webcam_sizes
[i
].width
== mp
->width
&&
743 webcam_sizes
[i
].height
== mp
->height
)
745 dev
->webcam_size_idx
= i
;
746 if (dev
->webcam_ival_idx
>= 2 * (VIVID_WEBCAM_SIZES
- i
))
747 dev
->webcam_ival_idx
= 2 * (VIVID_WEBCAM_SIZES
- i
) - 1;
748 vivid_update_format_cap(dev
, false);
750 struct v4l2_rect r
= { 0, 0, mp
->width
, mp
->height
};
752 v4l2_rect_set_size_to(compose
, &r
);
754 v4l2_rect_set_size_to(crop
, &r
);
757 dev
->fmt_cap_rect
.width
= mp
->width
;
758 dev
->fmt_cap_rect
.height
= mp
->height
;
759 tpg_s_buf_height(&dev
->tpg
, mp
->height
);
760 tpg_s_fourcc(&dev
->tpg
, dev
->fmt_cap
->fourcc
);
761 for (p
= 0; p
< tpg_g_buffers(&dev
->tpg
); p
++)
762 tpg_s_bytesperline(&dev
->tpg
, p
, mp
->plane_fmt
[p
].bytesperline
);
763 dev
->field_cap
= mp
->field
;
764 if (dev
->field_cap
== V4L2_FIELD_ALTERNATE
)
765 tpg_s_field(&dev
->tpg
, V4L2_FIELD_TOP
, true);
767 tpg_s_field(&dev
->tpg
, dev
->field_cap
, false);
768 tpg_s_crop_compose(&dev
->tpg
, &dev
->crop_cap
, &dev
->compose_cap
);
769 if (vivid_is_sdtv_cap(dev
))
770 dev
->tv_field_cap
= mp
->field
;
771 tpg_update_mv_step(&dev
->tpg
);
775 int vidioc_g_fmt_vid_cap_mplane(struct file
*file
, void *priv
,
776 struct v4l2_format
*f
)
778 struct vivid_dev
*dev
= video_drvdata(file
);
780 if (!dev
->multiplanar
)
782 return vivid_g_fmt_vid_cap(file
, priv
, f
);
785 int vidioc_try_fmt_vid_cap_mplane(struct file
*file
, void *priv
,
786 struct v4l2_format
*f
)
788 struct vivid_dev
*dev
= video_drvdata(file
);
790 if (!dev
->multiplanar
)
792 return vivid_try_fmt_vid_cap(file
, priv
, f
);
795 int vidioc_s_fmt_vid_cap_mplane(struct file
*file
, void *priv
,
796 struct v4l2_format
*f
)
798 struct vivid_dev
*dev
= video_drvdata(file
);
800 if (!dev
->multiplanar
)
802 return vivid_s_fmt_vid_cap(file
, priv
, f
);
805 int vidioc_g_fmt_vid_cap(struct file
*file
, void *priv
,
806 struct v4l2_format
*f
)
808 struct vivid_dev
*dev
= video_drvdata(file
);
810 if (dev
->multiplanar
)
812 return fmt_sp2mp_func(file
, priv
, f
, vivid_g_fmt_vid_cap
);
815 int vidioc_try_fmt_vid_cap(struct file
*file
, void *priv
,
816 struct v4l2_format
*f
)
818 struct vivid_dev
*dev
= video_drvdata(file
);
820 if (dev
->multiplanar
)
822 return fmt_sp2mp_func(file
, priv
, f
, vivid_try_fmt_vid_cap
);
825 int vidioc_s_fmt_vid_cap(struct file
*file
, void *priv
,
826 struct v4l2_format
*f
)
828 struct vivid_dev
*dev
= video_drvdata(file
);
830 if (dev
->multiplanar
)
832 return fmt_sp2mp_func(file
, priv
, f
, vivid_s_fmt_vid_cap
);
835 int vivid_vid_cap_g_selection(struct file
*file
, void *priv
,
836 struct v4l2_selection
*sel
)
838 struct vivid_dev
*dev
= video_drvdata(file
);
840 if (!dev
->has_crop_cap
&& !dev
->has_compose_cap
)
842 if (sel
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
844 if (vivid_is_webcam(dev
))
847 sel
->r
.left
= sel
->r
.top
= 0;
848 switch (sel
->target
) {
849 case V4L2_SEL_TGT_CROP
:
850 if (!dev
->has_crop_cap
)
852 sel
->r
= dev
->crop_cap
;
854 case V4L2_SEL_TGT_CROP_DEFAULT
:
855 case V4L2_SEL_TGT_CROP_BOUNDS
:
856 if (!dev
->has_crop_cap
)
858 sel
->r
= dev
->src_rect
;
860 case V4L2_SEL_TGT_COMPOSE_BOUNDS
:
861 if (!dev
->has_compose_cap
)
863 sel
->r
= vivid_max_rect
;
865 case V4L2_SEL_TGT_COMPOSE
:
866 if (!dev
->has_compose_cap
)
868 sel
->r
= dev
->compose_cap
;
870 case V4L2_SEL_TGT_COMPOSE_DEFAULT
:
871 if (!dev
->has_compose_cap
)
873 sel
->r
= dev
->fmt_cap_rect
;
881 int vivid_vid_cap_s_selection(struct file
*file
, void *fh
, struct v4l2_selection
*s
)
883 struct vivid_dev
*dev
= video_drvdata(file
);
884 struct v4l2_rect
*crop
= &dev
->crop_cap
;
885 struct v4l2_rect
*compose
= &dev
->compose_cap
;
886 unsigned factor
= V4L2_FIELD_HAS_T_OR_B(dev
->field_cap
) ? 2 : 1;
889 if (!dev
->has_crop_cap
&& !dev
->has_compose_cap
)
891 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
893 if (vivid_is_webcam(dev
))
897 case V4L2_SEL_TGT_CROP
:
898 if (!dev
->has_crop_cap
)
900 ret
= vivid_vid_adjust_sel(s
->flags
, &s
->r
);
903 v4l2_rect_set_min_size(&s
->r
, &vivid_min_rect
);
904 v4l2_rect_set_max_size(&s
->r
, &dev
->src_rect
);
905 v4l2_rect_map_inside(&s
->r
, &dev
->crop_bounds_cap
);
907 s
->r
.height
/= factor
;
908 if (dev
->has_scaler_cap
) {
909 struct v4l2_rect fmt
= dev
->fmt_cap_rect
;
910 struct v4l2_rect max_rect
= {
912 s
->r
.width
* MAX_ZOOM
,
913 s
->r
.height
* MAX_ZOOM
915 struct v4l2_rect min_rect
= {
917 s
->r
.width
/ MAX_ZOOM
,
918 s
->r
.height
/ MAX_ZOOM
921 v4l2_rect_set_min_size(&fmt
, &min_rect
);
922 if (!dev
->has_compose_cap
)
923 v4l2_rect_set_max_size(&fmt
, &max_rect
);
924 if (!v4l2_rect_same_size(&dev
->fmt_cap_rect
, &fmt
) &&
925 vb2_is_busy(&dev
->vb_vid_cap_q
))
927 if (dev
->has_compose_cap
) {
928 v4l2_rect_set_min_size(compose
, &min_rect
);
929 v4l2_rect_set_max_size(compose
, &max_rect
);
931 dev
->fmt_cap_rect
= fmt
;
932 tpg_s_buf_height(&dev
->tpg
, fmt
.height
);
933 } else if (dev
->has_compose_cap
) {
934 struct v4l2_rect fmt
= dev
->fmt_cap_rect
;
936 v4l2_rect_set_min_size(&fmt
, &s
->r
);
937 if (!v4l2_rect_same_size(&dev
->fmt_cap_rect
, &fmt
) &&
938 vb2_is_busy(&dev
->vb_vid_cap_q
))
940 dev
->fmt_cap_rect
= fmt
;
941 tpg_s_buf_height(&dev
->tpg
, fmt
.height
);
942 v4l2_rect_set_size_to(compose
, &s
->r
);
943 v4l2_rect_map_inside(compose
, &dev
->fmt_cap_rect
);
945 if (!v4l2_rect_same_size(&s
->r
, &dev
->fmt_cap_rect
) &&
946 vb2_is_busy(&dev
->vb_vid_cap_q
))
948 v4l2_rect_set_size_to(&dev
->fmt_cap_rect
, &s
->r
);
949 v4l2_rect_set_size_to(compose
, &s
->r
);
950 v4l2_rect_map_inside(compose
, &dev
->fmt_cap_rect
);
951 tpg_s_buf_height(&dev
->tpg
, dev
->fmt_cap_rect
.height
);
954 s
->r
.height
*= factor
;
957 case V4L2_SEL_TGT_COMPOSE
:
958 if (!dev
->has_compose_cap
)
960 ret
= vivid_vid_adjust_sel(s
->flags
, &s
->r
);
963 v4l2_rect_set_min_size(&s
->r
, &vivid_min_rect
);
964 v4l2_rect_set_max_size(&s
->r
, &dev
->fmt_cap_rect
);
965 if (dev
->has_scaler_cap
) {
966 struct v4l2_rect max_rect
= {
968 dev
->src_rect
.width
* MAX_ZOOM
,
969 (dev
->src_rect
.height
/ factor
) * MAX_ZOOM
972 v4l2_rect_set_max_size(&s
->r
, &max_rect
);
973 if (dev
->has_crop_cap
) {
974 struct v4l2_rect min_rect
= {
976 s
->r
.width
/ MAX_ZOOM
,
977 (s
->r
.height
* factor
) / MAX_ZOOM
979 struct v4l2_rect max_rect
= {
981 s
->r
.width
* MAX_ZOOM
,
982 (s
->r
.height
* factor
) * MAX_ZOOM
985 v4l2_rect_set_min_size(crop
, &min_rect
);
986 v4l2_rect_set_max_size(crop
, &max_rect
);
987 v4l2_rect_map_inside(crop
, &dev
->crop_bounds_cap
);
989 } else if (dev
->has_crop_cap
) {
991 s
->r
.height
*= factor
;
992 v4l2_rect_set_max_size(&s
->r
, &dev
->src_rect
);
993 v4l2_rect_set_size_to(crop
, &s
->r
);
994 v4l2_rect_map_inside(crop
, &dev
->crop_bounds_cap
);
996 s
->r
.height
/= factor
;
998 v4l2_rect_set_size_to(&s
->r
, &dev
->src_rect
);
999 s
->r
.height
/= factor
;
1001 v4l2_rect_map_inside(&s
->r
, &dev
->fmt_cap_rect
);
1002 if (dev
->bitmap_cap
&& (compose
->width
!= s
->r
.width
||
1003 compose
->height
!= s
->r
.height
)) {
1004 vfree(dev
->bitmap_cap
);
1005 dev
->bitmap_cap
= NULL
;
1013 tpg_s_crop_compose(&dev
->tpg
, crop
, compose
);
1017 int vivid_vid_cap_g_pixelaspect(struct file
*file
, void *priv
,
1018 int type
, struct v4l2_fract
*f
)
1020 struct vivid_dev
*dev
= video_drvdata(file
);
1022 if (type
!= V4L2_BUF_TYPE_VIDEO_CAPTURE
)
1025 switch (vivid_get_pixel_aspect(dev
)) {
1026 case TPG_PIXEL_ASPECT_NTSC
:
1028 f
->denominator
= 10;
1030 case TPG_PIXEL_ASPECT_PAL
:
1032 f
->denominator
= 59;
1040 int vidioc_enum_fmt_vid_overlay(struct file
*file
, void *priv
,
1041 struct v4l2_fmtdesc
*f
)
1043 struct vivid_dev
*dev
= video_drvdata(file
);
1044 const struct vivid_fmt
*fmt
;
1046 if (dev
->multiplanar
)
1049 if (f
->index
>= ARRAY_SIZE(formats_ovl
))
1052 fmt
= &formats_ovl
[f
->index
];
1054 f
->pixelformat
= fmt
->fourcc
;
1058 int vidioc_g_fmt_vid_overlay(struct file
*file
, void *priv
,
1059 struct v4l2_format
*f
)
1061 struct vivid_dev
*dev
= video_drvdata(file
);
1062 const struct v4l2_rect
*compose
= &dev
->compose_cap
;
1063 struct v4l2_window
*win
= &f
->fmt
.win
;
1064 unsigned clipcount
= win
->clipcount
;
1066 if (dev
->multiplanar
)
1069 win
->w
.top
= dev
->overlay_cap_top
;
1070 win
->w
.left
= dev
->overlay_cap_left
;
1071 win
->w
.width
= compose
->width
;
1072 win
->w
.height
= compose
->height
;
1073 win
->field
= dev
->overlay_cap_field
;
1074 win
->clipcount
= dev
->clipcount_cap
;
1075 if (clipcount
> dev
->clipcount_cap
)
1076 clipcount
= dev
->clipcount_cap
;
1077 if (dev
->bitmap_cap
== NULL
)
1079 else if (win
->bitmap
) {
1080 if (copy_to_user(win
->bitmap
, dev
->bitmap_cap
,
1081 ((compose
->width
+ 7) / 8) * compose
->height
))
1084 if (clipcount
&& win
->clips
) {
1085 if (copy_to_user(win
->clips
, dev
->clips_cap
,
1086 clipcount
* sizeof(dev
->clips_cap
[0])))
1092 int vidioc_try_fmt_vid_overlay(struct file
*file
, void *priv
,
1093 struct v4l2_format
*f
)
1095 struct vivid_dev
*dev
= video_drvdata(file
);
1096 const struct v4l2_rect
*compose
= &dev
->compose_cap
;
1097 struct v4l2_window
*win
= &f
->fmt
.win
;
1100 if (dev
->multiplanar
)
1103 win
->w
.left
= clamp_t(int, win
->w
.left
,
1104 -dev
->fb_cap
.fmt
.width
, dev
->fb_cap
.fmt
.width
);
1105 win
->w
.top
= clamp_t(int, win
->w
.top
,
1106 -dev
->fb_cap
.fmt
.height
, dev
->fb_cap
.fmt
.height
);
1107 win
->w
.width
= compose
->width
;
1108 win
->w
.height
= compose
->height
;
1109 if (win
->field
!= V4L2_FIELD_BOTTOM
&& win
->field
!= V4L2_FIELD_TOP
)
1110 win
->field
= V4L2_FIELD_ANY
;
1112 win
->global_alpha
= 0;
1113 if (win
->clipcount
&& !win
->clips
)
1115 if (win
->clipcount
> MAX_CLIPS
)
1116 win
->clipcount
= MAX_CLIPS
;
1117 if (win
->clipcount
) {
1118 if (copy_from_user(dev
->try_clips_cap
, win
->clips
,
1119 win
->clipcount
* sizeof(dev
->clips_cap
[0])))
1121 for (i
= 0; i
< win
->clipcount
; i
++) {
1122 struct v4l2_rect
*r
= &dev
->try_clips_cap
[i
].c
;
1124 r
->top
= clamp_t(s32
, r
->top
, 0, dev
->fb_cap
.fmt
.height
- 1);
1125 r
->height
= clamp_t(s32
, r
->height
, 1, dev
->fb_cap
.fmt
.height
- r
->top
);
1126 r
->left
= clamp_t(u32
, r
->left
, 0, dev
->fb_cap
.fmt
.width
- 1);
1127 r
->width
= clamp_t(u32
, r
->width
, 1, dev
->fb_cap
.fmt
.width
- r
->left
);
1130 * Yeah, so sue me, it's an O(n^2) algorithm. But n is a small
1131 * number and it's typically a one-time deal.
1133 for (i
= 0; i
< win
->clipcount
- 1; i
++) {
1134 struct v4l2_rect
*r1
= &dev
->try_clips_cap
[i
].c
;
1136 for (j
= i
+ 1; j
< win
->clipcount
; j
++) {
1137 struct v4l2_rect
*r2
= &dev
->try_clips_cap
[j
].c
;
1139 if (v4l2_rect_overlap(r1
, r2
))
1143 if (copy_to_user(win
->clips
, dev
->try_clips_cap
,
1144 win
->clipcount
* sizeof(dev
->clips_cap
[0])))
1150 int vidioc_s_fmt_vid_overlay(struct file
*file
, void *priv
,
1151 struct v4l2_format
*f
)
1153 struct vivid_dev
*dev
= video_drvdata(file
);
1154 const struct v4l2_rect
*compose
= &dev
->compose_cap
;
1155 struct v4l2_window
*win
= &f
->fmt
.win
;
1156 int ret
= vidioc_try_fmt_vid_overlay(file
, priv
, f
);
1157 unsigned bitmap_size
= ((compose
->width
+ 7) / 8) * compose
->height
;
1158 unsigned clips_size
= win
->clipcount
* sizeof(dev
->clips_cap
[0]);
1159 void *new_bitmap
= NULL
;
1165 new_bitmap
= vzalloc(bitmap_size
);
1167 if (new_bitmap
== NULL
)
1169 if (copy_from_user(new_bitmap
, win
->bitmap
, bitmap_size
)) {
1175 dev
->overlay_cap_top
= win
->w
.top
;
1176 dev
->overlay_cap_left
= win
->w
.left
;
1177 dev
->overlay_cap_field
= win
->field
;
1178 vfree(dev
->bitmap_cap
);
1179 dev
->bitmap_cap
= new_bitmap
;
1180 dev
->clipcount_cap
= win
->clipcount
;
1181 if (dev
->clipcount_cap
)
1182 memcpy(dev
->clips_cap
, dev
->try_clips_cap
, clips_size
);
1186 int vivid_vid_cap_overlay(struct file
*file
, void *fh
, unsigned i
)
1188 struct vivid_dev
*dev
= video_drvdata(file
);
1190 if (dev
->multiplanar
)
1193 if (i
&& dev
->fb_vbase_cap
== NULL
)
1196 if (i
&& dev
->fb_cap
.fmt
.pixelformat
!= dev
->fmt_cap
->fourcc
) {
1197 dprintk(dev
, 1, "mismatch between overlay and video capture pixelformats\n");
1201 if (dev
->overlay_cap_owner
&& dev
->overlay_cap_owner
!= fh
)
1203 dev
->overlay_cap_owner
= i
? fh
: NULL
;
1207 int vivid_vid_cap_g_fbuf(struct file
*file
, void *fh
,
1208 struct v4l2_framebuffer
*a
)
1210 struct vivid_dev
*dev
= video_drvdata(file
);
1212 if (dev
->multiplanar
)
1216 a
->capability
= V4L2_FBUF_CAP_BITMAP_CLIPPING
|
1217 V4L2_FBUF_CAP_LIST_CLIPPING
;
1218 a
->flags
= V4L2_FBUF_FLAG_PRIMARY
;
1219 a
->fmt
.field
= V4L2_FIELD_NONE
;
1220 a
->fmt
.colorspace
= V4L2_COLORSPACE_SRGB
;
1225 int vivid_vid_cap_s_fbuf(struct file
*file
, void *fh
,
1226 const struct v4l2_framebuffer
*a
)
1228 struct vivid_dev
*dev
= video_drvdata(file
);
1229 const struct vivid_fmt
*fmt
;
1231 if (dev
->multiplanar
)
1234 if (!capable(CAP_SYS_ADMIN
) && !capable(CAP_SYS_RAWIO
))
1237 if (dev
->overlay_cap_owner
)
1240 if (a
->base
== NULL
) {
1241 dev
->fb_cap
.base
= NULL
;
1242 dev
->fb_vbase_cap
= NULL
;
1246 if (a
->fmt
.width
< 48 || a
->fmt
.height
< 32)
1248 fmt
= vivid_get_format(dev
, a
->fmt
.pixelformat
);
1249 if (!fmt
|| !fmt
->can_do_overlay
)
1251 if (a
->fmt
.bytesperline
< (a
->fmt
.width
* fmt
->bit_depth
[0]) / 8)
1253 if (a
->fmt
.height
* a
->fmt
.bytesperline
< a
->fmt
.sizeimage
)
1256 dev
->fb_vbase_cap
= phys_to_virt((unsigned long)a
->base
);
1258 dev
->overlay_cap_left
= clamp_t(int, dev
->overlay_cap_left
,
1259 -dev
->fb_cap
.fmt
.width
, dev
->fb_cap
.fmt
.width
);
1260 dev
->overlay_cap_top
= clamp_t(int, dev
->overlay_cap_top
,
1261 -dev
->fb_cap
.fmt
.height
, dev
->fb_cap
.fmt
.height
);
1265 static const struct v4l2_audio vivid_audio_inputs
[] = {
1266 { 0, "TV", V4L2_AUDCAP_STEREO
},
1267 { 1, "Line-In", V4L2_AUDCAP_STEREO
},
1270 int vidioc_enum_input(struct file
*file
, void *priv
,
1271 struct v4l2_input
*inp
)
1273 struct vivid_dev
*dev
= video_drvdata(file
);
1275 if (inp
->index
>= dev
->num_inputs
)
1278 inp
->type
= V4L2_INPUT_TYPE_CAMERA
;
1279 switch (dev
->input_type
[inp
->index
]) {
1281 snprintf(inp
->name
, sizeof(inp
->name
), "Webcam %u",
1282 dev
->input_name_counter
[inp
->index
]);
1283 inp
->capabilities
= 0;
1286 snprintf(inp
->name
, sizeof(inp
->name
), "TV %u",
1287 dev
->input_name_counter
[inp
->index
]);
1288 inp
->type
= V4L2_INPUT_TYPE_TUNER
;
1289 inp
->std
= V4L2_STD_ALL
;
1290 if (dev
->has_audio_inputs
)
1291 inp
->audioset
= (1 << ARRAY_SIZE(vivid_audio_inputs
)) - 1;
1292 inp
->capabilities
= V4L2_IN_CAP_STD
;
1295 snprintf(inp
->name
, sizeof(inp
->name
), "S-Video %u",
1296 dev
->input_name_counter
[inp
->index
]);
1297 inp
->std
= V4L2_STD_ALL
;
1298 if (dev
->has_audio_inputs
)
1299 inp
->audioset
= (1 << ARRAY_SIZE(vivid_audio_inputs
)) - 1;
1300 inp
->capabilities
= V4L2_IN_CAP_STD
;
1303 snprintf(inp
->name
, sizeof(inp
->name
), "HDMI %u",
1304 dev
->input_name_counter
[inp
->index
]);
1305 inp
->capabilities
= V4L2_IN_CAP_DV_TIMINGS
;
1306 if (dev
->edid_blocks
== 0 ||
1307 dev
->dv_timings_signal_mode
[dev
->input
] == NO_SIGNAL
)
1308 inp
->status
|= V4L2_IN_ST_NO_SIGNAL
;
1309 else if (dev
->dv_timings_signal_mode
[dev
->input
] == NO_LOCK
||
1310 dev
->dv_timings_signal_mode
[dev
->input
] == OUT_OF_RANGE
)
1311 inp
->status
|= V4L2_IN_ST_NO_H_LOCK
;
1314 if (dev
->sensor_hflip
)
1315 inp
->status
|= V4L2_IN_ST_HFLIP
;
1316 if (dev
->sensor_vflip
)
1317 inp
->status
|= V4L2_IN_ST_VFLIP
;
1318 if (dev
->input
== inp
->index
&& vivid_is_sdtv_cap(dev
)) {
1319 if (dev
->std_signal_mode
[dev
->input
] == NO_SIGNAL
) {
1320 inp
->status
|= V4L2_IN_ST_NO_SIGNAL
;
1321 } else if (dev
->std_signal_mode
[dev
->input
] == NO_LOCK
) {
1322 inp
->status
|= V4L2_IN_ST_NO_H_LOCK
;
1323 } else if (vivid_is_tv_cap(dev
)) {
1324 switch (tpg_g_quality(&dev
->tpg
)) {
1326 inp
->status
|= V4L2_IN_ST_COLOR_KILL
;
1328 case TPG_QUAL_NOISE
:
1329 inp
->status
|= V4L2_IN_ST_NO_H_LOCK
;
1339 int vidioc_g_input(struct file
*file
, void *priv
, unsigned *i
)
1341 struct vivid_dev
*dev
= video_drvdata(file
);
1347 int vidioc_s_input(struct file
*file
, void *priv
, unsigned i
)
1349 struct vivid_dev
*dev
= video_drvdata(file
);
1350 struct v4l2_bt_timings
*bt
= &dev
->dv_timings_cap
[dev
->input
].bt
;
1351 unsigned brightness
;
1353 if (i
>= dev
->num_inputs
)
1356 if (i
== dev
->input
)
1359 if (vb2_is_busy(&dev
->vb_vid_cap_q
) ||
1360 vb2_is_busy(&dev
->vb_vbi_cap_q
) ||
1361 vb2_is_busy(&dev
->vb_meta_cap_q
))
1365 dev
->vid_cap_dev
.tvnorms
= 0;
1366 if (dev
->input_type
[i
] == TV
|| dev
->input_type
[i
] == SVID
) {
1367 dev
->tv_audio_input
= (dev
->input_type
[i
] == TV
) ? 0 : 1;
1368 dev
->vid_cap_dev
.tvnorms
= V4L2_STD_ALL
;
1370 dev
->vbi_cap_dev
.tvnorms
= dev
->vid_cap_dev
.tvnorms
;
1371 dev
->meta_cap_dev
.tvnorms
= dev
->vid_cap_dev
.tvnorms
;
1372 vivid_update_format_cap(dev
, false);
1374 if (dev
->colorspace
) {
1375 switch (dev
->input_type
[i
]) {
1377 v4l2_ctrl_s_ctrl(dev
->colorspace
, VIVID_CS_SRGB
);
1381 v4l2_ctrl_s_ctrl(dev
->colorspace
, VIVID_CS_170M
);
1384 if (bt
->flags
& V4L2_DV_FL_IS_CE_VIDEO
) {
1385 if (dev
->src_rect
.width
== 720 && dev
->src_rect
.height
<= 576)
1386 v4l2_ctrl_s_ctrl(dev
->colorspace
, VIVID_CS_170M
);
1388 v4l2_ctrl_s_ctrl(dev
->colorspace
, VIVID_CS_709
);
1390 v4l2_ctrl_s_ctrl(dev
->colorspace
, VIVID_CS_SRGB
);
1397 * Modify the brightness range depending on the input.
1398 * This makes it easy to use vivid to test if applications can
1399 * handle control range modifications and is also how this is
1400 * typically used in practice as different inputs may be hooked
1401 * up to different receivers with different control ranges.
1403 brightness
= 128 * i
+ dev
->input_brightness
[i
];
1404 v4l2_ctrl_modify_range(dev
->brightness
,
1405 128 * i
, 255 + 128 * i
, 1, 128 + 128 * i
);
1406 v4l2_ctrl_s_ctrl(dev
->brightness
, brightness
);
1408 /* Restore per-input states. */
1409 v4l2_ctrl_activate(dev
->ctrl_dv_timings_signal_mode
,
1410 vivid_is_hdmi_cap(dev
));
1411 v4l2_ctrl_activate(dev
->ctrl_dv_timings
, vivid_is_hdmi_cap(dev
) &&
1412 dev
->dv_timings_signal_mode
[dev
->input
] ==
1413 SELECTED_DV_TIMINGS
);
1414 v4l2_ctrl_activate(dev
->ctrl_std_signal_mode
, vivid_is_sdtv_cap(dev
));
1415 v4l2_ctrl_activate(dev
->ctrl_standard
, vivid_is_sdtv_cap(dev
) &&
1416 dev
->std_signal_mode
[dev
->input
]);
1418 if (vivid_is_hdmi_cap(dev
)) {
1419 v4l2_ctrl_s_ctrl(dev
->ctrl_dv_timings_signal_mode
,
1420 dev
->dv_timings_signal_mode
[dev
->input
]);
1421 v4l2_ctrl_s_ctrl(dev
->ctrl_dv_timings
,
1422 dev
->query_dv_timings
[dev
->input
]);
1423 } else if (vivid_is_sdtv_cap(dev
)) {
1424 v4l2_ctrl_s_ctrl(dev
->ctrl_std_signal_mode
,
1425 dev
->std_signal_mode
[dev
->input
]);
1426 v4l2_ctrl_s_ctrl(dev
->ctrl_standard
,
1427 dev
->std_signal_mode
[dev
->input
]);
1433 int vidioc_enumaudio(struct file
*file
, void *fh
, struct v4l2_audio
*vin
)
1435 if (vin
->index
>= ARRAY_SIZE(vivid_audio_inputs
))
1437 *vin
= vivid_audio_inputs
[vin
->index
];
1441 int vidioc_g_audio(struct file
*file
, void *fh
, struct v4l2_audio
*vin
)
1443 struct vivid_dev
*dev
= video_drvdata(file
);
1445 if (!vivid_is_sdtv_cap(dev
))
1447 *vin
= vivid_audio_inputs
[dev
->tv_audio_input
];
1451 int vidioc_s_audio(struct file
*file
, void *fh
, const struct v4l2_audio
*vin
)
1453 struct vivid_dev
*dev
= video_drvdata(file
);
1455 if (!vivid_is_sdtv_cap(dev
))
1457 if (vin
->index
>= ARRAY_SIZE(vivid_audio_inputs
))
1459 dev
->tv_audio_input
= vin
->index
;
1463 int vivid_video_g_frequency(struct file
*file
, void *fh
, struct v4l2_frequency
*vf
)
1465 struct vivid_dev
*dev
= video_drvdata(file
);
1469 vf
->frequency
= dev
->tv_freq
;
1473 int vivid_video_s_frequency(struct file
*file
, void *fh
, const struct v4l2_frequency
*vf
)
1475 struct vivid_dev
*dev
= video_drvdata(file
);
1479 dev
->tv_freq
= clamp_t(unsigned, vf
->frequency
, MIN_TV_FREQ
, MAX_TV_FREQ
);
1480 if (vivid_is_tv_cap(dev
))
1481 vivid_update_quality(dev
);
1485 int vivid_video_s_tuner(struct file
*file
, void *fh
, const struct v4l2_tuner
*vt
)
1487 struct vivid_dev
*dev
= video_drvdata(file
);
1491 if (vt
->audmode
> V4L2_TUNER_MODE_LANG1_LANG2
)
1493 dev
->tv_audmode
= vt
->audmode
;
1497 int vivid_video_g_tuner(struct file
*file
, void *fh
, struct v4l2_tuner
*vt
)
1499 struct vivid_dev
*dev
= video_drvdata(file
);
1500 enum tpg_quality qual
;
1505 vt
->capability
= V4L2_TUNER_CAP_NORM
| V4L2_TUNER_CAP_STEREO
|
1506 V4L2_TUNER_CAP_LANG1
| V4L2_TUNER_CAP_LANG2
;
1507 vt
->audmode
= dev
->tv_audmode
;
1508 vt
->rangelow
= MIN_TV_FREQ
;
1509 vt
->rangehigh
= MAX_TV_FREQ
;
1510 qual
= vivid_get_quality(dev
, &vt
->afc
);
1511 if (qual
== TPG_QUAL_COLOR
)
1512 vt
->signal
= 0xffff;
1513 else if (qual
== TPG_QUAL_GRAY
)
1514 vt
->signal
= 0x8000;
1517 if (qual
== TPG_QUAL_NOISE
) {
1519 } else if (qual
== TPG_QUAL_GRAY
) {
1520 vt
->rxsubchans
= V4L2_TUNER_SUB_MONO
;
1522 unsigned int channel_nr
= dev
->tv_freq
/ (6 * 16);
1523 unsigned int options
=
1524 (dev
->std_cap
[dev
->input
] & V4L2_STD_NTSC_M
) ? 4 : 3;
1526 switch (channel_nr
% options
) {
1528 vt
->rxsubchans
= V4L2_TUNER_SUB_MONO
;
1531 vt
->rxsubchans
= V4L2_TUNER_SUB_STEREO
;
1534 if (dev
->std_cap
[dev
->input
] & V4L2_STD_NTSC_M
)
1535 vt
->rxsubchans
= V4L2_TUNER_SUB_MONO
| V4L2_TUNER_SUB_SAP
;
1537 vt
->rxsubchans
= V4L2_TUNER_SUB_LANG1
| V4L2_TUNER_SUB_LANG2
;
1540 vt
->rxsubchans
= V4L2_TUNER_SUB_STEREO
| V4L2_TUNER_SUB_SAP
;
1544 strscpy(vt
->name
, "TV Tuner", sizeof(vt
->name
));
1548 /* Must remain in sync with the vivid_ctrl_standard_strings array */
1549 const v4l2_std_id vivid_standard
[] = {
1554 V4L2_STD_PAL_BG
| V4L2_STD_PAL_H
,
1561 V4L2_STD_SECAM_B
| V4L2_STD_SECAM_G
| V4L2_STD_SECAM_H
,
1568 /* Must remain in sync with the vivid_standard array */
1569 const char * const vivid_ctrl_standard_strings
[] = {
1588 int vidioc_querystd(struct file
*file
, void *priv
, v4l2_std_id
*id
)
1590 struct vivid_dev
*dev
= video_drvdata(file
);
1591 unsigned int last
= dev
->query_std_last
[dev
->input
];
1593 if (!vivid_is_sdtv_cap(dev
))
1595 if (dev
->std_signal_mode
[dev
->input
] == NO_SIGNAL
||
1596 dev
->std_signal_mode
[dev
->input
] == NO_LOCK
) {
1597 *id
= V4L2_STD_UNKNOWN
;
1600 if (vivid_is_tv_cap(dev
) && tpg_g_quality(&dev
->tpg
) == TPG_QUAL_NOISE
) {
1601 *id
= V4L2_STD_UNKNOWN
;
1602 } else if (dev
->std_signal_mode
[dev
->input
] == CURRENT_STD
) {
1603 *id
= dev
->std_cap
[dev
->input
];
1604 } else if (dev
->std_signal_mode
[dev
->input
] == SELECTED_STD
) {
1605 *id
= dev
->query_std
[dev
->input
];
1607 *id
= vivid_standard
[last
];
1608 dev
->query_std_last
[dev
->input
] =
1609 (last
+ 1) % ARRAY_SIZE(vivid_standard
);
1615 int vivid_vid_cap_s_std(struct file
*file
, void *priv
, v4l2_std_id id
)
1617 struct vivid_dev
*dev
= video_drvdata(file
);
1619 if (!vivid_is_sdtv_cap(dev
))
1621 if (dev
->std_cap
[dev
->input
] == id
)
1623 if (vb2_is_busy(&dev
->vb_vid_cap_q
) || vb2_is_busy(&dev
->vb_vbi_cap_q
))
1625 dev
->std_cap
[dev
->input
] = id
;
1626 vivid_update_format_cap(dev
, false);
1630 static void find_aspect_ratio(u32 width
, u32 height
,
1631 u32
*num
, u32
*denom
)
1633 if (!(height
% 3) && ((height
* 4 / 3) == width
)) {
1636 } else if (!(height
% 9) && ((height
* 16 / 9) == width
)) {
1639 } else if (!(height
% 10) && ((height
* 16 / 10) == width
)) {
1642 } else if (!(height
% 4) && ((height
* 5 / 4) == width
)) {
1645 } else if (!(height
% 9) && ((height
* 15 / 9) == width
)) {
1648 } else { /* default to 16:9 */
1654 static bool valid_cvt_gtf_timings(struct v4l2_dv_timings
*timings
)
1656 struct v4l2_bt_timings
*bt
= &timings
->bt
;
1661 if (!v4l2_valid_dv_timings(timings
, &vivid_dv_timings_cap
,
1665 total_h_pixel
= V4L2_DV_BT_FRAME_WIDTH(bt
);
1666 total_v_lines
= V4L2_DV_BT_FRAME_HEIGHT(bt
);
1668 h_freq
= (u32
)bt
->pixelclock
/ total_h_pixel
;
1670 if (bt
->standards
== 0 || (bt
->standards
& V4L2_DV_BT_STD_CVT
)) {
1671 if (v4l2_detect_cvt(total_v_lines
, h_freq
, bt
->vsync
, bt
->width
,
1672 bt
->polarities
, bt
->interlaced
, timings
))
1676 if (bt
->standards
== 0 || (bt
->standards
& V4L2_DV_BT_STD_GTF
)) {
1677 struct v4l2_fract aspect_ratio
;
1679 find_aspect_ratio(bt
->width
, bt
->height
,
1680 &aspect_ratio
.numerator
,
1681 &aspect_ratio
.denominator
);
1682 if (v4l2_detect_gtf(total_v_lines
, h_freq
, bt
->vsync
,
1683 bt
->polarities
, bt
->interlaced
,
1684 aspect_ratio
, timings
))
1690 int vivid_vid_cap_s_dv_timings(struct file
*file
, void *_fh
,
1691 struct v4l2_dv_timings
*timings
)
1693 struct vivid_dev
*dev
= video_drvdata(file
);
1695 if (!vivid_is_hdmi_cap(dev
))
1697 if (!v4l2_find_dv_timings_cap(timings
, &vivid_dv_timings_cap
,
1699 !valid_cvt_gtf_timings(timings
))
1702 if (v4l2_match_dv_timings(timings
, &dev
->dv_timings_cap
[dev
->input
],
1705 if (vb2_is_busy(&dev
->vb_vid_cap_q
))
1708 dev
->dv_timings_cap
[dev
->input
] = *timings
;
1709 vivid_update_format_cap(dev
, false);
1713 int vidioc_query_dv_timings(struct file
*file
, void *_fh
,
1714 struct v4l2_dv_timings
*timings
)
1716 struct vivid_dev
*dev
= video_drvdata(file
);
1717 unsigned int input
= dev
->input
;
1718 unsigned int last
= dev
->query_dv_timings_last
[input
];
1720 if (!vivid_is_hdmi_cap(dev
))
1722 if (dev
->dv_timings_signal_mode
[input
] == NO_SIGNAL
||
1723 dev
->edid_blocks
== 0)
1725 if (dev
->dv_timings_signal_mode
[input
] == NO_LOCK
)
1727 if (dev
->dv_timings_signal_mode
[input
] == OUT_OF_RANGE
) {
1728 timings
->bt
.pixelclock
= vivid_dv_timings_cap
.bt
.max_pixelclock
* 2;
1731 if (dev
->dv_timings_signal_mode
[input
] == CURRENT_DV_TIMINGS
) {
1732 *timings
= dev
->dv_timings_cap
[input
];
1733 } else if (dev
->dv_timings_signal_mode
[input
] ==
1734 SELECTED_DV_TIMINGS
) {
1736 v4l2_dv_timings_presets
[dev
->query_dv_timings
[input
]];
1739 v4l2_dv_timings_presets
[last
];
1740 dev
->query_dv_timings_last
[input
] =
1741 (last
+ 1) % dev
->query_dv_timings_size
;
1746 int vidioc_s_edid(struct file
*file
, void *_fh
,
1747 struct v4l2_edid
*edid
)
1749 struct vivid_dev
*dev
= video_drvdata(file
);
1751 u32 display_present
= 0;
1755 memset(edid
->reserved
, 0, sizeof(edid
->reserved
));
1756 if (edid
->pad
>= dev
->num_inputs
)
1758 if (dev
->input_type
[edid
->pad
] != HDMI
|| edid
->start_block
)
1760 if (edid
->blocks
== 0) {
1761 dev
->edid_blocks
= 0;
1762 v4l2_ctrl_s_ctrl(dev
->ctrl_tx_edid_present
, 0);
1763 v4l2_ctrl_s_ctrl(dev
->ctrl_tx_hotplug
, 0);
1764 phys_addr
= CEC_PHYS_ADDR_INVALID
;
1767 if (edid
->blocks
> dev
->edid_max_blocks
) {
1768 edid
->blocks
= dev
->edid_max_blocks
;
1771 phys_addr
= cec_get_edid_phys_addr(edid
->edid
, edid
->blocks
* 128, NULL
);
1772 ret
= v4l2_phys_addr_validate(phys_addr
, &phys_addr
, NULL
);
1776 if (vb2_is_busy(&dev
->vb_vid_cap_q
))
1779 dev
->edid_blocks
= edid
->blocks
;
1780 memcpy(dev
->edid
, edid
->edid
, edid
->blocks
* 128);
1782 for (i
= 0, j
= 0; i
< dev
->num_outputs
; i
++)
1783 if (dev
->output_type
[i
] == HDMI
)
1785 dev
->display_present
[i
] << j
++;
1787 v4l2_ctrl_s_ctrl(dev
->ctrl_tx_edid_present
, display_present
);
1788 v4l2_ctrl_s_ctrl(dev
->ctrl_tx_hotplug
, display_present
);
1791 /* TODO: a proper hotplug detect cycle should be emulated here */
1792 cec_s_phys_addr(dev
->cec_rx_adap
, phys_addr
, false);
1794 for (i
= 0; i
< MAX_OUTPUTS
&& dev
->cec_tx_adap
[i
]; i
++)
1795 cec_s_phys_addr(dev
->cec_tx_adap
[i
],
1796 dev
->display_present
[i
] ?
1797 v4l2_phys_addr_for_input(phys_addr
, i
+ 1) :
1798 CEC_PHYS_ADDR_INVALID
,
1803 int vidioc_enum_framesizes(struct file
*file
, void *fh
,
1804 struct v4l2_frmsizeenum
*fsize
)
1806 struct vivid_dev
*dev
= video_drvdata(file
);
1808 if (!vivid_is_webcam(dev
) && !dev
->has_scaler_cap
)
1810 if (vivid_get_format(dev
, fsize
->pixel_format
) == NULL
)
1812 if (vivid_is_webcam(dev
)) {
1813 if (fsize
->index
>= ARRAY_SIZE(webcam_sizes
))
1815 fsize
->type
= V4L2_FRMSIZE_TYPE_DISCRETE
;
1816 fsize
->discrete
= webcam_sizes
[fsize
->index
];
1821 fsize
->type
= V4L2_FRMSIZE_TYPE_STEPWISE
;
1822 fsize
->stepwise
.min_width
= MIN_WIDTH
;
1823 fsize
->stepwise
.max_width
= MAX_WIDTH
* MAX_ZOOM
;
1824 fsize
->stepwise
.step_width
= 2;
1825 fsize
->stepwise
.min_height
= MIN_HEIGHT
;
1826 fsize
->stepwise
.max_height
= MAX_HEIGHT
* MAX_ZOOM
;
1827 fsize
->stepwise
.step_height
= 2;
1831 /* timeperframe is arbitrary and continuous */
1832 int vidioc_enum_frameintervals(struct file
*file
, void *priv
,
1833 struct v4l2_frmivalenum
*fival
)
1835 struct vivid_dev
*dev
= video_drvdata(file
);
1836 const struct vivid_fmt
*fmt
;
1839 fmt
= vivid_get_format(dev
, fival
->pixel_format
);
1843 if (!vivid_is_webcam(dev
)) {
1846 if (fival
->width
< MIN_WIDTH
|| fival
->width
> MAX_WIDTH
* MAX_ZOOM
)
1848 if (fival
->height
< MIN_HEIGHT
|| fival
->height
> MAX_HEIGHT
* MAX_ZOOM
)
1850 fival
->type
= V4L2_FRMIVAL_TYPE_DISCRETE
;
1851 fival
->discrete
= dev
->timeperframe_vid_cap
;
1855 for (i
= 0; i
< ARRAY_SIZE(webcam_sizes
); i
++)
1856 if (fival
->width
== webcam_sizes
[i
].width
&&
1857 fival
->height
== webcam_sizes
[i
].height
)
1859 if (i
== ARRAY_SIZE(webcam_sizes
))
1861 if (fival
->index
>= 2 * (VIVID_WEBCAM_SIZES
- i
))
1863 fival
->type
= V4L2_FRMIVAL_TYPE_DISCRETE
;
1864 fival
->discrete
= webcam_intervals
[fival
->index
];
1868 int vivid_vid_cap_g_parm(struct file
*file
, void *priv
,
1869 struct v4l2_streamparm
*parm
)
1871 struct vivid_dev
*dev
= video_drvdata(file
);
1873 if (parm
->type
!= (dev
->multiplanar
?
1874 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
:
1875 V4L2_BUF_TYPE_VIDEO_CAPTURE
))
1878 parm
->parm
.capture
.capability
= V4L2_CAP_TIMEPERFRAME
;
1879 parm
->parm
.capture
.timeperframe
= dev
->timeperframe_vid_cap
;
1880 parm
->parm
.capture
.readbuffers
= 1;
1884 int vivid_vid_cap_s_parm(struct file
*file
, void *priv
,
1885 struct v4l2_streamparm
*parm
)
1887 struct vivid_dev
*dev
= video_drvdata(file
);
1888 unsigned ival_sz
= 2 * (VIVID_WEBCAM_SIZES
- dev
->webcam_size_idx
);
1889 struct v4l2_fract tpf
;
1892 if (parm
->type
!= (dev
->multiplanar
?
1893 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
:
1894 V4L2_BUF_TYPE_VIDEO_CAPTURE
))
1896 if (!vivid_is_webcam(dev
))
1897 return vivid_vid_cap_g_parm(file
, priv
, parm
);
1899 tpf
= parm
->parm
.capture
.timeperframe
;
1901 if (tpf
.denominator
== 0)
1902 tpf
= webcam_intervals
[ival_sz
- 1];
1903 for (i
= 0; i
< ival_sz
; i
++)
1904 if (V4L2_FRACT_COMPARE(tpf
, >=, webcam_intervals
[i
]))
1908 dev
->webcam_ival_idx
= i
;
1909 tpf
= webcam_intervals
[dev
->webcam_ival_idx
];
1911 /* resync the thread's timings */
1912 dev
->cap_seq_resync
= true;
1913 dev
->timeperframe_vid_cap
= tpf
;
1914 parm
->parm
.capture
.capability
= V4L2_CAP_TIMEPERFRAME
;
1915 parm
->parm
.capture
.timeperframe
= tpf
;
1916 parm
->parm
.capture
.readbuffers
= 1;