From patchwork Tue Aug 9 20:50:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17053 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 E02C9BE173 for ; Tue, 9 Aug 2022 20:51:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7E5D563328; Tue, 9 Aug 2022 22:51:00 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660078260; bh=u4MTFmMccitsy66efRjXwl3R+v/Nznti/BpmNgO8DPg=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=mYZ4G8k4P53TFYUS2AdhoUxaxfdoOo/t2knclnpZbOmNL9xq/Cv3STByuec7tZW3M T3VwM3uJkMLJTuKy/ktJhd1+TJwPVNrq9a0+DIgpS/J9wUlCNpUNdoo9uJqaYbCLJQ jcHSmvr4c5FaDRdw+cJhReostZUa1M57qOP+3Hws3ZKmLvDJWsXHM9oU0out3ONrMm WtJ6Zx5yKF8/pK01kXGuvVVTvRnwgrhRR1xHm4CeWIH8dAddtBrrDI/xIbnfrteoAE x2d8x++B7hTrCJcUdZ33vkIGugznNPizKRbkW6CciXZPA470co4pRY/LVynrQRRcnd exx0QABnOQI6A== Received: from mail-pg1-x530.google.com (mail-pg1-x530.google.com [IPv6:2607:f8b0:4864:20::530]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 144F263326 for ; Tue, 9 Aug 2022 22:50:58 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="PC+88RYD"; dkim-atps=neutral Received: by mail-pg1-x530.google.com with SMTP id r69so5913816pgr.2 for ; Tue, 09 Aug 2022 13:50:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=dfYq8LWQIvsQ5s6c7P+CGWO6qRw4gGkJtVXHJcDVppQ=; b=PC+88RYDCWlkbuI1ZGci2B0lo7jyuSUAonLhW6HKobKX/cw2I2r1OVLbl6B/z4C/Mw 3GicsE2Sd+TzafA+a30JmG+pnq1dkcz8oHh8aYlGLrENF4gWX4cPkUyPx8SF63+kzYG2 n2AW6Z/bV0nU+74vAvpASqCQ2zSu41dYj5S1tJYqHrrww4jzRun5I39Llr/3J1RU5s+E TOt78e7NYujdVWlAp01cSwW9zSu6EKzdIfnUpGqiMLAKnXDdRZJkcxaaQ0xbfAaIsoL8 K9RxEJ5oXH4tLPXzqN4WFcO35aQTJaYfezK9azrhlbqRgajzFA+w7apPEQA1VFFH2GP4 Ayag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=dfYq8LWQIvsQ5s6c7P+CGWO6qRw4gGkJtVXHJcDVppQ=; b=4mhOQ8A8azZFDhjBkyNiHBiwevuIO31JQTYwcT2BoKmM6OroNv8GWhKYLM7iq+ofdt Hs0Y/CnRSEioYeDeKCn95lWdTvrWvmYEyJRbvfjzp3xFbg+5wP49+ugXoZLhUFuSSKG8 u0v+0Ntbe2rFPPLSK9Ala89YsEaG7WWOomHsSAzSJgxyW6uyZ61BHJzsCdEgI9iyuCub W+zYTW+I1ptZk1sBAnNykP3ZCkM4hX29DHFGbndqzjD98fpXRU9b6CQwFXp3v8w76pia IHk2qUr9LZmDHy4gKYmRf7sqpcenPfmckZcJ2WSOho7vKQQawOLF/SeBnnWyQ3zRDIdE Slkg== X-Gm-Message-State: ACgBeo3eYTwcUTFW8Y0+JnXaaT7/2RxxAICMG+drwQ+c1BmExc4iYAu/ Rfwghg3GAtjCItTnIm0r+iZPEHzPuUs= X-Google-Smtp-Source: AA6agR4U7mHh6tlaqB5K8XMCugqer/529ygfmo5MYIe7JdXDxygoyrSETYFgpZJlWOa8bk8zh0axLQ== X-Received: by 2002:a65:6398:0:b0:415:7d00:c1de with SMTP id h24-20020a656398000000b004157d00c1demr20996195pgv.610.1660078256368; Tue, 09 Aug 2022 13:50:56 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2358:3bcd:fb4f:cbb7]) by smtp.gmail.com with ESMTPSA id d3-20020a623603000000b0052d981e7842sm301936pfa.208.2022.08.09.13.50.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:50:55 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 02:20:35 +0530 Message-Id: <20220809205042.344923-2-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809205042.344923-1-utkarsh02t@gmail.com> References: <20220809205042.344923-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 1/8] qcam: Use QDialog for selection of cameras at startup 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: Utkarsh Tiwari via libcamera-devel From: Utkarsh Tiwari Reply-To: Utkarsh Tiwari Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Currently we use QInputDialog convenience dialogs to allow the user to select a camera. This doesn't allow adding of more information (such as camera location, model etc). Create a QDialog with a QFormLayout that shows a QComboBox with camera Ids. Use a QDialogButtonBox to provide buttons for accepting and cancelling the action. Signed-off-by: Utkarsh Tiwari Reviewed-by: Kieran Bingham Reviewed-by: Kieran Bingham --- Difference 1. Renamed dialogButtonBox to buttonBox 2. Removed spaces 3. Renamed to just layout 4. No longer use the QPointer 5. The dialog is always constructed now src/qcam/cam_select_dialog.cpp | 51 ++++++++++++++++++++++++++++++++++ src/qcam/cam_select_dialog.h | 37 ++++++++++++++++++++++++ src/qcam/main_window.cpp | 39 +++++++++----------------- src/qcam/main_window.h | 4 +++ src/qcam/meson.build | 2 ++ 5 files changed, 107 insertions(+), 26 deletions(-) create mode 100644 src/qcam/cam_select_dialog.cpp create mode 100644 src/qcam/cam_select_dialog.h diff --git a/src/qcam/cam_select_dialog.cpp b/src/qcam/cam_select_dialog.cpp new file mode 100644 index 00000000..dceaa590 --- /dev/null +++ b/src/qcam/cam_select_dialog.cpp @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2022, Utkarsh Tiwari + * + * cam_select_dialog.cpp - qcam - Camera Selection dialog + */ + +#include "cam_select_dialog.h" + +#include + +#include +#include + +#include +#include +#include +#include +#include + +CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManager, + QWidget *parent) + : QDialog(parent), cm_(cameraManager) +{ + /* Use a QFormLayout for the dialog. */ + QFormLayout *layout = new QFormLayout(this); + + /* Setup the camera id combo-box. */ + cameraIdComboBox_ = new QComboBox; + for (const auto &cam : cm_->cameras()) + cameraIdComboBox_->addItem(QString::fromStdString(cam->id())); + + /* Setup the QDialogButton Box */ + QDialogButtonBox *buttonBox = + new QDialogButtonBox(QDialogButtonBox::Ok | + QDialogButtonBox::Cancel); + + connect(buttonBox, &QDialogButtonBox::accepted, + this, &QDialog::accept); + connect(buttonBox, &QDialogButtonBox::rejected, + this, &QDialog::reject); + + /* Set the layout. */ + layout->addRow("Camera:", cameraIdComboBox_); + layout->addWidget(buttonBox); +} + +std::string CameraSelectorDialog::getCameraId() +{ + return cameraIdComboBox_->currentText().toStdString(); +} diff --git a/src/qcam/cam_select_dialog.h b/src/qcam/cam_select_dialog.h new file mode 100644 index 00000000..8e54f916 --- /dev/null +++ b/src/qcam/cam_select_dialog.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2022, Utkarsh Tiwari + * + * cam_select_dialog.h - qcam - Camera Selection dialog + */ + +#pragma once + +#include + +#include +#include + +#include +#include +#include +#include +#include + +class CameraSelectorDialog : public QDialog +{ + Q_OBJECT +public: + CameraSelectorDialog(libcamera::CameraManager *cameraManager, + QWidget *parent); + + ~CameraSelectorDialog() = default; + + std::string getCameraId(); + +private: + libcamera::CameraManager *cm_; + + /* UI elements. */ + QComboBox *cameraIdComboBox_; +}; diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 7433d647..48479f35 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -30,6 +29,7 @@ #include "../cam/image.h" +#include "cam_select_dialog.h" #include "dng_writer.h" #ifndef QT_NO_OPENGL #include "viewfinder_gl.h" @@ -290,38 +290,25 @@ void MainWindow::switchCamera(int index) std::string MainWindow::chooseCamera() { - QStringList cameras; - bool result; - - /* If only one camera is available, use it automatically. */ - if (cm_->cameras().size() == 1) - return cm_->cameras()[0]->id(); - - /* Present a dialog box to pick a camera. */ - for (const std::shared_ptr &cam : cm_->cameras()) - cameras.append(QString::fromStdString(cam->id())); - - QString id = QInputDialog::getItem(this, "Select Camera", - "Camera:", cameras, 0, - false, &result); - if (!result) - return std::string(); - - return id.toStdString(); -} - -int MainWindow::openCamera() -{ - std::string cameraName; + /* Construct the selection dialog, unconditionally. */ + cameraSelectorDialog_ = new CameraSelectorDialog(cm_, this); /* * Use the camera specified on the command line, if any, or display the * camera selection dialog box otherwise. */ if (options_.isSet(OptCamera)) - cameraName = static_cast(options_[OptCamera]); + return static_cast(options_[OptCamera]); + + if (cameraSelectorDialog_->exec() == QDialog::Accepted) + return cameraSelectorDialog_->getCameraId(); else - cameraName = chooseCamera(); + return std::string(); +} + +int MainWindow::openCamera() +{ + std::string cameraName = chooseCamera(); if (cameraName == "") return -EINVAL; diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index fc70920f..b01d2e59 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -23,11 +23,13 @@ #include #include #include +#include #include #include #include "../cam/stream_options.h" +#include "cam_select_dialog.h" #include "viewfinder.h" class QAction; @@ -99,6 +101,8 @@ private: QString title_; QTimer titleTimer_; + CameraSelectorDialog *cameraSelectorDialog_; + /* Options */ const OptionsParser::Options &options_; diff --git a/src/qcam/meson.build b/src/qcam/meson.build index c46f4631..61861ea6 100644 --- a/src/qcam/meson.build +++ b/src/qcam/meson.build @@ -18,6 +18,7 @@ qcam_sources = files([ '../cam/image.cpp', '../cam/options.cpp', '../cam/stream_options.cpp', + 'cam_select_dialog.cpp', 'format_converter.cpp', 'main.cpp', 'main_window.cpp', @@ -26,6 +27,7 @@ qcam_sources = files([ ]) qcam_moc_headers = files([ + 'cam_select_dialog.h', 'main_window.h', 'viewfinder_qt.h', ]) From patchwork Tue Aug 9 20:50:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17054 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 5B66ABE173 for ; Tue, 9 Aug 2022 20:51:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 165DE6332E; Tue, 9 Aug 2022 22:51:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660078262; bh=Jr3N5xZ/pt0OpbqVWsjfe9vtI7OL/MbZ6n1JpILI72Y=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=HMWNBGRQgbYzgT4hJtxTafZBB8+uRY4/8R0jEg440WMbODKRcjhT92ynq8x+wu0i6 wp4aMeHfSE4jcfqHn9irL/Oqi+qoqecZBgSXhIyr+LsFLxvopuuG3qx616jS6RVnV2 z+iGwf5zXNw8PnWRm3Cf2Tg0I1U1u3NhAANDpAMb92Z9gjtTVldjJWNKTHaxtWCxij o2/tGS1ifgLWQO3J9r/X4eYCY4cW1JffANL3/RDRMiAbgwwP7kLuvJxYf91qj8Yrpw 9E2XC0Dufy/S7UN5c1RjjfQO7apRYSniWAmCQQrca7vGDO5K1fYaBNt9C2xguZOS+m 9PErkHWJkeJeA== Received: from mail-pf1-x42f.google.com (mail-pf1-x42f.google.com [IPv6:2607:f8b0:4864:20::42f]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F333C63328 for ; Tue, 9 Aug 2022 22:50:59 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="pFRj4lnM"; dkim-atps=neutral Received: by mail-pf1-x42f.google.com with SMTP id 130so11817411pfv.13 for ; Tue, 09 Aug 2022 13:50:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=MXl7enM09lK80T/81FGaBB7h+PlTHLqNA78faA96bmc=; b=pFRj4lnMq+W/Qzq8mmRjGgR+QZwfQ1rVG4RBX9PfiwUAilRXEZ0qzqCl6bIrbJSmj/ eik7NkKROpD+bmAE3PaX3YhAocmvjEtmRTqfO9mIpOfHeOII8efUhCdMOfsj5XuFMb9n NODhRHl1cLMyQDSURpFGM7aiQjUEbwHuhdSmY9N2/6NgFpp8S20MP2SCxLsHgnjqmDyN gY9+SoM3sUcUDonIvxXTRyWVOGnENEjktqH/OxeZttJO2T6PQWLsQkWhtAv9k0JVSKI9 a5CVYyG1/hanfeO8icHdZXi7O3j7pE/nOf3HB1V1+HFdDE6ZHUn1azz9ttxwuvaDupmR bUnw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=MXl7enM09lK80T/81FGaBB7h+PlTHLqNA78faA96bmc=; b=To7DQEzPSkTRepsYD/+fBAhfczh7bSHxJ/TCF6JJBcrJeVt8v2I2Mz6tOW0s/X2fFR 06drEAlPN/KVGe28Gu9+fmweTZV3xwhkrYFCrZ+GxGtg1cqionUo3RdZ8J11O0PwQL67 U3BE/AHg87hxiBBosx1JifULAqCck5KthoCL6gJOjrgATKQBM4Aas20tR6+s2KuPnbqv PbdgyC6GXRMvGzUeeJbrZ2m3m7B1pzhOVBGv07xo6z3ze6d3WOsUFBtL64zj9yIA0BuM 49K569bK8L8MpbJvnrfc3b/VhhAHzMfr/nKWRMMj8UTgwWOda6moEXpWtRar0AWGQd06 QQFQ== X-Gm-Message-State: ACgBeo1iM0bm0+SJSBc/ndRzi2XQkB1Io7czg9t08qPRgpCXGfU6Kh9s Lxe5cTIe4MA18g87oUF28tH9DBsJIJU= X-Google-Smtp-Source: AA6agR75QJoIaSc7v4srUDdaiDfJmmdzzy/4dYspseaIV/LRpKuTke2jDh/VaKKyXRzJFfYtteIWlg== X-Received: by 2002:aa7:8c51:0:b0:528:2ed8:7e35 with SMTP id e17-20020aa78c51000000b005282ed87e35mr24012073pfd.13.1660078258364; Tue, 09 Aug 2022 13:50:58 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2358:3bcd:fb4f:cbb7]) by smtp.gmail.com with ESMTPSA id d3-20020a623603000000b0052d981e7842sm301936pfa.208.2022.08.09.13.50.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:50:58 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 02:20:36 +0530 Message-Id: <20220809205042.344923-3-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809205042.344923-1-utkarsh02t@gmail.com> References: <20220809205042.344923-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 2/8] qcam: Support Hotplug for Camera Selection Dialog 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: Utkarsh Tiwari via libcamera-devel From: Utkarsh Tiwari Reply-To: Utkarsh Tiwari Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Currently if there is HotPlug event when the user is on the Camera selection dialog, the QComboBox didn't update to reflect the change. If the QDialog exists then alert it for the Hotplug event. The check for QDialog existance is done by QPointer. Signed-off-by: Utkarsh Tiwari Reviewed-by: Kieran Bingham --- Difference: 1. Moved functions implementation to its own .cpp src/qcam/cam_select_dialog.cpp | 14 ++++++++++++++ src/qcam/cam_select_dialog.h | 4 ++++ src/qcam/main_window.cpp | 4 ++++ 3 files changed, 22 insertions(+) diff --git a/src/qcam/cam_select_dialog.cpp b/src/qcam/cam_select_dialog.cpp index dceaa590..d8982800 100644 --- a/src/qcam/cam_select_dialog.cpp +++ b/src/qcam/cam_select_dialog.cpp @@ -49,3 +49,17 @@ std::string CameraSelectorDialog::getCameraId() { return cameraIdComboBox_->currentText().toStdString(); } + +/* Hotplug / Unplug Support. */ +void CameraSelectorDialog::cameraAdded(libcamera::Camera *camera) +{ + cameraIdComboBox_->addItem(QString::fromStdString(camera->id())); +} + +void CameraSelectorDialog::cameraRemoved(libcamera::Camera *camera) +{ + int cameraIndex = cameraIdComboBox_->findText( + QString::fromStdString(camera->id())); + + cameraIdComboBox_->removeItem(cameraIndex); +} diff --git a/src/qcam/cam_select_dialog.h b/src/qcam/cam_select_dialog.h index 8e54f916..567083ae 100644 --- a/src/qcam/cam_select_dialog.h +++ b/src/qcam/cam_select_dialog.h @@ -29,6 +29,10 @@ public: std::string getCameraId(); + /* Hotplug / Unplug Support. */ + void cameraAdded(libcamera::Camera *camera); + + void cameraRemoved(libcamera::Camera *camera); private: libcamera::CameraManager *cm_; diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 48479f35..377b4650 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -593,6 +593,8 @@ void MainWindow::processHotplug(HotplugEvent *e) if (event == HotplugEvent::HotPlug) { cameraCombo_->addItem(QString::fromStdString(camera->id())); + + cameraSelectorDialog_->cameraAdded(camera); } else if (event == HotplugEvent::HotUnplug) { /* Check if the currently-streaming camera is removed. */ if (camera == camera_.get()) { @@ -604,6 +606,8 @@ void MainWindow::processHotplug(HotplugEvent *e) int camIndex = cameraCombo_->findText(QString::fromStdString(camera->id())); cameraCombo_->removeItem(camIndex); + + cameraSelectorDialog_->cameraRemoved(camera); } } From patchwork Tue Aug 9 20:50:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17055 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 D1BDCBE173 for ; Tue, 9 Aug 2022 20:51:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 91AC363335; Tue, 9 Aug 2022 22:51:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660078263; bh=O0zffZEsQGLvkgsJV0VrElWOOtCbYO+RXg5NRXzZw4g=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=y8WMx6vPXeefvBkoj3uY4ZH3N7dI3tiEHtU/z7qK2u3mhmsWB3bUoF3FFHMV/n1yS AKZOyzjvs+AMjuuIimx31sFom6FaKs438bLyypbVVJ7eLrvaLw1EYXYVa0G8gh+g1b 5AjjNtYUtHe1I/KX+6aAkuypJiwxpnhmjUQ9Ker77dRIs229bEiKUA8WiW/gxAuMx3 69uo6Qw+wGkBVgkQIF7QI2i5rMZ0Zt76cMkOmN8gSIEpu4BuBvuSooAaW/SWEPmL9O 1BkhRu+3pomP181E7lElM7LuDYl9Z7T8DDZmsO2x4ZWmRpFaYc6hi2Kb/HXJFG/oqc XCMYFPGF4NdfQ== Received: from mail-pj1-x102d.google.com (mail-pj1-x102d.google.com [IPv6:2607:f8b0:4864:20::102d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 7C66763330 for ; Tue, 9 Aug 2022 22:51:02 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ltuJG+do"; dkim-atps=neutral Received: by mail-pj1-x102d.google.com with SMTP id o5-20020a17090a3d4500b001ef76490983so117591pjf.2 for ; Tue, 09 Aug 2022 13:51:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=y/7tBegz/tztP0/ebOqZEEH7T7DW+fI884vXr5casuw=; b=ltuJG+dorHyXkzg2hwnUB4FBJinA7GBfk5JwiJEFnm1WFcIcS5oNW6LGZREDvNS9cj ur1DWvBR6knqGXiGuhMhwfy5xGciLOXsVTslWlHhdEVncsoO8jGwyJ5WGzHGygmrTGON cA4J74bO4VoEsxjgV0ZjXmpZOUZViGI+ZWSnsbov23qNcUAaZ8+LQgyybi4sz8DALkEa gnDEJG1/4fsVffwmGgmhaApxYHhjLYPc24zbRNaZp4wJomKX0V9Lbb26TreKlcdnzNC1 UmcdJsp1nK2tC8y0YqJyHthaQQu7cShbSut72dVmH6qaOLXykT9xNXgxrQWnS5rpRqi6 4Lkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=y/7tBegz/tztP0/ebOqZEEH7T7DW+fI884vXr5casuw=; b=0mfOY6WytnyMuzC7cq+SwA7LzrYmwl9vo6Dk9tsAxTik5r1urnCD2LWYm6VHIypmxo 0C/7y5fG1lt94FSs8NBXKsmADZ2lowwZPIckGvZfKvzPM9y8FuYdHSBPZfaZvoiuapQG Zw8LGVdC1/u3JwVbfAyAJJIEeGvvR0dRnGFO0iIsSPGGdxDjyDFoPI2kRwKfnh4KFwch 2ZKW+UiuEAbgjoGJ1L530kv073BzrTvApNdqn1qRZhHS6Geas8tCFWGVJEzvQqRhM+S6 bK10x+6zHZFRi8KhjG3qwYzXSqaQURTuutT66Pq5MnmJfBR2t5o1hrLWOii+t8tIJLbl gAhQ== X-Gm-Message-State: ACgBeo3OiTuWH8jaDtj2Exabhpcpu7/8lQZpiP0qQGZ2JTiKudshChSq hMUdbyxFs6gsN2oKoNve5UdZdl11rGU= X-Google-Smtp-Source: AA6agR5YgmSRh8l2DuIxZvsrkU2XPvrOQvPIclJocUeKZsdFTOvSAYN0h90iq6yVUfmS/UfCyuVsPw== X-Received: by 2002:a17:902:ea03:b0:16f:2506:bfd5 with SMTP id s3-20020a170902ea0300b0016f2506bfd5mr24597020plg.21.1660078260726; Tue, 09 Aug 2022 13:51:00 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2358:3bcd:fb4f:cbb7]) by smtp.gmail.com with ESMTPSA id d3-20020a623603000000b0052d981e7842sm301936pfa.208.2022.08.09.13.50.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:51:00 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 02:20:37 +0530 Message-Id: <20220809205042.344923-4-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809205042.344923-1-utkarsh02t@gmail.com> References: <20220809205042.344923-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 3/8] qcam: MainWindow: Replace cameraCombo_ with CameraSelectorDialog 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: Utkarsh Tiwari via libcamera-devel From: Utkarsh Tiwari Reply-To: Utkarsh Tiwari Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Replace the cameraCombo_ on the toolbar with a QPushButton which displays the CameraSelectorDialog. This would allow the user to view information about the camera when switching. The QPushButton text is set to the camera Id currently in use. Signed-off-by: Utkarsh Tiwari Reviewed-by: Kieran Bingham --- Difference: 1. cameraSwitchButton_ to cameraSelectButton_ src/qcam/main_window.cpp | 44 +++++++++++++++++++--------------------- src/qcam/main_window.h | 5 +++-- 2 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 377b4650..15b150ec 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -193,14 +193,11 @@ int MainWindow::createToolbars() connect(action, &QAction::triggered, this, &MainWindow::quit); /* Camera selector. */ - cameraCombo_ = new QComboBox(); - connect(cameraCombo_, QOverload::of(&QComboBox::activated), + cameraSelectButton_ = new QPushButton; + connect(cameraSelectButton_, &QPushButton::clicked, this, &MainWindow::switchCamera); - for (const std::shared_ptr &cam : cm_->cameras()) - cameraCombo_->addItem(QString::fromStdString(cam->id())); - - toolbar_->addWidget(cameraCombo_); + toolbar_->addWidget(cameraSelectButton_); toolbar_->addSeparator(); @@ -260,14 +257,18 @@ void MainWindow::updateTitle() * Camera Selection */ -void MainWindow::switchCamera(int index) +void MainWindow::switchCamera() { /* Get and acquire the new camera. */ - const auto &cameras = cm_->cameras(); - if (static_cast(index) >= cameras.size()) + std::string newCameraId = chooseCamera(); + + if (newCameraId.empty()) + return; + + if (camera_ && newCameraId == camera_->id()) return; - const std::shared_ptr &cam = cameras[index]; + const std::shared_ptr &cam = cm_->get(newCameraId); if (cam->acquire()) { qInfo() << "Failed to acquire camera" << cam->id().c_str(); @@ -300,9 +301,12 @@ std::string MainWindow::chooseCamera() if (options_.isSet(OptCamera)) return static_cast(options_[OptCamera]); - if (cameraSelectorDialog_->exec() == QDialog::Accepted) - return cameraSelectorDialog_->getCameraId(); - else + if (cameraSelectorDialog_->exec() == QDialog::Accepted) { + std::string cameraId = cameraSelectorDialog_->getCameraId(); + cameraSelectButton_->setText(QString::fromStdString(cameraId)); + + return cameraId; + } else return std::string(); } @@ -326,8 +330,8 @@ int MainWindow::openCamera() return -EBUSY; } - /* Set the combo-box entry with the currently selected Camera. */ - cameraCombo_->setCurrentText(QString::fromStdString(cameraName)); + /* Set the camera switch button with the currently selected Camera id. */ + cameraSelectButton_->setText(QString::fromStdString(cameraName)); return 0; } @@ -591,22 +595,16 @@ void MainWindow::processHotplug(HotplugEvent *e) Camera *camera = e->camera(); HotplugEvent::PlugEvent event = e->hotplugEvent(); - if (event == HotplugEvent::HotPlug) { - cameraCombo_->addItem(QString::fromStdString(camera->id())); - + if (event == HotplugEvent::HotPlug) cameraSelectorDialog_->cameraAdded(camera); - } else if (event == HotplugEvent::HotUnplug) { + else if (event == HotplugEvent::HotUnplug) { /* Check if the currently-streaming camera is removed. */ if (camera == camera_.get()) { toggleCapture(false); camera_->release(); camera_.reset(); - cameraCombo_->setCurrentIndex(0); } - int camIndex = cameraCombo_->findText(QString::fromStdString(camera->id())); - cameraCombo_->removeItem(camIndex); - cameraSelectorDialog_->cameraRemoved(camera); } } diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index b01d2e59..bbdbb21c 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -61,7 +62,7 @@ private Q_SLOTS: void quit(); void updateTitle(); - void switchCamera(int index); + void switchCamera(); void toggleCapture(bool start); void saveImageAs(); @@ -91,7 +92,7 @@ private: /* UI elements */ QToolBar *toolbar_; QAction *startStopAction_; - QComboBox *cameraCombo_; + QPushButton *cameraSelectButton_; QAction *saveRaw_; ViewFinder *viewfinder_; From patchwork Tue Aug 9 20:50:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17056 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 46CFBBE173 for ; Tue, 9 Aug 2022 20:51:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0530863330; Tue, 9 Aug 2022 22:51:06 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660078266; bh=Bfo3MNw2X87wUqYkn7yZ5Z7KL5aO6MgRuLdiAKhIk+c=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=robKugGc1Ars3j0jGtZBIBS1S6r2ggETt6eyUtFT+6abxOLqfUziklB6KJuzJuVjZ MyMQrrmMk+AdIhsDNob7cxvxnCx4KDbXzMlVSGrwab2GnbmjhDTvt1/cgRQcnw7inX 0OgZ0NnNnpL59m87kmBES17EdzU9a44C1DihAqxWBToEIQD/Lx7ORzhhbjsNsY0BrX TxG+2QVppqPLGmAQC4h3k1XnhcngwYQbyLaWce5/KltzJ2e80ASuxL1aQwltH1De7c N2MTSg6X+6UFovVRlfe8Mx7SXUhNStSmugwe+E1GJpbBsA7gvY6kqP6ZI9aor4Cyt2 vs0XcKApWeeZQ== Received: from mail-pj1-x1030.google.com (mail-pj1-x1030.google.com [IPv6:2607:f8b0:4864:20::1030]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id F3E2E6332F for ; Tue, 9 Aug 2022 22:51:04 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Nxt562N+"; dkim-atps=neutral Received: by mail-pj1-x1030.google.com with SMTP id pm17so12830956pjb.3 for ; Tue, 09 Aug 2022 13:51:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=8FNAgahM9w38jWDF6h/O2SKek+RtA3Cc8HkrQLIP6LM=; b=Nxt562N+VZh51IxuMOndZRLBo1a+qm7B/5ERFEvZ/2bD9EE3+H7Xv/DhmjnKCtdtnt upD9zeFZ0Oel+G5yIj2kvfaZIfUAQDPxf6LrlVyUZsDeAyI/O2iiUm0J50Kh2EYxUL3l hK/X1DKVjV3kW0d3CgMUgNpOE993Q7XOmffKZ/G9CO5Jk8YCXahUyGOJWMcpmB2ur3SS 5EyjVraWjYkuhst0CUkSCS4nzSFHJ2wRGF7P24XCwyrpO5VRa6K8VuNIBL+Oel1Nefo+ 0n7JdgYl82eko2nNGgJwRtT2anpvNUz2bTMZr1/xkLDCsNynYmcwhI2Q2LQPUri5NNnk X7DA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=8FNAgahM9w38jWDF6h/O2SKek+RtA3Cc8HkrQLIP6LM=; b=jUB1rgKnCivP4zNgZIBHB28wIUuq3UXizgh7ifgIl9AQwFmjLZaZV0bC6YV/Vyjw6k k7ovY0DPVmR92mwSV2dUHXLdGNDh6MgTTmq21SIaq+JsfW6zKFM5MrINW1ebjY4vrlWN 5L0S9xAJmXS1DLk5gp5aGK0glR7jkvHfWIhIT58SfxUxLFwOTZBc0GmL9/OCpfIhqHrV +iJbNfM4BGKuMWduBqe1VU7uguMbdT67bnzYd0tesE0ZKVGj4HFlX32PlF2elDzhdRp6 c3Uvyl2z4pzPVbZ5CtjF4cm1VjelAIRQ0fFmI+3M9trxEQNiGvFmMOCWworG8B5DUGav pUNw== X-Gm-Message-State: ACgBeo34Kq3QeZU/W/cZmauhP7FawD7vrMMasaFQ/sM861Wo/QGFSdAo SR1Yl/RuLtrMclVLXkDEapHDlogLXs8= X-Google-Smtp-Source: AA6agR5+N9dgNTrq5lWo5ZGMZ9RLZ35MicT9B+aCi3IeGrGinUlbEj9Sv9kqayYEfJMkPLoiz0Mlgw== X-Received: by 2002:a17:90b:1b08:b0:1f5:b65:9654 with SMTP id nu8-20020a17090b1b0800b001f50b659654mr292169pjb.77.1660078263357; Tue, 09 Aug 2022 13:51:03 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2358:3bcd:fb4f:cbb7]) by smtp.gmail.com with ESMTPSA id d3-20020a623603000000b0052d981e7842sm301936pfa.208.2022.08.09.13.51.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:51:03 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 02:20:38 +0530 Message-Id: <20220809205042.344923-5-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809205042.344923-1-utkarsh02t@gmail.com> References: <20220809205042.344923-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 4/8] qcam: CamSelectDialog: Display Location and Model propety of camera 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: Utkarsh Tiwari via libcamera-devel From: Utkarsh Tiwari Reply-To: Utkarsh Tiwari Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The camera selection dialog currently only displays the camera Id. Display the camera location and camera model if available. Signed-off-by: Utkarsh Tiwari Reviewed-by: Kieran Bingham --- Difference : 1. Now use value_or for optional 2. Not use lambda and make a private member function src/qcam/cam_select_dialog.cpp | 52 ++++++++++++++++++++++++++++++++++ src/qcam/cam_select_dialog.h | 10 +++++++ 2 files changed, 62 insertions(+) diff --git a/src/qcam/cam_select_dialog.cpp b/src/qcam/cam_select_dialog.cpp index d8982800..f97ad6eb 100644 --- a/src/qcam/cam_select_dialog.cpp +++ b/src/qcam/cam_select_dialog.cpp @@ -7,6 +7,7 @@ #include "cam_select_dialog.h" +#include #include #include @@ -30,6 +31,14 @@ CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManag for (const auto &cam : cm_->cameras()) cameraIdComboBox_->addItem(QString::fromStdString(cam->id())); + /* Set camera information labels. */ + cameraLocation_ = new QLabel; + cameraModel_ = new QLabel; + + handleCameraChange(); + connect(cameraIdComboBox_, &QComboBox::currentTextChanged, + this, &CameraSelectorDialog::handleCameraChange); + /* Setup the QDialogButton Box */ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | @@ -41,7 +50,10 @@ CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManag this, &QDialog::reject); /* Set the layout. */ + layout->addRow("Camera:", cameraIdComboBox_); + layout->addRow("Location:", cameraLocation_); + layout->addRow("Model:", cameraModel_); layout->addWidget(buttonBox); } @@ -63,3 +75,43 @@ void CameraSelectorDialog::cameraRemoved(libcamera::Camera *camera) cameraIdComboBox_->removeItem(cameraIndex); } + +/* Camera Information */ +void CameraSelectorDialog::handleCameraChange() +{ + updateCamInfo(cm_->get(getCameraId())); +} + +void CameraSelectorDialog::updateCamInfo(const std::shared_ptr &camera) +{ + if (!camera) + return; + + const libcamera::ControlList &cameraProperties = camera->properties(); + + const auto &location = + cameraProperties.get(libcamera::properties::Location); + if (location) { + switch (*location) { + case libcamera::properties::CameraLocationFront: + cameraLocation_->setText("Internal front camera"); + break; + case libcamera::properties::CameraLocationBack: + cameraLocation_->setText("Internal back camera"); + break; + case libcamera::properties::CameraLocationExternal: + cameraLocation_->setText("External camera"); + break; + default: + cameraLocation_->setText("Unknown"); + } + } else { + cameraLocation_->setText("Unknown"); + } + + const auto &model = cameraProperties + .get(libcamera::properties::Model) + .value_or("Unknown"); + + cameraModel_->setText(QString::fromStdString(model)); +} diff --git a/src/qcam/cam_select_dialog.h b/src/qcam/cam_select_dialog.h index 567083ae..359df811 100644 --- a/src/qcam/cam_select_dialog.h +++ b/src/qcam/cam_select_dialog.h @@ -11,11 +11,14 @@ #include #include +#include +#include #include #include #include #include +#include #include class CameraSelectorDialog : public QDialog @@ -33,9 +36,16 @@ public: void cameraAdded(libcamera::Camera *camera); void cameraRemoved(libcamera::Camera *camera); + + /* Camera Information */ + void updateCamInfo(const std::shared_ptr &camera); + void handleCameraChange(); + private: libcamera::CameraManager *cm_; /* UI elements. */ QComboBox *cameraIdComboBox_; + QLabel *cameraLocation_; + QLabel *cameraModel_; }; From patchwork Tue Aug 9 20:50:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17057 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 25AE1BE173 for ; Tue, 9 Aug 2022 20:53:19 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9B7116332B; Tue, 9 Aug 2022 22:53:18 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660078398; bh=W3QoFPcQqQKVRH5GnhX5zifdpYLJkUVHcrTW7dGcBEk=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=TJSwRHwHdkpHzTjWTF3v3mco5Qzsq06kqr7UYsOwZXrfBbaQRXvIe6bfdYQWiX8b2 C8WeUl+EZO/UaxLwuWht/VBr8J1QzP/HIWI93Deilrl/nFmSLxZFbUR8eDjU7OACyl Dg1w90azhKBQgadQiR2+/wGvPEo3LKUtSD6Y630ef7LCsDqwuye13+2fj2Na93oHMW aYStA/+iLlYe8fsWvlv91ZaZ7e/5wCwlMRfd843SK+df3O7xVIne4OBME1lwA9+/88 S9AB9R3cssg9OAKukvIlQkHfZkQkuzmutNtDipqQJ8cWQly5wnciVXHe7cnAsr5cw9 Db/qP1V5cchng== Received: from mail-pf1-x42d.google.com (mail-pf1-x42d.google.com [IPv6:2607:f8b0:4864:20::42d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 95F0D61FAA for ; Tue, 9 Aug 2022 22:53:16 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="a6JTGAaG"; dkim-atps=neutral Received: by mail-pf1-x42d.google.com with SMTP id f28so11875444pfk.1 for ; Tue, 09 Aug 2022 13:53:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=yt6mCUrFgve5P3MjYWCshMuvkLX5Znj/8iQ14Dej+Rw=; b=a6JTGAaG352LuGbn+YwGH7sCPWtjMuCYCDfqnTJ4ir7q+ewd0k+Av4htEoS/B37Mu/ aZwrkZSZH8D5lDekMet9Ug4HZzxYBtYy8EpRWB+SAcIg79FzkKRoj2sGpZOZYZ8rFC1k Y+m+tRSsknLs1lWzOVnlK5ex3Z1QnkleWI8GHxbDOtnIq7FJz9GetKEAQafh4L7R35/O cGBDV2CCMYBNi6fLDGwkJz6KEAMekWP/JoJkmKcW6LsyJJjaR9H+CIx6mQgmNcRfXtg6 rWiAaOXWNt+ASKRghh/scco9YF88qEd0VRfP2BzyMoFX04nBlCN+olwh6ekwO5ZdfuJ2 Y60g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=yt6mCUrFgve5P3MjYWCshMuvkLX5Znj/8iQ14Dej+Rw=; b=eIqKCp4Nch44WsUDeljXHN84QvKzZekRGTMa1wXewfkes/JubGNS4A6fs5VmCNMrB4 V/JWmwVXSAHdWpdxuEEcLSsSBoRkiJa2rf1oPg+UDsBBduTT42wt2637LkmThQ9geImj UhqQXpYWoeUKZMxBqoqFpXc42djiI8/5UucVsSSZuZGeMzbUT/Z4MaVVzCc+qvJgjPlT vtcWjLoSAYMJXpefNRwDTvjER+SFm42hVLx5INqR3Do4X0ChAsT6yNHoqLMW6hMFtXVt NWnaLskd3wcqYoG1SsrO0FiqocHI+stUXAzUXwxXpeke95OwOackh8rDwQ96wCwjxKDc bs+g== X-Gm-Message-State: ACgBeo2tZeuc3b5pKWtf9FuIPBkeqrKH9vusc7UJau76vA0ROZpTnZ1L lei1V0cRC9z/oolCO/TW6JYiM+DPMpI= X-Google-Smtp-Source: AA6agR6JR3GL/BdC28AFsWmFPvUUZG+y4o0epkIKlN5e8kbJO98xbN59ige4cjQx53o3/zWwepEe2A== X-Received: by 2002:a65:6556:0:b0:41c:9c36:98fa with SMTP id a22-20020a656556000000b0041c9c3698famr20978778pgw.491.1660078394957; Tue, 09 Aug 2022 13:53:14 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2358:3bcd:fb4f:cbb7]) by smtp.gmail.com with ESMTPSA id d3-20020a623603000000b0052d981e7842sm301936pfa.208.2022.08.09.13.53.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:53:14 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 02:20:39 +0530 Message-Id: <20220809205042.344923-6-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809205042.344923-1-utkarsh02t@gmail.com> References: <20220809205042.344923-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 5/8] qcam: Queue requests only through MainWindow::queueRequest() 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: Utkarsh Tiwari via libcamera-devel From: Utkarsh Tiwari Reply-To: Utkarsh Tiwari Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Currently to request a frame, we operate the camera directly. This approach is also scattered in two places, MainWindow::startCapture() and MainWindow::queueRequest(). This makes it difficult to account for requests. Centralize all the queuing to a single function queueRequest() Rename the current queueRequest() to renderComplete(). This makes more sense as this slot is triggered when the render is complete and we want to queue another request. Signed-off-by: Utkarsh Tiwari Reviewed-by: Kieran Bingham Reviewed-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Umang Jain --- src/qcam/main_window.cpp | 14 +++++++++----- src/qcam/main_window.h | 3 ++- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 15b150ec..3feabcff 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -120,14 +120,14 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) if (renderType == "qt") { ViewFinderQt *viewfinder = new ViewFinderQt(this); connect(viewfinder, &ViewFinderQt::renderComplete, - this, &MainWindow::queueRequest); + this, &MainWindow::renderComplete); viewfinder_ = viewfinder; setCentralWidget(viewfinder); #ifndef QT_NO_OPENGL } else if (renderType == "gles") { ViewFinderGL *viewfinder = new ViewFinderGL(this); connect(viewfinder, &ViewFinderGL::renderComplete, - this, &MainWindow::queueRequest); + this, &MainWindow::renderComplete); viewfinder_ = viewfinder; setCentralWidget(viewfinder); #endif @@ -513,7 +513,7 @@ int MainWindow::startCapture() /* Queue all requests. */ for (std::unique_ptr &request : requests_) { - ret = camera_->queueRequest(request.get()); + ret = queueRequest(request.get()); if (ret < 0) { qWarning() << "Can't queue request"; goto error_disconnect; @@ -745,7 +745,7 @@ void MainWindow::processViewfinder(FrameBuffer *buffer) viewfinder_->render(buffer, mappedBuffers_[buffer].get()); } -void MainWindow::queueRequest(FrameBuffer *buffer) +void MainWindow::renderComplete(FrameBuffer *buffer) { Request *request; { @@ -774,6 +774,10 @@ void MainWindow::queueRequest(FrameBuffer *buffer) qWarning() << "No free buffer available for RAW capture"; } } + queueRequest(request); +} - camera_->queueRequest(request); +int MainWindow::queueRequest(Request *request) +{ + return camera_->queueRequest(request); } diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index bbdbb21c..bd6f0172 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -70,7 +70,7 @@ private Q_SLOTS: void processRaw(libcamera::FrameBuffer *buffer, const libcamera::ControlList &metadata); - void queueRequest(libcamera::FrameBuffer *buffer); + void renderComplete(libcamera::FrameBuffer *buffer); private: int createToolbars(); @@ -84,6 +84,7 @@ private: void addCamera(std::shared_ptr camera); void removeCamera(std::shared_ptr camera); + int queueRequest(libcamera::Request *request); void requestComplete(libcamera::Request *request); void processCapture(); void processHotplug(HotplugEvent *e); From patchwork Tue Aug 9 20:50:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17058 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 81292BE173 for ; Tue, 9 Aug 2022 20:53:20 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2D33463330; Tue, 9 Aug 2022 22:53:20 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660078400; bh=yGiyvD6CNzKoNXt3g9zqrzvMZXD/w3VQgQy4aizvZzM=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=gTwQe/XHYnID/ZV7fT7Nef4XdeTnVomAgWRBcnC+X9Bs3eaAXC9+BXAgRNMdEyXc3 KOX/vLB6ZQiBht7cRccVaFFpGzxZKEQMIFHbFp67QcL+qhnYixdY2crMruSSro4sAR 61TkWp7tsSbgCWNTONHMcxi4L5DDsekHUfocEIqtywDsyTMFjVOdStjC7uxhFMcA4w fksy7fi4DSf2a9ESTxYHyrEOaN/pC+iupA5tC2PDQzJSKvXCCE6CWK+gdg8NNERhPv Odj8RlfSg4Jhifq1wmFAfhk0SYM58yV54a54lcw2oPkUeIYkB67Xtgt27EFE6qvj8i TLeUXK8BliNpg== Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 8FF2263326 for ; Tue, 9 Aug 2022 22:53:18 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="IU+10EBm"; dkim-atps=neutral Received: by mail-pg1-x536.google.com with SMTP id r22so10050094pgm.5 for ; Tue, 09 Aug 2022 13:53:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=Mcr64yjVCfEAXiluxTvpzmJGc/Y98mtU/N/B27cP2jA=; b=IU+10EBmKTgtfPDDrs1ecW+INRHl2FQo/JncMdpxpdMsybAIIn2GvrnsH+QM45CaJw 8C34zAnl7GOcYFhrNsb1a7izIOYA4SThF6xMVjkJy60t0kgmIgZwYzUPa4CGdKCBJ0sA WsZRnz5+4Za493e4TMbW87Y7FWhk8R+2R8qpgX1cOj+UHe42nHrolVCubrbt3JpccT6z b/S7pcaob23oXNPaB+Nw8gle3FsyKF66fumRr0cPgj4GxKcJ1x2s/Y7WmkqUIcRYfROL hogSbAUJSR8pX+Nquub0ij/PEi1dYWdeo+O6kHqB+OsSysoST4W3IGOD4pZktF8QL/pX cwSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=Mcr64yjVCfEAXiluxTvpzmJGc/Y98mtU/N/B27cP2jA=; b=AYPqx1QCNk9famHxlCgw7ORXkcbF1BEiPy1/ludvhW3cGnZyRgN9o08InDSjL4vYvH ac1n6zL4dqMaTbWv1IQ/C9nrESh+75Th58kgA956v5vDrEmrk74Rhi5L25oQc41aWSym S0SF25RV92w+hb6754Bq7C2LpnHQ6JZqugAr/Cl382RflucFBUwjXQ5VRY4eLSQOSON8 7rdrp1mFnVy9LU5imomi6rnk0R52PvbbdLdLURDICAAw6pgu82tvo7s5ibw52DYR38Zh FJ2CZBmHCdCETuNKYooMJ20ZVAClIDjx4rfh6GKntOg3f30JqAuEC6EVrriVtJHskL8k hq2w== X-Gm-Message-State: ACgBeo3ZX3A3nYtGn7cHO60tWCTAaRfAF7s5gTT1nsc30fFVRPSLY9sR nN4RDToc1S/EXtUHfxQJ20gyaampfI0= X-Google-Smtp-Source: AA6agR41oW00X1WTf9EjnSirkTrq5QzprDsLoyRYioVEjt5P1WQ8jQ/XVaVRM0CsKi4hIxb58v7GFg== X-Received: by 2002:a63:1021:0:b0:41c:89f8:f4f4 with SMTP id f33-20020a631021000000b0041c89f8f4f4mr21058880pgl.416.1660078396830; Tue, 09 Aug 2022 13:53:16 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2358:3bcd:fb4f:cbb7]) by smtp.gmail.com with ESMTPSA id d3-20020a623603000000b0052d981e7842sm301936pfa.208.2022.08.09.13.53.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:53:16 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 02:20:40 +0530 Message-Id: <20220809205042.344923-7-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809205042.344923-1-utkarsh02t@gmail.com> References: <20220809205042.344923-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 6/8] qcam: CamSelectDialog: Add capture script button 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: Utkarsh Tiwari via libcamera-devel From: Utkarsh Tiwari Reply-To: Utkarsh Tiwari Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Implement an Capture Script in CamSelectDialog button which would allow the user to open a Capture Script (*.yaml). This button has three states : - Open Capture Script - Loaded - Stop the execution of current capture script When being clicked in open state, present them with a QFileDialog to allow user to select a single file. When the script is loaded the button displays "Loaded", the script has not been verified yet. Verifying the script and executing it happens after user presses Ok. Introduce a queueCount_ to keep track of the requests queued. When stopping the execution of the capture script the queueCount_ is not reseted and the capture is continues as it is (i.e it is not stopped or restarted). Requests are queued with any controls the script matching the current queueCount_. Signed-off-by: Utkarsh Tiwari --- Difference: 1. override accept and reject to handle capture script paths. src/qcam/cam_select_dialog.cpp | 68 ++++++++++++++++++++++++++++++++-- src/qcam/cam_select_dialog.h | 21 ++++++++++- src/qcam/main_window.cpp | 59 ++++++++++++++++++++++++++++- src/qcam/main_window.h | 7 ++++ src/qcam/meson.build | 2 + 5 files changed, 152 insertions(+), 5 deletions(-) diff --git a/src/qcam/cam_select_dialog.cpp b/src/qcam/cam_select_dialog.cpp index f97ad6eb..f3df9970 100644 --- a/src/qcam/cam_select_dialog.cpp +++ b/src/qcam/cam_select_dialog.cpp @@ -20,8 +20,8 @@ #include CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManager, - QWidget *parent) - : QDialog(parent), cm_(cameraManager) + bool isScriptRunning, QWidget *parent) + : QDialog(parent), cm_(cameraManager), isScriptRunning_(isScriptRunning) { /* Use a QFormLayout for the dialog. */ QFormLayout *layout = new QFormLayout(this); @@ -39,6 +39,16 @@ CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManag connect(cameraIdComboBox_, &QComboBox::currentTextChanged, this, &CameraSelectorDialog::handleCameraChange); + captureScriptButton_ = new QPushButton; + connect(captureScriptButton_, &QPushButton::clicked, + this, &CameraSelectorDialog::handleCaptureScriptButton); + + /* Display the action that would be performed when button is clicked. */ + if (isScriptRunning_) + captureScriptButton_->setText("Stop"); + else + captureScriptButton_->setText("Open"); + /* Setup the QDialogButton Box */ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | @@ -50,10 +60,10 @@ CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManag this, &QDialog::reject); /* Set the layout. */ - layout->addRow("Camera:", cameraIdComboBox_); layout->addRow("Location:", cameraLocation_); layout->addRow("Model:", cameraModel_); + layout->addRow("Capture Script:", captureScriptButton_); layout->addWidget(buttonBox); } @@ -62,6 +72,11 @@ std::string CameraSelectorDialog::getCameraId() return cameraIdComboBox_->currentText().toStdString(); } +std::string CameraSelectorDialog::getCaptureScript() +{ + return scriptPath_; +} + /* Hotplug / Unplug Support. */ void CameraSelectorDialog::cameraAdded(libcamera::Camera *camera) { @@ -115,3 +130,50 @@ void CameraSelectorDialog::updateCamInfo(const std::shared_ptrsetText(QString::fromStdString(model)); } + +/* Capture script support. */ +void CameraSelectorDialog::handleCaptureScriptButton() +{ + if (isScriptRunning_) { + Q_EMIT stopCaptureScript(); + isScriptRunning_ = false; + captureScriptButton_->setText("Open"); + } else { + selectedScriptPath_ = QFileDialog::getOpenFileName(this, + "Run Capture Script", QDir::currentPath(), + "Capture Script (*.yaml)") + .toStdString(); + + if (!selectedScriptPath_.empty()) + captureScriptButton_->setText("Loaded"); + else + captureScriptButton_->setText("Open"); + } +} + +void CameraSelectorDialog::accept() +{ + scriptPath_ = selectedScriptPath_; + QDialog::accept(); +} + +void CameraSelectorDialog::reject() +{ + if (isScriptRunning_) + selectedScriptPath_ = scriptPath_; + QDialog::reject(); +} + +void CameraSelectorDialog::informScriptReset() +{ + isScriptRunning_ = false; + scriptPath_.clear(); + captureScriptButton_->setText("Open"); +} + +void CameraSelectorDialog::informScriptRunning(std::string scriptPath) +{ + isScriptRunning_ = true; + scriptPath_ = scriptPath; + captureScriptButton_->setText("Stop"); +} diff --git a/src/qcam/cam_select_dialog.h b/src/qcam/cam_select_dialog.h index 359df811..56d90596 100644 --- a/src/qcam/cam_select_dialog.h +++ b/src/qcam/cam_select_dialog.h @@ -17,8 +17,10 @@ #include #include #include +#include #include #include +#include #include class CameraSelectorDialog : public QDialog @@ -26,12 +28,14 @@ class CameraSelectorDialog : public QDialog Q_OBJECT public: CameraSelectorDialog(libcamera::CameraManager *cameraManager, - QWidget *parent); + bool isScriptRunning, QWidget *parent); ~CameraSelectorDialog() = default; std::string getCameraId(); + std::string getCaptureScript(); + /* Hotplug / Unplug Support. */ void cameraAdded(libcamera::Camera *camera); @@ -41,11 +45,26 @@ public: void updateCamInfo(const std::shared_ptr &camera); void handleCameraChange(); + /* Capture script support. */ + void handleCaptureScriptButton(); + void informScriptReset(); + void informScriptRunning(std::string scriptPath); + void accept() override; + void reject() override; + +Q_SIGNALS: + void stopCaptureScript(); + private: libcamera::CameraManager *cm_; + bool isScriptRunning_; + std::string scriptPath_; + std::string selectedScriptPath_; + /* UI elements. */ QComboBox *cameraIdComboBox_; QLabel *cameraLocation_; QLabel *cameraModel_; + QPushButton *captureScriptButton_; }; diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 3feabcff..d73fb42a 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -19,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -151,6 +153,9 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) return; } + /* Start capture script. */ + loadCaptureScript(); + startStopAction_->setChecked(true); } @@ -289,10 +294,53 @@ void MainWindow::switchCamera() startStopAction_->setChecked(true); } +void MainWindow::stopCaptureScript() +{ + if (script_) { + script_.reset(); + cameraSelectorDialog_->informScriptReset(); + } +} + +void MainWindow::loadCaptureScript() +{ + if (scriptPath_.empty() || camera_ == nullptr) + return; + + script_ = std::make_unique(camera_, scriptPath_); + + /* + * If we are already capturing, stop so we don't have stuck image + * in viewfinder. + */ + bool wasCapturing = isCapturing_; + if (isCapturing_) + toggleCapture(false); + + if (!script_->valid()) { + script_.reset(); + cameraSelectorDialog_->informScriptReset(); + + QMessageBox::critical(this, "Invalid Script", + "Couldn't load the capture script"); + + } else + cameraSelectorDialog_->informScriptRunning(scriptPath_); + + /* Start capture again if we were capturing before. */ + if (wasCapturing) + toggleCapture(true); +} + std::string MainWindow::chooseCamera() { + bool scriptRunning = script_ != nullptr; + /* Construct the selection dialog, unconditionally. */ - cameraSelectorDialog_ = new CameraSelectorDialog(cm_, this); + cameraSelectorDialog_ = new CameraSelectorDialog(cm_, scriptRunning, this); + + connect(cameraSelectorDialog_, &CameraSelectorDialog::stopCaptureScript, + this, &MainWindow::stopCaptureScript); /* * Use the camera specified on the command line, if any, or display the @@ -305,6 +353,9 @@ std::string MainWindow::chooseCamera() std::string cameraId = cameraSelectorDialog_->getCameraId(); cameraSelectButton_->setText(QString::fromStdString(cameraId)); + scriptPath_ = cameraSelectorDialog_->getCaptureScript(); + loadCaptureScript(); + return cameraId; } else return std::string(); @@ -502,6 +553,7 @@ int MainWindow::startCapture() previousFrames_ = 0; framesCaptured_ = 0; lastBufferTime_ = 0; + queueCount_ = 0; ret = camera_->start(); if (ret) { @@ -779,5 +831,10 @@ void MainWindow::renderComplete(FrameBuffer *buffer) int MainWindow::queueRequest(Request *request) { + if (script_) + request->controls() = script_->frameControls(queueCount_); + + queueCount_++; + return camera_->queueRequest(request); } diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index bd6f0172..887f1db1 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -28,6 +28,7 @@ #include #include +#include "../cam/capture_script.h" #include "../cam/stream_options.h" #include "cam_select_dialog.h" @@ -90,6 +91,9 @@ private: void processHotplug(HotplugEvent *e); void processViewfinder(libcamera::FrameBuffer *buffer); + void loadCaptureScript(); + void stopCaptureScript(); + /* UI elements */ QToolBar *toolbar_; QAction *startStopAction_; @@ -130,6 +134,9 @@ private: QElapsedTimer frameRateInterval_; uint32_t previousFrames_; uint32_t framesCaptured_; + uint32_t queueCount_; std::vector> requests_; + std::unique_ptr script_; + std::string scriptPath_; }; diff --git a/src/qcam/meson.build b/src/qcam/meson.build index 61861ea6..70a18d7e 100644 --- a/src/qcam/meson.build +++ b/src/qcam/meson.build @@ -15,6 +15,7 @@ endif qcam_enabled = true qcam_sources = files([ + '../cam/capture_script.cpp', '../cam/image.cpp', '../cam/options.cpp', '../cam/stream_options.cpp', @@ -39,6 +40,7 @@ qcam_resources = files([ qcam_deps = [ libatomic, libcamera_public, + libyaml, qt5_dep, ] From patchwork Tue Aug 9 20:50:41 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17059 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 62AFABE173 for ; Tue, 9 Aug 2022 20:53:22 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 1D94363334; Tue, 9 Aug 2022 22:53:22 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660078402; bh=XyTA9Gh1d2o5gLaO6sM827NF2rOSS/csQrznwpcDSK4=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=kkvMXchCie3N2uYd763caObDofERbs/664iqnoEwbNjgPDxXpDr982aXDzU1bAWEP b0h475JmfvyRo03uSnKjf+NlwK6CTtRp6w9uRQkPDdlKJ5ut8WoRzf0UWMuFhmfK+a kX8l5cFqAD3MY6w+++3oRI/o4EwB/D0SaHiNRCS6Y4aUbhei+nEwYE50VH989OTzLM YA/BGJlxknTJapsMe1PUnZ2fd91WCRO7516+MLH4rwv3xWf3X8MJhze7WTHcLaunOZ vnrnunZDvH6d5zpb09r/tbFjqqFDTk1+aIl9Pm0Sf/3/ZY5p/Opj+/b/mg7qzvDdvX dGXDAeYyUBdrQ== Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0F61063328 for ; Tue, 9 Aug 2022 22:53:20 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Goy0GOSY"; dkim-atps=neutral Received: by mail-pl1-x62d.google.com with SMTP id o3so12435519ple.5 for ; Tue, 09 Aug 2022 13:53:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=OmavJLYphfFZBhTcOP/Gxk0CM7TEQuFfx5FQ9o/vXsI=; b=Goy0GOSYNIE/yY+g+K4FQP3JIh4FpR0N2zylI9G9roo23EBSIM+tYNMtIq+M4Fl/Wg NFmjXPXqESYG9AtSwf14J7ihPZTXMZFHEpXlvsSfidrV9wAtoAC6fBzpHH9GNxg/wHpq 1i2pIn6dpFCiCMnKZ87kx15BOZYsw6/x1UDgAwjTflcSCT2ocvZaBuoVhPdxhhk3ZYDl XVpobKSB2YTEnZi8VKxdZ4DJrhpXW6kgOGoMp95ngNJkaoU4n0P9Ti4otFDeB9PfBv13 mzc9HYoYl7mRL9Nc8IWTDiY62oTNhtfxer0bHrOmJzQ8Pq0U9FJHm/+QmWBtQT0yt4gc f9tA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=OmavJLYphfFZBhTcOP/Gxk0CM7TEQuFfx5FQ9o/vXsI=; b=Rc7YPG4oGI73SpS/95bXxQHRqbxiapgv5eIblMAiHyoX1Ys0oCNftQLUkkZLG2cdIz puwZwkU8bT/95qe3XJsYM+Ki8S2kTp+J5zxVSfq0WV/30+RPOHIgUsjfH5f6y59witOP vM2MqlyD2sdA7lWy2HxtAA+OCxS4MtvUQmEvbbEGB/pc6+1u077qvS973hcH8Pxc6/7D LRu7dobKWCR5NNKtiPlgqwcoVZsmlKTTSvwnnF4ow9YFftSzviR1PeBjmSW9/4hz14kf aRk9C5zNK0Bs85Pbh4qyJvyFsWg2RwWae5FMBs2qgU6U2RVM/wLcZ1TlHUR0NwjtWWrC UOnA== X-Gm-Message-State: ACgBeo2WV6G0kJ4ijOpW5RNx+uSkUYQSnT1Hm20pOuBaALJT1NtQ+/xx 1x4Ok/BQhZzkO24xQusT6jSJEBe9zjg= X-Google-Smtp-Source: AA6agR7fkgHTKzxfEznfu19AWEqR9AvZROS19j3KJsCh1+m6Sty5OsF1dZgcF8DyxlvTkVG9MfU8wA== X-Received: by 2002:a17:903:1104:b0:16c:2f71:7803 with SMTP id n4-20020a170903110400b0016c2f717803mr25590962plh.101.1660078398468; Tue, 09 Aug 2022 13:53:18 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2358:3bcd:fb4f:cbb7]) by smtp.gmail.com with ESMTPSA id d3-20020a623603000000b0052d981e7842sm301936pfa.208.2022.08.09.13.53.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:53:18 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 02:20:41 +0530 Message-Id: <20220809205042.344923-8-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809205042.344923-1-utkarsh02t@gmail.com> References: <20220809205042.344923-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 7/8] qcam: CamSelectDialog: Display Capture script path 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: Utkarsh Tiwari via libcamera-devel From: Utkarsh Tiwari Reply-To: Utkarsh Tiwari Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Display the path of the selected capture script in a thinner font. Signed-off-by: Utkarsh Tiwari --- src/qcam/cam_select_dialog.cpp | 38 +++++++++++++++++++++++++++------- src/qcam/cam_select_dialog.h | 8 ++++++- src/qcam/main_window.cpp | 3 ++- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/qcam/cam_select_dialog.cpp b/src/qcam/cam_select_dialog.cpp index f3df9970..5a9de08c 100644 --- a/src/qcam/cam_select_dialog.cpp +++ b/src/qcam/cam_select_dialog.cpp @@ -20,8 +20,9 @@ #include CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManager, - bool isScriptRunning, QWidget *parent) - : QDialog(parent), cm_(cameraManager), isScriptRunning_(isScriptRunning) + bool isScriptRunning, std::string scriptPath, QWidget *parent) + : QDialog(parent), cm_(cameraManager), + isScriptRunning_(isScriptRunning), scriptPath_(scriptPath) { /* Use a QFormLayout for the dialog. */ QFormLayout *layout = new QFormLayout(this); @@ -39,14 +40,31 @@ CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManag connect(cameraIdComboBox_, &QComboBox::currentTextChanged, this, &CameraSelectorDialog::handleCameraChange); + /* Setup widget for capture script button. */ + QWidget *captureWidget = new QWidget; + captureWidgetLayout_ = new QVBoxLayout(captureWidget); + captureWidgetLayout_->setMargin(0); + captureScriptButton_ = new QPushButton; connect(captureScriptButton_, &QPushButton::clicked, this, &CameraSelectorDialog::handleCaptureScriptButton); + captureWidgetLayout_->addWidget(captureScriptButton_); + + /* Use a thinner font to indicate script info. */ + QFont smallFont; + smallFont.setWeight(QFont::Thin); + + scriptPathLabel_ = new QLabel; + scriptPathLabel_->setFont(smallFont); + scriptPathLabel_->setWordWrap(true); /* Display the action that would be performed when button is clicked. */ - if (isScriptRunning_) + if (isScriptRunning_) { captureScriptButton_->setText("Stop"); - else + + scriptPathLabel_->setText(QString::fromStdString(scriptPath_)); + captureWidgetLayout_->addWidget(scriptPathLabel_); + } else captureScriptButton_->setText("Open"); /* Setup the QDialogButton Box */ @@ -63,7 +81,7 @@ CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManag layout->addRow("Camera:", cameraIdComboBox_); layout->addRow("Location:", cameraLocation_); layout->addRow("Model:", cameraModel_); - layout->addRow("Capture Script:", captureScriptButton_); + layout->addRow("Capture Script:", captureWidget); layout->addWidget(buttonBox); } @@ -138,16 +156,22 @@ void CameraSelectorDialog::handleCaptureScriptButton() Q_EMIT stopCaptureScript(); isScriptRunning_ = false; captureScriptButton_->setText("Open"); + + captureWidgetLayout_->removeWidget(scriptPathLabel_); } else { selectedScriptPath_ = QFileDialog::getOpenFileName(this, "Run Capture Script", QDir::currentPath(), "Capture Script (*.yaml)") .toStdString(); - if (!selectedScriptPath_.empty()) + if (!selectedScriptPath_.empty()) { captureScriptButton_->setText("Loaded"); - else + scriptPathLabel_->setText(QString::fromStdString(selectedScriptPath_)); + captureWidgetLayout_->addWidget(scriptPathLabel_); + } else { captureScriptButton_->setText("Open"); + captureWidgetLayout_->removeWidget(scriptPathLabel_); + } } } diff --git a/src/qcam/cam_select_dialog.h b/src/qcam/cam_select_dialog.h index 56d90596..84904640 100644 --- a/src/qcam/cam_select_dialog.h +++ b/src/qcam/cam_select_dialog.h @@ -18,17 +18,20 @@ #include #include #include +#include #include #include #include #include +#include +#include class CameraSelectorDialog : public QDialog { Q_OBJECT public: CameraSelectorDialog(libcamera::CameraManager *cameraManager, - bool isScriptRunning, QWidget *parent); + bool isScriptRunning, std::string scriptPath, QWidget *parent); ~CameraSelectorDialog() = default; @@ -66,5 +69,8 @@ private: QComboBox *cameraIdComboBox_; QLabel *cameraLocation_; QLabel *cameraModel_; + + QVBoxLayout *captureWidgetLayout_; QPushButton *captureScriptButton_; + QLabel *scriptPathLabel_ = new QLabel; }; diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index d73fb42a..f2e3c576 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -337,7 +337,8 @@ std::string MainWindow::chooseCamera() bool scriptRunning = script_ != nullptr; /* Construct the selection dialog, unconditionally. */ - cameraSelectorDialog_ = new CameraSelectorDialog(cm_, scriptRunning, this); + cameraSelectorDialog_ = new CameraSelectorDialog(cm_, scriptRunning, + scriptPath_, this); connect(cameraSelectorDialog_, &CameraSelectorDialog::stopCaptureScript, this, &MainWindow::stopCaptureScript); From patchwork Tue Aug 9 20:50:42 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17060 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 E61EFBE173 for ; Tue, 9 Aug 2022 20:53:24 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A58196332F; Tue, 9 Aug 2022 22:53:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660078404; bh=Mh458UP2fIbdUlAJuSxCqrj9cpiKx0IlnO1iGdmcrJs=; h=To:Date:In-Reply-To:References:Subject:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=vA55UoBaU5B3f14icWFKoXMoO6W+oIHmP5vQq7udY3fU7ZdMRsAlWREq4jouFtkKk s/T7yHXlHuPIDPMSWLA+RK1477/u/X2961Y7kyd6pZfq2s//HoLzT7OR9HL/UmzsLH 0jjW9ge3cHLN0cNZB5gWBE4sMu4RbyeyFKDXR7h2lmMDx/1yo8J0GcVhxp7cI2RvTi vC/FsradFQmr6dCJJHsF58nBQMLD057ht4zHDs4wPSKdf0/mSpEREBQXMsiqdue94Z XpZFy8qsXgESOQUbmZQEcKzN8pLcYctjIb2Gw/7HXUmTIw3sgLf4b6JjNJH1JAVuL9 8rbpTheSsro/A== Received: from mail-pg1-x535.google.com (mail-pg1-x535.google.com [IPv6:2607:f8b0:4864:20::535]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 022B863326 for ; Tue, 9 Aug 2022 22:53:22 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="HghvDntf"; dkim-atps=neutral Received: by mail-pg1-x535.google.com with SMTP id f65so12428788pgc.12 for ; Tue, 09 Aug 2022 13:53:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc; bh=4kJc2X3IFnYFC/i3pZnsTvmeQjYWGAtyZAF3am6hQFI=; b=HghvDntfyzWVtJ1HEDVC+pMzAAwYYvbo3+X3lkH61qWa+uViHkPgvmA/0t0mZqtcJm KXrHQz/jN818HilaTFTAW2Jw1ZiQtFqGyq19Z+dnrE8vE29dSpL8BvlQl55n8Tsh3gY8 og77Cr+00Dq3jnuX2okK7xdmD48BGRI1OHnsLO2WTSfDEaKt8ubhEPgV1x5NMCuvfA7E J0WNEYa+mUG1D+2/0QLHVakebmdi6pr5MMakJQgIrkKwghFKu+VPchbW6rvnqMMbTeIf iSyRlY9cryg62po/+0rFDfJWlsvbsv3S3zwnAZv2xuoarYcMleoDXtoRawNhkbRYFtQ2 505w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc; bh=4kJc2X3IFnYFC/i3pZnsTvmeQjYWGAtyZAF3am6hQFI=; b=pEk3XtAggDXlrJnO3JgBREJJdxogx5MA4f8kjG5mDK65WgcZ7IAcHaHHvz84pLIk5x OAg9lWhFrHxIy7caOS9S/jqelWWMwqf3iNLpptfqzDSkB384JcQ2WttCwFcyZwPTdSmV /Sd5LvWWaaMhPSk1b1z32A6hP4tuGcwmZWlyjHpFzDZR6/cfH3T6wupk8er+LRZ6TmoX pN0dyI95ADq/32K+HNP06AwhWjh0MPwvCKSG/1Sj8KdSvZHT5zzxKx2DLWUiG7oM8RMF IkbRrbUfIvpRIFsRMRurwRGelaT2+9PbM6BuffvBksmOdzoM6V/PD9oeqehCKPXYZ2GR EUzw== X-Gm-Message-State: ACgBeo1FhT5Vn8xXu9+PmT2LRI7Y0KsdFXdqCyRaN+JtcEXfDYBG55t4 FyWruRz7XygkMrR4n8VUcNNooIihL0k= X-Google-Smtp-Source: AA6agR6yTOQL9duoirMgjBc/pFzH+oKgMVDyuk9UCzOMYYBdoHdH8iDIurdbyS2u7YogHna4ycDjQg== X-Received: by 2002:a05:6a00:240f:b0:52e:f99d:1157 with SMTP id z15-20020a056a00240f00b0052ef99d1157mr15371950pfh.70.1660078400416; Tue, 09 Aug 2022 13:53:20 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2358:3bcd:fb4f:cbb7]) by smtp.gmail.com with ESMTPSA id d3-20020a623603000000b0052d981e7842sm301936pfa.208.2022.08.09.13.53.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Aug 2022 13:53:20 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 02:20:42 +0530 Message-Id: <20220809205042.344923-9-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220809205042.344923-1-utkarsh02t@gmail.com> References: <20220809205042.344923-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v7 8/8] qcam: Add --script to load capture script 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: Utkarsh Tiwari via libcamera-devel From: Utkarsh Tiwari Reply-To: Utkarsh Tiwari Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" Add --script as an individual option to load capture scripts. Load the capture script before starting the capture. If an invalid capture script has been given, display an critical error QMessageBox and close the application. Signed-off-by: Utkarsh Tiwari --- Difference: 1. firstCameraSelect_ newly introduced to keep track if its the first time dialog is been opened. src/qcam/main.cpp | 3 +++ src/qcam/main_window.cpp | 16 ++++++++++++++-- src/qcam/main_window.h | 2 ++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/qcam/main.cpp b/src/qcam/main.cpp index d3f01a85..91166be5 100644 --- a/src/qcam/main.cpp +++ b/src/qcam/main.cpp @@ -43,6 +43,9 @@ OptionsParser::Options parseOptions(int argc, char *argv[]) "Set configuration of a camera stream", "stream", true); parser.addOption(OptVerbose, OptionNone, "Print verbose log messages", "verbose"); + parser.addOption(OptCaptureScript, OptionString, + "Load a capture session configuration script from a file", + "script", ArgumentRequired, "script"); OptionsParser::Options options = parser.parse(argc, argv); if (options.isSet(OptHelp)) diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index f2e3c576..d6ad0083 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -100,7 +100,7 @@ private: MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) : saveRaw_(nullptr), options_(options), cm_(cm), allocator_(nullptr), - isCapturing_(false), captureRaw_(false) + isCapturing_(false), captureRaw_(false), firstCameraSelect_(true) { int ret; @@ -146,6 +146,9 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) cm_->cameraAdded.connect(this, &MainWindow::addCamera); cm_->cameraRemoved.connect(this, &MainWindow::removeCamera); + if (options_.isSet(OptCaptureScript)) + scriptPath_ = options_[OptCaptureScript].toString(); + /* Open the camera and start capture. */ ret = openCamera(); if (ret < 0) { @@ -324,6 +327,13 @@ void MainWindow::loadCaptureScript() QMessageBox::critical(this, "Invalid Script", "Couldn't load the capture script"); + /* + * Close the camera if started by command line and its the first capture + * script. + */ + if (firstCameraSelect_ && options_.isSet(OptCaptureScript)) + quit(); + } else cameraSelectorDialog_->informScriptRunning(scriptPath_); @@ -347,8 +357,10 @@ std::string MainWindow::chooseCamera() * Use the camera specified on the command line, if any, or display the * camera selection dialog box otherwise. */ - if (options_.isSet(OptCamera)) + if (firstCameraSelect_ && options_.isSet(OptCamera)) { + firstCameraSelect_ = false; return static_cast(options_[OptCamera]); + } if (cameraSelectorDialog_->exec() == QDialog::Accepted) { std::string cameraId = cameraSelectorDialog_->getCameraId(); diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index 887f1db1..3a264f96 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -46,6 +46,7 @@ enum { OptRenderer = 'r', OptStream = 's', OptVerbose = 'v', + OptCaptureScript = 256, }; class MainWindow : public QMainWindow @@ -123,6 +124,7 @@ private: /* Capture state, buffers queue and statistics */ bool isCapturing_; bool captureRaw_; + bool firstCameraSelect_; libcamera::Stream *vfStream_; libcamera::Stream *rawStream_; std::map> freeBuffers_;