[libcamera-devel,v3] cam: Add --monitor option

Message ID 20200803124823.82691-1-kieran.bingham@ideasonboard.com
State Accepted
Headers show
Series
  • [libcamera-devel,v3] cam: Add --monitor option
Related show

Commit Message

Kieran Bingham Aug. 3, 2020, 12:48 p.m. UTC
From: Umang Jain <email@uajain.com>

Add --monitor to monitor new hotplug and unplug camera events from
the CameraManager.

Signed-off-by: Umang Jain <email@uajain.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
---
 src/cam/main.cpp | 27 +++++++++++++++++++++++++++
 src/cam/main.h   |  1 +
 2 files changed, 28 insertions(+)

v3:
  - V1 rebased, and slightly modified to update the conditional
    connection of the signals during CamApp::init()
  - Adjust formatting of parser.addOption


Hi all,

I am aiming to merge Umang's patch, but because I have ended up making a
more than superficial change to the code path in CamApp::init() I'm
reposting as v3. This is essentially v1 of Umangs patch (thanks, and
sorry for incorrectly leading you to make a v2) with the small line
adjustment to the parser addition, but a more impacting adjustment to
the conditional which enables the signals.


If there are no objections, I can merge this patch.

Testing with the two options combined shows:

./build/src/cam/cam -m -c 1 -C

fps: 25.64 stream0 seq: 000052 bytesused: 36000
fps: 25.00 stream0 seq: 000053 bytesused: 36024
fps: 25.00 stream0 seq: 000054 bytesused: 36784
fps: 25.64 stream0 seq: 000055 bytesused: 36968
fps: 25.64 stream0 seq: 000056 bytesused: 36792
fps: 25.00 stream0 seq: 000057 bytesused: 37040
fps: 25.64 stream0 seq: 000058 bytesused: 36808
fps: 25.00 stream0 seq: 000059 bytesused: 36848
fps: 25.00 stream0 seq: 000060 bytesused: 37480
Camera Removed: VF0520 Live! Cam Sync: VF0520 L
Camera Added: VF0520 Live! Cam Sync: VF0520 L
Camera Removed: VF0520 Live! Cam Sync: VF0520 L

So the stream doesn't continue, but no crashing - so we're fine ;-)


--
Kieran

Comments

Umang Jain Aug. 3, 2020, 1:09 p.m. UTC | #1
Hi Kieran,

On 8/3/20 6:18 PM, Kieran Bingham wrote:
> From: Umang Jain <email@uajain.com>
>
> Add --monitor to monitor new hotplug and unplug camera events from
> the CameraManager.
>
> Signed-off-by: Umang Jain <email@uajain.com>
> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> ---
>   src/cam/main.cpp | 27 +++++++++++++++++++++++++++
>   src/cam/main.h   |  1 +
>   2 files changed, 28 insertions(+)
>
> v3:
>    - V1 rebased, and slightly modified to update the conditional
>      connection of the signals during CamApp::init()
>    - Adjust formatting of parser.addOption
>
>
> Hi all,
>
> I am aiming to merge Umang's patch, but because I have ended up making a
> more than superficial change to the code path in CamApp::init() I'm
> reposting as v3. This is essentially v1 of Umangs patch (thanks, and
> sorry for incorrectly leading you to make a v2) with the small line
> adjustment to the parser addition, but a more impacting adjustment to
> the conditional which enables the signals.
>
>
> If there are no objections, I can merge this patch.
Yes, Ack from my side.
>
> Testing with the two options combined shows:
>
> ./build/src/cam/cam -m -c 1 -C
>
> fps: 25.64 stream0 seq: 000052 bytesused: 36000
> fps: 25.00 stream0 seq: 000053 bytesused: 36024
> fps: 25.00 stream0 seq: 000054 bytesused: 36784
> fps: 25.64 stream0 seq: 000055 bytesused: 36968
> fps: 25.64 stream0 seq: 000056 bytesused: 36792
> fps: 25.00 stream0 seq: 000057 bytesused: 37040
> fps: 25.64 stream0 seq: 000058 bytesused: 36808
> fps: 25.00 stream0 seq: 000059 bytesused: 36848
> fps: 25.00 stream0 seq: 000060 bytesused: 37480
> Camera Removed: VF0520 Live! Cam Sync: VF0520 L
> Camera Added: VF0520 Live! Cam Sync: VF0520 L
> Camera Removed: VF0520 Live! Cam Sync: VF0520 L
>
> So the stream doesn't continue, but no crashing - so we're fine ;-)
Indeed, restarting the stream would be nice to have feature.
It would be obvious in case only one camera is present, will probably
need to think a bit in case of multiple cameras.

Thanks for the v3.

>
>
> --
> Kieran
>
>
>
> diff --git a/src/cam/main.cpp b/src/cam/main.cpp
> index f5aba041d7c4..3ceb6576960e 100644
> --- a/src/cam/main.cpp
> +++ b/src/cam/main.cpp
> @@ -36,6 +36,8 @@ public:
>   	void quit();
>   
>   private:
> +	void cameraAdded(std::shared_ptr<Camera> cam);
> +	void cameraRemoved(std::shared_ptr<Camera> cam);
>   	int parseOptions(int argc, char *argv[]);
>   	int prepareConfig();
>   	int listControls();
> @@ -123,6 +125,12 @@ int CamApp::init(int argc, char **argv)
>   			return ret;
>   	}
>   
> +	if (options_.isSet(OptMonitor)) {
> +		cm_->cameraAdded.connect(this, &CamApp::cameraAdded);
> +		cm_->cameraRemoved.connect(this, &CamApp::cameraRemoved);
> +		std::cout << "Monitoring new hotplug and unplug events..." << std::endl;
> +	}
> +
>   	loop_ = new EventLoop(cm_->eventDispatcher());
>   
>   	return 0;
> @@ -186,6 +194,9 @@ int CamApp::parseOptions(int argc, char *argv[])
>   			 "list-controls");
>   	parser.addOption(OptListProperties, OptionNone, "List cameras properties",
>   			 "list-properties");
> +	parser.addOption(OptMonitor, OptionNone,
> +			 "Monitor for hotplug and unplug camera events",
> +			 "monitor");
>   	parser.addOption(OptStrictFormats, OptionNone,
>   			 "Do not allow requested stream format(s) to be adjusted",
>   			 "strict-formats");
> @@ -309,6 +320,16 @@ int CamApp::infoConfiguration()
>   	return 0;
>   }
>   
> +void CamApp::cameraAdded(std::shared_ptr<Camera> cam)
> +{
> +	std::cout << "Camera Added: " << cam->name() << std::endl;
> +}
> +
> +void CamApp::cameraRemoved(std::shared_ptr<Camera> cam)
> +{
> +	std::cout << "Camera Removed: " << cam->name() << std::endl;
> +}
> +
>   int CamApp::run()
>   {
>   	int ret;
> @@ -346,6 +367,12 @@ int CamApp::run()
>   		return capture.run(options_);
>   	}
>   
> +	if (options_.isSet(OptMonitor)) {
> +		ret = loop_->exec();
> +		if (ret)
> +			std::cout << "Failed to run monitor loop" << std::endl;
> +	}
> +
>   	return 0;
>   }
>   
> diff --git a/src/cam/main.h b/src/cam/main.h
> index 6f95add31a63..ea8dfd330830 100644
> --- a/src/cam/main.h
> +++ b/src/cam/main.h
> @@ -15,6 +15,7 @@ enum {
>   	OptInfo = 'I',
>   	OptList = 'l',
>   	OptListProperties = 'p',
> +	OptMonitor = 'm',
>   	OptStream = 's',
>   	OptListControls = 256,
>   	OptStrictFormats = 257,
Laurent Pinchart Aug. 3, 2020, 1:09 p.m. UTC | #2
Hi Kieran (and Umang),

Thank you for the patch.

On Mon, Aug 03, 2020 at 01:48:23PM +0100, Kieran Bingham wrote:
> From: Umang Jain <email@uajain.com>
> 
> Add --monitor to monitor new hotplug and unplug camera events from
> the CameraManager.
> 
> Signed-off-by: Umang Jain <email@uajain.com>
> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> ---
>  src/cam/main.cpp | 27 +++++++++++++++++++++++++++
>  src/cam/main.h   |  1 +
>  2 files changed, 28 insertions(+)
> 
> v3:
>   - V1 rebased, and slightly modified to update the conditional
>     connection of the signals during CamApp::init()
>   - Adjust formatting of parser.addOption
> 
> 
> Hi all,
> 
> I am aiming to merge Umang's patch, but because I have ended up making a
> more than superficial change to the code path in CamApp::init() I'm
> reposting as v3. This is essentially v1 of Umangs patch (thanks, and
> sorry for incorrectly leading you to make a v2) with the small line
> adjustment to the parser addition, but a more impacting adjustment to
> the conditional which enables the signals.
> 
> 
> If there are no objections, I can merge this patch.
> 
> Testing with the two options combined shows:
> 
> ./build/src/cam/cam -m -c 1 -C
> 
> fps: 25.64 stream0 seq: 000052 bytesused: 36000
> fps: 25.00 stream0 seq: 000053 bytesused: 36024
> fps: 25.00 stream0 seq: 000054 bytesused: 36784
> fps: 25.64 stream0 seq: 000055 bytesused: 36968
> fps: 25.64 stream0 seq: 000056 bytesused: 36792
> fps: 25.00 stream0 seq: 000057 bytesused: 37040
> fps: 25.64 stream0 seq: 000058 bytesused: 36808
> fps: 25.00 stream0 seq: 000059 bytesused: 36848
> fps: 25.00 stream0 seq: 000060 bytesused: 37480
> Camera Removed: VF0520 Live! Cam Sync: VF0520 L
> Camera Added: VF0520 Live! Cam Sync: VF0520 L
> Camera Removed: VF0520 Live! Cam Sync: VF0520 L
> 
> So the stream doesn't continue, but no crashing - so we're fine ;-)
> 
> 
> --
> Kieran
> 
> 
> 
> diff --git a/src/cam/main.cpp b/src/cam/main.cpp
> index f5aba041d7c4..3ceb6576960e 100644
> --- a/src/cam/main.cpp
> +++ b/src/cam/main.cpp
> @@ -36,6 +36,8 @@ public:
>  	void quit();
>  
>  private:
> +	void cameraAdded(std::shared_ptr<Camera> cam);
> +	void cameraRemoved(std::shared_ptr<Camera> cam);
>  	int parseOptions(int argc, char *argv[]);
>  	int prepareConfig();
>  	int listControls();
> @@ -123,6 +125,12 @@ int CamApp::init(int argc, char **argv)
>  			return ret;
>  	}
>  
> +	if (options_.isSet(OptMonitor)) {
> +		cm_->cameraAdded.connect(this, &CamApp::cameraAdded);
> +		cm_->cameraRemoved.connect(this, &CamApp::cameraRemoved);
> +		std::cout << "Monitoring new hotplug and unplug events..." << std::endl;
> +	}
> +
>  	loop_ = new EventLoop(cm_->eventDispatcher());
>  
>  	return 0;
> @@ -186,6 +194,9 @@ int CamApp::parseOptions(int argc, char *argv[])
>  			 "list-controls");
>  	parser.addOption(OptListProperties, OptionNone, "List cameras properties",
>  			 "list-properties");
> +	parser.addOption(OptMonitor, OptionNone,
> +			 "Monitor for hotplug and unplug camera events",
> +			 "monitor");
>  	parser.addOption(OptStrictFormats, OptionNone,
>  			 "Do not allow requested stream format(s) to be adjusted",
>  			 "strict-formats");
> @@ -309,6 +320,16 @@ int CamApp::infoConfiguration()
>  	return 0;
>  }
>  
> +void CamApp::cameraAdded(std::shared_ptr<Camera> cam)
> +{
> +	std::cout << "Camera Added: " << cam->name() << std::endl;
> +}
> +
> +void CamApp::cameraRemoved(std::shared_ptr<Camera> cam)
> +{
> +	std::cout << "Camera Removed: " << cam->name() << std::endl;
> +}
> +
>  int CamApp::run()
>  {
>  	int ret;
> @@ -346,6 +367,12 @@ int CamApp::run()
>  		return capture.run(options_);
>  	}
>  
> +	if (options_.isSet(OptMonitor)) {

I wonder if we should add here

		std::cout << "Press Ctrl-C to interrupt" << std::endl;

With or without that (or with a modified version),

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +		ret = loop_->exec();
> +		if (ret)
> +			std::cout << "Failed to run monitor loop" << std::endl;
> +	}
> +
>  	return 0;
>  }
>  
> diff --git a/src/cam/main.h b/src/cam/main.h
> index 6f95add31a63..ea8dfd330830 100644
> --- a/src/cam/main.h
> +++ b/src/cam/main.h
> @@ -15,6 +15,7 @@ enum {
>  	OptInfo = 'I',
>  	OptList = 'l',
>  	OptListProperties = 'p',
> +	OptMonitor = 'm',
>  	OptStream = 's',
>  	OptListControls = 256,
>  	OptStrictFormats = 257,
Kieran Bingham Aug. 3, 2020, 1:13 p.m. UTC | #3
Hi Laurent,

On 03/08/2020 14:09, Laurent Pinchart wrote:
> Hi Kieran (and Umang),
> 
> Thank you for the patch.
> 
> On Mon, Aug 03, 2020 at 01:48:23PM +0100, Kieran Bingham wrote:
>> From: Umang Jain <email@uajain.com>
>>
>> Add --monitor to monitor new hotplug and unplug camera events from
>> the CameraManager.
>>
>> Signed-off-by: Umang Jain <email@uajain.com>
>> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
>> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
>> ---
>>  src/cam/main.cpp | 27 +++++++++++++++++++++++++++
>>  src/cam/main.h   |  1 +
>>  2 files changed, 28 insertions(+)
>>
>> v3:
>>   - V1 rebased, and slightly modified to update the conditional
>>     connection of the signals during CamApp::init()
>>   - Adjust formatting of parser.addOption
>>
>>
>> Hi all,
>>
>> I am aiming to merge Umang's patch, but because I have ended up making a
>> more than superficial change to the code path in CamApp::init() I'm
>> reposting as v3. This is essentially v1 of Umangs patch (thanks, and
>> sorry for incorrectly leading you to make a v2) with the small line
>> adjustment to the parser addition, but a more impacting adjustment to
>> the conditional which enables the signals.
>>
>>
>> If there are no objections, I can merge this patch.
>>
>> Testing with the two options combined shows:
>>
>> ./build/src/cam/cam -m -c 1 -C
>>
>> fps: 25.64 stream0 seq: 000052 bytesused: 36000
>> fps: 25.00 stream0 seq: 000053 bytesused: 36024
>> fps: 25.00 stream0 seq: 000054 bytesused: 36784
>> fps: 25.64 stream0 seq: 000055 bytesused: 36968
>> fps: 25.64 stream0 seq: 000056 bytesused: 36792
>> fps: 25.00 stream0 seq: 000057 bytesused: 37040
>> fps: 25.64 stream0 seq: 000058 bytesused: 36808
>> fps: 25.00 stream0 seq: 000059 bytesused: 36848
>> fps: 25.00 stream0 seq: 000060 bytesused: 37480
>> Camera Removed: VF0520 Live! Cam Sync: VF0520 L
>> Camera Added: VF0520 Live! Cam Sync: VF0520 L
>> Camera Removed: VF0520 Live! Cam Sync: VF0520 L
>>
>> So the stream doesn't continue, but no crashing - so we're fine ;-)
>>
>>
>> --
>> Kieran
>>
>>
>>
>> diff --git a/src/cam/main.cpp b/src/cam/main.cpp
>> index f5aba041d7c4..3ceb6576960e 100644
>> --- a/src/cam/main.cpp
>> +++ b/src/cam/main.cpp
>> @@ -36,6 +36,8 @@ public:
>>  	void quit();
>>  
>>  private:
>> +	void cameraAdded(std::shared_ptr<Camera> cam);
>> +	void cameraRemoved(std::shared_ptr<Camera> cam);
>>  	int parseOptions(int argc, char *argv[]);
>>  	int prepareConfig();
>>  	int listControls();
>> @@ -123,6 +125,12 @@ int CamApp::init(int argc, char **argv)
>>  			return ret;
>>  	}
>>  
>> +	if (options_.isSet(OptMonitor)) {
>> +		cm_->cameraAdded.connect(this, &CamApp::cameraAdded);
>> +		cm_->cameraRemoved.connect(this, &CamApp::cameraRemoved);
>> +		std::cout << "Monitoring new hotplug and unplug events..." << std::endl;
>> +	}
>> +
>>  	loop_ = new EventLoop(cm_->eventDispatcher());
>>  
>>  	return 0;
>> @@ -186,6 +194,9 @@ int CamApp::parseOptions(int argc, char *argv[])
>>  			 "list-controls");
>>  	parser.addOption(OptListProperties, OptionNone, "List cameras properties",
>>  			 "list-properties");
>> +	parser.addOption(OptMonitor, OptionNone,
>> +			 "Monitor for hotplug and unplug camera events",
>> +			 "monitor");
>>  	parser.addOption(OptStrictFormats, OptionNone,
>>  			 "Do not allow requested stream format(s) to be adjusted",
>>  			 "strict-formats");
>> @@ -309,6 +320,16 @@ int CamApp::infoConfiguration()
>>  	return 0;
>>  }
>>  
>> +void CamApp::cameraAdded(std::shared_ptr<Camera> cam)
>> +{
>> +	std::cout << "Camera Added: " << cam->name() << std::endl;
>> +}
>> +
>> +void CamApp::cameraRemoved(std::shared_ptr<Camera> cam)
>> +{
>> +	std::cout << "Camera Removed: " << cam->name() << std::endl;
>> +}
>> +
>>  int CamApp::run()
>>  {
>>  	int ret;
>> @@ -346,6 +367,12 @@ int CamApp::run()
>>  		return capture.run(options_);
>>  	}
>>  
>> +	if (options_.isSet(OptMonitor)) {
> 
> I wonder if we should add here
> 
> 		std::cout << "Press Ctrl-C to interrupt" << std::endl;
> 
> With or without that (or with a modified version),

Well, I hope that is usually expected, but it does otherwise sit
reasonably quietly:

The current output is:

> ./build/src/cam/cam -m
> [5:07:13.071292781] [83575]  INFO IPAManager ipa_manager.cpp:136 libcamera is not installed. Adding '/home/libcamera/libcamera-next/build/src/ipa' to the IPA search path
> [5:07:13.076546278] [83575]  INFO Camera camera_manager.cpp:287 libcamera v0.0.11+797-785d7418-dirty
> [5:07:13.223619576] [83576]  INFO IPAProxy ipa_proxy.cpp:122 libcamera is not installed. Loading IPA configuration from '/home/libcamera/libcamera-next/src/ipa/vimc/data'
> Monitoring new hotplug and unplug events...

I hope the '...' implies that it is waiting.

Would you still like to see the "Press Ctrl-C to interrupt" ?

I'm happy with that text if you think it helps, otherwise the loop does
indeed sit there idly (excepting actual hotplug notifications of course).

--
Kieran


> 
> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> 
>> +		ret = loop_->exec();
>> +		if (ret)
>> +			std::cout << "Failed to run monitor loop" << std::endl;
>> +	}
>> +
>>  	return 0;
>>  }
>>  
>> diff --git a/src/cam/main.h b/src/cam/main.h
>> index 6f95add31a63..ea8dfd330830 100644
>> --- a/src/cam/main.h
>> +++ b/src/cam/main.h
>> @@ -15,6 +15,7 @@ enum {
>>  	OptInfo = 'I',
>>  	OptList = 'l',
>>  	OptListProperties = 'p',
>> +	OptMonitor = 'm',
>>  	OptStream = 's',
>>  	OptListControls = 256,
>>  	OptStrictFormats = 257,
>
Laurent Pinchart Aug. 3, 2020, 1:15 p.m. UTC | #4
Hi Kieran,

On Mon, Aug 03, 2020 at 02:13:52PM +0100, Kieran Bingham wrote:
> On 03/08/2020 14:09, Laurent Pinchart wrote:
> > On Mon, Aug 03, 2020 at 01:48:23PM +0100, Kieran Bingham wrote:
> >> From: Umang Jain <email@uajain.com>
> >>
> >> Add --monitor to monitor new hotplug and unplug camera events from
> >> the CameraManager.
> >>
> >> Signed-off-by: Umang Jain <email@uajain.com>
> >> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> >> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
> >> ---
> >>  src/cam/main.cpp | 27 +++++++++++++++++++++++++++
> >>  src/cam/main.h   |  1 +
> >>  2 files changed, 28 insertions(+)
> >>
> >> v3:
> >>   - V1 rebased, and slightly modified to update the conditional
> >>     connection of the signals during CamApp::init()
> >>   - Adjust formatting of parser.addOption
> >>
> >>
> >> Hi all,
> >>
> >> I am aiming to merge Umang's patch, but because I have ended up making a
> >> more than superficial change to the code path in CamApp::init() I'm
> >> reposting as v3. This is essentially v1 of Umangs patch (thanks, and
> >> sorry for incorrectly leading you to make a v2) with the small line
> >> adjustment to the parser addition, but a more impacting adjustment to
> >> the conditional which enables the signals.
> >>
> >>
> >> If there are no objections, I can merge this patch.
> >>
> >> Testing with the two options combined shows:
> >>
> >> ./build/src/cam/cam -m -c 1 -C
> >>
> >> fps: 25.64 stream0 seq: 000052 bytesused: 36000
> >> fps: 25.00 stream0 seq: 000053 bytesused: 36024
> >> fps: 25.00 stream0 seq: 000054 bytesused: 36784
> >> fps: 25.64 stream0 seq: 000055 bytesused: 36968
> >> fps: 25.64 stream0 seq: 000056 bytesused: 36792
> >> fps: 25.00 stream0 seq: 000057 bytesused: 37040
> >> fps: 25.64 stream0 seq: 000058 bytesused: 36808
> >> fps: 25.00 stream0 seq: 000059 bytesused: 36848
> >> fps: 25.00 stream0 seq: 000060 bytesused: 37480
> >> Camera Removed: VF0520 Live! Cam Sync: VF0520 L
> >> Camera Added: VF0520 Live! Cam Sync: VF0520 L
> >> Camera Removed: VF0520 Live! Cam Sync: VF0520 L
> >>
> >> So the stream doesn't continue, but no crashing - so we're fine ;-)
> >>
> >> diff --git a/src/cam/main.cpp b/src/cam/main.cpp
> >> index f5aba041d7c4..3ceb6576960e 100644
> >> --- a/src/cam/main.cpp
> >> +++ b/src/cam/main.cpp
> >> @@ -36,6 +36,8 @@ public:
> >>  	void quit();
> >>  
> >>  private:
> >> +	void cameraAdded(std::shared_ptr<Camera> cam);
> >> +	void cameraRemoved(std::shared_ptr<Camera> cam);
> >>  	int parseOptions(int argc, char *argv[]);
> >>  	int prepareConfig();
> >>  	int listControls();
> >> @@ -123,6 +125,12 @@ int CamApp::init(int argc, char **argv)
> >>  			return ret;
> >>  	}
> >>  
> >> +	if (options_.isSet(OptMonitor)) {
> >> +		cm_->cameraAdded.connect(this, &CamApp::cameraAdded);
> >> +		cm_->cameraRemoved.connect(this, &CamApp::cameraRemoved);
> >> +		std::cout << "Monitoring new hotplug and unplug events..." << std::endl;
> >> +	}
> >> +
> >>  	loop_ = new EventLoop(cm_->eventDispatcher());
> >>  
> >>  	return 0;
> >> @@ -186,6 +194,9 @@ int CamApp::parseOptions(int argc, char *argv[])
> >>  			 "list-controls");
> >>  	parser.addOption(OptListProperties, OptionNone, "List cameras properties",
> >>  			 "list-properties");
> >> +	parser.addOption(OptMonitor, OptionNone,
> >> +			 "Monitor for hotplug and unplug camera events",
> >> +			 "monitor");
> >>  	parser.addOption(OptStrictFormats, OptionNone,
> >>  			 "Do not allow requested stream format(s) to be adjusted",
> >>  			 "strict-formats");
> >> @@ -309,6 +320,16 @@ int CamApp::infoConfiguration()
> >>  	return 0;
> >>  }
> >>  
> >> +void CamApp::cameraAdded(std::shared_ptr<Camera> cam)
> >> +{
> >> +	std::cout << "Camera Added: " << cam->name() << std::endl;
> >> +}
> >> +
> >> +void CamApp::cameraRemoved(std::shared_ptr<Camera> cam)
> >> +{
> >> +	std::cout << "Camera Removed: " << cam->name() << std::endl;
> >> +}
> >> +
> >>  int CamApp::run()
> >>  {
> >>  	int ret;
> >> @@ -346,6 +367,12 @@ int CamApp::run()
> >>  		return capture.run(options_);
> >>  	}
> >>  
> >> +	if (options_.isSet(OptMonitor)) {
> > 
> > I wonder if we should add here
> > 
> > 		std::cout << "Press Ctrl-C to interrupt" << std::endl;
> > 
> > With or without that (or with a modified version),
> 
> Well, I hope that is usually expected, but it does otherwise sit
> reasonably quietly:
> 
> The current output is:
> 
> > ./build/src/cam/cam -m
> > [5:07:13.071292781] [83575]  INFO IPAManager ipa_manager.cpp:136 libcamera is not installed. Adding '/home/libcamera/libcamera-next/build/src/ipa' to the IPA search path
> > [5:07:13.076546278] [83575]  INFO Camera camera_manager.cpp:287 libcamera v0.0.11+797-785d7418-dirty
> > [5:07:13.223619576] [83576]  INFO IPAProxy ipa_proxy.cpp:122 libcamera is not installed. Loading IPA configuration from '/home/libcamera/libcamera-next/src/ipa/vimc/data'
> > Monitoring new hotplug and unplug events...
> 
> I hope the '...' implies that it is waiting.
> 
> Would you still like to see the "Press Ctrl-C to interrupt" ?
> 
> I'm happy with that text if you think it helps, otherwise the loop does
> indeed sit there idly (excepting actual hotplug notifications of course).

If it was just me I'd remove the ... and add the Ctrl-C message, as when
specifying -C -m the ... seem a bit weird. Up to you really, I don't
mind. Pick the option you like best and push :-)

> > Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
> > 
> >> +		ret = loop_->exec();
> >> +		if (ret)
> >> +			std::cout << "Failed to run monitor loop" << std::endl;
> >> +	}
> >> +
> >>  	return 0;
> >>  }
> >>  
> >> diff --git a/src/cam/main.h b/src/cam/main.h
> >> index 6f95add31a63..ea8dfd330830 100644
> >> --- a/src/cam/main.h
> >> +++ b/src/cam/main.h
> >> @@ -15,6 +15,7 @@ enum {
> >>  	OptInfo = 'I',
> >>  	OptList = 'l',
> >>  	OptListProperties = 'p',
> >> +	OptMonitor = 'm',
> >>  	OptStream = 's',
> >>  	OptListControls = 256,
> >>  	OptStrictFormats = 257,

Patch

diff --git a/src/cam/main.cpp b/src/cam/main.cpp
index f5aba041d7c4..3ceb6576960e 100644
--- a/src/cam/main.cpp
+++ b/src/cam/main.cpp
@@ -36,6 +36,8 @@  public:
 	void quit();
 
 private:
+	void cameraAdded(std::shared_ptr<Camera> cam);
+	void cameraRemoved(std::shared_ptr<Camera> cam);
 	int parseOptions(int argc, char *argv[]);
 	int prepareConfig();
 	int listControls();
@@ -123,6 +125,12 @@  int CamApp::init(int argc, char **argv)
 			return ret;
 	}
 
+	if (options_.isSet(OptMonitor)) {
+		cm_->cameraAdded.connect(this, &CamApp::cameraAdded);
+		cm_->cameraRemoved.connect(this, &CamApp::cameraRemoved);
+		std::cout << "Monitoring new hotplug and unplug events..." << std::endl;
+	}
+
 	loop_ = new EventLoop(cm_->eventDispatcher());
 
 	return 0;
@@ -186,6 +194,9 @@  int CamApp::parseOptions(int argc, char *argv[])
 			 "list-controls");
 	parser.addOption(OptListProperties, OptionNone, "List cameras properties",
 			 "list-properties");
+	parser.addOption(OptMonitor, OptionNone,
+			 "Monitor for hotplug and unplug camera events",
+			 "monitor");
 	parser.addOption(OptStrictFormats, OptionNone,
 			 "Do not allow requested stream format(s) to be adjusted",
 			 "strict-formats");
@@ -309,6 +320,16 @@  int CamApp::infoConfiguration()
 	return 0;
 }
 
+void CamApp::cameraAdded(std::shared_ptr<Camera> cam)
+{
+	std::cout << "Camera Added: " << cam->name() << std::endl;
+}
+
+void CamApp::cameraRemoved(std::shared_ptr<Camera> cam)
+{
+	std::cout << "Camera Removed: " << cam->name() << std::endl;
+}
+
 int CamApp::run()
 {
 	int ret;
@@ -346,6 +367,12 @@  int CamApp::run()
 		return capture.run(options_);
 	}
 
+	if (options_.isSet(OptMonitor)) {
+		ret = loop_->exec();
+		if (ret)
+			std::cout << "Failed to run monitor loop" << std::endl;
+	}
+
 	return 0;
 }
 
diff --git a/src/cam/main.h b/src/cam/main.h
index 6f95add31a63..ea8dfd330830 100644
--- a/src/cam/main.h
+++ b/src/cam/main.h
@@ -15,6 +15,7 @@  enum {
 	OptInfo = 'I',
 	OptList = 'l',
 	OptListProperties = 'p',
+	OptMonitor = 'm',
 	OptStream = 's',
 	OptListControls = 256,
 	OptStrictFormats = 257,