{"id":26875,"url":"https://patchwork.libcamera.org/api/patches/26875/?format=json","web_url":"https://patchwork.libcamera.org/patch/26875/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20260612071117.109431-1-tju_cooyun@163.com>","date":"2026-06-12T07:11:17","name":"libcamera: camera: make Camera::create private","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"3fcd88195876dbb8dfed047bb160de2e5b18a944","submitter":{"id":277,"url":"https://patchwork.libcamera.org/api/people/277/?format=json","name":"张朝阳","email":"tju_cooyun@163.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/26875/mbox/","series":[{"id":5990,"url":"https://patchwork.libcamera.org/api/series/5990/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=5990","date":"2026-06-12T07:11:17","name":"libcamera: camera: make Camera::create private","version":1,"mbox":"https://patchwork.libcamera.org/series/5990/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/26875/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/26875/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id C8000C324C\n\tfor <parsemail@patchwork.libcamera.org>;\n\tFri, 12 Jun 2026 07:11:57 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 694BD623BC;\n\tFri, 12 Jun 2026 09:11:56 +0200 (CEST)","from m16.mail.163.com (m16.mail.163.com [117.135.210.3])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id DB2D861E76\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri, 12 Jun 2026 09:11:53 +0200 (CEST)","from SH-DESKTOP.taile2d4ba.ts.net (unknown [])\n\tby gzga-smtp-mtada-g0-0 (Coremail) with SMTP id\n\t_____wAXdCU0sStqndINCw--.56982S2; \n\tFri, 12 Jun 2026 15:11:49 +0800 (CST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key;\n\tunprotected) header.d=163.com header.i=@163.com header.b=\"kyDyxvRf\";\n\tdkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com;\n\ts=s110527; h=From:To:Subject:Date:Message-ID:MIME-Version; bh=gO\n\tu8sBwxdi4A+C2evL4Hv6XZ06wwVQUQ95ciA4eYRNU=; b=kyDyxvRfPDCk3/nwzx\n\tLZsJSaDJuuMyMNsDrkCJc3m8/Y3TNq79NtHJ0LDWPJhOi1l/Z9zM6dBCMkTWScJX\n\tWDB1wHtMFnOyEajsG7Djt5F2H4Mf7k8puFbkQ5mr03fSlEpbLiNkH9lyCrsRzUbf\n\tqW9BNGcle6xq+vEKDKGBizb4E=","From":"tju_cooyun@163.com","To":"libcamera-devel@lists.libcamera.org","Cc":"zcy <tju_cooyun@163.com>","Subject":"[PATCH] libcamera: camera: make Camera::create private","Date":"Fri, 12 Jun 2026 15:11:17 +0800","Message-ID":"<20260612071117.109431-1-tju_cooyun@163.com>","X-Mailer":"git-send-email 2.43.0","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","X-CM-TRANSID":"_____wAXdCU0sStqndINCw--.56982S2","X-Coremail-Antispam":"1Uf129KBjvAXoWfGrWfCFWkXFW8GF15XFWkZwb_yoW8Jr4DCo\n\tZ5trW8Gw15Aryj9F1ftF1xKr1UA390k3s7Jw42ga1qya1fXrWYg3yxCF17ur1fGFWUGFn7\n\tAry2qF1xAF4j9FW8n29KB7ZKAUJUUUU8529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3\n\tAaLaJ3UbIYCTnIWIevJa73UjIFyTuYvjfUnfOwUUUUU","X-Originating-IP":"[183.195.143.58]","X-CM-SenderInfo":"5wmxsuprr130i6rwjhhfrp/xtbC5hXeNmorsTWTrQAA3g","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"From: zcy <tju_cooyun@163.com>\n\nMake Camera::create a private implementation detail since it is only\nused by pipeline handler subclasses. This prevents app users from\nmisunderstanding or misusing the function. Add a protected\nPipelineHandler::createCamera helper so pipeline implementations can\ncreate Camera instances internally.\n---\n Documentation/guides/pipeline-handler.rst     | 13 +++++++------\n include/libcamera/camera.h                    |  8 ++++----\n include/libcamera/internal/pipeline_handler.h |  5 +++++\n src/libcamera/pipeline/imx8-isi/imx8-isi.cpp  |  2 +-\n src/libcamera/pipeline/ipu3/ipu3.cpp          |  2 +-\n src/libcamera/pipeline/mali-c55/mali-c55.cpp  |  3 +--\n src/libcamera/pipeline/rkisp1/rkisp1.cpp      |  2 +-\n src/libcamera/pipeline/rpi/pisp/pisp.cpp      |  2 +-\n src/libcamera/pipeline/rpi/vc4/vc4.cpp        |  2 +-\n src/libcamera/pipeline/simple/simple.cpp      |  2 +-\n src/libcamera/pipeline/uvcvideo/uvcvideo.cpp  |  2 +-\n src/libcamera/pipeline/vimc/vimc.cpp          |  2 +-\n src/libcamera/pipeline/virtual/virtual.cpp    |  2 +-\n src/libcamera/pipeline_handler.cpp            |  7 +++++++\n 14 files changed, 33 insertions(+), 21 deletions(-)","diff":"diff --git a/Documentation/guides/pipeline-handler.rst b/Documentation/guides/pipeline-handler.rst\nindex 083cdb745..2a661cf24 100644\n--- a/Documentation/guides/pipeline-handler.rst\n+++ b/Documentation/guides/pipeline-handler.rst\n@@ -489,10 +489,11 @@ handler.\n \n Once the camera data has been initialized, the Camera device instances and the\n associated streams have to be registered. Create a set of streams for the\n-camera, which for this device is only one. You create a camera using the static\n-:doxy-int:`Camera::create` function, passing the Camera::Private instance, the\n-id of the camera, and the streams available. Then register the camera with the\n-pipeline handler and camera manager using :doxy-int:`PipelineHandler::registerCamera`.\n+camera, which for this device is only one. You create a camera using the\n+protected :doxy-int:`PipelineHandler::createCamera` helper, passing the\n+Camera::Private instance, the id of the camera, and the streams available.\n+Then register the camera with the pipeline handler and camera manager using\n+:doxy-int:`PipelineHandler::registerCamera`.\n \n Finally with a successful construction, we return 'true' indicating that the\n PipelineHandler successfully matched and constructed a device.\n@@ -501,7 +502,7 @@ PipelineHandler successfully matched and constructed a device.\n \n    std::set<Stream *> streams{ &data->stream_ };\n    const char *id = data->video_->deviceName();\n-   std::shared_ptr<Camera> camera = Camera::create(std::move(data), id, streams);\n+   std::shared_ptr<Camera> camera = createCamera(std::move(data), id, streams);\n    registerCamera(std::move(camera));\n \n    return true;\n@@ -529,7 +530,7 @@ Our match function should now look like the following:\n    \t/* Create and register the camera. */\n    \tstd::set<Stream *> streams{ &data->stream_ };\n    \tconst char *id = data->video_->deviceName();\n-   \tstd::shared_ptr<Camera> camera = Camera::create(std::move(data), id, streams);\n+   \tstd::shared_ptr<Camera> camera = createCamera(std::move(data), id, streams);\n    \tregisterCamera(std::move(camera));\n \n    \treturn true;\ndiff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\nindex b24a29740..a5e8ba03a 100644\n--- a/include/libcamera/camera.h\n+++ b/include/libcamera/camera.h\n@@ -116,10 +116,6 @@ class Camera final : public Object, public std::enable_shared_from_this<Camera>,\n \tLIBCAMERA_DECLARE_PRIVATE()\n \n public:\n-\tstatic std::shared_ptr<Camera> create(std::unique_ptr<Private> d,\n-\t\t\t\t\t      const std::string &id,\n-\t\t\t\t\t      const std::set<Stream *> &streams);\n-\n \tconst std::string &id() const;\n \n \tSignal<Request *, FrameBuffer *> bufferCompleted;\n@@ -154,6 +150,10 @@ public:\n private:\n \tLIBCAMERA_DISABLE_COPY(Camera)\n \n+\tstatic std::shared_ptr<Camera> create(std::unique_ptr<Private> d,\n+\t\t\t\t\t      const std::string &id,\n+\t\t\t\t\t      const std::set<Stream *> &streams);\n+\n \tCamera(std::unique_ptr<Private> d, const std::string &id,\n \t       const std::set<Stream *> &streams);\n \t~Camera();\ndiff --git a/include/libcamera/internal/pipeline_handler.h b/include/libcamera/internal/pipeline_handler.h\nindex 6922ce18e..69531b836 100644\n--- a/include/libcamera/internal/pipeline_handler.h\n+++ b/include/libcamera/internal/pipeline_handler.h\n@@ -14,6 +14,7 @@\n \n #include <libcamera/base/object.h>\n \n+#include <libcamera/camera.h>\n #include <libcamera/controls.h>\n #include <libcamera/stream.h>\n \n@@ -80,6 +81,10 @@ public:\n \t}\n \n protected:\n+\tstd::shared_ptr<Camera> createCamera(std::unique_ptr<Camera::Private> d,\n+\t\t\t\t\t     const std::string &id,\n+\t\t\t\t\t     const std::set<Stream *> &streams);\n+\n \tvoid registerCamera(std::shared_ptr<Camera> camera);\n \tvoid hotplugMediaDevice(std::shared_ptr<MediaDevice> media);\n \tunsigned int useCount() const { return useCount_; }\ndiff --git a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\nindex 706681fce..36a42eb8e 100644\n--- a/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n+++ b/src/libcamera/pipeline/imx8-isi/imx8-isi.cpp\n@@ -1101,7 +1101,7 @@ bool PipelineHandlerISI::match(DeviceEnumerator *enumerator)\n \t\t}\n \n \t\tstd::shared_ptr<Camera> camera =\n-\t\t\tCamera::create(std::move(data), id, streams);\n+\t\t\tcreateCamera(std::move(data), id, streams);\n \n \t\tregisterCamera(std::move(camera));\n \t\tnumCameras++;\ndiff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\nindex bf4c2921f..7d36c148b 100644\n--- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n@@ -1133,7 +1133,7 @@ int PipelineHandlerIPU3::registerCameras()\n \t\t/* Create and register the Camera instance. */\n \t\tconst std::string &cameraId = cio2->sensor()->id();\n \t\tstd::shared_ptr<Camera> camera =\n-\t\t\tCamera::create(std::move(data), cameraId, streams);\n+\t\t\tcreateCamera(std::move(data), cameraId, streams);\n \n \t\tregisterCamera(std::move(camera));\n \ndiff --git a/src/libcamera/pipeline/mali-c55/mali-c55.cpp b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\nindex ce2469ed1..62f7fafe1 100644\n--- a/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n+++ b/src/libcamera/pipeline/mali-c55/mali-c55.cpp\n@@ -1778,8 +1778,7 @@ bool PipelineHandlerMaliC55::registerMaliCamera(std::unique_ptr<MaliC55CameraDat\n \tif (dsFitted_)\n \t\tstreams.insert(&data->dsStream_);\n \n-\tstd::shared_ptr<Camera> camera = Camera::create(std::move(data),\n-\t\t\t\t\t\t\tname, streams);\n+\tstd::shared_ptr<Camera> camera = createCamera(std::move(data), name, streams);\n \tregisterCamera(std::move(camera));\n \n \treturn true;\ndiff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\nindex 9606459fc..48505c6b4 100644\n--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n@@ -1504,7 +1504,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)\n \t};\n \tconst std::string &id = data->sensor_->id();\n \tstd::shared_ptr<Camera> camera =\n-\t\tCamera::create(std::move(data), id, streams);\n+\t\tcreateCamera(std::move(data), id, streams);\n \n \tregisterCamera(std::move(camera));\n \ndiff --git a/src/libcamera/pipeline/rpi/pisp/pisp.cpp b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\nindex b744c901f..62bd4ad1d 100644\n--- a/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n+++ b/src/libcamera/pipeline/rpi/pisp/pisp.cpp\n@@ -1175,7 +1175,7 @@ int PipelineHandlerPiSP::platformRegister(std::unique_ptr<RPi::CameraData> &came\n \t/* Create and register the camera. */\n \tconst std::string &id = data->sensor_->id();\n \tstd::shared_ptr<Camera> camera =\n-\t\tCamera::create(std::move(cameraData), id, streams);\n+\t\tcreateCamera(std::move(cameraData), id, streams);\n \tPipelineHandler::registerCamera(std::move(camera));\n \n \tLOG(RPI, Info) << \"Registered camera \" << id\ndiff --git a/src/libcamera/pipeline/rpi/vc4/vc4.cpp b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\nindex 3e9a49058..bf520b3a0 100644\n--- a/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n+++ b/src/libcamera/pipeline/rpi/vc4/vc4.cpp\n@@ -400,7 +400,7 @@ int PipelineHandlerVc4::platformRegister(std::unique_ptr<RPi::CameraData> &camer\n \t/* Create and register the camera. */\n \tconst std::string &id = data->sensor_->id();\n \tstd::shared_ptr<Camera> camera =\n-\t\tCamera::create(std::move(cameraData), id, streams);\n+\t\tcreateCamera(std::move(cameraData), id, streams);\n \tPipelineHandler::registerCamera(std::move(camera));\n \n \tLOG(RPI, Info) << \"Registered camera \" << id\ndiff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp\nindex c6fe12d65..4e672067c 100644\n--- a/src/libcamera/pipeline/simple/simple.cpp\n+++ b/src/libcamera/pipeline/simple/simple.cpp\n@@ -2002,7 +2002,7 @@ bool SimplePipelineHandler::matchDevice(std::shared_ptr<MediaDevice> media,\n \n \t\tconst std::string &id = data->sensor_->id();\n \t\tstd::shared_ptr<Camera> camera =\n-\t\t\tCamera::create(std::move(data), id, streams);\n+\t\t\tcreateCamera(std::move(data), id, streams);\n \t\tregisterCamera(std::move(camera));\n \t\tregistered = true;\n \t}\ndiff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\nindex 3bd51733d..88b0f23a1 100644\n--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp\n@@ -485,7 +485,7 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)\n \tstd::string id = data->id();\n \tstd::set<Stream *> streams{ &data->stream_ };\n \tstd::shared_ptr<Camera> camera =\n-\t\tCamera::create(std::move(data), id, streams);\n+\t\tcreateCamera(std::move(data), id, streams);\n \tregisterCamera(std::move(camera));\n \n \t/* Enable hot-unplug notifications. */\ndiff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp\nindex 6681c74ee..b5518e6e8 100644\n--- a/src/libcamera/pipeline/vimc/vimc.cpp\n+++ b/src/libcamera/pipeline/vimc/vimc.cpp\n@@ -510,7 +510,7 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator)\n \tstd::set<Stream *> streams{ &data->stream_ };\n \tconst std::string &id = data->sensor_->id();\n \tstd::shared_ptr<Camera> camera =\n-\t\tCamera::create(std::move(data), id, streams);\n+\t\tcreateCamera(std::move(data), id, streams);\n \tregisterCamera(std::move(camera));\n \n \treturn true;\ndiff --git a/src/libcamera/pipeline/virtual/virtual.cpp b/src/libcamera/pipeline/virtual/virtual.cpp\nindex 81d2dddab..1ecfe9d13 100644\n--- a/src/libcamera/pipeline/virtual/virtual.cpp\n+++ b/src/libcamera/pipeline/virtual/virtual.cpp\n@@ -402,7 +402,7 @@ bool PipelineHandlerVirtual::match([[maybe_unused]] DeviceEnumerator *enumerator\n \t\tfor (auto &streamConfig : data->streamConfigs_)\n \t\t\tstreams.insert(&streamConfig.stream);\n \t\tstd::string id = data->config_.id;\n-\t\tstd::shared_ptr<Camera> camera = Camera::create(std::move(data), id, streams);\n+\t\tstd::shared_ptr<Camera> camera = createCamera(std::move(data), id, streams);\n \n \t\tif (!initFrameGenerator(camera.get())) {\n \t\t\tLOG(Virtual, Error) << \"Failed to initialize frame \"\ndiff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\nindex e7145c1d4..c5cdbfda1 100644\n--- a/src/libcamera/pipeline_handler.cpp\n+++ b/src/libcamera/pipeline_handler.cpp\n@@ -76,6 +76,13 @@ PipelineHandler::PipelineHandler(CameraManager *manager,\n {\n }\n \n+std::shared_ptr<Camera> PipelineHandler::createCamera(std::unique_ptr<Camera::Private> d,\n+\t\t\t\t\t\t      const std::string &id,\n+\t\t\t\t\t\t      const std::set<Stream *> &streams)\n+{\n+\treturn Camera::create(std::move(d), id, streams);\n+}\n+\n PipelineHandler::~PipelineHandler()\n {\n \tfor (std::shared_ptr<MediaDevice> &media : mediaDevices_)\n","prefixes":[]}