From patchwork Mon Jun 20 11:52:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Curtin X-Patchwork-Id: 16285 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 94A9EBD808 for ; Mon, 20 Jun 2022 11:55:37 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id CDAA165635; Mon, 20 Jun 2022 13:55:36 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1655726136; bh=t4ubaAXKxvm8akX5y/yD/ZJX0ifX/V18g8LpvReRfbo=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=AGiaxDiPBBXYzArdVbrrM82eFA1S0WkfI+ZKcumBNBJyj8aXldYgyBczpbEOCWf9p 29UrDF1+5F3+JkUPVvzN6ND+EJJqkD7j3ofWXi4mvOhSnWo5P0WpV/F2ZEZzwqfSzq f56vIx6XwM/3Vlx7jr5zxR/X4dlOLWOn3PRV4fw0TvLo7oQIl3CQXh9q/iCkSjmdxu PQ33zDbwLlydscyZyazbabyi/WPzeXKVlc+DFPJzgqWEDsu3u+tsaOS+A9DXdVnEtw NjitIqOyoCbUlWTXn8cT98IUNyQqB044xHGsqL3xeUA2b0Kb78K/Cxr5tk5/RVaopc DqDC299/zIHuw== Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 876DF60498 for ; Mon, 20 Jun 2022 13:55:34 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.b="bCYlWtCh"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1655726133; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=MX7dKoczXP2emmVnHyN75QkZbiirMKKNuz4mDMjFj7E=; b=bCYlWtChkDEPThQqT0+NDfk+e6ePuUiDpeYbIY4CJ7mW39Tkv3o3UeehKmK6xcOYq5xthM Hp537gTB9vpxsTiKgncrX4bm8Et++g04Ggd7R1LfThryDb3T69gTTsHXtS0n0/QUvIdGD1 S7xD4UJoml8Wn65XKM0VEFzO3LPRqgs= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-628-P4UJTk5pPA--tfYahWYWyw-1; Mon, 20 Jun 2022 07:55:32 -0400 X-MC-Unique: P4UJTk5pPA--tfYahWYWyw-1 Received: by mail-wm1-f71.google.com with SMTP id l3-20020a05600c1d0300b0039c7efa2526so4942305wms.3 for ; Mon, 20 Jun 2022 04:55:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=MX7dKoczXP2emmVnHyN75QkZbiirMKKNuz4mDMjFj7E=; b=Mum4Nw2hNrGJ7HjNiL4lQaM2MobZDnwlbK619hoWBHOsO0dBnfvur3ir4C9LL93sYi UApGOwIZadVU9i3vp/exTpsg8iNn2/CVq+EWd7sb3x5UtgmmvTBGSMRyKl5l7IzXH8pU nVZfCRVpxqK/AcD7cRpb4Cez+OIg6AjQUCoJDClFcICul8TwFL6VBvZhud0qnXrXoq3x FxvZ7M3yDhVqLYzfG3PHnZ/ZqiuVZiXOJSi+LYezow/5xGoJgumeWl/6zQEgHhUvN0DO IcXFiVe/2AfhhOAh3CnRBdtNwpWuSvd5lFE9HfBXNTshH8lRfguzHQ2GEoJJ12FAz8aN nEOw== X-Gm-Message-State: AJIora+EZdxB5nYPSO+00fhWxMkExsAsMgjRa+yLYwvpOVfZePqEW7TE kmOXF7bDJG7FbV7bY/KlloStfQJTTJspOyh3SovU115bMfMsHjF67vBJMmW0mVpK7IjCkUyh5lO woTbysXxtD8WCZmi7K7W4yq4Xz6ShIsIgAjfL8QPtlPfavDJ0NwyGKnFHkLhIiaDmyx/EPYoEln 3Xf7ISK6Bi X-Received: by 2002:adf:e9cd:0:b0:21b:94a2:572f with SMTP id l13-20020adfe9cd000000b0021b94a2572fmr396707wrn.647.1655726130849; Mon, 20 Jun 2022 04:55:30 -0700 (PDT) X-Google-Smtp-Source: AGRyM1uIHsufV3Ok8PAa2FtuyH1jx9Q6lZlkA/H97g9w1WhycM14R287zJMNpSZtsEWjRZIYDWZMZg== X-Received: by 2002:adf:e9cd:0:b0:21b:94a2:572f with SMTP id l13-20020adfe9cd000000b0021b94a2572fmr396674wrn.647.1655726130485; Mon, 20 Jun 2022 04:55:30 -0700 (PDT) Received: from p1.Home ([2001:8a0:6724:4500:a69c:e66f:828e:b340]) by smtp.gmail.com with ESMTPSA id y14-20020a1c4b0e000000b0039c95b31812sm14627485wma.31.2022.06.20.04.55.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 Jun 2022 04:55:29 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Mon, 20 Jun 2022 12:52:39 +0100 Message-Id: <20220620115238.16138-1-ecurtin@redhat.com> X-Mailer: git-send-email 2.35.3 MIME-Version: 1.0 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=ecurtin@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Subject: [libcamera-devel] [PATCH v5] cam: kms_sink: Remove limitation that camera and display must match X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Eric Curtin via libcamera-devel From: Eric Curtin Reply-To: Eric Curtin Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" There is a limitation that requires input and output to be pixel for pixel identical in terms of height and width. Remove this limitation to enable more hardware that doesn't match. Just start drawing from top left 0, 0 corner. Try and pick the mode closest to the stream size. Suggested-by: Laurent Pinchart Signed-off-by: Eric Curtin Signed-off-by: Laurent Pinchart Tested-by: Eric Curtin Tested-by: Eric Curtin --- Changes in v5: - Tested Laurents suggested change successfully - Added to commit message about trying to pick closest Changes in v4: - Change commit message to say top left - Spaces to tabs Changes in v3: - Much simplified version of the patch where we just attempt to draw from point 0, 0. Only in the case where we do not find a matching mode. Can expand to do centralization, scaling, etc. in further patches if needs be. Changes in v2: - Tested and support drawing from negative pixel range kernel parameter (video=960x540@60) was useful here --- src/cam/kms_sink.cpp | 45 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 36 insertions(+), 9 deletions(-) diff --git a/src/cam/kms_sink.cpp b/src/cam/kms_sink.cpp index 7add81a6..7904bca8 100644 --- a/src/cam/kms_sink.cpp +++ b/src/cam/kms_sink.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -112,6 +113,7 @@ int KMSSink::configure(const libcamera::CameraConfiguration &config) const libcamera::StreamConfiguration &cfg = config.at(0); + /* Find the best mode for the stream size. */ const std::vector &modes = connector_->modes(); const auto iter = std::find_if(modes.begin(), modes.end(), [&](const DRM::Mode &mode) { @@ -120,6 +122,32 @@ int KMSSink::configure(const libcamera::CameraConfiguration &config) }); if (iter == modes.end()) { std::cerr << "No mode matching " << cfg.size << std::endl; + + unsigned int cfgArea = cfg.size.width * cfg.size.height; + unsigned int bestDistance = UINT_MAX; + + for (const DRM::Mode &mode : modes) { + unsigned int modeArea = mode.hdisplay * mode.vdisplay; + unsigned int distance = modeArea > cfgArea + ? modeArea - cfgArea + : cfgArea - modeArea; + + if (distance < bestDistance) { + mode_ = &mode; + bestDistance = distance; + + /* + * If the sizes match exactly, there will be no better + * match. + */ + if (distance == 0) + break; + } + } + } + + if (!mode_) { + std::cerr << "No modes\n"; return -EINVAL; } @@ -127,7 +155,6 @@ int KMSSink::configure(const libcamera::CameraConfiguration &config) if (ret < 0) return ret; - mode_ = &*iter; size_ = cfg.size; stride_ = cfg.stride; @@ -199,10 +226,10 @@ int KMSSink::configurePipeline(const libcamera::PixelFormat &format) return ret; } - std::cout - << "Using KMS plane " << plane_->id() << ", CRTC " << crtc_->id() - << ", connector " << connector_->name() - << " (" << connector_->id() << ")" << std::endl; + std::cout << "Using KMS plane " << plane_->id() << ", CRTC " + << crtc_->id() << ", connector " << connector_->name() << " (" + << connector_->id() << "), mode " << mode_->hdisplay << "x" + << mode_->vdisplay << "@" << mode_->vrefresh << std::endl; return 0; } @@ -295,12 +322,12 @@ bool KMSSink::processRequest(libcamera::Request *camRequest) drmRequest->addProperty(plane_, "CRTC_ID", crtc_->id()); drmRequest->addProperty(plane_, "SRC_X", 0 << 16); drmRequest->addProperty(plane_, "SRC_Y", 0 << 16); - drmRequest->addProperty(plane_, "SRC_W", mode_->hdisplay << 16); - drmRequest->addProperty(plane_, "SRC_H", mode_->vdisplay << 16); + drmRequest->addProperty(plane_, "SRC_W", size_.width << 16); + drmRequest->addProperty(plane_, "SRC_H", size_.height << 16); drmRequest->addProperty(plane_, "CRTC_X", 0); drmRequest->addProperty(plane_, "CRTC_Y", 0); - drmRequest->addProperty(plane_, "CRTC_W", mode_->hdisplay); - drmRequest->addProperty(plane_, "CRTC_H", mode_->vdisplay); + drmRequest->addProperty(plane_, "CRTC_W", size_.width); + drmRequest->addProperty(plane_, "CRTC_H", size_.height); flags |= DRM::AtomicRequest::FlagAllowModeset; }