[{"id":5098,"web_url":"https://patchwork.libcamera.org/comment/5098/","msgid":"<20200606214814.GG7339@pendragon.ideasonboard.com>","date":"2020-06-06T21:48:14","subject":"Re: [libcamera-devel] [PATCH v2 08/10] libcamera: ipu3: cio2: Make\n\tthe V4L2 devices private","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Niklas,\n\nThank you for the patch.\n\nOn Sat, Jun 06, 2020 at 05:04:34PM +0200, Niklas Söderlund wrote:\n> In order to make the CIO2 easier to extend with new features make the\n> V4L2 deices (sensor, CIO2 and video device) private members. This\n\ns/deices/devices/\n\n> requires a few helper functions to be added to allow for the IPU3 driver\n> to still be able to interact with all parts of the CIO2. These helper\n> functions will later be extended to add new features to the IPU3\n> pipeline.\n\nI understand it may feel cleaner, but is it really, given that the\nCIO2Device class is closely related to the rest of the IPU3 pipeline\nhandler ?\n\n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> ---\n> * Changes since v1\n> - Drop sensor access helpers and replace with a sensor() call to get\n>   hold of the CameraSensor pointer directly.\n> ---\n>  src/libcamera/pipeline/ipu3/cio2.cpp | 20 +++++++++++++++++++-\n>  src/libcamera/pipeline/ipu3/cio2.h   | 16 +++++++++++++---\n>  src/libcamera/pipeline/ipu3/ipu3.cpp | 16 +++++++---------\n>  3 files changed, 39 insertions(+), 13 deletions(-)\n> \n> diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp\n> index 0d961ae8f5a0682b..2399be8de974ff92 100644\n> --- a/src/libcamera/pipeline/ipu3/cio2.cpp\n> +++ b/src/libcamera/pipeline/ipu3/cio2.cpp\n> @@ -32,7 +32,7 @@ const std::map<uint32_t, PixelFormat> sensorMbusToPixel = {\n>  } /* namespace */\n>  \n>  CIO2Device::CIO2Device()\n> -\t: output_(nullptr), csi2_(nullptr), sensor_(nullptr)\n> +\t: sensor_(nullptr), csi2_(nullptr), output_(nullptr)\n>  {\n>  }\n>  \n> @@ -123,6 +123,8 @@ int CIO2Device::init(const MediaDevice *media, unsigned int index)\n>  \tif (ret)\n>  \t\treturn ret;\n>  \n> +\toutput_->bufferReady.connect(this, &CIO2Device::cio2BufferReady);\n> +\n>  \treturn 0;\n>  }\n>  \n> @@ -248,6 +250,12 @@ int CIO2Device::allocateBuffers()\n>  \treturn ret;\n>  }\n>  \n> +int CIO2Device::exportBuffers(unsigned int count,\n> +\t\t\t      std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n> +{\n> +\treturn output_->exportBuffers(count, buffers);\n> +}\n> +\n>  void CIO2Device::freeBuffers()\n>  {\n>  \t/* The default std::queue constructor is explicit with gcc 5 and 6. */\n> @@ -288,4 +296,14 @@ int CIO2Device::stop()\n>  \treturn output_->streamOff();\n>  }\n>  \n> +int CIO2Device::queueBuffer(FrameBuffer *buffer)\n> +{\n> +\treturn output_->queueBuffer(buffer);\n> +}\n> +\n> +void CIO2Device::cio2BufferReady(FrameBuffer *buffer)\n> +{\n> +\tbufferReady.emit(buffer);\n> +}\n> +\n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h\n> index b7eb69a4e104f400..8c3d9dd24188ef1c 100644\n> --- a/src/libcamera/pipeline/ipu3/cio2.h\n> +++ b/src/libcamera/pipeline/ipu3/cio2.h\n> @@ -13,6 +13,7 @@\n>  \n>  #include <libcamera/geometry.h>\n>  #include <libcamera/pixel_format.h>\n> +#include <libcamera/signal.h>\n>  \n>  namespace libcamera {\n>  \n> @@ -39,6 +40,8 @@ public:\n>  \t\t\t\t\t\t  const Size desiredSize = {}) const;\n>  \n>  \tint allocateBuffers();\n> +\tint exportBuffers(unsigned int count,\n> +\t\t\t  std::vector<std::unique_ptr<FrameBuffer>> *buffers);\n>  \tvoid freeBuffers();\n>  \n>  \tFrameBuffer *getBuffer();\n> @@ -47,11 +50,18 @@ public:\n>  \tint start();\n>  \tint stop();\n>  \n> -\tV4L2VideoDevice *output_;\n> -\tV4L2Subdevice *csi2_;\n> -\tCameraSensor *sensor_;\n> +\tCameraSensor *sensor() { return sensor_; }\n> +\n> +\tint queueBuffer(FrameBuffer *buffer);\n> +\tSignal<FrameBuffer *> bufferReady;\n\nProxying the signal emitted by the output video device is a bit costly,\nand is executed in a hot path :-( Is there a way we could improve that ?\n\n>  \n>  private:\n> +\tvoid cio2BufferReady(FrameBuffer *buffer);\n> +\n> +\tCameraSensor *sensor_;\n> +\tV4L2Subdevice *csi2_;\n> +\tV4L2VideoDevice *output_;\n> +\n>  \tstd::vector<std::unique_ptr<FrameBuffer>> buffers_;\n>  \tstd::queue<FrameBuffer *> availableBuffers_;\n>  };\n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index 85d4e64396e77222..55958a6c5e64dbf1 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -447,7 +447,7 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n>  \t\t\t * available sensor resolution and to the IPU3\n>  \t\t\t * alignment constraints.\n>  \t\t\t */\n> -\t\t\tconst Size &res = data->cio2_.sensor_->resolution();\n> +\t\t\tconst Size &res = data->cio2_.sensor()->resolution();\n>  \t\t\tunsigned int width = std::min(1280U, res.width);\n>  \t\t\tunsigned int height = std::min(720U, res.height);\n>  \t\t\tcfg.size = { width & ~7, height & ~3 };\n> @@ -627,13 +627,11 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream,\n>  \tIPU3CameraData *data = cameraData(camera);\n>  \tIPU3Stream *ipu3stream = static_cast<IPU3Stream *>(stream);\n>  \tunsigned int count = stream->configuration().bufferCount;\n> -\tV4L2VideoDevice *video;\n>  \n>  \tif (ipu3stream->raw_)\n> -\t\tvideo = data->cio2_.output_;\n> -\telse\n> -\t\tvideo = ipu3stream->device_->dev;\n> +\t\treturn data->cio2_.exportBuffers(count, buffers);\n>  \n> +\tV4L2VideoDevice *video = ipu3stream->device_->dev;\n>  \treturn video->exportBuffers(count, buffers);\n\nThis could be\n\n \treturn ipu3stream->device_->dev->exportBuffers(count, buffers);\n\n>  }\n>  \n> @@ -744,7 +742,7 @@ int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)\n>  \t\treturn -EINVAL;\n>  \n>  \tbuffer->setRequest(request);\n> -\tdata->cio2_.output_->queueBuffer(buffer);\n> +\tdata->cio2_.queueBuffer(buffer);\n>  \n>  \tfor (auto it : request->buffers()) {\n>  \t\tIPU3Stream *stream = static_cast<IPU3Stream *>(it.first);\n> @@ -857,7 +855,7 @@ int PipelineHandlerIPU3::registerCameras()\n>  \t\t\tcontinue;\n>  \n>  \t\t/* Initialize the camera properties. */\n> -\t\tdata->properties_ = cio2->sensor_->properties();\n> +\t\tdata->properties_ = cio2->sensor()->properties();\n>  \n>  \t\t/**\n>  \t\t * \\todo Dynamically assign ImgU and output devices to each\n> @@ -881,7 +879,7 @@ int PipelineHandlerIPU3::registerCameras()\n>  \t\t * associated ImgU input where they get processed and\n>  \t\t * returned through the ImgU main and secondary outputs.\n>  \t\t */\n> -\t\tdata->cio2_.output_->bufferReady.connect(data.get(),\n> +\t\tdata->cio2_.bufferReady.connect(data.get(),\n>  \t\t\t\t\t&IPU3CameraData::cio2BufferReady);\n>  \t\tdata->imgu_->input_->bufferReady.connect(data.get(),\n>  \t\t\t\t\t&IPU3CameraData::imguInputBufferReady);\n> @@ -891,7 +889,7 @@ int PipelineHandlerIPU3::registerCameras()\n>  \t\t\t\t\t&IPU3CameraData::imguOutputBufferReady);\n>  \n>  \t\t/* Create and register the Camera instance. */\n> -\t\tstd::string cameraName = cio2->sensor_->entity()->name();\n> +\t\tstd::string cameraName = cio2->sensor()->entity()->name();\n>  \t\tstd::shared_ptr<Camera> camera = Camera::create(this,\n>  \t\t\t\t\t\t\t\tcameraName,\n>  \t\t\t\t\t\t\t\tstreams);","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id B2C7261167\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tSat,  6 Jun 2020 23:48:33 +0200 (CEST)","from pendragon.ideasonboard.com (81-175-216-236.bb.dnainternet.fi\n\t[81.175.216.236])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 24E0CF9;\n\tSat,  6 Jun 2020 23:48:33 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (1024-bit key; \n\tunprotected) header.d=ideasonboard.com\n\theader.i=@ideasonboard.com\n\theader.b=\"bk6vMIwd\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1591480113;\n\tbh=AckBdV3RMNgjs55ZttL3Uq6dkrx5p0Y/8D5ONhQ69R8=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=bk6vMIwd/2Oej/p8hduXYCVaGmLaa0QR4bTGLBYuQx88730TRy0skP4PF92/AkZbO\n\t46Kgkm0oE+ijQDkVVBfBlZUZGcqu/3YYoVhJoZHo8jfdNlyy/h8TLnuDax2lHkZuip\n\tkPjBwlDjffF3CEBi9sotOTHwzxqHA1vDDvhZ6xoM=","Date":"Sun, 7 Jun 2020 00:48:14 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Niklas =?utf-8?q?S=C3=B6derlund?= <niklas.soderlund@ragnatech.se>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200606214814.GG7339@pendragon.ideasonboard.com>","References":"<20200606150436.1851700-1-niklas.soderlund@ragnatech.se>\n\t<20200606150436.1851700-9-niklas.soderlund@ragnatech.se>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20200606150436.1851700-9-niklas.soderlund@ragnatech.se>","Subject":"Re: [libcamera-devel] [PATCH v2 08/10] libcamera: ipu3: cio2: Make\n\tthe V4L2 devices private","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>","X-List-Received-Date":"Sat, 06 Jun 2020 21:48:33 -0000"}},{"id":5340,"web_url":"https://patchwork.libcamera.org/comment/5340/","msgid":"<20200623021648.GB691357@oden.dyn.berto.se>","date":"2020-06-23T02:16:48","subject":"Re: [libcamera-devel] [PATCH v2 08/10] libcamera: ipu3: cio2: Make\n\tthe V4L2 devices private","submitter":{"id":5,"url":"https://patchwork.libcamera.org/api/people/5/","name":"Niklas Söderlund","email":"niklas.soderlund@ragnatech.se"},"content":"Hi Laurent,\n\nThanks for your feedback.\n\nOn 2020-06-07 00:48:14 +0300, Laurent Pinchart wrote:\n> Hi Niklas,\n> \n> Thank you for the patch.\n> \n> On Sat, Jun 06, 2020 at 05:04:34PM +0200, Niklas Söderlund wrote:\n> > In order to make the CIO2 easier to extend with new features make the\n> > V4L2 deices (sensor, CIO2 and video device) private members. This\n> \n> s/deices/devices/\n> \n> > requires a few helper functions to be added to allow for the IPU3 driver\n> > to still be able to interact with all parts of the CIO2. These helper\n> > functions will later be extended to add new features to the IPU3\n> > pipeline.\n> \n> I understand it may feel cleaner, but is it really, given that the\n> CIO2Device class is closely related to the rest of the IPU3 pipeline\n> handler ?\n\nYes and no, maybe some of these requirements can be relaxed with future \nwork. Right now whats on top of my refactor list is to break it all \napart to be able to see what can be grouped better and what can not.\n\nI think observing the CIO2 as a sub-pipeline makesens and adds to a nice \nabstraction. The only thing I don't like is that we have a slot that \ncalls a slot in the hot-path. Even with that I still think this is \nbetter then what we have in master today and with a bit of luck we can \naddress this together with the ImgU work.\n\n> \n> > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> > ---\n> > * Changes since v1\n> > - Drop sensor access helpers and replace with a sensor() call to get\n> >   hold of the CameraSensor pointer directly.\n> > ---\n> >  src/libcamera/pipeline/ipu3/cio2.cpp | 20 +++++++++++++++++++-\n> >  src/libcamera/pipeline/ipu3/cio2.h   | 16 +++++++++++++---\n> >  src/libcamera/pipeline/ipu3/ipu3.cpp | 16 +++++++---------\n> >  3 files changed, 39 insertions(+), 13 deletions(-)\n> > \n> > diff --git a/src/libcamera/pipeline/ipu3/cio2.cpp b/src/libcamera/pipeline/ipu3/cio2.cpp\n> > index 0d961ae8f5a0682b..2399be8de974ff92 100644\n> > --- a/src/libcamera/pipeline/ipu3/cio2.cpp\n> > +++ b/src/libcamera/pipeline/ipu3/cio2.cpp\n> > @@ -32,7 +32,7 @@ const std::map<uint32_t, PixelFormat> sensorMbusToPixel = {\n> >  } /* namespace */\n> >  \n> >  CIO2Device::CIO2Device()\n> > -\t: output_(nullptr), csi2_(nullptr), sensor_(nullptr)\n> > +\t: sensor_(nullptr), csi2_(nullptr), output_(nullptr)\n> >  {\n> >  }\n> >  \n> > @@ -123,6 +123,8 @@ int CIO2Device::init(const MediaDevice *media, unsigned int index)\n> >  \tif (ret)\n> >  \t\treturn ret;\n> >  \n> > +\toutput_->bufferReady.connect(this, &CIO2Device::cio2BufferReady);\n> > +\n> >  \treturn 0;\n> >  }\n> >  \n> > @@ -248,6 +250,12 @@ int CIO2Device::allocateBuffers()\n> >  \treturn ret;\n> >  }\n> >  \n> > +int CIO2Device::exportBuffers(unsigned int count,\n> > +\t\t\t      std::vector<std::unique_ptr<FrameBuffer>> *buffers)\n> > +{\n> > +\treturn output_->exportBuffers(count, buffers);\n> > +}\n> > +\n> >  void CIO2Device::freeBuffers()\n> >  {\n> >  \t/* The default std::queue constructor is explicit with gcc 5 and 6. */\n> > @@ -288,4 +296,14 @@ int CIO2Device::stop()\n> >  \treturn output_->streamOff();\n> >  }\n> >  \n> > +int CIO2Device::queueBuffer(FrameBuffer *buffer)\n> > +{\n> > +\treturn output_->queueBuffer(buffer);\n> > +}\n> > +\n> > +void CIO2Device::cio2BufferReady(FrameBuffer *buffer)\n> > +{\n> > +\tbufferReady.emit(buffer);\n> > +}\n> > +\n> >  } /* namespace libcamera */\n> > diff --git a/src/libcamera/pipeline/ipu3/cio2.h b/src/libcamera/pipeline/ipu3/cio2.h\n> > index b7eb69a4e104f400..8c3d9dd24188ef1c 100644\n> > --- a/src/libcamera/pipeline/ipu3/cio2.h\n> > +++ b/src/libcamera/pipeline/ipu3/cio2.h\n> > @@ -13,6 +13,7 @@\n> >  \n> >  #include <libcamera/geometry.h>\n> >  #include <libcamera/pixel_format.h>\n> > +#include <libcamera/signal.h>\n> >  \n> >  namespace libcamera {\n> >  \n> > @@ -39,6 +40,8 @@ public:\n> >  \t\t\t\t\t\t  const Size desiredSize = {}) const;\n> >  \n> >  \tint allocateBuffers();\n> > +\tint exportBuffers(unsigned int count,\n> > +\t\t\t  std::vector<std::unique_ptr<FrameBuffer>> *buffers);\n> >  \tvoid freeBuffers();\n> >  \n> >  \tFrameBuffer *getBuffer();\n> > @@ -47,11 +50,18 @@ public:\n> >  \tint start();\n> >  \tint stop();\n> >  \n> > -\tV4L2VideoDevice *output_;\n> > -\tV4L2Subdevice *csi2_;\n> > -\tCameraSensor *sensor_;\n> > +\tCameraSensor *sensor() { return sensor_; }\n> > +\n> > +\tint queueBuffer(FrameBuffer *buffer);\n> > +\tSignal<FrameBuffer *> bufferReady;\n> \n> Proxying the signal emitted by the output video device is a bit costly,\n> and is executed in a hot path :-( Is there a way we could improve that ?\n\nI'm hoping this can be done on-top of this. I have no clear idea on how \nat the moment as I still have a hard time reading this driver as it's \nbeen reworkd in parts so many times. Why did we not know the complete \nand design the first time we wrote it ;-)\n\n> \n> >  \n> >  private:\n> > +\tvoid cio2BufferReady(FrameBuffer *buffer);\n> > +\n> > +\tCameraSensor *sensor_;\n> > +\tV4L2Subdevice *csi2_;\n> > +\tV4L2VideoDevice *output_;\n> > +\n> >  \tstd::vector<std::unique_ptr<FrameBuffer>> buffers_;\n> >  \tstd::queue<FrameBuffer *> availableBuffers_;\n> >  };\n> > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > index 85d4e64396e77222..55958a6c5e64dbf1 100644\n> > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > @@ -447,7 +447,7 @@ CameraConfiguration *PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n> >  \t\t\t * available sensor resolution and to the IPU3\n> >  \t\t\t * alignment constraints.\n> >  \t\t\t */\n> > -\t\t\tconst Size &res = data->cio2_.sensor_->resolution();\n> > +\t\t\tconst Size &res = data->cio2_.sensor()->resolution();\n> >  \t\t\tunsigned int width = std::min(1280U, res.width);\n> >  \t\t\tunsigned int height = std::min(720U, res.height);\n> >  \t\t\tcfg.size = { width & ~7, height & ~3 };\n> > @@ -627,13 +627,11 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream,\n> >  \tIPU3CameraData *data = cameraData(camera);\n> >  \tIPU3Stream *ipu3stream = static_cast<IPU3Stream *>(stream);\n> >  \tunsigned int count = stream->configuration().bufferCount;\n> > -\tV4L2VideoDevice *video;\n> >  \n> >  \tif (ipu3stream->raw_)\n> > -\t\tvideo = data->cio2_.output_;\n> > -\telse\n> > -\t\tvideo = ipu3stream->device_->dev;\n> > +\t\treturn data->cio2_.exportBuffers(count, buffers);\n> >  \n> > +\tV4L2VideoDevice *video = ipu3stream->device_->dev;\n> >  \treturn video->exportBuffers(count, buffers);\n> \n> This could be\n> \n>  \treturn ipu3stream->device_->dev->exportBuffers(count, buffers);\n> \n> >  }\n> >  \n> > @@ -744,7 +742,7 @@ int PipelineHandlerIPU3::queueRequestDevice(Camera *camera, Request *request)\n> >  \t\treturn -EINVAL;\n> >  \n> >  \tbuffer->setRequest(request);\n> > -\tdata->cio2_.output_->queueBuffer(buffer);\n> > +\tdata->cio2_.queueBuffer(buffer);\n> >  \n> >  \tfor (auto it : request->buffers()) {\n> >  \t\tIPU3Stream *stream = static_cast<IPU3Stream *>(it.first);\n> > @@ -857,7 +855,7 @@ int PipelineHandlerIPU3::registerCameras()\n> >  \t\t\tcontinue;\n> >  \n> >  \t\t/* Initialize the camera properties. */\n> > -\t\tdata->properties_ = cio2->sensor_->properties();\n> > +\t\tdata->properties_ = cio2->sensor()->properties();\n> >  \n> >  \t\t/**\n> >  \t\t * \\todo Dynamically assign ImgU and output devices to each\n> > @@ -881,7 +879,7 @@ int PipelineHandlerIPU3::registerCameras()\n> >  \t\t * associated ImgU input where they get processed and\n> >  \t\t * returned through the ImgU main and secondary outputs.\n> >  \t\t */\n> > -\t\tdata->cio2_.output_->bufferReady.connect(data.get(),\n> > +\t\tdata->cio2_.bufferReady.connect(data.get(),\n> >  \t\t\t\t\t&IPU3CameraData::cio2BufferReady);\n> >  \t\tdata->imgu_->input_->bufferReady.connect(data.get(),\n> >  \t\t\t\t\t&IPU3CameraData::imguInputBufferReady);\n> > @@ -891,7 +889,7 @@ int PipelineHandlerIPU3::registerCameras()\n> >  \t\t\t\t\t&IPU3CameraData::imguOutputBufferReady);\n> >  \n> >  \t\t/* Create and register the Camera instance. */\n> > -\t\tstd::string cameraName = cio2->sensor_->entity()->name();\n> > +\t\tstd::string cameraName = cio2->sensor()->entity()->name();\n> >  \t\tstd::shared_ptr<Camera> camera = Camera::create(this,\n> >  \t\t\t\t\t\t\t\tcameraName,\n> >  \t\t\t\t\t\t\t\tstreams);\n> \n> -- \n> Regards,\n> \n> Laurent Pinchart","headers":{"Return-Path":"<niklas.soderlund@ragnatech.se>","Received":["from mail-lf1-x144.google.com (mail-lf1-x144.google.com\n\t[IPv6:2a00:1450:4864:20::144])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id EFFD4603BD\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 23 Jun 2020 04:16:50 +0200 (CEST)","by mail-lf1-x144.google.com with SMTP id g2so10817332lfb.0\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 22 Jun 2020 19:16:50 -0700 (PDT)","from localhost (h-209-203.A463.priv.bahnhof.se. [155.4.209.203])\n\tby smtp.gmail.com with ESMTPSA id\n\tr22sm3820037lfm.30.2020.06.22.19.16.48\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 22 Jun 2020 19:16:48 -0700 (PDT)"],"Authentication-Results":"lancelot.ideasonboard.com; dkim=pass (2048-bit key; \n\tunprotected)\n\theader.d=ragnatech-se.20150623.gappssmtp.com\n\theader.i=@ragnatech-se.20150623.gappssmtp.com header.b=\"n5Iyxc81\"; \n\tdkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=kKyH3H4/i01KCVDRjnI526u/1g16oAsCeJk08gvlPpc=;\n\tb=n5Iyxc81sjuXFl5jUoq3MLj46zcL3j/72LIYtqAz5G4EkCL32f0+I2hZkVCYzzzyaI\n\t/ht9VA5bl5my0tfBrPyS+UyspAJE8i6aC+ipkPq0AZ6nRFf3NLFeaaW0qcUlJOYCVVU/\n\trHn7ESJW8VNGRQLX72SOX502DZulXWXcKAbYcz0Klc8QOIxCmV2HJ+uz3AQZPZkkcx5f\n\tJSJgne1/3XFQPpnRmE8j1O2szTBANMwZ2COnTS1wZ1LXMRCstLOI4vOMtDWAbduwlZ51\n\tbRAOkRZW+b//U/AAVilbFAJhHIEfV+sZcuP1nWYGkTG6plAcVdYNlzWYgkfruVjtwlF2\n\tAuKg==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=kKyH3H4/i01KCVDRjnI526u/1g16oAsCeJk08gvlPpc=;\n\tb=sslN9lTfhYLXfHfqqxoP7rpEgC/pJWlBnaigAUOfqg3Czm8Nc6yCEMOjxajaVB5U9c\n\tpXhY6zRMPLtjhdoLpHbrAKiaDomhVtjWXs9geRqjRX9C3hTSey8AMKIyszr3Zh+SCdnx\n\t6OBG+2i2wfV16kpNksyhbYaFduMrJPrVDtbE0HajODRvJSQjz/N2BBbX+5UBUGWro1OW\n\tZoJiCQ65hK9o916Tlgv1eZzViQklvyNG1BpOK87bbvU103xKssE3VZDZY/4EloXbu3rH\n\tKSy2rd8KDUNSaLCREv+bNl5Ag/ImIbRmoHpHKUGFSq8V28L4vMZCm6z4iR3glWb+nKOc\n\tb7tw==","X-Gm-Message-State":"AOAM533uPD7zbcEAdMdH0u1i8F13Oz80H5LUxQeUsXaOb2QZ8JUhvSMj\n\t+CSFdufmWrlcIynZD/5yQkb+BfN8F3U=","X-Google-Smtp-Source":"ABdhPJy7MvaFu5TiG3pYLNxYPatCcq14Qw3Bk+n/m9JCkxAGnk9bN+N+o8yGZbCTxoxBW4fwH1hn6Q==","X-Received":"by 2002:a05:6512:104b:: with SMTP id\n\tc11mr6152917lfb.88.1592878609910; \n\tMon, 22 Jun 2020 19:16:49 -0700 (PDT)","Date":"Tue, 23 Jun 2020 04:16:48 +0200","From":"Niklas =?iso-8859-1?q?S=F6derlund?= <niklas.soderlund@ragnatech.se>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20200623021648.GB691357@oden.dyn.berto.se>","References":"<20200606150436.1851700-1-niklas.soderlund@ragnatech.se>\n\t<20200606150436.1851700-9-niklas.soderlund@ragnatech.se>\n\t<20200606214814.GG7339@pendragon.ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20200606214814.GG7339@pendragon.ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH v2 08/10] libcamera: ipu3: cio2: Make\n\tthe V4L2 devices private","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>","X-List-Received-Date":"Tue, 23 Jun 2020 02:16:51 -0000"}}]