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