1/* 2 * vivid-vid-out.c - video output support functions. 3 * 4 * Copyright 2014 Cisco Systems, Inc. and/or its affiliates. All rights reserved. 5 * 6 * This program is free software; you may redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; version 2 of the License. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 11 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 12 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 13 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 14 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 15 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 16 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 17 * SOFTWARE. 18 */ 19 20#include <linux/errno.h> 21#include <linux/kernel.h> 22#include <linux/sched.h> 23#include <linux/videodev2.h> 24#include <linux/v4l2-dv-timings.h> 25#include <media/v4l2-common.h> 26#include <media/v4l2-event.h> 27#include <media/v4l2-dv-timings.h> 28 29#include "vivid-core.h" 30#include "vivid-vid-common.h" 31#include "vivid-kthread-out.h" 32#include "vivid-vid-out.h" 33 34static int vid_out_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt, 35 unsigned *nbuffers, unsigned *nplanes, 36 unsigned sizes[], void *alloc_ctxs[]) 37{ 38 struct vivid_dev *dev = vb2_get_drv_priv(vq); 39 const struct vivid_fmt *vfmt = dev->fmt_out; 40 unsigned planes = vfmt->buffers; 41 unsigned h = dev->fmt_out_rect.height; 42 unsigned size = dev->bytesperline_out[0] * h; 43 unsigned p; 44 45 for (p = vfmt->buffers; p < vfmt->planes; p++) 46 size += dev->bytesperline_out[p] * h / vfmt->vdownsampling[p]; 47 48 if (dev->field_out == V4L2_FIELD_ALTERNATE) { 49 /* 50 * You cannot use write() with FIELD_ALTERNATE since the field 51 * information (TOP/BOTTOM) cannot be passed to the kernel. 52 */ 53 if (vb2_fileio_is_active(vq)) 54 return -EINVAL; 55 } 56 57 if (dev->queue_setup_error) { 58 /* 59 * Error injection: test what happens if queue_setup() returns 60 * an error. 61 */ 62 dev->queue_setup_error = false; 63 return -EINVAL; 64 } 65 66 if (fmt) { 67 const struct v4l2_pix_format_mplane *mp; 68 struct v4l2_format mp_fmt; 69 70 if (!V4L2_TYPE_IS_MULTIPLANAR(fmt->type)) { 71 fmt_sp2mp(fmt, &mp_fmt); 72 fmt = &mp_fmt; 73 } 74 mp = &fmt->fmt.pix_mp; 75 /* 76 * Check if the number of planes in the specified format match 77 * the number of planes in the current format. You can't mix that. 78 */ 79 if (mp->num_planes != planes) 80 return -EINVAL; 81 sizes[0] = mp->plane_fmt[0].sizeimage; 82 if (sizes[0] < size) 83 return -EINVAL; 84 for (p = 1; p < planes; p++) { 85 sizes[p] = mp->plane_fmt[p].sizeimage; 86 if (sizes[p] < dev->bytesperline_out[p] * h) 87 return -EINVAL; 88 } 89 } else { 90 for (p = 0; p < planes; p++) 91 sizes[p] = p ? dev->bytesperline_out[p] * h : size; 92 } 93 94 if (vq->num_buffers + *nbuffers < 2) 95 *nbuffers = 2 - vq->num_buffers; 96 97 *nplanes = planes; 98 99 /* 100 * videobuf2-vmalloc allocator is context-less so no need to set 101 * alloc_ctxs array. 102 */ 103 104 dprintk(dev, 1, "%s: count=%d\n", __func__, *nbuffers); 105 for (p = 0; p < planes; p++) 106 dprintk(dev, 1, "%s: size[%u]=%u\n", __func__, p, sizes[p]); 107 return 0; 108} 109 110static int vid_out_buf_prepare(struct vb2_buffer *vb) 111{ 112 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 113 unsigned long size; 114 unsigned planes; 115 unsigned p; 116 117 dprintk(dev, 1, "%s\n", __func__); 118 119 if (WARN_ON(NULL == dev->fmt_out)) 120 return -EINVAL; 121 122 planes = dev->fmt_out->planes; 123 124 if (dev->buf_prepare_error) { 125 /* 126 * Error injection: test what happens if buf_prepare() returns 127 * an error. 128 */ 129 dev->buf_prepare_error = false; 130 return -EINVAL; 131 } 132 133 if (dev->field_out != V4L2_FIELD_ALTERNATE) 134 vb->v4l2_buf.field = dev->field_out; 135 else if (vb->v4l2_buf.field != V4L2_FIELD_TOP && 136 vb->v4l2_buf.field != V4L2_FIELD_BOTTOM) 137 return -EINVAL; 138 139 for (p = 0; p < planes; p++) { 140 size = dev->bytesperline_out[p] * dev->fmt_out_rect.height + 141 vb->v4l2_planes[p].data_offset; 142 143 if (vb2_get_plane_payload(vb, p) < size) { 144 dprintk(dev, 1, "%s the payload is too small for plane %u (%lu < %lu)\n", 145 __func__, p, vb2_get_plane_payload(vb, p), size); 146 return -EINVAL; 147 } 148 } 149 150 return 0; 151} 152 153static void vid_out_buf_queue(struct vb2_buffer *vb) 154{ 155 struct vivid_dev *dev = vb2_get_drv_priv(vb->vb2_queue); 156 struct vivid_buffer *buf = container_of(vb, struct vivid_buffer, vb); 157 158 dprintk(dev, 1, "%s\n", __func__); 159 160 spin_lock(&dev->slock); 161 list_add_tail(&buf->list, &dev->vid_out_active); 162 spin_unlock(&dev->slock); 163} 164 165static int vid_out_start_streaming(struct vb2_queue *vq, unsigned count) 166{ 167 struct vivid_dev *dev = vb2_get_drv_priv(vq); 168 int err; 169 170 if (vb2_is_streaming(&dev->vb_vid_cap_q)) 171 dev->can_loop_video = vivid_vid_can_loop(dev); 172 173 if (dev->kthread_vid_out) 174 return 0; 175 176 dev->vid_out_seq_count = 0; 177 dprintk(dev, 1, "%s\n", __func__); 178 if (dev->start_streaming_error) { 179 dev->start_streaming_error = false; 180 err = -EINVAL; 181 } else { 182 err = vivid_start_generating_vid_out(dev, &dev->vid_out_streaming); 183 } 184 if (err) { 185 struct vivid_buffer *buf, *tmp; 186 187 list_for_each_entry_safe(buf, tmp, &dev->vid_out_active, list) { 188 list_del(&buf->list); 189 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_QUEUED); 190 } 191 } 192 return err; 193} 194 195/* abort streaming and wait for last buffer */ 196static void vid_out_stop_streaming(struct vb2_queue *vq) 197{ 198 struct vivid_dev *dev = vb2_get_drv_priv(vq); 199 200 dprintk(dev, 1, "%s\n", __func__); 201 vivid_stop_generating_vid_out(dev, &dev->vid_out_streaming); 202 dev->can_loop_video = false; 203} 204 205const struct vb2_ops vivid_vid_out_qops = { 206 .queue_setup = vid_out_queue_setup, 207 .buf_prepare = vid_out_buf_prepare, 208 .buf_queue = vid_out_buf_queue, 209 .start_streaming = vid_out_start_streaming, 210 .stop_streaming = vid_out_stop_streaming, 211 .wait_prepare = vb2_ops_wait_prepare, 212 .wait_finish = vb2_ops_wait_finish, 213}; 214 215/* 216 * Called whenever the format has to be reset which can occur when 217 * changing outputs, standard, timings, etc. 218 */ 219void vivid_update_format_out(struct vivid_dev *dev) 220{ 221 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; 222 unsigned size, p; 223 224 switch (dev->output_type[dev->output]) { 225 case SVID: 226 default: 227 dev->field_out = dev->tv_field_out; 228 dev->sink_rect.width = 720; 229 if (dev->std_out & V4L2_STD_525_60) { 230 dev->sink_rect.height = 480; 231 dev->timeperframe_vid_out = (struct v4l2_fract) { 1001, 30000 }; 232 dev->service_set_out = V4L2_SLICED_CAPTION_525; 233 } else { 234 dev->sink_rect.height = 576; 235 dev->timeperframe_vid_out = (struct v4l2_fract) { 1000, 25000 }; 236 dev->service_set_out = V4L2_SLICED_WSS_625 | V4L2_SLICED_TELETEXT_B; 237 } 238 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; 239 break; 240 case HDMI: 241 dev->sink_rect.width = bt->width; 242 dev->sink_rect.height = bt->height; 243 size = V4L2_DV_BT_FRAME_WIDTH(bt) * V4L2_DV_BT_FRAME_HEIGHT(bt); 244 dev->timeperframe_vid_out = (struct v4l2_fract) { 245 size / 100, (u32)bt->pixelclock / 100 246 }; 247 if (bt->interlaced) 248 dev->field_out = V4L2_FIELD_ALTERNATE; 249 else 250 dev->field_out = V4L2_FIELD_NONE; 251 if (!dev->dvi_d_out && (bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) { 252 if (bt->width == 720 && bt->height <= 576) 253 dev->colorspace_out = V4L2_COLORSPACE_SMPTE170M; 254 else 255 dev->colorspace_out = V4L2_COLORSPACE_REC709; 256 } else { 257 dev->colorspace_out = V4L2_COLORSPACE_SRGB; 258 } 259 break; 260 } 261 dev->ycbcr_enc_out = V4L2_YCBCR_ENC_DEFAULT; 262 dev->quantization_out = V4L2_QUANTIZATION_DEFAULT; 263 dev->compose_out = dev->sink_rect; 264 dev->compose_bounds_out = dev->sink_rect; 265 dev->crop_out = dev->compose_out; 266 if (V4L2_FIELD_HAS_T_OR_B(dev->field_out)) 267 dev->crop_out.height /= 2; 268 dev->fmt_out_rect = dev->crop_out; 269 for (p = 0; p < dev->fmt_out->planes; p++) 270 dev->bytesperline_out[p] = 271 (dev->sink_rect.width * dev->fmt_out->bit_depth[p]) / 8; 272} 273 274/* Map the field to something that is valid for the current output */ 275static enum v4l2_field vivid_field_out(struct vivid_dev *dev, enum v4l2_field field) 276{ 277 if (vivid_is_svid_out(dev)) { 278 switch (field) { 279 case V4L2_FIELD_INTERLACED_TB: 280 case V4L2_FIELD_INTERLACED_BT: 281 case V4L2_FIELD_SEQ_TB: 282 case V4L2_FIELD_SEQ_BT: 283 case V4L2_FIELD_ALTERNATE: 284 return field; 285 case V4L2_FIELD_INTERLACED: 286 default: 287 return V4L2_FIELD_INTERLACED; 288 } 289 } 290 if (vivid_is_hdmi_out(dev)) 291 return dev->dv_timings_out.bt.interlaced ? V4L2_FIELD_ALTERNATE : 292 V4L2_FIELD_NONE; 293 return V4L2_FIELD_NONE; 294} 295 296static enum tpg_pixel_aspect vivid_get_pixel_aspect(const struct vivid_dev *dev) 297{ 298 if (vivid_is_svid_out(dev)) 299 return (dev->std_out & V4L2_STD_525_60) ? 300 TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL; 301 302 if (vivid_is_hdmi_out(dev) && 303 dev->sink_rect.width == 720 && dev->sink_rect.height <= 576) 304 return dev->sink_rect.height == 480 ? 305 TPG_PIXEL_ASPECT_NTSC : TPG_PIXEL_ASPECT_PAL; 306 307 return TPG_PIXEL_ASPECT_SQUARE; 308} 309 310int vivid_g_fmt_vid_out(struct file *file, void *priv, 311 struct v4l2_format *f) 312{ 313 struct vivid_dev *dev = video_drvdata(file); 314 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; 315 const struct vivid_fmt *fmt = dev->fmt_out; 316 unsigned p; 317 318 mp->width = dev->fmt_out_rect.width; 319 mp->height = dev->fmt_out_rect.height; 320 mp->field = dev->field_out; 321 mp->pixelformat = fmt->fourcc; 322 mp->colorspace = dev->colorspace_out; 323 mp->ycbcr_enc = dev->ycbcr_enc_out; 324 mp->quantization = dev->quantization_out; 325 mp->num_planes = fmt->buffers; 326 for (p = 0; p < mp->num_planes; p++) { 327 mp->plane_fmt[p].bytesperline = dev->bytesperline_out[p]; 328 mp->plane_fmt[p].sizeimage = 329 mp->plane_fmt[p].bytesperline * mp->height; 330 } 331 for (p = fmt->buffers; p < fmt->planes; p++) { 332 unsigned stride = dev->bytesperline_out[p]; 333 334 mp->plane_fmt[0].sizeimage += 335 (stride * mp->height) / fmt->vdownsampling[p]; 336 } 337 return 0; 338} 339 340int vivid_try_fmt_vid_out(struct file *file, void *priv, 341 struct v4l2_format *f) 342{ 343 struct vivid_dev *dev = video_drvdata(file); 344 struct v4l2_bt_timings *bt = &dev->dv_timings_out.bt; 345 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; 346 struct v4l2_plane_pix_format *pfmt = mp->plane_fmt; 347 const struct vivid_fmt *fmt; 348 unsigned bytesperline, max_bpl; 349 unsigned factor = 1; 350 unsigned w, h; 351 unsigned p; 352 353 fmt = vivid_get_format(dev, mp->pixelformat); 354 if (!fmt) { 355 dprintk(dev, 1, "Fourcc format (0x%08x) unknown.\n", 356 mp->pixelformat); 357 mp->pixelformat = V4L2_PIX_FMT_YUYV; 358 fmt = vivid_get_format(dev, mp->pixelformat); 359 } 360 361 mp->field = vivid_field_out(dev, mp->field); 362 if (vivid_is_svid_out(dev)) { 363 w = 720; 364 h = (dev->std_out & V4L2_STD_525_60) ? 480 : 576; 365 } else { 366 w = dev->sink_rect.width; 367 h = dev->sink_rect.height; 368 } 369 if (V4L2_FIELD_HAS_T_OR_B(mp->field)) 370 factor = 2; 371 if (!dev->has_scaler_out && !dev->has_crop_out && !dev->has_compose_out) { 372 mp->width = w; 373 mp->height = h / factor; 374 } else { 375 struct v4l2_rect r = { 0, 0, mp->width, mp->height * factor }; 376 377 rect_set_min_size(&r, &vivid_min_rect); 378 rect_set_max_size(&r, &vivid_max_rect); 379 if (dev->has_scaler_out && !dev->has_crop_out) { 380 struct v4l2_rect max_r = { 0, 0, MAX_ZOOM * w, MAX_ZOOM * h }; 381 382 rect_set_max_size(&r, &max_r); 383 } else if (!dev->has_scaler_out && dev->has_compose_out && !dev->has_crop_out) { 384 rect_set_max_size(&r, &dev->sink_rect); 385 } else if (!dev->has_scaler_out && !dev->has_compose_out) { 386 rect_set_min_size(&r, &dev->sink_rect); 387 } 388 mp->width = r.width; 389 mp->height = r.height / factor; 390 } 391 392 /* This driver supports custom bytesperline values */ 393 394 /* Calculate the minimum supported bytesperline value */ 395 bytesperline = (mp->width * fmt->bit_depth[0]) >> 3; 396 /* Calculate the maximum supported bytesperline value */ 397 max_bpl = (MAX_ZOOM * MAX_WIDTH * fmt->bit_depth[0]) >> 3; 398 mp->num_planes = fmt->buffers; 399 for (p = 0; p < mp->num_planes; p++) { 400 if (pfmt[p].bytesperline > max_bpl) 401 pfmt[p].bytesperline = max_bpl; 402 if (pfmt[p].bytesperline < bytesperline) 403 pfmt[p].bytesperline = bytesperline; 404 pfmt[p].sizeimage = pfmt[p].bytesperline * mp->height; 405 memset(pfmt[p].reserved, 0, sizeof(pfmt[p].reserved)); 406 } 407 for (p = fmt->buffers; p < fmt->planes; p++) 408 pfmt[0].sizeimage += (pfmt[0].bytesperline * fmt->bit_depth[p]) / 409 (fmt->bit_depth[0] * fmt->vdownsampling[p]); 410 mp->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; 411 mp->quantization = V4L2_QUANTIZATION_DEFAULT; 412 if (vivid_is_svid_out(dev)) { 413 mp->colorspace = V4L2_COLORSPACE_SMPTE170M; 414 } else if (dev->dvi_d_out || !(bt->flags & V4L2_DV_FL_IS_CE_VIDEO)) { 415 mp->colorspace = V4L2_COLORSPACE_SRGB; 416 if (dev->dvi_d_out) 417 mp->quantization = V4L2_QUANTIZATION_LIM_RANGE; 418 } else if (bt->width == 720 && bt->height <= 576) { 419 mp->colorspace = V4L2_COLORSPACE_SMPTE170M; 420 } else if (mp->colorspace != V4L2_COLORSPACE_SMPTE170M && 421 mp->colorspace != V4L2_COLORSPACE_REC709 && 422 mp->colorspace != V4L2_COLORSPACE_ADOBERGB && 423 mp->colorspace != V4L2_COLORSPACE_BT2020 && 424 mp->colorspace != V4L2_COLORSPACE_SRGB) { 425 mp->colorspace = V4L2_COLORSPACE_REC709; 426 } 427 memset(mp->reserved, 0, sizeof(mp->reserved)); 428 return 0; 429} 430 431int vivid_s_fmt_vid_out(struct file *file, void *priv, 432 struct v4l2_format *f) 433{ 434 struct v4l2_pix_format_mplane *mp = &f->fmt.pix_mp; 435 struct vivid_dev *dev = video_drvdata(file); 436 struct v4l2_rect *crop = &dev->crop_out; 437 struct v4l2_rect *compose = &dev->compose_out; 438 struct vb2_queue *q = &dev->vb_vid_out_q; 439 int ret = vivid_try_fmt_vid_out(file, priv, f); 440 unsigned factor = 1; 441 unsigned p; 442 443 if (ret < 0) 444 return ret; 445 446 if (vb2_is_busy(q) && 447 (vivid_is_svid_out(dev) || 448 mp->width != dev->fmt_out_rect.width || 449 mp->height != dev->fmt_out_rect.height || 450 mp->pixelformat != dev->fmt_out->fourcc || 451 mp->field != dev->field_out)) { 452 dprintk(dev, 1, "%s device busy\n", __func__); 453 return -EBUSY; 454 } 455 456 /* 457 * Allow for changing the colorspace on the fly. Useful for testing 458 * purposes, and it is something that HDMI transmitters are able 459 * to do. 460 */ 461 if (vb2_is_busy(q)) 462 goto set_colorspace; 463 464 dev->fmt_out = vivid_get_format(dev, mp->pixelformat); 465 if (V4L2_FIELD_HAS_T_OR_B(mp->field)) 466 factor = 2; 467 468 if (dev->has_scaler_out || dev->has_crop_out || dev->has_compose_out) { 469 struct v4l2_rect r = { 0, 0, mp->width, mp->height }; 470 471 if (dev->has_scaler_out) { 472 if (dev->has_crop_out) 473 rect_map_inside(crop, &r); 474 else 475 *crop = r; 476 if (dev->has_compose_out && !dev->has_crop_out) { 477 struct v4l2_rect min_r = { 478 0, 0, 479 r.width / MAX_ZOOM, 480 factor * r.height / MAX_ZOOM 481 }; 482 struct v4l2_rect max_r = { 483 0, 0, 484 r.width * MAX_ZOOM, 485 factor * r.height * MAX_ZOOM 486 }; 487 488 rect_set_min_size(compose, &min_r); 489 rect_set_max_size(compose, &max_r); 490 rect_map_inside(compose, &dev->compose_bounds_out); 491 } else if (dev->has_compose_out) { 492 struct v4l2_rect min_r = { 493 0, 0, 494 crop->width / MAX_ZOOM, 495 factor * crop->height / MAX_ZOOM 496 }; 497 struct v4l2_rect max_r = { 498 0, 0, 499 crop->width * MAX_ZOOM, 500 factor * crop->height * MAX_ZOOM 501 }; 502 503 rect_set_min_size(compose, &min_r); 504 rect_set_max_size(compose, &max_r); 505 rect_map_inside(compose, &dev->compose_bounds_out); 506 } 507 } else if (dev->has_compose_out && !dev->has_crop_out) { 508 rect_set_size_to(crop, &r); 509 r.height *= factor; 510 rect_set_size_to(compose, &r); 511 rect_map_inside(compose, &dev->compose_bounds_out); 512 } else if (!dev->has_compose_out) { 513 rect_map_inside(crop, &r); 514 r.height /= factor; 515 rect_set_size_to(compose, &r); 516 } else { 517 r.height *= factor; 518 rect_set_max_size(compose, &r); 519 rect_map_inside(compose, &dev->compose_bounds_out); 520 crop->top *= factor; 521 crop->height *= factor; 522 rect_set_size_to(crop, compose); 523 rect_map_inside(crop, &r); 524 crop->top /= factor; 525 crop->height /= factor; 526 } 527 } else { 528 struct v4l2_rect r = { 0, 0, mp->width, mp->height }; 529 530 rect_set_size_to(crop, &r); 531 r.height /= factor; 532 rect_set_size_to(compose, &r); 533 } 534 535 dev->fmt_out_rect.width = mp->width; 536 dev->fmt_out_rect.height = mp->height; 537 for (p = 0; p < mp->num_planes; p++) 538 dev->bytesperline_out[p] = mp->plane_fmt[p].bytesperline; 539 for (p = dev->fmt_out->buffers; p < dev->fmt_out->planes; p++) 540 dev->bytesperline_out[p] = 541 (dev->bytesperline_out[0] * dev->fmt_out->bit_depth[p]) / 542 dev->fmt_out->bit_depth[0]; 543 dev->field_out = mp->field; 544 if (vivid_is_svid_out(dev)) 545 dev->tv_field_out = mp->field; 546 547set_colorspace: 548 dev->colorspace_out = mp->colorspace; 549 dev->ycbcr_enc_out = mp->ycbcr_enc; 550 dev->quantization_out = mp->quantization; 551 if (dev->loop_video) { 552 vivid_send_source_change(dev, SVID); 553 vivid_send_source_change(dev, HDMI); 554 } 555 return 0; 556} 557 558int vidioc_g_fmt_vid_out_mplane(struct file *file, void *priv, 559 struct v4l2_format *f) 560{ 561 struct vivid_dev *dev = video_drvdata(file); 562 563 if (!dev->multiplanar) 564 return -ENOTTY; 565 return vivid_g_fmt_vid_out(file, priv, f); 566} 567 568int vidioc_try_fmt_vid_out_mplane(struct file *file, void *priv, 569 struct v4l2_format *f) 570{ 571 struct vivid_dev *dev = video_drvdata(file); 572 573 if (!dev->multiplanar) 574 return -ENOTTY; 575 return vivid_try_fmt_vid_out(file, priv, f); 576} 577 578int vidioc_s_fmt_vid_out_mplane(struct file *file, void *priv, 579 struct v4l2_format *f) 580{ 581 struct vivid_dev *dev = video_drvdata(file); 582 583 if (!dev->multiplanar) 584 return -ENOTTY; 585 return vivid_s_fmt_vid_out(file, priv, f); 586} 587 588int vidioc_g_fmt_vid_out(struct file *file, void *priv, 589 struct v4l2_format *f) 590{ 591 struct vivid_dev *dev = video_drvdata(file); 592 593 if (dev->multiplanar) 594 return -ENOTTY; 595 return fmt_sp2mp_func(file, priv, f, vivid_g_fmt_vid_out); 596} 597 598int vidioc_try_fmt_vid_out(struct file *file, void *priv, 599 struct v4l2_format *f) 600{ 601 struct vivid_dev *dev = video_drvdata(file); 602 603 if (dev->multiplanar) 604 return -ENOTTY; 605 return fmt_sp2mp_func(file, priv, f, vivid_try_fmt_vid_out); 606} 607 608int vidioc_s_fmt_vid_out(struct file *file, void *priv, 609 struct v4l2_format *f) 610{ 611 struct vivid_dev *dev = video_drvdata(file); 612 613 if (dev->multiplanar) 614 return -ENOTTY; 615 return fmt_sp2mp_func(file, priv, f, vivid_s_fmt_vid_out); 616} 617 618int vivid_vid_out_g_selection(struct file *file, void *priv, 619 struct v4l2_selection *sel) 620{ 621 struct vivid_dev *dev = video_drvdata(file); 622 623 if (!dev->has_crop_out && !dev->has_compose_out) 624 return -ENOTTY; 625 if (sel->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 626 return -EINVAL; 627 628 sel->r.left = sel->r.top = 0; 629 switch (sel->target) { 630 case V4L2_SEL_TGT_CROP: 631 if (!dev->has_crop_out) 632 return -EINVAL; 633 sel->r = dev->crop_out; 634 break; 635 case V4L2_SEL_TGT_CROP_DEFAULT: 636 if (!dev->has_crop_out) 637 return -EINVAL; 638 sel->r = dev->fmt_out_rect; 639 break; 640 case V4L2_SEL_TGT_CROP_BOUNDS: 641 if (!dev->has_crop_out) 642 return -EINVAL; 643 sel->r = vivid_max_rect; 644 break; 645 case V4L2_SEL_TGT_COMPOSE: 646 if (!dev->has_compose_out) 647 return -EINVAL; 648 sel->r = dev->compose_out; 649 break; 650 case V4L2_SEL_TGT_COMPOSE_DEFAULT: 651 case V4L2_SEL_TGT_COMPOSE_BOUNDS: 652 if (!dev->has_compose_out) 653 return -EINVAL; 654 sel->r = dev->sink_rect; 655 break; 656 default: 657 return -EINVAL; 658 } 659 return 0; 660} 661 662int vivid_vid_out_s_selection(struct file *file, void *fh, struct v4l2_selection *s) 663{ 664 struct vivid_dev *dev = video_drvdata(file); 665 struct v4l2_rect *crop = &dev->crop_out; 666 struct v4l2_rect *compose = &dev->compose_out; 667 unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_out) ? 2 : 1; 668 int ret; 669 670 if (!dev->has_crop_out && !dev->has_compose_out) 671 return -ENOTTY; 672 if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 673 return -EINVAL; 674 675 switch (s->target) { 676 case V4L2_SEL_TGT_CROP: 677 if (!dev->has_crop_out) 678 return -EINVAL; 679 ret = vivid_vid_adjust_sel(s->flags, &s->r); 680 if (ret) 681 return ret; 682 rect_set_min_size(&s->r, &vivid_min_rect); 683 rect_set_max_size(&s->r, &dev->fmt_out_rect); 684 if (dev->has_scaler_out) { 685 struct v4l2_rect max_rect = { 686 0, 0, 687 dev->sink_rect.width * MAX_ZOOM, 688 (dev->sink_rect.height / factor) * MAX_ZOOM 689 }; 690 691 rect_set_max_size(&s->r, &max_rect); 692 if (dev->has_compose_out) { 693 struct v4l2_rect min_rect = { 694 0, 0, 695 s->r.width / MAX_ZOOM, 696 (s->r.height * factor) / MAX_ZOOM 697 }; 698 struct v4l2_rect max_rect = { 699 0, 0, 700 s->r.width * MAX_ZOOM, 701 (s->r.height * factor) * MAX_ZOOM 702 }; 703 704 rect_set_min_size(compose, &min_rect); 705 rect_set_max_size(compose, &max_rect); 706 rect_map_inside(compose, &dev->compose_bounds_out); 707 } 708 } else if (dev->has_compose_out) { 709 s->r.top *= factor; 710 s->r.height *= factor; 711 rect_set_max_size(&s->r, &dev->sink_rect); 712 rect_set_size_to(compose, &s->r); 713 rect_map_inside(compose, &dev->compose_bounds_out); 714 s->r.top /= factor; 715 s->r.height /= factor; 716 } else { 717 rect_set_size_to(&s->r, &dev->sink_rect); 718 s->r.height /= factor; 719 } 720 rect_map_inside(&s->r, &dev->fmt_out_rect); 721 *crop = s->r; 722 break; 723 case V4L2_SEL_TGT_COMPOSE: 724 if (!dev->has_compose_out) 725 return -EINVAL; 726 ret = vivid_vid_adjust_sel(s->flags, &s->r); 727 if (ret) 728 return ret; 729 rect_set_min_size(&s->r, &vivid_min_rect); 730 rect_set_max_size(&s->r, &dev->sink_rect); 731 rect_map_inside(&s->r, &dev->compose_bounds_out); 732 s->r.top /= factor; 733 s->r.height /= factor; 734 if (dev->has_scaler_out) { 735 struct v4l2_rect fmt = dev->fmt_out_rect; 736 struct v4l2_rect max_rect = { 737 0, 0, 738 s->r.width * MAX_ZOOM, 739 s->r.height * MAX_ZOOM 740 }; 741 struct v4l2_rect min_rect = { 742 0, 0, 743 s->r.width / MAX_ZOOM, 744 s->r.height / MAX_ZOOM 745 }; 746 747 rect_set_min_size(&fmt, &min_rect); 748 if (!dev->has_crop_out) 749 rect_set_max_size(&fmt, &max_rect); 750 if (!rect_same_size(&dev->fmt_out_rect, &fmt) && 751 vb2_is_busy(&dev->vb_vid_out_q)) 752 return -EBUSY; 753 if (dev->has_crop_out) { 754 rect_set_min_size(crop, &min_rect); 755 rect_set_max_size(crop, &max_rect); 756 } 757 dev->fmt_out_rect = fmt; 758 } else if (dev->has_crop_out) { 759 struct v4l2_rect fmt = dev->fmt_out_rect; 760 761 rect_set_min_size(&fmt, &s->r); 762 if (!rect_same_size(&dev->fmt_out_rect, &fmt) && 763 vb2_is_busy(&dev->vb_vid_out_q)) 764 return -EBUSY; 765 dev->fmt_out_rect = fmt; 766 rect_set_size_to(crop, &s->r); 767 rect_map_inside(crop, &dev->fmt_out_rect); 768 } else { 769 if (!rect_same_size(&s->r, &dev->fmt_out_rect) && 770 vb2_is_busy(&dev->vb_vid_out_q)) 771 return -EBUSY; 772 rect_set_size_to(&dev->fmt_out_rect, &s->r); 773 rect_set_size_to(crop, &s->r); 774 crop->height /= factor; 775 rect_map_inside(crop, &dev->fmt_out_rect); 776 } 777 s->r.top *= factor; 778 s->r.height *= factor; 779 if (dev->bitmap_out && (compose->width != s->r.width || 780 compose->height != s->r.height)) { 781 kfree(dev->bitmap_out); 782 dev->bitmap_out = NULL; 783 } 784 *compose = s->r; 785 break; 786 default: 787 return -EINVAL; 788 } 789 790 return 0; 791} 792 793int vivid_vid_out_cropcap(struct file *file, void *priv, 794 struct v4l2_cropcap *cap) 795{ 796 struct vivid_dev *dev = video_drvdata(file); 797 798 if (cap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 799 return -EINVAL; 800 801 switch (vivid_get_pixel_aspect(dev)) { 802 case TPG_PIXEL_ASPECT_NTSC: 803 cap->pixelaspect.numerator = 11; 804 cap->pixelaspect.denominator = 10; 805 break; 806 case TPG_PIXEL_ASPECT_PAL: 807 cap->pixelaspect.numerator = 54; 808 cap->pixelaspect.denominator = 59; 809 break; 810 case TPG_PIXEL_ASPECT_SQUARE: 811 cap->pixelaspect.numerator = 1; 812 cap->pixelaspect.denominator = 1; 813 break; 814 } 815 return 0; 816} 817 818int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv, 819 struct v4l2_format *f) 820{ 821 struct vivid_dev *dev = video_drvdata(file); 822 const struct v4l2_rect *compose = &dev->compose_out; 823 struct v4l2_window *win = &f->fmt.win; 824 unsigned clipcount = win->clipcount; 825 826 if (!dev->has_fb) 827 return -EINVAL; 828 win->w.top = dev->overlay_out_top; 829 win->w.left = dev->overlay_out_left; 830 win->w.width = compose->width; 831 win->w.height = compose->height; 832 win->clipcount = dev->clipcount_out; 833 win->field = V4L2_FIELD_ANY; 834 win->chromakey = dev->chromakey_out; 835 win->global_alpha = dev->global_alpha_out; 836 if (clipcount > dev->clipcount_out) 837 clipcount = dev->clipcount_out; 838 if (dev->bitmap_out == NULL) 839 win->bitmap = NULL; 840 else if (win->bitmap) { 841 if (copy_to_user(win->bitmap, dev->bitmap_out, 842 ((dev->compose_out.width + 7) / 8) * dev->compose_out.height)) 843 return -EFAULT; 844 } 845 if (clipcount && win->clips) { 846 if (copy_to_user(win->clips, dev->clips_out, 847 clipcount * sizeof(dev->clips_out[0]))) 848 return -EFAULT; 849 } 850 return 0; 851} 852 853int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv, 854 struct v4l2_format *f) 855{ 856 struct vivid_dev *dev = video_drvdata(file); 857 const struct v4l2_rect *compose = &dev->compose_out; 858 struct v4l2_window *win = &f->fmt.win; 859 int i, j; 860 861 if (!dev->has_fb) 862 return -EINVAL; 863 win->w.left = clamp_t(int, win->w.left, 864 -dev->display_width, dev->display_width); 865 win->w.top = clamp_t(int, win->w.top, 866 -dev->display_height, dev->display_height); 867 win->w.width = compose->width; 868 win->w.height = compose->height; 869 /* 870 * It makes no sense for an OSD to overlay only top or bottom fields, 871 * so always set this to ANY. 872 */ 873 win->field = V4L2_FIELD_ANY; 874 if (win->clipcount && !win->clips) 875 win->clipcount = 0; 876 if (win->clipcount > MAX_CLIPS) 877 win->clipcount = MAX_CLIPS; 878 if (win->clipcount) { 879 if (copy_from_user(dev->try_clips_out, win->clips, 880 win->clipcount * sizeof(dev->clips_out[0]))) 881 return -EFAULT; 882 for (i = 0; i < win->clipcount; i++) { 883 struct v4l2_rect *r = &dev->try_clips_out[i].c; 884 885 r->top = clamp_t(s32, r->top, 0, dev->display_height - 1); 886 r->height = clamp_t(s32, r->height, 1, dev->display_height - r->top); 887 r->left = clamp_t(u32, r->left, 0, dev->display_width - 1); 888 r->width = clamp_t(u32, r->width, 1, dev->display_width - r->left); 889 } 890 /* 891 * Yeah, so sue me, it's an O(n^2) algorithm. But n is a small 892 * number and it's typically a one-time deal. 893 */ 894 for (i = 0; i < win->clipcount - 1; i++) { 895 struct v4l2_rect *r1 = &dev->try_clips_out[i].c; 896 897 for (j = i + 1; j < win->clipcount; j++) { 898 struct v4l2_rect *r2 = &dev->try_clips_out[j].c; 899 900 if (rect_overlap(r1, r2)) 901 return -EINVAL; 902 } 903 } 904 if (copy_to_user(win->clips, dev->try_clips_out, 905 win->clipcount * sizeof(dev->clips_out[0]))) 906 return -EFAULT; 907 } 908 return 0; 909} 910 911int vidioc_s_fmt_vid_out_overlay(struct file *file, void *priv, 912 struct v4l2_format *f) 913{ 914 struct vivid_dev *dev = video_drvdata(file); 915 const struct v4l2_rect *compose = &dev->compose_out; 916 struct v4l2_window *win = &f->fmt.win; 917 int ret = vidioc_try_fmt_vid_out_overlay(file, priv, f); 918 unsigned bitmap_size = ((compose->width + 7) / 8) * compose->height; 919 unsigned clips_size = win->clipcount * sizeof(dev->clips_out[0]); 920 void *new_bitmap = NULL; 921 922 if (ret) 923 return ret; 924 925 if (win->bitmap) { 926 new_bitmap = memdup_user(win->bitmap, bitmap_size); 927 928 if (IS_ERR(new_bitmap)) 929 return PTR_ERR(new_bitmap); 930 } 931 932 dev->overlay_out_top = win->w.top; 933 dev->overlay_out_left = win->w.left; 934 kfree(dev->bitmap_out); 935 dev->bitmap_out = new_bitmap; 936 dev->clipcount_out = win->clipcount; 937 if (dev->clipcount_out) 938 memcpy(dev->clips_out, dev->try_clips_out, clips_size); 939 dev->chromakey_out = win->chromakey; 940 dev->global_alpha_out = win->global_alpha; 941 return ret; 942} 943 944int vivid_vid_out_overlay(struct file *file, void *fh, unsigned i) 945{ 946 struct vivid_dev *dev = video_drvdata(file); 947 948 if (i && !dev->fmt_out->can_do_overlay) { 949 dprintk(dev, 1, "unsupported output format for output overlay\n"); 950 return -EINVAL; 951 } 952 953 dev->overlay_out_enabled = i; 954 return 0; 955} 956 957int vivid_vid_out_g_fbuf(struct file *file, void *fh, 958 struct v4l2_framebuffer *a) 959{ 960 struct vivid_dev *dev = video_drvdata(file); 961 962 a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | 963 V4L2_FBUF_CAP_BITMAP_CLIPPING | 964 V4L2_FBUF_CAP_LIST_CLIPPING | 965 V4L2_FBUF_CAP_CHROMAKEY | 966 V4L2_FBUF_CAP_SRC_CHROMAKEY | 967 V4L2_FBUF_CAP_GLOBAL_ALPHA | 968 V4L2_FBUF_CAP_LOCAL_ALPHA | 969 V4L2_FBUF_CAP_LOCAL_INV_ALPHA; 970 a->flags = V4L2_FBUF_FLAG_OVERLAY | dev->fbuf_out_flags; 971 a->base = (void *)dev->video_pbase; 972 a->fmt.width = dev->display_width; 973 a->fmt.height = dev->display_height; 974 if (dev->fb_defined.green.length == 5) 975 a->fmt.pixelformat = V4L2_PIX_FMT_ARGB555; 976 else 977 a->fmt.pixelformat = V4L2_PIX_FMT_RGB565; 978 a->fmt.bytesperline = dev->display_byte_stride; 979 a->fmt.sizeimage = a->fmt.height * a->fmt.bytesperline; 980 a->fmt.field = V4L2_FIELD_NONE; 981 a->fmt.colorspace = V4L2_COLORSPACE_SRGB; 982 a->fmt.priv = 0; 983 return 0; 984} 985 986int vivid_vid_out_s_fbuf(struct file *file, void *fh, 987 const struct v4l2_framebuffer *a) 988{ 989 struct vivid_dev *dev = video_drvdata(file); 990 const unsigned chroma_flags = V4L2_FBUF_FLAG_CHROMAKEY | 991 V4L2_FBUF_FLAG_SRC_CHROMAKEY; 992 const unsigned alpha_flags = V4L2_FBUF_FLAG_GLOBAL_ALPHA | 993 V4L2_FBUF_FLAG_LOCAL_ALPHA | 994 V4L2_FBUF_FLAG_LOCAL_INV_ALPHA; 995 996 997 if ((a->flags & chroma_flags) == chroma_flags) 998 return -EINVAL; 999 switch (a->flags & alpha_flags) { 1000 case 0: 1001 case V4L2_FBUF_FLAG_GLOBAL_ALPHA: 1002 case V4L2_FBUF_FLAG_LOCAL_ALPHA: 1003 case V4L2_FBUF_FLAG_LOCAL_INV_ALPHA: 1004 break; 1005 default: 1006 return -EINVAL; 1007 } 1008 dev->fbuf_out_flags &= ~(chroma_flags | alpha_flags); 1009 dev->fbuf_out_flags = a->flags & (chroma_flags | alpha_flags); 1010 return 0; 1011} 1012 1013static const struct v4l2_audioout vivid_audio_outputs[] = { 1014 { 0, "Line-Out 1" }, 1015 { 1, "Line-Out 2" }, 1016}; 1017 1018int vidioc_enum_output(struct file *file, void *priv, 1019 struct v4l2_output *out) 1020{ 1021 struct vivid_dev *dev = video_drvdata(file); 1022 1023 if (out->index >= dev->num_outputs) 1024 return -EINVAL; 1025 1026 out->type = V4L2_OUTPUT_TYPE_ANALOG; 1027 switch (dev->output_type[out->index]) { 1028 case SVID: 1029 snprintf(out->name, sizeof(out->name), "S-Video %u", 1030 dev->output_name_counter[out->index]); 1031 out->std = V4L2_STD_ALL; 1032 if (dev->has_audio_outputs) 1033 out->audioset = (1 << ARRAY_SIZE(vivid_audio_outputs)) - 1; 1034 out->capabilities = V4L2_OUT_CAP_STD; 1035 break; 1036 case HDMI: 1037 snprintf(out->name, sizeof(out->name), "HDMI %u", 1038 dev->output_name_counter[out->index]); 1039 out->capabilities = V4L2_OUT_CAP_DV_TIMINGS; 1040 break; 1041 } 1042 return 0; 1043} 1044 1045int vidioc_g_output(struct file *file, void *priv, unsigned *o) 1046{ 1047 struct vivid_dev *dev = video_drvdata(file); 1048 1049 *o = dev->output; 1050 return 0; 1051} 1052 1053int vidioc_s_output(struct file *file, void *priv, unsigned o) 1054{ 1055 struct vivid_dev *dev = video_drvdata(file); 1056 1057 if (o >= dev->num_outputs) 1058 return -EINVAL; 1059 1060 if (o == dev->output) 1061 return 0; 1062 1063 if (vb2_is_busy(&dev->vb_vid_out_q) || vb2_is_busy(&dev->vb_vbi_out_q)) 1064 return -EBUSY; 1065 1066 dev->output = o; 1067 dev->tv_audio_output = 0; 1068 if (dev->output_type[o] == SVID) 1069 dev->vid_out_dev.tvnorms = V4L2_STD_ALL; 1070 else 1071 dev->vid_out_dev.tvnorms = 0; 1072 1073 dev->vbi_out_dev.tvnorms = dev->vid_out_dev.tvnorms; 1074 vivid_update_format_out(dev); 1075 return 0; 1076} 1077 1078int vidioc_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vout) 1079{ 1080 if (vout->index >= ARRAY_SIZE(vivid_audio_outputs)) 1081 return -EINVAL; 1082 *vout = vivid_audio_outputs[vout->index]; 1083 return 0; 1084} 1085 1086int vidioc_g_audout(struct file *file, void *fh, struct v4l2_audioout *vout) 1087{ 1088 struct vivid_dev *dev = video_drvdata(file); 1089 1090 if (!vivid_is_svid_out(dev)) 1091 return -EINVAL; 1092 *vout = vivid_audio_outputs[dev->tv_audio_output]; 1093 return 0; 1094} 1095 1096int vidioc_s_audout(struct file *file, void *fh, const struct v4l2_audioout *vout) 1097{ 1098 struct vivid_dev *dev = video_drvdata(file); 1099 1100 if (!vivid_is_svid_out(dev)) 1101 return -EINVAL; 1102 if (vout->index >= ARRAY_SIZE(vivid_audio_outputs)) 1103 return -EINVAL; 1104 dev->tv_audio_output = vout->index; 1105 return 0; 1106} 1107 1108int vivid_vid_out_s_std(struct file *file, void *priv, v4l2_std_id id) 1109{ 1110 struct vivid_dev *dev = video_drvdata(file); 1111 1112 if (!vivid_is_svid_out(dev)) 1113 return -ENODATA; 1114 if (dev->std_out == id) 1115 return 0; 1116 if (vb2_is_busy(&dev->vb_vid_out_q) || vb2_is_busy(&dev->vb_vbi_out_q)) 1117 return -EBUSY; 1118 dev->std_out = id; 1119 vivid_update_format_out(dev); 1120 return 0; 1121} 1122 1123int vivid_vid_out_s_dv_timings(struct file *file, void *_fh, 1124 struct v4l2_dv_timings *timings) 1125{ 1126 struct vivid_dev *dev = video_drvdata(file); 1127 1128 if (!vivid_is_hdmi_out(dev)) 1129 return -ENODATA; 1130 if (!v4l2_find_dv_timings_cap(timings, &vivid_dv_timings_cap, 1131 0, NULL, NULL)) 1132 return -EINVAL; 1133 if (v4l2_match_dv_timings(timings, &dev->dv_timings_out, 0)) 1134 return 0; 1135 if (vb2_is_busy(&dev->vb_vid_out_q)) 1136 return -EBUSY; 1137 dev->dv_timings_out = *timings; 1138 vivid_update_format_out(dev); 1139 return 0; 1140} 1141 1142int vivid_vid_out_g_parm(struct file *file, void *priv, 1143 struct v4l2_streamparm *parm) 1144{ 1145 struct vivid_dev *dev = video_drvdata(file); 1146 1147 if (parm->type != (dev->multiplanar ? 1148 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE : 1149 V4L2_BUF_TYPE_VIDEO_OUTPUT)) 1150 return -EINVAL; 1151 1152 parm->parm.output.capability = V4L2_CAP_TIMEPERFRAME; 1153 parm->parm.output.timeperframe = dev->timeperframe_vid_out; 1154 parm->parm.output.writebuffers = 1; 1155return 0; 1156} 1157 1158int vidioc_subscribe_event(struct v4l2_fh *fh, 1159 const struct v4l2_event_subscription *sub) 1160{ 1161 switch (sub->type) { 1162 case V4L2_EVENT_CTRL: 1163 return v4l2_ctrl_subscribe_event(fh, sub); 1164 case V4L2_EVENT_SOURCE_CHANGE: 1165 if (fh->vdev->vfl_dir == VFL_DIR_RX) 1166 return v4l2_src_change_event_subscribe(fh, sub); 1167 break; 1168 default: 1169 break; 1170 } 1171 return -EINVAL; 1172} 1173