[{"id":709,"web_url":"https://patchwork.libcamera.org/comment/709/","msgid":"<20190130233541.GD5358@pendragon.ideasonboard.com>","date":"2019-01-30T23:35:41","subject":"Re: [libcamera-devel] [PATCH v5 4/6] libcamera: camera: extend\n\tcamera object to support streams","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 Wed, Jan 30, 2019 at 12:56:13PM +0100, Niklas Söderlund wrote:\n> A camera consists of one or more video streams originating from the same\n> video source. The different streams could for example have access to\n> different hardware blocks in the video pipeline and therefore be able to\n> process the video source in different ways.\n> \n> All static information describing each stream need to be recorded at\n> camera creation. After a camera is created an application can retrieve\n> the static information about its stream at any time.\n\ns/stream/streams/\n\n> Update all pipeline handlers to register one stream per camera, this\n> will be extended in the future for some of the pipelines.\n> \n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>\n> ---\n>  include/libcamera/camera.h           |  8 ++++++-\n>  src/libcamera/camera.cpp             | 34 ++++++++++++++++++++++++----\n>  src/libcamera/pipeline/ipu3/ipu3.cpp |  8 +++++--\n>  src/libcamera/pipeline/uvcvideo.cpp  |  5 +++-\n>  src/libcamera/pipeline/vimc.cpp      |  5 +++-\n>  5 files changed, 51 insertions(+), 9 deletions(-)\n> \n> diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> index 7e358f8c0aa093cf..01498935ae4aab58 100644\n> --- a/include/libcamera/camera.h\n> +++ b/include/libcamera/camera.h\n> @@ -15,12 +15,14 @@\n>  namespace libcamera {\n>  \n>  class PipelineHandler;\n> +class Stream;\n>  \n>  class Camera final\n>  {\n>  public:\n>  \tstatic std::shared_ptr<Camera> create(PipelineHandler *pipe,\n> -\t\t\t\t\t      const std::string &name);\n> +\t\t\t\t\t      const std::string &name,\n> +\t\t\t\t\t      const std::vector<Stream *> &streams);\n>  \n>  \tCamera(const Camera &) = delete;\n>  \tvoid operator=(const Camera &) = delete;\n> @@ -32,6 +34,8 @@ public:\n>  \tint acquire();\n>  \tvoid release();\n>  \n> +\tconst std::vector<Stream *> streams() const;\n\ns/streams/&streams/\n\n> +\n>  private:\n>  \tCamera(PipelineHandler *pipe, const std::string &name);\n>  \t~Camera();\n> @@ -41,8 +45,10 @@ private:\n>  \n>  \tstd::shared_ptr<PipelineHandler> pipe_;\n>  \tstd::string name_;\n> +\tstd::vector<Stream *> streams_;\n>  \n>  \tbool acquired_;\n> +\tbool disconnected_;\n>  };\n>  \n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> index 500976b237bcbd2d..986b74407aed6bd2 100644\n> --- a/src/libcamera/camera.cpp\n> +++ b/src/libcamera/camera.cpp\n> @@ -6,6 +6,7 @@\n>   */\n>  \n>  #include <libcamera/camera.h>\n> +#include <libcamera/stream.h>\n>  \n>  #include \"log.h\"\n>  #include \"pipeline_handler.h\"\n> @@ -56,13 +57,15 @@ LOG_DECLARE_CATEGORY(Camera)\n>   * \\brief Create a camera instance\n>   * \\param[in] name The name of the camera device\n>   * \\param[in] pipe The pipeline handler responsible for the camera device\n> + * \\param[in] streams Array of streams the camera provides\n>   *\n>   * The caller is responsible for guaranteeing unicity of the camera name.\n>   *\n>   * \\return A shared pointer to the newly created camera object\n>   */\n>  std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,\n> -\t\t\t\t       const std::string &name)\n> +\t\t\t\t       const std::string &name,\n> +\t\t\t\t       const std::vector<Stream *> &streams)\n>  {\n>  \tstruct Allocator : std::allocator<Camera> {\n>  \t\tvoid construct(void *p, PipelineHandler *pipe,\n> @@ -76,7 +79,12 @@ std::shared_ptr<Camera> Camera::create(PipelineHandler *pipe,\n>  \t\t}\n>  \t};\n>  \n> -\treturn std::allocate_shared<Camera>(Allocator(), pipe, name);\n> +\tstd::shared_ptr<Camera> camera =\n> +\t\tstd::allocate_shared<Camera>(Allocator(), pipe, name);\n> +\n> +\tcamera->streams_ = streams;\n> +\n> +\treturn camera;\n>  }\n>  \n>  /**\n> @@ -102,7 +110,8 @@ const std::string &Camera::name() const\n>   */\n>  \n>  Camera::Camera(PipelineHandler *pipe, const std::string &name)\n> -\t: pipe_(pipe->shared_from_this()), name_(name), acquired_(false)\n> +\t: pipe_(pipe->shared_from_this()), name_(name), acquired_(false),\n> +\t  disconnected_(false)\n>  {\n>  }\n>  \n> @@ -125,7 +134,7 @@ void Camera::disconnect()\n>  {\n>  \tLOG(Camera, Debug) << \"Disconnecting camera \" << name_;\n>  \n> -\t/** \\todo Block API calls when they will be implemented. */\n> +\tdisconnected_ = true;\n>  \tdisconnected.emit(this);\n>  }\n>  \n> @@ -164,4 +173,21 @@ void Camera::release()\n>  \tacquired_ = false;\n>  }\n>  \n> +/**\n> + * \\brief Retrieve all the camera's stream information\n> + *\n> + * Retrieve all of the camera's static stream information. The static\n> + * information describes among other things how many streams the camera\n> + * support and each streams capabilities.\n\ns/support/supports/\ns/each streams capabilities/the capabilities of each stream/\n\n> + *\n> + * \\return An array of all the camera's streams valid streams.\n\nstreams valid streams ?\n\n> + */\n> +const std::vector<Stream *> Camera::streams() const\n> +{\n> +\tif (disconnected_)\n> +\t\treturn std::vector<Stream *>{};\n\nI still think we should still return the streams even after the camera\nis disconnected, as I see no reason not to. It can be useful for\napplications and come at no cost. Don't forget to remove the disconnect_\nmember variable from this patch.\n\nWith these small issues fixed,\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> +\treturn streams_;\n> +}\n> +\n>  } /* namespace libcamera */\n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index 80f4a7bffee52948..52844da78419943d 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -9,6 +9,7 @@\n>  #include <vector>\n>  \n>  #include <libcamera/camera.h>\n> +#include <libcamera/stream.h>\n>  \n>  #include \"device_enumerator.h\"\n>  #include \"log.h\"\n> @@ -37,6 +38,7 @@ private:\n>  \t\t\t: dev_(nullptr) {}\n>  \t\t~IPU3CameraData() { delete dev_; }\n>  \t\tV4L2Device *dev_;\n> +\t\tStream stream_;\n>  \t};\n>  \n>  \tstd::shared_ptr<MediaDevice> cio2_;\n> @@ -202,15 +204,17 @@ void PipelineHandlerIPU3::registerCameras()\n>  \t\tif (link->setEnabled(true))\n>  \t\t\tcontinue;\n>  \n> +\t\tstd::unique_ptr<IPU3CameraData> data = utils::make_unique<IPU3CameraData>();\n> +\n>  \t\tstd::string cameraName = sensor->name() + \" \" + std::to_string(id);\n> -\t\tstd::shared_ptr<Camera> camera = Camera::create(this, cameraName);\n> +\t\tstd::vector<Stream *> streams{ &data->stream_ };\n> +\t\tstd::shared_ptr<Camera> camera = Camera::create(this, cameraName, streams);\n>  \n>  \t\t/*\n>  \t\t * If V4L2 device creation fails, the Camera instance won't be\n>  \t\t * registered. The 'camera' shared pointer goes out of scope\n>  \t\t * and deletes the Camera it manages.\n>  \t\t */\n> -\t\tstd::unique_ptr<IPU3CameraData> data = utils::make_unique<IPU3CameraData>();\n>  \t\tdata->dev_ = createVideoDevice(id);\n>  \t\tif (!data->dev_) {\n>  \t\t\tLOG(IPU3, Error)\n> diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\n> index c51e8bc1f2c2bf25..8ea7ac74d2a5395d 100644\n> --- a/src/libcamera/pipeline/uvcvideo.cpp\n> +++ b/src/libcamera/pipeline/uvcvideo.cpp\n> @@ -6,6 +6,7 @@\n>   */\n>  \n>  #include <libcamera/camera.h>\n> +#include <libcamera/stream.h>\n>  \n>  #include \"device_enumerator.h\"\n>  #include \"media_device.h\"\n> @@ -25,6 +26,7 @@ public:\n>  private:\n>  \tstd::shared_ptr<MediaDevice> media_;\n>  \tV4L2Device *video_;\n> +\tStream stream_;\n>  };\n>  \n>  PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager)\n> @@ -64,7 +66,8 @@ bool PipelineHandlerUVC::match(DeviceEnumerator *enumerator)\n>  \t\treturn false;\n>  \t}\n>  \n> -\tstd::shared_ptr<Camera> camera = Camera::create(this, media_->model());\n> +\tstd::vector<Stream *> streams{ &stream_ };\n> +\tstd::shared_ptr<Camera> camera = Camera::create(this, media_->model(), streams);\n>  \tregisterCamera(std::move(camera));\n>  \thotplugMediaDevice(media_.get());\n>  \n> diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp\n> index f58a97d51619515d..9e1cf11a20c7a7e3 100644\n> --- a/src/libcamera/pipeline/vimc.cpp\n> +++ b/src/libcamera/pipeline/vimc.cpp\n> @@ -6,6 +6,7 @@\n>   */\n>  \n>  #include <libcamera/camera.h>\n> +#include <libcamera/stream.h>\n>  \n>  #include \"device_enumerator.h\"\n>  #include \"media_device.h\"\n> @@ -23,6 +24,7 @@ public:\n>  \n>  private:\n>  \tstd::shared_ptr<MediaDevice> media_;\n> +\tStream stream_;\n>  };\n>  \n>  PipeHandlerVimc::PipeHandlerVimc(CameraManager *manager)\n> @@ -56,7 +58,8 @@ bool PipeHandlerVimc::match(DeviceEnumerator *enumerator)\n>  \n>  \tmedia_->acquire();\n>  \n> -\tstd::shared_ptr<Camera> camera = Camera::create(this, \"Dummy VIMC Camera\");\n> +\tstd::vector<Stream *> streams{ &stream_ };\n> +\tstd::shared_ptr<Camera> camera = Camera::create(this, \"Dummy VIMC Camera\", streams);\n>  \tregisterCamera(std::move(camera));\n>  \n>  \treturn true;","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 CE38360C78\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 31 Jan 2019 00:35:43 +0100 (CET)","from pendragon.ideasonboard.com (85-76-34-136-nat.elisa-mobile.fi\n\t[85.76.34.136])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id 695E241;\n\tThu, 31 Jan 2019 00:35:42 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1548891343;\n\tbh=wqCkLIbuKOtYLbVcvO1EmOUltHWJFCzwbSM7a3Huvm4=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=iY3ttlcafGrGQS2bBwRHVfjle/9CxPgo7Qhgl7T0/KmX/Ia+do9RhIduAC1z8RbFW\n\tEjbCjp8FfOMK3ZXJq6v+YskH1W54tMXmXku9c7fwysMSdSmy+HVTqPeDxQY3F6xCy9\n\tf9uk9we+5GsBKe2dpzR+NHTa5k3FM369x1R1PRPM=","Date":"Thu, 31 Jan 2019 01:35:41 +0200","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":"<20190130233541.GD5358@pendragon.ideasonboard.com>","References":"<20190130115615.17362-1-niklas.soderlund@ragnatech.se>\n\t<20190130115615.17362-5-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":"<20190130115615.17362-5-niklas.soderlund@ragnatech.se>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH v5 4/6] libcamera: camera: extend\n\tcamera object to support streams","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.23","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":"Wed, 30 Jan 2019 23:35:44 -0000"}}]