[libcamera-devel] [PATCH 21/30] libcamera: pipelines: Explicitly allocate streams

Niklas Söderlund niklas.soderlund at ragnatech.se
Wed Nov 27 00:36:11 CET 2019


Prepare for sub-classing the Stream class with a V4L2 specific
implementation which will need to be constructed later when knowledge
about the V4L2 video device is available.

Signed-off-by: Niklas Söderlund <niklas.soderlund at ragnatech.se>
Reviewed-by: Jacopo Mondi <jacopo at jmondi.org>
---
 src/libcamera/pipeline/ipu3/ipu3.cpp     | 64 +++++++++++++-----------
 src/libcamera/pipeline/rkisp1/rkisp1.cpp | 19 ++++---
 src/libcamera/pipeline/uvcvideo.cpp      | 13 +++--
 src/libcamera/pipeline/vimc.cpp          | 14 ++++--
 4 files changed, 62 insertions(+), 48 deletions(-)

diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp
index 8ba08351c950f5e2..094c4db6bc32b683 100644
--- a/src/libcamera/pipeline/ipu3/ipu3.cpp
+++ b/src/libcamera/pipeline/ipu3/ipu3.cpp
@@ -138,8 +138,8 @@ public:
 class IPU3Stream : public Stream
 {
 public:
-	IPU3Stream()
-		: active_(false), device_(nullptr)
+	IPU3Stream(ImgUDevice::ImgUOutput *device, const std::string &name)
+		: active_(false), name_(name), device_(device)
 	{
 	}
 
@@ -152,10 +152,16 @@ class IPU3CameraData : public CameraData
 {
 public:
 	IPU3CameraData(PipelineHandler *pipe)
-		: CameraData(pipe)
+		: CameraData(pipe), outStream_(nullptr), vfStream_(nullptr)
 	{
 	}
 
+	~IPU3CameraData()
+	{
+		delete outStream_;
+		delete vfStream_;
+	}
+
 	void imguOutputBufferReady(Buffer *buffer);
 	void imguInputBufferReady(Buffer *buffer);
 	void cio2BufferReady(Buffer *buffer);
@@ -163,8 +169,8 @@ public:
 	CIO2Device cio2_;
 	ImgUDevice *imgu_;
 
-	IPU3Stream outStream_;
-	IPU3Stream vfStream_;
+	IPU3Stream *outStream_;
+	IPU3Stream *vfStream_;
 
 	std::vector<std::unique_ptr<Buffer>> rawBuffers_;
 };
@@ -343,8 +349,8 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()
 	 * stream otherwise.
 	 */
 	std::set<const IPU3Stream *> availableStreams = {
-		&data_->outStream_,
-		&data_->vfStream_,
+		data_->outStream_,
+		data_->vfStream_,
 	};
 
 	streams_.clear();
@@ -357,9 +363,9 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()
 		const IPU3Stream *stream;
 
 		if (cfg.size == sensorFormat_.size)
-			stream = &data_->outStream_;
+			stream = data_->outStream_;
 		else
-			stream = &data_->vfStream_;
+			stream = data_->vfStream_;
 
 		if (availableStreams.find(stream) == availableStreams.end())
 			stream = *availableStreams.begin();
@@ -367,7 +373,7 @@ CameraConfiguration::Status IPU3CameraConfiguration::validate()
 		LOG(IPU3, Debug)
 			<< "Assigned '" << stream->name_ << "' to stream " << i;
 
-		bool scale = stream == &data_->vfStream_;
+		bool scale = stream == data_->vfStream_;
 		adjustStream(config_[i], scale);
 
 		if (cfg.pixelFormat != pixelFormat || cfg.size != size) {
@@ -395,8 +401,8 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,
 	IPU3CameraData *data = cameraData(camera);
 	IPU3CameraConfiguration *config;
 	std::set<IPU3Stream *> streams = {
-		&data->outStream_,
-		&data->vfStream_,
+		data->outStream_,
+		data->vfStream_,
 	};
 
 	config = new IPU3CameraConfiguration(camera, data);
@@ -414,10 +420,10 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,
 			 * and VideoRecording roles are not allowed on
 			 * the output stream.
 			 */
-			if (streams.find(&data->outStream_) != streams.end()) {
-				stream = &data->outStream_;
-			} else if (streams.find(&data->vfStream_) != streams.end()) {
-				stream = &data->vfStream_;
+			if (streams.find(data->outStream_) != streams.end()) {
+				stream = data->outStream_;
+			} else if (streams.find(data->vfStream_) != streams.end()) {
+				stream = data->vfStream_;
 			} else {
 				LOG(IPU3, Error)
 					<< "No stream available for requested role "
@@ -447,14 +453,14 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,
 			 * \todo This is an artificial limitation until we
 			 * figure out the exact capabilities of the hardware.
 			 */
-			if (streams.find(&data->vfStream_) == streams.end()) {
+			if (streams.find(data->vfStream_) == streams.end()) {
 				LOG(IPU3, Error)
 					<< "No stream available for requested role "
 					<< role;
 				break;
 			}
 
-			stream = &data->vfStream_;
+			stream = data->vfStream_;
 
 			/*
 			 * Align the default viewfinder size to the maximum
@@ -495,8 +501,8 @@ int PipelineHandlerIPU3::configure(Camera *camera, CameraConfiguration *c)
 	IPU3CameraConfiguration *config =
 		static_cast<IPU3CameraConfiguration *>(c);
 	IPU3CameraData *data = cameraData(camera);
-	IPU3Stream *outStream = &data->outStream_;
-	IPU3Stream *vfStream = &data->vfStream_;
+	IPU3Stream *outStream = data->outStream_;
+	IPU3Stream *vfStream = data->vfStream_;
 	CIO2Device *cio2 = &data->cio2_;
 	ImgUDevice *imgu = data->imgu_;
 	int ret;
@@ -630,8 +636,8 @@ int PipelineHandlerIPU3::allocateBuffers(Camera *camera,
 					 const std::set<Stream *> &streams)
 {
 	IPU3CameraData *data = cameraData(camera);
-	IPU3Stream *outStream = &data->outStream_;
-	IPU3Stream *vfStream = &data->vfStream_;
+	IPU3Stream *outStream = data->outStream_;
+	IPU3Stream *vfStream = data->vfStream_;
 	CIO2Device *cio2 = &data->cio2_;
 	ImgUDevice *imgu = data->imgu_;
 	unsigned int bufferCount;
@@ -855,10 +861,6 @@ int PipelineHandlerIPU3::registerCameras()
 	for (unsigned int id = 0; id < 4 && numCameras < 2; ++id) {
 		std::unique_ptr<IPU3CameraData> data =
 			utils::make_unique<IPU3CameraData>(this);
-		std::set<Stream *> streams = {
-			&data->outStream_,
-			&data->vfStream_,
-		};
 		CIO2Device *cio2 = &data->cio2_;
 
 		ret = cio2->init(cio2MediaDev_, id);
@@ -872,10 +874,8 @@ int PipelineHandlerIPU3::registerCameras()
 		 * second.
 		 */
 		data->imgu_ = numCameras ? &imgu1_ : &imgu0_;
-		data->outStream_.device_ = &data->imgu_->output_;
-		data->outStream_.name_ = "output";
-		data->vfStream_.device_ = &data->imgu_->viewfinder_;
-		data->vfStream_.name_ = "viewfinder";
+		data->outStream_ = new IPU3Stream(&data->imgu_->output_, "output");
+		data->vfStream_ = new IPU3Stream(&data->imgu_->viewfinder_, "viewfinder");
 
 		/*
 		 * Connect video devices' 'bufferReady' signals to their
@@ -895,6 +895,10 @@ int PipelineHandlerIPU3::registerCameras()
 					&IPU3CameraData::imguOutputBufferReady);
 
 		/* Create and register the Camera instance. */
+		std::set<Stream *> streams = {
+			data->outStream_,
+			data->vfStream_,
+		};
 		std::string cameraName = cio2->sensor_->entity()->name() + " "
 				       + std::to_string(id);
 		std::shared_ptr<Camera> camera = Camera::create(this,
diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
index 6ad9b57d8353896c..1ae50bec0d401b3f 100644
--- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp
+++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp
@@ -117,19 +117,20 @@ class RkISP1CameraData : public CameraData
 {
 public:
 	RkISP1CameraData(PipelineHandler *pipe)
-		: CameraData(pipe), sensor_(nullptr), frame_(0),
-		  frameInfo_(pipe)
+		: CameraData(pipe), stream_(nullptr), sensor_(nullptr),
+		  frame_(0), frameInfo_(pipe)
 	{
 	}
 
 	~RkISP1CameraData()
 	{
+		delete stream_;
 		delete sensor_;
 	}
 
 	int loadIPA();
 
-	Stream stream_;
+	Stream *stream_;
 	CameraSensor *sensor_;
 	unsigned int frame_;
 	std::vector<IPABuffer> ipaBuffers_;
@@ -651,7 +652,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
 	if (ret)
 		return ret;
 
-	cfg.setStream(&data->stream_);
+	cfg.setStream(data->stream_);
 
 	return 0;
 }
@@ -785,8 +786,8 @@ int PipelineHandlerRkISP1::start(Camera *camera)
 	/* Inform IPA of stream configuration and sensor controls. */
 	std::map<unsigned int, IPAStream> streamConfig;
 	streamConfig[0] = {
-		.pixelFormat = data->stream_.configuration().pixelFormat,
-		.size = data->stream_.configuration().size,
+		.pixelFormat = data->stream_->configuration().pixelFormat,
+		.size = data->stream_->configuration().size,
 	};
 
 	std::map<unsigned int, const ControlInfoMap &> entityControls;
@@ -826,7 +827,7 @@ int PipelineHandlerRkISP1::queueRequestHardware(Camera *camera,
 						Request *request)
 {
 	RkISP1CameraData *data = cameraData(camera);
-	Stream *stream = &data->stream_;
+	Stream *stream = data->stream_;
 
 	RkISP1FrameInfo *info = data->frameInfo_.create(data->frame_, request,
 							stream);
@@ -887,6 +888,8 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
 	std::unique_ptr<RkISP1CameraData> data =
 		utils::make_unique<RkISP1CameraData>(this);
 
+	data->stream_ = new Stream();
+
 	ControlInfoMap::Map ctrls;
 	ctrls.emplace(std::piecewise_construct,
 		      std::forward_as_tuple(&controls::AeEnable),
@@ -903,7 +906,7 @@ int PipelineHandlerRkISP1::createCamera(MediaEntity *sensor)
 	if (ret)
 		return ret;
 
-	std::set<Stream *> streams{ &data->stream_ };
+	std::set<Stream *> streams{ data->stream_ };
 	std::shared_ptr<Camera> camera =
 		Camera::create(this, sensor->name(), streams);
 	registerCamera(std::move(camera), std::move(data));
diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp
index 3a76653ff6dc2b5e..64fc488912e5a82f 100644
--- a/src/libcamera/pipeline/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo.cpp
@@ -31,12 +31,13 @@ class UVCCameraData : public CameraData
 {
 public:
 	UVCCameraData(PipelineHandler *pipe)
-		: CameraData(pipe), video_(nullptr)
+		: CameraData(pipe), video_(nullptr), stream_(nullptr)
 	{
 	}
 
 	~UVCCameraData()
 	{
+		delete stream_;
 		delete video_;
 	}
 
@@ -44,7 +45,7 @@ public:
 	void bufferReady(Buffer *buffer);
 
 	V4L2VideoDevice *video_;
-	Stream stream_;
+	Stream *stream_;
 };
 
 class UVCCameraConfiguration : public CameraConfiguration
@@ -187,7 +188,7 @@ int PipelineHandlerUVC::configure(Camera *camera, CameraConfiguration *config)
 	    format.fourcc != data->video_->toV4L2Fourcc(cfg.pixelFormat))
 		return -EINVAL;
 
-	cfg.setStream(&data->stream_);
+	cfg.setStream(data->stream_);
 
 	return 0;
 }
@@ -265,7 +266,7 @@ int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)
 int PipelineHandlerUVC::queueRequestHardware(Camera *camera, Request *request)
 {
 	UVCCameraData *data = cameraData(camera);
-	Buffer *buffer = request->findBuffer(&data->stream_);
+	Buffer *buffer = request->findBuffer(data->stream_);
 	if (!buffer) {
 		LOG(UVC, Error)
 			<< "Attempt to queue request with invalid stream";
@@ -310,7 +311,7 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)
 	}
 
 	/* Create and register the camera. */
-	std::set<Stream *> streams{ &data->stream_ };
+	std::set<Stream *> streams{ data->stream_ };
 	std::shared_ptr<Camera> camera = Camera::create(this, media->model(), streams);
 	registerCamera(std::move(camera), std::move(data));
 
@@ -330,6 +331,8 @@ int UVCCameraData::init(MediaEntity *entity)
 	if (ret)
 		return ret;
 
+	stream_ = new Stream();
+
 	video_->bufferReady.connect(this, &UVCCameraData::bufferReady);
 
 	/* Initialise the supported controls. */
diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp
index f5550a1723668106..3f9e92163642f0c2 100644
--- a/src/libcamera/pipeline/vimc.cpp
+++ b/src/libcamera/pipeline/vimc.cpp
@@ -41,7 +41,8 @@ class VimcCameraData : public CameraData
 public:
 	VimcCameraData(PipelineHandler *pipe)
 		: CameraData(pipe), sensor_(nullptr), debayer_(nullptr),
-		  scaler_(nullptr), video_(nullptr), raw_(nullptr)
+		  scaler_(nullptr), video_(nullptr), raw_(nullptr),
+		  stream_(nullptr)
 	{
 	}
 
@@ -52,6 +53,7 @@ public:
 		delete scaler_;
 		delete video_;
 		delete raw_;
+		delete stream_;
 	}
 
 	int init(MediaDevice *media);
@@ -62,7 +64,7 @@ public:
 	V4L2Subdevice *scaler_;
 	V4L2VideoDevice *video_;
 	V4L2VideoDevice *raw_;
-	Stream stream_;
+	Stream *stream_;
 };
 
 class VimcCameraConfiguration : public CameraConfiguration
@@ -254,7 +256,7 @@ int PipelineHandlerVimc::configure(Camera *camera, CameraConfiguration *config)
 	if (ret)
 		return ret;
 
-	cfg.setStream(&data->stream_);
+	cfg.setStream(data->stream_);
 
 	return 0;
 }
@@ -326,7 +328,7 @@ int PipelineHandlerVimc::processControls(VimcCameraData *data, Request *request)
 int PipelineHandlerVimc::queueRequestHardware(Camera *camera, Request *request)
 {
 	VimcCameraData *data = cameraData(camera);
-	Buffer *buffer = request->findBuffer(&data->stream_);
+	Buffer *buffer = request->findBuffer(data->stream_);
 	if (!buffer) {
 		LOG(VIMC, Error)
 			<< "Attempt to queue request with invalid stream";
@@ -376,7 +378,7 @@ bool PipelineHandlerVimc::match(DeviceEnumerator *enumerator)
 		return false;
 
 	/* Create and register the camera. */
-	std::set<Stream *> streams{ &data->stream_ };
+	std::set<Stream *> streams{ data->stream_ };
 	std::shared_ptr<Camera> camera = Camera::create(this, "VIMC Sensor B",
 							streams);
 	registerCamera(std::move(camera), std::move(data));
@@ -418,6 +420,8 @@ int VimcCameraData::init(MediaDevice *media)
 	if (video_->open())
 		return -ENODEV;
 
+	stream_ = new Stream();
+
 	video_->bufferReady.connect(this, &VimcCameraData::bufferReady);
 
 	raw_ = new V4L2VideoDevice(media->getEntityByName("Raw Capture 1"));
-- 
2.24.0



More information about the libcamera-devel mailing list