mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-25 01:25:08 +03:00
libcamera: pipeline: simple: Open all video devices at match() time
Move opening of video devices at match() time, the same way as subdevs are opened, to make the handling of V4L2 video devices and subdevices more consistent. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Tested-by: Martin Kepplinger <martin.kepplinger@puri.sm>
This commit is contained in:
parent
2b31458763
commit
f69b19667f
1 changed files with 33 additions and 34 deletions
|
@ -83,14 +83,12 @@ LOG_DEFINE_CATEGORY(SimplePipeline)
|
||||||
* handled by this heuristic.
|
* handled by this heuristic.
|
||||||
*
|
*
|
||||||
* Once the camera data instances have been created, the match() function
|
* Once the camera data instances have been created, the match() function
|
||||||
* creates a V4L2Subdevice instance for each entity used by any of the cameras
|
* creates a V4L2VideoDevice or V4L2Subdevice instance for each entity used by
|
||||||
* and stores the instances in SimplePipelineHandler::subdevs_, accessible by
|
* any of the cameras and stores them in SimplePipelineHandler::entities_,
|
||||||
* the SimpleCameraData class through the SimplePipelineHandler::subdev()
|
* accessible by the SimpleCameraData class through the
|
||||||
* function. This avoids duplication of subdev instances between different
|
* SimplePipelineHandler::subdev() and SimplePipelineHandler::video() functions.
|
||||||
* cameras when the same entity is used in multiple paths. A similar mechanism
|
* This avoids duplication of subdev instances between different cameras when
|
||||||
* is used for V4L2VideoDevice instances, but instances are in this case created
|
* the same entity is used in multiple paths.
|
||||||
* on demand when accessed through SimplePipelineHandler::video() instead of all
|
|
||||||
* in one go at initialization time.
|
|
||||||
*
|
*
|
||||||
* Finally, all camera data instances are initialized to gather information
|
* Finally, all camera data instances are initialized to gather information
|
||||||
* about the possible pipeline configurations for the corresponding camera. If
|
* about the possible pipeline configurations for the corresponding camera. If
|
||||||
|
@ -403,10 +401,7 @@ int SimpleCameraData::init()
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
video_ = pipe->video(entities_.back().entity);
|
video_ = pipe->video(entities_.back().entity);
|
||||||
if (!video_) {
|
ASSERT(video_);
|
||||||
LOG(SimplePipeline, Error) << "Failed to open video device";
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup links first as some subdev drivers take active links into
|
* Setup links first as some subdev drivers take active links into
|
||||||
|
@ -1074,24 +1069,44 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert all entities in the global entities list. Create and open
|
* Insert all entities in the global entities list. Create and open
|
||||||
* V4L2Subdevice instances for each entity corresponding to a V4L2
|
* V4L2VideoDevice and V4L2Subdevice instances for the corresponding
|
||||||
* subdevice.
|
* entities.
|
||||||
*/
|
*/
|
||||||
for (MediaEntity *entity : entities) {
|
for (MediaEntity *entity : entities) {
|
||||||
|
std::unique_ptr<V4L2VideoDevice> video;
|
||||||
std::unique_ptr<V4L2Subdevice> subdev;
|
std::unique_ptr<V4L2Subdevice> subdev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (entity->type() == MediaEntity::Type::V4L2Subdevice) {
|
switch (entity->type()) {
|
||||||
|
case MediaEntity::Type::V4L2VideoDevice:
|
||||||
|
video = std::make_unique<V4L2VideoDevice>(entity);
|
||||||
|
ret = video->open();
|
||||||
|
if (ret < 0) {
|
||||||
|
LOG(SimplePipeline, Error)
|
||||||
|
<< "Failed to open " << video->deviceNode()
|
||||||
|
<< ": " << strerror(-ret);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
video->bufferReady.connect(this, &SimplePipelineHandler::bufferReady);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MediaEntity::Type::V4L2Subdevice:
|
||||||
subdev = std::make_unique<V4L2Subdevice>(entity);
|
subdev = std::make_unique<V4L2Subdevice>(entity);
|
||||||
int ret = subdev->open();
|
ret = subdev->open();
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
LOG(SimplePipeline, Error)
|
LOG(SimplePipeline, Error)
|
||||||
<< "Failed to open " << subdev->deviceNode()
|
<< "Failed to open " << subdev->deviceNode()
|
||||||
<< ": " << strerror(-ret);
|
<< ": " << strerror(-ret);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
entities_[entity] = { nullptr, std::move(subdev) };
|
entities_[entity] = { std::move(video), std::move(subdev) };
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize each pipeline and register a corresponding camera. */
|
/* Initialize each pipeline and register a corresponding camera. */
|
||||||
|
@ -1119,27 +1134,11 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
|
||||||
|
|
||||||
V4L2VideoDevice *SimplePipelineHandler::video(const MediaEntity *entity)
|
V4L2VideoDevice *SimplePipelineHandler::video(const MediaEntity *entity)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
* Return the V4L2VideoDevice corresponding to the media entity, either
|
|
||||||
* as a previously constructed device if available from the cache, or
|
|
||||||
* by constructing a new one.
|
|
||||||
*/
|
|
||||||
|
|
||||||
auto iter = entities_.find(entity);
|
auto iter = entities_.find(entity);
|
||||||
if (iter == entities_.end())
|
if (iter == entities_.end())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
EntityData &data = iter->second;
|
return iter->second.video.get();
|
||||||
if (data.video)
|
|
||||||
return data.video.get();
|
|
||||||
|
|
||||||
data.video = std::make_unique<V4L2VideoDevice>(entity);
|
|
||||||
if (data.video->open() < 0)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
data.video->bufferReady.connect(this, &SimplePipelineHandler::bufferReady);
|
|
||||||
|
|
||||||
return data.video.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
V4L2Subdevice *SimplePipelineHandler::subdev(const MediaEntity *entity)
|
V4L2Subdevice *SimplePipelineHandler::subdev(const MediaEntity *entity)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue