@@ -53,7 +53,7 @@ public:
std::map<PixelFormat, std::vector<SizeRange>> formats_;
private:
- bool generateId();
+ bool generateId(V4L2VideoDevice *video);
std::string id_;
};
@@ -74,6 +74,9 @@ class PipelineHandlerUVC : public PipelineHandler
public:
PipelineHandlerUVC(CameraManager *manager);
+ bool acquireDevice(Camera *camera);
+ void releaseDevice(Camera *camera);
+
std::unique_ptr<CameraConfiguration> generateConfiguration(Camera *camera,
const StreamRoles &roles) override;
int configure(Camera *camera, CameraConfiguration *config) override;
@@ -178,6 +181,28 @@ PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager)
{
}
+bool PipelineHandlerUVC::acquireDevice(Camera *camera)
+{
+ UVCCameraData *data = cameraData(camera);
+
+ int ret = data->video_->open();
+ if (ret)
+ return false;
+
+ data->video_->bufferReady.connect(data, &UVCCameraData::bufferReady);
+
+ return true;
+}
+
+void PipelineHandlerUVC::releaseDevice(Camera *camera)
+{
+ UVCCameraData *data = cameraData(camera);
+
+ data->video_->bufferReady.disconnect();
+
+ data->video_->close();
+}
+
std::unique_ptr<CameraConfiguration>
PipelineHandlerUVC::generateConfiguration(Camera *camera,
const StreamRoles &roles)
@@ -426,16 +451,15 @@ int UVCCameraData::init(MediaDevice *media)
return -ENODEV;
}
+ std::unique_ptr<V4L2VideoDevice> video = std::make_unique<V4L2VideoDevice>(*entity);
+
/* Create and open the video device. */
- video_ = std::make_unique<V4L2VideoDevice>(*entity);
- ret = video_->open();
+ ret = video->open();
if (ret)
return ret;
- video_->bufferReady.connect(this, &UVCCameraData::bufferReady);
-
/* Generate the camera ID. */
- if (!generateId()) {
+ if (!generateId(video.get())) {
LOG(UVC, Error) << "Failed to generate camera ID";
return -EINVAL;
}
@@ -445,7 +469,7 @@ int UVCCameraData::init(MediaDevice *media)
* resolution from the largest size it advertises.
*/
Size resolution;
- for (const auto &format : video_->formats()) {
+ for (const auto &format : video->formats()) {
PixelFormat pixelFormat = format.first.toPixelFormat();
if (!pixelFormat.isValid())
continue;
@@ -485,7 +509,7 @@ int UVCCameraData::init(MediaDevice *media)
* the _UPC.
*/
properties::LocationEnum location = properties::CameraLocationExternal;
- std::ifstream file(video_->devicePath() + "/../removable");
+ std::ifstream file(video->devicePath() + "/../removable");
if (file.is_open()) {
std::string value;
std::getline(file, value);
@@ -503,7 +527,7 @@ int UVCCameraData::init(MediaDevice *media)
/* Initialise the supported controls. */
ControlInfoMap::Map ctrls;
- for (const auto &ctrl : video_->controls()) {
+ for (const auto &ctrl : video->controls()) {
uint32_t cid = ctrl.first->id();
const ControlInfo &info = ctrl.second;
@@ -512,12 +536,21 @@ int UVCCameraData::init(MediaDevice *media)
controlInfo_ = ControlInfoMap(std::move(ctrls), controls::controls);
+ /*
+ * Close the camera until it is acquired to prevent holding on to
+ * resources that we do not own, or keeping devices powered when not in
+ * use.
+ */
+ video->close();
+
+ video_ = std::move(video);
+
return 0;
}
-bool UVCCameraData::generateId()
+bool UVCCameraData::generateId(V4L2VideoDevice *video)
{
- const std::string path = video_->devicePath();
+ const std::string path = video->devicePath();
/* Create a controller ID from first device described in firmware. */
std::string controllerId;