1 // SPDX-License-Identifier: GPL-2.0-only
3 * vivid-vid-out.c - video output 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/videodev2.h>
12 #include <linux/v4l2-dv-timings.h>
13 #include <media/v4l2-common.h>
14 #include <media/v4l2-event.h>
15 #include <media/v4l2-dv-timings.h>
16 #include <media/v4l2-rect.h>
18 #include "vivid-core.h"
19 #include "vivid-vid-common.h"
20 #include "vivid-kthread-out.h"
21 #include "vivid-vid-out.h"
23 static int vid_out_queue_setup(struct vb2_queue
*vq
,
24 unsigned *nbuffers
, unsigned *nplanes
,
25 unsigned sizes
[], struct device
*alloc_devs
[])
27 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
28 const struct vivid_fmt
*vfmt
= dev
->fmt_out
;
29 unsigned planes
= vfmt
->buffers
;
30 unsigned h
= dev
->fmt_out_rect
.height
;
31 unsigned size
= dev
->bytesperline_out
[0] * h
;
34 for (p
= vfmt
->buffers
; p
< vfmt
->planes
; p
++)
35 size
+= dev
->bytesperline_out
[p
] * h
/ vfmt
->vdownsampling
[p
];
37 if (dev
->field_out
== V4L2_FIELD_ALTERNATE
) {
39 * You cannot use write() with FIELD_ALTERNATE since the field
40 * information (TOP/BOTTOM) cannot be passed to the kernel.
42 if (vb2_fileio_is_active(vq
))
46 if (dev
->queue_setup_error
) {
48 * Error injection: test what happens if queue_setup() returns
51 dev
->queue_setup_error
= false;
57 * Check if the number of requested planes match
58 * the number of planes in the current format. You can't mix that.
60 if (*nplanes
!= planes
)
64 for (p
= 1; p
< planes
; p
++) {
65 if (sizes
[p
] < dev
->bytesperline_out
[p
] * h
)
69 for (p
= 0; p
< planes
; p
++)
70 sizes
[p
] = p
? dev
->bytesperline_out
[p
] * h
: size
;
73 if (vq
->num_buffers
+ *nbuffers
< 2)
74 *nbuffers
= 2 - vq
->num_buffers
;
78 dprintk(dev
, 1, "%s: count=%d\n", __func__
, *nbuffers
);
79 for (p
= 0; p
< planes
; p
++)
80 dprintk(dev
, 1, "%s: size[%u]=%u\n", __func__
, p
, sizes
[p
]);
84 static int vid_out_buf_prepare(struct vb2_buffer
*vb
)
86 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
87 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
92 dprintk(dev
, 1, "%s\n", __func__
);
94 if (WARN_ON(NULL
== dev
->fmt_out
))
97 planes
= dev
->fmt_out
->planes
;
99 if (dev
->buf_prepare_error
) {
101 * Error injection: test what happens if buf_prepare() returns
104 dev
->buf_prepare_error
= false;
108 if (dev
->field_out
!= V4L2_FIELD_ALTERNATE
)
109 vbuf
->field
= dev
->field_out
;
110 else if (vbuf
->field
!= V4L2_FIELD_TOP
&&
111 vbuf
->field
!= V4L2_FIELD_BOTTOM
)
114 for (p
= 0; p
< planes
; p
++) {
115 size
= dev
->bytesperline_out
[p
] * dev
->fmt_out_rect
.height
+
116 vb
->planes
[p
].data_offset
;
118 if (vb2_get_plane_payload(vb
, p
) < size
) {
119 dprintk(dev
, 1, "%s the payload is too small for plane %u (%lu < %lu)\n",
120 __func__
, p
, vb2_get_plane_payload(vb
, p
), size
);
128 static void vid_out_buf_queue(struct vb2_buffer
*vb
)
130 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
131 struct vivid_dev
*dev
= vb2_get_drv_priv(vb
->vb2_queue
);
132 struct vivid_buffer
*buf
= container_of(vbuf
, struct vivid_buffer
, vb
);
134 dprintk(dev
, 1, "%s\n", __func__
);
136 spin_lock(&dev
->slock
);
137 list_add_tail(&buf
->list
, &dev
->vid_out_active
);
138 spin_unlock(&dev
->slock
);
141 static int vid_out_start_streaming(struct vb2_queue
*vq
, unsigned count
)
143 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
146 if (vb2_is_streaming(&dev
->vb_vid_cap_q
))
147 dev
->can_loop_video
= vivid_vid_can_loop(dev
);
149 if (dev
->kthread_vid_out
)
152 dev
->vid_out_seq_count
= 0;
153 dprintk(dev
, 1, "%s\n", __func__
);
154 if (dev
->start_streaming_error
) {
155 dev
->start_streaming_error
= false;
158 err
= vivid_start_generating_vid_out(dev
, &dev
->vid_out_streaming
);
161 struct vivid_buffer
*buf
, *tmp
;
163 list_for_each_entry_safe(buf
, tmp
, &dev
->vid_out_active
, list
) {
164 list_del(&buf
->list
);
165 vb2_buffer_done(&buf
->vb
.vb2_buf
,
166 VB2_BUF_STATE_QUEUED
);
172 /* abort streaming and wait for last buffer */
173 static void vid_out_stop_streaming(struct vb2_queue
*vq
)
175 struct vivid_dev
*dev
= vb2_get_drv_priv(vq
);
177 dprintk(dev
, 1, "%s\n", __func__
);
178 vivid_stop_generating_vid_out(dev
, &dev
->vid_out_streaming
);
179 dev
->can_loop_video
= false;
182 const struct vb2_ops vivid_vid_out_qops
= {
183 .queue_setup
= vid_out_queue_setup
,
184 .buf_prepare
= vid_out_buf_prepare
,
185 .buf_queue
= vid_out_buf_queue
,
186 .start_streaming
= vid_out_start_streaming
,
187 .stop_streaming
= vid_out_stop_streaming
,
188 .wait_prepare
= vb2_ops_wait_prepare
,
189 .wait_finish
= vb2_ops_wait_finish
,
193 * Called whenever the format has to be reset which can occur when
194 * changing outputs, standard, timings, etc.
196 void vivid_update_format_out(struct vivid_dev
*dev
)
198 struct v4l2_bt_timings
*bt
= &dev
->dv_timings_out
.bt
;
202 switch (dev
->output_type
[dev
->output
]) {
205 dev
->field_out
= dev
->tv_field_out
;
206 dev
->sink_rect
.width
= 720;
207 if (dev
->std_out
& V4L2_STD_525_60
) {
208 dev
->sink_rect
.height
= 480;
209 dev
->timeperframe_vid_out
= (struct v4l2_fract
) { 1001, 30000 };
210 dev
->service_set_out
= V4L2_SLICED_CAPTION_525
;
212 dev
->sink_rect
.height
= 576;
213 dev
->timeperframe_vid_out
= (struct v4l2_fract
) { 1000, 25000 };
214 dev
->service_set_out
= V4L2_SLICED_WSS_625
| V4L2_SLICED_TELETEXT_B
;
216 dev
->colorspace_out
= V4L2_COLORSPACE_SMPTE170M
;
219 dev
->sink_rect
.width
= bt
->width
;
220 dev
->sink_rect
.height
= bt
->height
;
221 size
= V4L2_DV_BT_FRAME_WIDTH(bt
) * V4L2_DV_BT_FRAME_HEIGHT(bt
);
223 if (can_reduce_fps(bt
) && (bt
->flags
& V4L2_DV_FL_REDUCED_FPS
))
224 pixelclock
= div_u64(bt
->pixelclock
* 1000, 1001);
226 pixelclock
= bt
->pixelclock
;
228 dev
->timeperframe_vid_out
= (struct v4l2_fract
) {
229 size
/ 100, (u32
)pixelclock
/ 100
232 dev
->field_out
= V4L2_FIELD_ALTERNATE
;
234 dev
->field_out
= V4L2_FIELD_NONE
;
235 if (!dev
->dvi_d_out
&& (bt
->flags
& V4L2_DV_FL_IS_CE_VIDEO
)) {
236 if (bt
->width
== 720 && bt
->height
<= 576)
237 dev
->colorspace_out
= V4L2_COLORSPACE_SMPTE170M
;
239 dev
->colorspace_out
= V4L2_COLORSPACE_REC709
;
241 dev
->colorspace_out
= V4L2_COLORSPACE_SRGB
;
245 dev
->xfer_func_out
= V4L2_XFER_FUNC_DEFAULT
;
246 dev
->ycbcr_enc_out
= V4L2_YCBCR_ENC_DEFAULT
;
247 dev
->hsv_enc_out
= V4L2_HSV_ENC_180
;
248 dev
->quantization_out
= V4L2_QUANTIZATION_DEFAULT
;
249 dev
->compose_out
= dev
->sink_rect
;
250 dev
->compose_bounds_out
= dev
->sink_rect
;
251 dev
->crop_out
= dev
->compose_out
;
252 if (V4L2_FIELD_HAS_T_OR_B(dev
->field_out
))
253 dev
->crop_out
.height
/= 2;
254 dev
->fmt_out_rect
= dev
->crop_out
;
255 for (p
= 0; p
< dev
->fmt_out
->planes
; p
++)
256 dev
->bytesperline_out
[p
] =
257 (dev
->sink_rect
.width
* dev
->fmt_out
->bit_depth
[p
]) / 8;
260 /* Map the field to something that is valid for the current output */
261 static enum v4l2_field
vivid_field_out(struct vivid_dev
*dev
, enum v4l2_field field
)
263 if (vivid_is_svid_out(dev
)) {
265 case V4L2_FIELD_INTERLACED_TB
:
266 case V4L2_FIELD_INTERLACED_BT
:
267 case V4L2_FIELD_SEQ_TB
:
268 case V4L2_FIELD_SEQ_BT
:
269 case V4L2_FIELD_ALTERNATE
:
271 case V4L2_FIELD_INTERLACED
:
273 return V4L2_FIELD_INTERLACED
;
276 if (vivid_is_hdmi_out(dev
))
277 return dev
->dv_timings_out
.bt
.interlaced
? V4L2_FIELD_ALTERNATE
:
279 return V4L2_FIELD_NONE
;
282 static enum tpg_pixel_aspect
vivid_get_pixel_aspect(const struct vivid_dev
*dev
)
284 if (vivid_is_svid_out(dev
))
285 return (dev
->std_out
& V4L2_STD_525_60
) ?
286 TPG_PIXEL_ASPECT_NTSC
: TPG_PIXEL_ASPECT_PAL
;
288 if (vivid_is_hdmi_out(dev
) &&
289 dev
->sink_rect
.width
== 720 && dev
->sink_rect
.height
<= 576)
290 return dev
->sink_rect
.height
== 480 ?
291 TPG_PIXEL_ASPECT_NTSC
: TPG_PIXEL_ASPECT_PAL
;
293 return TPG_PIXEL_ASPECT_SQUARE
;
296 int vivid_g_fmt_vid_out(struct file
*file
, void *priv
,
297 struct v4l2_format
*f
)
299 struct vivid_dev
*dev
= video_drvdata(file
);
300 struct v4l2_pix_format_mplane
*mp
= &f
->fmt
.pix_mp
;
301 const struct vivid_fmt
*fmt
= dev
->fmt_out
;
304 mp
->width
= dev
->fmt_out_rect
.width
;
305 mp
->height
= dev
->fmt_out_rect
.height
;
306 mp
->field
= dev
->field_out
;
307 mp
->pixelformat
= fmt
->fourcc
;
308 mp
->colorspace
= dev
->colorspace_out
;
309 mp
->xfer_func
= dev
->xfer_func_out
;
310 mp
->ycbcr_enc
= dev
->ycbcr_enc_out
;
311 mp
->quantization
= dev
->quantization_out
;
312 mp
->num_planes
= fmt
->buffers
;
313 for (p
= 0; p
< mp
->num_planes
; p
++) {
314 mp
->plane_fmt
[p
].bytesperline
= dev
->bytesperline_out
[p
];
315 mp
->plane_fmt
[p
].sizeimage
=
316 mp
->plane_fmt
[p
].bytesperline
* mp
->height
;
318 for (p
= fmt
->buffers
; p
< fmt
->planes
; p
++) {
319 unsigned stride
= dev
->bytesperline_out
[p
];
321 mp
->plane_fmt
[0].sizeimage
+=
322 (stride
* mp
->height
) / fmt
->vdownsampling
[p
];
327 int vivid_try_fmt_vid_out(struct file
*file
, void *priv
,
328 struct v4l2_format
*f
)
330 struct vivid_dev
*dev
= video_drvdata(file
);
331 struct v4l2_bt_timings
*bt
= &dev
->dv_timings_out
.bt
;
332 struct v4l2_pix_format_mplane
*mp
= &f
->fmt
.pix_mp
;
333 struct v4l2_plane_pix_format
*pfmt
= mp
->plane_fmt
;
334 const struct vivid_fmt
*fmt
;
335 unsigned bytesperline
, max_bpl
;
340 fmt
= vivid_get_format(dev
, mp
->pixelformat
);
342 dprintk(dev
, 1, "Fourcc format (0x%08x) unknown.\n",
344 mp
->pixelformat
= V4L2_PIX_FMT_YUYV
;
345 fmt
= vivid_get_format(dev
, mp
->pixelformat
);
348 mp
->field
= vivid_field_out(dev
, mp
->field
);
349 if (vivid_is_svid_out(dev
)) {
351 h
= (dev
->std_out
& V4L2_STD_525_60
) ? 480 : 576;
353 w
= dev
->sink_rect
.width
;
354 h
= dev
->sink_rect
.height
;
356 if (V4L2_FIELD_HAS_T_OR_B(mp
->field
))
358 if (!dev
->has_scaler_out
&& !dev
->has_crop_out
&& !dev
->has_compose_out
) {
360 mp
->height
= h
/ factor
;
362 struct v4l2_rect r
= { 0, 0, mp
->width
, mp
->height
* factor
};
364 v4l2_rect_set_min_size(&r
, &vivid_min_rect
);
365 v4l2_rect_set_max_size(&r
, &vivid_max_rect
);
366 if (dev
->has_scaler_out
&& !dev
->has_crop_out
) {
367 struct v4l2_rect max_r
= { 0, 0, MAX_ZOOM
* w
, MAX_ZOOM
* h
};
369 v4l2_rect_set_max_size(&r
, &max_r
);
370 } else if (!dev
->has_scaler_out
&& dev
->has_compose_out
&& !dev
->has_crop_out
) {
371 v4l2_rect_set_max_size(&r
, &dev
->sink_rect
);
372 } else if (!dev
->has_scaler_out
&& !dev
->has_compose_out
) {
373 v4l2_rect_set_min_size(&r
, &dev
->sink_rect
);
376 mp
->height
= r
.height
/ factor
;
379 /* This driver supports custom bytesperline values */
381 mp
->num_planes
= fmt
->buffers
;
382 for (p
= 0; p
< fmt
->buffers
; p
++) {
383 /* Calculate the minimum supported bytesperline value */
384 bytesperline
= (mp
->width
* fmt
->bit_depth
[p
]) >> 3;
385 /* Calculate the maximum supported bytesperline value */
386 max_bpl
= (MAX_ZOOM
* MAX_WIDTH
* fmt
->bit_depth
[p
]) >> 3;
388 if (pfmt
[p
].bytesperline
> max_bpl
)
389 pfmt
[p
].bytesperline
= max_bpl
;
390 if (pfmt
[p
].bytesperline
< bytesperline
)
391 pfmt
[p
].bytesperline
= bytesperline
;
393 pfmt
[p
].sizeimage
= (pfmt
[p
].bytesperline
* mp
->height
) /
394 fmt
->vdownsampling
[p
];
396 memset(pfmt
[p
].reserved
, 0, sizeof(pfmt
[p
].reserved
));
398 for (p
= fmt
->buffers
; p
< fmt
->planes
; p
++)
399 pfmt
[0].sizeimage
+= (pfmt
[0].bytesperline
* mp
->height
*
400 (fmt
->bit_depth
[p
] / fmt
->vdownsampling
[p
])) /
401 (fmt
->bit_depth
[0] / fmt
->vdownsampling
[0]);
403 mp
->xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
404 mp
->ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
405 mp
->quantization
= V4L2_QUANTIZATION_DEFAULT
;
406 if (vivid_is_svid_out(dev
)) {
407 mp
->colorspace
= V4L2_COLORSPACE_SMPTE170M
;
408 } else if (dev
->dvi_d_out
|| !(bt
->flags
& V4L2_DV_FL_IS_CE_VIDEO
)) {
409 mp
->colorspace
= V4L2_COLORSPACE_SRGB
;
411 mp
->quantization
= V4L2_QUANTIZATION_LIM_RANGE
;
412 } else if (bt
->width
== 720 && bt
->height
<= 576) {
413 mp
->colorspace
= V4L2_COLORSPACE_SMPTE170M
;
414 } else if (mp
->colorspace
!= V4L2_COLORSPACE_SMPTE170M
&&
415 mp
->colorspace
!= V4L2_COLORSPACE_REC709
&&
416 mp
->colorspace
!= V4L2_COLORSPACE_ADOBERGB
&&
417 mp
->colorspace
!= V4L2_COLORSPACE_BT2020
&&
418 mp
->colorspace
!= V4L2_COLORSPACE_SRGB
) {
419 mp
->colorspace
= V4L2_COLORSPACE_REC709
;
421 memset(mp
->reserved
, 0, sizeof(mp
->reserved
));
425 int vivid_s_fmt_vid_out(struct file
*file
, void *priv
,
426 struct v4l2_format
*f
)
428 struct v4l2_pix_format_mplane
*mp
= &f
->fmt
.pix_mp
;
429 struct vivid_dev
*dev
= video_drvdata(file
);
430 struct v4l2_rect
*crop
= &dev
->crop_out
;
431 struct v4l2_rect
*compose
= &dev
->compose_out
;
432 struct vb2_queue
*q
= &dev
->vb_vid_out_q
;
433 int ret
= vivid_try_fmt_vid_out(file
, priv
, f
);
440 if (vb2_is_busy(q
) &&
441 (vivid_is_svid_out(dev
) ||
442 mp
->width
!= dev
->fmt_out_rect
.width
||
443 mp
->height
!= dev
->fmt_out_rect
.height
||
444 mp
->pixelformat
!= dev
->fmt_out
->fourcc
||
445 mp
->field
!= dev
->field_out
)) {
446 dprintk(dev
, 1, "%s device busy\n", __func__
);
451 * Allow for changing the colorspace on the fly. Useful for testing
452 * purposes, and it is something that HDMI transmitters are able
458 dev
->fmt_out
= vivid_get_format(dev
, mp
->pixelformat
);
459 if (V4L2_FIELD_HAS_T_OR_B(mp
->field
))
462 if (dev
->has_scaler_out
|| dev
->has_crop_out
|| dev
->has_compose_out
) {
463 struct v4l2_rect r
= { 0, 0, mp
->width
, mp
->height
};
465 if (dev
->has_scaler_out
) {
466 if (dev
->has_crop_out
)
467 v4l2_rect_map_inside(crop
, &r
);
470 if (dev
->has_compose_out
&& !dev
->has_crop_out
) {
471 struct v4l2_rect min_r
= {
474 factor
* r
.height
/ MAX_ZOOM
476 struct v4l2_rect max_r
= {
479 factor
* r
.height
* MAX_ZOOM
482 v4l2_rect_set_min_size(compose
, &min_r
);
483 v4l2_rect_set_max_size(compose
, &max_r
);
484 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
485 } else if (dev
->has_compose_out
) {
486 struct v4l2_rect min_r
= {
488 crop
->width
/ MAX_ZOOM
,
489 factor
* crop
->height
/ MAX_ZOOM
491 struct v4l2_rect max_r
= {
493 crop
->width
* MAX_ZOOM
,
494 factor
* crop
->height
* MAX_ZOOM
497 v4l2_rect_set_min_size(compose
, &min_r
);
498 v4l2_rect_set_max_size(compose
, &max_r
);
499 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
501 } else if (dev
->has_compose_out
&& !dev
->has_crop_out
) {
502 v4l2_rect_set_size_to(crop
, &r
);
504 v4l2_rect_set_size_to(compose
, &r
);
505 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
506 } else if (!dev
->has_compose_out
) {
507 v4l2_rect_map_inside(crop
, &r
);
509 v4l2_rect_set_size_to(compose
, &r
);
512 v4l2_rect_set_max_size(compose
, &r
);
513 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
515 crop
->height
*= factor
;
516 v4l2_rect_set_size_to(crop
, compose
);
517 v4l2_rect_map_inside(crop
, &r
);
519 crop
->height
/= factor
;
522 struct v4l2_rect r
= { 0, 0, mp
->width
, mp
->height
};
524 v4l2_rect_set_size_to(crop
, &r
);
526 v4l2_rect_set_size_to(compose
, &r
);
529 dev
->fmt_out_rect
.width
= mp
->width
;
530 dev
->fmt_out_rect
.height
= mp
->height
;
531 for (p
= 0; p
< mp
->num_planes
; p
++)
532 dev
->bytesperline_out
[p
] = mp
->plane_fmt
[p
].bytesperline
;
533 for (p
= dev
->fmt_out
->buffers
; p
< dev
->fmt_out
->planes
; p
++)
534 dev
->bytesperline_out
[p
] =
535 (dev
->bytesperline_out
[0] * dev
->fmt_out
->bit_depth
[p
]) /
536 dev
->fmt_out
->bit_depth
[0];
537 dev
->field_out
= mp
->field
;
538 if (vivid_is_svid_out(dev
))
539 dev
->tv_field_out
= mp
->field
;
542 dev
->colorspace_out
= mp
->colorspace
;
543 dev
->xfer_func_out
= mp
->xfer_func
;
544 dev
->ycbcr_enc_out
= mp
->ycbcr_enc
;
545 dev
->quantization_out
= mp
->quantization
;
546 if (dev
->loop_video
) {
547 vivid_send_source_change(dev
, SVID
);
548 vivid_send_source_change(dev
, HDMI
);
553 int vidioc_g_fmt_vid_out_mplane(struct file
*file
, void *priv
,
554 struct v4l2_format
*f
)
556 struct vivid_dev
*dev
= video_drvdata(file
);
558 if (!dev
->multiplanar
)
560 return vivid_g_fmt_vid_out(file
, priv
, f
);
563 int vidioc_try_fmt_vid_out_mplane(struct file
*file
, void *priv
,
564 struct v4l2_format
*f
)
566 struct vivid_dev
*dev
= video_drvdata(file
);
568 if (!dev
->multiplanar
)
570 return vivid_try_fmt_vid_out(file
, priv
, f
);
573 int vidioc_s_fmt_vid_out_mplane(struct file
*file
, void *priv
,
574 struct v4l2_format
*f
)
576 struct vivid_dev
*dev
= video_drvdata(file
);
578 if (!dev
->multiplanar
)
580 return vivid_s_fmt_vid_out(file
, priv
, f
);
583 int vidioc_g_fmt_vid_out(struct file
*file
, void *priv
,
584 struct v4l2_format
*f
)
586 struct vivid_dev
*dev
= video_drvdata(file
);
588 if (dev
->multiplanar
)
590 return fmt_sp2mp_func(file
, priv
, f
, vivid_g_fmt_vid_out
);
593 int vidioc_try_fmt_vid_out(struct file
*file
, void *priv
,
594 struct v4l2_format
*f
)
596 struct vivid_dev
*dev
= video_drvdata(file
);
598 if (dev
->multiplanar
)
600 return fmt_sp2mp_func(file
, priv
, f
, vivid_try_fmt_vid_out
);
603 int vidioc_s_fmt_vid_out(struct file
*file
, void *priv
,
604 struct v4l2_format
*f
)
606 struct vivid_dev
*dev
= video_drvdata(file
);
608 if (dev
->multiplanar
)
610 return fmt_sp2mp_func(file
, priv
, f
, vivid_s_fmt_vid_out
);
613 int vivid_vid_out_g_selection(struct file
*file
, void *priv
,
614 struct v4l2_selection
*sel
)
616 struct vivid_dev
*dev
= video_drvdata(file
);
618 if (!dev
->has_crop_out
&& !dev
->has_compose_out
)
620 if (sel
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
623 sel
->r
.left
= sel
->r
.top
= 0;
624 switch (sel
->target
) {
625 case V4L2_SEL_TGT_CROP
:
626 if (!dev
->has_crop_out
)
628 sel
->r
= dev
->crop_out
;
630 case V4L2_SEL_TGT_CROP_DEFAULT
:
631 if (!dev
->has_crop_out
)
633 sel
->r
= dev
->fmt_out_rect
;
635 case V4L2_SEL_TGT_CROP_BOUNDS
:
636 if (!dev
->has_crop_out
)
638 sel
->r
= vivid_max_rect
;
640 case V4L2_SEL_TGT_COMPOSE
:
641 if (!dev
->has_compose_out
)
643 sel
->r
= dev
->compose_out
;
645 case V4L2_SEL_TGT_COMPOSE_DEFAULT
:
646 case V4L2_SEL_TGT_COMPOSE_BOUNDS
:
647 if (!dev
->has_compose_out
)
649 sel
->r
= dev
->sink_rect
;
657 int vivid_vid_out_s_selection(struct file
*file
, void *fh
, struct v4l2_selection
*s
)
659 struct vivid_dev
*dev
= video_drvdata(file
);
660 struct v4l2_rect
*crop
= &dev
->crop_out
;
661 struct v4l2_rect
*compose
= &dev
->compose_out
;
662 unsigned factor
= V4L2_FIELD_HAS_T_OR_B(dev
->field_out
) ? 2 : 1;
665 if (!dev
->has_crop_out
&& !dev
->has_compose_out
)
667 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
671 case V4L2_SEL_TGT_CROP
:
672 if (!dev
->has_crop_out
)
674 ret
= vivid_vid_adjust_sel(s
->flags
, &s
->r
);
677 v4l2_rect_set_min_size(&s
->r
, &vivid_min_rect
);
678 v4l2_rect_set_max_size(&s
->r
, &dev
->fmt_out_rect
);
679 if (dev
->has_scaler_out
) {
680 struct v4l2_rect max_rect
= {
682 dev
->sink_rect
.width
* MAX_ZOOM
,
683 (dev
->sink_rect
.height
/ factor
) * MAX_ZOOM
686 v4l2_rect_set_max_size(&s
->r
, &max_rect
);
687 if (dev
->has_compose_out
) {
688 struct v4l2_rect min_rect
= {
690 s
->r
.width
/ MAX_ZOOM
,
691 (s
->r
.height
* factor
) / MAX_ZOOM
693 struct v4l2_rect max_rect
= {
695 s
->r
.width
* MAX_ZOOM
,
696 (s
->r
.height
* factor
) * MAX_ZOOM
699 v4l2_rect_set_min_size(compose
, &min_rect
);
700 v4l2_rect_set_max_size(compose
, &max_rect
);
701 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
703 } else if (dev
->has_compose_out
) {
705 s
->r
.height
*= factor
;
706 v4l2_rect_set_max_size(&s
->r
, &dev
->sink_rect
);
707 v4l2_rect_set_size_to(compose
, &s
->r
);
708 v4l2_rect_map_inside(compose
, &dev
->compose_bounds_out
);
710 s
->r
.height
/= factor
;
712 v4l2_rect_set_size_to(&s
->r
, &dev
->sink_rect
);
713 s
->r
.height
/= factor
;
715 v4l2_rect_map_inside(&s
->r
, &dev
->fmt_out_rect
);
718 case V4L2_SEL_TGT_COMPOSE
:
719 if (!dev
->has_compose_out
)
721 ret
= vivid_vid_adjust_sel(s
->flags
, &s
->r
);
724 v4l2_rect_set_min_size(&s
->r
, &vivid_min_rect
);
725 v4l2_rect_set_max_size(&s
->r
, &dev
->sink_rect
);
726 v4l2_rect_map_inside(&s
->r
, &dev
->compose_bounds_out
);
728 s
->r
.height
/= factor
;
729 if (dev
->has_scaler_out
) {
730 struct v4l2_rect fmt
= dev
->fmt_out_rect
;
731 struct v4l2_rect max_rect
= {
733 s
->r
.width
* MAX_ZOOM
,
734 s
->r
.height
* MAX_ZOOM
736 struct v4l2_rect min_rect
= {
738 s
->r
.width
/ MAX_ZOOM
,
739 s
->r
.height
/ MAX_ZOOM
742 v4l2_rect_set_min_size(&fmt
, &min_rect
);
743 if (!dev
->has_crop_out
)
744 v4l2_rect_set_max_size(&fmt
, &max_rect
);
745 if (!v4l2_rect_same_size(&dev
->fmt_out_rect
, &fmt
) &&
746 vb2_is_busy(&dev
->vb_vid_out_q
))
748 if (dev
->has_crop_out
) {
749 v4l2_rect_set_min_size(crop
, &min_rect
);
750 v4l2_rect_set_max_size(crop
, &max_rect
);
752 dev
->fmt_out_rect
= fmt
;
753 } else if (dev
->has_crop_out
) {
754 struct v4l2_rect fmt
= dev
->fmt_out_rect
;
756 v4l2_rect_set_min_size(&fmt
, &s
->r
);
757 if (!v4l2_rect_same_size(&dev
->fmt_out_rect
, &fmt
) &&
758 vb2_is_busy(&dev
->vb_vid_out_q
))
760 dev
->fmt_out_rect
= fmt
;
761 v4l2_rect_set_size_to(crop
, &s
->r
);
762 v4l2_rect_map_inside(crop
, &dev
->fmt_out_rect
);
764 if (!v4l2_rect_same_size(&s
->r
, &dev
->fmt_out_rect
) &&
765 vb2_is_busy(&dev
->vb_vid_out_q
))
767 v4l2_rect_set_size_to(&dev
->fmt_out_rect
, &s
->r
);
768 v4l2_rect_set_size_to(crop
, &s
->r
);
769 crop
->height
/= factor
;
770 v4l2_rect_map_inside(crop
, &dev
->fmt_out_rect
);
773 s
->r
.height
*= factor
;
774 if (dev
->bitmap_out
&& (compose
->width
!= s
->r
.width
||
775 compose
->height
!= s
->r
.height
)) {
776 kfree(dev
->bitmap_out
);
777 dev
->bitmap_out
= NULL
;
788 int vivid_vid_out_cropcap(struct file
*file
, void *priv
,
789 struct v4l2_cropcap
*cap
)
791 struct vivid_dev
*dev
= video_drvdata(file
);
793 if (cap
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
796 switch (vivid_get_pixel_aspect(dev
)) {
797 case TPG_PIXEL_ASPECT_NTSC
:
798 cap
->pixelaspect
.numerator
= 11;
799 cap
->pixelaspect
.denominator
= 10;
801 case TPG_PIXEL_ASPECT_PAL
:
802 cap
->pixelaspect
.numerator
= 54;
803 cap
->pixelaspect
.denominator
= 59;
805 case TPG_PIXEL_ASPECT_SQUARE
:
806 cap
->pixelaspect
.numerator
= 1;
807 cap
->pixelaspect
.denominator
= 1;
813 int vidioc_g_fmt_vid_out_overlay(struct file
*file
, void *priv
,
814 struct v4l2_format
*f
)
816 struct vivid_dev
*dev
= video_drvdata(file
);
817 const struct v4l2_rect
*compose
= &dev
->compose_out
;
818 struct v4l2_window
*win
= &f
->fmt
.win
;
819 unsigned clipcount
= win
->clipcount
;
823 win
->w
.top
= dev
->overlay_out_top
;
824 win
->w
.left
= dev
->overlay_out_left
;
825 win
->w
.width
= compose
->width
;
826 win
->w
.height
= compose
->height
;
827 win
->clipcount
= dev
->clipcount_out
;
828 win
->field
= V4L2_FIELD_ANY
;
829 win
->chromakey
= dev
->chromakey_out
;
830 win
->global_alpha
= dev
->global_alpha_out
;
831 if (clipcount
> dev
->clipcount_out
)
832 clipcount
= dev
->clipcount_out
;
833 if (dev
->bitmap_out
== NULL
)
835 else if (win
->bitmap
) {
836 if (copy_to_user(win
->bitmap
, dev
->bitmap_out
,
837 ((dev
->compose_out
.width
+ 7) / 8) * dev
->compose_out
.height
))
840 if (clipcount
&& win
->clips
) {
841 if (copy_to_user(win
->clips
, dev
->clips_out
,
842 clipcount
* sizeof(dev
->clips_out
[0])))
848 int vidioc_try_fmt_vid_out_overlay(struct file
*file
, void *priv
,
849 struct v4l2_format
*f
)
851 struct vivid_dev
*dev
= video_drvdata(file
);
852 const struct v4l2_rect
*compose
= &dev
->compose_out
;
853 struct v4l2_window
*win
= &f
->fmt
.win
;
858 win
->w
.left
= clamp_t(int, win
->w
.left
,
859 -dev
->display_width
, dev
->display_width
);
860 win
->w
.top
= clamp_t(int, win
->w
.top
,
861 -dev
->display_height
, dev
->display_height
);
862 win
->w
.width
= compose
->width
;
863 win
->w
.height
= compose
->height
;
865 * It makes no sense for an OSD to overlay only top or bottom fields,
866 * so always set this to ANY.
868 win
->field
= V4L2_FIELD_ANY
;
869 if (win
->clipcount
&& !win
->clips
)
871 if (win
->clipcount
> MAX_CLIPS
)
872 win
->clipcount
= MAX_CLIPS
;
873 if (win
->clipcount
) {
874 if (copy_from_user(dev
->try_clips_out
, win
->clips
,
875 win
->clipcount
* sizeof(dev
->clips_out
[0])))
877 for (i
= 0; i
< win
->clipcount
; i
++) {
878 struct v4l2_rect
*r
= &dev
->try_clips_out
[i
].c
;
880 r
->top
= clamp_t(s32
, r
->top
, 0, dev
->display_height
- 1);
881 r
->height
= clamp_t(s32
, r
->height
, 1, dev
->display_height
- r
->top
);
882 r
->left
= clamp_t(u32
, r
->left
, 0, dev
->display_width
- 1);
883 r
->width
= clamp_t(u32
, r
->width
, 1, dev
->display_width
- r
->left
);
886 * Yeah, so sue me, it's an O(n^2) algorithm. But n is a small
887 * number and it's typically a one-time deal.
889 for (i
= 0; i
< win
->clipcount
- 1; i
++) {
890 struct v4l2_rect
*r1
= &dev
->try_clips_out
[i
].c
;
892 for (j
= i
+ 1; j
< win
->clipcount
; j
++) {
893 struct v4l2_rect
*r2
= &dev
->try_clips_out
[j
].c
;
895 if (v4l2_rect_overlap(r1
, r2
))
899 if (copy_to_user(win
->clips
, dev
->try_clips_out
,
900 win
->clipcount
* sizeof(dev
->clips_out
[0])))
906 int vidioc_s_fmt_vid_out_overlay(struct file
*file
, void *priv
,
907 struct v4l2_format
*f
)
909 struct vivid_dev
*dev
= video_drvdata(file
);
910 const struct v4l2_rect
*compose
= &dev
->compose_out
;
911 struct v4l2_window
*win
= &f
->fmt
.win
;
912 int ret
= vidioc_try_fmt_vid_out_overlay(file
, priv
, f
);
913 unsigned bitmap_size
= ((compose
->width
+ 7) / 8) * compose
->height
;
914 unsigned clips_size
= win
->clipcount
* sizeof(dev
->clips_out
[0]);
915 void *new_bitmap
= NULL
;
921 new_bitmap
= memdup_user(win
->bitmap
, bitmap_size
);
923 if (IS_ERR(new_bitmap
))
924 return PTR_ERR(new_bitmap
);
927 dev
->overlay_out_top
= win
->w
.top
;
928 dev
->overlay_out_left
= win
->w
.left
;
929 kfree(dev
->bitmap_out
);
930 dev
->bitmap_out
= new_bitmap
;
931 dev
->clipcount_out
= win
->clipcount
;
932 if (dev
->clipcount_out
)
933 memcpy(dev
->clips_out
, dev
->try_clips_out
, clips_size
);
934 dev
->chromakey_out
= win
->chromakey
;
935 dev
->global_alpha_out
= win
->global_alpha
;
939 int vivid_vid_out_overlay(struct file
*file
, void *fh
, unsigned i
)
941 struct vivid_dev
*dev
= video_drvdata(file
);
943 if (i
&& !dev
->fmt_out
->can_do_overlay
) {
944 dprintk(dev
, 1, "unsupported output format for output overlay\n");
948 dev
->overlay_out_enabled
= i
;
952 int vivid_vid_out_g_fbuf(struct file
*file
, void *fh
,
953 struct v4l2_framebuffer
*a
)
955 struct vivid_dev
*dev
= video_drvdata(file
);
957 a
->capability
= V4L2_FBUF_CAP_EXTERNOVERLAY
|
958 V4L2_FBUF_CAP_BITMAP_CLIPPING
|
959 V4L2_FBUF_CAP_LIST_CLIPPING
|
960 V4L2_FBUF_CAP_CHROMAKEY
|
961 V4L2_FBUF_CAP_SRC_CHROMAKEY
|
962 V4L2_FBUF_CAP_GLOBAL_ALPHA
|
963 V4L2_FBUF_CAP_LOCAL_ALPHA
|
964 V4L2_FBUF_CAP_LOCAL_INV_ALPHA
;
965 a
->flags
= V4L2_FBUF_FLAG_OVERLAY
| dev
->fbuf_out_flags
;
966 a
->base
= (void *)dev
->video_pbase
;
967 a
->fmt
.width
= dev
->display_width
;
968 a
->fmt
.height
= dev
->display_height
;
969 if (dev
->fb_defined
.green
.length
== 5)
970 a
->fmt
.pixelformat
= V4L2_PIX_FMT_ARGB555
;
972 a
->fmt
.pixelformat
= V4L2_PIX_FMT_RGB565
;
973 a
->fmt
.bytesperline
= dev
->display_byte_stride
;
974 a
->fmt
.sizeimage
= a
->fmt
.height
* a
->fmt
.bytesperline
;
975 a
->fmt
.field
= V4L2_FIELD_NONE
;
976 a
->fmt
.colorspace
= V4L2_COLORSPACE_SRGB
;
981 int vivid_vid_out_s_fbuf(struct file
*file
, void *fh
,
982 const struct v4l2_framebuffer
*a
)
984 struct vivid_dev
*dev
= video_drvdata(file
);
985 const unsigned chroma_flags
= V4L2_FBUF_FLAG_CHROMAKEY
|
986 V4L2_FBUF_FLAG_SRC_CHROMAKEY
;
987 const unsigned alpha_flags
= V4L2_FBUF_FLAG_GLOBAL_ALPHA
|
988 V4L2_FBUF_FLAG_LOCAL_ALPHA
|
989 V4L2_FBUF_FLAG_LOCAL_INV_ALPHA
;
992 if ((a
->flags
& chroma_flags
) == chroma_flags
)
994 switch (a
->flags
& alpha_flags
) {
996 case V4L2_FBUF_FLAG_GLOBAL_ALPHA
:
997 case V4L2_FBUF_FLAG_LOCAL_ALPHA
:
998 case V4L2_FBUF_FLAG_LOCAL_INV_ALPHA
:
1003 dev
->fbuf_out_flags
&= ~(chroma_flags
| alpha_flags
);
1004 dev
->fbuf_out_flags
= a
->flags
& (chroma_flags
| alpha_flags
);
1008 static const struct v4l2_audioout vivid_audio_outputs
[] = {
1009 { 0, "Line-Out 1" },
1010 { 1, "Line-Out 2" },
1013 int vidioc_enum_output(struct file
*file
, void *priv
,
1014 struct v4l2_output
*out
)
1016 struct vivid_dev
*dev
= video_drvdata(file
);
1018 if (out
->index
>= dev
->num_outputs
)
1021 out
->type
= V4L2_OUTPUT_TYPE_ANALOG
;
1022 switch (dev
->output_type
[out
->index
]) {
1024 snprintf(out
->name
, sizeof(out
->name
), "S-Video %u",
1025 dev
->output_name_counter
[out
->index
]);
1026 out
->std
= V4L2_STD_ALL
;
1027 if (dev
->has_audio_outputs
)
1028 out
->audioset
= (1 << ARRAY_SIZE(vivid_audio_outputs
)) - 1;
1029 out
->capabilities
= V4L2_OUT_CAP_STD
;
1032 snprintf(out
->name
, sizeof(out
->name
), "HDMI %u",
1033 dev
->output_name_counter
[out
->index
]);
1034 out
->capabilities
= V4L2_OUT_CAP_DV_TIMINGS
;
1040 int vidioc_g_output(struct file
*file
, void *priv
, unsigned *o
)
1042 struct vivid_dev
*dev
= video_drvdata(file
);
1048 int vidioc_s_output(struct file
*file
, void *priv
, unsigned o
)
1050 struct vivid_dev
*dev
= video_drvdata(file
);
1052 if (o
>= dev
->num_outputs
)
1055 if (o
== dev
->output
)
1058 if (vb2_is_busy(&dev
->vb_vid_out_q
) || vb2_is_busy(&dev
->vb_vbi_out_q
))
1062 dev
->tv_audio_output
= 0;
1063 if (dev
->output_type
[o
] == SVID
)
1064 dev
->vid_out_dev
.tvnorms
= V4L2_STD_ALL
;
1066 dev
->vid_out_dev
.tvnorms
= 0;
1068 dev
->vbi_out_dev
.tvnorms
= dev
->vid_out_dev
.tvnorms
;
1069 vivid_update_format_out(dev
);
1073 int vidioc_enumaudout(struct file
*file
, void *fh
, struct v4l2_audioout
*vout
)
1075 if (vout
->index
>= ARRAY_SIZE(vivid_audio_outputs
))
1077 *vout
= vivid_audio_outputs
[vout
->index
];
1081 int vidioc_g_audout(struct file
*file
, void *fh
, struct v4l2_audioout
*vout
)
1083 struct vivid_dev
*dev
= video_drvdata(file
);
1085 if (!vivid_is_svid_out(dev
))
1087 *vout
= vivid_audio_outputs
[dev
->tv_audio_output
];
1091 int vidioc_s_audout(struct file
*file
, void *fh
, const struct v4l2_audioout
*vout
)
1093 struct vivid_dev
*dev
= video_drvdata(file
);
1095 if (!vivid_is_svid_out(dev
))
1097 if (vout
->index
>= ARRAY_SIZE(vivid_audio_outputs
))
1099 dev
->tv_audio_output
= vout
->index
;
1103 int vivid_vid_out_s_std(struct file
*file
, void *priv
, v4l2_std_id id
)
1105 struct vivid_dev
*dev
= video_drvdata(file
);
1107 if (!vivid_is_svid_out(dev
))
1109 if (dev
->std_out
== id
)
1111 if (vb2_is_busy(&dev
->vb_vid_out_q
) || vb2_is_busy(&dev
->vb_vbi_out_q
))
1114 vivid_update_format_out(dev
);
1118 static bool valid_cvt_gtf_timings(struct v4l2_dv_timings
*timings
)
1120 struct v4l2_bt_timings
*bt
= &timings
->bt
;
1122 if ((bt
->standards
& (V4L2_DV_BT_STD_CVT
| V4L2_DV_BT_STD_GTF
)) &&
1123 v4l2_valid_dv_timings(timings
, &vivid_dv_timings_cap
, NULL
, NULL
))
1129 int vivid_vid_out_s_dv_timings(struct file
*file
, void *_fh
,
1130 struct v4l2_dv_timings
*timings
)
1132 struct vivid_dev
*dev
= video_drvdata(file
);
1133 if (!vivid_is_hdmi_out(dev
))
1135 if (!v4l2_find_dv_timings_cap(timings
, &vivid_dv_timings_cap
,
1137 !valid_cvt_gtf_timings(timings
))
1139 if (v4l2_match_dv_timings(timings
, &dev
->dv_timings_out
, 0, true))
1141 if (vb2_is_busy(&dev
->vb_vid_out_q
))
1143 dev
->dv_timings_out
= *timings
;
1144 vivid_update_format_out(dev
);
1148 int vivid_vid_out_g_parm(struct file
*file
, void *priv
,
1149 struct v4l2_streamparm
*parm
)
1151 struct vivid_dev
*dev
= video_drvdata(file
);
1153 if (parm
->type
!= (dev
->multiplanar
?
1154 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
:
1155 V4L2_BUF_TYPE_VIDEO_OUTPUT
))
1158 parm
->parm
.output
.capability
= V4L2_CAP_TIMEPERFRAME
;
1159 parm
->parm
.output
.timeperframe
= dev
->timeperframe_vid_out
;
1160 parm
->parm
.output
.writebuffers
= 1;
1165 int vidioc_subscribe_event(struct v4l2_fh
*fh
,
1166 const struct v4l2_event_subscription
*sub
)
1168 switch (sub
->type
) {
1169 case V4L2_EVENT_SOURCE_CHANGE
:
1170 if (fh
->vdev
->vfl_dir
== VFL_DIR_RX
)
1171 return v4l2_src_change_event_subscribe(fh
, sub
);
1174 return v4l2_ctrl_subscribe_event(fh
, sub
);