From patchwork Tue Dec 8 01:49:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 10604 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id D37E9BDB20 for ; Tue, 8 Dec 2020 01:50:33 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id 64D0967E6C; Tue, 8 Dec 2020 02:50:33 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="bxKuWHzj"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 32B3A60323 for ; Tue, 8 Dec 2020 02:50:31 +0100 (CET) Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id B0E46DD for ; Tue, 8 Dec 2020 02:50:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1607392230; bh=UHhxMC2AlDs4qYTQn+STYpQJDjm3VveaNmiUtfgETP8=; h=From:To:Subject:Date:From; b=bxKuWHzjfPDjWQsRtV4VoyVVWpyId2bDddzRpbxOlcTX0+mmb7s1OqQCWyY/0Y2tL 1GFYiQ+bR+V8IvqzXuoDmx2W9zTOzPD4d+g1I/qcO2fcBSHg9Z61IATkHJI0kFX5I/ wxOZyMEA763u7lh7vaqoxW3itYQ2IC0IaXPXHrC4= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Tue, 8 Dec 2020 03:49:50 +0200 Message-Id: <20201208014951.30989-1-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 1/2] libcamera: v4l2_subdevice: Return a unique pointer from fromEntityName() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The fromEntityName() function returns a pointer to a newly allocated V4L2Subdevice instance, which must be deleted by the caller. This opens the door to memory leaks. Return a unique pointer instead, which conveys the API semantics better than a sentence in the documentation. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Jacopo Mondi --- include/libcamera/internal/v4l2_subdevice.h | 5 +++-- src/libcamera/pipeline/ipu3/imgu.cpp | 2 +- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 6 ++---- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 3 +-- src/libcamera/pipeline/rkisp1/rkisp1_path.h | 3 ++- src/libcamera/v4l2_subdevice.cpp | 10 ++++------ 6 files changed, 13 insertions(+), 16 deletions(-) diff --git a/include/libcamera/internal/v4l2_subdevice.h b/include/libcamera/internal/v4l2_subdevice.h index 02ee3e914a8b..eb25fa2fd01b 100644 --- a/include/libcamera/internal/v4l2_subdevice.h +++ b/include/libcamera/internal/v4l2_subdevice.h @@ -7,6 +7,7 @@ #ifndef __LIBCAMERA_INTERNAL_V4L2_SUBDEVICE_H__ #define __LIBCAMERA_INTERNAL_V4L2_SUBDEVICE_H__ +#include #include #include @@ -60,8 +61,8 @@ public: int setFormat(unsigned int pad, V4L2SubdeviceFormat *format, Whence whence = ActiveFormat); - static V4L2Subdevice *fromEntityName(const MediaDevice *media, - const std::string &entity); + static std::unique_ptr + fromEntityName(const MediaDevice *media, const std::string &entity); protected: std::string logPrefix() const override; diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index a4d74a62f69a..bfe9624c7797 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -343,7 +343,7 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index) * by the match() function: no need to check for newly created * video devices and subdevice validity here. */ - imgu_.reset(V4L2Subdevice::fromEntityName(media, name_)); + imgu_ = V4L2Subdevice::fromEntityName(media, name_); ret = imgu_->open(); if (ret) return ret; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 6e74a49abfda..bcfe6c0514ab 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -217,7 +217,7 @@ private: int freeBuffers(Camera *camera); MediaDevice *media_; - V4L2Subdevice *isp_; + std::unique_ptr isp_; V4L2VideoDevice *param_; V4L2VideoDevice *stat_; @@ -599,8 +599,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() } PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager) - : PipelineHandler(manager), isp_(nullptr), param_(nullptr), - stat_(nullptr) + : PipelineHandler(manager), param_(nullptr), stat_(nullptr) { } @@ -608,7 +607,6 @@ PipelineHandlerRkISP1::~PipelineHandlerRkISP1() { delete param_; delete stat_; - delete isp_; } /* ----------------------------------------------------------------------------- diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index 3f77b1c12f9d..e05d9dd657cd 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -24,14 +24,13 @@ RkISP1Path::RkISP1Path(const char *name, const Span &formats, const Size &minResolution, const Size &maxResolution) : name_(name), running_(false), formats_(formats), minResolution_(minResolution), maxResolution_(maxResolution), - resizer_(nullptr), video_(nullptr), link_(nullptr) + video_(nullptr), link_(nullptr) { } RkISP1Path::~RkISP1Path() { delete video_; - delete resizer_; } bool RkISP1Path::init(MediaDevice *media) diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h index 8f443e5179f6..f06ac5a731cc 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h @@ -7,6 +7,7 @@ #ifndef __LIBCAMERA_PIPELINE_RKISP1_PATH_H__ #define __LIBCAMERA_PIPELINE_RKISP1_PATH_H__ +#include #include #include @@ -65,7 +66,7 @@ private: const Size minResolution_; const Size maxResolution_; - V4L2Subdevice *resizer_; + std::unique_ptr resizer_; V4L2VideoDevice *video_; MediaLink *link_; }; diff --git a/src/libcamera/v4l2_subdevice.cpp b/src/libcamera/v4l2_subdevice.cpp index 85d00c246f5e..721ff5a92a2b 100644 --- a/src/libcamera/v4l2_subdevice.cpp +++ b/src/libcamera/v4l2_subdevice.cpp @@ -446,19 +446,17 @@ int V4L2Subdevice::setFormat(unsigned int pad, V4L2SubdeviceFormat *format, * \param[in] media The media device where the entity is registered * \param[in] entity The media entity name * - * Releasing memory of the newly created instance is responsibility of the - * caller of this function. - * * \return A newly created V4L2Subdevice on success, nullptr otherwise */ -V4L2Subdevice *V4L2Subdevice::fromEntityName(const MediaDevice *media, - const std::string &entity) +std::unique_ptr +V4L2Subdevice::fromEntityName(const MediaDevice *media, + const std::string &entity) { MediaEntity *mediaEntity = media->getEntityByName(entity); if (!mediaEntity) return nullptr; - return new V4L2Subdevice(mediaEntity); + return std::make_unique(mediaEntity); } std::string V4L2Subdevice::logPrefix() const From patchwork Tue Dec 8 01:49:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Pinchart X-Patchwork-Id: 10605 Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 5E607BDB20 for ; Tue, 8 Dec 2020 01:50:34 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B4E1767E71; Tue, 8 Dec 2020 02:50:33 +0100 (CET) Authentication-Results: lancelot.ideasonboard.com; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="QFEMgxpD"; dkim-atps=neutral Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id 73C7867E6C for ; Tue, 8 Dec 2020 02:50:31 +0100 (CET) Received: from pendragon.lan (62-78-145-57.bb.dnainternet.fi [62.78.145.57]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id 1202D335 for ; Tue, 8 Dec 2020 02:50:31 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1607392231; bh=BYCVb7YctqWcAMzIAg1K/aYvjrkLga34S/u2Qw4KnFU=; h=From:To:Subject:Date:In-Reply-To:References:From; b=QFEMgxpDdb6XAE1R74PjD/km5rawi9TG75C9tZmQHVZfPmG+NjwGWpfmKOIe6rAnp yiE15lLsoBxJkrJSTk3AlQevkc0L07tCqVLqDty11mrafbTHUHnRb7GmTeAS2BoW0M Slse3yXsLWGPN8ppdEcQSSKpOwuyGSBZA0mniAAQ= From: Laurent Pinchart To: libcamera-devel@lists.libcamera.org Date: Tue, 8 Dec 2020 03:49:51 +0200 Message-Id: <20201208014951.30989-2-laurent.pinchart@ideasonboard.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20201208014951.30989-1-laurent.pinchart@ideasonboard.com> References: <20201208014951.30989-1-laurent.pinchart@ideasonboard.com> MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH 2/2] libcamera: v4l2_device: Return a unique pointer from fromEntityName() X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" The fromEntityName() function returns a pointer to a newly allocated V4L2Device instance, which must be deleted by the caller. This opens the door to memory leaks. Return a unique pointer instead, which conveys the API semantics better than a sentence in the documentation. Signed-off-by: Laurent Pinchart Reviewed-by: Kieran Bingham Reviewed-by: Jacopo Mondi --- include/libcamera/internal/v4l2_videodevice.h | 4 ++-- src/libcamera/pipeline/ipu3/cio2.cpp | 3 +-- src/libcamera/pipeline/ipu3/cio2.h | 2 +- src/libcamera/pipeline/ipu3/imgu.cpp | 10 ++++------ src/libcamera/pipeline/rkisp1/rkisp1.cpp | 13 +++---------- src/libcamera/pipeline/rkisp1/rkisp1_path.cpp | 7 +------ src/libcamera/pipeline/rkisp1/rkisp1_path.h | 3 +-- src/libcamera/v4l2_videodevice.cpp | 10 ++++------ test/libtest/buffer_source.cpp | 2 +- 9 files changed, 18 insertions(+), 36 deletions(-) diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h index 661503d1565a..529ca0e359d6 100644 --- a/include/libcamera/internal/v4l2_videodevice.h +++ b/include/libcamera/internal/v4l2_videodevice.h @@ -210,8 +210,8 @@ public: int streamOn(); int streamOff(); - static V4L2VideoDevice *fromEntityName(const MediaDevice *media, - const std::string &entity); + static std::unique_ptr + fromEntityName(const MediaDevice *media, const std::string &entity); V4L2PixelFormat toV4L2PixelFormat(const PixelFormat &pixelFormat); diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp index e43ec70fe3e4..821715e325b4 100644 --- a/src/libcamera/pipeline/ipu3/cio2.cpp +++ b/src/libcamera/pipeline/ipu3/cio2.cpp @@ -33,13 +33,12 @@ const std::map mbusCodesToPixelFormat = { } /* namespace */ CIO2Device::CIO2Device() - : sensor_(nullptr), csi2_(nullptr), output_(nullptr) + : sensor_(nullptr), csi2_(nullptr) { } CIO2Device::~CIO2Device() { - delete output_; delete csi2_; delete sensor_; } diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h index fa813a989fd2..0dca9673ca07 100644 --- a/src/libcamera/pipeline/ipu3/cio2.h +++ b/src/libcamera/pipeline/ipu3/cio2.h @@ -63,7 +63,7 @@ private: CameraSensor *sensor_; V4L2Subdevice *csi2_; - V4L2VideoDevice *output_; + std::unique_ptr output_; std::vector> buffers_; std::queue availableBuffers_; diff --git a/src/libcamera/pipeline/ipu3/imgu.cpp b/src/libcamera/pipeline/ipu3/imgu.cpp index bfe9624c7797..5b1c0318b426 100644 --- a/src/libcamera/pipeline/ipu3/imgu.cpp +++ b/src/libcamera/pipeline/ipu3/imgu.cpp @@ -348,24 +348,22 @@ int ImgUDevice::init(MediaDevice *media, unsigned int index) if (ret) return ret; - input_.reset(V4L2VideoDevice::fromEntityName(media, name_ + " input")); + input_ = V4L2VideoDevice::fromEntityName(media, name_ + " input"); ret = input_->open(); if (ret) return ret; - output_.reset(V4L2VideoDevice::fromEntityName(media, - name_ + " output")); + output_ = V4L2VideoDevice::fromEntityName(media, name_ + " output"); ret = output_->open(); if (ret) return ret; - viewfinder_.reset(V4L2VideoDevice::fromEntityName(media, - name_ + " viewfinder")); + viewfinder_ = V4L2VideoDevice::fromEntityName(media, name_ + " viewfinder"); ret = viewfinder_->open(); if (ret) return ret; - stat_.reset(V4L2VideoDevice::fromEntityName(media, name_ + " 3a stat")); + stat_ = V4L2VideoDevice::fromEntityName(media, name_ + " 3a stat"); ret = stat_->open(); if (ret) return ret; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index bcfe6c0514ab..064ab01057f4 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -178,7 +178,6 @@ class PipelineHandlerRkISP1 : public PipelineHandler { public: PipelineHandlerRkISP1(CameraManager *manager); - ~PipelineHandlerRkISP1(); CameraConfiguration *generateConfiguration(Camera *camera, const StreamRoles &roles) override; @@ -218,8 +217,8 @@ private: MediaDevice *media_; std::unique_ptr isp_; - V4L2VideoDevice *param_; - V4L2VideoDevice *stat_; + std::unique_ptr param_; + std::unique_ptr stat_; RkISP1MainPath mainPath_; RkISP1SelfPath selfPath_; @@ -599,16 +598,10 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() } PipelineHandlerRkISP1::PipelineHandlerRkISP1(CameraManager *manager) - : PipelineHandler(manager), param_(nullptr), stat_(nullptr) + : PipelineHandler(manager) { } -PipelineHandlerRkISP1::~PipelineHandlerRkISP1() -{ - delete param_; - delete stat_; -} - /* ----------------------------------------------------------------------------- * Pipeline Operations */ diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp index e05d9dd657cd..25f482eb8d8e 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.cpp @@ -24,15 +24,10 @@ RkISP1Path::RkISP1Path(const char *name, const Span &formats, const Size &minResolution, const Size &maxResolution) : name_(name), running_(false), formats_(formats), minResolution_(minResolution), maxResolution_(maxResolution), - video_(nullptr), link_(nullptr) + link_(nullptr) { } -RkISP1Path::~RkISP1Path() -{ - delete video_; -} - bool RkISP1Path::init(MediaDevice *media) { std::string resizer = std::string("rkisp1_resizer_") + name_ + "path"; diff --git a/src/libcamera/pipeline/rkisp1/rkisp1_path.h b/src/libcamera/pipeline/rkisp1/rkisp1_path.h index f06ac5a731cc..3b3e37d258d0 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1_path.h +++ b/src/libcamera/pipeline/rkisp1/rkisp1_path.h @@ -31,7 +31,6 @@ class RkISP1Path public: RkISP1Path(const char *name, const Span &formats, const Size &minResolution, const Size &maxResolution); - ~RkISP1Path(); bool init(MediaDevice *media); @@ -67,7 +66,7 @@ private: const Size maxResolution_; std::unique_ptr resizer_; - V4L2VideoDevice *video_; + std::unique_ptr video_; MediaLink *link_; }; diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp index e76fe2dd1f3a..e2b582842a9b 100644 --- a/src/libcamera/v4l2_videodevice.cpp +++ b/src/libcamera/v4l2_videodevice.cpp @@ -1598,19 +1598,17 @@ int V4L2VideoDevice::streamOff() * \param[in] media The media device where the entity is registered * \param[in] entity The media entity name * - * Releasing memory of the newly created instance is responsibility of the - * caller of this function. - * * \return A newly created V4L2VideoDevice on success, nullptr otherwise */ -V4L2VideoDevice *V4L2VideoDevice::fromEntityName(const MediaDevice *media, - const std::string &entity) +std::unique_ptr +V4L2VideoDevice::fromEntityName(const MediaDevice *media, + const std::string &entity) { MediaEntity *mediaEntity = media->getEntityByName(entity); if (!mediaEntity) return nullptr; - return new V4L2VideoDevice(mediaEntity); + return std::make_unique(mediaEntity); } /** diff --git a/test/libtest/buffer_source.cpp b/test/libtest/buffer_source.cpp index ee87c8cd821c..73563f2fc39d 100644 --- a/test/libtest/buffer_source.cpp +++ b/test/libtest/buffer_source.cpp @@ -50,7 +50,7 @@ int BufferSource::allocate(const StreamConfiguration &config) return TestSkip; } - std::unique_ptr video{ V4L2VideoDevice::fromEntityName(media_.get(), videoDeviceName) }; + std::unique_ptr video = V4L2VideoDevice::fromEntityName(media_.get(), videoDeviceName); if (!video) { std::cout << "Failed to get video device from entity " << videoDeviceName << std::endl;