From patchwork Wed Aug 31 05:49:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17265 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 65BAAC3272 for ; Wed, 31 Aug 2022 05:49:56 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 158F361FC0; Wed, 31 Aug 2022 07:49:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661924996; bh=pBtWysisUXQZjFS1DaxfJbevz+8j9IQ0PqWmQ3oVr+g=; 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=RC1kYB701+h1IHOnnBh7lTAaVBC5PNdp+cfIEVepipK0GphMuHN7qPNeAX4UYN2C1 suqqPTaM301pH8fvuyhCcOx71CoKXJnnwbSSElEf6hA9zUnFDGpmQRInr1hMIRLs5P USrrr961Qm/vnTSEOyO3OWNd7fRDxhkP+kx5UzRAqDT8jqNEXEg/pyQRKrHd+hVQU2 mUUJzMPPfj6iOs1pkznfF/jZZa7K2qErWSvCk6Y3MkK8Skj7Dj9PfpG95C8cPpeFeX X2KTc5gOCKLGMP7bu6b7lw8CR5B1uY9hnlf6qee0BSZkPWmYhXzbH5NLxBobIwRB6E Xa681tFMT7/LA== Received: from mail-pf1-x42e.google.com (mail-pf1-x42e.google.com [IPv6:2607:f8b0:4864:20::42e]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B2C7061FC0 for ; Wed, 31 Aug 2022 07:49:53 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="FCZFzW7t"; dkim-atps=neutral Received: by mail-pf1-x42e.google.com with SMTP id 72so13434650pfx.9 for ; Tue, 30 Aug 2022 22:49:53 -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=B9kMzQ/ssEmSlT0Blg3p++oQte936a/cWGLiumonPLE=; b=FCZFzW7tAhsfDivh6CQfSFEnA8TEREwijBL3ApZBAvIiATMalmqGbFDdpLlQUQlW2I 5ehDiwwLFaRk+ziO9L6sOZpjSAxbBhRhOCSiYL3bpclZ7BbdRDz6+n6MpjBnN/dV0tml GJZo4jUNDRAHz5XTjsZEDTNuJXEVcarYyW7Ug0sufmLGMpEXI2NuYMymRpJk6treopMH Qxa84LBa+oiydPW5Fh8klgwJ7C0uoxl2a/A+mU6ZxKJUzulb/a/yg/+l9KBDB3iER7cH UC9Q0wflMEPckBo0s5UQObj5v2ntreLo88mLwXQoYvil0SrvF+rrIlVX2f1NJigtUw8j PvXQ== 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=B9kMzQ/ssEmSlT0Blg3p++oQte936a/cWGLiumonPLE=; b=l2H+dileZP9PI0Up4rmx7Mw+tTOpvaYApRXFm7vX+Cns6y2dvLCoRF17hrXx+CyJRZ xhecJmkBXIPptF3CsxZPUZvWAK2q6by39HBQb8wFXNZGlwboPpHjL0wJcCpOhz6a/Nox R0sEVz2VBMloIOwyZRk60vdeHchyLErk4ypomYssujuUyBk4NTGdzOd5nxjYC4ymh3S8 Rqk+Ud8EdASA93Ob/ztlwWwcqC5dEQ+0Yp0VtCGfKlwYFuFihCd/2GNmFeff7ANFE2W1 W+qT8zgahuV9Qx2JBZ13ZzNgVu4fniacpF9de7UFyP003eeO5Iti5X4BMXc3VBZWdIlk ZluQ== X-Gm-Message-State: ACgBeo0akT2zl8B/B15wmTK9DyWSbtrWWLMRyL+Zm6A2mIi3hazvPRo9 q9CpK1bJum/K7/NGpOik6okDteYRjXs= X-Google-Smtp-Source: AA6agR7+0ZiNetMTj2+XSfdbs33U41OJvWKKldSRnFS3q5ri7u281d/pNNtB82FtYzK1iUu9Xj1mGg== X-Received: by 2002:a05:6a00:1384:b0:538:73c5:91ff with SMTP id t4-20020a056a00138400b0053873c591ffmr8888834pfg.54.1661924991961; Tue, 30 Aug 2022 22:49:51 -0700 (PDT) Received: from devut-HP-Laptop-14q-cs0xxx.. ([103.36.82.122]) by smtp.gmail.com with ESMTPSA id q19-20020aa79833000000b00537eacc8fa6sm8307333pfl.40.2022.08.30.22.49.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Aug 2022 22:49:51 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 31 Aug 2022 11:19:32 +0530 Message-Id: <20220831054938.21617-2-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831054938.21617-1-utkarsh02t@gmail.com> References: <20220831054938.21617-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v9 1/7] 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. The CameraSelectorDialog is only initialized the first time when the MainWindow is created. From this commit we cease to auto select the camera if only a single camera is available to libcamera. We would always display the selection dialog with the exception being that being if the camera is supplied on the command line. Signed-off-by: Utkarsh Tiwari Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- Difference from v8: 1. s/by the console/on the command line in the commit msg 2. Removed header from cam_select_dialog.cpp 3. Drop from cam_select_dialog.cpp 4. QComboBox is forward-declared in cam_select_dialog.h 5. ~CameraSelectorDialog() implementation now resides in .cpp 6. CameraSelectorDialog is forward-declared in main_window.h src/qcam/cam_select_dialog.cpp | 50 ++++++++++++++++++++++++++++++++++ src/qcam/cam_select_dialog.h | 35 ++++++++++++++++++++++++ src/qcam/main_window.cpp | 27 ++++-------------- src/qcam/main_window.h | 3 ++ src/qcam/meson.build | 2 ++ 5 files changed, 96 insertions(+), 21 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..a49d822b --- /dev/null +++ b/src/qcam/cam_select_dialog.cpp @@ -0,0 +1,50 @@ +/* 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 + +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); +} + +CameraSelectorDialog::~CameraSelectorDialog() = default; + +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..c31f4f82 --- /dev/null +++ b/src/qcam/cam_select_dialog.h @@ -0,0 +1,35 @@ +/* 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 + +class QComboBox; + +class CameraSelectorDialog : public QDialog +{ + Q_OBJECT +public: + CameraSelectorDialog(libcamera::CameraManager *cameraManager, + QWidget *parent); + + ~CameraSelectorDialog(); + + 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..14bcf03e 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" @@ -144,6 +144,8 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) cm_->cameraAdded.connect(this, &MainWindow::addCamera); cm_->cameraRemoved.connect(this, &MainWindow::removeCamera); + cameraSelectorDialog_ = new CameraSelectorDialog(cm_, this); + /* Open the camera and start capture. */ ret = openCamera(); if (ret < 0) { @@ -290,34 +292,17 @@ 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) + if (cameraSelectorDialog_->exec() != QDialog::Accepted) return std::string(); - return id.toStdString(); + return cameraSelectorDialog_->getCameraId(); } int MainWindow::openCamera() { std::string cameraName; - /* - * Use the camera specified on the command line, if any, or display the - * camera selection dialog box otherwise. - */ + /* Use camera provided on the command line else prompt for selection.*/ if (options_.isSet(OptCamera)) cameraName = static_cast(options_[OptCamera]); else diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index fc70920f..def44605 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -35,6 +35,7 @@ class QComboBox; class Image; class HotplugEvent; +class CameraSelectorDialog; enum { OptCamera = 'c', @@ -99,6 +100,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 Wed Aug 31 05:49:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17266 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 AAA67C3272 for ; Wed, 31 Aug 2022 05:49:58 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 75C1961FC6; Wed, 31 Aug 2022 07:49:58 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661924998; bh=g6D5m2WFhbwXTkn/Pct1kjEn4FTBYJsLIw9oQbIJ8Qk=; 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=orAodYh9twuu66qKripTPqVLTY3fl9WdcbV63mMSmcoORJGezTZ2YRx0Yj5l/Tb5P 5qjBCBL0tTqrD8I/VGrVjDX54OYaUH4+jzMTWAE4+deObRFhfXJZNnD1LBPYQFF20W ZqURAXj3+aXElPeRivyd9UP8cKP5oBY3T3pw9NDjyNIDY9f4bMfOiC8tQ7xhBpPhqD w8DCIRQ0U82Jb02ZCLjCvYkuWebsPDcaK4LnSHB+LmB2aOZZyfShYIQB/ltgMSdgKg xqTldMtJ15G/1tEu3oNDp0MO0R86mOfa6twXbfJcuCAejODmVBH+GvwJn33dyUakFw nEe1ea2zlr6Pg== 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 E726761F9B for ; Wed, 31 Aug 2022 07:49:56 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="CDC57I7O"; dkim-atps=neutral Received: by mail-pg1-x530.google.com with SMTP id q9so12625361pgq.6 for ; Tue, 30 Aug 2022 22:49:56 -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=uJ1eqaShmnTXo3AJN7h1xqQNAn/WbfbO7bzaBnyOrR4=; b=CDC57I7O1aC0xphtRIMK8o5x2DhTq3RTN+44/4rY3LQGaVx8AsO6FUyRTum8f1NBQE EnjKOJc6JJZ/2vYrLk1QbR8KyEl1grXz7eReiUCRBpT621zu64kjxdeXmhQwqR94fqHN QUA8v/EJBYVAsUIAAKj0zP65W3lqJFlgfHNezzGN4ibnjLUhv7RZilrXIV5tiu8T30qL s/Eh7ZM8Rzc/HaHNoOezSih0PauX9sgjSWA+va+PczBq68ZPDKZF6rvJj9lQb8LjreDR KZLgglP2fDpd8o5ra1nEE87QObuwjEvswtU6bNvBl9YiFo759ivIbyvHPrz0yJ/FOsBu YlFg== 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=uJ1eqaShmnTXo3AJN7h1xqQNAn/WbfbO7bzaBnyOrR4=; b=J9PQwel19spnM8Frn165x5IIr6LWOr9UfvpYA6ZJJuNqcGKDoPP62Vc8BrR3ERCKKx lSO2GaQTh5/J5IfbxlHpAo6p2x0plEOAnU9PeQ8qbAqJj8C/GU96uZdjxAAqiMhWhVHI Talx8x+8rL14aUhPJWctHXca4H62DcsoZDBsHwIPOnF3FFvvAp8dJzZg4wVBhmbzUnZ7 lA6snlJtK+00X8db7mcm3C9WZkr1j1/iDvTsCawtM9Xt8olFxPk+fIHBxasig6+Ko5gB yQPbt16c/NeW5H1okkXN5yr3HJqOKgidKPMWj/xpl41NZqAIrzbzSsaHNInEwPZz8MGD V/JA== X-Gm-Message-State: ACgBeo2xPut46y28i6TfCgxFdH5qrs55rpys01IDeni0rmWEJW6KbgZL 94CL3h+hToaOVmUchdpc0TzG0fjr9zM= X-Google-Smtp-Source: AA6agR6slkzwzNZNaqO8yUabs94tydRNwznL8PJWivtYwgbbEJfKybQwgHJCA5OItMGJ0jAXOjdR9g== X-Received: by 2002:a63:84c2:0:b0:42b:f6bc:69f5 with SMTP id k185-20020a6384c2000000b0042bf6bc69f5mr12163968pgd.10.1661924995304; Tue, 30 Aug 2022 22:49:55 -0700 (PDT) Received: from devut-HP-Laptop-14q-cs0xxx.. ([103.36.82.122]) by smtp.gmail.com with ESMTPSA id q19-20020aa79833000000b00537eacc8fa6sm8307333pfl.40.2022.08.30.22.49.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Aug 2022 22:49:55 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 31 Aug 2022 11:19:33 +0530 Message-Id: <20220831054938.21617-3-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831054938.21617-1-utkarsh02t@gmail.com> References: <20220831054938.21617-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v9 2/7] 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 doesn't update to reflect the change. Add support for hotplugging / unplugging cameras. Signed-off-by: Utkarsh Tiwari Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- Difference from v8: 1. Removed the part about QPointer from commit message, no longer needed. 2. s/didn't/doesn't commit msg. 3. Rename cameraRemoved to removeCamera and cameraAdded to addCamera 4. Pass QString to cameraRemoved, cameraAdded instead of libcamera::Camera 5. Removed blank line between cameraAdded, cameraRemoved 6. Optimize cameraId passing cameraCombo_ , cameraAdded, cameraRemoved. src/qcam/cam_select_dialog.cpp | 12 ++++++++++++ src/qcam/cam_select_dialog.h | 5 +++++ src/qcam/main_window.cpp | 7 +++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/qcam/cam_select_dialog.cpp b/src/qcam/cam_select_dialog.cpp index a49d822b..f82930cc 100644 --- a/src/qcam/cam_select_dialog.cpp +++ b/src/qcam/cam_select_dialog.cpp @@ -48,3 +48,15 @@ std::string CameraSelectorDialog::getCameraId() { return cameraIdComboBox_->currentText().toStdString(); } + +/* Hotplug / Unplug Support. */ +void CameraSelectorDialog::addCamera(QString camearaId) +{ + cameraIdComboBox_->addItem(camearaId); +} + +void CameraSelectorDialog::removeCamera(QString cameraId) +{ + int cameraIndex = cameraIdComboBox_->findText(cameraId); + cameraIdComboBox_->removeItem(cameraIndex); +} diff --git a/src/qcam/cam_select_dialog.h b/src/qcam/cam_select_dialog.h index c31f4f82..bd2dbc1e 100644 --- a/src/qcam/cam_select_dialog.h +++ b/src/qcam/cam_select_dialog.h @@ -13,6 +13,7 @@ #include #include +#include class QComboBox; @@ -27,6 +28,10 @@ public: std::string getCameraId(); + /* Hotplug / Unplug Support. */ + void addCamera(QString cameraId); + void removeCamera(QString cameraId); + private: libcamera::CameraManager *cm_; diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 14bcf03e..e8e22d49 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -587,10 +587,12 @@ void MainWindow::stopCapture() void MainWindow::processHotplug(HotplugEvent *e) { Camera *camera = e->camera(); + QString cameraId = QString::fromStdString(camera->id()); HotplugEvent::PlugEvent event = e->hotplugEvent(); if (event == HotplugEvent::HotPlug) { - cameraCombo_->addItem(QString::fromStdString(camera->id())); + cameraCombo_->addItem(cameraId); + cameraSelectorDialog_->addCamera(cameraId); } else if (event == HotplugEvent::HotUnplug) { /* Check if the currently-streaming camera is removed. */ if (camera == camera_.get()) { @@ -600,8 +602,9 @@ void MainWindow::processHotplug(HotplugEvent *e) cameraCombo_->setCurrentIndex(0); } - int camIndex = cameraCombo_->findText(QString::fromStdString(camera->id())); + int camIndex = cameraCombo_->findText(cameraId); cameraCombo_->removeItem(camIndex); + cameraSelectorDialog_->removeCamera(cameraId); } } From patchwork Wed Aug 31 05:49:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17267 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 DF365C3272 for ; Wed, 31 Aug 2022 05:50:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 0ABBB61FBB; Wed, 31 Aug 2022 07:50:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661925002; bh=hu64cImvTVadUShZEqI/nuzEqRWxOMJ5I3KUx/TRGQ8=; 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=NXtcsREAC/LnlSepGS6bl7bt/YG/y51ZE9dxWhmfNKnytTQdA4nYpKPMLA1XrN8hz CoZAns4Qm+v8NX5Rkb/BxN4r1HNOMY+3wv7aDbz/h1JzqmmkZf34v1xyKCMWrGy+YS jg7tWsPx6N0TlT7mZUur/+dVYqD6yPtVUBhZhvowjCRCBk1L4uRwg6jhqYvGQ42n+4 Q5k0k4NbEd2QFFBDX9t8XcR8E75CsV50Jq6HOKGpZw4o51tfHtVUpMcQYkioOzh0q9 c0EHd61wzK1RDZrVy1ogi5DQdVF0sl3MrX4LgEsSb8TpSEJHPO+MF7UrICKYQkcSPT 6h58EJQTtoEDQ== Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 9F9AE61F9B for ; Wed, 31 Aug 2022 07:50:00 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="RRPuQf7X"; dkim-atps=neutral Received: by mail-pl1-x633.google.com with SMTP id u22so13175680plq.12 for ; Tue, 30 Aug 2022 22:50:00 -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=1/DFNJqcQfnMM+yUXqCldUE401lVkLLcP0bJcD0xqfw=; b=RRPuQf7XoQMRIOUTKXwdlmz3xBsN+HTGly5RfJyIA3jmDbqXt9VmUluw/RZmUOecUd JDRWivvtVHQbKw0EBt/IMETd4dwvSkIxNndLEL7z/jeA++R3eWObOY0SK4AxXyuUp9nm +nScfE4dNdANT3dt8oRCfmjH0tIiPY7mogKvcwxtoHyzeWwxFzoEVIwIlK+XL7OkH7rb WXuMDpbFQtgk7pb4C9b1LUrBM3GRTX1uBByP1zwoGK4Tk+gFfMmFr/FZeIyi8ER2eXSB 1xKPCPHUtig6YYYXaCCzxMt8bNAhbzONAduNIy8myTyL7HbbaI9Axb/EPsNGKERNzxrG tOCQ== 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=1/DFNJqcQfnMM+yUXqCldUE401lVkLLcP0bJcD0xqfw=; b=mlwqe18quu/OVrf6swCAKtxxw3WOEfSHoDgGQYIH7Pj6G3Dept84rwf0TFsNVxSyEo dIkjmxZYtmjTnij78fx6qvXthXSDhPGwVz1HAugONUr9eS+9QUP0hOK5pTX6Imzou8aO n2x/fXJsgORvw46iBPd5HL/SKgY+fMbFet+9PmkmUCd5C70g+TJMFborW5wEX7P5zGTK 0M+1VVgtAT7ZJqk+7YXqH8Yc1eETesHp8RH4+IfLTRVjQpHl4qoJxIrmSJiw9FabjR1l AW+9QooweKpA9OqdKupiSzxFT9hbZkVSBY0HEIKK9BWZ2OfnFAcFpwQHOky5qudhZG0c K2DA== X-Gm-Message-State: ACgBeo24Em3tpUoH/4YhUT5oBVsf9MGVoGIYvxaCjdRFDmh3C55drutf C/F8RpcYxSkFvGE1pdbtFxI3FPkKRQ0= X-Google-Smtp-Source: AA6agR4V0AvL7FHCK4u4L+hBoTO/leeFDpOi7wMku0BjA6A/wmguI7uV8WnhnMJ5rPWsu8oR2n01pw== X-Received: by 2002:a17:90b:350b:b0:1fd:fe88:7cdf with SMTP id ls11-20020a17090b350b00b001fdfe887cdfmr1638375pjb.236.1661924999040; Tue, 30 Aug 2022 22:49:59 -0700 (PDT) Received: from devut-HP-Laptop-14q-cs0xxx.. ([103.36.82.122]) by smtp.gmail.com with ESMTPSA id q19-20020aa79833000000b00537eacc8fa6sm8307333pfl.40.2022.08.30.22.49.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Aug 2022 22:49:58 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 31 Aug 2022 11:19:34 +0530 Message-Id: <20220831054938.21617-4-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831054938.21617-1-utkarsh02t@gmail.com> References: <20220831054938.21617-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v9 3/7] 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 Reviewed-by: Laurent Pinchart --- Differences from v9: 1. Checking for OptCamera now happens in 1/7 in openCamera dropping the firstCameraSelect_ 2. Improve curly brace structure 3. Drop QComboBox src/qcam/main_window.cpp | 33 ++++++++++++++++----------------- src/qcam/main_window.h | 5 +++-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index e8e22d49..505bdc56 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -14,7 +14,6 @@ #include #include -#include #include #include #include @@ -195,14 +194,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(); @@ -262,14 +258,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; - const std::shared_ptr &cam = cameras[index]; + if (camera_ && newCameraId == camera_->id()) + return; + + const std::shared_ptr &cam = cm_->get(newCameraId); if (cam->acquire()) { qInfo() << "Failed to acquire camera" << cam->id().c_str(); @@ -288,6 +288,9 @@ void MainWindow::switchCamera(int index) camera_ = cam; startStopAction_->setChecked(true); + + /* Display the current cameraId in the toolbar .*/ + cameraSelectButton_->setText(QString::fromStdString(newCameraId)); } std::string MainWindow::chooseCamera() @@ -324,8 +327,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,7 +594,6 @@ void MainWindow::processHotplug(HotplugEvent *e) HotplugEvent::PlugEvent event = e->hotplugEvent(); if (event == HotplugEvent::HotPlug) { - cameraCombo_->addItem(cameraId); cameraSelectorDialog_->addCamera(cameraId); } else if (event == HotplugEvent::HotUnplug) { /* Check if the currently-streaming camera is removed. */ @@ -599,11 +601,8 @@ void MainWindow::processHotplug(HotplugEvent *e) toggleCapture(false); camera_->release(); camera_.reset(); - cameraCombo_->setCurrentIndex(0); } - int camIndex = cameraCombo_->findText(cameraId); - cameraCombo_->removeItem(camIndex); cameraSelectorDialog_->removeCamera(cameraId); } } diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index def44605..79723256 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -60,7 +61,7 @@ private Q_SLOTS: void quit(); void updateTitle(); - void switchCamera(int index); + void switchCamera(); void toggleCapture(bool start); void saveImageAs(); @@ -90,7 +91,7 @@ private: /* UI elements */ QToolBar *toolbar_; QAction *startStopAction_; - QComboBox *cameraCombo_; + QPushButton *cameraSelectButton_; QAction *saveRaw_; ViewFinder *viewfinder_; From patchwork Wed Aug 31 05:49: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: 17268 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 CAE51C3272 for ; Wed, 31 Aug 2022 05:50:04 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 7A48261FC4; Wed, 31 Aug 2022 07:50:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661925004; bh=YvZ727gfLjtvWMXWh3ahMRI3I+UkZdTkjnh9L2o62rk=; 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=XNeUVGyZv5JyIq9UYg1rLkmsqTMSvI/QE3CrUj0VE5/jYFXzeNp07Rt7ckwPDjEn6 XWQC2U3YHOtMWOQ/d3h4WwiHkBJXtqxygeoQnb9raBDY0z+fXyJJl74AsqwlmVXxkE eY9lm8W75xZp+dFo7E/Uib3sz04ezC85zAkiOc+nYveuylCenOWmpqYyvwYPr6T1B7 TQRyHaqZcKHFhaAnFOw7cbMqsCwHZ9QcjYCadPrJRIAo08WidULR5//9iwFJThD3u/ cz+bIxDyl+Ij4A0URi49sQp6BuI2mMQcGq7U+UgU/Coj1u8v8YNQol/xqPy5cQ6W69 NjUy2WkdXgn+Q== Received: from mail-pl1-x633.google.com (mail-pl1-x633.google.com [IPv6:2607:f8b0:4864:20::633]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id B9AF361F9B for ; Wed, 31 Aug 2022 07:50:02 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="dfGPshDH"; dkim-atps=neutral Received: by mail-pl1-x633.google.com with SMTP id m2so13195304pls.4 for ; Tue, 30 Aug 2022 22:50: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=bstUSyjs2LmOJ8SXsae32HU48ED7P1q8tMxr+a1QFf8=; b=dfGPshDHE+0Mnfr2kpmhDfUXZhs6g4ZF7g1Mn5kxnGx+YUDrfpOlzsul6vtyOnRs7t jFhUeCMaf9RJWEtVtumJEzROeV9HRME04DjBlgJDsqemTS6Xe3yM8d6RPJKY+6yCptA2 seECuWbVShHh0i9YlaE307tiCmq0Yk/AH9Xr0AVb0Wiw5V7RXZtISdlWPLXxtcR32t2r 0WnX0YXUz4DW2gfav3Wyy3gM+4A3bcO/Kp8cMMM1t+6Ko9rBtzNYHAZYZJIknqCsibO+ 9h6e0ZafgnT6nVqacrTWT36g88pkpcnMbNNiTB/UCb09BqzbKQnThyUDQr/qwZOBTlj9 j9tA== 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=bstUSyjs2LmOJ8SXsae32HU48ED7P1q8tMxr+a1QFf8=; b=ndaU+hZfnz5nHytTH542Zr6MyZzegebPNK92YavhvYPKsLzHMx1jOwMcAXLV1sGv3s toOp6CaGIrcVbCZtfeCflo9LlyOCe3TFvWSDjsH/oVz6rp98hA/r2PdphSAXtPXI/EGd I0GyLuh4DVxqcyQFuRgflVZuAeiyPkwVNiKOnFIA1rXJC2gagaBCVlPJF8umZOtda/EG V4PMdx0mTu/q9puMlvVyK8JT4TlGn03FlivKaKLNPRQnV76lAK/jPvlSQUEzBHWSshQw 2gwzufj0Zy9F811nxpBgZno5Wn6EBFzxWcVYTIem+Lb7GuRm2se+tDP5Ik9Kn7AgzqI2 zo0g== X-Gm-Message-State: ACgBeo2IeHmLHNgfjXcsCu80alkjX+25KfFCU76yngQIthDwKvlPvZW2 l2TcytyOJ2pQxte9WOLi1tkpFIiIUIc= X-Google-Smtp-Source: AA6agR60BCjwOWDsNOYdQfS0BecQVoO1+ilocqWrB2gi1HOTvlMuJOtbCJ0GuGcrtGdEyqVCrE3uOQ== X-Received: by 2002:a17:902:e552:b0:16d:d3c0:85fb with SMTP id n18-20020a170902e55200b0016dd3c085fbmr23655018plf.38.1661925001180; Tue, 30 Aug 2022 22:50:01 -0700 (PDT) Received: from devut-HP-Laptop-14q-cs0xxx.. ([103.36.82.122]) by smtp.gmail.com with ESMTPSA id q19-20020aa79833000000b00537eacc8fa6sm8307333pfl.40.2022.08.30.22.49.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Aug 2022 22:50:00 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 31 Aug 2022 11:19:35 +0530 Message-Id: <20220831054938.21617-5-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831054938.21617-1-utkarsh02t@gmail.com> References: <20220831054938.21617-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v9 4/7] 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 Reviewed-by: Laurent Pinchart --- Difference from v9: 1. Remove handleCameraChange and use updateCamInfo directly 2. QLabel forward-declare 3. Rename cameraProperties to just properties src/qcam/cam_select_dialog.cpp | 50 ++++++++++++++++++++++++++++++++++ src/qcam/cam_select_dialog.h | 8 ++++++ 2 files changed, 58 insertions(+) diff --git a/src/qcam/cam_select_dialog.cpp b/src/qcam/cam_select_dialog.cpp index f82930cc..6543228a 100644 --- a/src/qcam/cam_select_dialog.cpp +++ b/src/qcam/cam_select_dialog.cpp @@ -7,12 +7,15 @@ #include "cam_select_dialog.h" +#include + #include #include #include #include #include +#include #include CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManager, @@ -27,6 +30,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; + + updateCamInfo(cameraIdComboBox_->currentText()); + connect(cameraIdComboBox_, &QComboBox::currentTextChanged, + this, &CameraSelectorDialog::updateCamInfo); + /* Setup the QDialogButton Box */ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | @@ -39,6 +50,8 @@ CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManag /* Set the layout. */ layout->addRow("Camera:", cameraIdComboBox_); + layout->addRow("Location:", cameraLocation_); + layout->addRow("Model:", cameraModel_); layout->addWidget(buttonBox); } @@ -60,3 +73,40 @@ void CameraSelectorDialog::removeCamera(QString cameraId) int cameraIndex = cameraIdComboBox_->findText(cameraId); cameraIdComboBox_->removeItem(cameraIndex); } + +/* Camera Information */ +void CameraSelectorDialog::updateCamInfo(QString cameraId) +{ + const std::shared_ptr &camera = + cm_->get(cameraId.toStdString()); + + if (!camera) + return; + + const libcamera::ControlList &properties = camera->properties(); + + const auto &location = properties.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 = properties + .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 bd2dbc1e..c91b7ebe 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 class QComboBox; +class QLabel; class CameraSelectorDialog : public QDialog { @@ -32,9 +35,14 @@ public: void addCamera(QString cameraId); void removeCamera(QString cameraId); + /* Camera Information */ + void updateCamInfo(QString cameraId); + private: libcamera::CameraManager *cm_; /* UI elements. */ QComboBox *cameraIdComboBox_; + QLabel *cameraLocation_; + QLabel *cameraModel_; }; From patchwork Wed Aug 31 05:49: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: 17269 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 79098C3272 for ; Wed, 31 Aug 2022 05:50:08 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 21BB161FC7; Wed, 31 Aug 2022 07:50:08 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661925008; bh=fXoMlk6sgHoLEmRpFy57e1Hx90cBeYwS6e11OGTXJAQ=; 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=GI3LsYOZ2WVFTuekhD+1vRyb8O8tir/UHn6jDYU1Fi7tyIxZJJWnrkqKaV6SRKCRh x51dxV4cXDgLicbRjF64hcLD63F6hZGFNReQ3qHDQXqWoFsB4Us5m6m7R944LlNq6s t547dJwx7dka1w5p71P3mXrZcVuTIHd/vOKHJdn10OPzp5/ZdoblZYCyK4DyoGxemX 6Wo2xNHKDmEvctzw9ePJ7OJ7BT1IijMW/YCFB42M7Z95116v+/8J0Fvdq0bfm/vmkI Hd7uYg6+bl1iphI1M1pY7HwGN7TWrLq23oIkNj1a7A5WtIBHW3BFIXswPwnWVNXPr/ WuIpKF2ZIwaow== 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 A20F661F9B for ; Wed, 31 Aug 2022 07:50:06 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="HJDo1rkE"; dkim-atps=neutral Received: by mail-pg1-x536.google.com with SMTP id f4so12610075pgc.12 for ; Tue, 30 Aug 2022 22:50:06 -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=K8djUDQAO1qcatMQ0yfPTxbPOky+Dev0DXfz/BLLymk=; b=HJDo1rkE4k4FhO9gs5wM7H23G8ABRYh1Tt5TnVSVVSSHsnamv/CqIVJ7MrlibRkxM8 frB3kl6uPR2VXs0ubZ6PAT1Sdn8rdUjR9V68hcWk8Gy3+/3djs3KS84YwClrcoha1QQs oFnaVSsIA05iIRZYsNPk6CPM/mYv/MDopvwoBxDOhlDYsyqDSqIdj4scCA52Npgn7ZMI pOQz75JX5WMykHfdd99ViXztIn0yvsWIt/h5xRRANN+jVFB5/U5Wg/8oV+qc/kwBqKma KXdm9crMwiV3Jb75Q36hjv1uAK0n98cl3vizuJOMY7RIE2mamdPUPa2bc8OXhcc7+jXH pxtw== 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=K8djUDQAO1qcatMQ0yfPTxbPOky+Dev0DXfz/BLLymk=; b=do+KW0b6DAW+Z7CBaifY0N9O8z1W+jW6pLiHkTCwES+zPaFuyNpjCGVmi/KQnb2eOM mz90TD/k/8w6LESvMp54uoTuO8iRHpdW01fsOvHSD6Z3mBs+FCbwuyb79Af8fwJeAkq6 GdIHm4B33pe6hA8AAct2y1IRcdjgQRE9JkYhMvo+1SD2oS+hXsYyT9JrEq72SFKIXYq5 1dgyPYJgRYdv9do7mueHSPqwmCNPT4baEKYyX0PRBHS13zr/Z2QAwEaVfI4I+E9jx9R1 eXOJ9zckrzaWZqu9C6JLFK2R0CIgEiC/Caa0EX7LhIrdbcBgf8hsbyr3r4AZKfFzPsFE uP4A== X-Gm-Message-State: ACgBeo01TtQFiA82ciiDQm5twBBAiaBhvAcZJKZ/QkJ/zxTREIm1QwGo W6BLjNHBmUhSUNlz4eUMbkrbJcFGgIY= X-Google-Smtp-Source: AA6agR4fuwry5k7sidZOfIHHqM9wUJ/ai6Z3pjpJeNwd7i3K9oAFSY2Pjht56YDRJfhvv21xvmM++Q== X-Received: by 2002:a63:91c1:0:b0:42b:50f8:774c with SMTP id l184-20020a6391c1000000b0042b50f8774cmr20821571pge.496.1661925005109; Tue, 30 Aug 2022 22:50:05 -0700 (PDT) Received: from devut-HP-Laptop-14q-cs0xxx.. ([103.36.82.122]) by smtp.gmail.com with ESMTPSA id q19-20020aa79833000000b00537eacc8fa6sm8307333pfl.40.2022.08.30.22.50.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Aug 2022 22:50:04 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 31 Aug 2022 11:19:36 +0530 Message-Id: <20220831054938.21617-6-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831054938.21617-1-utkarsh02t@gmail.com> References: <20220831054938.21617-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v9 5/7] 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 --- Difference from v8: 1. None :D 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 505bdc56..2a9ca830 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -119,14 +119,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 @@ -510,7 +510,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; @@ -743,7 +743,7 @@ void MainWindow::processViewfinder(FrameBuffer *buffer) viewfinder_->render(buffer, mappedBuffers_[buffer].get()); } -void MainWindow::queueRequest(FrameBuffer *buffer) +void MainWindow::renderComplete(FrameBuffer *buffer) { Request *request; { @@ -772,6 +772,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 79723256..22c85247 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -69,7 +69,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(); @@ -83,6 +83,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 Wed Aug 31 05:49: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: 17270 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 D9E2CC3272 for ; Wed, 31 Aug 2022 05:50:10 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9284061FC0; Wed, 31 Aug 2022 07:50:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661925010; bh=A9VDPAbsuWT4PSFI3gmdY8a8KPlIC/WDS7qw2qTMhWw=; 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=deeBSB8E3nEAoNWLE0Oy8DU6olr7uLiuyheOMYV0jcgDP75A6SeVEQeIaaqQWuxLt DSa83ApVlKtPsZYKrROy4WtdHeHk+tCbOBMEbY8esse6irUm3HWIL+PaqM0dgXus8V tmMmbmP2SfguEK/kpkvZE7kWAgEiX741WL9Uh/sqPvMUEZYpFlOCKWDQLIvJaBeagj ZTwBz1uvhTAJD42Nkpk3ezBPG5mRIzDnoJ+YVyZCYhzrUO/0raVylOhRZYa5INWOyR Gg6hzJPhHSkfUayFTdRwtiqsww0iAPsIEdrfqWj1Uei/Op8WbZWCIPoMtRWkM3ZCG0 dzRLFwtG+oucQ== Received: from mail-pl1-x62a.google.com (mail-pl1-x62a.google.com [IPv6:2607:f8b0:4864:20::62a]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 48CE561FBC for ; Wed, 31 Aug 2022 07:50:09 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="QrQlWXXE"; dkim-atps=neutral Received: by mail-pl1-x62a.google.com with SMTP id v5so6975835plo.9 for ; Tue, 30 Aug 2022 22:50:09 -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=7oZU/s9Vw1tSQFJ3JtJmVKSNaVPLKq0zm5Ljm6xj+b0=; b=QrQlWXXEeUVW793k2fq9uuQ9DCrMOQXfup1KNfcUv+NSZijKjFo7i8qLLLJPlUi+lB xblbIzGTm1JbraYRO93R4jb3NMkb7zyMzPUatbcJ4wMbX7rGebBnDOw3m0YffqdzSsor pH4blkAZQzGghe8FabNtcRVA83vrPoapGSswyYDpLqCvvN/DAYh9mfp+lshGcItvCufk yYDatk5AyDHdQVwzla0Yxno8FA90ZouMZhWfUL9z4mB5jzuj0lkFymiG8cWO8XB9Oden 33fPXhXaZJ1SUEj7f8gsHIA/HMRK+0u6sbCZDpwgHAaQ/5uozFIzYx1M2Q6Ug+CbAy0e RO5Q== 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=7oZU/s9Vw1tSQFJ3JtJmVKSNaVPLKq0zm5Ljm6xj+b0=; b=sOjSvqgR31ck/Ut7YSYdmMGVuEhybw335FwVCKaT6aPPw4mSUoAbU1OOgd4nJJHnAz SmUq6ELHUqmsRGz0CfpKwdnxUCQC2mEOwO+jvmZJLAvb47iP4Fu6Cc/0eZ+bEAcbkVvI 6MqGsgDS8Z9wUfzC+LwC7/tDlrleju7fN6Znzg5nTFkbq79msAK4Ra228qo9fEknL6IO TZQCwCrzTFi3y/dsE0WA0Xu6nazOhhfFWXwXfMRMAzWIP4DYvrLT+NCDw4uo9sMqVIC7 xF6n+dEaOHkrvc6Y/hL5Jbz78Wie59+aN2CUWYOwRbXBUBN8PCGbueiw2ynAS0SenH/H X+lw== X-Gm-Message-State: ACgBeo21TWoWvNveWVWf+S9lBPV7WLACgtnFxA/H3eLQx32gshhMOt5T 52U5In5GCXTFcPiHX5VHbcvoOFX756Y= X-Google-Smtp-Source: AA6agR6BRxXCjD9zDkfwqlkQx5qThUjIu0r73f7Xucc2bNvalQL5R5Yr5Yhz5Wxod4qhIUUBXUKCkw== X-Received: by 2002:a17:902:a60f:b0:172:e476:fde with SMTP id u15-20020a170902a60f00b00172e4760fdemr24122143plq.104.1661925007485; Tue, 30 Aug 2022 22:50:07 -0700 (PDT) Received: from devut-HP-Laptop-14q-cs0xxx.. ([103.36.82.122]) by smtp.gmail.com with ESMTPSA id q19-20020aa79833000000b00537eacc8fa6sm8307333pfl.40.2022.08.30.22.50.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Aug 2022 22:50:07 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 31 Aug 2022 11:19:37 +0530 Message-Id: <20220831054938.21617-7-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831054938.21617-1-utkarsh02t@gmail.com> References: <20220831054938.21617-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v9 6/7] 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" Display a QLabel which is readonly, and displays the currently selected capture script. The tooltip of the QLabel displays the file path of the script. Implement a capture script button which is a QToolButton which when clicked opens a QFileDialog this allows to select a capture script (*.yaml) file. Next to the capture scipt button, show a QToolButton which stops the capture script. If an invalid script has been selected show a QMesssageBox::critical and continue with the capture's previous state. Introduce a queueCount_ to keep track of the requests queued. When stopping the execution of the capture script the queueCount_ is not reset and the capture continues as it is (i.e it is not stopped or restarted). Requests are queued with any controls the script matching the current queueCount_. Reviewed-by: Kieran Bingham --- Differnce from v8: 1. Now display a QLabel with the fileName and filePath with button on the side. 2. infromScriptReset() informScriptRunning() are removed 3. Local script makes handling of invalid scripts easy. src/qcam/assets/feathericons/feathericons.qrc | 2 + src/qcam/cam_select_dialog.cpp | 88 ++++++++++++++++++- src/qcam/cam_select_dialog.h | 20 ++++- src/qcam/main_window.cpp | 67 +++++++++++++- src/qcam/main_window.h | 7 ++ src/qcam/meson.build | 2 + 6 files changed, 181 insertions(+), 5 deletions(-) diff --git a/src/qcam/assets/feathericons/feathericons.qrc b/src/qcam/assets/feathericons/feathericons.qrc index c5302040..0ea0c2d5 100644 --- a/src/qcam/assets/feathericons/feathericons.qrc +++ b/src/qcam/assets/feathericons/feathericons.qrc @@ -3,7 +3,9 @@ aperture.svg camera-off.svg + delete.svg play-circle.svg + upload.svg save.svg stop-circle.svg x-circle.svg diff --git a/src/qcam/cam_select_dialog.cpp b/src/qcam/cam_select_dialog.cpp index 6543228a..99405cc1 100644 --- a/src/qcam/cam_select_dialog.cpp +++ b/src/qcam/cam_select_dialog.cpp @@ -14,13 +14,18 @@ #include #include +#include #include +#include +#include #include #include +#include +#include CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManager, - QWidget *parent) - : QDialog(parent), cm_(cameraManager) + std::string scriptPath, QWidget *parent) + : QDialog(parent), cm_(cameraManager), scriptPath_(scriptPath) { /* Use a QFormLayout for the dialog. */ QFormLayout *layout = new QFormLayout(this); @@ -38,6 +43,41 @@ CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManag connect(cameraIdComboBox_, &QComboBox::currentTextChanged, this, &CameraSelectorDialog::updateCamInfo); + /* Set capture script selection / removal button. */ + QWidget *captureWidget = new QWidget(this); + QHBoxLayout *captureLayout = new QHBoxLayout(captureWidget); + + scriptFileLine_ = new QLabel; + scriptFileLine_->setFrameStyle(QFrame::Sunken | QFrame::StyledPanel); + + chooseCaptureScriptButton_ = new QToolButton; + chooseCaptureScriptButton_->setIcon(QIcon::fromTheme("document-open", + QIcon(":upload.svg"))); + chooseCaptureScriptButton_->setStyleSheet("border:none"); + connect(chooseCaptureScriptButton_, &QToolButton::clicked, + this, &CameraSelectorDialog::selectCaptureScript); + + QToolButton *stopCaptureScriptButton = new QToolButton; + stopCaptureScriptButton->setIcon(QIcon::fromTheme("edit-clear", + QIcon(":delete.svg"))); + stopCaptureScriptButton->setStyleSheet("border:node;"); + connect(stopCaptureScriptButton, &QToolButton::clicked, + this, &CameraSelectorDialog::resetCaptureScript); + + captureLayout->addWidget(scriptFileLine_); + captureLayout->addWidget(chooseCaptureScriptButton_); + captureLayout->addWidget(stopCaptureScriptButton); + captureLayout->setMargin(0); + + /* Set the file name of the capture script. */ + if (scriptPath_.empty()) { + scriptFileLine_->setText("No File Selected"); + } else { + scriptFileInfo_.setFile(QString::fromStdString(scriptPath_)); + scriptFileLine_->setText(scriptFileInfo_.fileName()); + scriptFileLine_->setToolTip(scriptFileInfo_.filePath()); + } + /* Setup the QDialogButton Box */ QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | @@ -52,6 +92,7 @@ CameraSelectorDialog::CameraSelectorDialog(libcamera::CameraManager *cameraManag layout->addRow("Camera:", cameraIdComboBox_); layout->addRow("Location:", cameraLocation_); layout->addRow("Model:", cameraModel_); + layout->addRow("Capture Script:", captureWidget); layout->addWidget(buttonBox); } @@ -110,3 +151,46 @@ void CameraSelectorDialog::updateCamInfo(QString cameraId) cameraModel_->setText(QString::fromStdString(model)); } + +/* Capture script support. */ +void CameraSelectorDialog::selectCaptureScript() +{ + selectedScriptPath_ = QFileDialog::getOpenFileName(this, + "Run Capture Script", QDir::currentPath(), + "Capture Script (*.yaml)") + .toStdString(); + + if (!selectedScriptPath_.empty()) { + scriptFileInfo_.setFile(QString::fromStdString(selectedScriptPath_)); + scriptFileLine_->setText(scriptFileInfo_.fileName()); + scriptFileLine_->setToolTip(scriptFileInfo_.filePath()); + } else { + selectedScriptPath_ = scriptPath_; + } +} + +void CameraSelectorDialog::resetCaptureScript() +{ + Q_EMIT stopCaptureScript(); + scriptPath_.clear(); + selectedScriptPath_.clear(); + scriptFileLine_->setText("No File Selected"); +} + +void CameraSelectorDialog::accept() +{ + scriptPath_ = selectedScriptPath_; + QDialog::accept(); +} + +void CameraSelectorDialog::reject() +{ + if (scriptPath_.empty()) { + scriptFileLine_->setText("No File Selected"); + } else { + scriptFileInfo_.setFile(QString::fromStdString(scriptPath_)); + scriptFileLine_->setText(scriptFileInfo_.fileName()); + scriptFileLine_->setToolTip(scriptFileInfo_.filePath()); + } + QDialog::reject(); +} diff --git a/src/qcam/cam_select_dialog.h b/src/qcam/cam_select_dialog.h index c91b7ebe..377faebc 100644 --- a/src/qcam/cam_select_dialog.h +++ b/src/qcam/cam_select_dialog.h @@ -15,21 +15,24 @@ #include #include +#include #include class QComboBox; class QLabel; +class QToolButton; class CameraSelectorDialog : public QDialog { Q_OBJECT public: CameraSelectorDialog(libcamera::CameraManager *cameraManager, - QWidget *parent); + std::string scriptPath, QWidget *parent); ~CameraSelectorDialog(); std::string getCameraId(); + std::string getCaptureScript() { return scriptPath_; }; /* Hotplug / Unplug Support. */ void addCamera(QString cameraId); @@ -38,11 +41,26 @@ public: /* Camera Information */ void updateCamInfo(QString cameraId); + /* Capture script support. */ + void selectCaptureScript(); + void resetCaptureScript(); + + void accept() override; + void reject() override; + +Q_SIGNALS: + void stopCaptureScript(); + private: libcamera::CameraManager *cm_; + std::string scriptPath_; + std::string selectedScriptPath_; + QFileInfo scriptFileInfo_; /* UI elements. */ QComboBox *cameraIdComboBox_; QLabel *cameraLocation_; QLabel *cameraModel_; + QLabel *scriptFileLine_; + QToolButton *chooseCaptureScriptButton_; }; diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 2a9ca830..af992b94 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -143,7 +145,9 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) cm_->cameraAdded.connect(this, &MainWindow::addCamera); cm_->cameraRemoved.connect(this, &MainWindow::removeCamera); - cameraSelectorDialog_ = new CameraSelectorDialog(cm_, this); + cameraSelectorDialog_ = new CameraSelectorDialog(cm_, scriptPath_, this); + connect(cameraSelectorDialog_, &CameraSelectorDialog::stopCaptureScript, + this, &MainWindow::stopCaptureScript); /* Open the camera and start capture. */ ret = openCamera(); @@ -152,6 +156,10 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) return; } + /* Start capture script. */ + if (!scriptPath_.empty()) + ret = loadCaptureScript(); + startStopAction_->setChecked(true); } @@ -266,8 +274,11 @@ void MainWindow::switchCamera() if (newCameraId.empty()) return; - if (camera_ && newCameraId == camera_->id()) + if (camera_ && newCameraId == camera_->id()) { + // When user opens camera selection dialog for CaptureScript selection + loadCaptureScript(); return; + } const std::shared_ptr &cam = cm_->get(newCameraId); @@ -287,17 +298,63 @@ void MainWindow::switchCamera() camera_->release(); camera_ = cam; + loadCaptureScript(); + startStopAction_->setChecked(true); /* Display the current cameraId in the toolbar .*/ cameraSelectButton_->setText(QString::fromStdString(newCameraId)); } +void MainWindow::stopCaptureScript() +{ + if (script_) + script_.reset(); +} +/** + * \brief Loads and validates the current capture script + * + * returns -EINVAL on failure and 0 on success + */ +int MainWindow::loadCaptureScript() +{ + if (scriptPath_.empty() || camera_ == nullptr) + return -EINVAL; + + auto script = std::make_unique(camera_, scriptPath_); + + if (!script->valid()) { + script.reset(); + + QMessageBox::critical(this, "Invalid Script", + "Couldn't load the capture script"); + + return -EINVAL; + } + + /* + * If we are already capturing, stop so we don't have stuck image + * in viewfinder. + */ + bool wasCapturing = isCapturing_; + if (isCapturing_) + toggleCapture(false); + + script_ = std::move(script); + + /* Start capture again if we were capturing before. */ + if (wasCapturing) + toggleCapture(true); + return 0; +} + std::string MainWindow::chooseCamera() { if (cameraSelectorDialog_->exec() != QDialog::Accepted) return std::string(); + scriptPath_ = cameraSelectorDialog_->getCaptureScript(); + return cameraSelectorDialog_->getCameraId(); } @@ -499,6 +556,7 @@ int MainWindow::startCapture() previousFrames_ = 0; framesCaptured_ = 0; lastBufferTime_ = 0; + queueCount_ = 0; ret = camera_->start(); if (ret) { @@ -777,5 +835,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 22c85247..7c877ae1 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -27,6 +27,7 @@ #include #include +#include "../cam/capture_script.h" #include "../cam/stream_options.h" #include "viewfinder.h" @@ -89,6 +90,9 @@ private: void processHotplug(HotplugEvent *e); void processViewfinder(libcamera::FrameBuffer *buffer); + int loadCaptureScript(); + void stopCaptureScript(); + /* UI elements */ QToolBar *toolbar_; QAction *startStopAction_; @@ -129,6 +133,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 Wed Aug 31 05:49: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: 17271 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 7D66CC3272 for ; Wed, 31 Aug 2022 05:50:13 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 361A861FCE; Wed, 31 Aug 2022 07:50:13 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1661925013; bh=sfCzj5KVEAzrKNuGbN4WwAUaNUY/CmOphjxwj3CPXOI=; 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=fQh5hiYdG321ijvfr9jqZGmmeWcXBcvs5g82gEQdG4qrISfWz9HTvAUaHyhj0sY6F K1JRHvlFv920dKkx9P9BRv5jM/oQ3ijrdM1epY4yh4aSfW739tnV+DPZiDz4YuAK1N OneDlpXeFMfWykrj5iBT8pB1JszmKu9mB6bdYqvPTOINCDt1F4+Md+i2SQSxFJtjWp GuIOf96mEsPTOhvV3BcjEIayGEQyZ8fytSxns7r4s3Ry8DhZm5FMHUkhkYJjrz4dth 37beAAVYaigKh8cNBcoJfCx8GIZu6uQ1nIURCrThxwCws/0F3zEIiG6wgInPlnuTnq lBCTsQoZM6Whw== Received: from mail-pj1-x1035.google.com (mail-pj1-x1035.google.com [IPv6:2607:f8b0:4864:20::1035]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 3E23F61FBC for ; Wed, 31 Aug 2022 07:50:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="HAOrPXQA"; dkim-atps=neutral Received: by mail-pj1-x1035.google.com with SMTP id w88-20020a17090a6be100b001fbb0f0b013so13967228pjj.5 for ; Tue, 30 Aug 2022 22:50:12 -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=qi9RfznzV8BFNNvtVx87j3wkZRX+zAexw9WtM1zCQ94=; b=HAOrPXQA/Yxll96GqY5xcM7YQ3Zg/kXbRI6QSVw6UuX4TJPacU2je0Y146fzt39N9D F73PuNxb/WLNxPHmFztqnOgDKbn8zrQHj2gsymp3G+95xqug3aNei8njF0IxWmMmXTM1 kzHEns67ETsgzBQtT4rUEq1XTLgEylTmgKpUTagkZX5qTMXKsE8QugXAs/Ct//6d1tUW mb4YUTihsBZZVrM7JNup7ieMmfiRm0/Ya8K/v0ERlH346Or0/qZRyvDS4xLhKNFTFIIi T9Y1h05ZPhuVQ0hdwj1rxzqTj8ClI07W734GYwL9z4oyy4QGTDQ3d7B5AzIMz+psOhQh JgeA== 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=qi9RfznzV8BFNNvtVx87j3wkZRX+zAexw9WtM1zCQ94=; b=TH/8HTk0jb4Xu7ufUBYr0sHitt6B3iTYT0kE6u/zWnbxPPsL+xKIpZGx0od5TFU6qR peIaW/hpSK+abGW/zZXBoyosa26ILX3EtywE2bTuTvP93ItzQiYf5UZeNPlrrBH4lp+T 5pg0xKSGh53TaCSrrXA4dQBIVjUItjzjkwZNMjkYPyZXx6YcFOw2gx03OcOB/DRL0CyS ixdu8av8pUQNjVsLMNom/ov2ieg4wkby5ef4Z9hI0SgcQ+8P1U9JQA3UeXv7y1YWnbn1 ++/CvGkBH3agT84W/bvttl2MQKJuNwP2LrKL0nzXHht4DfW+Ri8k+GmRewUremapK78g ps+Q== X-Gm-Message-State: ACgBeo0eQa04YAPSV0Uwr/50Hhio4W2b2o2RIGcJrPdAmEKf47hIo9xD kKXyqHL73hXzTTuoyAoXg+E5Ld/DKEc= X-Google-Smtp-Source: AA6agR4f2EGeNST++y+3++x4pJHSS/oN3wHuYpSI/n7thuzuGtqMcmPNprB50QeY8TWBx87IGy1xuA== X-Received: by 2002:a17:90a:8a90:b0:1fd:bf26:58fb with SMTP id x16-20020a17090a8a9000b001fdbf2658fbmr1575704pjn.91.1661925010628; Tue, 30 Aug 2022 22:50:10 -0700 (PDT) Received: from devut-HP-Laptop-14q-cs0xxx.. ([103.36.82.122]) by smtp.gmail.com with ESMTPSA id q19-20020aa79833000000b00537eacc8fa6sm8307333pfl.40.2022.08.30.22.50.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 30 Aug 2022 22:50:10 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 31 Aug 2022 11:19:38 +0530 Message-Id: <20220831054938.21617-8-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220831054938.21617-1-utkarsh02t@gmail.com> References: <20220831054938.21617-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v9 7/7] 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. --- Differences from v8: 1. Functionally the patch remains same. 2. The difference is that checking for OptCaptureScript is now done in MainWindow::MainWindow() src/qcam/main.cpp | 3 +++ src/qcam/main_window.cpp | 11 +++++++++-- src/qcam/main_window.h | 1 + 3 files changed, 13 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 af992b94..e488b67f 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -145,6 +145,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(); + cameraSelectorDialog_ = new CameraSelectorDialog(cm_, scriptPath_, this); connect(cameraSelectorDialog_, &CameraSelectorDialog::stopCaptureScript, this, &MainWindow::stopCaptureScript); @@ -157,9 +160,13 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) } /* Start capture script. */ - if (!scriptPath_.empty()) + if (!scriptPath_.empty()) { ret = loadCaptureScript(); - + if (options_.isSet(OptCaptureScript)) { + quit(); + return; + } + } startStopAction_->setChecked(true); } diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index 7c877ae1..24ebd019 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -45,6 +45,7 @@ enum { OptRenderer = 'r', OptStream = 's', OptVerbose = 'v', + OptCaptureScript = 256, }; class MainWindow : public QMainWindow