summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libcamera/pipeline/uvcvideo.cpp80
1 files changed, 57 insertions, 23 deletions
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index adfdc4c6..a9edd22d 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -13,6 +13,7 @@
#include "log.h"
#include "media_device.h"
#include "pipeline_handler.h"
+#include "utils.h"
#include "v4l2_device.h"
namespace libcamera {
@@ -42,21 +43,39 @@ public:
bool match(DeviceEnumerator *enumerator);
private:
+ class UVCCameraData : public CameraData
+ {
+ public:
+ UVCCameraData()
+ : video_(nullptr)
+ {
+ }
+
+ ~UVCCameraData()
+ {
+ delete video_;
+ }
+
+ V4L2Device *video_;
+ Stream stream_;
+ };
+
+ UVCCameraData *cameraData(const Camera *camera)
+ {
+ return static_cast<UVCCameraData *>(
+ PipelineHandler::cameraData(camera));
+ }
+
std::shared_ptr<MediaDevice> media_;
- V4L2Device *video_;
- Stream stream_;
};
PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager)
- : PipelineHandler(manager), media_(nullptr), video_(nullptr)
+ : PipelineHandler(manager), media_(nullptr)
{
}
PipelineHandlerUVC::~PipelineHandlerUVC()
{
- if (video_)
- delete video_;
-
if (media_)
media_->release();
}
@@ -65,8 +84,9 @@ std::map<Stream *, StreamConfiguration>
PipelineHandlerUVC::streamConfiguration(Camera *camera,
std::set<Stream *> &streams)
{
- std::map<Stream *, StreamConfiguration> configs;
+ UVCCameraData *data = cameraData(camera);
+ std::map<Stream *, StreamConfiguration> configs;
StreamConfiguration config{};
LOG(UVC, Debug) << "Retrieving default format";
@@ -75,7 +95,7 @@ PipelineHandlerUVC::streamConfiguration(Camera *camera,
config.pixelFormat = V4L2_PIX_FMT_YUYV;
config.bufferCount = 4;
- configs[&stream_] = config;
+ configs[&data->stream_] = config;
return configs;
}
@@ -83,7 +103,8 @@ PipelineHandlerUVC::streamConfiguration(Camera *camera,
int PipelineHandlerUVC::configureStreams(Camera *camera,
std::map<Stream *, StreamConfiguration> &config)
{
- StreamConfiguration *cfg = &config[&stream_];
+ UVCCameraData *data = cameraData(camera);
+ StreamConfiguration *cfg = &config[&data->stream_];
int ret;
LOG(UVC, Debug) << "Configure the camera for resolution "
@@ -94,7 +115,7 @@ int PipelineHandlerUVC::configureStreams(Camera *camera,
format.height = cfg->height;
format.fourcc = cfg->pixelFormat;
- ret = video_->setFormat(&format);
+ ret = data->video_->setFormat(&format);
if (ret)
return ret;
@@ -108,31 +129,36 @@ int PipelineHandlerUVC::configureStreams(Camera *camera,
int PipelineHandlerUVC::allocateBuffers(Camera *camera, Stream *stream)
{
+ UVCCameraData *data = cameraData(camera);
const StreamConfiguration &cfg = stream->configuration();
LOG(UVC, Debug) << "Requesting " << cfg.bufferCount << " buffers";
- return video_->exportBuffers(&stream->bufferPool());
+ return data->video_->exportBuffers(&stream->bufferPool());
}
int PipelineHandlerUVC::freeBuffers(Camera *camera, Stream *stream)
{
- return video_->releaseBuffers();
+ UVCCameraData *data = cameraData(camera);
+ return data->video_->releaseBuffers();
}
int PipelineHandlerUVC::start(const Camera *camera)
{
- return video_->streamOn();
+ UVCCameraData *data = cameraData(camera);
+ return data->video_->streamOn();
}
void PipelineHandlerUVC::stop(const Camera *camera)
{
- video_->streamOff();
+ UVCCameraData *data = cameraData(camera);
+ data->video_->streamOff();
}
int PipelineHandlerUVC::queueRequest(const Camera *camera, Request *request)
{
- Buffer *buffer = request->findBuffer(&stream_);
+ UVCCameraData *data = cameraData(camera);
+ Buffer *buffer = request->findBuffer(&data->stream_);
if (!buffer) {
LOG(UVC, Error)
<< "Attempt to queue request with invalid stream";
@@ -140,7 +166,7 @@ int PipelineHandlerUVC::queueRequest(const Camera *camera, Request *request)
return -ENOENT;
}
- video_->queueBuffer(buffer);
+ data->video_->queueBuffer(buffer);
return 0;
}
@@ -150,29 +176,37 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
DeviceMatch dm("uvcvideo");
media_ = enumerator->search(dm);
-
if (!media_)
return false;
media_->acquire();
+ std::unique_ptr<UVCCameraData> data = utils::make_unique<UVCCameraData>();
+
+ /* Locate and open the default video node. */
for (MediaEntity *entity : media_->entities()) {
if (entity->flags() & MEDIA_ENT_FL_DEFAULT) {
- video_ = new V4L2Device(entity);
+ data->video_ = new V4L2Device(entity);
break;
}
}
- if (!video_ || video_->open()) {
- if (!video_)
- LOG(UVC, Error) << "Could not find a default video device";
-
+ if (!data->video_) {
+ LOG(UVC, Error) << "Could not find a default video device";
return false;
}
- std::set<Stream *> streams{ &stream_ };
+ if (data->video_->open())
+ return false;
+
+ /* Create and register the camera. */
+ std::set<Stream *> streams{ &data->stream_ };
std::shared_ptr<Camera> camera = Camera::create(this, media_->model(), streams);
+
+ setCameraData(camera.get(), std::move(data));
registerCamera(std::move(camera));
+
+ /* Enable hot-unplug notifications. */
hotplugMediaDevice(media_.get());
return true;