[{"id":1639,"web_url":"https://patchwork.libcamera.org/comment/1639/","msgid":"<20190521101206.yitlckkrnqe7cl4h@uno.localdomain>","date":"2019-05-21T10:12:06","subject":"Re: [libcamera-devel] [PATCH v2 2/6] libcamera: Use stream roles\n\tdirectly instead of StreamUsage","submitter":{"id":3,"url":"https://patchwork.libcamera.org/api/people/3/","name":"Jacopo Mondi","email":"jacopo@jmondi.org"},"content":"Hi Laurent,\n\nOn Sun, May 19, 2019 at 06:00:43PM +0300, Laurent Pinchart wrote:\n> In order to prepare for an API overhall of the camera configuration\n> generation, remove the StreamUsage class and replace its uses by stream\n> roles. The size hints can't be specified anymore, and will be replaced\n> with an API on the StreamConfiguration to negotiate configuration\n> parameters with cameras.\n>\n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> ---\n>  include/libcamera/camera.h               |  8 +--\n>  include/libcamera/stream.h               | 44 ++----------\n>  src/cam/main.cpp                         | 13 ++--\n>  src/libcamera/camera.cpp                 | 16 ++---\n>  src/libcamera/include/pipeline_handler.h |  6 +-\n>  src/libcamera/pipeline/ipu3/ipu3.cpp     | 28 ++++----\n>  src/libcamera/pipeline/rkisp1/rkisp1.cpp |  4 +-\n>  src/libcamera/pipeline/uvcvideo.cpp      |  5 +-\n>  src/libcamera/pipeline/vimc.cpp          |  5 +-\n>  src/libcamera/pipeline_handler.cpp       | 10 +--\n>  src/libcamera/stream.cpp                 | 89 ++++--------------------\n>  src/qcam/main_window.cpp                 |  2 +-\n>  test/camera/capture.cpp                  |  2 +-\n>  test/camera/configuration_default.cpp    |  6 +-\n>  test/camera/configuration_set.cpp        |  2 +-\n>  test/camera/statemachine.cpp             |  2 +-\n>  16 files changed, 69 insertions(+), 173 deletions(-)\n>\n> diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> index 306739b7014a..42ba5201eabc 100644\n> --- a/include/libcamera/camera.h\n> +++ b/include/libcamera/camera.h\n> @@ -14,16 +14,13 @@\n>\n>  #include <libcamera/request.h>\n>  #include <libcamera/signal.h>\n> +#include <libcamera/stream.h>\n>\n>  namespace libcamera {\n>\n>  class Buffer;\n>  class PipelineHandler;\n>  class Request;\n> -class Stream;\n> -class StreamUsage;\n\nI guess this would just need a StreamUsage/StreamRoles but I'm fine\nwith dropping forward declarations and include stream.h\n\n> -\n> -struct StreamConfiguration;\n>\n>  class CameraConfiguration\n>  {\n> @@ -74,8 +71,7 @@ public:\n>  \tint release();\n>\n>  \tconst std::set<Stream *> &streams() const;\n> -\tCameraConfiguration\n> -\tgenerateConfiguration(const std::vector<StreamUsage> &usage);\n> +\tCameraConfiguration generateConfiguration(const StreamRoles &roles);\n>  \tint configure(const CameraConfiguration &config);\n>\n>  \tint allocateBuffers();\n> diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h\n> index 0c986310939b..59bdf217eb31 100644\n> --- a/include/libcamera/stream.h\n> +++ b/include/libcamera/stream.h\n> @@ -8,6 +8,7 @@\n>  #define __LIBCAMERA_STREAM_H__\n>\n>  #include <string>\n> +#include <vector>\n>\n>  #include <libcamera/buffer.h>\n>  #include <libcamera/geometry.h>\n> @@ -25,48 +26,17 @@ struct StreamConfiguration {\n>  \tstd::string toString() const;\n>  };\n>\n> -class StreamUsage\n> -{\n> -public:\n> -\tenum Role {\n> -\t\tStillCapture,\n> -\t\tVideoRecording,\n> -\t\tViewfinder,\n> -\t};\n> -\n> -\tRole role() const { return role_; }\n> -\tconst Size &size() const { return size_; }\n> -\n> -protected:\n> -\texplicit StreamUsage(Role role);\n> -\tStreamUsage(Role role, const Size &size);\n> -\n> -private:\n> -\tRole role_;\n> -\tSize size_;\n> +enum StreamRole {\n> +\tStillCapture,\n> +\tVideoRecording,\n> +\tViewfinder,\n>  };\n>\n> +using StreamRoles = std::vector<StreamRole>;\n> +\n\nThis is indeed nicer to write, it's true that for a user of it,\ndealing with an std::vector directly would make it clear which API to\nuse without having to look at the type def here.\n\n>  class Stream\n>  {\n>  public:\n> -\tclass StillCapture : public StreamUsage\n> -\t{\n> -\tpublic:\n> -\t\tStillCapture();\n> -\t};\n> -\n> -\tclass VideoRecording : public StreamUsage\n> -\t{\n> -\tpublic:\n> -\t\tVideoRecording();\n> -\t};\n> -\n> -\tclass Viewfinder : public StreamUsage\n> -\t{\n> -\tpublic:\n> -\t\tViewfinder(int width, int height);\n> -\t};\n> -\n>  \tStream();\n>  \tBufferPool &bufferPool() { return bufferPool_; }\n>  \tconst StreamConfiguration &configuration() const { return configuration_; }\n> diff --git a/src/cam/main.cpp b/src/cam/main.cpp\n> index 6a2508dd3bd9..d603228c0116 100644\n> --- a/src/cam/main.cpp\n> +++ b/src/cam/main.cpp\n> @@ -87,13 +87,13 @@ static int parseOptions(int argc, char *argv[])\n>\n>  static int prepareCameraConfig(CameraConfiguration *config)\n>  {\n> -\tstd::vector<StreamUsage> roles;\n> +\tStreamRoles roles;\n>\n>  \tstreamInfo.clear();\n>\n>  \t/* If no configuration is provided assume a single video stream. */\n>  \tif (!options.isSet(OptStream)) {\n> -\t\t*config = camera->generateConfiguration({ Stream::VideoRecording() });\n> +\t\t*config = camera->generateConfiguration({ StreamRole::VideoRecording });\n>  \t\tstreamInfo[config->front()] = \"stream0\";\n>  \t\treturn 0;\n>  \t}\n> @@ -106,14 +106,13 @@ static int prepareCameraConfig(CameraConfiguration *config)\n>  \t\tKeyValueParser::Options conf = value.toKeyValues();\n>\n>  \t\tif (!conf.isSet(\"role\")) {\n> -\t\t\troles.push_back(Stream::VideoRecording());\n> +\t\t\troles.push_back(StreamRole::VideoRecording);\n>  \t\t} else if (conf[\"role\"].toString() == \"viewfinder\") {\n> -\t\t\troles.push_back(Stream::Viewfinder(conf[\"width\"],\n> -\t\t\t\t\t\t\t   conf[\"height\"]));\n> +\t\t\troles.push_back(StreamRole::Viewfinder);\n>  \t\t} else if (conf[\"role\"].toString() == \"video\") {\n> -\t\t\troles.push_back(Stream::VideoRecording());\n> +\t\t\troles.push_back(StreamRole::VideoRecording);\n>  \t\t} else if (conf[\"role\"].toString() == \"still\") {\n> -\t\t\troles.push_back(Stream::StillCapture());\n> +\t\t\troles.push_back(StreamRole::StillCapture);\n>  \t\t} else {\n>  \t\t\tstd::cerr << \"Unknown stream role \"\n>  \t\t\t\t  << conf[\"role\"].toString() << std::endl;\n> diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> index 359174a41823..a3921f91f1c9 100644\n> --- a/src/libcamera/camera.cpp\n> +++ b/src/libcamera/camera.cpp\n> @@ -542,23 +542,23 @@ const std::set<Stream *> &Camera::streams() const\n>  }\n>\n>  /**\n> - * \\brief Generate a default camera configuration according to stream usages\n> - * \\param[in] usages A list of stream usages\n> + * \\brief Generate a default camera configuration according to stream roles\n> + * \\param[in] roles A list of stream roles\n>   *\n> - * Generate a camera configuration for a set of desired usages. The caller\n> - * specifies a list of stream usages and the camera returns a configuration\n> + * Generate a camera configuration for a set of desired stream roles. The caller\n> + * specifies a list of stream roles and the camera returns a configuration\n>   * containing suitable streams and their suggested default configurations.\n>   *\n> - * \\return A valid CameraConfiguration if the requested usages can be satisfied,\n> + * \\return A valid CameraConfiguration if the requested roles can be satisfied,\n>   * or a invalid one otherwise\n>   */\n>  CameraConfiguration\n> -Camera::generateConfiguration(const std::vector<StreamUsage> &usages)\n> +Camera::generateConfiguration(const StreamRoles &roles)\n>  {\n> -\tif (disconnected_ || !usages.size() || usages.size() > streams_.size())\n> +\tif (disconnected_ || !roles.size() || roles.size() > streams_.size())\n>  \t\treturn CameraConfiguration();\n>\n> -\tCameraConfiguration config = pipe_->generateConfiguration(this, usages);\n> +\tCameraConfiguration config = pipe_->generateConfiguration(this, roles);\n>\n>  \tstd::ostringstream msg(\"streams configuration:\", std::ios_base::ate);\n>  \tunsigned int index = 0;\n> diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h\n> index 9cc11a8e192e..3352cb0e5bc9 100644\n> --- a/src/libcamera/include/pipeline_handler.h\n> +++ b/src/libcamera/include/pipeline_handler.h\n> @@ -14,6 +14,8 @@\n>  #include <string>\n>  #include <vector>\n>\n> +#include <libcamera/stream.h>\n> +\n>  namespace libcamera {\n>\n>  class Buffer;\n> @@ -26,8 +28,6 @@ class DeviceMatch;\n>  class MediaDevice;\n>  class PipelineHandler;\n>  class Request;\n> -class Stream;\n> -class StreamUsage;\n\nSame comment as above. Or would you need to forward declare both StreamRoles\nand StreamRole?\n\n>\n>  class CameraData\n>  {\n> @@ -61,7 +61,7 @@ public:\n>  \tvoid unlock();\n>\n>  \tvirtual CameraConfiguration\n> -\tgenerateConfiguration(Camera *camera, const std::vector<StreamUsage> &usages) = 0;\n> +\tgenerateConfiguration(Camera *camera, const StreamRoles &roles) = 0;\n>  \tvirtual int configure(Camera *camera, const CameraConfiguration &config) = 0;\n>\n>  \tvirtual int allocateBuffers(Camera *camera,\n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index ba0c708f9e1e..d234a8ac5289 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -151,8 +151,7 @@ public:\n>  \tPipelineHandlerIPU3(CameraManager *manager);\n>\n>  \tCameraConfiguration\n> -\tgenerateConfiguration(Camera *camera,\n> -\t\t\t      const std::vector<StreamUsage> &usages) override;\n> +\tgenerateConfiguration(Camera *camera, const StreamRoles &roles) override;\n>  \tint configure(Camera *camera,\n>  \t\t      const CameraConfiguration &config) override;\n>\n> @@ -211,7 +210,7 @@ PipelineHandlerIPU3::PipelineHandlerIPU3(CameraManager *manager)\n>\n>  CameraConfiguration\n>  PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n> -\t\t\t\t\t   const std::vector<StreamUsage> &usages)\n> +\t\t\t\t\t   const StreamRoles &roles)\n>  {\n>  \tIPU3CameraData *data = cameraData(camera);\n>  \tCameraConfiguration config = {};\n> @@ -220,13 +219,12 @@ PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n>  \t\t&data->vfStream_,\n>  \t};\n>\n> -\tfor (const StreamUsage &usage : usages) {\n> +\tfor (const StreamRole role : roles) {\n>  \t\tStreamConfiguration cfg = {};\n> -\t\tStreamUsage::Role role = usage.role();\n>  \t\tIPU3Stream *stream = nullptr;\n>\n>  \t\tswitch (role) {\n> -\t\tcase StreamUsage::Role::StillCapture:\n> +\t\tcase StreamRole::StillCapture:\n>  \t\t\t/*\n>  \t\t\t * Pick the output stream by default as the Viewfinder\n>  \t\t\t * and VideoRecording roles are not allowed on\n> @@ -256,11 +254,11 @@ PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n>\n>  \t\t\tbreak;\n>\n> -\t\tcase StreamUsage::Role::Viewfinder:\n> -\t\tcase StreamUsage::Role::VideoRecording: {\n> +\t\tcase StreamRole::Viewfinder:\n> +\t\tcase StreamRole::VideoRecording: {\n>  \t\t\t/*\n>  \t\t\t * We can't use the 'output' stream for viewfinder or\n> -\t\t\t * video capture usages.\n> +\t\t\t * video capture roles.\n>  \t\t\t *\n>  \t\t\t * \\todo This is an artificial limitation until we\n>  \t\t\t * figure out the exact capabilities of the hardware.\n> @@ -275,15 +273,13 @@ PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n>  \t\t\tstream = &data->vfStream_;\n>\n>  \t\t\t/*\n> -\t\t\t * Align the requested viewfinder size to the\n> -\t\t\t * maximum available sensor resolution and to the\n> -\t\t\t * IPU3 alignment constraints.\n> +\t\t\t * Align the default viewfinder size to the maximum\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\tunsigned int width = std::min(usage.size().width,\n> -\t\t\t\t\t\t      res.width);\n> -\t\t\tunsigned int height = std::min(usage.size().height,\n> -\t\t\t\t\t\t       res.height);\n> +\t\t\tunsigned int width = std::min(1280U, res.width);\n> +\t\t\tunsigned int height = std::min(720U, res.height);\n\nWhy 1280x720 ?\n\n>  \t\t\tcfg.size = { width & ~7, height & ~3 };\n>\n>  \t\t\tbreak;\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index 4d02f9604ad9..4bd8c5101a96 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -35,7 +35,7 @@ public:\n>  \t~PipelineHandlerRkISP1();\n>\n>  \tCameraConfiguration generateConfiguration(Camera *camera,\n> -\t\tconst std::vector<StreamUsage> &usages) override;\n> +\t\tconst StreamRoles &roles) override;\n>  \tint configure(Camera *camera,\n>  \t\tconst CameraConfiguration &config) override;\n>\n> @@ -107,7 +107,7 @@ PipelineHandlerRkISP1::~PipelineHandlerRkISP1()\n>   */\n>\n>  CameraConfiguration PipelineHandlerRkISP1::generateConfiguration(Camera *camera,\n> -\tconst std::vector<StreamUsage> &usages)\n> +\tconst StreamRoles &roles)\n>  {\n>  \tRkISP1CameraData *data = cameraData(camera);\n>  \tCameraConfiguration config;\n> diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\n> index 118b97457d2a..d2e1f7d4e5b2 100644\n> --- a/src/libcamera/pipeline/uvcvideo.cpp\n> +++ b/src/libcamera/pipeline/uvcvideo.cpp\n> @@ -26,8 +26,7 @@ public:\n>  \tPipelineHandlerUVC(CameraManager *manager);\n>\n>  \tCameraConfiguration\n> -\tgenerateConfiguration(Camera *camera,\n> -\t\t\t      const std::vector<StreamUsage> &usages) override;\n> +\tgenerateConfiguration(Camera *camera, const StreamRoles &roles) override;\n>  \tint configure(Camera *camera,\n>  \t\t      const CameraConfiguration &config) override;\n>\n> @@ -77,7 +76,7 @@ PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager)\n>\n>  CameraConfiguration\n>  PipelineHandlerUVC::generateConfiguration(Camera *camera,\n> -\t\t\t\t\t  const std::vector<StreamUsage> &usages)\n> +\t\t\t\t\t  const StreamRoles &roles)\n>  {\n>  \tUVCCameraData *data = cameraData(camera);\n>  \tCameraConfiguration config;\n> diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp\n> index 74959581a7ef..17e2491e5c27 100644\n> --- a/src/libcamera/pipeline/vimc.cpp\n> +++ b/src/libcamera/pipeline/vimc.cpp\n> @@ -26,8 +26,7 @@ public:\n>  \tPipelineHandlerVimc(CameraManager *manager);\n>\n>  \tCameraConfiguration\n> -\tgenerateConfiguration(Camera *camera,\n> -\t\t\t      const std::vector<StreamUsage> &usages) override;\n> +\tgenerateConfiguration(Camera *camera, const StreamRoles &roles) override;\n>  \tint configure(Camera *camera,\n>  \t\t      const CameraConfiguration &config) override;\n>\n> @@ -77,7 +76,7 @@ PipelineHandlerVimc::PipelineHandlerVimc(CameraManager *manager)\n>\n>  CameraConfiguration\n>  PipelineHandlerVimc::generateConfiguration(Camera *camera,\n> -\t\t\t\t\t   const std::vector<StreamUsage> &usages)\n> +\t\t\t\t\t   const StreamRoles &roles)\n>  {\n>  \tVimcCameraData *data = cameraData(camera);\n>  \tCameraConfiguration config;\n> diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\n> index b9ac64328f1d..81c11149c9fe 100644\n> --- a/src/libcamera/pipeline_handler.cpp\n> +++ b/src/libcamera/pipeline_handler.cpp\n> @@ -221,18 +221,18 @@ void PipelineHandler::unlock()\n>   * \\fn PipelineHandler::generateConfiguration()\n>   * \\brief Generate a camera configuration for a specified camera\n>   * \\param[in] camera The camera to generate a default configuration for\n> - * \\param[in] usages A list of stream usages\n> + * \\param[in] roles A list of stream roles\n>   *\n> - * Generate a default configuration for the \\a camera for a specified group of\n> - * use-cases. The caller shall populate the \\a usages array with the use-cases\n> - * it wishes to fetch the default configuration for. The returned configuration\n> + * Generate a default configuration for the \\a camera for a specified list of\n> + * stream roles. The caller shall populate the \\a roles with the use-cases it\n> + * wishes to fetch the default configuration for. The returned configuration\n>   * can then be examined by the caller to learn about the selected streams and\n>   * their default parameters.\n>   *\n>   * The intended companion to this is \\a configure() which can be used to change\n>   * the group of streams parameters.\n>   *\n> - * \\return A valid CameraConfiguration if the requested usages can be satisfied,\n> + * \\return A valid CameraConfiguration if the requested roles can be satisfied,\n>   * or a invalid configuration otherwise\n>   */\n>\n> diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp\n> index af259510b19c..fe4c4ecf4150 100644\n> --- a/src/libcamera/stream.cpp\n> +++ b/src/libcamera/stream.cpp\n> @@ -75,61 +75,31 @@ std::string StreamConfiguration::toString() const\n>  }\n>\n>  /**\n> - * \\class StreamUsage\n> - * \\brief Stream usage information\n> - *\n> - * The StreamUsage class describes how an application intends to use a stream.\n> - * Usages are specified by applications and passed to cameras, that then select\n> - * the most appropriate streams and their default configurations.\n> - */\n> -\n> -/**\n> - * \\enum StreamUsage::Role\n> + * \\enum StreamRole\n>   * \\brief Identify the role a stream is intended to play\n> - * \\var StreamUsage::StillCapture\n> + *\n> + * The StreamRole describes how an application intends to use a stream. Roles\n> + * are specified by applications and passed to cameras, that then select the\n\ns/select/selects ?\n\nMinors apart, and the resolution selected on IPU3 clarified:\nReviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n\nThanks\n   j\n\n\n> + * most appropriate streams and their default configurations.\n> + *\n> + * \\var StillCapture\n>   * The stream is intended to capture high-resolution, high-quality still images\n>   * with low frame rate. The captured frames may be exposed with flash.\n> - * \\var StreamUsage::VideoRecording\n> + * \\var VideoRecording\n>   * The stream is intended to capture video for the purpose of recording or\n>   * streaming. The video stream may produce a high frame rate and may be\n>   * enhanced with video stabilization.\n> - * \\var StreamUsage::Viewfinder\n> + * \\var Viewfinder\n>   * The stream is intended to capture video for the purpose of display on the\n> - * local screen. The StreamUsage includes the desired resolution. Trade-offs\n> - * between quality and usage of system resources are acceptable.\n> + * local screen. Trade-offs between quality and usage of system resources are\n> + * acceptable.\n>   */\n>\n>  /**\n> - * \\fn StreamUsage::role()\n> - * \\brief Retrieve the stream role\n> - * \\return The stream role\n> + * \\typedef StreamRoles\n> + * \\brief A vector of StreamRole\n>   */\n>\n> -/**\n> - * \\fn StreamUsage::size()\n> - * \\brief Retrieve desired size\n> - * \\return The desired size\n> - */\n> -\n> -/**\n> - * \\brief Create a stream usage\n> - * \\param[in] role Stream role\n> - */\n> -StreamUsage::StreamUsage(Role role)\n> -\t: role_(role)\n> -{\n> -}\n> -\n> -/**\n> - * \\brief Create a stream usage with a desired size\n> - * \\param[in] role Stream role\n> - * \\param[in] size The desired size\n> - */\n> -StreamUsage::StreamUsage(Role role, const Size &size)\n> -\t: role_(role), size_(size)\n> -{\n> -}\n> -\n>  /**\n>   * \\class Stream\n>   * \\brief Video stream for a camera\n> @@ -148,39 +118,6 @@ StreamUsage::StreamUsage(Role role, const Size &size)\n>   * optimal stream for the task.\n>   */\n>\n> -/**\n> - * \\class Stream::StillCapture\n> - * \\brief Describe a still capture usage\n> - */\n> -Stream::StillCapture::StillCapture()\n> -\t: StreamUsage(Role::StillCapture)\n> -{\n> -}\n> -\n> -/**\n> - * \\class Stream::VideoRecording\n> - * \\brief Describe a video recording usage\n> - */\n> -Stream::VideoRecording::VideoRecording()\n> -\t: StreamUsage(Role::VideoRecording)\n> -{\n> -}\n> -\n> -/**\n> - * \\class Stream::Viewfinder\n> - * \\brief Describe a viewfinder usage\n> - */\n> -\n> -/**\n> - * \\brief Create a viewfinder usage with a desired dimension\n> - * \\param[in] width The desired viewfinder width\n> - * \\param[in] height The desired viewfinder height\n> - */\n> -Stream::Viewfinder::Viewfinder(int width, int height)\n> -\t: StreamUsage(Role::Viewfinder, Size(width, height))\n> -{\n> -}\n> -\n>  /**\n>   * \\brief Construct a stream with default parameters\n>   */\n> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> index c91b82727ec6..a984aaca764f 100644\n> --- a/src/qcam/main_window.cpp\n> +++ b/src/qcam/main_window.cpp\n> @@ -97,7 +97,7 @@ int MainWindow::startCapture()\n>  {\n>  \tint ret;\n>\n> -\tconfig_ = camera_->generateConfiguration({ Stream::VideoRecording() });\n> +\tconfig_ = camera_->generateConfiguration({ StreamRole::VideoRecording });\n>  \tStream *stream = config_.front();\n>  \tret = camera_->configure(config_);\n>  \tif (ret < 0) {\n> diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp\n> index bc3a4d6cb9f2..e7e6438203b9 100644\n> --- a/test/camera/capture.cpp\n> +++ b/test/camera/capture.cpp\n> @@ -43,7 +43,7 @@ protected:\n>  \tint run()\n>  \t{\n>  \t\tCameraConfiguration config =\n> -\t\t\tcamera_->generateConfiguration({ Stream::VideoRecording() });\n> +\t\t\tcamera_->generateConfiguration({ StreamRole::VideoRecording });\n>  \t\tStream *stream = config.front();\n>  \t\tStreamConfiguration *cfg = &config[stream];\n>\n> diff --git a/test/camera/configuration_default.cpp b/test/camera/configuration_default.cpp\n> index 340b5f58f04c..8c4a03db498a 100644\n> --- a/test/camera/configuration_default.cpp\n> +++ b/test/camera/configuration_default.cpp\n> @@ -21,7 +21,7 @@ protected:\n>  \t\tCameraConfiguration config;\n>\n>  \t\t/* Test asking for configuration for a video stream. */\n> -\t\tconfig = camera_->generateConfiguration({ Stream::VideoRecording() });\n> +\t\tconfig = camera_->generateConfiguration({ StreamRole::VideoRecording });\n>  \t\tif (!config.isValid()) {\n>  \t\t\tcout << \"Default configuration invalid\" << endl;\n>  \t\t\treturn TestFail;\n> @@ -29,11 +29,11 @@ protected:\n>\n>  \t\t/*\n>  \t\t * Test that asking for configuration for an empty array of\n> -\t\t * stream usages returns an empty list of configurations.\n> +\t\t * stream roles returns an empty list of configurations.\n>  \t\t */\n>  \t\tconfig = camera_->generateConfiguration({});\n>  \t\tif (config.isValid()) {\n> -\t\t\tcout << \"Failed to retrieve configuration for empty usage list\"\n> +\t\t\tcout << \"Failed to retrieve configuration for empty roles list\"\n>  \t\t\t     << endl;\n>  \t\t\treturn TestFail;\n>  \t\t}\n> diff --git a/test/camera/configuration_set.cpp b/test/camera/configuration_set.cpp\n> index 24d5ca6690b7..76d8bc3e40a4 100644\n> --- a/test/camera/configuration_set.cpp\n> +++ b/test/camera/configuration_set.cpp\n> @@ -19,7 +19,7 @@ protected:\n>  \tint run()\n>  \t{\n>  \t\tCameraConfiguration config =\n> -\t\t\tcamera_->generateConfiguration({ Stream::VideoRecording() });\n> +\t\t\tcamera_->generateConfiguration({ StreamRole::VideoRecording });\n>  \t\tStreamConfiguration *cfg = &config[config.front()];\n>\n>  \t\tif (!config.isValid()) {\n> diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp\n> index bd2e61ff2939..7a74cd85a37a 100644\n> --- a/test/camera/statemachine.cpp\n> +++ b/test/camera/statemachine.cpp\n> @@ -235,7 +235,7 @@ protected:\n>\n>  \tint run()\n>  \t{\n> -\t\tdefconf_ = camera_->generateConfiguration({ Stream::VideoRecording() });\n> +\t\tdefconf_ = camera_->generateConfiguration({ StreamRole::VideoRecording });\n>\n>  \t\tif (testAvailable() != TestPass) {\n>  \t\t\tcout << \"State machine in Available state failed\" << endl;\n> --\n> Regards,\n>\n> Laurent Pinchart\n>\n> _______________________________________________\n> libcamera-devel mailing list\n> libcamera-devel@lists.libcamera.org\n> https://lists.libcamera.org/listinfo/libcamera-devel","headers":{"Return-Path":"<jacopo@jmondi.org>","Received":["from relay9-d.mail.gandi.net (relay9-d.mail.gandi.net\n\t[217.70.183.199])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id D27F860C27\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 21 May 2019 12:11:01 +0200 (CEST)","from uno.localdomain (2-224-242-101.ip172.fastwebnet.it\n\t[2.224.242.101]) (Authenticated sender: jacopo@jmondi.org)\n\tby relay9-d.mail.gandi.net (Postfix) with ESMTPSA id C6627FF816;\n\tTue, 21 May 2019 10:11:00 +0000 (UTC)"],"X-Originating-IP":"2.224.242.101","Date":"Tue, 21 May 2019 12:12:06 +0200","From":"Jacopo Mondi <jacopo@jmondi.org>","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20190521101206.yitlckkrnqe7cl4h@uno.localdomain>","References":"<20190519150047.12444-1-laurent.pinchart@ideasonboard.com>\n\t<20190519150047.12444-3-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"multipart/signed; micalg=pgp-sha256;\n\tprotocol=\"application/pgp-signature\"; boundary=\"s6e5fi4fttjbrl3t\"","Content-Disposition":"inline","In-Reply-To":"<20190519150047.12444-3-laurent.pinchart@ideasonboard.com>","User-Agent":"NeoMutt/20180716","Subject":"Re: [libcamera-devel] [PATCH v2 2/6] libcamera: Use stream roles\n\tdirectly instead of StreamUsage","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":"Tue, 21 May 2019 10:11:02 -0000"}},{"id":1643,"web_url":"https://patchwork.libcamera.org/comment/1643/","msgid":"<20190521135658.GF5674@pendragon.ideasonboard.com>","date":"2019-05-21T13:56:58","subject":"Re: [libcamera-devel] [PATCH v2 2/6] libcamera: Use stream roles\n\tdirectly instead of StreamUsage","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Jacopo,\n\nOn Tue, May 21, 2019 at 12:12:06PM +0200, Jacopo Mondi wrote:\n> On Sun, May 19, 2019 at 06:00:43PM +0300, Laurent Pinchart wrote:\n> > In order to prepare for an API overhall of the camera configuration\n> > generation, remove the StreamUsage class and replace its uses by stream\n> > roles. The size hints can't be specified anymore, and will be replaced\n> > with an API on the StreamConfiguration to negotiate configuration\n> > parameters with cameras.\n> >\n> > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n> > Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> > ---\n> >  include/libcamera/camera.h               |  8 +--\n> >  include/libcamera/stream.h               | 44 ++----------\n> >  src/cam/main.cpp                         | 13 ++--\n> >  src/libcamera/camera.cpp                 | 16 ++---\n> >  src/libcamera/include/pipeline_handler.h |  6 +-\n> >  src/libcamera/pipeline/ipu3/ipu3.cpp     | 28 ++++----\n> >  src/libcamera/pipeline/rkisp1/rkisp1.cpp |  4 +-\n> >  src/libcamera/pipeline/uvcvideo.cpp      |  5 +-\n> >  src/libcamera/pipeline/vimc.cpp          |  5 +-\n> >  src/libcamera/pipeline_handler.cpp       | 10 +--\n> >  src/libcamera/stream.cpp                 | 89 ++++--------------------\n> >  src/qcam/main_window.cpp                 |  2 +-\n> >  test/camera/capture.cpp                  |  2 +-\n> >  test/camera/configuration_default.cpp    |  6 +-\n> >  test/camera/configuration_set.cpp        |  2 +-\n> >  test/camera/statemachine.cpp             |  2 +-\n> >  16 files changed, 69 insertions(+), 173 deletions(-)\n> >\n> > diff --git a/include/libcamera/camera.h b/include/libcamera/camera.h\n> > index 306739b7014a..42ba5201eabc 100644\n> > --- a/include/libcamera/camera.h\n> > +++ b/include/libcamera/camera.h\n> > @@ -14,16 +14,13 @@\n> >\n> >  #include <libcamera/request.h>\n> >  #include <libcamera/signal.h>\n> > +#include <libcamera/stream.h>\n> >\n> >  namespace libcamera {\n> >\n> >  class Buffer;\n> >  class PipelineHandler;\n> >  class Request;\n> > -class Stream;\n> > -class StreamUsage;\n> \n> I guess this would just need a StreamUsage/StreamRoles but I'm fine\n> with dropping forward declarations and include stream.h\n\nStreamRoles is defined as\n\nusing StreamRoles = std::vector<StreamRole>;\n\nso I would have to duplicate that for the forward-declaration, which\nwouldn't be nice.\n\n> > -\n> > -struct StreamConfiguration;\n> >\n> >  class CameraConfiguration\n> >  {\n> > @@ -74,8 +71,7 @@ public:\n> >  \tint release();\n> >\n> >  \tconst std::set<Stream *> &streams() const;\n> > -\tCameraConfiguration\n> > -\tgenerateConfiguration(const std::vector<StreamUsage> &usage);\n> > +\tCameraConfiguration generateConfiguration(const StreamRoles &roles);\n> >  \tint configure(const CameraConfiguration &config);\n> >\n> >  \tint allocateBuffers();\n> > diff --git a/include/libcamera/stream.h b/include/libcamera/stream.h\n> > index 0c986310939b..59bdf217eb31 100644\n> > --- a/include/libcamera/stream.h\n> > +++ b/include/libcamera/stream.h\n> > @@ -8,6 +8,7 @@\n> >  #define __LIBCAMERA_STREAM_H__\n> >\n> >  #include <string>\n> > +#include <vector>\n> >\n> >  #include <libcamera/buffer.h>\n> >  #include <libcamera/geometry.h>\n> > @@ -25,48 +26,17 @@ struct StreamConfiguration {\n> >  \tstd::string toString() const;\n> >  };\n> >\n> > -class StreamUsage\n> > -{\n> > -public:\n> > -\tenum Role {\n> > -\t\tStillCapture,\n> > -\t\tVideoRecording,\n> > -\t\tViewfinder,\n> > -\t};\n> > -\n> > -\tRole role() const { return role_; }\n> > -\tconst Size &size() const { return size_; }\n> > -\n> > -protected:\n> > -\texplicit StreamUsage(Role role);\n> > -\tStreamUsage(Role role, const Size &size);\n> > -\n> > -private:\n> > -\tRole role_;\n> > -\tSize size_;\n> > +enum StreamRole {\n> > +\tStillCapture,\n> > +\tVideoRecording,\n> > +\tViewfinder,\n> >  };\n> >\n> > +using StreamRoles = std::vector<StreamRole>;\n> > +\n> \n> This is indeed nicer to write, it's true that for a user of it,\n> dealing with an std::vector directly would make it clear which API to\n> use without having to look at the type def here.\n\nI was a bit in two minds, but I decided to go for simplicity.\n\n> >  class Stream\n> >  {\n> >  public:\n> > -\tclass StillCapture : public StreamUsage\n> > -\t{\n> > -\tpublic:\n> > -\t\tStillCapture();\n> > -\t};\n> > -\n> > -\tclass VideoRecording : public StreamUsage\n> > -\t{\n> > -\tpublic:\n> > -\t\tVideoRecording();\n> > -\t};\n> > -\n> > -\tclass Viewfinder : public StreamUsage\n> > -\t{\n> > -\tpublic:\n> > -\t\tViewfinder(int width, int height);\n> > -\t};\n> > -\n> >  \tStream();\n> >  \tBufferPool &bufferPool() { return bufferPool_; }\n> >  \tconst StreamConfiguration &configuration() const { return configuration_; }\n> > diff --git a/src/cam/main.cpp b/src/cam/main.cpp\n> > index 6a2508dd3bd9..d603228c0116 100644\n> > --- a/src/cam/main.cpp\n> > +++ b/src/cam/main.cpp\n> > @@ -87,13 +87,13 @@ static int parseOptions(int argc, char *argv[])\n> >\n> >  static int prepareCameraConfig(CameraConfiguration *config)\n> >  {\n> > -\tstd::vector<StreamUsage> roles;\n> > +\tStreamRoles roles;\n> >\n> >  \tstreamInfo.clear();\n> >\n> >  \t/* If no configuration is provided assume a single video stream. */\n> >  \tif (!options.isSet(OptStream)) {\n> > -\t\t*config = camera->generateConfiguration({ Stream::VideoRecording() });\n> > +\t\t*config = camera->generateConfiguration({ StreamRole::VideoRecording });\n> >  \t\tstreamInfo[config->front()] = \"stream0\";\n> >  \t\treturn 0;\n> >  \t}\n> > @@ -106,14 +106,13 @@ static int prepareCameraConfig(CameraConfiguration *config)\n> >  \t\tKeyValueParser::Options conf = value.toKeyValues();\n> >\n> >  \t\tif (!conf.isSet(\"role\")) {\n> > -\t\t\troles.push_back(Stream::VideoRecording());\n> > +\t\t\troles.push_back(StreamRole::VideoRecording);\n> >  \t\t} else if (conf[\"role\"].toString() == \"viewfinder\") {\n> > -\t\t\troles.push_back(Stream::Viewfinder(conf[\"width\"],\n> > -\t\t\t\t\t\t\t   conf[\"height\"]));\n> > +\t\t\troles.push_back(StreamRole::Viewfinder);\n> >  \t\t} else if (conf[\"role\"].toString() == \"video\") {\n> > -\t\t\troles.push_back(Stream::VideoRecording());\n> > +\t\t\troles.push_back(StreamRole::VideoRecording);\n> >  \t\t} else if (conf[\"role\"].toString() == \"still\") {\n> > -\t\t\troles.push_back(Stream::StillCapture());\n> > +\t\t\troles.push_back(StreamRole::StillCapture);\n> >  \t\t} else {\n> >  \t\t\tstd::cerr << \"Unknown stream role \"\n> >  \t\t\t\t  << conf[\"role\"].toString() << std::endl;\n> > diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> > index 359174a41823..a3921f91f1c9 100644\n> > --- a/src/libcamera/camera.cpp\n> > +++ b/src/libcamera/camera.cpp\n> > @@ -542,23 +542,23 @@ const std::set<Stream *> &Camera::streams() const\n> >  }\n> >\n> >  /**\n> > - * \\brief Generate a default camera configuration according to stream usages\n> > - * \\param[in] usages A list of stream usages\n> > + * \\brief Generate a default camera configuration according to stream roles\n> > + * \\param[in] roles A list of stream roles\n> >   *\n> > - * Generate a camera configuration for a set of desired usages. The caller\n> > - * specifies a list of stream usages and the camera returns a configuration\n> > + * Generate a camera configuration for a set of desired stream roles. The caller\n> > + * specifies a list of stream roles and the camera returns a configuration\n> >   * containing suitable streams and their suggested default configurations.\n> >   *\n> > - * \\return A valid CameraConfiguration if the requested usages can be satisfied,\n> > + * \\return A valid CameraConfiguration if the requested roles can be satisfied,\n> >   * or a invalid one otherwise\n> >   */\n> >  CameraConfiguration\n> > -Camera::generateConfiguration(const std::vector<StreamUsage> &usages)\n> > +Camera::generateConfiguration(const StreamRoles &roles)\n> >  {\n> > -\tif (disconnected_ || !usages.size() || usages.size() > streams_.size())\n> > +\tif (disconnected_ || !roles.size() || roles.size() > streams_.size())\n> >  \t\treturn CameraConfiguration();\n> >\n> > -\tCameraConfiguration config = pipe_->generateConfiguration(this, usages);\n> > +\tCameraConfiguration config = pipe_->generateConfiguration(this, roles);\n> >\n> >  \tstd::ostringstream msg(\"streams configuration:\", std::ios_base::ate);\n> >  \tunsigned int index = 0;\n> > diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h\n> > index 9cc11a8e192e..3352cb0e5bc9 100644\n> > --- a/src/libcamera/include/pipeline_handler.h\n> > +++ b/src/libcamera/include/pipeline_handler.h\n> > @@ -14,6 +14,8 @@\n> >  #include <string>\n> >  #include <vector>\n> >\n> > +#include <libcamera/stream.h>\n> > +\n> >  namespace libcamera {\n> >\n> >  class Buffer;\n> > @@ -26,8 +28,6 @@ class DeviceMatch;\n> >  class MediaDevice;\n> >  class PipelineHandler;\n> >  class Request;\n> > -class Stream;\n> > -class StreamUsage;\n> \n> Same comment as above. Or would you need to forward declare both StreamRoles\n> and StreamRole?\n\nI would have to copy the using line :-(\n\n> >\n> >  class CameraData\n> >  {\n> > @@ -61,7 +61,7 @@ public:\n> >  \tvoid unlock();\n> >\n> >  \tvirtual CameraConfiguration\n> > -\tgenerateConfiguration(Camera *camera, const std::vector<StreamUsage> &usages) = 0;\n> > +\tgenerateConfiguration(Camera *camera, const StreamRoles &roles) = 0;\n> >  \tvirtual int configure(Camera *camera, const CameraConfiguration &config) = 0;\n> >\n> >  \tvirtual int allocateBuffers(Camera *camera,\n> > diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > index ba0c708f9e1e..d234a8ac5289 100644\n> > --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> > @@ -151,8 +151,7 @@ public:\n> >  \tPipelineHandlerIPU3(CameraManager *manager);\n> >\n> >  \tCameraConfiguration\n> > -\tgenerateConfiguration(Camera *camera,\n> > -\t\t\t      const std::vector<StreamUsage> &usages) override;\n> > +\tgenerateConfiguration(Camera *camera, const StreamRoles &roles) override;\n> >  \tint configure(Camera *camera,\n> >  \t\t      const CameraConfiguration &config) override;\n> >\n> > @@ -211,7 +210,7 @@ PipelineHandlerIPU3::PipelineHandlerIPU3(CameraManager *manager)\n> >\n> >  CameraConfiguration\n> >  PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n> > -\t\t\t\t\t   const std::vector<StreamUsage> &usages)\n> > +\t\t\t\t\t   const StreamRoles &roles)\n> >  {\n> >  \tIPU3CameraData *data = cameraData(camera);\n> >  \tCameraConfiguration config = {};\n> > @@ -220,13 +219,12 @@ PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n> >  \t\t&data->vfStream_,\n> >  \t};\n> >\n> > -\tfor (const StreamUsage &usage : usages) {\n> > +\tfor (const StreamRole role : roles) {\n> >  \t\tStreamConfiguration cfg = {};\n> > -\t\tStreamUsage::Role role = usage.role();\n> >  \t\tIPU3Stream *stream = nullptr;\n> >\n> >  \t\tswitch (role) {\n> > -\t\tcase StreamUsage::Role::StillCapture:\n> > +\t\tcase StreamRole::StillCapture:\n> >  \t\t\t/*\n> >  \t\t\t * Pick the output stream by default as the Viewfinder\n> >  \t\t\t * and VideoRecording roles are not allowed on\n> > @@ -256,11 +254,11 @@ PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n> >\n> >  \t\t\tbreak;\n> >\n> > -\t\tcase StreamUsage::Role::Viewfinder:\n> > -\t\tcase StreamUsage::Role::VideoRecording: {\n> > +\t\tcase StreamRole::Viewfinder:\n> > +\t\tcase StreamRole::VideoRecording: {\n> >  \t\t\t/*\n> >  \t\t\t * We can't use the 'output' stream for viewfinder or\n> > -\t\t\t * video capture usages.\n> > +\t\t\t * video capture roles.\n> >  \t\t\t *\n> >  \t\t\t * \\todo This is an artificial limitation until we\n> >  \t\t\t * figure out the exact capabilities of the hardware.\n> > @@ -275,15 +273,13 @@ PipelineHandlerIPU3::generateConfiguration(Camera *camera,\n> >  \t\t\tstream = &data->vfStream_;\n> >\n> >  \t\t\t/*\n> > -\t\t\t * Align the requested viewfinder size to the\n> > -\t\t\t * maximum available sensor resolution and to the\n> > -\t\t\t * IPU3 alignment constraints.\n> > +\t\t\t * Align the default viewfinder size to the maximum\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\tunsigned int width = std::min(usage.size().width,\n> > -\t\t\t\t\t\t      res.width);\n> > -\t\t\tunsigned int height = std::min(usage.size().height,\n> > -\t\t\t\t\t\t       res.height);\n> > +\t\t\tunsigned int width = std::min(1280U, res.width);\n> > +\t\t\tunsigned int height = std::min(720U, res.height);\n> \n> Why 1280x720 ?\n\nIt's just a random default, suitable for today's devices in general.\nApplications are expected to override it. Do you think another default\nwould be best ?\n\n> >  \t\t\tcfg.size = { width & ~7, height & ~3 };\n> >\n> >  \t\t\tbreak;\n> > diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> > index 4d02f9604ad9..4bd8c5101a96 100644\n> > --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> > +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> > @@ -35,7 +35,7 @@ public:\n> >  \t~PipelineHandlerRkISP1();\n> >\n> >  \tCameraConfiguration generateConfiguration(Camera *camera,\n> > -\t\tconst std::vector<StreamUsage> &usages) override;\n> > +\t\tconst StreamRoles &roles) override;\n> >  \tint configure(Camera *camera,\n> >  \t\tconst CameraConfiguration &config) override;\n> >\n> > @@ -107,7 +107,7 @@ PipelineHandlerRkISP1::~PipelineHandlerRkISP1()\n> >   */\n> >\n> >  CameraConfiguration PipelineHandlerRkISP1::generateConfiguration(Camera *camera,\n> > -\tconst std::vector<StreamUsage> &usages)\n> > +\tconst StreamRoles &roles)\n> >  {\n> >  \tRkISP1CameraData *data = cameraData(camera);\n> >  \tCameraConfiguration config;\n> > diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\n> > index 118b97457d2a..d2e1f7d4e5b2 100644\n> > --- a/src/libcamera/pipeline/uvcvideo.cpp\n> > +++ b/src/libcamera/pipeline/uvcvideo.cpp\n> > @@ -26,8 +26,7 @@ public:\n> >  \tPipelineHandlerUVC(CameraManager *manager);\n> >\n> >  \tCameraConfiguration\n> > -\tgenerateConfiguration(Camera *camera,\n> > -\t\t\t      const std::vector<StreamUsage> &usages) override;\n> > +\tgenerateConfiguration(Camera *camera, const StreamRoles &roles) override;\n> >  \tint configure(Camera *camera,\n> >  \t\t      const CameraConfiguration &config) override;\n> >\n> > @@ -77,7 +76,7 @@ PipelineHandlerUVC::PipelineHandlerUVC(CameraManager *manager)\n> >\n> >  CameraConfiguration\n> >  PipelineHandlerUVC::generateConfiguration(Camera *camera,\n> > -\t\t\t\t\t  const std::vector<StreamUsage> &usages)\n> > +\t\t\t\t\t  const StreamRoles &roles)\n> >  {\n> >  \tUVCCameraData *data = cameraData(camera);\n> >  \tCameraConfiguration config;\n> > diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp\n> > index 74959581a7ef..17e2491e5c27 100644\n> > --- a/src/libcamera/pipeline/vimc.cpp\n> > +++ b/src/libcamera/pipeline/vimc.cpp\n> > @@ -26,8 +26,7 @@ public:\n> >  \tPipelineHandlerVimc(CameraManager *manager);\n> >\n> >  \tCameraConfiguration\n> > -\tgenerateConfiguration(Camera *camera,\n> > -\t\t\t      const std::vector<StreamUsage> &usages) override;\n> > +\tgenerateConfiguration(Camera *camera, const StreamRoles &roles) override;\n> >  \tint configure(Camera *camera,\n> >  \t\t      const CameraConfiguration &config) override;\n> >\n> > @@ -77,7 +76,7 @@ PipelineHandlerVimc::PipelineHandlerVimc(CameraManager *manager)\n> >\n> >  CameraConfiguration\n> >  PipelineHandlerVimc::generateConfiguration(Camera *camera,\n> > -\t\t\t\t\t   const std::vector<StreamUsage> &usages)\n> > +\t\t\t\t\t   const StreamRoles &roles)\n> >  {\n> >  \tVimcCameraData *data = cameraData(camera);\n> >  \tCameraConfiguration config;\n> > diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\n> > index b9ac64328f1d..81c11149c9fe 100644\n> > --- a/src/libcamera/pipeline_handler.cpp\n> > +++ b/src/libcamera/pipeline_handler.cpp\n> > @@ -221,18 +221,18 @@ void PipelineHandler::unlock()\n> >   * \\fn PipelineHandler::generateConfiguration()\n> >   * \\brief Generate a camera configuration for a specified camera\n> >   * \\param[in] camera The camera to generate a default configuration for\n> > - * \\param[in] usages A list of stream usages\n> > + * \\param[in] roles A list of stream roles\n> >   *\n> > - * Generate a default configuration for the \\a camera for a specified group of\n> > - * use-cases. The caller shall populate the \\a usages array with the use-cases\n> > - * it wishes to fetch the default configuration for. The returned configuration\n> > + * Generate a default configuration for the \\a camera for a specified list of\n> > + * stream roles. The caller shall populate the \\a roles with the use-cases it\n> > + * wishes to fetch the default configuration for. The returned configuration\n> >   * can then be examined by the caller to learn about the selected streams and\n> >   * their default parameters.\n> >   *\n> >   * The intended companion to this is \\a configure() which can be used to change\n> >   * the group of streams parameters.\n> >   *\n> > - * \\return A valid CameraConfiguration if the requested usages can be satisfied,\n> > + * \\return A valid CameraConfiguration if the requested roles can be satisfied,\n> >   * or a invalid configuration otherwise\n> >   */\n> >\n> > diff --git a/src/libcamera/stream.cpp b/src/libcamera/stream.cpp\n> > index af259510b19c..fe4c4ecf4150 100644\n> > --- a/src/libcamera/stream.cpp\n> > +++ b/src/libcamera/stream.cpp\n> > @@ -75,61 +75,31 @@ std::string StreamConfiguration::toString() const\n> >  }\n> >\n> >  /**\n> > - * \\class StreamUsage\n> > - * \\brief Stream usage information\n> > - *\n> > - * The StreamUsage class describes how an application intends to use a stream.\n> > - * Usages are specified by applications and passed to cameras, that then select\n> > - * the most appropriate streams and their default configurations.\n> > - */\n> > -\n> > -/**\n> > - * \\enum StreamUsage::Role\n> > + * \\enum StreamRole\n> >   * \\brief Identify the role a stream is intended to play\n> > - * \\var StreamUsage::StillCapture\n> > + *\n> > + * The StreamRole describes how an application intends to use a stream. Roles\n> > + * are specified by applications and passed to cameras, that then select the\n> \n> s/select/selects ?\n\nThe subject is \"cameras\", which is a plural, hence \"select\".\n\n> Minors apart, and the resolution selected on IPU3 clarified:\n> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>\n> \n> > + * most appropriate streams and their default configurations.\n> > + *\n> > + * \\var StillCapture\n> >   * The stream is intended to capture high-resolution, high-quality still images\n> >   * with low frame rate. The captured frames may be exposed with flash.\n> > - * \\var StreamUsage::VideoRecording\n> > + * \\var VideoRecording\n> >   * The stream is intended to capture video for the purpose of recording or\n> >   * streaming. The video stream may produce a high frame rate and may be\n> >   * enhanced with video stabilization.\n> > - * \\var StreamUsage::Viewfinder\n> > + * \\var Viewfinder\n> >   * The stream is intended to capture video for the purpose of display on the\n> > - * local screen. The StreamUsage includes the desired resolution. Trade-offs\n> > - * between quality and usage of system resources are acceptable.\n> > + * local screen. Trade-offs between quality and usage of system resources are\n> > + * acceptable.\n> >   */\n> >\n> >  /**\n> > - * \\fn StreamUsage::role()\n> > - * \\brief Retrieve the stream role\n> > - * \\return The stream role\n> > + * \\typedef StreamRoles\n> > + * \\brief A vector of StreamRole\n> >   */\n> >\n> > -/**\n> > - * \\fn StreamUsage::size()\n> > - * \\brief Retrieve desired size\n> > - * \\return The desired size\n> > - */\n> > -\n> > -/**\n> > - * \\brief Create a stream usage\n> > - * \\param[in] role Stream role\n> > - */\n> > -StreamUsage::StreamUsage(Role role)\n> > -\t: role_(role)\n> > -{\n> > -}\n> > -\n> > -/**\n> > - * \\brief Create a stream usage with a desired size\n> > - * \\param[in] role Stream role\n> > - * \\param[in] size The desired size\n> > - */\n> > -StreamUsage::StreamUsage(Role role, const Size &size)\n> > -\t: role_(role), size_(size)\n> > -{\n> > -}\n> > -\n> >  /**\n> >   * \\class Stream\n> >   * \\brief Video stream for a camera\n> > @@ -148,39 +118,6 @@ StreamUsage::StreamUsage(Role role, const Size &size)\n> >   * optimal stream for the task.\n> >   */\n> >\n> > -/**\n> > - * \\class Stream::StillCapture\n> > - * \\brief Describe a still capture usage\n> > - */\n> > -Stream::StillCapture::StillCapture()\n> > -\t: StreamUsage(Role::StillCapture)\n> > -{\n> > -}\n> > -\n> > -/**\n> > - * \\class Stream::VideoRecording\n> > - * \\brief Describe a video recording usage\n> > - */\n> > -Stream::VideoRecording::VideoRecording()\n> > -\t: StreamUsage(Role::VideoRecording)\n> > -{\n> > -}\n> > -\n> > -/**\n> > - * \\class Stream::Viewfinder\n> > - * \\brief Describe a viewfinder usage\n> > - */\n> > -\n> > -/**\n> > - * \\brief Create a viewfinder usage with a desired dimension\n> > - * \\param[in] width The desired viewfinder width\n> > - * \\param[in] height The desired viewfinder height\n> > - */\n> > -Stream::Viewfinder::Viewfinder(int width, int height)\n> > -\t: StreamUsage(Role::Viewfinder, Size(width, height))\n> > -{\n> > -}\n> > -\n> >  /**\n> >   * \\brief Construct a stream with default parameters\n> >   */\n> > diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> > index c91b82727ec6..a984aaca764f 100644\n> > --- a/src/qcam/main_window.cpp\n> > +++ b/src/qcam/main_window.cpp\n> > @@ -97,7 +97,7 @@ int MainWindow::startCapture()\n> >  {\n> >  \tint ret;\n> >\n> > -\tconfig_ = camera_->generateConfiguration({ Stream::VideoRecording() });\n> > +\tconfig_ = camera_->generateConfiguration({ StreamRole::VideoRecording });\n> >  \tStream *stream = config_.front();\n> >  \tret = camera_->configure(config_);\n> >  \tif (ret < 0) {\n> > diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp\n> > index bc3a4d6cb9f2..e7e6438203b9 100644\n> > --- a/test/camera/capture.cpp\n> > +++ b/test/camera/capture.cpp\n> > @@ -43,7 +43,7 @@ protected:\n> >  \tint run()\n> >  \t{\n> >  \t\tCameraConfiguration config =\n> > -\t\t\tcamera_->generateConfiguration({ Stream::VideoRecording() });\n> > +\t\t\tcamera_->generateConfiguration({ StreamRole::VideoRecording });\n> >  \t\tStream *stream = config.front();\n> >  \t\tStreamConfiguration *cfg = &config[stream];\n> >\n> > diff --git a/test/camera/configuration_default.cpp b/test/camera/configuration_default.cpp\n> > index 340b5f58f04c..8c4a03db498a 100644\n> > --- a/test/camera/configuration_default.cpp\n> > +++ b/test/camera/configuration_default.cpp\n> > @@ -21,7 +21,7 @@ protected:\n> >  \t\tCameraConfiguration config;\n> >\n> >  \t\t/* Test asking for configuration for a video stream. */\n> > -\t\tconfig = camera_->generateConfiguration({ Stream::VideoRecording() });\n> > +\t\tconfig = camera_->generateConfiguration({ StreamRole::VideoRecording });\n> >  \t\tif (!config.isValid()) {\n> >  \t\t\tcout << \"Default configuration invalid\" << endl;\n> >  \t\t\treturn TestFail;\n> > @@ -29,11 +29,11 @@ protected:\n> >\n> >  \t\t/*\n> >  \t\t * Test that asking for configuration for an empty array of\n> > -\t\t * stream usages returns an empty list of configurations.\n> > +\t\t * stream roles returns an empty list of configurations.\n> >  \t\t */\n> >  \t\tconfig = camera_->generateConfiguration({});\n> >  \t\tif (config.isValid()) {\n> > -\t\t\tcout << \"Failed to retrieve configuration for empty usage list\"\n> > +\t\t\tcout << \"Failed to retrieve configuration for empty roles list\"\n> >  \t\t\t     << endl;\n> >  \t\t\treturn TestFail;\n> >  \t\t}\n> > diff --git a/test/camera/configuration_set.cpp b/test/camera/configuration_set.cpp\n> > index 24d5ca6690b7..76d8bc3e40a4 100644\n> > --- a/test/camera/configuration_set.cpp\n> > +++ b/test/camera/configuration_set.cpp\n> > @@ -19,7 +19,7 @@ protected:\n> >  \tint run()\n> >  \t{\n> >  \t\tCameraConfiguration config =\n> > -\t\t\tcamera_->generateConfiguration({ Stream::VideoRecording() });\n> > +\t\t\tcamera_->generateConfiguration({ StreamRole::VideoRecording });\n> >  \t\tStreamConfiguration *cfg = &config[config.front()];\n> >\n> >  \t\tif (!config.isValid()) {\n> > diff --git a/test/camera/statemachine.cpp b/test/camera/statemachine.cpp\n> > index bd2e61ff2939..7a74cd85a37a 100644\n> > --- a/test/camera/statemachine.cpp\n> > +++ b/test/camera/statemachine.cpp\n> > @@ -235,7 +235,7 @@ protected:\n> >\n> >  \tint run()\n> >  \t{\n> > -\t\tdefconf_ = camera_->generateConfiguration({ Stream::VideoRecording() });\n> > +\t\tdefconf_ = camera_->generateConfiguration({ StreamRole::VideoRecording });\n> >\n> >  \t\tif (testAvailable() != TestPass) {\n> >  \t\t\tcout << \"State machine in Available state failed\" << endl;","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 6A55560C27\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue, 21 May 2019 15:57:16 +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 A248252C;\n\tTue, 21 May 2019 15:57:15 +0200 (CEST)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1558447035;\n\tbh=tWJMjx/73YZvpi5Wy9hGJMhjL4POGhZf8M/3hNX14U8=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=YXmaSptFoJcnxrH/lalYEY9Je7f+KZimGNfwnt1gCRqbTUIiZtRveojx7diKsHcg8\n\tXyN/0CciUt1+FQT8IygNcLQJCEZ03/R7alSMVB0P1icVqm60JBllyVWKgPAyw9YnBo\n\t4ddOOB+qGuU54QJvsssQWeVoXEDyP6ANalyS83O0=","Date":"Tue, 21 May 2019 16:56:58 +0300","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Jacopo Mondi <jacopo@jmondi.org>","Cc":"libcamera-devel@lists.libcamera.org","Message-ID":"<20190521135658.GF5674@pendragon.ideasonboard.com>","References":"<20190519150047.12444-1-laurent.pinchart@ideasonboard.com>\n\t<20190519150047.12444-3-laurent.pinchart@ideasonboard.com>\n\t<20190521101206.yitlckkrnqe7cl4h@uno.localdomain>","MIME-Version":"1.0","Content-Type":"text/plain; charset=utf-8","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20190521101206.yitlckkrnqe7cl4h@uno.localdomain>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH v2 2/6] libcamera: Use stream roles\n\tdirectly instead of StreamUsage","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":"Tue, 21 May 2019 13:57:16 -0000"}}]