[{"id":5109,"web_url":"https://patchwork.libcamera.org/comment/5109/","msgid":"<20200607170414.GD22208@pendragon.ideasonboard.com>","date":"2020-06-07T17:04:14","subject":"Re: [libcamera-devel] [PATCH v3 4/5] qcam: main_window: Introduce\n\tinitial hotplug support","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Umang,\n\nThank you for the patch.\n\nOn Thu, May 21, 2020 at 01:54:26PM +0000, Umang Jain wrote:\n> Hook up various QCam UI bits with hotplug support introduced\n> in previous commits. This looks good-enough as first steps\n> to see how the hotplugging functionality is turning out to be\n> from application point-of-view.\n> \n> One can still think of few edge case nuances not yet covered\n> under this implementation hence, those are intentionally\n> kept out of scope for now. It might require some thinking\n> and/or additional time on hand.\n\nOut of curiosity, do you have any such cases in mind already ?\n\n> Signed-off-by: Umang Jain <email@uajain.com>\n> ---\n>  src/qcam/main_window.cpp | 83 ++++++++++++++++++++++++++++++++++++++++\n>  src/qcam/main_window.h   |  6 +++\n>  2 files changed, 89 insertions(+)\n> \n> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> index 7de0895..ba96c27 100644\n> --- a/src/qcam/main_window.cpp\n> +++ b/src/qcam/main_window.cpp\n> @@ -49,6 +49,43 @@ public:\n>  \t}\n>  };\n>  \n> +/**\n> + * \\brief Custom QEvent to signal hotplug or unplug\n> + */\n> +class HotplugEvent : public QEvent\n> +{\n> +public:\n> +\tenum PLUGEVENT {\n\nWe Use CamelCase for types, this would be PlugEvent.\n\n> +\t\tHOTPLUG,\n> +\t\tUNPLUG\n\nSame here,\n\n\t\tHotplug,\n\t\tUnplug,\n\nKieran will hate me for asking if it should be\n\n\t\tPlug,\n\t\tUnplug,\n\n,\n\n\t\tHotplug,\n\t\tHotunplug,\n\nor\n\n\t\tHotPlug,\n\t\tHotUnplug,\n\nMy personal preference is (from most preferred to least preferred)\nHotUnplug, Unplug, Hotunplug, but at the same time I wouldn't rename\nHotplugEvent to HotPlugEvent. Maybe we could use \"hotplug\" (Hotplug in\nCamelCase) as a generic term that would cover both plug and unplug, and\n\"hot-plug\" and \"hot-unplug\" (respectively HotPlug and HotUnplug in\nCamelCase) when talking about plug and unplug specifically ? Or maybe\nthat's overkill :-)\n\n> +\t};\n> +\n> +\tHotplugEvent(std::shared_ptr<Camera> camera, PLUGEVENT event)\n> +\t\t: QEvent(type())\n\n\t\t: QEvent(type()), camera_(std::move(camera)), plugEvent_(event)\n\t{\n\t}\n\n> +\t{\n> +\t\tcamera_ = camera;\n> +\t\tplugEvent_ = event;\n> +\t}\n> +\n> +\t~HotplugEvent()\n> +\t{\n> +\t\tcamera_.reset();\n\nThis isn't needed, the shared pointer is automatically reset when\ndestroyed. You can drop the HotplugEvent destructor.\n\n> +\t}\n> +\n> +\tstatic Type type()\n> +\t{\n> +\t\tstatic int type = QEvent::registerEventType();\n> +\t\treturn static_cast<Type>(type);\n> +\t}\n> +\n> +\tPLUGEVENT getHotplugEvent() { return plugEvent_; }\n\nWe don't usually prefix getters with get,\n\n\tPlugEvent hotplugEvent() const { return plugEvent; }\n\n(with an added const)\n\n> +\tCamera *getCamera() { return camera_.get(); }\n\nSame here.\n\n> +\n> +private:\n> +\tstd::shared_ptr<Camera> camera_;\n> +\tPLUGEVENT plugEvent_;\n> +};\n> +\n>  MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)\n>  \t: saveRaw_(nullptr), options_(options), cm_(cm), allocator_(nullptr),\n>  \t  isCapturing_(false), captureRaw_(false)\n> @@ -71,6 +108,10 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)\n>  \tsetCentralWidget(viewfinder_);\n>  \tadjustSize();\n>  \n> +\t/* Hotplug/unplug support */\n> +\tcm_->newCameraAdded.connect(this, &MainWindow::addNewCamera);\n> +\tcm_->cameraRemoved.connect(this, &MainWindow::removeCamera);\n> +\n>  \t/* Open the camera and start capture. */\n>  \tret = openCamera();\n>  \tif (ret < 0) {\n> @@ -95,6 +136,9 @@ bool MainWindow::event(QEvent *e)\n>  \tif (e->type() == CaptureEvent::type()) {\n>  \t\tprocessCapture();\n>  \t\treturn true;\n> +\t} else if (e->type() == HotplugEvent::type()) {\n> +\t\tprocessHotplug(static_cast<HotplugEvent *>(e));\n> +\t\treturn true;\n>  \t}\n>  \n>  \treturn QMainWindow::event(e);\n> @@ -525,6 +569,45 @@ void MainWindow::stopCapture()\n>  \tsetWindowTitle(title_);\n>  }\n>  \n> +/* -----------------------------------------------------------------------------\n> + * Camera hotplugging support\n> + */\n> +\n> +void MainWindow::processHotplug(HotplugEvent *e)\n> +{\n> +\tCamera *camera = e->getCamera();\n> +\tHotplugEvent::PLUGEVENT event = e->getHotplugEvent();\n> +\n> +\tif (event == HotplugEvent::PLUGEVENT::HOTPLUG) {\n\nThis can be shortened to HotplugEvent::HOTPLUG (same for similar\noccurences below).\n\n> +\t\tcameraCombo_->addItem(QString::fromStdString(camera->name()));\n> +\t} else if (event == HotplugEvent::PLUGEVENT::UNPLUG) {\n> +\t\tint camIndex = cameraCombo_->findText(QString::fromStdString(camera->name()));\n\nI'd move this line right before cameraCombo_->removeItem() (with a blank\nline above) to keep the variable declaration close to its usage.\n\n> +\n> +\t\t/* Check if the currently-streaming camera is removed. */\n> +\t\tif (camera == camera_.get()) {\n> +\t\t\ttoggleCapture(false);\n> +\t\t\tcameraCombo_->setCurrentIndex(0);\n> +\t\t}\n> +\t\tcameraCombo_->removeItem(camIndex);\n> +\t}\n> +}\n> +\n> +void MainWindow::addNewCamera(std::shared_ptr<Camera> camera)\n\nIf we rename CameraManager::newCameraAdded this should be renamed to\naddCamera().\n\nThat's quite a few comments, but nothing major. I believe the next\nversion will be the last. Thanks for your work !\n\n> +{\n> +\tqInfo() << \"Adding new camera:\" << camera->name().c_str();\n> +\tQCoreApplication::postEvent(this,\n> +\t\t\t\t    new HotplugEvent(std::move(camera),\n> +\t\t\t\t\t\t     HotplugEvent::PLUGEVENT::HOTPLUG));\n> +}\n> +\n> +void MainWindow::removeCamera(std::shared_ptr<Camera> camera)\n> +{\n> +\tqInfo() << \"Removing camera:\" << camera->name().c_str();\n> +\tQCoreApplication::postEvent(this,\n> +\t\t\t\t    new HotplugEvent(std::move(camera),\n> +\t\t\t\t\t\t     HotplugEvent::PLUGEVENT::UNPLUG));\n> +}\n> +\n>  /* -----------------------------------------------------------------------------\n>   * Image Save\n>   */\n> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n> index 59fa2d9..9108780 100644\n> --- a/src/qcam/main_window.h\n> +++ b/src/qcam/main_window.h\n> @@ -32,6 +32,8 @@ using namespace libcamera;\n>  class QAction;\n>  class QComboBox;\n>  \n> +class HotplugEvent;\n> +\n>  enum {\n>  \tOptCamera = 'c',\n>  \tOptHelp = 'h',\n> @@ -87,8 +89,12 @@ private:\n>  \tint startCapture();\n>  \tvoid stopCapture();\n>  \n> +\tvoid addNewCamera(std::shared_ptr<Camera> camera);\n> +\tvoid removeCamera(std::shared_ptr<Camera> camera);\n> +\n>  \tvoid requestComplete(Request *request);\n>  \tvoid processCapture();\n> +\tvoid processHotplug(HotplugEvent *e);\n>  \tvoid processViewfinder(FrameBuffer *buffer);\n>  \n>  \t/* UI elements */","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B928D600F7\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSun,  7 Jun 2020 19:04:33 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 351102C9;\n\tSun,  7 Jun 2020 19:04:33 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"YB/xBNuy\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1591549473;\n\tbh=JkeKfPmD7T4N8tmHOXWDRY62QdvBTrr7WRi4aPB5J24=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=YB/xBNuywBYZyK7jasCz1iuoTqK6sO6Qu+rMKQVETE5yc64YJJcyiXvqa4UqALEYx\n\tQZ4FpaxeJdvaB2JK3aOOfiEQ+3dEj3Rg3s7gHjcLZgAeYqMjjOnkoVbQaadGSBKOPs\n\thwKyGwQhznW7ENUsdPowgc5xpI/bA1r/za36OWNQ=","Date":"Sun, 7 Jun 2020 20:04:14 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Umang Jain <email@uajain.com>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200607170414.GD22208@pendragon.ideasonboard.com>","References":"<20200521135416.13685-1-email@uajain.com>\n\t<20200521135416.13685-5-email@uajain.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","In-Reply-To":"<20200521135416.13685-5-email@uajain.com>","Subject":"Re: [libcamera-devel] [PATCH v3 4/5] qcam: main_window: Introduce\n\tinitial hotplug support","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Sun, 07 Jun 2020 17:04:34 -0000"}},{"id":5182,"web_url":"https://patchwork.libcamera.org/comment/5182/","msgid":"<62a7a6b0-f07f-9857-1f16-e07396329c5f@uajain.com>","date":"2020-06-11T12:34:15","subject":"Re: [libcamera-devel] [PATCH v3 4/5] qcam: main_window: Introduce\n\tinitial hotplug support","submitter":{"id":1,"url":"https://patchwork.libcamera.org/api/people/1/","name":"Umang Jain","email":"email@uajain.com"},"content":"Hi Laurent,\n\nOn 6/7/20 10:34 PM, Laurent Pinchart wrote:\n> Hi Umang,\n>\n> Thank you for the patch.\n>\n> On Thu, May 21, 2020 at 01:54:26PM +0000, Umang Jain wrote:\n>> Hook up various QCam UI bits with hotplug support introduced\n>> in previous commits. This looks good-enough as first steps\n>> to see how the hotplugging functionality is turning out to be\n>> from application point-of-view.\n>>\n>> One can still think of few edge case nuances not yet covered\n>> under this implementation hence, those are intentionally\n>> kept out of scope for now. It might require some thinking\n>> and/or additional time on hand.\n> Out of curiosity, do you have any such cases in mind already ?\n\nYes, They were mostly around having one camera on the system.\n\nHot-unplugging the only camera present and plugging it back in, does not\n\nstart streaming it out of the box. Might need to handle this case a bit \ndifferently\n\nin qcam, which honestly I was hoping to address after these patch series \nis landed,\n\nin chunks of small improvements.\n\n>\n>> Signed-off-by: Umang Jain <email@uajain.com>\n>> ---\n>>   src/qcam/main_window.cpp | 83 ++++++++++++++++++++++++++++++++++++++++\n>>   src/qcam/main_window.h   |  6 +++\n>>   2 files changed, 89 insertions(+)\n>>\n>> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n>> index 7de0895..ba96c27 100644\n>> --- a/src/qcam/main_window.cpp\n>> +++ b/src/qcam/main_window.cpp\n>> @@ -49,6 +49,43 @@ public:\n>>   \t}\n>>   };\n>>   \n>> +/**\n>> + * \\brief Custom QEvent to signal hotplug or unplug\n>> + */\n>> +class HotplugEvent : public QEvent\n>> +{\n>> +public:\n>> +\tenum PLUGEVENT {\n> We Use CamelCase for types, this would be PlugEvent.\n>\n>> +\t\tHOTPLUG,\n>> +\t\tUNPLUG\n> Same here,\n>\n> \t\tHotplug,\n> \t\tUnplug,\n>\n> Kieran will hate me for asking if it should be\n>\n> \t\tPlug,\n> \t\tUnplug,\n>\n> ,\n>\n> \t\tHotplug,\n> \t\tHotunplug,\n>\n> or\n>\n> \t\tHotPlug,\n> \t\tHotUnplug,\n>\n> My personal preference is (from most preferred to least preferred)\n> HotUnplug, Unplug, Hotunplug, but at the same time I wouldn't rename\n> HotplugEvent to HotPlugEvent. Maybe we could use \"hotplug\" (Hotplug in\n> CamelCase) as a generic term that would cover both plug and unplug, and\n> \"hot-plug\" and \"hot-unplug\" (respectively HotPlug and HotUnplug in\n> CamelCase) when talking about plug and unplug specifically ? Or maybe\n> that's overkill :-)\n>\n>> +\t};\n>> +\n>> +\tHotplugEvent(std::shared_ptr<Camera> camera, PLUGEVENT event)\n>> +\t\t: QEvent(type())\n> \t\t: QEvent(type()), camera_(std::move(camera)), plugEvent_(event)\n> \t{\n> \t}\n>\n>> +\t{\n>> +\t\tcamera_ = camera;\n>> +\t\tplugEvent_ = event;\n>> +\t}\n>> +\n>> +\t~HotplugEvent()\n>> +\t{\n>> +\t\tcamera_.reset();\n> This isn't needed, the shared pointer is automatically reset when\n> destroyed. You can drop the HotplugEvent destructor.\n>\n>> +\t}\n>> +\n>> +\tstatic Type type()\n>> +\t{\n>> +\t\tstatic int type = QEvent::registerEventType();\n>> +\t\treturn static_cast<Type>(type);\n>> +\t}\n>> +\n>> +\tPLUGEVENT getHotplugEvent() { return plugEvent_; }\n> We don't usually prefix getters with get,\n>\n> \tPlugEvent hotplugEvent() const { return plugEvent; }\n>\n> (with an added const)\n>\n>> +\tCamera *getCamera() { return camera_.get(); }\n> Same here.\n>\n>> +\n>> +private:\n>> +\tstd::shared_ptr<Camera> camera_;\n>> +\tPLUGEVENT plugEvent_;\n>> +};\n>> +\n>>   MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)\n>>   \t: saveRaw_(nullptr), options_(options), cm_(cm), allocator_(nullptr),\n>>   \t  isCapturing_(false), captureRaw_(false)\n>> @@ -71,6 +108,10 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)\n>>   \tsetCentralWidget(viewfinder_);\n>>   \tadjustSize();\n>>   \n>> +\t/* Hotplug/unplug support */\n>> +\tcm_->newCameraAdded.connect(this, &MainWindow::addNewCamera);\n>> +\tcm_->cameraRemoved.connect(this, &MainWindow::removeCamera);\n>> +\n>>   \t/* Open the camera and start capture. */\n>>   \tret = openCamera();\n>>   \tif (ret < 0) {\n>> @@ -95,6 +136,9 @@ bool MainWindow::event(QEvent *e)\n>>   \tif (e->type() == CaptureEvent::type()) {\n>>   \t\tprocessCapture();\n>>   \t\treturn true;\n>> +\t} else if (e->type() == HotplugEvent::type()) {\n>> +\t\tprocessHotplug(static_cast<HotplugEvent *>(e));\n>> +\t\treturn true;\n>>   \t}\n>>   \n>>   \treturn QMainWindow::event(e);\n>> @@ -525,6 +569,45 @@ void MainWindow::stopCapture()\n>>   \tsetWindowTitle(title_);\n>>   }\n>>   \n>> +/* -----------------------------------------------------------------------------\n>> + * Camera hotplugging support\n>> + */\n>> +\n>> +void MainWindow::processHotplug(HotplugEvent *e)\n>> +{\n>> +\tCamera *camera = e->getCamera();\n>> +\tHotplugEvent::PLUGEVENT event = e->getHotplugEvent();\n>> +\n>> +\tif (event == HotplugEvent::PLUGEVENT::HOTPLUG) {\n> This can be shortened to HotplugEvent::HOTPLUG (same for similar\n> occurences below).\n>\n>> +\t\tcameraCombo_->addItem(QString::fromStdString(camera->name()));\n>> +\t} else if (event == HotplugEvent::PLUGEVENT::UNPLUG) {\n>> +\t\tint camIndex = cameraCombo_->findText(QString::fromStdString(camera->name()));\n> I'd move this line right before cameraCombo_->removeItem() (with a blank\n> line above) to keep the variable declaration close to its usage.\n>\n>> +\n>> +\t\t/* Check if the currently-streaming camera is removed. */\n>> +\t\tif (camera == camera_.get()) {\n>> +\t\t\ttoggleCapture(false);\n>> +\t\t\tcameraCombo_->setCurrentIndex(0);\n>> +\t\t}\n>> +\t\tcameraCombo_->removeItem(camIndex);\n>> +\t}\n>> +}\n>> +\n>> +void MainWindow::addNewCamera(std::shared_ptr<Camera> camera)\n> If we rename CameraManager::newCameraAdded this should be renamed to\n> addCamera().\n>\n> That's quite a few comments, but nothing major. I believe the next\n> version will be the last. Thanks for your work !\n>\n>> +{\n>> +\tqInfo() << \"Adding new camera:\" << camera->name().c_str();\n>> +\tQCoreApplication::postEvent(this,\n>> +\t\t\t\t    new HotplugEvent(std::move(camera),\n>> +\t\t\t\t\t\t     HotplugEvent::PLUGEVENT::HOTPLUG));\n>> +}\n>> +\n>> +void MainWindow::removeCamera(std::shared_ptr<Camera> camera)\n>> +{\n>> +\tqInfo() << \"Removing camera:\" << camera->name().c_str();\n>> +\tQCoreApplication::postEvent(this,\n>> +\t\t\t\t    new HotplugEvent(std::move(camera),\n>> +\t\t\t\t\t\t     HotplugEvent::PLUGEVENT::UNPLUG));\n>> +}\n>> +\n>>   /* -----------------------------------------------------------------------------\n>>    * Image Save\n>>    */\n>> diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h\n>> index 59fa2d9..9108780 100644\n>> --- a/src/qcam/main_window.h\n>> +++ b/src/qcam/main_window.h\n>> @@ -32,6 +32,8 @@ using namespace libcamera;\n>>   class QAction;\n>>   class QComboBox;\n>>   \n>> +class HotplugEvent;\n>> +\n>>   enum {\n>>   \tOptCamera = 'c',\n>>   \tOptHelp = 'h',\n>> @@ -87,8 +89,12 @@ private:\n>>   \tint startCapture();\n>>   \tvoid stopCapture();\n>>   \n>> +\tvoid addNewCamera(std::shared_ptr<Camera> camera);\n>> +\tvoid removeCamera(std::shared_ptr<Camera> camera);\n>> +\n>>   \tvoid requestComplete(Request *request);\n>>   \tvoid processCapture();\n>> +\tvoid processHotplug(HotplugEvent *e);\n>>   \tvoid processViewfinder(FrameBuffer *buffer);\n>>   \n>>   \t/* UI elements */","headers":{"Return-Path":"<bounces+15657259-5c31-libcamera-devel=lists.libcamera.org@em7280.uajain.com>","Received":["from o1.f.az.sendgrid.net (o1.f.az.sendgrid.net [208.117.55.132])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id C407B610A5\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 11 Jun 2020 14:34:16 +0200 (CEST)","by filterdrecv-p3iad2-784dbb6bd8-z6chg with SMTP id\n\tfilterdrecv-p3iad2-784dbb6bd8-z6chg-19-5EE224C7-1F\n\t2020-06-11 12:34:15.391386883 +0000 UTC m=+664046.424635052","from mail.uajain.com (unknown)\n\tby ismtpd0008p1hnd1.sendgrid.net (SG) with ESMTP\n\tid e8oTWg5HQ-mMEWxFIetY7w Thu, 11 Jun 2020 12:34:14.660 +0000 (UTC)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=uajain.com\n\theader.i=@uajain.com header.b=\"hGE0pcqr\"; \n\tdkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=uajain.com;\n\th=subject:references:from:mime-version:in-reply-to:to:cc:content-type:\n\tcontent-transfer-encoding;\n\ts=s1; bh=g2i1LzE1uWAAQpAlU8CoPTyvhOejKK0xeZRHIhSFSSk=;\n\tb=hGE0pcqr6LvmTQGrfsAdp7xmwKXL3C4xcjzTQYSM2juJZMNBTcBLXOZA3dmFeTMJ3guh\n\tvIkE+ytpRtMXdCoUJ0sUe/GosTJOlTePUNynLd8gNaNJZ5bVoDTBjR4NbopjfdU6tjtphq\n\t37S+YHjz1iZweOqmouz5nqZ2nnn7o06Nc=","References":"<20200521135416.13685-1-email@uajain.com>\n\t<20200521135416.13685-5-email@uajain.com>\n\t<20200607170414.GD22208@pendragon.ideasonboard.com>","From":"Umang Jain <email@uajain.com>","Message-ID":"<62a7a6b0-f07f-9857-1f16-e07396329c5f@uajain.com>","Date":"Thu, 11 Jun 2020 12:34:15 +0000 (UTC)","Mime-Version":"1.0","In-Reply-To":"<20200607170414.GD22208@pendragon.ideasonboard.com>","X-SG-EID":"1Q40EQ7YGir8a9gjSIAdTjhngY657NMk9ckeo4dbHZDiOpywc/L3L9rFqlwE4KPcjyJADjWRSqlSUDT552L9UCoWlLvMuhFCfUtJy1ZqXhM4nO9nXK0g4cKMA2bImz2Vs2RyfnBMpKJisX18liqlsbTy+eXKX255ykIg+DvdiiCJTrYz4m0s2zCRTbgqGRblp09VQ54YYg3jfE2XiD0YqAKJjFcoAT462Xl+m4+Vj8L4GjCM82SPfTvwoR+I+aWwQxuhypuoOGH+Q2XdGPIYdQ==","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Content-Type":"text/plain; charset=us-ascii; format=flowed","Content-Transfer-Encoding":"7bit","Content-Language":"en-US","Subject":"Re: [libcamera-devel] [PATCH v3 4/5] qcam: main_window: Introduce\n\tinitial hotplug support","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Thu, 11 Jun 2020 12:34:17 -0000"}}]