treewide: Query list of cameras just once

This is more efficient since only a single vector will be constructed,
and furthermore, it prevents the TOCTOU issue that might arise when
the list of cameras changes between the two queries.

Signed-off-by: Barnabás Pőcze <pobrn@protonmail.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Barnabás Pőcze 2024-04-29 14:24:09 +00:00 committed by Kieran Bingham
parent aee16c0691
commit e77a275110
3 changed files with 18 additions and 10 deletions

View file

@ -116,19 +116,21 @@ available.
.. code:: cpp .. code:: cpp
if (cm->cameras().empty()) { auto cameras = cm->cameras();
if (cameras.empty()) {
std::cout << "No cameras were identified on the system." std::cout << "No cameras were identified on the system."
<< std::endl; << std::endl;
cm->stop(); cm->stop();
return EXIT_FAILURE; return EXIT_FAILURE;
} }
std::string cameraId = cm->cameras()[0]->id(); std::string cameraId = cameras[0]->id();
camera = cm->get(cameraId);
auto camera = cm->get(cameraId);
/* /*
* Note that is equivalent to: * Note that `camera` may not compare equal to `cameras[0]`.
* camera = cm->cameras()[0]; * In fact, it might simply be a `nullptr`, as the particular
* device might have disappeared (and reappeared) in the meantime.
*/ */
Once a camera has been selected an application needs to acquire an exclusive Once a camera has been selected an application needs to acquire an exclusive

View file

@ -39,9 +39,14 @@ CameraSession::CameraSession(CameraManager *cm,
{ {
char *endptr; char *endptr;
unsigned long index = strtoul(cameraId.c_str(), &endptr, 10); unsigned long index = strtoul(cameraId.c_str(), &endptr, 10);
if (*endptr == '\0' && index > 0 && index <= cm->cameras().size())
camera_ = cm->cameras()[index - 1]; if (*endptr == '\0' && index > 0) {
else auto cameras = cm->cameras();
if (index <= cameras.size())
camera_ = cameras[index - 1];
}
if (!camera_)
camera_ = cm->get(cameraId); camera_ = cm->get(cameraId);
if (!camera_) { if (!camera_) {

View file

@ -385,13 +385,14 @@ gst_libcamera_src_open(GstLibcameraSrc *self)
return false; return false;
} }
} else { } else {
if (cm->cameras().empty()) { auto cameras = cm->cameras();
if (cameras.empty()) {
GST_ELEMENT_ERROR(self, RESOURCE, NOT_FOUND, GST_ELEMENT_ERROR(self, RESOURCE, NOT_FOUND,
("Could not find any supported camera on this system."), ("Could not find any supported camera on this system."),
("libcamera::CameraMananger::cameras() is empty")); ("libcamera::CameraMananger::cameras() is empty"));
return false; return false;
} }
cam = cm->cameras()[0]; cam = cameras[0];
} }
GST_INFO_OBJECT(self, "Using camera '%s'", cam->id().c_str()); GST_INFO_OBJECT(self, "Using camera '%s'", cam->id().c_str());