libcamera: camera: Inherit from Extensible

Use the d-pointer infrastructure offered by the Extensible class to
replace the custom implementation.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
Laurent Pinchart 2020-09-21 04:06:34 +03:00
parent 549d982f61
commit 68d2c41835
2 changed files with 80 additions and 52 deletions

View file

@ -13,6 +13,7 @@
#include <string> #include <string>
#include <libcamera/controls.h> #include <libcamera/controls.h>
#include <libcamera/extensible.h>
#include <libcamera/object.h> #include <libcamera/object.h>
#include <libcamera/request.h> #include <libcamera/request.h>
#include <libcamera/signal.h> #include <libcamera/signal.h>
@ -70,8 +71,11 @@ protected:
std::vector<StreamConfiguration> config_; std::vector<StreamConfiguration> config_;
}; };
class Camera final : public Object, public std::enable_shared_from_this<Camera> class Camera final : public Object, public std::enable_shared_from_this<Camera>,
public Extensible
{ {
LIBCAMERA_DECLARE_PRIVATE(Camera)
public: public:
static std::shared_ptr<Camera> create(PipelineHandler *pipe, static std::shared_ptr<Camera> create(PipelineHandler *pipe,
const std::string &id, const std::string &id,
@ -107,9 +111,6 @@ private:
const std::set<Stream *> &streams); const std::set<Stream *> &streams);
~Camera(); ~Camera();
class Private;
std::unique_ptr<Private> p_;
friend class PipelineHandler; friend class PipelineHandler;
void disconnect(); void disconnect();
void requestComplete(Request *request); void requestComplete(Request *request);

View file

@ -270,8 +270,10 @@ std::size_t CameraConfiguration::size() const
* \brief The vector of stream configurations * \brief The vector of stream configurations
*/ */
class Camera::Private class Camera::Private : public Extensible::Private
{ {
LIBCAMERA_DECLARE_PUBLIC(Camera)
public: public:
enum State { enum State {
CameraAvailable, CameraAvailable,
@ -280,7 +282,7 @@ public:
CameraRunning, CameraRunning,
}; };
Private(PipelineHandler *pipe, const std::string &id, Private(Camera *camera, PipelineHandler *pipe, const std::string &id,
const std::set<Stream *> &streams); const std::set<Stream *> &streams);
~Private(); ~Private();
@ -301,10 +303,11 @@ private:
std::atomic<State> state_; std::atomic<State> state_;
}; };
Camera::Private::Private(PipelineHandler *pipe, const std::string &id, Camera::Private::Private(Camera *camera, PipelineHandler *pipe,
const std::string &id,
const std::set<Stream *> &streams) const std::set<Stream *> &streams)
: pipe_(pipe->shared_from_this()), id_(id), streams_(streams), : Extensible::Private(camera), pipe_(pipe->shared_from_this()), id_(id),
disconnected_(false), state_(CameraAvailable) streams_(streams), disconnected_(false), state_(CameraAvailable)
{ {
} }
@ -519,7 +522,8 @@ std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,
*/ */
const std::string &Camera::id() const const std::string &Camera::id() const
{ {
return p_->id_; const Private *const d = LIBCAMERA_D_PTR();
return d->id_;
} }
/** /**
@ -547,7 +551,7 @@ const std::string &Camera::id() const
Camera::Camera(PipelineHandler *pipe, const std::string &id, Camera::Camera(PipelineHandler *pipe, const std::string &id,
const std::set<Stream *> &streams) const std::set<Stream *> &streams)
: p_(new Private(pipe, id, streams)) : Extensible(new Private(this, pipe, id, streams))
{ {
} }
@ -569,26 +573,30 @@ Camera::~Camera()
*/ */
void Camera::disconnect() void Camera::disconnect()
{ {
Private *const d = LIBCAMERA_D_PTR();
LOG(Camera, Debug) << "Disconnecting camera " << id(); LOG(Camera, Debug) << "Disconnecting camera " << id();
p_->disconnect(); d->disconnect();
disconnected.emit(this); disconnected.emit(this);
} }
int Camera::exportFrameBuffers(Stream *stream, int Camera::exportFrameBuffers(Stream *stream,
std::vector<std::unique_ptr<FrameBuffer>> *buffers) std::vector<std::unique_ptr<FrameBuffer>> *buffers)
{ {
int ret = p_->isAccessAllowed(Private::CameraConfigured); Private *const d = LIBCAMERA_D_PTR();
int ret = d->isAccessAllowed(Private::CameraConfigured);
if (ret < 0) if (ret < 0)
return ret; return ret;
if (streams().find(stream) == streams().end()) if (streams().find(stream) == streams().end())
return -EINVAL; return -EINVAL;
if (p_->activeStreams_.find(stream) == p_->activeStreams_.end()) if (d->activeStreams_.find(stream) == d->activeStreams_.end())
return -EINVAL; return -EINVAL;
return p_->pipe_->invokeMethod(&PipelineHandler::exportFrameBuffers, return d->pipe_->invokeMethod(&PipelineHandler::exportFrameBuffers,
ConnectionTypeBlocking, this, stream, ConnectionTypeBlocking, this, stream,
buffers); buffers);
} }
@ -619,21 +627,23 @@ int Camera::exportFrameBuffers(Stream *stream,
*/ */
int Camera::acquire() int Camera::acquire()
{ {
Private *const d = LIBCAMERA_D_PTR();
/* /*
* No manual locking is required as PipelineHandler::lock() is * No manual locking is required as PipelineHandler::lock() is
* thread-safe. * thread-safe.
*/ */
int ret = p_->isAccessAllowed(Private::CameraAvailable); int ret = d->isAccessAllowed(Private::CameraAvailable);
if (ret < 0) if (ret < 0)
return ret == -EACCES ? -EBUSY : ret; return ret == -EACCES ? -EBUSY : ret;
if (!p_->pipe_->lock()) { if (!d->pipe_->lock()) {
LOG(Camera, Info) LOG(Camera, Info)
<< "Pipeline handler in use by another process"; << "Pipeline handler in use by another process";
return -EBUSY; return -EBUSY;
} }
p_->setState(Private::CameraAcquired); d->setState(Private::CameraAcquired);
return 0; return 0;
} }
@ -654,14 +664,16 @@ int Camera::acquire()
*/ */
int Camera::release() int Camera::release()
{ {
int ret = p_->isAccessAllowed(Private::CameraAvailable, Private *const d = LIBCAMERA_D_PTR();
int ret = d->isAccessAllowed(Private::CameraAvailable,
Private::CameraConfigured, true); Private::CameraConfigured, true);
if (ret < 0) if (ret < 0)
return ret == -EACCES ? -EBUSY : ret; return ret == -EACCES ? -EBUSY : ret;
p_->pipe_->unlock(); d->pipe_->unlock();
p_->setState(Private::CameraAvailable); d->setState(Private::CameraAvailable);
return 0; return 0;
} }
@ -678,7 +690,8 @@ int Camera::release()
*/ */
const ControlInfoMap &Camera::controls() const const ControlInfoMap &Camera::controls() const
{ {
return p_->pipe_->controls(this); const Private *const d = LIBCAMERA_D_PTR();
return d->pipe_->controls(this);
} }
/** /**
@ -691,7 +704,8 @@ const ControlInfoMap &Camera::controls() const
*/ */
const ControlList &Camera::properties() const const ControlList &Camera::properties() const
{ {
return p_->pipe_->properties(this); const Private *const d = LIBCAMERA_D_PTR();
return d->pipe_->properties(this);
} }
/** /**
@ -707,7 +721,8 @@ const ControlList &Camera::properties() const
*/ */
const std::set<Stream *> &Camera::streams() const const std::set<Stream *> &Camera::streams() const
{ {
return p_->streams_; const Private *const d = LIBCAMERA_D_PTR();
return d->streams_;
} }
/** /**
@ -728,7 +743,9 @@ const std::set<Stream *> &Camera::streams() const
*/ */
std::unique_ptr<CameraConfiguration> Camera::generateConfiguration(const StreamRoles &roles) std::unique_ptr<CameraConfiguration> Camera::generateConfiguration(const StreamRoles &roles)
{ {
int ret = p_->isAccessAllowed(Private::CameraAvailable, Private *const d = LIBCAMERA_D_PTR();
int ret = d->isAccessAllowed(Private::CameraAvailable,
Private::CameraRunning); Private::CameraRunning);
if (ret < 0) if (ret < 0)
return nullptr; return nullptr;
@ -736,7 +753,7 @@ std::unique_ptr<CameraConfiguration> Camera::generateConfiguration(const StreamR
if (roles.size() > streams().size()) if (roles.size() > streams().size())
return nullptr; return nullptr;
CameraConfiguration *config = p_->pipe_->generateConfiguration(this, roles); CameraConfiguration *config = d->pipe_->generateConfiguration(this, roles);
if (!config) { if (!config) {
LOG(Camera, Debug) LOG(Camera, Debug)
<< "Pipeline handler failed to generate configuration"; << "Pipeline handler failed to generate configuration";
@ -787,7 +804,9 @@ std::unique_ptr<CameraConfiguration> Camera::generateConfiguration(const StreamR
*/ */
int Camera::configure(CameraConfiguration *config) int Camera::configure(CameraConfiguration *config)
{ {
int ret = p_->isAccessAllowed(Private::CameraAcquired, Private *const d = LIBCAMERA_D_PTR();
int ret = d->isAccessAllowed(Private::CameraAcquired,
Private::CameraConfigured); Private::CameraConfigured);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -810,26 +829,26 @@ int Camera::configure(CameraConfiguration *config)
LOG(Camera, Info) << msg.str(); LOG(Camera, Info) << msg.str();
ret = p_->pipe_->invokeMethod(&PipelineHandler::configure, ret = d->pipe_->invokeMethod(&PipelineHandler::configure,
ConnectionTypeBlocking, this, config); ConnectionTypeBlocking, this, config);
if (ret) if (ret)
return ret; return ret;
p_->activeStreams_.clear(); d->activeStreams_.clear();
for (const StreamConfiguration &cfg : *config) { for (const StreamConfiguration &cfg : *config) {
Stream *stream = cfg.stream(); Stream *stream = cfg.stream();
if (!stream) { if (!stream) {
LOG(Camera, Fatal) LOG(Camera, Fatal)
<< "Pipeline handler failed to update stream configuration"; << "Pipeline handler failed to update stream configuration";
p_->activeStreams_.clear(); d->activeStreams_.clear();
return -EINVAL; return -EINVAL;
} }
stream->configuration_ = cfg; stream->configuration_ = cfg;
p_->activeStreams_.insert(stream); d->activeStreams_.insert(stream);
} }
p_->setState(Private::CameraConfigured); d->setState(Private::CameraConfigured);
return 0; return 0;
} }
@ -857,7 +876,9 @@ int Camera::configure(CameraConfiguration *config)
*/ */
std::unique_ptr<Request> Camera::createRequest(uint64_t cookie) std::unique_ptr<Request> Camera::createRequest(uint64_t cookie)
{ {
int ret = p_->isAccessAllowed(Private::CameraConfigured, Private *const d = LIBCAMERA_D_PTR();
int ret = d->isAccessAllowed(Private::CameraConfigured,
Private::CameraRunning); Private::CameraRunning);
if (ret < 0) if (ret < 0)
return nullptr; return nullptr;
@ -889,7 +910,9 @@ std::unique_ptr<Request> Camera::createRequest(uint64_t cookie)
*/ */
int Camera::queueRequest(Request *request) int Camera::queueRequest(Request *request)
{ {
int ret = p_->isAccessAllowed(Private::CameraRunning); Private *const d = LIBCAMERA_D_PTR();
int ret = d->isAccessAllowed(Private::CameraRunning);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -907,13 +930,13 @@ int Camera::queueRequest(Request *request)
for (auto const &it : request->buffers()) { for (auto const &it : request->buffers()) {
const Stream *stream = it.first; const Stream *stream = it.first;
if (p_->activeStreams_.find(stream) == p_->activeStreams_.end()) { if (d->activeStreams_.find(stream) == d->activeStreams_.end()) {
LOG(Camera, Error) << "Invalid request"; LOG(Camera, Error) << "Invalid request";
return -EINVAL; return -EINVAL;
} }
} }
return p_->pipe_->invokeMethod(&PipelineHandler::queueRequest, return d->pipe_->invokeMethod(&PipelineHandler::queueRequest,
ConnectionTypeQueued, this, request); ConnectionTypeQueued, this, request);
} }
@ -935,18 +958,20 @@ int Camera::queueRequest(Request *request)
*/ */
int Camera::start() int Camera::start()
{ {
int ret = p_->isAccessAllowed(Private::CameraConfigured); Private *const d = LIBCAMERA_D_PTR();
int ret = d->isAccessAllowed(Private::CameraConfigured);
if (ret < 0) if (ret < 0)
return ret; return ret;
LOG(Camera, Debug) << "Starting capture"; LOG(Camera, Debug) << "Starting capture";
ret = p_->pipe_->invokeMethod(&PipelineHandler::start, ret = d->pipe_->invokeMethod(&PipelineHandler::start,
ConnectionTypeBlocking, this); ConnectionTypeBlocking, this);
if (ret) if (ret)
return ret; return ret;
p_->setState(Private::CameraRunning); d->setState(Private::CameraRunning);
return 0; return 0;
} }
@ -967,15 +992,17 @@ int Camera::start()
*/ */
int Camera::stop() int Camera::stop()
{ {
int ret = p_->isAccessAllowed(Private::CameraRunning); Private *const d = LIBCAMERA_D_PTR();
int ret = d->isAccessAllowed(Private::CameraRunning);
if (ret < 0) if (ret < 0)
return ret; return ret;
LOG(Camera, Debug) << "Stopping capture"; LOG(Camera, Debug) << "Stopping capture";
p_->setState(Private::CameraConfigured); d->setState(Private::CameraConfigured);
p_->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking, d->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking,
this); this);
return 0; return 0;