From patchwork Wed Mar 1 11:18:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 657988 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98609C64EC7 for ; Wed, 1 Mar 2023 11:19:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229942AbjCALTB (ORCPT ); Wed, 1 Mar 2023 06:19:01 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59838 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229955AbjCALTA (ORCPT ); Wed, 1 Mar 2023 06:19:00 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2BB351E5FA for ; Wed, 1 Mar 2023 03:18:58 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 588CBB80FF0 for ; Wed, 1 Mar 2023 11:18:56 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 25AF1C433EF; Wed, 1 Mar 2023 11:18:53 +0000 (UTC) From: Hans Verkuil To: linux-media@vger.kernel.org Cc: Hans Verkuil Subject: [RFC PATCH 2/9] saa7134: drop overlay support Date: Wed, 1 Mar 2023 12:18:43 +0100 Message-Id: <20230301111850.607515-3-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230301111850.607515-1-hverkuil-cisco@xs4all.nl> References: <20230301111850.607515-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Destructive overlay support (i.e. where the video frame is DMA-ed straight into a framebuffer) is effectively dead. It was a necessary evil in the early days when computers were not fast enough to copy SDTV video frames around, but today that's no longer a problem. It requires access to the framebuffer memory, which is a bad idea and very hard to do safely. In addition, in drm it is today almost impossible to get hold of the framebuffer address. So drop support for this. Signed-off-by: Hans Verkuil --- drivers/media/pci/saa7134/saa7134-cards.c | 1 - drivers/media/pci/saa7134/saa7134-core.c | 32 -- drivers/media/pci/saa7134/saa7134-video.c | 411 +--------------------- drivers/media/pci/saa7134/saa7134.h | 13 - 4 files changed, 4 insertions(+), 453 deletions(-) diff --git a/drivers/media/pci/saa7134/saa7134-cards.c b/drivers/media/pci/saa7134/saa7134-cards.c index 99be59af3560..1280696f65f2 100644 --- a/drivers/media/pci/saa7134/saa7134-cards.c +++ b/drivers/media/pci/saa7134/saa7134-cards.c @@ -2116,7 +2116,6 @@ struct saa7134_board saa7134_boards[] = { - Remote control doesn't initialize properly. - Audio volume starts muted, then gradually increases after channel change. - - Overlay scaling problems (application error?) - Composite S-Video untested. From: Konrad Rzepecki */ diff --git a/drivers/media/pci/saa7134/saa7134-core.c b/drivers/media/pci/saa7134/saa7134-core.c index cf2871306987..ea0585e43abb 100644 --- a/drivers/media/pci/saa7134/saa7134-core.c +++ b/drivers/media/pci/saa7134/saa7134-core.c @@ -51,10 +51,6 @@ static unsigned int latency = UNSET; module_param(latency, int, 0444); MODULE_PARM_DESC(latency,"pci latency timer"); -int saa7134_no_overlay=-1; -module_param_named(no_overlay, saa7134_no_overlay, int, 0444); -MODULE_PARM_DESC(no_overlay, "allow override overlay default (0 disables, 1 enables) [some VIA/SIS chipsets are known to have problem with overlay]"); - bool saa7134_userptr; module_param(saa7134_userptr, bool, 0644); MODULE_PARM_DESC(saa7134_userptr, "enable page-aligned userptr support"); @@ -400,13 +396,6 @@ int saa7134_set_dmabits(struct saa7134_dev *dev) SAA7134_MAIN_CTRL_TE5; } - /* screen overlay -- dma 0 + video task B */ - if (dev->ovenable) { - task |= 0x10; - ctrl |= SAA7134_MAIN_CTRL_TE1; - ov = dev->ovfield; - } - /* vbi capture -- dma 0 + vbi task A+B */ if (dev->vbi_q.curr) { task |= 0x22; @@ -1066,18 +1055,6 @@ static int saa7134_initdev(struct pci_dev *pci_dev, latency = 0x0A; } #endif - if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) { - pr_info("%s: quirk: this driver and your chipset may not work together in overlay mode.\n", - dev->name); - if (!saa7134_no_overlay) { - pr_info("%s: quirk: overlay mode will be disabled.\n", - dev->name); - saa7134_no_overlay = 1; - } else { - pr_info("%s: quirk: overlay mode will be forced. Use this option at your own risk.\n", - dev->name); - } - } } if (UNSET != latency) { pr_info("%s: setting pci latency timer to %d\n", @@ -1198,9 +1175,6 @@ static int saa7134_initdev(struct pci_dev *pci_dev, saa_call_all(dev, core, s_power, 0); /* register v4l devices */ - if (saa7134_no_overlay > 0) - pr_info("%s: Overlay support disabled.\n", dev->name); - dev->video_dev = vdev_init(dev,&saa7134_video_template,"video"); dev->video_dev->ctrl_handler = &dev->ctrl_handler; dev->video_dev->lock = &dev->lock; @@ -1210,9 +1184,6 @@ static int saa7134_initdev(struct pci_dev *pci_dev, if (dev->tuner_type != TUNER_ABSENT && dev->tuner_type != UNSET) dev->video_dev->device_caps |= V4L2_CAP_TUNER; - if (saa7134_no_overlay <= 0) - dev->video_dev->device_caps |= V4L2_CAP_VIDEO_OVERLAY; - err = video_register_device(dev->video_dev,VFL_TYPE_VIDEO, video_nr[dev->nr]); if (err < 0) { @@ -1403,9 +1374,6 @@ static int __maybe_unused saa7134_suspend(struct device *dev_d) struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); struct saa7134_dev *dev = container_of(v4l2_dev, struct saa7134_dev, v4l2_dev); - /* disable overlay - apps should enable it explicitly on resume*/ - dev->ovenable = 0; - /* Disable interrupts, DMA, and rest of the chip*/ saa_writel(SAA7134_IRQ1, 0); saa_writel(SAA7134_IRQ2, 0); diff --git a/drivers/media/pci/saa7134/saa7134-video.c b/drivers/media/pci/saa7134/saa7134-video.c index 4d8974c9fcc9..c5e68f33640f 100644 --- a/drivers/media/pci/saa7134/saa7134-video.c +++ b/drivers/media/pci/saa7134/saa7134-video.c @@ -571,193 +571,6 @@ static void set_size(struct saa7134_dev *dev, int task, /* ------------------------------------------------------------------ */ -struct cliplist { - __u16 position; - __u8 enable; - __u8 disable; -}; - -static void set_cliplist(struct saa7134_dev *dev, int reg, - struct cliplist *cl, int entries, char *name) -{ - __u8 winbits = 0; - int i; - - for (i = 0; i < entries; i++) { - winbits |= cl[i].enable; - winbits &= ~cl[i].disable; - if (i < 15 && cl[i].position == cl[i+1].position) - continue; - saa_writeb(reg + 0, winbits); - saa_writeb(reg + 2, cl[i].position & 0xff); - saa_writeb(reg + 3, cl[i].position >> 8); - video_dbg("clip: %s winbits=%02x pos=%d\n", - name,winbits,cl[i].position); - reg += 8; - } - for (; reg < 0x400; reg += 8) { - saa_writeb(reg+ 0, 0); - saa_writeb(reg + 1, 0); - saa_writeb(reg + 2, 0); - saa_writeb(reg + 3, 0); - } -} - -static int clip_range(int val) -{ - if (val < 0) - val = 0; - return val; -} - -/* Sort into smallest position first order */ -static int cliplist_cmp(const void *a, const void *b) -{ - const struct cliplist *cla = a; - const struct cliplist *clb = b; - if (cla->position < clb->position) - return -1; - if (cla->position > clb->position) - return 1; - return 0; -} - -static int setup_clipping(struct saa7134_dev *dev, struct v4l2_clip *clips, - int nclips, int interlace) -{ - struct cliplist col[16], row[16]; - int cols = 0, rows = 0, i; - int div = interlace ? 2 : 1; - - memset(col, 0, sizeof(col)); - memset(row, 0, sizeof(row)); - for (i = 0; i < nclips && i < 8; i++) { - col[cols].position = clip_range(clips[i].c.left); - col[cols].enable = (1 << i); - cols++; - col[cols].position = clip_range(clips[i].c.left+clips[i].c.width); - col[cols].disable = (1 << i); - cols++; - row[rows].position = clip_range(clips[i].c.top / div); - row[rows].enable = (1 << i); - rows++; - row[rows].position = clip_range((clips[i].c.top + clips[i].c.height) - / div); - row[rows].disable = (1 << i); - rows++; - } - sort(col, cols, sizeof col[0], cliplist_cmp, NULL); - sort(row, rows, sizeof row[0], cliplist_cmp, NULL); - set_cliplist(dev,0x380,col,cols,"cols"); - set_cliplist(dev,0x384,row,rows,"rows"); - return 0; -} - -static int verify_preview(struct saa7134_dev *dev, struct v4l2_window *win, bool try) -{ - enum v4l2_field field; - int maxw, maxh; - - if (!try && (dev->ovbuf.base == NULL || dev->ovfmt == NULL)) - return -EINVAL; - if (win->w.width < 48) - win->w.width = 48; - if (win->w.height < 32) - win->w.height = 32; - if (win->clipcount > 8) - win->clipcount = 8; - - win->chromakey = 0; - win->global_alpha = 0; - field = win->field; - maxw = dev->crop_current.width; - maxh = dev->crop_current.height; - - if (V4L2_FIELD_ANY == field) { - field = (win->w.height > maxh/2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_TOP; - } - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - maxh = maxh / 2; - break; - default: - field = V4L2_FIELD_INTERLACED; - break; - } - - win->field = field; - if (win->w.width > maxw) - win->w.width = maxw; - if (win->w.height > maxh) - win->w.height = maxh; - return 0; -} - -static int start_preview(struct saa7134_dev *dev) -{ - unsigned long base,control,bpl; - int err; - - err = verify_preview(dev, &dev->win, false); - if (0 != err) - return err; - - dev->ovfield = dev->win.field; - video_dbg("%s %dx%d+%d+%d 0x%08x field=%s\n", __func__, - dev->win.w.width, dev->win.w.height, - dev->win.w.left, dev->win.w.top, - dev->ovfmt->fourcc, v4l2_field_names[dev->ovfield]); - - /* setup window + clipping */ - set_size(dev, TASK_B, dev->win.w.width, dev->win.w.height, - V4L2_FIELD_HAS_BOTH(dev->ovfield)); - setup_clipping(dev, dev->clips, dev->nclips, - V4L2_FIELD_HAS_BOTH(dev->ovfield)); - if (dev->ovfmt->yuv) - saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x03); - else - saa_andorb(SAA7134_DATA_PATH(TASK_B), 0x3f, 0x01); - saa_writeb(SAA7134_OFMT_VIDEO_B, dev->ovfmt->pm | 0x20); - - /* dma: setup channel 1 (= Video Task B) */ - base = (unsigned long)dev->ovbuf.base; - base += dev->ovbuf.fmt.bytesperline * dev->win.w.top; - base += dev->ovfmt->depth/8 * dev->win.w.left; - bpl = dev->ovbuf.fmt.bytesperline; - control = SAA7134_RS_CONTROL_BURST_16; - if (dev->ovfmt->bswap) - control |= SAA7134_RS_CONTROL_BSWAP; - if (dev->ovfmt->wswap) - control |= SAA7134_RS_CONTROL_WSWAP; - if (V4L2_FIELD_HAS_BOTH(dev->ovfield)) { - saa_writel(SAA7134_RS_BA1(1),base); - saa_writel(SAA7134_RS_BA2(1),base+bpl); - saa_writel(SAA7134_RS_PITCH(1),bpl*2); - saa_writel(SAA7134_RS_CONTROL(1),control); - } else { - saa_writel(SAA7134_RS_BA1(1),base); - saa_writel(SAA7134_RS_BA2(1),base); - saa_writel(SAA7134_RS_PITCH(1),bpl); - saa_writel(SAA7134_RS_CONTROL(1),control); - } - - /* start dma */ - dev->ovenable = 1; - saa7134_set_dmabits(dev); - - return 0; -} - -static int stop_preview(struct saa7134_dev *dev) -{ - dev->ovenable = 0; - saa7134_set_dmabits(dev); - return 0; -} - /* * Media Controller helper functions */ @@ -1042,8 +855,6 @@ static const struct vb2_ops vb2_qops = { static int saa7134_s_ctrl(struct v4l2_ctrl *ctrl) { struct saa7134_dev *dev = container_of(ctrl->handler, struct saa7134_dev, ctrl_handler); - unsigned long flags; - int restart_overlay = 0; switch (ctrl->id) { case V4L2_CID_BRIGHTNESS: @@ -1081,15 +892,12 @@ static int saa7134_s_ctrl(struct v4l2_ctrl *ctrl) break; case V4L2_CID_HFLIP: dev->ctl_mirror = ctrl->val; - restart_overlay = 1; break; case V4L2_CID_PRIVATE_Y_EVEN: dev->ctl_y_even = ctrl->val; - restart_overlay = 1; break; case V4L2_CID_PRIVATE_Y_ODD: dev->ctl_y_odd = ctrl->val; - restart_overlay = 1; break; case V4L2_CID_PRIVATE_AUTOMUTE: { @@ -1112,12 +920,6 @@ static int saa7134_s_ctrl(struct v4l2_ctrl *ctrl) default: return -EINVAL; } - if (restart_overlay && dev->overlay_owner) { - spin_lock_irqsave(&dev->slock, flags); - stop_preview(dev); - start_preview(dev); - spin_unlock_irqrestore(&dev->slock, flags); - } return 0; } @@ -1150,21 +952,11 @@ static int video_release(struct file *file) { struct video_device *vdev = video_devdata(file); struct saa7134_dev *dev = video_drvdata(file); - struct v4l2_fh *fh = file->private_data; struct saa6588_command cmd; - unsigned long flags; mutex_lock(&dev->lock); saa7134_tvaudio_close(dev); - /* turn off overlay */ - if (fh == dev->overlay_owner) { - spin_lock_irqsave(&dev->slock,flags); - stop_preview(dev); - spin_unlock_irqrestore(&dev->slock,flags); - dev->overlay_owner = NULL; - } - if (vdev->vfl_type == VFL_TYPE_RADIO) v4l2_fh_release(file); else @@ -1261,34 +1053,6 @@ static int saa7134_g_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int saa7134_g_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7134_dev *dev = video_drvdata(file); - u32 clipcount = f->fmt.win.clipcount; - int i; - - if (saa7134_no_overlay > 0) { - pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - f->fmt.win = dev->win; - if (!f->fmt.win.clips) { - f->fmt.win.clipcount = 0; - return 0; - } - if (dev->nclips < clipcount) - clipcount = dev->nclips; - f->fmt.win.clipcount = clipcount; - - for (i = 0; i < clipcount; i++) { - memcpy(&f->fmt.win.clips[i].c, &dev->clips[i].c, - sizeof(struct v4l2_rect)); - } - - return 0; -} - static int saa7134_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { @@ -1342,21 +1106,6 @@ static int saa7134_try_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int saa7134_try_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7134_dev *dev = video_drvdata(file); - - if (saa7134_no_overlay > 0) { - pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - - if (f->fmt.win.clips == NULL) - f->fmt.win.clipcount = 0; - return verify_preview(dev, &f->fmt.win, true); -} - static int saa7134_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { @@ -1374,39 +1123,6 @@ static int saa7134_s_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int saa7134_s_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct saa7134_dev *dev = video_drvdata(file); - int err; - unsigned long flags; - - if (saa7134_no_overlay > 0) { - pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - if (f->fmt.win.clips == NULL) - f->fmt.win.clipcount = 0; - err = verify_preview(dev, &f->fmt.win, true); - if (0 != err) - return err; - - dev->win = f->fmt.win; - dev->nclips = f->fmt.win.clipcount; - - memcpy(dev->clips, f->fmt.win.clips, - sizeof(struct v4l2_clip) * dev->nclips); - - if (priv == dev->overlay_owner) { - spin_lock_irqsave(&dev->slock, flags); - stop_preview(dev); - start_preview(dev); - spin_unlock_irqrestore(&dev->slock, flags); - } - - return 0; -} - int saa7134_enum_input(struct file *file, void *priv, struct v4l2_input *i) { struct saa7134_dev *dev = video_drvdata(file); @@ -1482,8 +1198,6 @@ int saa7134_querycap(struct file *file, void *priv, cap->capabilities |= V4L2_CAP_TUNER; if (dev->has_rds) cap->capabilities |= V4L2_CAP_RDS_CAPTURE; - if (saa7134_no_overlay <= 0) - cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; return 0; } @@ -1492,17 +1206,9 @@ EXPORT_SYMBOL_GPL(saa7134_querycap); int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id) { struct saa7134_dev *dev = video_drvdata(file); - struct v4l2_fh *fh = priv; - unsigned long flags; unsigned int i; v4l2_std_id fixup; - if (is_empress(file) && dev->overlay_owner) { - /* Don't change the std from the mpeg device - if overlay is active. */ - return -EBUSY; - } - for (i = 0; i < TVNORMS; i++) if (id == tvnorms[i].id) break; @@ -1534,18 +1240,7 @@ int saa7134_s_std(struct file *file, void *priv, v4l2_std_id id) return -EINVAL; } - if (!is_empress(file) && fh == dev->overlay_owner) { - spin_lock_irqsave(&dev->slock, flags); - stop_preview(dev); - spin_unlock_irqrestore(&dev->slock, flags); - - set_tvnorm(dev, &tvnorms[i]); - - spin_lock_irqsave(&dev->slock, flags); - start_preview(dev); - spin_unlock_irqrestore(&dev->slock, flags); - } else - set_tvnorm(dev, &tvnorms[i]); + set_tvnorm(dev, &tvnorms[i]); saa7134_tvaudio_do_scan(dev); return 0; @@ -1595,8 +1290,7 @@ static int saa7134_g_pixelaspect(struct file *file, void *priv, { struct saa7134_dev *dev = video_drvdata(file); - if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - type != V4L2_BUF_TYPE_VIDEO_OVERLAY) + if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; if (dev->tvnorm->id & V4L2_STD_525_60) { @@ -1614,8 +1308,7 @@ static int saa7134_g_selection(struct file *file, void *f, struct v4l2_selection { struct saa7134_dev *dev = video_drvdata(file); - if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - sel->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) + if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; switch (sel->target) { @@ -1640,15 +1333,12 @@ static int saa7134_s_selection(struct file *file, void *f, struct v4l2_selection struct v4l2_rect *b = &dev->crop_bounds; struct v4l2_rect *c = &dev->crop_current; - if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - sel->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) + if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; if (sel->target != V4L2_SEL_TGT_CROP) return -EINVAL; - if (dev->overlay_owner) - return -EBUSY; if (vb2_is_streaming(&dev->video_vbq)) return -EBUSY; @@ -1764,85 +1454,6 @@ static int saa7134_enum_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int saa7134_enum_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (saa7134_no_overlay > 0) { - pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - - if ((f->index >= FORMATS) || formats[f->index].planar) - return -EINVAL; - - f->pixelformat = formats[f->index].fourcc; - - return 0; -} - -static int saa7134_g_fbuf(struct file *file, void *f, - struct v4l2_framebuffer *fb) -{ - struct saa7134_dev *dev = video_drvdata(file); - - *fb = dev->ovbuf; - fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; - - return 0; -} - -static int saa7134_s_fbuf(struct file *file, void *f, - const struct v4l2_framebuffer *fb) -{ - struct saa7134_dev *dev = video_drvdata(file); - struct saa7134_format *fmt; - - if (!capable(CAP_SYS_ADMIN) && - !capable(CAP_SYS_RAWIO)) - return -EPERM; - - /* check args */ - fmt = format_by_fourcc(fb->fmt.pixelformat); - if (NULL == fmt) - return -EINVAL; - - /* ok, accept it */ - dev->ovbuf = *fb; - dev->ovfmt = fmt; - if (0 == dev->ovbuf.fmt.bytesperline) - dev->ovbuf.fmt.bytesperline = - dev->ovbuf.fmt.width*fmt->depth/8; - return 0; -} - -static int saa7134_overlay(struct file *file, void *priv, unsigned int on) -{ - struct saa7134_dev *dev = video_drvdata(file); - unsigned long flags; - - if (on) { - if (saa7134_no_overlay > 0) { - video_dbg("no_overlay\n"); - return -EINVAL; - } - - if (dev->overlay_owner && priv != dev->overlay_owner) - return -EBUSY; - dev->overlay_owner = priv; - spin_lock_irqsave(&dev->slock, flags); - start_preview(dev); - spin_unlock_irqrestore(&dev->slock, flags); - } else { - if (priv != dev->overlay_owner) - return -EINVAL; - spin_lock_irqsave(&dev->slock, flags); - stop_preview(dev); - spin_unlock_irqrestore(&dev->slock, flags); - dev->overlay_owner = NULL; - } - return 0; -} - #ifdef CONFIG_VIDEO_ADV_DEBUG static int vidioc_g_register (struct file *file, void *priv, struct v4l2_dbg_register *reg) @@ -1912,10 +1523,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_g_fmt_vid_cap = saa7134_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = saa7134_try_fmt_vid_cap, .vidioc_s_fmt_vid_cap = saa7134_s_fmt_vid_cap, - .vidioc_enum_fmt_vid_overlay = saa7134_enum_fmt_vid_overlay, - .vidioc_g_fmt_vid_overlay = saa7134_g_fmt_vid_overlay, - .vidioc_try_fmt_vid_overlay = saa7134_try_fmt_vid_overlay, - .vidioc_s_fmt_vid_overlay = saa7134_s_fmt_vid_overlay, .vidioc_g_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, .vidioc_s_fmt_vbi_cap = saa7134_try_get_set_fmt_vbi_cap, @@ -1937,9 +1544,6 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_s_tuner = saa7134_s_tuner, .vidioc_g_selection = saa7134_g_selection, .vidioc_s_selection = saa7134_s_selection, - .vidioc_g_fbuf = saa7134_g_fbuf, - .vidioc_s_fbuf = saa7134_s_fbuf, - .vidioc_overlay = saa7134_overlay, .vidioc_g_frequency = saa7134_g_frequency, .vidioc_s_frequency = saa7134_s_frequency, #ifdef CONFIG_VIDEO_ADV_DEBUG @@ -2086,13 +1690,6 @@ int saa7134_video_init1(struct saa7134_dev *dev) dev->width = 720; dev->height = 576; dev->field = V4L2_FIELD_INTERLACED; - dev->win.w.width = dev->width; - dev->win.w.height = dev->height; - dev->win.field = V4L2_FIELD_INTERLACED; - dev->ovbuf.fmt.width = dev->width; - dev->ovbuf.fmt.height = dev->height; - dev->ovbuf.fmt.pixelformat = dev->fmt->fourcc; - dev->ovbuf.fmt.colorspace = V4L2_COLORSPACE_SMPTE170M; if (saa7134_boards[dev->board].video_out) saa7134_videoport_init(dev); diff --git a/drivers/media/pci/saa7134/saa7134.h b/drivers/media/pci/saa7134/saa7134.h index 5c9b2912a9d1..9f27e3775c27 100644 --- a/drivers/media/pci/saa7134/saa7134.h +++ b/drivers/media/pci/saa7134/saa7134.h @@ -429,7 +429,6 @@ struct saa7134_board { /* ----------------------------------------------------------- */ /* device / file handle status */ -#define RESOURCE_OVERLAY 1 #define RESOURCE_VIDEO 2 #define RESOURCE_VBI 4 #define RESOURCE_EMPRESS 8 @@ -589,17 +588,6 @@ struct saa7134_dev { unsigned char eedata[256]; int has_rds; - /* video overlay */ - struct v4l2_framebuffer ovbuf; - struct saa7134_format *ovfmt; - unsigned int ovenable; - enum v4l2_field ovfield; - struct v4l2_window win; - struct v4l2_clip clips[8]; - unsigned int nclips; - struct v4l2_fh *overlay_owner; - - /* video+ts+vbi capture */ struct saa7134_dmaqueue video_q; struct vb2_queue video_vbq; @@ -745,7 +733,6 @@ static inline bool is_empress(struct file *file) extern struct list_head saa7134_devlist; extern struct mutex saa7134_devlist_lock; -extern int saa7134_no_overlay; extern bool saa7134_userptr; void saa7134_track_gpio(struct saa7134_dev *dev, const char *msg); From patchwork Wed Mar 1 11:18:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 657985 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A74E7C7EE33 for ; Wed, 1 Mar 2023 11:19:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229973AbjCALTF (ORCPT ); Wed, 1 Mar 2023 06:19:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59894 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229969AbjCALTD (ORCPT ); Wed, 1 Mar 2023 06:19:03 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [IPv6:2604:1380:40e1:4800::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DCDB21A48A for ; Wed, 1 Mar 2023 03:18:59 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id BBD92CE0FB6 for ; Wed, 1 Mar 2023 11:18:57 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4F02AC4339C; Wed, 1 Mar 2023 11:18:55 +0000 (UTC) From: Hans Verkuil To: linux-media@vger.kernel.org Cc: Hans Verkuil Subject: [RFC PATCH 3/9] bttv: drop overlay support Date: Wed, 1 Mar 2023 12:18:44 +0100 Message-Id: <20230301111850.607515-4-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230301111850.607515-1-hverkuil-cisco@xs4all.nl> References: <20230301111850.607515-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Destructive overlay support (i.e. where the video frame is DMA-ed straight into a framebuffer) is effectively dead. It was a necessary evil in the early days when computers were not fast enough to copy SDTV video frames around, but today that's no longer a problem. It requires access to the framebuffer memory, which is a bad idea and very hard to do safely. In addition, in drm it is today almost impossible to get hold of the framebuffer address. So drop support for this. Signed-off-by: Hans Verkuil --- drivers/media/pci/bt8xx/Kconfig | 2 +- drivers/media/pci/bt8xx/btcx-risc.c | 153 --------- drivers/media/pci/bt8xx/bttv-cards.c | 15 - drivers/media/pci/bt8xx/bttv-driver.c | 436 +------------------------- drivers/media/pci/bt8xx/bttv-risc.c | 131 -------- drivers/media/pci/bt8xx/bttvp.h | 28 +- 6 files changed, 11 insertions(+), 754 deletions(-) diff --git a/drivers/media/pci/bt8xx/Kconfig b/drivers/media/pci/bt8xx/Kconfig index 927190281bd5..2d674dc28cec 100644 --- a/drivers/media/pci/bt8xx/Kconfig +++ b/drivers/media/pci/bt8xx/Kconfig @@ -15,7 +15,7 @@ config VIDEO_BT848 select RADIO_ADAPTERS select RADIO_TEA575X help - Support for BT848 based frame grabber/overlay boards. This includes + Support for BT848 based frame grabber boards. This includes the Miro, Hauppauge and STB boards. Please read the material in for more information. diff --git a/drivers/media/pci/bt8xx/btcx-risc.c b/drivers/media/pci/bt8xx/btcx-risc.c index b3179038b900..0adbf8233e1a 100644 --- a/drivers/media/pci/bt8xx/btcx-risc.c +++ b/drivers/media/pci/bt8xx/btcx-risc.c @@ -75,156 +75,3 @@ int btcx_riscmem_alloc(struct pci_dev *pci, } return 0; } - -/* ---------------------------------------------------------- */ -/* screen overlay helpers */ - -int -btcx_screen_clips(int swidth, int sheight, struct v4l2_rect *win, - struct v4l2_clip *clips, unsigned int n) -{ - if (win->left < 0) { - /* left */ - clips[n].c.left = 0; - clips[n].c.top = 0; - clips[n].c.width = -win->left; - clips[n].c.height = win->height; - n++; - } - if (win->left + win->width > swidth) { - /* right */ - clips[n].c.left = swidth - win->left; - clips[n].c.top = 0; - clips[n].c.width = win->width - clips[n].c.left; - clips[n].c.height = win->height; - n++; - } - if (win->top < 0) { - /* top */ - clips[n].c.left = 0; - clips[n].c.top = 0; - clips[n].c.width = win->width; - clips[n].c.height = -win->top; - n++; - } - if (win->top + win->height > sheight) { - /* bottom */ - clips[n].c.left = 0; - clips[n].c.top = sheight - win->top; - clips[n].c.width = win->width; - clips[n].c.height = win->height - clips[n].c.top; - n++; - } - return n; -} - -int -btcx_align(struct v4l2_rect *win, struct v4l2_clip *clips, unsigned int n, int mask) -{ - s32 nx,nw,dx; - unsigned int i; - - /* fixup window */ - nx = (win->left + mask) & ~mask; - nw = (win->width) & ~mask; - if (nx + nw > win->left + win->width) - nw -= mask+1; - dx = nx - win->left; - win->left = nx; - win->width = nw; - dprintk("btcx: window align %dx%d+%d+%d [dx=%d]\n", - win->width, win->height, win->left, win->top, dx); - - /* fixup clips */ - for (i = 0; i < n; i++) { - nx = (clips[i].c.left-dx) & ~mask; - nw = (clips[i].c.width) & ~mask; - if (nx + nw < clips[i].c.left-dx + clips[i].c.width) - nw += mask+1; - clips[i].c.left = nx; - clips[i].c.width = nw; - dprintk("btcx: clip align %dx%d+%d+%d\n", - clips[i].c.width, clips[i].c.height, - clips[i].c.left, clips[i].c.top); - } - return 0; -} - -void -btcx_sort_clips(struct v4l2_clip *clips, unsigned int nclips) -{ - int i,j,n; - - if (nclips < 2) - return; - for (i = nclips-2; i >= 0; i--) { - for (n = 0, j = 0; j <= i; j++) { - if (clips[j].c.left > clips[j+1].c.left) { - swap(clips[j], clips[j + 1]); - n++; - } - } - if (0 == n) - break; - } -} - -void -btcx_calc_skips(int line, int width, int *maxy, - struct btcx_skiplist *skips, unsigned int *nskips, - const struct v4l2_clip *clips, unsigned int nclips) -{ - unsigned int clip,skip; - int end, maxline; - - skip=0; - maxline = 9999; - for (clip = 0; clip < nclips; clip++) { - - /* sanity checks */ - if (clips[clip].c.left + clips[clip].c.width <= 0) - continue; - if (clips[clip].c.left > (signed)width) - break; - - /* vertical range */ - if (line > clips[clip].c.top+clips[clip].c.height-1) - continue; - if (line < clips[clip].c.top) { - if (maxline > clips[clip].c.top-1) - maxline = clips[clip].c.top-1; - continue; - } - if (maxline > clips[clip].c.top+clips[clip].c.height-1) - maxline = clips[clip].c.top+clips[clip].c.height-1; - - /* horizontal range */ - if (0 == skip || clips[clip].c.left > skips[skip-1].end) { - /* new one */ - skips[skip].start = clips[clip].c.left; - if (skips[skip].start < 0) - skips[skip].start = 0; - skips[skip].end = clips[clip].c.left + clips[clip].c.width; - if (skips[skip].end > width) - skips[skip].end = width; - skip++; - } else { - /* overlaps -- expand last one */ - end = clips[clip].c.left + clips[clip].c.width; - if (skips[skip-1].end < end) - skips[skip-1].end = end; - if (skips[skip-1].end > width) - skips[skip-1].end = width; - } - } - *nskips = skip; - *maxy = maxline; - - if (btcx_debug) { - dprintk("btcx: skips line %d-%d:", line, maxline); - for (skip = 0; skip < *nskips; skip++) { - pr_cont(" %d-%d", skips[skip].start, skips[skip].end); - } - pr_cont("\n"); - } -} diff --git a/drivers/media/pci/bt8xx/bttv-cards.c b/drivers/media/pci/bt8xx/bttv-cards.c index c2b5ab287dd7..ec78f7fc5e1b 100644 --- a/drivers/media/pci/bt8xx/bttv-cards.c +++ b/drivers/media/pci/bt8xx/bttv-cards.c @@ -81,7 +81,6 @@ static int pvr_boot(struct bttv *btv); static unsigned int triton1; static unsigned int vsfx; static unsigned int latency = UNSET; -int no_overlay=-1; static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET }; @@ -99,7 +98,6 @@ static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET }; /* insmod options */ module_param(triton1, int, 0444); module_param(vsfx, int, 0444); -module_param(no_overlay, int, 0444); module_param(latency, int, 0444); module_param(gpiomask, int, 0444); module_param(audioall, int, 0444); @@ -127,7 +125,6 @@ MODULE_PARM_DESC(audiodev, "specify audio device:\n" "\t\t 2 = tda7432\n" "\t\t 3 = tvaudio"); MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) is to use the card definition."); -MODULE_PARM_DESC(no_overlay, "allow override overlay default (0 disables, 1 enables) [some VIA/SIS chipsets are known to have problem with overlay]"); /* I2C addresses list */ @@ -4869,11 +4866,8 @@ static void gv800s_init(struct bttv *btv) void __init bttv_check_chipset(void) { - int pcipci_fail = 0; struct pci_dev *dev = NULL; - if (pci_pci_problems & (PCIPCI_FAIL|PCIAGP_FAIL)) /* should check if target is AGP */ - pcipci_fail = 1; if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF)) triton1 = 1; if (pci_pci_problems & PCIPCI_VSFX) @@ -4889,15 +4883,6 @@ void __init bttv_check_chipset(void) pr_info("Host bridge needs ETBF enabled\n"); if (vsfx) pr_info("Host bridge needs VSFX enabled\n"); - if (pcipci_fail) { - pr_info("bttv and your chipset may not work together\n"); - if (!no_overlay) { - pr_info("overlay will be disabled\n"); - no_overlay = 1; - } else { - pr_info("overlay forced. Use this option at your own risk.\n"); - } - } if (UNSET != latency) pr_info("pci latency fixup [%d]\n", latency); while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL, diff --git a/drivers/media/pci/bt8xx/bttv-driver.c b/drivers/media/pci/bt8xx/bttv-driver.c index d40b537f4e98..d9aed8111d59 100644 --- a/drivers/media/pci/bt8xx/bttv-driver.c +++ b/drivers/media/pci/bt8xx/bttv-driver.c @@ -624,20 +624,14 @@ static const unsigned int FORMATS = ARRAY_SIZE(formats); VIDIOC_QBUF 1) bttv_release VIDIOCMCAPTURE 1) - OVERLAY VIDIOCCAPTURE on VIDIOCCAPTURE off - VIDIOC_OVERLAY on VIDIOC_OVERLAY off - 3) bttv_release - VBI VIDIOC_STREAMON VIDIOC_STREAMOFF VIDIOC_QBUF 1) bttv_release - bttv_read, bttv_poll 1) 4) + bttv_read, bttv_poll 1) 3) 1) The resource must be allocated when we enter buffer prepare functions and remain allocated while buffers are in the DMA queue. 2) This is a single frame read. - 3) VIDIOC_S_FBUF and VIDIOC_S_FMT (OVERLAY) still work when - RESOURCE_OVERLAY is allocated. - 4) This is a continuous read, implies VIDIOC_STREAMON. + 3) This is a continuous read, implies VIDIOC_STREAMON. Note this driver permits video input and standard changes regardless if resources are allocated. @@ -645,8 +639,7 @@ static const unsigned int FORMATS = ARRAY_SIZE(formats); #define VBI_RESOURCES (RESOURCE_VBI) #define VIDEO_RESOURCES (RESOURCE_VIDEO_READ | \ - RESOURCE_VIDEO_STREAM | \ - RESOURCE_OVERLAY) + RESOURCE_VIDEO_STREAM) static int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit) @@ -1491,37 +1484,6 @@ format_by_fourcc(int fourcc) return NULL; } -/* ----------------------------------------------------------------------- */ -/* misc helpers */ - -static int -bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh, - struct bttv_buffer *new) -{ - struct bttv_buffer *old; - unsigned long flags; - - dprintk("switch_overlay: enter [new=%p]\n", new); - if (new) - new->vb.state = VIDEOBUF_DONE; - spin_lock_irqsave(&btv->s_lock,flags); - old = btv->screen; - btv->screen = new; - btv->loop_irq |= 1; - bttv_set_dma(btv, 0x03); - spin_unlock_irqrestore(&btv->s_lock,flags); - if (NULL != old) { - dprintk("switch_overlay: old=%p state is %d\n", - old, old->vb.state); - bttv_dma_free(&fh->cap,btv, old); - kfree(old); - } - if (NULL == new) - free_btres_lock(btv,fh,RESOURCE_OVERLAY); - dprintk("switch_overlay: done\n"); - return 0; -} - /* ----------------------------------------------------------------------- */ /* video4linux (1) interface */ @@ -2045,150 +2007,6 @@ limit_scaled_size_lock (struct bttv_fh * fh, return rc; } -/* Returns an error if the given overlay window dimensions are not - possible with the current cropping parameters. If adjust_size is - TRUE the function may adjust the window width and/or height - instead, however it always rounds the horizontal position and - width as btcx_align() does. If adjust_crop is TRUE the function - may also adjust the current cropping parameters to get closer - to the desired window size. */ -static int -verify_window_lock(struct bttv_fh *fh, struct v4l2_window *win, - int adjust_size, int adjust_crop) -{ - enum v4l2_field field; - unsigned int width_mask; - - if (win->w.width < 48) - win->w.width = 48; - if (win->w.height < 32) - win->w.height = 32; - if (win->clipcount > 2048) - win->clipcount = 2048; - - win->chromakey = 0; - win->global_alpha = 0; - field = win->field; - - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - case V4L2_FIELD_INTERLACED: - break; - default: - field = V4L2_FIELD_ANY; - break; - } - if (V4L2_FIELD_ANY == field) { - __s32 height2; - - height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; - field = (win->w.height > height2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_TOP; - } - win->field = field; - - if (NULL == fh->ovfmt) - return -EINVAL; - /* 4-byte alignment. */ - width_mask = ~0; - switch (fh->ovfmt->depth) { - case 8: - case 24: - width_mask = ~3; - break; - case 16: - width_mask = ~1; - break; - case 32: - break; - default: - BUG(); - } - - win->w.width -= win->w.left & ~width_mask; - win->w.left = (win->w.left - width_mask - 1) & width_mask; - - return limit_scaled_size_lock(fh, &win->w.width, &win->w.height, - field, width_mask, - /* width_bias: round down */ 0, - adjust_size, adjust_crop); -} - -static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, - struct v4l2_window *win, int fixup) -{ - struct v4l2_clip *clips = NULL; - int n,size,retval = 0; - - if (NULL == fh->ovfmt) - return -EINVAL; - if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED)) - return -EINVAL; - retval = verify_window_lock(fh, win, - /* adjust_size */ fixup, - /* adjust_crop */ fixup); - if (0 != retval) - return retval; - - /* copy clips -- luckily v4l1 + v4l2 are binary - compatible here ...*/ - n = win->clipcount; - size = sizeof(*clips)*(n+4); - clips = kmalloc(size,GFP_KERNEL); - if (NULL == clips) - return -ENOMEM; - if (n > 0) - memcpy(clips, win->clips, sizeof(struct v4l2_clip) * n); - - /* clip against screen */ - if (NULL != btv->fbuf.base) - n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height, - &win->w, clips, n); - btcx_sort_clips(clips,n); - - /* 4-byte alignments */ - switch (fh->ovfmt->depth) { - case 8: - case 24: - btcx_align(&win->w, clips, n, 3); - break; - case 16: - btcx_align(&win->w, clips, n, 1); - break; - case 32: - /* no alignment fixups needed */ - break; - default: - BUG(); - } - - kfree(fh->ov.clips); - fh->ov.clips = clips; - fh->ov.nclips = n; - - fh->ov.w = win->w; - fh->ov.field = win->field; - fh->ov.setup_ok = 1; - - btv->init.ov.w.width = win->w.width; - btv->init.ov.w.height = win->w.height; - btv->init.ov.field = win->field; - - /* update overlay if needed */ - retval = 0; - if (check_btres(fh, RESOURCE_OVERLAY)) { - struct bttv_buffer *new; - - new = videobuf_sg_alloc(sizeof(*new)); - new->crop = btv->crop[!!fh->do_crop].rect; - bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); - retval = bttv_switch_overlay(btv,fh,new); - } - return retval; -} - /* ----------------------------------------------------------------------- */ static struct videobuf_queue* bttv_queue(struct bttv_fh *fh) @@ -2270,17 +2088,6 @@ static int bttv_g_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int bttv_g_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct bttv_fh *fh = priv; - - f->fmt.win.w = fh->ov.w; - f->fmt.win.field = fh->ov.field; - - return 0; -} - static void bttv_get_width_mask_vid_cap(const struct bttv_format *fmt, unsigned int *width_mask, unsigned int *width_bias) @@ -2352,17 +2159,6 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int bttv_try_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct bttv_fh *fh = priv; - - verify_window_lock(fh, &f->fmt.win, - /* adjust_size */ 1, - /* adjust_crop */ 0); - return 0; -} - static int bttv_s_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f) { @@ -2410,20 +2206,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv, return 0; } -static int bttv_s_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct bttv_fh *fh = priv; - struct bttv *btv = fh->btv; - - if (no_overlay > 0) { - pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - - return setup_window_lock(fh, btv, &f->fmt.win, 1); -} - static int bttv_querycap(struct file *file, void *priv, struct v4l2_capability *cap) { @@ -2437,8 +2219,6 @@ static int bttv_querycap(struct file *file, void *priv, strscpy(cap->card, btv->video_dev.name, sizeof(cap->card)); cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS; - if (no_overlay <= 0) - cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY; if (video_is_registered(&btv->vbi_dev)) cap->capabilities |= V4L2_CAP_VBI_CAPTURE; if (video_is_registered(&btv->radio_dev)) { @@ -2458,7 +2238,8 @@ static int bttv_querycap(struct file *file, void *priv, return 0; } -static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f) +static int bttv_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) { int index = -1, i; @@ -2476,159 +2257,6 @@ static int bttv_enum_fmt_cap_ovr(struct v4l2_fmtdesc *f) return i; } -static int bttv_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - int rc = bttv_enum_fmt_cap_ovr(f); - - if (rc < 0) - return rc; - - return 0; -} - -static int bttv_enum_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - int rc; - - if (no_overlay > 0) { - pr_err("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n"); - return -EINVAL; - } - - rc = bttv_enum_fmt_cap_ovr(f); - - if (rc < 0) - return rc; - - if (!(formats[rc].flags & FORMAT_FLAGS_PACKED)) - return -EINVAL; - - return 0; -} - -static int bttv_g_fbuf(struct file *file, void *f, - struct v4l2_framebuffer *fb) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - - *fb = btv->fbuf; - fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING; - fb->flags = V4L2_FBUF_FLAG_PRIMARY; - if (fh->ovfmt) - fb->fmt.pixelformat = fh->ovfmt->fourcc; - return 0; -} - -static int bttv_overlay(struct file *file, void *f, unsigned int on) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - struct bttv_buffer *new; - int retval = 0; - - if (on) { - /* verify args */ - if (unlikely(!btv->fbuf.base)) { - return -EINVAL; - } - if (unlikely(!fh->ov.setup_ok)) { - dprintk("%d: overlay: !setup_ok\n", btv->c.nr); - retval = -EINVAL; - } - if (retval) - return retval; - } - - if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY)) - return -EBUSY; - - if (on) { - fh->ov.tvnorm = btv->tvnorm; - new = videobuf_sg_alloc(sizeof(*new)); - new->crop = btv->crop[!!fh->do_crop].rect; - bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); - } else { - new = NULL; - } - - /* switch over */ - retval = bttv_switch_overlay(btv, fh, new); - return retval; -} - -static int bttv_s_fbuf(struct file *file, void *f, - const struct v4l2_framebuffer *fb) -{ - struct bttv_fh *fh = f; - struct bttv *btv = fh->btv; - const struct bttv_format *fmt; - int retval; - - if (!capable(CAP_SYS_ADMIN) && - !capable(CAP_SYS_RAWIO)) - return -EPERM; - - /* check args */ - fmt = format_by_fourcc(fb->fmt.pixelformat); - if (NULL == fmt) - return -EINVAL; - if (0 == (fmt->flags & FORMAT_FLAGS_PACKED)) - return -EINVAL; - - retval = -EINVAL; - if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { - __s32 width = fb->fmt.width; - __s32 height = fb->fmt.height; - - retval = limit_scaled_size_lock(fh, &width, &height, - V4L2_FIELD_INTERLACED, - /* width_mask */ ~3, - /* width_bias */ 2, - /* adjust_size */ 0, - /* adjust_crop */ 0); - if (0 != retval) - return retval; - } - - /* ok, accept it */ - btv->fbuf.base = fb->base; - btv->fbuf.fmt.width = fb->fmt.width; - btv->fbuf.fmt.height = fb->fmt.height; - if (0 != fb->fmt.bytesperline) - btv->fbuf.fmt.bytesperline = fb->fmt.bytesperline; - else - btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fmt->depth/8; - - retval = 0; - fh->ovfmt = fmt; - btv->init.ovfmt = fmt; - if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) { - fh->ov.w.left = 0; - fh->ov.w.top = 0; - fh->ov.w.width = fb->fmt.width; - fh->ov.w.height = fb->fmt.height; - btv->init.ov.w.width = fb->fmt.width; - btv->init.ov.w.height = fb->fmt.height; - - kfree(fh->ov.clips); - fh->ov.clips = NULL; - fh->ov.nclips = 0; - - if (check_btres(fh, RESOURCE_OVERLAY)) { - struct bttv_buffer *new; - - new = videobuf_sg_alloc(sizeof(*new)); - new->crop = btv->crop[!!fh->do_crop].rect; - bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); - retval = bttv_switch_overlay(btv, fh, new); - } - } - return retval; -} - static int bttv_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p) { @@ -2748,8 +2376,7 @@ static int bttv_g_selection(struct file *file, void *f, struct v4l2_selection *s struct bttv_fh *fh = f; struct bttv *btv = fh->btv; - if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - sel->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) + if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; switch (sel->target) { @@ -2786,8 +2413,7 @@ static int bttv_s_selection(struct file *file, void *f, struct v4l2_selection *s __s32 b_right; __s32 b_bottom; - if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && - sel->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) + if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; if (sel->target != V4L2_SEL_TGT_CROP) @@ -2977,7 +2603,6 @@ static int bttv_open(struct file *file) v4l2_fh_init(&fh->fh, vdev); fh->type = type; - fh->ov.setup_ok = 0; videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, &btv->c.pci->dev, &btv->s_lock, @@ -3021,10 +2646,6 @@ static int bttv_release(struct file *file) struct bttv_fh *fh = file->private_data; struct bttv *btv = fh->btv; - /* turn off overlay */ - if (check_btres(fh, RESOURCE_OVERLAY)) - bttv_switch_overlay(btv,fh,NULL); - /* stop video capture */ if (check_btres(fh, RESOURCE_VIDEO_STREAM)) { videobuf_streamoff(&fh->cap); @@ -3090,10 +2711,6 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_g_fmt_vid_cap = bttv_g_fmt_vid_cap, .vidioc_try_fmt_vid_cap = bttv_try_fmt_vid_cap, .vidioc_s_fmt_vid_cap = bttv_s_fmt_vid_cap, - .vidioc_enum_fmt_vid_overlay = bttv_enum_fmt_vid_overlay, - .vidioc_g_fmt_vid_overlay = bttv_g_fmt_vid_overlay, - .vidioc_try_fmt_vid_overlay = bttv_try_fmt_vid_overlay, - .vidioc_s_fmt_vid_overlay = bttv_s_fmt_vid_overlay, .vidioc_g_fmt_vbi_cap = bttv_g_fmt_vbi_cap, .vidioc_try_fmt_vbi_cap = bttv_try_fmt_vbi_cap, .vidioc_s_fmt_vbi_cap = bttv_s_fmt_vbi_cap, @@ -3113,9 +2730,6 @@ static const struct v4l2_ioctl_ops bttv_ioctl_ops = { .vidioc_s_tuner = bttv_s_tuner, .vidioc_g_selection = bttv_g_selection, .vidioc_s_selection = bttv_s_selection, - .vidioc_g_fbuf = bttv_g_fbuf, - .vidioc_s_fbuf = bttv_s_fbuf, - .vidioc_overlay = bttv_overlay, .vidioc_g_parm = bttv_g_parm, .vidioc_g_frequency = bttv_g_frequency, .vidioc_s_frequency = bttv_s_frequency, @@ -3385,9 +2999,6 @@ static void bttv_print_riscaddr(struct bttv *btv) ? (unsigned long long)btv->curr.top->top.dma : 0, btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0); - pr_info(" scr : o=%08llx e=%08llx\n", - btv->screen ? (unsigned long long)btv->screen->top.dma : 0, - btv->screen ? (unsigned long long)btv->screen->bottom.dma : 0); bttv_risc_disasm(btv, &btv->main); } @@ -3508,28 +3119,9 @@ bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set) } } - /* screen overlay ? */ - if (NULL != btv->screen) { - if (V4L2_FIELD_HAS_BOTH(btv->screen->vb.field)) { - if (NULL == set->top && NULL == set->bottom) { - set->top = btv->screen; - set->bottom = btv->screen; - } - } else { - if (V4L2_FIELD_TOP == btv->screen->vb.field && - NULL == set->top) { - set->top = btv->screen; - } - if (V4L2_FIELD_BOTTOM == btv->screen->vb.field && - NULL == set->bottom) { - set->bottom = btv->screen; - } - } - } - - dprintk("%d: next set: top=%p bottom=%p [screen=%p,irq=%d,%d]\n", + dprintk("%d: next set: top=%p bottom=%p [irq=%d,%d]\n", btv->c.nr, set->top, set->bottom, - btv->screen, set->frame_irq, set->top_irq); + set->frame_irq, set->top_irq); return 0; } @@ -3883,17 +3475,12 @@ static void bttv_unregister_video(struct bttv *btv) /* register video4linux devices */ static int bttv_register_video(struct bttv *btv) { - if (no_overlay > 0) - pr_notice("Overlay support disabled\n"); - /* video */ vdev_init(btv, &btv->video_dev, &bttv_video_template, "video"); btv->video_dev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; if (btv->tuner_type != TUNER_ABSENT) btv->video_dev.device_caps |= V4L2_CAP_TUNER; - if (no_overlay <= 0) - btv->video_dev.device_caps |= V4L2_CAP_VIDEO_OVERLAY; if (video_register_device(&btv->video_dev, VFL_TYPE_VIDEO, video_nr[btv->c.nr]) < 0) @@ -4084,14 +3671,9 @@ static int bttv_probe(struct pci_dev *dev, const struct pci_device_id *pci_id) /* fill struct bttv with some useful defaults */ btv->init.btv = btv; - btv->init.ov.w.width = 320; - btv->init.ov.w.height = 240; btv->init.fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24); btv->init.width = 320; btv->init.height = 240; - btv->init.ov.w.width = 320; - btv->init.ov.w.height = 240; - btv->init.ov.field = V4L2_FIELD_INTERLACED; btv->input = 0; v4l2_ctrl_new_std(hdl, &bttv_ctrl_ops, diff --git a/drivers/media/pci/bt8xx/bttv-risc.c b/drivers/media/pci/bt8xx/bttv-risc.c index 32fa4a7fe76f..4fa4b9da9634 100644 --- a/drivers/media/pci/bt8xx/bttv-risc.c +++ b/drivers/media/pci/bt8xx/bttv-risc.c @@ -231,95 +231,6 @@ bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc, return 0; } -static int -bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc, - const struct bttv_format *fmt, struct bttv_overlay *ov, - int skip_even, int skip_odd) -{ - int dwords, rc, line, maxy, start, end; - unsigned skip, nskips; - struct btcx_skiplist *skips; - __le32 *rp; - u32 ri,ra; - u32 addr; - - /* skip list for window clipping */ - skips = kmalloc_array(ov->nclips, sizeof(*skips),GFP_KERNEL); - if (NULL == skips) - return -ENOMEM; - - /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions - + sync + jump (all 2 dwords) */ - dwords = (3 * ov->nclips + 2) * - ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height); - dwords += 4; - if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) { - kfree(skips); - return rc; - } - - /* sync instruction */ - rp = risc->cpu; - *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1); - *(rp++) = cpu_to_le32(0); - - addr = (unsigned long)btv->fbuf.base; - addr += btv->fbuf.fmt.bytesperline * ov->w.top; - addr += (fmt->depth >> 3) * ov->w.left; - - /* scan lines */ - for (maxy = -1, line = 0; line < ov->w.height; - line++, addr += btv->fbuf.fmt.bytesperline) { - if ((btv->opt_vcr_hack) && - (line >= (ov->w.height - VCR_HACK_LINES))) - continue; - if ((line%2) == 0 && skip_even) - continue; - if ((line%2) == 1 && skip_odd) - continue; - - /* calculate clipping */ - if (line > maxy) - btcx_calc_skips(line, ov->w.width, &maxy, - skips, &nskips, ov->clips, ov->nclips); - - /* write out risc code */ - for (start = 0, skip = 0; start < ov->w.width; start = end) { - if (skip >= nskips) { - ri = BT848_RISC_WRITE; - end = ov->w.width; - } else if (start < skips[skip].start) { - ri = BT848_RISC_WRITE; - end = skips[skip].start; - } else { - ri = BT848_RISC_SKIP; - end = skips[skip].end; - skip++; - } - if (BT848_RISC_WRITE == ri) - ra = addr + (fmt->depth>>3)*start; - else - ra = 0; - - if (0 == start) - ri |= BT848_RISC_SOL; - if (ov->w.width == end) - ri |= BT848_RISC_EOL; - ri |= (fmt->depth>>3) * (end-start); - - *(rp++)=cpu_to_le32(ri); - if (0 != ra) - *(rp++)=cpu_to_le32(ra); - } - } - - /* save pointer to jmp instruction address */ - risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); - kfree(skips); - return 0; -} - /* ---------------------------------------------------------- */ static void @@ -848,45 +759,3 @@ bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf) buf->btswap = buf->fmt->btswap; return 0; } - -/* ---------------------------------------------------------- */ - -/* calculate geometry, build risc code */ -int -bttv_overlay_risc(struct bttv *btv, - struct bttv_overlay *ov, - const struct bttv_format *fmt, - struct bttv_buffer *buf) -{ - /* check interleave, bottom+top fields */ - dprintk("%d: overlay fields: %s format: 0x%08x size: %dx%d\n", - btv->c.nr, v4l2_field_names[buf->vb.field], - fmt->fourcc, ov->w.width, ov->w.height); - - /* calculate geometry */ - bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height, - V4L2_FIELD_HAS_BOTH(ov->field), - &bttv_tvnorms[ov->tvnorm],&buf->crop); - - /* build risc code */ - switch (ov->field) { - case V4L2_FIELD_TOP: - bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0); - break; - case V4L2_FIELD_BOTTOM: - bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0); - break; - case V4L2_FIELD_INTERLACED: - bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1); - bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0); - break; - default: - BUG(); - } - - /* copy format info */ - buf->btformat = fmt->btformat; - buf->btswap = fmt->btswap; - buf->vb.field = ov->field; - return 0; -} diff --git a/drivers/media/pci/bt8xx/bttvp.h b/drivers/media/pci/bt8xx/bttvp.h index 4abf43657846..717f002a41df 100644 --- a/drivers/media/pci/bt8xx/bttvp.h +++ b/drivers/media/pci/bt8xx/bttvp.h @@ -50,7 +50,6 @@ #define RISC_SLOT_E_FIELD 12 #define RISC_SLOT_LOOP 14 -#define RESOURCE_OVERLAY 1 #define RESOURCE_VIDEO_STREAM 2 #define RESOURCE_VBI 4 #define RESOURCE_VIDEO_READ 8 @@ -165,15 +164,6 @@ struct bttv_buffer_set { unsigned int frame_irq; }; -struct bttv_overlay { - unsigned int tvnorm; - struct v4l2_rect w; - enum v4l2_field field; - struct v4l2_clip *clips; - int nclips; - int setup_ok; -}; - struct bttv_vbi_fmt { struct v4l2_vbi_format fmt; @@ -216,10 +206,6 @@ struct bttv_fh { int width; int height; - /* video overlay */ - const struct bttv_format *ovfmt; - struct bttv_overlay ov; - /* Application called VIDIOC_S_SELECTION. */ int do_crop; @@ -256,12 +242,6 @@ int bttv_buffer_activate_vbi(struct bttv *btv, void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv, struct bttv_buffer *buf); -/* overlay handling */ -int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov, - const struct bttv_format *fmt, - struct bttv_buffer *buf); - - /* ---------------------------------------------------------- */ /* bttv-vbi.c */ @@ -278,11 +258,6 @@ extern struct bus_type bttv_sub_bus_type; int bttv_sub_add_device(struct bttv_core *core, char *name); int bttv_sub_del_devices(struct bttv_core *core); -/* ---------------------------------------------------------- */ -/* bttv-cards.c */ - -extern int no_overlay; - /* ---------------------------------------------------------- */ /* bttv-input.c */ @@ -454,7 +429,6 @@ struct bttv { - must acquire s_lock before changing these - only the irq handler is supported to touch top + bottom + vcurr */ struct btcx_riscmem main; - struct bttv_buffer *screen; /* overlay */ struct list_head capture; /* video capture queue */ struct list_head vcapture; /* vbi capture queue */ struct bttv_buffer_set curr; /* active buffers */ @@ -479,7 +453,7 @@ struct bttv { /* used to make dvb-bt8xx autoloadable */ struct work_struct request_module_wk; - /* Default (0) and current (1) video capturing and overlay + /* Default (0) and current (1) video capturing cropping parameters in bttv_tvnorm.cropcap units. Protected by bttv.lock. */ struct bttv_crop crop[2]; From patchwork Wed Mar 1 11:18:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 657986 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 133DBC7EE32 for ; Wed, 1 Mar 2023 11:19:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229970AbjCALTD (ORCPT ); Wed, 1 Mar 2023 06:19:03 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59862 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229961AbjCALTC (ORCPT ); Wed, 1 Mar 2023 06:19:02 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AA5E7199E3 for ; Wed, 1 Mar 2023 03:18:59 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 3A699B80E05 for ; Wed, 1 Mar 2023 11:18:58 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4F8E6C4339B; Wed, 1 Mar 2023 11:18:56 +0000 (UTC) From: Hans Verkuil To: linux-media@vger.kernel.org Cc: Hans Verkuil Subject: [RFC PATCH 4/9] vivid: drop overlay support Date: Wed, 1 Mar 2023 12:18:45 +0100 Message-Id: <20230301111850.607515-5-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230301111850.607515-1-hverkuil-cisco@xs4all.nl> References: <20230301111850.607515-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Destructive overlay support (i.e. where the video frame is DMA-ed straight into a framebuffer) is effectively dead. It was a necessary evil in the early days when computers were not fast enough to copy SDTV video frames around, but today that's no longer a problem. It requires access to the framebuffer memory, which is a bad idea and very hard to do safely. In addition, in drm it is today almost impossible to get hold of the framebuffer address. So drop support for this. Signed-off-by: Hans Verkuil --- drivers/media/test-drivers/vivid/vivid-core.c | 48 +--- drivers/media/test-drivers/vivid/vivid-core.h | 13 - .../test-drivers/vivid/vivid-kthread-cap.c | 108 ------- .../media/test-drivers/vivid/vivid-vid-cap.c | 272 ------------------ .../media/test-drivers/vivid/vivid-vid-cap.h | 3 - 5 files changed, 6 insertions(+), 438 deletions(-) diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c index f28440e6c9f8..31d8c34495cb 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.c +++ b/drivers/media/test-drivers/vivid/vivid-core.c @@ -126,7 +126,7 @@ MODULE_PARM_DESC(node_types, " node types, default is 0xe1d3d. Bitmask with the "\t\t bit 8: Video Output node\n" "\t\t bit 10-11: VBI Output node: 0 = none, 1 = raw vbi, 2 = sliced vbi, 3 = both\n" "\t\t bit 12: Radio Transmitter node\n" - "\t\t bit 16: Framebuffer for testing overlays\n" + "\t\t bit 16: Framebuffer for testing output overlays\n" "\t\t bit 17: Metadata Capture node\n" "\t\t bit 18: Metadata Output node\n" "\t\t bit 19: Touch Capture node\n"); @@ -326,7 +326,7 @@ static int vidioc_overlay(struct file *file, void *fh, unsigned i) struct video_device *vdev = video_devdata(file); if (vdev->vfl_dir == VFL_DIR_RX) - return vivid_vid_cap_overlay(file, fh, i); + return -ENOTTY; return vivid_vid_out_overlay(file, fh, i); } @@ -335,38 +335,16 @@ static int vidioc_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a struct video_device *vdev = video_devdata(file); if (vdev->vfl_dir == VFL_DIR_RX) - return vivid_vid_cap_g_fbuf(file, fh, a); + return -ENOTTY; return vivid_vid_out_g_fbuf(file, fh, a); } -/* - * Only support the framebuffer of one of the vivid instances. - * Anything else is rejected. - */ -bool vivid_validate_fb(const struct v4l2_framebuffer *a) -{ - struct vivid_dev *dev; - int i; - - for (i = 0; i < n_devs; i++) { - dev = vivid_devs[i]; - if (!dev || !dev->video_pbase) - continue; - if ((unsigned long)a->base == dev->video_pbase && - a->fmt.width <= dev->display_width && - a->fmt.height <= dev->display_height && - a->fmt.bytesperline <= dev->display_byte_stride) - return true; - } - return false; -} - static int vidioc_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a) { struct video_device *vdev = video_devdata(file); if (vdev->vfl_dir == VFL_DIR_RX) - return vivid_vid_cap_s_fbuf(file, fh, a); + return -ENOTTY; return vivid_vid_out_s_fbuf(file, fh, a); } @@ -651,8 +629,6 @@ static int vivid_fop_release(struct file *file) vivid_reconnect(dev); } mutex_unlock(&dev->mutex); - if (file->private_data == dev->overlay_cap_owner) - dev->overlay_cap_owner = NULL; if (file->private_data == dev->radio_rx_rds_owner) { dev->radio_rx_rds_last_block = 0; dev->radio_rx_rds_owner = NULL; @@ -778,10 +754,6 @@ static const struct v4l2_ioctl_ops vivid_ioctl_ops = { .vidioc_g_parm = vidioc_g_parm, .vidioc_s_parm = vidioc_s_parm, - .vidioc_enum_fmt_vid_overlay = vidioc_enum_fmt_vid_overlay, - .vidioc_g_fmt_vid_overlay = vidioc_g_fmt_vid_overlay, - .vidioc_try_fmt_vid_overlay = vidioc_try_fmt_vid_overlay, - .vidioc_s_fmt_vid_overlay = vidioc_s_fmt_vid_overlay, .vidioc_g_fmt_vid_out_overlay = vidioc_g_fmt_vid_out_overlay, .vidioc_try_fmt_vid_out_overlay = vidioc_try_fmt_vid_out_overlay, .vidioc_s_fmt_vid_out_overlay = vidioc_s_fmt_vid_out_overlay, @@ -862,7 +834,6 @@ static void vivid_dev_release(struct v4l2_device *v4l2_dev) vfree(dev->scaled_line); vfree(dev->blended_line); vfree(dev->edid); - vfree(dev->bitmap_cap); vfree(dev->bitmap_out); tpg_free(&dev->tpg); kfree(dev->query_dv_timings_qmenu); @@ -1107,7 +1078,7 @@ static void vivid_set_capabilities(struct vivid_dev *dev) /* set up the capabilities of the video capture device */ dev->vid_cap_caps = dev->multiplanar ? V4L2_CAP_VIDEO_CAPTURE_MPLANE : - V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OVERLAY; + V4L2_CAP_VIDEO_CAPTURE; dev->vid_cap_caps |= V4L2_CAP_STREAMING | V4L2_CAP_READWRITE; if (dev->has_audio_inputs) dev->vid_cap_caps |= V4L2_CAP_AUDIO; @@ -1396,7 +1367,7 @@ static int vivid_create_queues(struct vivid_dev *dev) } if (dev->has_fb) { - /* Create framebuffer for testing capture/output overlay */ + /* Create framebuffer for testing output overlay */ ret = vivid_fb_init(dev); if (ret) return ret; @@ -1892,13 +1863,6 @@ static int vivid_create_instance(struct platform_device *pdev, int inst) vivid_update_format_cap(dev, false); vivid_update_format_out(dev); - /* initialize overlay */ - dev->fb_cap.fmt.width = dev->src_rect.width; - dev->fb_cap.fmt.height = dev->src_rect.height; - dev->fb_cap.fmt.pixelformat = dev->fmt_cap->fourcc; - dev->fb_cap.fmt.bytesperline = dev->src_rect.width * tpg_g_twopixelsize(&dev->tpg, 0) / 2; - dev->fb_cap.fmt.sizeimage = dev->src_rect.height * dev->fb_cap.fmt.bytesperline; - /* update touch configuration */ dev->timeperframe_tch_cap.numerator = 1; dev->timeperframe_tch_cap.denominator = 10; diff --git a/drivers/media/test-drivers/vivid/vivid-core.h b/drivers/media/test-drivers/vivid/vivid-core.h index 473f3598db5a..02a75d04ff8a 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.h +++ b/drivers/media/test-drivers/vivid/vivid-core.h @@ -345,17 +345,6 @@ struct vivid_dev { u32 power_present; - /* Capture Overlay */ - struct v4l2_framebuffer fb_cap; - struct v4l2_fh *overlay_cap_owner; - void *fb_vbase_cap; - int overlay_cap_top, overlay_cap_left; - enum v4l2_field overlay_cap_field; - void *bitmap_cap; - struct v4l2_clip clips_cap[MAX_CLIPS]; - struct v4l2_clip try_clips_cap[MAX_CLIPS]; - unsigned clipcount_cap; - /* Output */ unsigned output; v4l2_std_id std_out; @@ -613,6 +602,4 @@ static inline bool vivid_is_hdmi_out(const struct vivid_dev *dev) return dev->output_type[dev->output] == HDMI; } -bool vivid_validate_fb(const struct v4l2_framebuffer *a); - #endif diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c index ee65d20314d3..177c73979325 100644 --- a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c @@ -554,109 +554,6 @@ static void vivid_fillbuff(struct vivid_dev *dev, struct vivid_buffer *buf) } } -/* - * Return true if this pixel coordinate is a valid video pixel. - */ -static bool valid_pix(struct vivid_dev *dev, int win_y, int win_x, int fb_y, int fb_x) -{ - int i; - - if (dev->bitmap_cap) { - /* - * Only if the corresponding bit in the bitmap is set can - * the video pixel be shown. Coordinates are relative to - * the overlay window set by VIDIOC_S_FMT. - */ - const u8 *p = dev->bitmap_cap; - unsigned stride = (dev->compose_cap.width + 7) / 8; - - if (!(p[stride * win_y + win_x / 8] & (1 << (win_x & 7)))) - return false; - } - - for (i = 0; i < dev->clipcount_cap; i++) { - /* - * Only if the framebuffer coordinate is not in any of the - * clip rectangles will be video pixel be shown. - */ - struct v4l2_rect *r = &dev->clips_cap[i].c; - - if (fb_y >= r->top && fb_y < r->top + r->height && - fb_x >= r->left && fb_x < r->left + r->width) - return false; - } - return true; -} - -/* - * Draw the image into the overlay buffer. - * Note that the combination of overlay and multiplanar is not supported. - */ -static void vivid_overlay(struct vivid_dev *dev, struct vivid_buffer *buf) -{ - struct tpg_data *tpg = &dev->tpg; - unsigned pixsize = tpg_g_twopixelsize(tpg, 0) / 2; - void *vbase = dev->fb_vbase_cap; - void *vbuf = vb2_plane_vaddr(&buf->vb.vb2_buf, 0); - unsigned img_width = dev->compose_cap.width; - unsigned img_height = dev->compose_cap.height; - unsigned stride = tpg->bytesperline[0]; - /* if quick is true, then valid_pix() doesn't have to be called */ - bool quick = dev->bitmap_cap == NULL && dev->clipcount_cap == 0; - int x, y, w, out_x = 0; - - /* - * Overlay support is only supported for formats that have a twopixelsize - * that's >= 2. Warn and bail out if that's not the case. - */ - if (WARN_ON(pixsize == 0)) - return; - if ((dev->overlay_cap_field == V4L2_FIELD_TOP || - dev->overlay_cap_field == V4L2_FIELD_BOTTOM) && - dev->overlay_cap_field != buf->vb.field) - return; - - vbuf += dev->compose_cap.left * pixsize + dev->compose_cap.top * stride; - x = dev->overlay_cap_left; - w = img_width; - if (x < 0) { - out_x = -x; - w = w - out_x; - x = 0; - } else { - w = dev->fb_cap.fmt.width - x; - if (w > img_width) - w = img_width; - } - if (w <= 0) - return; - if (dev->overlay_cap_top >= 0) - vbase += dev->overlay_cap_top * dev->fb_cap.fmt.bytesperline; - for (y = dev->overlay_cap_top; - y < dev->overlay_cap_top + (int)img_height; - y++, vbuf += stride) { - int px; - - if (y < 0 || y > dev->fb_cap.fmt.height) - continue; - if (quick) { - memcpy(vbase + x * pixsize, - vbuf + out_x * pixsize, w * pixsize); - vbase += dev->fb_cap.fmt.bytesperline; - continue; - } - for (px = 0; px < w; px++) { - if (!valid_pix(dev, y - dev->overlay_cap_top, - px + out_x, y, px + x)) - continue; - memcpy(vbase + (px + x) * pixsize, - vbuf + (px + out_x) * pixsize, - pixsize); - } - vbase += dev->fb_cap.fmt.bytesperline; - } -} - static void vivid_cap_update_frame_period(struct vivid_dev *dev) { u64 f_period; @@ -730,11 +627,6 @@ static noinline_for_stack void vivid_thread_vid_cap_tick(struct vivid_dev *dev, dprintk(dev, 1, "filled buffer %d\n", vid_cap_buf->vb.vb2_buf.index); - /* Handle overlay */ - if (dev->overlay_cap_owner && dev->fb_cap.base && - dev->fb_cap.fmt.pixelformat == dev->fmt_cap->fourcc) - vivid_overlay(dev, vid_cap_buf); - v4l2_ctrl_request_complete(vid_cap_buf->vb.vb2_buf.req_obj.req, &dev->ctrl_hdl_vid_cap); vb2_buffer_done(&vid_cap_buf->vb.vb2_buf, dev->dqbuf_error ? diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.c b/drivers/media/test-drivers/vivid/vivid-vid-cap.c index c0999581c599..801286dc1448 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.c @@ -21,30 +21,6 @@ #include "vivid-kthread-cap.h" #include "vivid-vid-cap.h" -static const struct vivid_fmt formats_ovl[] = { - { - .fourcc = V4L2_PIX_FMT_RGB565, /* gggbbbbb rrrrrggg */ - .vdownsampling = { 1 }, - .bit_depth = { 16 }, - .planes = 1, - .buffers = 1, - }, - { - .fourcc = V4L2_PIX_FMT_XRGB555, /* gggbbbbb arrrrrgg */ - .vdownsampling = { 1 }, - .bit_depth = { 16 }, - .planes = 1, - .buffers = 1, - }, - { - .fourcc = V4L2_PIX_FMT_ARGB555, /* gggbbbbb arrrrrgg */ - .vdownsampling = { 1 }, - .bit_depth = { 16 }, - .planes = 1, - .buffers = 1, - }, -}; - /* The number of discrete webcam framesizes */ #define VIVID_WEBCAM_SIZES 6 /* The number of discrete webcam frameintervals */ @@ -447,18 +423,10 @@ void vivid_update_format_cap(struct vivid_dev *dev, bool keep_controls) tpg_s_rgb_range(&dev->tpg, v4l2_ctrl_g_ctrl(dev->rgb_range_cap)); break; } - vfree(dev->bitmap_cap); - dev->bitmap_cap = NULL; vivid_update_quality(dev); tpg_reset_source(&dev->tpg, dev->src_rect.width, dev->src_rect.height, dev->field_cap); dev->crop_cap = dev->src_rect; dev->crop_bounds_cap = dev->src_rect; - if (dev->bitmap_cap && - (dev->compose_cap.width != dev->crop_cap.width || - dev->compose_cap.height != dev->crop_cap.height)) { - vfree(dev->bitmap_cap); - dev->bitmap_cap = NULL; - } dev->compose_cap = dev->crop_cap; if (V4L2_FIELD_HAS_T_OR_B(dev->field_cap)) dev->compose_cap.height /= 2; @@ -701,11 +669,6 @@ int vivid_s_fmt_vid_cap(struct file *file, void *priv, return -EBUSY; } - if (dev->overlay_cap_owner && dev->fb_cap.fmt.pixelformat != mp->pixelformat) { - dprintk(dev, 1, "overlay is active, can't change pixelformat\n"); - return -EBUSY; - } - dev->fmt_cap = vivid_get_format(dev, mp->pixelformat); if (V4L2_FIELD_HAS_T_OR_B(mp->field)) factor = 2; @@ -927,8 +890,6 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection struct vivid_dev *dev = video_drvdata(file); struct v4l2_rect *crop = &dev->crop_cap; struct v4l2_rect *compose = &dev->compose_cap; - unsigned orig_compose_w = compose->width; - unsigned orig_compose_h = compose->height; unsigned factor = V4L2_FIELD_HAS_T_OR_B(dev->field_cap) ? 2 : 1; int ret; @@ -1052,11 +1013,6 @@ int vivid_vid_cap_s_selection(struct file *file, void *fh, struct v4l2_selection return -EINVAL; } - if (dev->bitmap_cap && (compose->width != orig_compose_w || - compose->height != orig_compose_h)) { - vfree(dev->bitmap_cap); - dev->bitmap_cap = NULL; - } tpg_s_crop_compose(&dev->tpg, crop, compose); return 0; } @@ -1084,234 +1040,6 @@ int vivid_vid_cap_g_pixelaspect(struct file *file, void *priv, return 0; } -int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - struct vivid_dev *dev = video_drvdata(file); - const struct vivid_fmt *fmt; - - if (dev->multiplanar) - return -ENOTTY; - - if (f->index >= ARRAY_SIZE(formats_ovl)) - return -EINVAL; - - fmt = &formats_ovl[f->index]; - - f->pixelformat = fmt->fourcc; - return 0; -} - -int vidioc_g_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct vivid_dev *dev = video_drvdata(file); - const struct v4l2_rect *compose = &dev->compose_cap; - struct v4l2_window *win = &f->fmt.win; - unsigned clipcount = win->clipcount; - - if (dev->multiplanar) - return -ENOTTY; - - win->w.top = dev->overlay_cap_top; - win->w.left = dev->overlay_cap_left; - win->w.width = compose->width; - win->w.height = compose->height; - win->field = dev->overlay_cap_field; - win->clipcount = dev->clipcount_cap; - if (clipcount > dev->clipcount_cap) - clipcount = dev->clipcount_cap; - if (dev->bitmap_cap == NULL) - win->bitmap = NULL; - else if (win->bitmap) { - if (copy_to_user(win->bitmap, dev->bitmap_cap, - ((compose->width + 7) / 8) * compose->height)) - return -EFAULT; - } - if (clipcount && win->clips) - memcpy(win->clips, dev->clips_cap, - clipcount * sizeof(dev->clips_cap[0])); - return 0; -} - -int vidioc_try_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct vivid_dev *dev = video_drvdata(file); - const struct v4l2_rect *compose = &dev->compose_cap; - struct v4l2_window *win = &f->fmt.win; - int i, j; - - if (dev->multiplanar) - return -ENOTTY; - - win->w.left = clamp_t(int, win->w.left, - -dev->fb_cap.fmt.width, dev->fb_cap.fmt.width); - win->w.top = clamp_t(int, win->w.top, - -dev->fb_cap.fmt.height, dev->fb_cap.fmt.height); - win->w.width = compose->width; - win->w.height = compose->height; - if (win->field != V4L2_FIELD_BOTTOM && win->field != V4L2_FIELD_TOP) - win->field = V4L2_FIELD_ANY; - win->chromakey = 0; - win->global_alpha = 0; - if (win->clipcount && !win->clips) - win->clipcount = 0; - if (win->clipcount > MAX_CLIPS) - win->clipcount = MAX_CLIPS; - if (win->clipcount) { - memcpy(dev->try_clips_cap, win->clips, - win->clipcount * sizeof(dev->clips_cap[0])); - for (i = 0; i < win->clipcount; i++) { - struct v4l2_rect *r = &dev->try_clips_cap[i].c; - - r->top = clamp_t(s32, r->top, 0, dev->fb_cap.fmt.height - 1); - r->height = clamp_t(s32, r->height, 1, dev->fb_cap.fmt.height - r->top); - r->left = clamp_t(u32, r->left, 0, dev->fb_cap.fmt.width - 1); - r->width = clamp_t(u32, r->width, 1, dev->fb_cap.fmt.width - r->left); - } - /* - * Yeah, so sue me, it's an O(n^2) algorithm. But n is a small - * number and it's typically a one-time deal. - */ - for (i = 0; i < win->clipcount - 1; i++) { - struct v4l2_rect *r1 = &dev->try_clips_cap[i].c; - - for (j = i + 1; j < win->clipcount; j++) { - struct v4l2_rect *r2 = &dev->try_clips_cap[j].c; - - if (v4l2_rect_overlap(r1, r2)) - return -EINVAL; - } - } - memcpy(win->clips, dev->try_clips_cap, - win->clipcount * sizeof(dev->clips_cap[0])); - } - return 0; -} - -int vidioc_s_fmt_vid_overlay(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct vivid_dev *dev = video_drvdata(file); - const struct v4l2_rect *compose = &dev->compose_cap; - struct v4l2_window *win = &f->fmt.win; - int ret = vidioc_try_fmt_vid_overlay(file, priv, f); - unsigned bitmap_size = ((compose->width + 7) / 8) * compose->height; - unsigned clips_size = win->clipcount * sizeof(dev->clips_cap[0]); - void *new_bitmap = NULL; - - if (ret) - return ret; - - if (win->bitmap) { - new_bitmap = vzalloc(bitmap_size); - - if (new_bitmap == NULL) - return -ENOMEM; - if (copy_from_user(new_bitmap, win->bitmap, bitmap_size)) { - vfree(new_bitmap); - return -EFAULT; - } - } - - dev->overlay_cap_top = win->w.top; - dev->overlay_cap_left = win->w.left; - dev->overlay_cap_field = win->field; - vfree(dev->bitmap_cap); - dev->bitmap_cap = new_bitmap; - dev->clipcount_cap = win->clipcount; - if (dev->clipcount_cap) - memcpy(dev->clips_cap, dev->try_clips_cap, clips_size); - return 0; -} - -int vivid_vid_cap_overlay(struct file *file, void *fh, unsigned i) -{ - struct vivid_dev *dev = video_drvdata(file); - - if (dev->multiplanar) - return -ENOTTY; - - if (i && dev->fb_vbase_cap == NULL) - return -EINVAL; - - if (i && dev->fb_cap.fmt.pixelformat != dev->fmt_cap->fourcc) { - dprintk(dev, 1, "mismatch between overlay and video capture pixelformats\n"); - return -EINVAL; - } - - if (dev->overlay_cap_owner && dev->overlay_cap_owner != fh) - return -EBUSY; - dev->overlay_cap_owner = i ? fh : NULL; - return 0; -} - -int vivid_vid_cap_g_fbuf(struct file *file, void *fh, - struct v4l2_framebuffer *a) -{ - struct vivid_dev *dev = video_drvdata(file); - - if (dev->multiplanar) - return -ENOTTY; - - *a = dev->fb_cap; - a->capability = V4L2_FBUF_CAP_BITMAP_CLIPPING | - V4L2_FBUF_CAP_LIST_CLIPPING; - a->flags = V4L2_FBUF_FLAG_PRIMARY; - a->fmt.field = V4L2_FIELD_NONE; - a->fmt.colorspace = V4L2_COLORSPACE_SRGB; - a->fmt.priv = 0; - return 0; -} - -int vivid_vid_cap_s_fbuf(struct file *file, void *fh, - const struct v4l2_framebuffer *a) -{ - struct vivid_dev *dev = video_drvdata(file); - const struct vivid_fmt *fmt; - - if (dev->multiplanar) - return -ENOTTY; - - if (!capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RAWIO)) - return -EPERM; - - if (dev->overlay_cap_owner) - return -EBUSY; - - if (a->base == NULL) { - dev->fb_cap.base = NULL; - dev->fb_vbase_cap = NULL; - return 0; - } - - if (a->fmt.width < 48 || a->fmt.height < 32) - return -EINVAL; - fmt = vivid_get_format(dev, a->fmt.pixelformat); - if (!fmt || !fmt->can_do_overlay) - return -EINVAL; - if (a->fmt.bytesperline < (a->fmt.width * fmt->bit_depth[0]) / 8) - return -EINVAL; - if (a->fmt.bytesperline > a->fmt.sizeimage / a->fmt.height) - return -EINVAL; - - /* - * Only support the framebuffer of one of the vivid instances. - * Anything else is rejected. - */ - if (!vivid_validate_fb(a)) - return -EINVAL; - - dev->fb_vbase_cap = phys_to_virt((unsigned long)a->base); - dev->fb_cap = *a; - dev->overlay_cap_left = clamp_t(int, dev->overlay_cap_left, - -dev->fb_cap.fmt.width, dev->fb_cap.fmt.width); - dev->overlay_cap_top = clamp_t(int, dev->overlay_cap_top, - -dev->fb_cap.fmt.height, dev->fb_cap.fmt.height); - return 0; -} - static const struct v4l2_audio vivid_audio_inputs[] = { { 0, "TV", V4L2_AUDCAP_STEREO }, { 1, "Line-In", V4L2_AUDCAP_STEREO }, diff --git a/drivers/media/test-drivers/vivid/vivid-vid-cap.h b/drivers/media/test-drivers/vivid/vivid-vid-cap.h index 1e422a59eeab..949768652d38 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-cap.h +++ b/drivers/media/test-drivers/vivid/vivid-vid-cap.h @@ -33,9 +33,6 @@ int vidioc_enum_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_fmtd int vidioc_g_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f); int vidioc_try_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f); int vidioc_s_fmt_vid_overlay(struct file *file, void *priv, struct v4l2_format *f); -int vivid_vid_cap_overlay(struct file *file, void *fh, unsigned i); -int vivid_vid_cap_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *a); -int vivid_vid_cap_s_fbuf(struct file *file, void *fh, const struct v4l2_framebuffer *a); int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *inp); int vidioc_g_input(struct file *file, void *priv, unsigned *i); int vidioc_s_input(struct file *file, void *priv, unsigned i); From patchwork Wed Mar 1 11:18:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 657987 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA7C7C7EE31 for ; Wed, 1 Mar 2023 11:19:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229972AbjCALTE (ORCPT ); Wed, 1 Mar 2023 06:19:04 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59866 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229964AbjCALTC (ORCPT ); Wed, 1 Mar 2023 06:19:02 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [145.40.68.75]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CF8AD83E6 for ; Wed, 1 Mar 2023 03:19:00 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 5029FB8100C for ; Wed, 1 Mar 2023 11:18:59 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4FD8DC433EF; Wed, 1 Mar 2023 11:18:57 +0000 (UTC) From: Hans Verkuil To: linux-media@vger.kernel.org Cc: Hans Verkuil Subject: [RFC PATCH 5/9] vivid: drop bitmap and clipping output overlay support Date: Wed, 1 Mar 2023 12:18:46 +0100 Message-Id: <20230301111850.607515-6-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230301111850.607515-1-hverkuil-cisco@xs4all.nl> References: <20230301111850.607515-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org This test driver is the only remaining driver still using the clipping and bitmap method. Drop support for this so we can remove this in the V4L2 API as well. Signed-off-by: Hans Verkuil --- drivers/media/test-drivers/vivid/vivid-core.c | 1 - drivers/media/test-drivers/vivid/vivid-core.h | 6 -- .../test-drivers/vivid/vivid-kthread-cap.c | 23 +----- .../media/test-drivers/vivid/vivid-vid-out.c | 74 ------------------- 4 files changed, 1 insertion(+), 103 deletions(-) diff --git a/drivers/media/test-drivers/vivid/vivid-core.c b/drivers/media/test-drivers/vivid/vivid-core.c index 31d8c34495cb..bdabf7671011 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.c +++ b/drivers/media/test-drivers/vivid/vivid-core.c @@ -834,7 +834,6 @@ static void vivid_dev_release(struct v4l2_device *v4l2_dev) vfree(dev->scaled_line); vfree(dev->blended_line); vfree(dev->edid); - vfree(dev->bitmap_out); tpg_free(&dev->tpg); kfree(dev->query_dv_timings_qmenu); kfree(dev->query_dv_timings_qmenu_strings); diff --git a/drivers/media/test-drivers/vivid/vivid-core.h b/drivers/media/test-drivers/vivid/vivid-core.h index 02a75d04ff8a..cfb8e66083f6 100644 --- a/drivers/media/test-drivers/vivid/vivid-core.h +++ b/drivers/media/test-drivers/vivid/vivid-core.h @@ -22,8 +22,6 @@ #define dprintk(dev, level, fmt, arg...) \ v4l2_dbg(level, vivid_debug, &dev->v4l2_dev, fmt, ## arg) -/* The maximum number of clip rectangles */ -#define MAX_CLIPS 16 /* The maximum number of inputs */ #define MAX_INPUTS 16 /* The maximum number of outputs */ @@ -372,10 +370,6 @@ struct vivid_dev { void *fb_vbase_out; bool overlay_out_enabled; int overlay_out_top, overlay_out_left; - void *bitmap_out; - struct v4l2_clip clips_out[MAX_CLIPS]; - struct v4l2_clip try_clips_out[MAX_CLIPS]; - unsigned clipcount_out; unsigned fbuf_out_flags; u32 chromakey_out; u8 global_alpha_out; diff --git a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c index 177c73979325..42048727d7ff 100644 --- a/drivers/media/test-drivers/vivid/vivid-kthread-cap.c +++ b/drivers/media/test-drivers/vivid/vivid-kthread-cap.c @@ -53,31 +53,10 @@ static void copy_pix(struct vivid_dev *dev, int win_y, int win_x, u16 *cap, const u16 *osd) { u16 out; - int left = dev->overlay_out_left; - int top = dev->overlay_out_top; - int fb_x = win_x + left; - int fb_y = win_y + top; - int i; out = *cap; *cap = *osd; - if (dev->bitmap_out) { - const u8 *p = dev->bitmap_out; - unsigned stride = (dev->compose_out.width + 7) / 8; - win_x -= dev->compose_out.left; - win_y -= dev->compose_out.top; - if (!(p[stride * win_y + win_x / 8] & (1 << (win_x & 7)))) - return; - } - - for (i = 0; i < dev->clipcount_out; i++) { - struct v4l2_rect *r = &dev->clips_out[i].c; - - if (fb_y >= r->top && fb_y < r->top + r->height && - fb_x >= r->left && fb_x < r->left + r->width) - return; - } if ((dev->fbuf_out_flags & V4L2_FBUF_FLAG_CHROMAKEY) && *osd != dev->chromakey_out) return; @@ -251,7 +230,7 @@ static noinline_for_stack int vivid_copy_buffer(struct vivid_dev *dev, unsigned u8 *voutbuf; u8 *vosdbuf = NULL; unsigned y; - bool blend = dev->bitmap_out || dev->clipcount_out || dev->fbuf_out_flags; + bool blend = dev->fbuf_out_flags; /* Coarse scaling with Bresenham */ unsigned vid_out_int_part; unsigned vid_out_fract_part; diff --git a/drivers/media/test-drivers/vivid/vivid-vid-out.c b/drivers/media/test-drivers/vivid/vivid-vid-out.c index 9f731f085179..184a6df2c29f 100644 --- a/drivers/media/test-drivers/vivid/vivid-vid-out.c +++ b/drivers/media/test-drivers/vivid/vivid-vid-out.c @@ -793,11 +793,6 @@ int vivid_vid_out_s_selection(struct file *file, void *fh, struct v4l2_selection } s->r.top *= factor; s->r.height *= factor; - if (dev->bitmap_out && (compose->width != s->r.width || - compose->height != s->r.height)) { - vfree(dev->bitmap_out); - dev->bitmap_out = NULL; - } *compose = s->r; break; default: @@ -836,7 +831,6 @@ int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv, struct vivid_dev *dev = video_drvdata(file); const struct v4l2_rect *compose = &dev->compose_out; struct v4l2_window *win = &f->fmt.win; - unsigned clipcount = win->clipcount; if (!dev->has_fb) return -EINVAL; @@ -844,22 +838,9 @@ int vidioc_g_fmt_vid_out_overlay(struct file *file, void *priv, win->w.left = dev->overlay_out_left; win->w.width = compose->width; win->w.height = compose->height; - win->clipcount = dev->clipcount_out; win->field = V4L2_FIELD_ANY; win->chromakey = dev->chromakey_out; win->global_alpha = dev->global_alpha_out; - if (clipcount > dev->clipcount_out) - clipcount = dev->clipcount_out; - if (dev->bitmap_out == NULL) - win->bitmap = NULL; - else if (win->bitmap) { - if (copy_to_user(win->bitmap, dev->bitmap_out, - ((dev->compose_out.width + 7) / 8) * dev->compose_out.height)) - return -EFAULT; - } - if (clipcount && win->clips) - memcpy(win->clips, dev->clips_out, - clipcount * sizeof(dev->clips_out[0])); return 0; } @@ -869,7 +850,6 @@ int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv, struct vivid_dev *dev = video_drvdata(file); const struct v4l2_rect *compose = &dev->compose_out; struct v4l2_window *win = &f->fmt.win; - int i, j; if (!dev->has_fb) return -EINVAL; @@ -884,38 +864,6 @@ int vidioc_try_fmt_vid_out_overlay(struct file *file, void *priv, * so always set this to ANY. */ win->field = V4L2_FIELD_ANY; - if (win->clipcount && !win->clips) - win->clipcount = 0; - if (win->clipcount > MAX_CLIPS) - win->clipcount = MAX_CLIPS; - if (win->clipcount) { - memcpy(dev->try_clips_out, win->clips, - win->clipcount * sizeof(dev->clips_out[0])); - for (i = 0; i < win->clipcount; i++) { - struct v4l2_rect *r = &dev->try_clips_out[i].c; - - r->top = clamp_t(s32, r->top, 0, dev->display_height - 1); - r->height = clamp_t(s32, r->height, 1, dev->display_height - r->top); - r->left = clamp_t(u32, r->left, 0, dev->display_width - 1); - r->width = clamp_t(u32, r->width, 1, dev->display_width - r->left); - } - /* - * Yeah, so sue me, it's an O(n^2) algorithm. But n is a small - * number and it's typically a one-time deal. - */ - for (i = 0; i < win->clipcount - 1; i++) { - struct v4l2_rect *r1 = &dev->try_clips_out[i].c; - - for (j = i + 1; j < win->clipcount; j++) { - struct v4l2_rect *r2 = &dev->try_clips_out[j].c; - - if (v4l2_rect_overlap(r1, r2)) - return -EINVAL; - } - } - memcpy(win->clips, dev->try_clips_out, - win->clipcount * sizeof(dev->clips_out[0])); - } return 0; } @@ -923,34 +871,14 @@ int vidioc_s_fmt_vid_out_overlay(struct file *file, void *priv, struct v4l2_format *f) { struct vivid_dev *dev = video_drvdata(file); - const struct v4l2_rect *compose = &dev->compose_out; struct v4l2_window *win = &f->fmt.win; int ret = vidioc_try_fmt_vid_out_overlay(file, priv, f); - unsigned bitmap_size = ((compose->width + 7) / 8) * compose->height; - unsigned clips_size = win->clipcount * sizeof(dev->clips_out[0]); - void *new_bitmap = NULL; if (ret) return ret; - if (win->bitmap) { - new_bitmap = vzalloc(bitmap_size); - - if (!new_bitmap) - return -ENOMEM; - if (copy_from_user(new_bitmap, win->bitmap, bitmap_size)) { - vfree(new_bitmap); - return -EFAULT; - } - } - dev->overlay_out_top = win->w.top; dev->overlay_out_left = win->w.left; - vfree(dev->bitmap_out); - dev->bitmap_out = new_bitmap; - dev->clipcount_out = win->clipcount; - if (dev->clipcount_out) - memcpy(dev->clips_out, dev->try_clips_out, clips_size); dev->chromakey_out = win->chromakey; dev->global_alpha_out = win->global_alpha; return ret; @@ -975,8 +903,6 @@ int vivid_vid_out_g_fbuf(struct file *file, void *fh, struct vivid_dev *dev = video_drvdata(file); a->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | - V4L2_FBUF_CAP_BITMAP_CLIPPING | - V4L2_FBUF_CAP_LIST_CLIPPING | V4L2_FBUF_CAP_CHROMAKEY | V4L2_FBUF_CAP_SRC_CHROMAKEY | V4L2_FBUF_CAP_GLOBAL_ALPHA | From patchwork Wed Mar 1 11:18:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans Verkuil X-Patchwork-Id: 657984 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B5AF5C64EC7 for ; Wed, 1 Mar 2023 11:19:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229984AbjCALTI (ORCPT ); Wed, 1 Mar 2023 06:19:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59986 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229976AbjCALTG (ORCPT ); Wed, 1 Mar 2023 06:19:06 -0500 Received: from ams.source.kernel.org (ams.source.kernel.org [IPv6:2604:1380:4601:e00::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5937E1C596 for ; Wed, 1 Mar 2023 03:19:04 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ams.source.kernel.org (Postfix) with ESMTPS id 1C50CB8100E for ; Wed, 1 Mar 2023 11:19:03 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 5151EC433EF; Wed, 1 Mar 2023 11:19:01 +0000 (UTC) From: Hans Verkuil To: linux-media@vger.kernel.org Cc: Hans Verkuil Subject: [RFC PATCH 9/9] Documentation: userspace-api: media: drop clipping, destructive overlays Date: Wed, 1 Mar 2023 12:18:50 +0100 Message-Id: <20230301111850.607515-10-hverkuil-cisco@xs4all.nl> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230301111850.607515-1-hverkuil-cisco@xs4all.nl> References: <20230301111850.607515-1-hverkuil-cisco@xs4all.nl> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org Support for clipping for overlays has been removed, update the documentation. Support for destructive overlay support has been removed as well, also update the documentation for this. Signed-off-by: Hans Verkuil --- .../userspace-api/media/v4l/dev-overlay.rst | 10 +++- .../userspace-api/media/v4l/vidioc-g-fbuf.rst | 52 ++++++------------- 2 files changed, 24 insertions(+), 38 deletions(-) diff --git a/Documentation/userspace-api/media/v4l/dev-overlay.rst b/Documentation/userspace-api/media/v4l/dev-overlay.rst index 4f4b23b95b9b..d52977120b41 100644 --- a/Documentation/userspace-api/media/v4l/dev-overlay.rst +++ b/Documentation/userspace-api/media/v4l/dev-overlay.rst @@ -67,6 +67,7 @@ ioctls must be supported by all video overlay devices. Setup ===== +*Note: support for this has been removed.* Before overlay can commence applications must program the driver with frame buffer parameters, namely the address and size of the frame buffer and the image format, for example RGB 5:6:5. The @@ -92,11 +93,13 @@ A driver may support any (or none) of five clipping/blending methods: 1. Chroma-keying displays the overlaid image only where pixels in the primary graphics surface assume a certain color. -2. A bitmap can be specified where each bit corresponds to a pixel in +2. *Note: support for this has been removed.* + A bitmap can be specified where each bit corresponds to a pixel in the overlaid image. When the bit is set, the corresponding video pixel is displayed, otherwise a pixel of the graphics surface. -3. A list of clipping rectangles can be specified. In these regions *no* +3. *Note: support for this has been removed.* + A list of clipping rectangles can be specified. In these regions *no* video is displayed, so the graphics surface can be seen here. 4. The framebuffer has an alpha channel that can be used to clip or @@ -185,6 +188,7 @@ struct v4l2_window be 0xRRGGBB on a little endian, 0xBBGGRR on a big endian host. ``struct v4l2_clip * clips`` + *Note: support for this has been removed.* When chroma-keying has *not* been negotiated and :ref:`VIDIOC_G_FBUF ` indicated this capability, applications can set this field to point to an array of clipping @@ -201,6 +205,7 @@ struct v4l2_window are undefined. ``__u32 clipcount`` + *Note: support for this has been removed.* When the application set the ``clips`` field, this field must contain the number of clipping rectangles in the list. When clip lists are not supported the driver ignores this field, its contents @@ -208,6 +213,7 @@ struct v4l2_window supported but no clipping is desired this field must be set to zero. ``void * bitmap`` + *Note: support for this has been removed.* When chroma-keying has *not* been negotiated and :ref:`VIDIOC_G_FBUF ` indicated this capability, applications can set this field to point to a clipping bit mask. diff --git a/Documentation/userspace-api/media/v4l/vidioc-g-fbuf.rst b/Documentation/userspace-api/media/v4l/vidioc-g-fbuf.rst index b6cc1a823207..b651e53643dd 100644 --- a/Documentation/userspace-api/media/v4l/vidioc-g-fbuf.rst +++ b/Documentation/userspace-api/media/v4l/vidioc-g-fbuf.rst @@ -49,6 +49,9 @@ of a graphics card. A non-destructive overlay blends video images into a VGA signal or graphics into a video signal. *Video Output Overlays* are always non-destructive. +Destructive overlay support has been removed: with modern GPUs and CPUs +this is no longer needed, and it was always a very dangerous feature. + To get the current parameters applications call the :ref:`VIDIOC_G_FBUF ` ioctl with a pointer to a struct :c:type:`v4l2_framebuffer` structure. The driver fills all fields of the structure or returns an @@ -63,18 +66,12 @@ this structure, the driver prepares for the overlay and returns the framebuffer parameters as :ref:`VIDIOC_G_FBUF ` does, or it returns an error code. -To set the parameters for a *non-destructive Video Overlay*, +To set the parameters for a *Video Capture Overlay* applications must initialize the ``flags`` field, the ``fmt`` substructure, and call :ref:`VIDIOC_S_FBUF `. Again the driver prepares for the overlay and returns the framebuffer parameters as :ref:`VIDIOC_G_FBUF ` does, or it returns an error code. -For a *destructive Video Overlay* applications must additionally provide -a ``base`` address. Setting up a DMA to a random memory location can -jeopardize the system security, its stability or even damage the -hardware, therefore only the superuser can set the parameters for a -destructive video overlay. - .. tabularcolumns:: |p{3.5cm}|p{3.5cm}|p{3.5cm}|p{6.6cm}| .. c:type:: v4l2_framebuffer @@ -100,17 +97,14 @@ destructive video overlay. - ``base`` - - Physical base address of the framebuffer, that is the address of - the pixel in the top left corner of the framebuffer. [#f1]_ - * - - - - - - - This field is irrelevant to *non-destructive Video Overlays*. For - *destructive Video Overlays* applications must provide a base - address. The driver may accept only base addresses which are a - multiple of two, four or eight bytes. For *Video Output Overlays* - the driver must return a valid base address, so applications can + the pixel in the top left corner of the framebuffer. + For :ref:`VIDIOC_S_FBUF ` this field is no longer supported + and the kernel will always set this to NULL. + For *Video Output Overlays* + the driver will return a valid base address, so applications can find the corresponding Linux framebuffer device (see - :ref:`osd`). + :ref:`osd`). For *Video Capture Overlays* this field will always be + NULL. * - struct - ``fmt`` - @@ -136,8 +130,7 @@ destructive video overlay. * - - - - - For *destructive Video Overlays* applications must initialize this - field. For *Video Output Overlays* the driver must return a valid + - For *Video Output Overlays* the driver must return a valid format. * - - @@ -165,13 +158,6 @@ destructive video overlay. This field is irrelevant to *non-destructive Video Overlays*. - For *destructive Video Overlays* both applications and drivers can - set this field to request padding bytes at the end of each line. - Drivers however may ignore the requested value, returning - ``width`` times bytes-per-pixel or a larger value required by the - hardware. That implies applications can just set this field to - zero to get a reasonable default. - For *Video Output Overlays* the driver must return a valid value. Video hardware may access padding bytes, therefore they must @@ -190,9 +176,8 @@ destructive video overlay. * - - __u32 - ``sizeimage`` - - This field is irrelevant to *non-destructive Video Overlays*. For - *destructive Video Overlays* applications must initialize this - field. For *Video Output Overlays* the driver must return a valid + - This field is irrelevant to *non-destructive Video Overlays*. + For *Video Output Overlays* the driver must return a valid format. Together with ``base`` it defines the framebuffer memory @@ -232,9 +217,11 @@ destructive video overlay. * - ``V4L2_FBUF_CAP_LIST_CLIPPING`` - 0x0004 - The device supports clipping using a list of clip rectangles. + Note that this is no longer supported. * - ``V4L2_FBUF_CAP_BITMAP_CLIPPING`` - 0x0008 - The device supports clipping using a bit mask. + Note that this is no longer supported. * - ``V4L2_FBUF_CAP_LOCAL_ALPHA`` - 0x0010 - The device supports clipping/blending using the alpha channel of @@ -342,10 +329,3 @@ EPERM EINVAL The :ref:`VIDIOC_S_FBUF ` parameters are unsuitable. - -.. [#f1] - A physical base address may not suit all platforms. GK notes in - theory we should pass something like PCI device + memory region + - offset instead. If you encounter problems please discuss on the - linux-media mailing list: - `https://linuxtv.org/lists.php `__.