[libcamera-devel] [PATCH v4 5/6] qcam: main_window: Introduce initial hotplug support

Kieran Bingham kieran.bingham at ideasonboard.com
Fri Jun 12 17:25:08 CEST 2020


Hi Umang,

On 12/06/2020 12:04, Laurent Pinchart wrote:
> Hi Umang,
> 
> Thank you for the patch.
> 
> On Thu, Jun 11, 2020 at 05:16:07PM +0000, Umang Jain wrote:
>> 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 hence, those are intentionally
>> kept out of scope for now. It might require some thinking
>> and/or additional time on hand.
>>
>> Signed-off-by: Umang Jain <email at uajain.com>
> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> 
>> ---
>>  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
>> +	};


Re: Laurent's quizzing of if I would dislike the choices here ...
I think this is the best choice of naming, but I can see how it can be a
bit painful.

Reviewed-by: Kieran Bingham <kieran.bingham at ideasonboard.com>


>> +
>> +	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);
>> @@ -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> 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 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> camera);
>> +	void removeCamera(std::shared_ptr<Camera> camera);
>> +
>>  	void requestComplete(Request *request);
>>  	void processCapture();
>> +	void processHotplug(HotplugEvent *e);
>>  	void processViewfinder(FrameBuffer *buffer);
>>  
>>  	/* UI elements */
> 

-- 
Regards
--
Kieran


More information about the libcamera-devel mailing list