From patchwork Tue Jun 16 19:45:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Umang Jain X-Patchwork-Id: 4069 Return-Path: Received: from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id CB66D61F24 for ; Tue, 16 Jun 2020 21:45:39 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=uajain.com header.i=@uajain.com header.b="BUwHJwKf"; dkim-atps=neutral DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com; h=from:subject:in-reply-to:references:mime-version:to:cc: content-transfer-encoding:content-type; s=s1; bh=a09DxRVCdx2Juyi1912x8Ji3Vtfs0ty9OppLXC61jBU=; b=BUwHJwKf7bZwXvvE9ULEI3dqiG6hE/iU3VI0xYjXAFpuDBZ7rCEChxJBOK6TyY/fE1s3 GNsopYyY6jzxvBE7pVDLMsU6jwYe0KxK/A2VFEhiZhojcGbTnaVjYLp6q4WTunwaKj/Uj0 N7EG13km5YyhSSIQmloJsJI4j6Ysie7aI= Received: by filter0104p3las1.sendgrid.net with SMTP id filter0104p3las1-31629-5EE92161-132 2020-06-16 19:45:38.316073928 +0000 UTC m=+696655.239765817 Received: from mail.uajain.com (unknown) by ismtpd0001p1maa1.sendgrid.net (SG) with ESMTP id Nedy3N-4RE-Rf1Vu5vXEXA Tue, 16 Jun 2020 19:45:37.797 +0000 (UTC) From: Umang Jain Date: Tue, 16 Jun 2020 19:45:38 +0000 (UTC) Message-Id: <20200616194523.23268-6-email@uajain.com> In-Reply-To: <20200616194523.23268-1-email@uajain.com> References: <20200616194523.23268-1-email@uajain.com> Mime-Version: 1.0 X-SG-EID: 1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcHIuSzkf5/M5SksOT1pntG8LZHPMsqXV31uFoZfh8NyQ1mvi2JGiTrcfWSqIMI8j0KquW2MH6aIEnkoN7gUAHjmyCKl4og9A4/KNXnVW+11FuaP4xODobxRLrV0REhw/D2+W2JFRAsgQ7CAvTUcS2jJUcOPtyF1cfOi0fF0MjCxp0LfPp75ju9BR6uSLHqau2 To: laurent.pinchart@ideasonboard.com, kieran.bingham@ideasonboard.com, libcamera-devel@lists.libcamera.org Subject: [libcamera-devel] [PATCH v5 5/6] qcam: main_window: Introduce initial hotplug support 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-List-Received-Date: Tue, 16 Jun 2020 19:45:40 -0000 Hook up various QCam UI bits with hotplug support introduced in previous commits. This looks good-enough as first steps to see how the hotplugging functionality is turning out to be from application point-of-view. One can still think of few edge case nuances not yet covered under this implementation especially around having only one camera in the system and hotplugging/hot-unplugging it. Hence, those are intentionally kept out of scope for now. It might require some thinking on how to handle it on application level having additional time on hand. Signed-off-by: Umang Jain Reviewed-by: Laurent Pinchart Reviewed-by: Kieran Bingham --- src/qcam/main_window.cpp | 76 ++++++++++++++++++++++++++++++++++++++++ src/qcam/main_window.h | 6 ++++ 2 files changed, 82 insertions(+) diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp index 2960259..7bc1360 100644 --- a/src/qcam/main_window.cpp +++ b/src/qcam/main_window.cpp @@ -59,6 +59,36 @@ public: } }; +/** + * \brief Custom QEvent to signal hotplug or unplug + */ +class HotplugEvent : public QEvent +{ +public: + enum PlugEvent { + HotPlug, + HotUnplug + }; + + HotplugEvent(std::shared_ptr camera, PlugEvent event) + : QEvent(type()), camera_(std::move(camera)), plugEvent_(event) + { + } + + static Type type() + { + static int type = QEvent::registerEventType(); + return static_cast(type); + } + + PlugEvent hotplugEvent() const { return plugEvent_; } + Camera *camera() const { return camera_.get(); } + +private: + std::shared_ptr camera_; + PlugEvent plugEvent_; +}; + MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) : saveRaw_(nullptr), options_(options), cm_(cm), allocator_(nullptr), isCapturing_(false), captureRaw_(false) @@ -81,6 +111,10 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options) setCentralWidget(viewfinder_); adjustSize(); + /* Hotplug/unplug support */ + cm_->cameraAdded.connect(this, &MainWindow::addCamera); + cm_->cameraRemoved.connect(this, &MainWindow::removeCamera); + /* Open the camera and start capture. */ ret = openCamera(); if (ret < 0) { @@ -105,6 +139,9 @@ bool MainWindow::event(QEvent *e) if (e->type() == CaptureEvent::type()) { processCapture(); return true; + } else if (e->type() == HotplugEvent::type()) { + processHotplug(static_cast(e)); + return true; } return QMainWindow::event(e); @@ -535,6 +572,45 @@ void MainWindow::stopCapture() setWindowTitle(title_); } +/* ----------------------------------------------------------------------------- + * Camera hotplugging support + */ + +void MainWindow::processHotplug(HotplugEvent *e) +{ + Camera *camera = e->camera(); + HotplugEvent::PlugEvent event = e->hotplugEvent(); + + if (event == HotplugEvent::HotPlug) { + cameraCombo_->addItem(QString::fromStdString(camera->name())); + } else if (event == HotplugEvent::HotUnplug) { + /* Check if the currently-streaming camera is removed. */ + if (camera == camera_.get()) { + toggleCapture(false); + cameraCombo_->setCurrentIndex(0); + } + + int camIndex = cameraCombo_->findText(QString::fromStdString(camera->name())); + cameraCombo_->removeItem(camIndex); + } +} + +void MainWindow::addCamera(std::shared_ptr camera) +{ + qInfo() << "Adding new camera:" << camera->name().c_str(); + QCoreApplication::postEvent(this, + new HotplugEvent(std::move(camera), + HotplugEvent::HotPlug)); +} + +void MainWindow::removeCamera(std::shared_ptr camera) +{ + qInfo() << "Removing camera:" << camera->name().c_str(); + QCoreApplication::postEvent(this, + new HotplugEvent(std::move(camera), + HotplugEvent::HotUnplug)); +} + /* ----------------------------------------------------------------------------- * Image Save */ diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h index 59fa2d9..4606fe4 100644 --- a/src/qcam/main_window.h +++ b/src/qcam/main_window.h @@ -32,6 +32,8 @@ using namespace libcamera; class QAction; class QComboBox; +class HotplugEvent; + enum { OptCamera = 'c', OptHelp = 'h', @@ -87,8 +89,12 @@ private: int startCapture(); void stopCapture(); + void addCamera(std::shared_ptr camera); + void removeCamera(std::shared_ptr camera); + void requestComplete(Request *request); void processCapture(); + void processHotplug(HotplugEvent *e); void processViewfinder(FrameBuffer *buffer); /* UI elements */