summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUmang Jain <email@uajain.com>2020-06-16 19:45:38 +0000
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2020-06-17 00:27:56 +0300
commit7055e96ecc9144390a259e4e23be7fb77ca93364 (patch)
tree55493af50a1bd6c4ba4bb593e214ef414d9ac80d
parente9b47217b44cd775498e3fd676be50217d73ad41 (diff)
qcam: main_window: Introduce initial hotplug support
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 <email@uajain.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r--src/qcam/main_window.cpp76
-rw-r--r--src/qcam/main_window.h6
2 files changed, 82 insertions, 0 deletions
diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
index 2960259f..7bc13603 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> camera, PlugEvent event)
+ : QEvent(type()), camera_(std::move(camera)), plugEvent_(event)
+ {
+ }
+
+ static Type type()
+ {
+ static int type = QEvent::registerEventType();
+ return static_cast<Type>(type);
+ }
+
+ PlugEvent hotplugEvent() const { return plugEvent_; }
+ Camera *camera() const { return camera_.get(); }
+
+private:
+ std::shared_ptr<Camera> 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<HotplugEvent *>(e));
+ return true;
}
return QMainWindow::event(e);
@@ -536,6 +573,45 @@ void MainWindow::stopCapture()
}
/* -----------------------------------------------------------------------------
+ * 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> 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> 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 59fa2d98..4606fe48 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> camera);
+ void removeCamera(std::shared_ptr<Camera> camera);
+
void requestComplete(Request *request);
void processCapture();
+ void processHotplug(HotplugEvent *e);
void processViewfinder(FrameBuffer *buffer);
/* UI elements */