libcamera: pipeline_handler: Return unique_ptr from generateConfiguration()

The PipelineHandler::generateConfiguration() function allocates a
CameraConfiguration instance and returns it. The ownership of the
instance is transferred to the caller. This is a perfect match for a
std::unique_ptr<>, which the Camera::generateConfiguration() function
already returns. Update PipelineHandler::generateConfiguration() to
match it. This fixes a memory leak in one of the error return paths in
the IPU3 pipeline handler.

While at it, update the Camera::generateConfiguration() function
documentation to drop the sentence that describes the ownership
transfer, as that is implied by usage of std::unique_ptr<>.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>
Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
Laurent Pinchart 2022-10-22 23:53:26 +03:00
parent 00b650b6b8
commit a07968bed2
9 changed files with 38 additions and 34 deletions

View file

@ -48,7 +48,7 @@ public:
bool acquire(); bool acquire();
void release(); void release();
virtual CameraConfiguration *generateConfiguration(Camera *camera, virtual std::unique_ptr<CameraConfiguration> generateConfiguration(Camera *camera,
const StreamRoles &roles) = 0; const StreamRoles &roles) = 0;
virtual int configure(Camera *camera, CameraConfiguration *config) = 0; virtual int configure(Camera *camera, CameraConfiguration *config) = 0;

View file

@ -934,8 +934,7 @@ const std::set<Stream *> &Camera::streams() const
* \context This function is \threadsafe. * \context This function is \threadsafe.
* *
* \return A CameraConfiguration if the requested roles can be satisfied, or a * \return A CameraConfiguration if the requested roles can be satisfied, or a
* null pointer otherwise. The ownership of the returned configuration is * null pointer otherwise.
* passed to the caller.
*/ */
std::unique_ptr<CameraConfiguration> Camera::generateConfiguration(const StreamRoles &roles) std::unique_ptr<CameraConfiguration> Camera::generateConfiguration(const StreamRoles &roles)
{ {
@ -949,7 +948,8 @@ std::unique_ptr<CameraConfiguration> Camera::generateConfiguration(const StreamR
if (roles.size() > streams().size()) if (roles.size() > streams().size())
return nullptr; return nullptr;
CameraConfiguration *config = d->pipe_->generateConfiguration(this, roles); std::unique_ptr<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";
@ -966,7 +966,7 @@ std::unique_ptr<CameraConfiguration> Camera::generateConfiguration(const StreamR
LOG(Camera, Debug) << msg.str(); LOG(Camera, Debug) << msg.str();
return std::unique_ptr<CameraConfiguration>(config); return config;
} }
/** /**

View file

@ -136,7 +136,7 @@ public:
PipelineHandlerIPU3(CameraManager *manager); PipelineHandlerIPU3(CameraManager *manager);
CameraConfiguration *generateConfiguration(Camera *camera, std::unique_ptr<CameraConfiguration> generateConfiguration(Camera *camera,
const StreamRoles &roles) override; const StreamRoles &roles) override;
int configure(Camera *camera, CameraConfiguration *config) override; int configure(Camera *camera, CameraConfiguration *config) override;
@ -424,11 +424,12 @@ PipelineHandlerIPU3::PipelineHandlerIPU3(CameraManager *manager)
{ {
} }
CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera, std::unique_ptr<CameraConfiguration>
const StreamRoles &roles) PipelineHandlerIPU3::generateConfiguration(Camera *camera, const StreamRoles &roles)
{ {
IPU3CameraData *data = cameraData(camera); IPU3CameraData *data = cameraData(camera);
IPU3CameraConfiguration *config = new IPU3CameraConfiguration(data); std::unique_ptr<IPU3CameraConfiguration> config =
std::make_unique<IPU3CameraConfiguration>(data);
if (roles.empty()) if (roles.empty())
return config; return config;
@ -494,7 +495,6 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,
default: default:
LOG(IPU3, Error) LOG(IPU3, Error)
<< "Requested stream role not supported: " << role; << "Requested stream role not supported: " << role;
delete config;
return nullptr; return nullptr;
} }

View file

@ -323,7 +323,8 @@ class PipelineHandlerRPi : public PipelineHandler
public: public:
PipelineHandlerRPi(CameraManager *manager); PipelineHandlerRPi(CameraManager *manager);
CameraConfiguration *generateConfiguration(Camera *camera, const StreamRoles &roles) override; std::unique_ptr<CameraConfiguration> generateConfiguration(Camera *camera,
const StreamRoles &roles) override;
int configure(Camera *camera, CameraConfiguration *config) override; int configure(Camera *camera, CameraConfiguration *config) override;
int exportFrameBuffers(Camera *camera, Stream *stream, int exportFrameBuffers(Camera *camera, Stream *stream,
@ -561,11 +562,12 @@ PipelineHandlerRPi::PipelineHandlerRPi(CameraManager *manager)
{ {
} }
CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera, std::unique_ptr<CameraConfiguration>
const StreamRoles &roles) PipelineHandlerRPi::generateConfiguration(Camera *camera, const StreamRoles &roles)
{ {
RPiCameraData *data = cameraData(camera); RPiCameraData *data = cameraData(camera);
CameraConfiguration *config = new RPiCameraConfiguration(data); std::unique_ptr<CameraConfiguration> config =
std::make_unique<RPiCameraConfiguration>(data);
V4L2SubdeviceFormat sensorFormat; V4L2SubdeviceFormat sensorFormat;
unsigned int bufferCount; unsigned int bufferCount;
PixelFormat pixelFormat; PixelFormat pixelFormat;
@ -640,13 +642,11 @@ CameraConfiguration *PipelineHandlerRPi::generateConfiguration(Camera *camera,
default: default:
LOG(RPI, Error) << "Requested stream role not supported: " LOG(RPI, Error) << "Requested stream role not supported: "
<< role; << role;
delete config;
return nullptr; return nullptr;
} }
if (rawCount > 1 || outCount > 2) { if (rawCount > 1 || outCount > 2) {
LOG(RPI, Error) << "Invalid stream roles requested"; LOG(RPI, Error) << "Invalid stream roles requested";
delete config;
return nullptr; return nullptr;
} }

View file

@ -142,7 +142,7 @@ class PipelineHandlerRkISP1 : public PipelineHandler
public: public:
PipelineHandlerRkISP1(CameraManager *manager); PipelineHandlerRkISP1(CameraManager *manager);
CameraConfiguration *generateConfiguration(Camera *camera, std::unique_ptr<CameraConfiguration> generateConfiguration(Camera *camera,
const StreamRoles &roles) override; const StreamRoles &roles) override;
int configure(Camera *camera, CameraConfiguration *config) override; int configure(Camera *camera, CameraConfiguration *config) override;
@ -539,7 +539,8 @@ PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager)
* Pipeline Operations * Pipeline Operations
*/ */
CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera, std::unique_ptr<CameraConfiguration>
PipelineHandlerRkISP1::generateConfiguration(Camera *camera,
const StreamRoles &roles) const StreamRoles &roles)
{ {
RkISP1CameraData *data = cameraData(camera); RkISP1CameraData *data = cameraData(camera);
@ -550,7 +551,8 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera
return nullptr; return nullptr;
} }
CameraConfiguration *config = new RkISP1CameraConfiguration(camera, data); std::unique_ptr<CameraConfiguration> config =
std::make_unique<RkISP1CameraConfiguration>(camera, data);
if (roles.empty()) if (roles.empty())
return config; return config;
@ -595,7 +597,6 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera
default: default:
LOG(RkISP1, Warning) LOG(RkISP1, Warning)
<< "Requested stream role not supported: " << role; << "Requested stream role not supported: " << role;
delete config;
return nullptr; return nullptr;
} }

View file

@ -311,7 +311,7 @@ class SimplePipelineHandler : public PipelineHandler
public: public:
SimplePipelineHandler(CameraManager *manager); SimplePipelineHandler(CameraManager *manager);
CameraConfiguration *generateConfiguration(Camera *camera, std::unique_ptr<CameraConfiguration> generateConfiguration(Camera *camera,
const StreamRoles &roles) override; const StreamRoles &roles) override;
int configure(Camera *camera, CameraConfiguration *config) override; int configure(Camera *camera, CameraConfiguration *config) override;
@ -1037,12 +1037,12 @@ SimplePipelineHandler::SimplePipelineHandler(CameraManager *manager)
{ {
} }
CameraConfiguration *SimplePipelineHandler::generateConfiguration(Camera *camera, std::unique_ptr<CameraConfiguration>
const StreamRoles &roles) SimplePipelineHandler::generateConfiguration(Camera *camera, const StreamRoles &roles)
{ {
SimpleCameraData *data = cameraData(camera); SimpleCameraData *data = cameraData(camera);
CameraConfiguration *config = std::unique_ptr<CameraConfiguration> config =
new SimpleCameraConfiguration(camera, data); std::make_unique<SimpleCameraConfiguration>(camera, data);
if (roles.empty()) if (roles.empty())
return config; return config;

View file

@ -74,7 +74,7 @@ class PipelineHandlerUVC : public PipelineHandler
public: public:
PipelineHandlerUVC(CameraManager *manager); PipelineHandlerUVC(CameraManager *manager);
CameraConfiguration *generateConfiguration(Camera *camera, std::unique_ptr<CameraConfiguration> generateConfiguration(Camera *camera,
const StreamRoles &roles) override; const StreamRoles &roles) override;
int configure(Camera *camera, CameraConfiguration *config) override; int configure(Camera *camera, CameraConfiguration *config) override;
@ -178,11 +178,13 @@ PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager)
{ {
} }
CameraConfiguration *PipelineHandlerUVC::generateConfiguration(Camera *camera, std::unique_ptr<CameraConfiguration>
PipelineHandlerUVC::generateConfiguration(Camera *camera,
const StreamRoles &roles) const StreamRoles &roles)
{ {
UVCCameraData *data = cameraData(camera); UVCCameraData *data = cameraData(camera);
CameraConfiguration *config = new UVCCameraConfiguration(data); std::unique_ptr<CameraConfiguration> config =
std::make_unique<UVCCameraConfiguration>(data);
if (roles.empty()) if (roles.empty())
return config; return config;

View file

@ -84,7 +84,7 @@ class PipelineHandlerVimc : public PipelineHandler
public: public:
PipelineHandlerVimc(CameraManager *manager); PipelineHandlerVimc(CameraManager *manager);
CameraConfiguration *generateConfiguration(Camera *camera, std::unique_ptr<CameraConfiguration> generateConfiguration(Camera *camera,
const StreamRoles &roles) override; const StreamRoles &roles) override;
int configure(Camera *camera, CameraConfiguration *config) override; int configure(Camera *camera, CameraConfiguration *config) override;
@ -189,11 +189,13 @@ PipelineHandlerVimc::PipelineHandlerVimc(CameraManager *manager)
{ {
} }
CameraConfiguration *PipelineHandlerVimc::generateConfiguration(Camera *camera, std::unique_ptr<CameraConfiguration>
PipelineHandlerVimc::generateConfiguration(Camera *camera,
const StreamRoles &roles) const StreamRoles &roles)
{ {
VimcCameraData *data = cameraData(camera); VimcCameraData *data = cameraData(camera);
CameraConfiguration *config = new VimcCameraConfiguration(data); std::unique_ptr<CameraConfiguration> config =
std::make_unique<VimcCameraConfiguration>(data);
if (roles.empty()) if (roles.empty())
return config; return config;

View file

@ -233,8 +233,7 @@ void PipelineHandler::unlockMediaDevices()
* handler. * handler.
* *
* \return A valid CameraConfiguration if the requested roles can be satisfied, * \return A valid CameraConfiguration if the requested roles can be satisfied,
* or a null pointer otherwise. The ownership of the returned configuration is * or a null pointer otherwise.
* passed to the caller.
*/ */
/** /**