[{"id":711,"web_url":"https://patchwork.libcamera.org/comment/711/","msgid":"<20190131003032.GF5358@pendragon.ideasonboard.com>","date":"2019-01-31T00:30:32","subject":"Re: [libcamera-devel] [PATCH v5 6/6] libcamera: camera: extend\n\tcamera object to support configuration of 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:15PM +0100, Niklas Söderlund wrote:\n> Extend the camera to support reading and configuring formats for\n> groups of streams. The implementation in the Camera are minimalistic as\n> the heavy lifting are done by the pipeline handler implementations.\n> \n> The most important functionality the camera provides in this context is\n> validation of data structures passed to it from the application and\n> access control to the pipeline handler.\n> \n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> ---\n>  include/libcamera/camera.h |  4 +++\n>  src/libcamera/camera.cpp   | 61 ++++++++++++++++++++++++++++++++++++++\n>  2 files changed, 65 insertions(+)\n> \n> diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> index 01498935ae4aab58..b21d116edc0f3a57 100644\n> --- a/include/libcamera/camera.h\n> +++ b/include/libcamera/camera.h\n> @@ -7,6 +7,7 @@\n>  #ifndef __LIBCAMERA_CAMERA_H__\n>  #define __LIBCAMERA_CAMERA_H__\n>  \n> +#include <map>\n>  #include <memory>\n>  #include <string>\n>  \n> @@ -16,6 +17,7 @@ namespace libcamera {\n>  \n>  class PipelineHandler;\n>  class Stream;\n> +class StreamConfiguration;\n>  \n>  class Camera final\n>  {\n> @@ -35,6 +37,8 @@ public:\n>  \tvoid release();\n>  \n>  \tconst std::vector<Stream *> streams() const;\n> +\tstd::map<Stream*, StreamConfiguration> streamConfiguration(std::vector<Stream*> &streams);\n\ns/;/ const;/\n\n> +\tint configureStreams(std::map<Stream*, StreamConfiguration> &config);\n\ns/(/(const /\n\n>  \n>  private:\n>  \tCamera(PipelineHandler *pipe, const std::string &name);\n> diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> index 986b74407aed6bd2..a293350f731e18df 100644\n> --- a/src/libcamera/camera.cpp\n> +++ b/src/libcamera/camera.cpp\n> @@ -190,4 +190,65 @@ const std::vector<Stream *> Camera::streams() const\n>  \treturn streams_;\n>  }\n>  \n> +/**\n> + * \\brief Retrieve a group of stream configurations\n> + * \\param[in] streams A map of stream IDs and configurations to setup\n> + *\n> + * Retrieve the camera's configuration for a specified group of streams. The\n> + * caller can specifies which of the camera's streams to retrieve configuration\n> + * from by populating \\a streams.\n> + *\n> + * The easiest way to populate the array of streams to fetch configuration from\n> + * is to first retrieve the camera's full array of stream by with streams() and\n\n\"by with\" ?\n\n> + * then potentially trim it down to only contain the streams the caller\n> + * are interested in.\n> + *\n> + * \\return A map of successfully retrieved stream IDs and configurations or an\n> + * empty list on error.\n\nThat doesn't allow returning an error code to discriminate between\nerrors :-/ I wonder if we should pass the map as an argument by pointer\nand return an integer. Or maybe there's no need to discriminate between\nerrors ?\n\n> + */\n> +std::map<Stream*, StreamConfiguration>\n> +Camera::streamConfiguration(std::vector<Stream*> &streams)\n> +{\n> +\tif (disconnected_ || !streams.size())\n> +\t\tstd::map<unsigned int, StreamConfiguration>{};\n> +\n> +\treturn pipe_->streamConfiguration(this, streams);\n> +}\n> +\n> +/**\n> + * \\brief Configure the camera's streams prior to capture\n> + * \\param[in] config A map of stream IDs and configurations to setup\n> + *\n> + * Prior to starting capture, the camera must be configured to select a\n> + * group of streams to be involved in the capture and their configuration.\n> + * The caller specifies which streams are to be involved and their configuration\n> + * by populating \\a config.\n> + *\n> + * The easiest way to populate the array of config is to fetch an initial\n> + * configuration from the camera with streamConfiguration() and then change the\n> + * parameters to fit the caller's need and once all the streams parameters are\n> + * configured hand that over to configureStreams() to actually setup the camera.\n> + *\n> + * Exclusive access to the camera shall be ensured by a call to acquire() prior\n> + * to calling this function, otherwise an -EACCES error is be returned.\n\ns/is be/will be/\n\n> + *\n> + * \\return 0 on success or a negative error code on error.\n> + * \\retval -ENODEV The camera is not connected to any hardware\n> + * \\retval -EACCES The user have not acquired exclusive access to the camera\n\ns/have not/has not/\n\n> + * \\retval -EINVAL The configuration is not valid\n> + */\n> +int Camera::configureStreams(std::map<Stream*, StreamConfiguration> &config)\n> +{\n> +\tif (disconnected_)\n> +\t\treturn -ENODEV;\n> +\n> +\tif (!acquired_)\n> +\t\treturn -EACCES;\n> +\n> +\tif (!config.size())\n> +\t\treturn -EINVAL;\n> +\n> +\treturn pipe_->configureStreams(this, config);\n> +}\n> +\n>  } /* namespace libcamera */","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id BE74060C78\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 31 Jan 2019 01:30:34 +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 C2E8D41;\n\tThu, 31 Jan 2019 01:30:33 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1548894634;\n\tbh=TBCt3lfXJOh3AqJZKU5mN5Lk2ODnVT3CZQ2iSbE/lU8=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=JdJYD5YtSPehJZvqvqw98f+eN0WNbQbCo1HdWyDyZRuylsZPYtvb5OdKBjTZZsP6w\n\tTNbAbBK/yfI+fEE388HziY3Je/0ZibQB0JdbZos54IYto4PKOoEGPxYWKjk14ZyqWZ\n\tIsIXOESAEtg6dsNJuRGOeRuQwbXC/WX3d/BxDTMU=","Date":"Thu, 31 Jan 2019 02:30:32 +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":"<20190131003032.GF5358@pendragon.ideasonboard.com>","References":"<20190130115615.17362-1-niklas.soderlund@ragnatech.se>\n\t<20190130115615.17362-7-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-7-niklas.soderlund@ragnatech.se>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH v5 6/6] libcamera: camera: extend\n\tcamera object to support configuration of 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":"Thu, 31 Jan 2019 00:30:35 -0000"}},{"id":722,"web_url":"https://patchwork.libcamera.org/comment/722/","msgid":"<20190131180112.GJ19527@bigcity.dyn.berto.se>","date":"2019-01-31T18:01:13","subject":"Re: [libcamera-devel] [PATCH v5 6/6] libcamera: camera: extend\n\tcamera object to support configuration of streams","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 2019-01-31 02:30:32 +0200, Laurent Pinchart wrote:\n> Hi Niklas,\n> \n> Thank you for the patch.\n> \n> On Wed, Jan 30, 2019 at 12:56:15PM +0100, Niklas Söderlund wrote:\n> > Extend the camera to support reading and configuring formats for\n> > groups of streams. The implementation in the Camera are minimalistic as\n> > the heavy lifting are done by the pipeline handler implementations.\n> > \n> > The most important functionality the camera provides in this context is\n> > validation of data structures passed to it from the application and\n> > access control to the pipeline handler.\n> > \n> > Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> > ---\n> >  include/libcamera/camera.h |  4 +++\n> >  src/libcamera/camera.cpp   | 61 ++++++++++++++++++++++++++++++++++++++\n> >  2 files changed, 65 insertions(+)\n> > \n> > diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> > index 01498935ae4aab58..b21d116edc0f3a57 100644\n> > --- a/include/libcamera/camera.h\n> > +++ b/include/libcamera/camera.h\n> > @@ -7,6 +7,7 @@\n> >  #ifndef __LIBCAMERA_CAMERA_H__\n> >  #define __LIBCAMERA_CAMERA_H__\n> >  \n> > +#include <map>\n> >  #include <memory>\n> >  #include <string>\n> >  \n> > @@ -16,6 +17,7 @@ namespace libcamera {\n> >  \n> >  class PipelineHandler;\n> >  class Stream;\n> > +class StreamConfiguration;\n> >  \n> >  class Camera final\n> >  {\n> > @@ -35,6 +37,8 @@ public:\n> >  \tvoid release();\n> >  \n> >  \tconst std::vector<Stream *> streams() const;\n> > +\tstd::map<Stream*, StreamConfiguration> streamConfiguration(std::vector<Stream*> &streams);\n> \n> s/;/ const;/\n> \n> > +\tint configureStreams(std::map<Stream*, StreamConfiguration> &config);\n> \n> s/(/(const /\n> \n> >  \n> >  private:\n> >  \tCamera(PipelineHandler *pipe, const std::string &name);\n> > diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> > index 986b74407aed6bd2..a293350f731e18df 100644\n> > --- a/src/libcamera/camera.cpp\n> > +++ b/src/libcamera/camera.cpp\n> > @@ -190,4 +190,65 @@ const std::vector<Stream *> Camera::streams() const\n> >  \treturn streams_;\n> >  }\n> >  \n> > +/**\n> > + * \\brief Retrieve a group of stream configurations\n> > + * \\param[in] streams A map of stream IDs and configurations to setup\n> > + *\n> > + * Retrieve the camera's configuration for a specified group of streams. The\n> > + * caller can specifies which of the camera's streams to retrieve configuration\n> > + * from by populating \\a streams.\n> > + *\n> > + * The easiest way to populate the array of streams to fetch configuration from\n> > + * is to first retrieve the camera's full array of stream by with streams() and\n> \n> \"by with\" ?\n> \n> > + * then potentially trim it down to only contain the streams the caller\n> > + * are interested in.\n> > + *\n> > + * \\return A map of successfully retrieved stream IDs and configurations or an\n> > + * empty list on error.\n> \n> That doesn't allow returning an error code to discriminate between\n> errors :-/ I wonder if we should pass the map as an argument by pointer\n> and return an integer. Or maybe there's no need to discriminate between\n> errors ?\n\nGood question, I'm not sure if we need to discriminate between errors \nhere? If we do how would an application act on the different errors?\n\n> \n> > + */\n> > +std::map<Stream*, StreamConfiguration>\n> > +Camera::streamConfiguration(std::vector<Stream*> &streams)\n> > +{\n> > +\tif (disconnected_ || !streams.size())\n> > +\t\tstd::map<unsigned int, StreamConfiguration>{};\n> > +\n> > +\treturn pipe_->streamConfiguration(this, streams);\n> > +}\n> > +\n> > +/**\n> > + * \\brief Configure the camera's streams prior to capture\n> > + * \\param[in] config A map of stream IDs and configurations to setup\n> > + *\n> > + * Prior to starting capture, the camera must be configured to select a\n> > + * group of streams to be involved in the capture and their configuration.\n> > + * The caller specifies which streams are to be involved and their configuration\n> > + * by populating \\a config.\n> > + *\n> > + * The easiest way to populate the array of config is to fetch an initial\n> > + * configuration from the camera with streamConfiguration() and then change the\n> > + * parameters to fit the caller's need and once all the streams parameters are\n> > + * configured hand that over to configureStreams() to actually setup the camera.\n> > + *\n> > + * Exclusive access to the camera shall be ensured by a call to acquire() prior\n> > + * to calling this function, otherwise an -EACCES error is be returned.\n> \n> s/is be/will be/\n> \n> > + *\n> > + * \\return 0 on success or a negative error code on error.\n> > + * \\retval -ENODEV The camera is not connected to any hardware\n> > + * \\retval -EACCES The user have not acquired exclusive access to the camera\n> \n> s/have not/has not/\n> \n> > + * \\retval -EINVAL The configuration is not valid\n> > + */\n> > +int Camera::configureStreams(std::map<Stream*, StreamConfiguration> &config)\n> > +{\n> > +\tif (disconnected_)\n> > +\t\treturn -ENODEV;\n> > +\n> > +\tif (!acquired_)\n> > +\t\treturn -EACCES;\n> > +\n> > +\tif (!config.size())\n> > +\t\treturn -EINVAL;\n> > +\n> > +\treturn pipe_->configureStreams(this, config);\n> > +}\n> > +\n> >  } /* namespace libcamera */\n> \n> -- \n> Regards,\n> \n> Laurent Pinchart","headers":{"Return-Path":"<niklas.soderlund@ragnatech.se>","Received":["from mail-lj1-x242.google.com (mail-lj1-x242.google.com\n\t[IPv6:2a00:1450:4864:20::242])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 92B0560C6A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 31 Jan 2019 19:01:15 +0100 (CET)","by mail-lj1-x242.google.com with SMTP id g11-v6so3496738ljk.3\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tThu, 31 Jan 2019 10:01:15 -0800 (PST)","from localhost (89-233-230-99.cust.bredband2.com. [89.233.230.99])\n\tby smtp.gmail.com with ESMTPSA id\n\tz15-v6sm990298ljb.9.2019.01.31.10.01.13\n\t(version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256);\n\tThu, 31 Jan 2019 10:01:13 -0800 (PST)"],"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\t:user-agent; bh=6SwoRQ8K/jjiCFeqvIfm7j6Y0xXurXtTQQo+zt+GZPU=;\n\tb=fWqmnKd8c+LGsRivq8Fvze0TeV7AI0CalL/OPx2peoE2+YZo7kLL/2O5hlsaLhLniR\n\tj48GkD1LsUYTUbKhhSSy+ht4couoEdDpaYKW7c/lkNaWGRbeOOvRhSlRrywu1U5JMNlM\n\trCnXJfQzjpC2mSMmqqhrMqlaXEFXGEhlN2SXBcnpHaaHdI9wcInuZsgxkXksZJ16H4mi\n\tqyeCNmUdtkgh8ZeCUArfW/ySQEEChc9qW1IbZYLvWCnoiXwWoytvRWOY7N2jD+6DFEBC\n\tcI7jbCWqB3lyXykpqBRx647LXN6s/KTVHX89xHnE3HzUpDAiBBDbTUXEkLBex/rmuOB/\n\tYBmw==","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:user-agent;\n\tbh=6SwoRQ8K/jjiCFeqvIfm7j6Y0xXurXtTQQo+zt+GZPU=;\n\tb=KG2UohqGQ+0MA5X/BMDFkAhPIeaEpEoXCGbnKPCxiEq0m0B/j+ldAgT222s4xai/xk\n\tdMgTnqWwQ3ZlTDbJJranC+Q3SNC5fDInknXi73tvYOy7OJqUwItroua8ub0WeyDrLv8/\n\tHHoZAMGdVnkiuhN7JYb5bt9H70ZXfugD22y8ocioA1nxn4l/C/HXv79LpMKBdIGJpG1m\n\tF4A+nqLeMcTBs/UDmk5bM3fMz8SzrG/vYd+kX/FqvOV7pYBrFYgxL3sNYiVLzq6teyw6\n\tjZaH202s21zzkIEvMidNiJMudsqNrqSqrGFnM51Et6RTKXxpkxTcS1s1wHEr5LlyixGu\n\t8qQA==","X-Gm-Message-State":"AJcUukeJvE+/agIJMQvSPBaA3leNHzDe+1Kydqkl8h5nwJGC/5LECzSG\n\t56CrslfxzV0fQZndsAf22oH0RbG/TNA=","X-Google-Smtp-Source":"ALg8bN5vpFRnFn8XSRj4yjvkvah/I9fx9W/bdaHZZ394mwY4PSWTwhnuni5Dp3zH6CI6M9DI41AwZA==","X-Received":"by 2002:a2e:8007:: with SMTP id\n\tj7-v6mr29159822ljg.50.1548957674549; \n\tThu, 31 Jan 2019 10:01:14 -0800 (PST)","Date":"Thu, 31 Jan 2019 19:01:13 +0100","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":"<20190131180112.GJ19527@bigcity.dyn.berto.se>","References":"<20190130115615.17362-1-niklas.soderlund@ragnatech.se>\n\t<20190130115615.17362-7-niklas.soderlund@ragnatech.se>\n\t<20190131003032.GF5358@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":"<20190131003032.GF5358@pendragon.ideasonboard.com>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH v5 6/6] libcamera: camera: extend\n\tcamera object to support configuration of 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":"Thu, 31 Jan 2019 18:01:15 -0000"}},{"id":726,"web_url":"https://patchwork.libcamera.org/comment/726/","msgid":"<20190131235806.GB4674@pendragon.ideasonboard.com>","date":"2019-01-31T23:58:06","subject":"Re: [libcamera-devel] [PATCH v5 6/6] libcamera: camera: extend\n\tcamera object to support configuration of streams","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Niklas,\n\nOn Thu, Jan 31, 2019 at 07:01:13PM +0100, Niklas Söderlund wrote:\n> On 2019-01-31 02:30:32 +0200, Laurent Pinchart wrote:\n> > On Wed, Jan 30, 2019 at 12:56:15PM +0100, Niklas Söderlund wrote:\n> >> Extend the camera to support reading and configuring formats for\n> >> groups of streams. The implementation in the Camera are minimalistic as\n> >> the heavy lifting are done by the pipeline handler implementations.\n> >> \n> >> The most important functionality the camera provides in this context is\n> >> validation of data structures passed to it from the application and\n> >> access control to the pipeline handler.\n> >> \n> >> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> >> ---\n> >>  include/libcamera/camera.h |  4 +++\n> >>  src/libcamera/camera.cpp   | 61 ++++++++++++++++++++++++++++++++++++++\n> >>  2 files changed, 65 insertions(+)\n> >> \n> >> diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> >> index 01498935ae4aab58..b21d116edc0f3a57 100644\n> >> --- a/include/libcamera/camera.h\n> >> +++ b/include/libcamera/camera.h\n> >> @@ -7,6 +7,7 @@\n> >>  #ifndef __LIBCAMERA_CAMERA_H__\n> >>  #define __LIBCAMERA_CAMERA_H__\n> >>  \n> >> +#include <map>\n> >>  #include <memory>\n> >>  #include <string>\n> >>  \n> >> @@ -16,6 +17,7 @@ namespace libcamera {\n> >>  \n> >>  class PipelineHandler;\n> >>  class Stream;\n> >> +class StreamConfiguration;\n> >>  \n> >>  class Camera final\n> >>  {\n> >> @@ -35,6 +37,8 @@ public:\n> >>  \tvoid release();\n> >>  \n> >>  \tconst std::vector<Stream *> streams() const;\n> >> +\tstd::map<Stream*, StreamConfiguration> streamConfiguration(std::vector<Stream*> &streams);\n> > \n> > s/;/ const;/\n> > \n> >> +\tint configureStreams(std::map<Stream*, StreamConfiguration> &config);\n> > \n> > s/(/(const /\n> > \n> >>  private:\n> >>  \tCamera(PipelineHandler *pipe, const std::string &name);\n> >> diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> >> index 986b74407aed6bd2..a293350f731e18df 100644\n> >> --- a/src/libcamera/camera.cpp\n> >> +++ b/src/libcamera/camera.cpp\n> >> @@ -190,4 +190,65 @@ const std::vector<Stream *> Camera::streams() const\n> >>  \treturn streams_;\n> >>  }\n> >>  \n> >> +/**\n> >> + * \\brief Retrieve a group of stream configurations\n> >> + * \\param[in] streams A map of stream IDs and configurations to setup\n> >> + *\n> >> + * Retrieve the camera's configuration for a specified group of streams. The\n> >> + * caller can specifies which of the camera's streams to retrieve configuration\n> >> + * from by populating \\a streams.\n> >> + *\n> >> + * The easiest way to populate the array of streams to fetch configuration from\n> >> + * is to first retrieve the camera's full array of stream by with streams() and\n> > \n> > \"by with\" ?\n> > \n> >> + * then potentially trim it down to only contain the streams the caller\n> >> + * are interested in.\n> >> + *\n> >> + * \\return A map of successfully retrieved stream IDs and configurations or an\n> >> + * empty list on error.\n> > \n> > That doesn't allow returning an error code to discriminate between\n> > errors :-/ I wonder if we should pass the map as an argument by pointer\n> > and return an integer. Or maybe there's no need to discriminate between\n> > errors ?\n> \n> Good question, I'm not sure if we need to discriminate between errors \n> here? If we do how would an application act on the different errors?\n\nI'm not sure either, although distinguishing invalid arguments from\ndisconnection may be useful. Maybe we can leave it as-is for now.\n\n> >> + */\n> >> +std::map<Stream*, StreamConfiguration>\n> >> +Camera::streamConfiguration(std::vector<Stream*> &streams)\n> >> +{\n> >> +\tif (disconnected_ || !streams.size())\n> >> +\t\tstd::map<unsigned int, StreamConfiguration>{};\n> >> +\n> >> +\treturn pipe_->streamConfiguration(this, streams);\n> >> +}\n> >> +\n> >> +/**\n> >> + * \\brief Configure the camera's streams prior to capture\n> >> + * \\param[in] config A map of stream IDs and configurations to setup\n> >> + *\n> >> + * Prior to starting capture, the camera must be configured to select a\n> >> + * group of streams to be involved in the capture and their configuration.\n> >> + * The caller specifies which streams are to be involved and their configuration\n> >> + * by populating \\a config.\n> >> + *\n> >> + * The easiest way to populate the array of config is to fetch an initial\n> >> + * configuration from the camera with streamConfiguration() and then change the\n> >> + * parameters to fit the caller's need and once all the streams parameters are\n> >> + * configured hand that over to configureStreams() to actually setup the camera.\n> >> + *\n> >> + * Exclusive access to the camera shall be ensured by a call to acquire() prior\n> >> + * to calling this function, otherwise an -EACCES error is be returned.\n> > \n> > s/is be/will be/\n> > \n> >> + *\n> >> + * \\return 0 on success or a negative error code on error.\n> >> + * \\retval -ENODEV The camera is not connected to any hardware\n> >> + * \\retval -EACCES The user have not acquired exclusive access to the camera\n> > \n> > s/have not/has not/\n> > \n> >> + * \\retval -EINVAL The configuration is not valid\n> >> + */\n> >> +int Camera::configureStreams(std::map<Stream*, StreamConfiguration> &config)\n> >> +{\n> >> +\tif (disconnected_)\n> >> +\t\treturn -ENODEV;\n> >> +\n> >> +\tif (!acquired_)\n> >> +\t\treturn -EACCES;\n> >> +\n> >> +\tif (!config.size())\n> >> +\t\treturn -EINVAL;\n> >> +\n> >> +\treturn pipe_->configureStreams(this, config);\n> >> +}\n> >> +\n> >>  } /* namespace libcamera */","headers":{"Return-Path":"<laurent.pinchart@ideasonboard.com>","Received":["from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[213.167.242.64])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D64B760DB4\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tFri,  1 Feb 2019 00:58:14 +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 65B6B41;\n\tFri,  1 Feb 2019 00:58:12 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1548979093;\n\tbh=JEmkFH6HjabaYoQ4PgfQjkQ45S//dZNypMg69FeiURk=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=i91SonG786cTlt7SYsUSdP3R/lje8LVwmCbLTOa0Kyd5JVrtGyitXnfX3Zwgith9L\n\tvtj7qHa5lWGuAPH11O6q6K0v+tcpaZ2Ug82r+Hb8TvrPNEp+D5K33Xa/pJCFVtJ7+P\n\tyrjqsks+eswBmiPFSSlnT/kPYz/9zK2seMYkdUMk=","Date":"Fri, 1 Feb 2019 01:58:06 +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":"<20190131235806.GB4674@pendragon.ideasonboard.com>","References":"<20190130115615.17362-1-niklas.soderlund@ragnatech.se>\n\t<20190130115615.17362-7-niklas.soderlund@ragnatech.se>\n\t<20190131003032.GF5358@pendragon.ideasonboard.com>\n\t<20190131180112.GJ19527@bigcity.dyn.berto.se>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20190131180112.GJ19527@bigcity.dyn.berto.se>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH v5 6/6] libcamera: camera: extend\n\tcamera object to support configuration of 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":"Thu, 31 Jan 2019 23:58:15 -0000"}}]