From patchwork Wed Aug 10 15:03: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: 17067 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 21D7CC3272 for ; Wed, 10 Aug 2022 15:04:02 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id D092063330; Wed, 10 Aug 2022 17:04:01 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660143841; bh=k1ygg5cAr3MHmyh7/K9n38RIh+/ZsJClzfGBFmKNHc4=; 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=iG9YSM2B7HetCGoqsi0rRCS/qf9b2G2wpIAeoVPSU2qQ49agzydpLOJeoypovra4t LSTNVUVPg/gIA/H00IQirEbqIirJU5hVkZbkLpNOawppDeklcy+xhSRwFeNFSnk3mh lRdCe6I0kuUEeU6PPqFm1C3KShgGLzPvF7rbBUqNpGof/Hhiwx22RZyvPhdfD8eyi2 2Z6+zgtodpgnCX4lb+iwW+Uv+rnKssVs91wPXczC7hHWZKbnLHrd6biasFbDOcrDss FXqqhvlWvLv08jX1Q1msVicb5DIawAc/57/eMjyFaPfMFidw1ZnLjPkmBdvSz4sVWu plyIjyK160dsw== 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 5B5676332C for ; Wed, 10 Aug 2022 17:03:59 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="ROzwz1dA"; dkim-atps=neutral Received: by mail-pg1-x530.google.com with SMTP id l64so14641199pge.0 for ; Wed, 10 Aug 2022 08:03: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=nTSKjqEoOIkLDAJNk+hwruS61OgtqBGKbBboEl9JhZc=; b=ROzwz1dAwnOLN/DuOGoH9imuw7ta3Xl7c0V167yOz5Us0ZdeJTzOtDrdq83boBXzcV BDgr59DAYxWmfWar04ked6E2+3MNLU8bvnQ2wuw8x/q95+pXjuXee+szhW7Zo6QKYBKO iSHGB+UKBiNlbadBfNRqVUmCO0V9f4k6FEebwo4ZiQIPTYbkZ48ZPZvyd0a8uomwAd/+ 54bK3fDG9vZOAyWEH1xvbnCCPGFFNqBVqYfSo50UGe+BUE6ZXRS5owrB5UDFm59V0DdW oRY3mfMfTbq4Uo5Mcj3qsnRY13Q4jvjwFtPoMnY5NqMYjVfQsyqb2U0a19zweM09hb9V 7gag== 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=nTSKjqEoOIkLDAJNk+hwruS61OgtqBGKbBboEl9JhZc=; b=polQDav8Oj6QU2ILIQFx2Kims9v4SabXMcCDbi0dpgP8dSTegQEyY6lYEqMpjed7Xw vWmVQyE++dkinxQJv+VoQWgTE8DwmdkTpoqsJ9sLOArLmFMS/JXbAOXKC5pEX7jimhkk Pf32NTkrOC3W/K7b+wpm0bocOrgZCDiqhbDj4K5OKlyUrXc2IJ9mhB1VBXYjoGkZEGxd SNcgiC6QlgFBFAY3KKg9nmRzjrY73p6ScLrDJoN4NCdDC/qBGCUVw9HbKgG2tzHYa1Df aKV20Gmey8FZY2MsvePKrVgSFsK69jwHxIrBwueBibmHf22n4Yn1w6BrCv2oYBCshiFl Szsw== X-Gm-Message-State: ACgBeo3JxerEu6WJYr4sPDP+YyCTivvYq77cQO1jTshYjvtPnbNjZjkn YxXzITCbnL2csXBYCYWfNVSS2efPvUI= X-Google-Smtp-Source: AA6agR4utrwDXyXtJVov/NkofvwP2GWKIqT5Y3NCZNtfb+FZJZMQJo43ARjsL94S5fC/0y23FiTUdQ== X-Received: by 2002:a05:6a00:cc1:b0:52d:a29d:fb1 with SMTP id b1-20020a056a000cc100b0052da29d0fb1mr27805499pfv.56.1660143837456; Wed, 10 Aug 2022 08:03:57 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2a55:4cae:bf8f:f4ed]) by smtp.gmail.com with ESMTPSA id b3-20020a1709027e0300b0016f1319d2a7sm12882624plm.297.2022.08.10.08.03.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Aug 2022 08:03:57 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 20:33:42 +0530 Message-Id: <20220810150349.414043-2-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220810150349.414043-1-utkarsh02t@gmail.com> References: <20220810150349.414043-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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. 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 by the console. Signed-off-by: Utkarsh Tiwari Reviewed-by: Kieran Bingham Reviewed-by: Laurent Pinchart --- Difference from v7: 1. Updated the commit message to inform of the behavioural change in selecting the first camera. src/qcam/cam_select_dialog.cpp | 51 ++++++++++++++++++++++++++++++++++ src/qcam/cam_select_dialog.h | 34 +++++++++++++++++++++++ src/qcam/main_window.cpp | 44 +++++++++++------------------ src/qcam/main_window.h | 3 ++ src/qcam/meson.build | 2 ++ 5 files changed, 106 insertions(+), 28 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..5544f49a --- /dev/null +++ b/src/qcam/cam_select_dialog.h @@ -0,0 +1,34 @@ +/* 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 + +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..e794221a 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" @@ -97,8 +97,8 @@ private: }; MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) - : saveRaw_(nullptr), options_(options), cm_(cm), allocator_(nullptr), - isCapturing_(false), captureRaw_(false) + : saveRaw_(nullptr), cameraSelectorDialog_(nullptr), options_(options), + cm_(cm), allocator_(nullptr), isCapturing_(false), captureRaw_(false) { int ret; @@ -290,38 +290,26 @@ 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, only the first time. */ + if (!cameraSelectorDialog_) + 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..4ad5e6e9 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -28,6 +28,7 @@ #include "../cam/stream_options.h" +#include "cam_select_dialog.h" #include "viewfinder.h" class QAction; @@ -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 10 15:03:43 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17068 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 62221C3272 for ; Wed, 10 Aug 2022 15:04:03 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 781926332C; Wed, 10 Aug 2022 17:04:02 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660143842; bh=a6AwtFQ3QrVrUPnhwmhPFs0L5JDLFHpteCPdPaZ6JNg=; 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=b6fLXWjej3k40xaG6ipmdRvb5zZok4T0FPlfBnkmcbeueKdp7sqi6zCyiIIePkH01 sjr454s5Dmlpa8teGyjt6SvmGTJSOm+vZ8ei0hIIUCAANxXxMVsaNxzP4mGGKZX4Fm 6xyVsn50dzli2U22xMFZXP91yFhZeRZs7Aoyd7/woSy8JQotq0QOae2gpl63cIIcOZ aGtSTPTidlD6lX+DNgXw9mJ384mm3AYnlH8iZelU7IWaBM6wEwTAbKYzH/wl9AOUQE jgPTpeu5/b2879R2yeeaLXq2b34A/yRVXVl9o+alU/UZacpMw8n3BgDZCVoITp4ci/ OcClCeOGY1W8Q== Received: from mail-pf1-x429.google.com (mail-pf1-x429.google.com [IPv6:2607:f8b0:4864:20::429]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 0206A63328 for ; Wed, 10 Aug 2022 17:04:01 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="pSWLGJJ4"; dkim-atps=neutral Received: by mail-pf1-x429.google.com with SMTP id u133so13933069pfc.10 for ; Wed, 10 Aug 2022 08:04: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=kvufxfZHW8jFx4wZYakmIfbO7HxI/zGP6BLC7jNXmrs=; b=pSWLGJJ4e4geNPryAV2dwBatxEftailbcpjpshC26dazVDCxp2Zddd6z0XG1QKiuJo IKRG+gJ5suKhQgqbAmnkZLVmwCe0SwBegMPemTyS8MzWeW9HzCo1CRWrhqkxuRDyiiIN 6FYzMIR+rJ1XFJQPz+WqZhRzn7LTEk4h32eK0S5elrl35QRF9d2LzWLGPk0fgEpgNLT6 ZQto+aOhH/oqyzP1Cbua1/SvSulx5aYh6FwxV2Xom+NBXNB8zXlfHgMKvUm/JyJ3qs33 8GmhUueIabmJcxwJOfDtHHx7WTUNGDMGYXwwj8KDEivEjfvqfTm/P3+EnYMx4yLoQxi8 /P2g== 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=kvufxfZHW8jFx4wZYakmIfbO7HxI/zGP6BLC7jNXmrs=; b=JRErbSRWsN+Y+/dOiZ2GlgXcaXzWSTjnzpdu8jRAIGi6F6wxO7L0jHWC5+HUMXSuGZ H/R2FsgTaaXomU5V9wPOjtzMlsFl5pq8GznF5fkLkxaH4FziTtJhd41VXImyrLGggnVp gJ2Sk2r5IBc9Yn/wwKxVAFmevkS3fNCFHncMsnXK+QxOjywilHux8mRtF7XVAWYS0c3u x8zCTeyJ9Qzfdt4gJzkCHrTktLgBNoCrl4NbhXhunXPls1JEFT7cJlq21vIB7f/2nYZ0 eA9jusdXk5GYLjVkJR/PrZeNFwuI5HO12gayizEnykm93skoyOxuwITgsy+tX8iNshdw lmdg== X-Gm-Message-State: ACgBeo1Ffmzo7vIDcrzIVGEe+aDrHHa5ILPIl3Yl8bSTk/diJzkf1Jp1 tJPh0niRvoWx97wZ/K3V+3kYX2NhDv0= X-Google-Smtp-Source: AA6agR5Y6PDit0QuxTah73xhgHw4zfTrP80aptT50jsG/OMxdHQvfqvWG3IDTGyHguL7EfpoUWK7hg== X-Received: by 2002:a05:6a00:1d84:b0:52f:4a8f:7381 with SMTP id z4-20020a056a001d8400b0052f4a8f7381mr14445905pfw.52.1660143839389; Wed, 10 Aug 2022 08:03:59 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2a55:4cae:bf8f:f4ed]) by smtp.gmail.com with ESMTPSA id b3-20020a1709027e0300b0016f1319d2a7sm12882624plm.297.2022.08.10.08.03.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Aug 2022 08:03:59 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 20:33:43 +0530 Message-Id: <20220810150349.414043-3-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220810150349.414043-1-utkarsh02t@gmail.com> References: <20220810150349.414043-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 Reviewed-by: Laurent Pinchart --- Difference from v7: 1. Nothing 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 5544f49a..04c71fd8 100644 --- a/src/qcam/cam_select_dialog.h +++ b/src/qcam/cam_select_dialog.h @@ -26,6 +26,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 e794221a..9ec94708 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -594,6 +594,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()) { @@ -605,6 +607,8 @@ void MainWindow::processHotplug(HotplugEvent *e) int camIndex = cameraCombo_->findText(QString::fromStdString(camera->id())); cameraCombo_->removeItem(camIndex); + + cameraSelectorDialog_->cameraRemoved(camera); } } From patchwork Wed Aug 10 15:03:44 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17069 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 2771BC3272 for ; Wed, 10 Aug 2022 15:04:06 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B27AB63335; Wed, 10 Aug 2022 17:04:05 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660143845; bh=Wch9S/K/rq7sqVEfWKmqaA/Tk9UfQePdXxaS0+8gKDc=; 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=31X+83DMjEjFBv1euaGEC+GK/KB4WeQuQ8SXZoSNj64onURqMfHkHMzlP9rrqv3qw UNva2JnJl7jHHQTc2ZBgP4X08QsnOf05i3vd3yMcKAw8JtJr5/3FMpOo9ypstEgdBD GoKodLEbIzHIskZbRBAIa6IbP52IDOji1dRjjw78jW4ghd32+0ryuLIsom8m0wm4Km JsYSPvKkIX1ePmmN+sNRO73sbJhmmddZ5N3ZbzMrzlGPUHMTcEg/Kadju/xy4CtkWr w0PNMHgPPoZrzFQwY2A2n4UPzMdnxT5UX6Z9SJKjhl8X7qZ2VXd8Z1wIdesRgxQ1Ig ye4yd8WUHJtTw== 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 8124763333 for ; Wed, 10 Aug 2022 17:04:02 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="YHXSJO7A"; dkim-atps=neutral Received: by mail-pg1-x530.google.com with SMTP id l64so14641391pge.0 for ; Wed, 10 Aug 2022 08:04: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=9iwKcpTOSLNqoHIQa8Jl32eZDEficXvu3/ctjnyaBtA=; b=YHXSJO7AjvZ7Qrh3AxnTRk66WXX+hhmOKxOtqtOFrWmC7pu2zXGVR/cNDuhX4pvf0i un1HeiQ6CTAGjHcBU2XebyjklwCiZOMko7uMs0Zsl+YYJervrKB0zMGwby8g9ntaNSRb lQkSoEh5BgIPgo0BegGkj0UCkXufXOtA0Vumf4kPe5eI3kYARTX3vk/678hNNdR+WCHN yrY25M1DczGZQV8S/iVSkMXfo9AfqzKClFYVDeAg+OiLPgFzYbcF+fjXi8rulJ1EvMgt jpwJpJUTbCA3pBNxbCh11oVQyZ7TPqAjAcoz8XLY1KBAtA7Iuf1uamxErduoe+xS92lb eJFQ== 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=9iwKcpTOSLNqoHIQa8Jl32eZDEficXvu3/ctjnyaBtA=; b=qRL7d1DCuAJ3JfIaMWGV3GWlClLnDHbIvK+Z3LxwJEAVporyudE4dxTpbjqzUfYwpi oRWD5IqpERpddsCCIsmHWf6MtycrikHlOvv9JI+KxIfzeAt+uyDhggV5xg1X4xR0iJWu 0qJ8yNfbIJWwJ3HG5lAzkYoPbyuJIvN/ULi4JJojKZ9auppVoF6SF7bG9+G7Omq8cFMg 0dNSPg6uyds7A60tuM7G2cn4iR+ty/qL2YLGW7Ec7Wls49/572ieHo/twUxoq8F/q0OO rq+5QXLnsXUOpawRUsUzFJoBCdiEIaTmmG6Xd5n3nOrQDD0QqN6kLfK/Rb9BqIaJ4sT8 z03w== X-Gm-Message-State: ACgBeo0fGdmM4kkWYs6aHk2bZjw5MmWIsSP2VHsXFj8SSmPzilLZ9kS5 nJCREwbiJh74nqfK8AhzQd88Eo5Oveo= X-Google-Smtp-Source: AA6agR4DwaF7NWYxCG2ZcBGiF3W3r65OCTTF/yZnNwyPNNVAWZ/ugeCS5TZZCOOt4sUOh4CH+QmKPg== X-Received: by 2002:a05:6a00:9a7:b0:52d:bbf9:c3d5 with SMTP id u39-20020a056a0009a700b0052dbbf9c3d5mr27987008pfg.9.1660143841722; Wed, 10 Aug 2022 08:04:01 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2a55:4cae:bf8f:f4ed]) by smtp.gmail.com with ESMTPSA id b3-20020a1709027e0300b0016f1319d2a7sm12882624plm.297.2022.08.10.08.03.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Aug 2022 08:04:01 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 20:33:44 +0530 Message-Id: <20220810150349.414043-4-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220810150349.414043-1-utkarsh02t@gmail.com> References: <20220810150349.414043-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 Reviewed-by: Laurent Pinchart --- Difference from v7: 1. Moved firstCameraSelect_ from 8/8 to here because if we were previously supplied camera id on the cmdline we always used that and sdisabled the showing of the dialog src/qcam/main_window.cpp | 51 ++++++++++++++++++++-------------------- src/qcam/main_window.h | 6 +++-- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 9ec94708..d1b8d2dd 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -98,7 +98,8 @@ private: MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) : saveRaw_(nullptr), cameraSelectorDialog_(nullptr), options_(options), - cm_(cm), allocator_(nullptr), isCapturing_(false), captureRaw_(false) + cm_(cm), allocator_(nullptr), isCapturing_(false), captureRaw_(false), + firstCameraSelect_(true) { int ret; @@ -193,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(); @@ -260,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(); @@ -298,12 +300,17 @@ 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) - 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(); } @@ -327,8 +334,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; } @@ -592,22 +599,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 4ad5e6e9..f9ea8bd3 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_; @@ -116,6 +117,7 @@ private: /* Capture state, buffers queue and statistics */ bool isCapturing_; bool captureRaw_; + bool firstCameraSelect_; libcamera::Stream *vfStream_; libcamera::Stream *rawStream_; std::map> freeBuffers_; From patchwork Wed Aug 10 15:03:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17070 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 8D4B3C3272 for ; Wed, 10 Aug 2022 15:04:07 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 5221063337; Wed, 10 Aug 2022 17:04:07 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660143847; bh=tSkV38layzPywD5+leW5gky6c211YBGtMOIU/YmxMJw=; 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=J5RLB16WcvEzy5LMj8mMXKFz3sy8EMrGxl1H5xo097id7+5xWA7IEDTnzv9cvaUgH A16BPJ/DxqI8bwG5mi5Zb3CTuMMIlMendPMjMEjuKrjf5svTEbILFhj7/Crw19RByc 7eMPuxEzsJLowGiZIRtu/K8MozgtrtmZXzLrik+ENfsYc+FGTYLqXnKz6lFKwbmKTs 4eE5BoNRtn4cQfzNhN7FY8FfnSBCsltsYcHlTuTMCyRnRS3T1+4NdQR1SpfFg+McXH 0rXp/JbNCRcMSFCM0I9CuUhfpaAqIhzwQqneP7GwJWY3AOn5Jcpc8luRtoq8RdhH2X si1McCRYTz4yg== Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 6AB56600EA for ; Wed, 10 Aug 2022 17:04:05 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ubfd9Qgy"; dkim-atps=neutral Received: by mail-pj1-x102c.google.com with SMTP id e8-20020a17090a280800b001f2fef7886eso2385362pjd.3 for ; Wed, 10 Aug 2022 08:04:05 -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=yPqc+syOGhMuqA0QCVsz3uFjAHkQ3W7uVeQQ/RZBUUA=; b=Ubfd9QgyD17IQsFF7t5fGWP23wFPZINsEtZEQXLE+PBKtx5PEG0Tf34vtVzMF4LpxF sf9iy3BuNFxFqcwnAyNYKnM05eQaeOHQmOTZHLobjntElv0+ZAJLhREEshIgpL2b8JKu Oz4B96EFmrB56ud8WrhFAIed9lJlmEohjUADkH2bYdwxT0zZSbwdiUV4+6QyPFpB+Xh+ tsR3qgFPtr/3jq9FrNvcerc+dNjsKXQmBIxJ1hz0BzlKOjHIK0cOeUJt9FNEM4OWsOLs GJiCrqBvUeDsEB5BFi2VLbsk/4K/6iso28l455dqxzzwnoYdokUKgeNrcPiEALDUVlBG P5Kw== 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=yPqc+syOGhMuqA0QCVsz3uFjAHkQ3W7uVeQQ/RZBUUA=; b=AJCtnVu4RZDTNOwUlF4ImXGPIdOK8W/YrP3y+AFWD6hIW0Hp4eqh3mzmCaL/1zlVDX R3G8H2yTc23aLSRWimmHDOfIuAD+bIoqPgwPlNoBcPcx4Xpy7zmQw03OkIfjLsv4DCzg Loi9qdeTGsh2bQ+x71S2N+JTsI53v7JrmfWYBSORGNo+/zfDUBQi9h8UlWEzwAtokqN+ rSqxLV6SeU2ChBsHy8fOgQLbdaIO5IySEs6FXgl4O/F3RtjY5Kit0yp9A/OwtwebrD+P /dchboIzL922TI5HUWM7wMYr4Xy+FWZlKc84ZSR3iW+xeEbiIMEhPNOodhHTHO6syMoT iBbg== X-Gm-Message-State: ACgBeo26qL2kJUdtfWuHw+CpsQPELasnc+7Soqie7d7gPrtkiQ7mjUd4 7aMHvFZ9RTJIXi/8Ofd5EjTp4zASNuY= X-Google-Smtp-Source: AA6agR40B/UOntW5AeWAFN0kIbHN8zph+pR6mwgPMmTtJDn4DiyLBmWrjMMN6VL07rWOMQPPPAf1lQ== X-Received: by 2002:a17:90a:fa91:b0:1f5:1f52:a2ba with SMTP id cu17-20020a17090afa9100b001f51f52a2bamr4135279pjb.16.1660143843741; Wed, 10 Aug 2022 08:04:03 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2a55:4cae:bf8f:f4ed]) by smtp.gmail.com with ESMTPSA id b3-20020a1709027e0300b0016f1319d2a7sm12882624plm.297.2022.08.10.08.04.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Aug 2022 08:04:03 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 20:33:45 +0530 Message-Id: <20220810150349.414043-5-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220810150349.414043-1-utkarsh02t@gmail.com> References: <20220810150349.414043-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 from v7: 1. Nothing 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 04c71fd8..16475af6 100644 --- a/src/qcam/cam_select_dialog.h +++ b/src/qcam/cam_select_dialog.h @@ -11,9 +11,12 @@ #include #include +#include +#include #include #include +#include class CameraSelectorDialog : public QDialog { @@ -30,9 +33,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 Wed Aug 10 15:03:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17071 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 20681C3272 for ; Wed, 10 Aug 2022 15:04:11 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B66796333B; Wed, 10 Aug 2022 17:04:10 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660143850; bh=eMQ9fTcDsbdhogqD9GzzYdsP7fFmYYdw8BiNGR78NOQ=; 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=z91wrlZrFyKzjGrmEWiC0MreoolpuLDLcKdcCW6eAKpIs1kSGBOdXnqspxgLMMsr8 FFOalW28ZLFC4BG5QohI5+L3R48YhEedgpXtavRTbbqIcmDXcCMiDbZlQSq5kh7Kr1 lvMDrcCD2nqF6HSeR+C87Sql9rLM9NcLLvC+6FPw6bI4YaUayWquCgvi660xtocHa9 /Uyzclj29iCb4Y9HcLjHEvMgAtW+qiPCXc4xQ0tCfcZNGhWVXHzJADuSOgBuKm7Y5V UIjmyC2aLyjdVSu7G35HvfIwHXcSaQOI4UhvYXRKgUJQQIBIfSX5Ydzkt6L5N++LA3 V1EhozPegZNXg== Received: from mail-pj1-x102c.google.com (mail-pj1-x102c.google.com [IPv6:2607:f8b0:4864:20::102c]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 82C686332F for ; Wed, 10 Aug 2022 17:04:08 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="UWElb8oX"; dkim-atps=neutral Received: by mail-pj1-x102c.google.com with SMTP id t2-20020a17090a4e4200b001f21572f3a4so2417614pjl.0 for ; Wed, 10 Aug 2022 08:04:08 -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=nah3tKvUMmyz1awvcvaknd4JXs71eyge+DgPppV+IVA=; b=UWElb8oXNcTh/kt8skmCKYAnMPCNyNAhRYynNzJstps3OkjONlI2nKK7UvyaaMi1cq o1tckfPNTGKuuD4UgFLTwdAAuq34Vt3oz1yA97ZeaDcm7hac9gcRZCGNLADhPxtT64pz TxDBX6esrfFyApeyhBsuv34dv6sjFqRy1qFFj5XuXZPnI88DE/S93FahwbJlR2UoxOj8 LIz38yed4yK8Zum9P6NB1iyz8e/vKhCj3RSu53o5678UkFFAE4jbCGYOhpGBAuSY49JB z7prbLGo8eN7qUzuS8Ba+SiwMLe7aFQhcEAG7G6gWKnscLso9BZb2PK08SiV525af6im 8ouA== 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=nah3tKvUMmyz1awvcvaknd4JXs71eyge+DgPppV+IVA=; b=iBJ54U94gViO4ILnAtDSymC2GaAEiSENiuF3H2sPGDfzTnW5lujb8kmIHuipfn1vvJ n5Vx5TlBJCI4cK0OjZkXV5DnArnDaY5BeXvebop52IRCIjgD6Fn/+sxNuJzYdfoTxvNC EgYzXisKh20X25gFjMqdu/vU0a2CusiTYntt1+3uCocYXtDrHME/nb8wP9C4NLrP+nD2 1Sxoxws+S9yWB98/nzsZNwGakU9G7lOLu4u+Gys08BA8RG7WkAZSRCEMNEBdtQY2RrSw GkIQQlx/1QJB2tZ/w9SZAaBWgsczPAmobEZRjDpEkWTZFXvNRKcIzGiD7eFybJYkgWLM bqrw== X-Gm-Message-State: ACgBeo1D2DmDwDKoCU98fi9rMlp19W+KyYj3pxxkgkr4U3DU9jUH8fR3 89uB7PaxzNt9t8FM2AaeiY8Ofns5ZGU= X-Google-Smtp-Source: AA6agR6lrHDQyN5Pow4I0NESyCE6bDfs3qGCQMQKobdWLnhvkwcfPYFQQgXqM64DKZlLpepFcKSFrg== X-Received: by 2002:a17:90b:4b46:b0:1f7:2430:2286 with SMTP id mi6-20020a17090b4b4600b001f724302286mr4091340pjb.138.1660143846788; Wed, 10 Aug 2022 08:04:06 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2a55:4cae:bf8f:f4ed]) by smtp.gmail.com with ESMTPSA id b3-20020a1709027e0300b0016f1319d2a7sm12882624plm.297.2022.08.10.08.04.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Aug 2022 08:04:05 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 20:33:46 +0530 Message-Id: <20220810150349.414043-6-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220810150349.414043-1-utkarsh02t@gmail.com> References: <20220810150349.414043-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 --- Difference from v7: 1. Nothing (the only perfect patch) 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 d1b8d2dd..bf40572a 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -121,14 +121,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 @@ -517,7 +517,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; @@ -749,7 +749,7 @@ void MainWindow::processViewfinder(FrameBuffer *buffer) viewfinder_->render(buffer, mappedBuffers_[buffer].get()); } -void MainWindow::queueRequest(FrameBuffer *buffer) +void MainWindow::renderComplete(FrameBuffer *buffer) { Request *request; { @@ -778,6 +778,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 f9ea8bd3..d161365a 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 10 15:03:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17072 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 D10EFC3272 for ; Wed, 10 Aug 2022 15:04:12 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 9B25963339; Wed, 10 Aug 2022 17:04:12 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660143852; bh=upCoIlKlT5qp5pF9zmX7F8MyEgG7EXGLGtXNIVPP4js=; 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=qxqbbJHQgZhZzOsZ5Ve3dfXJKCPcXNVYKY0zFz5WH5/1IKAINAAIgz5nG6O2Ks+fw NFBCbJDwDRrnnIiq9wmAyVz4zwQiv55IVbxWKCMsvYNY6B9A2Zr4sFrwVtxEttU0nA KCvlrNMXRK40TWL8LD/xHhgn4PScx9UpPshm7KESlR8VvMP4MtVePnTFk4WZuAMo9J VgJU8iH3Q4MTBxR0ooF6y261ftCWBklSK+Z8tDAAhjo5nw2n/hpP6iKLL/4FJEar/W uPZlmc8pEXHw2k6IJ+QdkcmchxlMnBrrKdJUYNjKQpP5D/KZuox5nqT0CvoHaUdaML RIHViC8qdi5kg== 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 A14BF6333A for ; Wed, 10 Aug 2022 17:04:10 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Xcczk3j8"; dkim-atps=neutral Received: by mail-pg1-x536.google.com with SMTP id f65so14568088pgc.12 for ; Wed, 10 Aug 2022 08:04:10 -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=19kf8evk0yJiVwc4l+BQ3glXTE//vBYqtlQDA6iT9iQ=; b=Xcczk3j8do8Ouv1FnHaxf3LsrW8Jcy7R3ZfupUUWjA9yYUVPqbPd3c5EtPv/LSw8R6 tp+sGuNu+/fjLUAfK8yNerXAAsWtqBByvN2BQ363g65PQ1R3R9g3FmLVeS5QNkKvOPm/ hl192LWtkNwp5UWsfD0Z2x1fL8DRNs0wut6453N9QL3C7cdwM/n8S2YZvRI58xmNOgxw r4ly9rKj3BfBYc11D+0XQ0MmA75QOHSFYGlKIk6t84fkWtzNgcl6W6ub/5tdp24ihz61 8X4FpxoIsTNRTrdwO5hJ+mP8Enopz4r5ZdrqmJqokg8DGmyOl4FA25ZYcq8GvfNId+WA Xxrg== 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=19kf8evk0yJiVwc4l+BQ3glXTE//vBYqtlQDA6iT9iQ=; b=dRgfqys8GerFXjPXEEyj3pumrlyU1hmfjnttIG29K75AOy3Z+wU5ISpLiA+vIknBR4 vAXr2FYM4l71sPTJZLExcK02t//6jJG9mtVOGeYbSgg2Y1lkvh57xsyiO4lPI+q+4bBg XmVDNPxm1nSm5SN+Drns8R3ZiROMmN8cIqIZuPAcInQK0HO32qkmUbAfyAZ1cgyYfsL3 ptJzy+p7xvo9Jf3aL/EoGufFUklWFvFJX02CJwqXtPraL5xNA0miJ+bqC4YWjzWqabcQ uSeF/TkDXVTegNpbgHf6L6kHoSqkJFJLirlDLzAV69T2cEndf+kOP1oLgNYvzOZNtmDf o8RQ== X-Gm-Message-State: ACgBeo0QAKxPsN8EKnQqLT8GA2f80QE6teBWsgJjyfgWbKjgH06S2/mY qdcfJFjrS9w08NUGkFrYKBsdCD9Yo4U= X-Google-Smtp-Source: AA6agR52dU11VAbKLtRtPpGW2DBb9AXIDCzFxOBrvShFsw5FhiMA87Z0bpS8SSzIFkRu01H8xnPPIg== X-Received: by 2002:a62:1c04:0:b0:52e:d2b4:c029 with SMTP id c4-20020a621c04000000b0052ed2b4c029mr22847371pfc.60.1660143848887; Wed, 10 Aug 2022 08:04:08 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2a55:4cae:bf8f:f4ed]) by smtp.gmail.com with ESMTPSA id b3-20020a1709027e0300b0016f1319d2a7sm12882624plm.297.2022.08.10.08.04.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Aug 2022 08:04:08 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 20:33:47 +0530 Message-Id: <20220810150349.414043-7-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220810150349.414043-1-utkarsh02t@gmail.com> References: <20220810150349.414043-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 clicked in an open state, present the user with a QFileDialog to allow selecting 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 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_. Signed-off-by: Utkarsh Tiwari --- Difference from v7: 1. Fix grammetical errors in the commit message 2. Intialize the cameraSelectorDialog_ to nullptr in Construct so we construct the CameraSelectorDialog just once src/qcam/cam_select_dialog.cpp | 69 ++++++++++++++++++++++++++++++++-- src/qcam/cam_select_dialog.h | 20 +++++++++- 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..0db0a5bd 100644 --- a/src/qcam/cam_select_dialog.cpp +++ b/src/qcam/cam_select_dialog.cpp @@ -16,12 +16,13 @@ #include #include #include +#include #include #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 +40,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 +61,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 +73,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 +131,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 16475af6..bbdf897e 100644 --- a/src/qcam/cam_select_dialog.h +++ b/src/qcam/cam_select_dialog.h @@ -17,18 +17,21 @@ #include #include #include +#include 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); @@ -38,11 +41,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 bf40572a..3c7c3173 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 @@ -152,6 +154,9 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) return; } + /* Start capture script. */ + loadCaptureScript(); + startStopAction_->setChecked(true); } @@ -290,11 +295,54 @@ 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, only the first time. */ if (!cameraSelectorDialog_) - 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 @@ -309,6 +357,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(); @@ -506,6 +557,7 @@ int MainWindow::startCapture() previousFrames_ = 0; framesCaptured_ = 0; lastBufferTime_ = 0; + queueCount_ = 0; ret = camera_->start(); if (ret) { @@ -783,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 d161365a..10994b67 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 "cam_select_dialog.h" @@ -89,6 +90,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 Wed Aug 10 15:03:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17073 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 77C32C3272 for ; Wed, 10 Aug 2022 15:04:14 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 2EE7963340; Wed, 10 Aug 2022 17:04:14 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660143854; bh=qytBWn/jAHqKVs+wfUAlvvbyclouipgE2JQ+P8k0rmU=; 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=yBfcpDrJrhxSp+l4LSbF2CXXM3O6Qh9XfODyeuAglTdiyK9jfFEmDFgqnXe/iweO0 jjTednZoKvhvCjcKFICGxy0DjBcG99ASbjMYq2pJsd3m0otDvlj1645woHo/iCbCIb LrAEOylo+I6KV8D9vBgxtdeSdW7l74y4oUjjl+G83XkL7uF6IAmcUzHhCu0fPUamyG pxNTifNtP2Xk+kcEjNTCLkQWMtc92Ef1IGDetO8WUuMd/6IZ1vBT6BdC2gHQJnAuVE 2gKB+0k2NvYvLPS11VY/ChjdOnlVXxhibBtKZpNyjPYASxLWiWC0XI8SbsKzmnhmTy Ft+4+CDweXeNw== Received: from mail-pf1-x42b.google.com (mail-pf1-x42b.google.com [IPv6:2607:f8b0:4864:20::42b]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 843F56333D for ; Wed, 10 Aug 2022 17:04:12 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Jx2azNbM"; dkim-atps=neutral Received: by mail-pf1-x42b.google.com with SMTP id f192so13938807pfa.9 for ; Wed, 10 Aug 2022 08:04: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=kx1n1X+NqDdSrABkSCaBRoZD7PnoXHnF4Drty4LDWhI=; b=Jx2azNbMCGbCbJkCYx8sKRtcRUA+/8ityRp39f6VUkzevP3vzHCKIUJWB4bmGglx95 qO8pjYR5voIN3+z7oWtcJAUJzM/85drIGFEyUrD5QocOeHrFN8COC4LtTT7wN4Y0twm7 mfSFdldpceBt/PJe+dnQFPbnyx2rP2D4HxnKkfMnsJs7DbIsrYde7OlHrQGEASibHPyv 4c+w8OZRKCeXXikGrn8fyhj6aUrdMJYIHHOv38qGprsD9VXIGxwfNwvi0tVoIfT4h6do CX4HjTSm6JJObTC1olgOPwUe98+WzW9r2mNOHInc7W0Kqcr2FcaCv2Nv9PHLoFYc042/ nV9Q== 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=kx1n1X+NqDdSrABkSCaBRoZD7PnoXHnF4Drty4LDWhI=; b=nLWRvuiwp7SiOLARy3onc3D3LflfV30xJMrvs8KkHfG/Y99dcIxmfD/tTl+qbVYTcK PEDR/FOlJBDxZgq8mnudEi269szWoZmqcIUosCjQunsMXqKB0uao8x3w3QREURnIFKMz JF+q6gH81OidJRzVdTpY+aq6HvrGJ37pvsKWNgFQuZ+wVsisvdsZmuHOGr/JUsRTFc2Q i1+tu9TvQX6WAKjSIyQCzq7qlieu/WYWZ3mMba+2DizHhO9W5FobEUxFA/bcuhIqbGDC pH07PDr0aVFhn3Xbn6Gq/G72IrnNBvKK+zoKl4HVTZuaxRb8a6bFxPSZNv9RKTj9EeDL 7G/w== X-Gm-Message-State: ACgBeo1P2XfXvZT+5KHuo2JnsgPFy967dL6tevue8HLxT7wVdVHNGvz5 roJh1nY5YiAYD6y8lLZmOLgrVoPPC2k= X-Google-Smtp-Source: AA6agR5sOXzNCgUK9dVPk12jzVv2TqoUMWjkDjfvNtUZF3VPrukX+VTUj/NVFoQpjXfI37bgO1nWHA== X-Received: by 2002:aa7:8096:0:b0:52d:d5f6:2ea6 with SMTP id v22-20020aa78096000000b0052dd5f62ea6mr28456817pff.0.1660143850861; Wed, 10 Aug 2022 08:04:10 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2a55:4cae:bf8f:f4ed]) by smtp.gmail.com with ESMTPSA id b3-20020a1709027e0300b0016f1319d2a7sm12882624plm.297.2022.08.10.08.04.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Aug 2022 08:04:10 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 20:33:48 +0530 Message-Id: <20220810150349.414043-8-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220810150349.414043-1-utkarsh02t@gmail.com> References: <20220810150349.414043-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 --- Difference: 1. The scriptPathLabel_ has a fixed parent now captureWidget src/qcam/cam_select_dialog.cpp | 39 ++++++++++++++++++++++++++++------ src/qcam/cam_select_dialog.h | 7 +++++- 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 0db0a5bd..3286c433 100644 --- a/src/qcam/cam_select_dialog.cpp +++ b/src/qcam/cam_select_dialog.cpp @@ -19,10 +19,12 @@ #include #include #include +#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); @@ -40,14 +42,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(captureWidget); + 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 */ @@ -64,7 +83,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); } @@ -139,16 +158,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 bbdf897e..72dfbb14 100644 --- a/src/qcam/cam_select_dialog.h +++ b/src/qcam/cam_select_dialog.h @@ -18,13 +18,15 @@ #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; @@ -62,5 +64,8 @@ private: QComboBox *cameraIdComboBox_; QLabel *cameraLocation_; QLabel *cameraModel_; + + QVBoxLayout *captureWidgetLayout_; QPushButton *captureScriptButton_; + QLabel *scriptPathLabel_; }; diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 3c7c3173..753e1af9 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -339,7 +339,8 @@ std::string MainWindow::chooseCamera() /* Construct the selection dialog, only the first time. */ if (!cameraSelectorDialog_) - cameraSelectorDialog_ = new CameraSelectorDialog(cm_, scriptRunning, this); + cameraSelectorDialog_ = new CameraSelectorDialog(cm_, scriptRunning, + scriptPath_, this); connect(cameraSelectorDialog_, &CameraSelectorDialog::stopCaptureScript, this, &MainWindow::stopCaptureScript); From patchwork Wed Aug 10 15:03:49 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Utkarsh Tiwari X-Patchwork-Id: 17074 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 E8806C3272 for ; Wed, 10 Aug 2022 15:04:16 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id A4E9D63330; Wed, 10 Aug 2022 17:04:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1660143856; bh=Gissg3Kolnsi/wJV5FavEAiRINqNVr57p7i3yoAwTvg=; 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=0j/kmbjag4yzKg5CDcofYgNjuV62lNZJIICtT/89vxf02i/DdiT3xmWgmOtorTXig oJsqaiP/yVT3oO8Ob3S+UJXGaHyOPG9m0hjsR887IKEEyFtkGSnAxPJSYO0qG5naoL SlOhiJoGiwEx9I59BGTldFhjeulrsoECqwuj+fllAq8CnbPvJ6byOrlV+9TDOlF/pq kK2R0NVZSxOMw40TiORRXC8yHdX+YRUatJ0b2eXhijSHMp/EOlNvywNGSnWr4M+Hh8 ZXiNOuQ5mSN8RGp6+TFp+YyLGPP9+pCxQ6UA/dsxBpREPnk34Htp/H1fssqf7ZLgah ypFf7A8TaroOQ== Received: from mail-pl1-x630.google.com (mail-pl1-x630.google.com [IPv6:2607:f8b0:4864:20::630]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 58B3663342 for ; Wed, 10 Aug 2022 17:04:14 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="R87G+CFl"; dkim-atps=neutral Received: by mail-pl1-x630.google.com with SMTP id m2so14497411pls.4 for ; Wed, 10 Aug 2022 08:04:14 -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=JJ6VsRgjEyvXjTIL05vJUEogvTNW4TalPItR7UT8ois=; b=R87G+CFloViHwgUMYWPd20mpy7gf7auhi8dLdSYcyS+HCu0FAMbQ7LH9vaQjfLsp5q +1A6fTKOUJvzXk2cW+aMY8hD+fRzc7osrMX/IoeClTNsr4UWS3jNyE/EfpQ/wkwNk3rk dnfhupwWtw5q3FTXP5P01nyfmVHvUSmu04fyVsjQYvBcJGlP73Eh2GI/ieQkggRXZGWV FG67meb8u42gzZTdUR4rri6uF/CD1LtXR8/vI48BwlsVn2qD8VGsJfoGfcA5Rv2/R6E2 oVkbkveuUHZ4nfQmdzVwNYiSKsNuR7yUYyBq9qRznxb47Jl6if0IZqSb+A2APhCxnYfL 3Ukw== 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=JJ6VsRgjEyvXjTIL05vJUEogvTNW4TalPItR7UT8ois=; b=ZP7N1mJMhdjLn/jeoxwaxMNtGaWJdzZIng841DxgcMAIf+9IrUNwJrx0YjXqZwC9Xi gToLTmQ+LNadgX2FuLPa4lODI6R4+noapxU9GJp77fDxumqBEL5itbhoyUNNCUoLQO4L Ih2QMrjUwWGKTFAqyTT4hiknX3outlJ+pJ+cD+BHDTArgUZ/xAwMXcPQj+eFNyenjIYI f7pWr8hHoxaOz7MKE07HSmmG8bgdugDJKWsLVBkua3CvYvKcmZMn0lOYMvnN3tac/nmL +L1G0gIu/mqip/JbYo4Ts30flsCzCZ2d/gDkxLGFAsfdH0zph1pSg7Vc3lkSTQMUQgxc n4aA== X-Gm-Message-State: ACgBeo0AzrIZTv1RJPZATEhnJSawgYzZmpgVBjw1Jd8WSdWwIA5b4X3p fjQoX/cfyzeSvLh21U2gCuFLkjjKQwk= X-Google-Smtp-Source: AA6agR7BILm1lOVHvCp5q3aCGd3xYo3e70KiBF/+V1vbC0jcj3GZur9gUeD8/2w4Sa3GljVAzELkUg== X-Received: by 2002:a17:903:40ca:b0:170:5b7a:a7c4 with SMTP id t10-20020a17090340ca00b001705b7aa7c4mr22675879pld.108.1660143852762; Wed, 10 Aug 2022 08:04:12 -0700 (PDT) Received: from localhost.localdomain ([2404:bd00:3:d2bc:2a55:4cae:bf8f:f4ed]) by smtp.gmail.com with ESMTPSA id b3-20020a1709027e0300b0016f1319d2a7sm12882624plm.297.2022.08.10.08.04.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 10 Aug 2022 08:04:12 -0700 (PDT) To: libcamera-devel@lists.libcamera.org Date: Wed, 10 Aug 2022 20:33:49 +0530 Message-Id: <20220810150349.414043-9-utkarsh02t@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220810150349.414043-1-utkarsh02t@gmail.com> References: <20220810150349.414043-1-utkarsh02t@gmail.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v8 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 from v7: 1. Moved firstCameraSelect_ to 3/8 src/qcam/main.cpp | 3 +++ src/qcam/main_window.cpp | 10 ++++++++++ src/qcam/main_window.h | 1 + 3 files changed, 14 insertions(+) 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 753e1af9..ce70cc02 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -147,6 +147,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) { @@ -325,6 +328,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_); diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index 10994b67..c7cba5e9 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