diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h
index 132225a37dcd1ef4..aa283bcb4713506b 100644
--- a/include/libcamera/camera.h
+++ b/include/libcamera/camera.h
@@ -19,6 +19,7 @@
 
 namespace libcamera {
 
+class CameraSensor;
 class FrameBuffer;
 class FrameBufferAllocator;
 class PipelineHandler;
@@ -74,6 +75,10 @@ public:
 					      const std::string &name,
 					      const std::set<Stream *> &streams);
 
+	static std::shared_ptr<Camera> create(PipelineHandler *pipe,
+					      const CameraSensor *sensor,
+					      const std::set<Stream *> &streams);
+
 	Camera(const Camera &) = delete;
 	Camera &operator=(const Camera &) = delete;
 
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index 638d15e0da5e1ca9..91498f23092cec39 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -14,7 +14,9 @@
 #include <libcamera/request.h>
 #include <libcamera/stream.h>
 
+#include "libcamera/internal/camera_sensor.h"
 #include "libcamera/internal/log.h"
+#include "libcamera/internal/media_object.h"
 #include "libcamera/internal/pipeline_handler.h"
 #include "libcamera/internal/utils.h"
 
@@ -477,6 +479,24 @@ std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,
 	return std::shared_ptr<Camera>(camera, Deleter());
 }
 
+/**
+ * \brief Create a camera instance
+ * \param[in] pipe The pipeline handler responsible for the camera device
+ * \param[in] sensor The sensor of the camera device
+ * \param[in] streams Array of streams the camera provides
+ *
+ * Create a camera with name and ID from \a sensor.
+ *
+ * \return A shared pointer to the newly created camera object
+ */
+std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,
+				       const CameraSensor *sensor,
+				       const std::set<Stream *> &streams)
+{
+	return Camera::create(pipe, sensor->id(), sensor->entity()->name(),
+			      streams);
+}
+
 /**
  * \brief Retrieve the name of the camera
  * \context This function is \threadsafe.
diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 09bab78b999b8b52..9d01c6b714e880b9 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -813,19 +813,17 @@ int PipelineHandlerIPU3::registerCameras()
 					&IPU3CameraData::imguOutputBufferReady);
 
 		/* Create and register the Camera instance. */
-		std::string cameraName = cio2->sensor()->entity()->name();
 		std::shared_ptr<Camera> camera = Camera::create(this,
-								cio2->sensor()->id(),
-								cameraName,
+								cio2->sensor(),
 								streams);
 
-		registerCamera(std::move(camera), std::move(data));
-
 		LOG(IPU3, Info)
 			<< "Registered Camera[" << numCameras << "] \""
-			<< cameraName << "\""
+			<< camera->name() << "\""
 			<< " connected to CSI-2 receiver " << id;
 
+		registerCamera(std::move(camera), std::move(data));
+
 		numCameras++;
 	}
 
diff --git a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
index bead2a6220e207f5..de0fe0fb4e09d82b 100644
--- a/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
+++ b/src/libcamera/pipeline/raspberrypi/raspberrypi.cpp
@@ -973,9 +973,7 @@ bool PipelineHandlerRPi::match(DeviceEnumerator *enumerator)
 	streams.insert(&data->isp_[Isp::Stats]);
 
 	/* Create and register the camera. */
-	std::shared_ptr<Camera> camera = Camera::create(this,
-							data->sensor_->id(),
-							data->sensor_->entity()->name(),
+	std::shared_ptr<Camera> camera = Camera::create(this, data->sensor_,
 							streams);
 	registerCamera(std::move(camera), std::move(data));
 
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 6f3699fe1a53eeaf..663e45b109aae9eb 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -971,8 +971,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
 
 	std::set<Stream *> streams{ &data->stream_ };
 	std::shared_ptr<Camera> camera =
-		Camera::create(this, data->sensor_->id(), sensor->name(),
-			       streams);
+		Camera::create(this, data->sensor_, streams);
 	registerCamera(std::move(camera), std::move(data));
 
 	return 0;
diff --git a/src/libcamera/pipeline/simple/simple.cpp b/src/libcamera/pipeline/simple/simple.cpp
index 3c27cc28f672e020..cc8e14d511799dab 100644
--- a/src/libcamera/pipeline/simple/simple.cpp
+++ b/src/libcamera/pipeline/simple/simple.cpp
@@ -800,9 +800,7 @@ bool SimplePipelineHandler::match(DeviceEnumerator *enumerator)
 			continue;
 
 		std::shared_ptr<Camera> camera =
-			Camera::create(this, data->sensor_->id(),
-				       data->sensor_->entity()->name(),
-				       data->streams());
+			Camera::create(this, data->sensor_.get(), data->streams());
 		registerCamera(std::move(camera), std::move(data));
 	}
 
diff --git a/src/libcamera/pipeline/vimc/vimc.cpp b/src/libcamera/pipeline/vimc/vimc.cpp
index 6560b632ae55b304..225c1bfb453e17bb 100644
--- a/src/libcamera/pipeline/vimc/vimc.cpp
+++ b/src/libcamera/pipeline/vimc/vimc.cpp
@@ -433,8 +433,7 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator)
 
 	/* Create and register the camera. */
 	std::set<Stream *> streams{ &data->stream_ };
-	std::shared_ptr<Camera> camera = Camera::create(this, data->sensor_->id(),
-							data->sensor_->entity()->name(),
+	std::shared_ptr<Camera> camera = Camera::create(this, data->sensor_,
 							streams);
 	registerCamera(std::move(camera), std::move(data));
 
