[{"id":4032,"web_url":"https://patchwork.libcamera.org/comment/4032/","msgid":"<20200316154841.GH2260535@oden.dyn.berto.se>","date":"2020-03-16T15:48:41","subject":"Re: [libcamera-devel] [PATCH 8/9] libcamera: pipeline_handler: Fold\n\tbuffer management with start/stop","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 patch.\n\nOn 2020-03-15 01:57:27 +0200, Laurent Pinchart wrote:\n> There's no need anymore to have the Camera object control how and when\n> pipeline handlers allocate and free the buffers for the\n> application-facing video devices. Fold those operations, currently\n> performed by importFrameBuffers() and freeFrameBuffers(), into the\n> start() and stop() functions. This simplifies the pipeline handler API,\n> its implementation, and the implementation of the Camera class.\n> \n> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nReviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n\n> ---\n>  src/libcamera/camera.cpp                 |  11 --\n>  src/libcamera/include/pipeline_handler.h |   2 -\n>  src/libcamera/pipeline/ipu3/ipu3.cpp     | 146 +++++++++++------------\n>  src/libcamera/pipeline/rkisp1/rkisp1.cpp |  20 ++--\n>  src/libcamera/pipeline/uvcvideo.cpp      |  28 ++---\n>  src/libcamera/pipeline/vimc.cpp          |  28 ++---\n>  src/libcamera/pipeline_handler.cpp       |  41 +------\n>  7 files changed, 101 insertions(+), 175 deletions(-)\n> \n> diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp\n> index 3192dfb42d01..5593c1b317a0 100644\n> --- a/src/libcamera/camera.cpp\n> +++ b/src/libcamera/camera.cpp\n> @@ -915,13 +915,6 @@ int Camera::start()\n>  \n>  \tLOG(Camera, Debug) << \"Starting capture\";\n>  \n> -\tfor (Stream *stream : p_->activeStreams_) {\n> -\t\tret = p_->pipe_->invokeMethod(&PipelineHandler::importFrameBuffers,\n> -\t\t\t\t\t      ConnectionTypeDirect, this, stream);\n> -\t\tif (ret < 0)\n> -\t\t\treturn ret;\n> -\t}\n> -\n>  \tret = p_->pipe_->invokeMethod(&PipelineHandler::start,\n>  \t\t\t\t      ConnectionTypeBlocking, this);\n>  \tif (ret)\n> @@ -959,10 +952,6 @@ int Camera::stop()\n>  \tp_->pipe_->invokeMethod(&PipelineHandler::stop, ConnectionTypeBlocking,\n>  \t\t\t\tthis);\n>  \n> -\tfor (Stream *stream : p_->activeStreams_)\n> -\t\tp_->pipe_->invokeMethod(&PipelineHandler::freeFrameBuffers,\n> -\t\t\t\t\tConnectionTypeBlocking, this, stream);\n> -\n>  \treturn 0;\n>  }\n>  \n> diff --git a/src/libcamera/include/pipeline_handler.h b/src/libcamera/include/pipeline_handler.h\n> index db6c3104d812..3fcfeda4bfee 100644\n> --- a/src/libcamera/include/pipeline_handler.h\n> +++ b/src/libcamera/include/pipeline_handler.h\n> @@ -76,8 +76,6 @@ public:\n>  \n>  \tvirtual int exportFrameBuffers(Camera *camera, Stream *stream,\n>  \t\t\t\t       std::vector<std::unique_ptr<FrameBuffer>> *buffers) = 0;\n> -\tvirtual int importFrameBuffers(Camera *camera, Stream *stream) = 0;\n> -\tvirtual void freeFrameBuffers(Camera *camera, Stream *stream) = 0;\n>  \n>  \tvirtual int start(Camera *camera) = 0;\n>  \tvirtual void stop(Camera *camera) = 0;\n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index b6db8d567ea4..6b93c50978a7 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -72,6 +72,7 @@ public:\n>  \tint configureOutput(ImgUOutput *output,\n>  \t\t\t    const StreamConfiguration &cfg);\n>  \n> +\tint allocateBuffers(IPU3CameraData *data, unsigned int bufferCount);\n>  \tvoid freeBuffers(IPU3CameraData *data);\n>  \n>  \tint start();\n> @@ -208,8 +209,6 @@ public:\n>  \n>  \tint exportFrameBuffers(Camera *camera, Stream *stream,\n>  \t\t\t       std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n> -\tint importFrameBuffers(Camera *camera, Stream *stream) override;\n> -\tvoid freeFrameBuffers(Camera *camera, Stream *stream) override;\n>  \n>  \tint start(Camera *camera) override;\n>  \tvoid stop(Camera *camera) override;\n> @@ -625,23 +624,6 @@ int PipelineHandlerIPU3::exportFrameBuffers(Camera *camera, Stream *stream,\n>  \treturn video->exportBuffers(count, buffers);\n>  }\n>  \n> -int PipelineHandlerIPU3::importFrameBuffers(Camera *camera, Stream *stream)\n> -{\n> -\tIPU3Stream *ipu3stream = static_cast<IPU3Stream *>(stream);\n> -\tV4L2VideoDevice *video = ipu3stream->device_->dev;\n> -\tunsigned int count = stream->configuration().bufferCount;\n> -\n> -\treturn video->importBuffers(count);\n> -}\n> -\n> -void PipelineHandlerIPU3::freeFrameBuffers(Camera *camera, Stream *stream)\n> -{\n> -\tIPU3Stream *ipu3stream = static_cast<IPU3Stream *>(stream);\n> -\tV4L2VideoDevice *video = ipu3stream->device_->dev;\n> -\n> -\tvideo->releaseBuffers();\n> -}\n> -\n>  /**\n>   * \\todo Clarify if 'viewfinder' and 'stat' nodes have to be set up and\n>   * started even if not in use. As of now, if not properly configured and\n> @@ -653,69 +635,24 @@ void PipelineHandlerIPU3::freeFrameBuffers(Camera *camera, Stream *stream)\n>  int PipelineHandlerIPU3::allocateBuffers(Camera *camera)\n>  {\n>  \tIPU3CameraData *data = cameraData(camera);\n> -\tIPU3Stream *outStream = &data->outStream_;\n> -\tIPU3Stream *vfStream = &data->vfStream_;\n>  \tCIO2Device *cio2 = &data->cio2_;\n>  \tImgUDevice *imgu = data->imgu_;\n>  \tunsigned int bufferCount;\n>  \tint ret;\n>  \n> -\t/* Share buffers between CIO2 output and ImgU input. */\n>  \tret = cio2->allocateBuffers();\n>  \tif (ret < 0)\n>  \t\treturn ret;\n>  \n>  \tbufferCount = ret;\n>  \n> -\tret = imgu->input_->importBuffers(bufferCount);\n> -\tif (ret) {\n> -\t\tLOG(IPU3, Error) << \"Failed to import ImgU input buffers\";\n> -\t\tgoto error;\n> -\t}\n> -\n> -\t/*\n> -\t * Use for the stat's internal pool the same number of buffers as for\n> -\t * the input pool.\n> -\t * \\todo To be revised when we'll actually use the stat node.\n> -\t */\n> -\tret = imgu->stat_.dev->allocateBuffers(bufferCount, &imgu->stat_.buffers);\n> +\tret = imgu->allocateBuffers(data, bufferCount);\n>  \tif (ret < 0) {\n> -\t\tLOG(IPU3, Error) << \"Failed to allocate ImgU stat buffers\";\n> -\t\tgoto error;\n> -\t}\n> -\n> -\t/*\n> -\t * Allocate buffers also on non-active outputs; use the same number\n> -\t * of buffers as the active ones.\n> -\t */\n> -\tif (!outStream->active_) {\n> -\t\tImgUDevice::ImgUOutput *output = outStream->device_;\n> -\n> -\t\tret = output->dev->allocateBuffers(bufferCount, &output->buffers);\n> -\t\tif (ret < 0) {\n> -\t\t\tLOG(IPU3, Error) << \"Failed to allocate ImgU \"\n> -\t\t\t\t\t << output->name << \" buffers\";\n> -\t\t\tgoto error;\n> -\t\t}\n> -\t}\n> -\n> -\tif (!vfStream->active_) {\n> -\t\tImgUDevice::ImgUOutput *output = vfStream->device_;\n> -\n> -\t\tret = output->dev->allocateBuffers(bufferCount, &output->buffers);\n> -\t\tif (ret < 0) {\n> -\t\t\tLOG(IPU3, Error) << \"Failed to allocate ImgU \"\n> -\t\t\t\t\t << output->name << \" buffers\";\n> -\t\t\tgoto error;\n> -\t\t}\n> +\t\tcio2->freeBuffers();\n> +\t\treturn ret;\n>  \t}\n>  \n>  \treturn 0;\n> -\n> -error:\n> -\tfreeBuffers(camera);\n> -\n> -\treturn ret;\n>  }\n>  \n>  int PipelineHandlerIPU3::freeBuffers(Camera *camera)\n> @@ -1156,6 +1093,65 @@ int ImgUDevice::configureOutput(ImgUOutput *output,\n>  \treturn 0;\n>  }\n>  \n> +/**\n> + * \\brief Allocate buffers for all the ImgU video devices\n> + */\n> +int ImgUDevice::allocateBuffers(IPU3CameraData *data, unsigned int bufferCount)\n> +{\n> +\tIPU3Stream *outStream = &data->outStream_;\n> +\tIPU3Stream *vfStream = &data->vfStream_;\n> +\n> +\t/* Share buffers between CIO2 output and ImgU input. */\n> +\tint ret = input_->importBuffers(bufferCount);\n> +\tif (ret) {\n> +\t\tLOG(IPU3, Error) << \"Failed to import ImgU input buffers\";\n> +\t\treturn ret;\n> +\t}\n> +\n> +\t/*\n> +\t * Use for the stat's internal pool the same number of buffers as for\n> +\t * the input pool.\n> +\t * \\todo To be revised when we'll actually use the stat node.\n> +\t */\n> +\tret = stat_.dev->allocateBuffers(bufferCount, &stat_.buffers);\n> +\tif (ret < 0) {\n> +\t\tLOG(IPU3, Error) << \"Failed to allocate ImgU stat buffers\";\n> +\t\tgoto error;\n> +\t}\n> +\n> +\t/*\n> +\t * Allocate buffers for both outputs. If an output is active, prepare\n> +\t * for buffer import, otherwise allocate internal buffers. Use the same\n> +\t * number of buffers in either case.\n> +\t */\n> +\tif (outStream->active_)\n> +\t\tret = output_.dev->importBuffers(bufferCount);\n> +\telse\n> +\t\tret = output_.dev->allocateBuffers(bufferCount,\n> +\t\t\t\t\t\t   &output_.buffers);\n> +\tif (ret < 0) {\n> +\t\tLOG(IPU3, Error) << \"Failed to allocate ImgU output buffers\";\n> +\t\tgoto error;\n> +\t}\n> +\n> +\tif (vfStream->active_)\n> +\t\tret = viewfinder_.dev->importBuffers(bufferCount);\n> +\telse\n> +\t\tret = viewfinder_.dev->allocateBuffers(bufferCount,\n> +\t\t\t\t\t\t       &viewfinder_.buffers);\n> +\tif (ret < 0) {\n> +\t\tLOG(IPU3, Error) << \"Failed to allocate ImgU viewfinder buffers\";\n> +\t\tgoto error;\n> +\t}\n> +\n> +\treturn 0;\n> +\n> +error:\n> +\tfreeBuffers(data);\n> +\n> +\treturn ret;\n> +}\n> +\n>  /**\n>   * \\brief Release buffers for all the ImgU video devices\n>   */\n> @@ -1163,21 +1159,17 @@ void ImgUDevice::freeBuffers(IPU3CameraData *data)\n>  {\n>  \tint ret;\n>  \n> -\tif (!data->outStream_.active_) {\n> -\t\tret = output_.dev->releaseBuffers();\n> -\t\tif (ret)\n> -\t\t\tLOG(IPU3, Error) << \"Failed to release ImgU output buffers\";\n> -\t}\n> +\tret = output_.dev->releaseBuffers();\n> +\tif (ret)\n> +\t\tLOG(IPU3, Error) << \"Failed to release ImgU output buffers\";\n>  \n>  \tret = stat_.dev->releaseBuffers();\n>  \tif (ret)\n>  \t\tLOG(IPU3, Error) << \"Failed to release ImgU stat buffers\";\n>  \n> -\tif (!data->vfStream_.active_) {\n> -\t\tret = viewfinder_.dev->releaseBuffers();\n> -\t\tif (ret)\n> -\t\t\tLOG(IPU3, Error) << \"Failed to release ImgU viewfinder buffers\";\n> -\t}\n> +\tret = viewfinder_.dev->releaseBuffers();\n> +\tif (ret)\n> +\t\tLOG(IPU3, Error) << \"Failed to release ImgU viewfinder buffers\";\n>  \n>  \tret = input_->releaseBuffers();\n>  \tif (ret)\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index 1ad53fbde112..01977ad697a9 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -175,8 +175,6 @@ public:\n>  \n>  \tint exportFrameBuffers(Camera *camera, Stream *stream,\n>  \t\t\t       std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n> -\tint importFrameBuffers(Camera *camera, Stream *stream) override;\n> -\tvoid freeFrameBuffers(Camera *camera, Stream *stream) override;\n>  \n>  \tint start(Camera *camera) override;\n>  \tvoid stop(Camera *camera) override;\n> @@ -668,17 +666,6 @@ int PipelineHandlerRkISP1::exportFrameBuffers(Camera *camera, Stream *stream,\n>  \treturn video_->exportBuffers(count, buffers);\n>  }\n>  \n> -int PipelineHandlerRkISP1::importFrameBuffers(Camera *camera, Stream *stream)\n> -{\n> -\tunsigned int count = stream->configuration().bufferCount;\n> -\treturn video_->importBuffers(count);\n> -}\n> -\n> -void PipelineHandlerRkISP1::freeFrameBuffers(Camera *camera, Stream *stream)\n> -{\n> -\tvideo_->releaseBuffers();\n> -}\n> -\n>  int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)\n>  {\n>  \tRkISP1CameraData *data = cameraData(camera);\n> @@ -689,6 +676,10 @@ int PipelineHandlerRkISP1::allocateBuffers(Camera *camera)\n>  \tfor (const Stream *s : camera->streams())\n>  \t\tmaxBuffers = std::max(maxBuffers, s->configuration().bufferCount);\n>  \n> +\tret = video_->importBuffers(count);\n> +\tif (ret < 0)\n> +\t\tgoto error;\n> +\n>  \tret = param_->allocateBuffers(maxBuffers, &paramBuffers_);\n>  \tif (ret < 0)\n>  \t\tgoto error;\n> @@ -749,6 +740,9 @@ int PipelineHandlerRkISP1::freeBuffers(Camera *camera)\n>  \tif (stat_->releaseBuffers())\n>  \t\tLOG(RkISP1, Error) << \"Failed to release stat buffers\";\n>  \n> +\tif (video_->releaseBuffers())\n> +\t\tLOG(RkISP1, Error) << \"Failed to release video buffers\";\n> +\n>  \treturn 0;\n>  }\n>  \n> diff --git a/src/libcamera/pipeline/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo.cpp\n> index 29afb121aa46..40cc3ee7d098 100644\n> --- a/src/libcamera/pipeline/uvcvideo.cpp\n> +++ b/src/libcamera/pipeline/uvcvideo.cpp\n> @@ -67,8 +67,6 @@ public:\n>  \n>  \tint exportFrameBuffers(Camera *camera, Stream *stream,\n>  \t\t\t       std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n> -\tint importFrameBuffers(Camera *camera, Stream *stream) override;\n> -\tvoid freeFrameBuffers(Camera *camera, Stream *stream) override;\n>  \n>  \tint start(Camera *camera) override;\n>  \tvoid stop(Camera *camera) override;\n> @@ -202,31 +200,29 @@ int PipelineHandlerUVC::exportFrameBuffers(Camera *camera, Stream *stream,\n>  \treturn data->video_->exportBuffers(count, buffers);\n>  }\n>  \n> -int PipelineHandlerUVC::importFrameBuffers(Camera *camera, Stream *stream)\n> +int PipelineHandlerUVC::start(Camera *camera)\n>  {\n>  \tUVCCameraData *data = cameraData(camera);\n> -\tunsigned int count = stream->configuration().bufferCount;\n> +\tunsigned int count = data->stream_.configuration().bufferCount;\n>  \n> -\treturn data->video_->importBuffers(count);\n> -}\n> -\n> -void PipelineHandlerUVC::freeFrameBuffers(Camera *camera, Stream *stream)\n> -{\n> -\tUVCCameraData *data = cameraData(camera);\n> +\tint ret = data->video_->importBuffers(count);\n> +\tif (ret < 0)\n> +\t\treturn ret;\n>  \n> -\tdata->video_->releaseBuffers();\n> -}\n> +\tret = data->video_->streamOn();\n> +\tif (ret < 0) {\n> +\t\tdata->video_->releaseBuffers();\n> +\t\treturn ret;\n> +\t}\n>  \n> -int PipelineHandlerUVC::start(Camera *camera)\n> -{\n> -\tUVCCameraData *data = cameraData(camera);\n> -\treturn data->video_->streamOn();\n> +\treturn 0;\n>  }\n>  \n>  void PipelineHandlerUVC::stop(Camera *camera)\n>  {\n>  \tUVCCameraData *data = cameraData(camera);\n>  \tdata->video_->streamOff();\n> +\tdata->video_->releaseBuffers();\n>  }\n>  \n>  int PipelineHandlerUVC::processControls(UVCCameraData *data, Request *request)\n> diff --git a/src/libcamera/pipeline/vimc.cpp b/src/libcamera/pipeline/vimc.cpp\n> index 5d3d12fef30b..eceb16d5586a 100644\n> --- a/src/libcamera/pipeline/vimc.cpp\n> +++ b/src/libcamera/pipeline/vimc.cpp\n> @@ -84,8 +84,6 @@ public:\n>  \n>  \tint exportFrameBuffers(Camera *camera, Stream *stream,\n>  \t\t\t       std::vector<std::unique_ptr<FrameBuffer>> *buffers) override;\n> -\tint importFrameBuffers(Camera *camera, Stream *stream) override;\n> -\tvoid freeFrameBuffers(Camera *camera, Stream *stream) override;\n>  \n>  \tint start(Camera *camera) override;\n>  \tvoid stop(Camera *camera) override;\n> @@ -268,31 +266,29 @@ int PipelineHandlerVimc::exportFrameBuffers(Camera *camera, Stream *stream,\n>  \treturn data->video_->exportBuffers(count, buffers);\n>  }\n>  \n> -int PipelineHandlerVimc::importFrameBuffers(Camera *camera, Stream *stream)\n> +int PipelineHandlerVimc::start(Camera *camera)\n>  {\n>  \tVimcCameraData *data = cameraData(camera);\n> -\tunsigned int count = stream->configuration().bufferCount;\n> +\tunsigned int count = data->stream_.configuration().bufferCount;\n>  \n> -\treturn data->video_->importBuffers(count);\n> -}\n> -\n> -void PipelineHandlerVimc::freeFrameBuffers(Camera *camera, Stream *stream)\n> -{\n> -\tVimcCameraData *data = cameraData(camera);\n> +\tint ret = data->video_->importBuffers(count);\n> +\tif (ret < 0)\n> +\t\treturn ret;\n>  \n> -\tdata->video_->releaseBuffers();\n> -}\n> +\tret = data->video_->streamOn();\n> +\tif (ret < 0) {\n> +\t\tdata->video_->releaseBuffers();\n> +\t\treturn ret;\n> +\t}\n>  \n> -int PipelineHandlerVimc::start(Camera *camera)\n> -{\n> -\tVimcCameraData *data = cameraData(camera);\n> -\treturn data->video_->streamOn();\n> +\treturn 0;\n>  }\n>  \n>  void PipelineHandlerVimc::stop(Camera *camera)\n>  {\n>  \tVimcCameraData *data = cameraData(camera);\n>  \tdata->video_->streamOff();\n> +\tdata->video_->releaseBuffers();\n>  }\n>  \n>  int PipelineHandlerVimc::processControls(VimcCameraData *data, Request *request)\n> diff --git a/src/libcamera/pipeline_handler.cpp b/src/libcamera/pipeline_handler.cpp\n> index e5034c54e2fb..254d341fb8a4 100644\n> --- a/src/libcamera/pipeline_handler.cpp\n> +++ b/src/libcamera/pipeline_handler.cpp\n> @@ -325,7 +325,7 @@ const ControlList &PipelineHandler::properties(Camera *camera)\n>  \n>  /**\n>   * \\fn PipelineHandler::exportFrameBuffers()\n> - * \\brief Allocate buffers for \\a stream\n> + * \\brief Allocate and export buffers for \\a stream\n>   * \\param[in] camera The camera\n>   * \\param[in] stream The stream to allocate buffers for\n>   * \\param[out] buffers Array of buffers successfully allocated\n> @@ -347,45 +347,6 @@ const ControlList &PipelineHandler::properties(Camera *camera)\n>   * otherwise\n>   */\n>  \n> -/**\n> - * \\fn PipelineHandler::importFrameBuffers()\n> - * \\brief Prepare \\a stream to use external buffers\n> - * \\param[in] camera The camera\n> - * \\param[in] stream The stream to prepare for import\n> - *\n> - * This method prepares the pipeline handler to use buffers provided by the\n> - * application for the \\a stream.\n> - *\n> - * The method may only be called after the Camera has been configured and before\n> - * it gets started, or after it gets stopped. It shall be called only for\n> - * streams that are part of the active camera configuration, and at most once\n> - * per stream until buffers for the stream are freed with freeFrameBuffers().\n> - *\n> - * importFrameBuffers() shall also allocate all other resources required by the\n> - * pipeline handler for the stream to prepare for starting the Camera.\n> - *\n> - * The only intended caller is Camera::start().\n> - *\n> - * \\context This function is called from the CameraManager thread.\n> - *\n> - * \\return 0 on success or a negative error code otherwise\n> - */\n> -\n> -/**\n> - * \\fn PipelineHandler::freeFrameBuffers()\n> - * \\brief Free buffers allocated from the stream\n> - * \\param[in] camera The camera\n> - * \\param[in] stream The stream to free buffers for\n> - *\n> - * This method shall release all resources allocated for the \\a stream by\n> - * importFrameBuffers(). It shall be called only after a successful call that\n> - * method, and only once per stream.\n> - *\n> - * The only intended callers are Camera::stop() and Camera::freeFrameBuffers().\n> - *\n> - * \\context This function is called from the CameraManager thread.\n> - */\n> -\n>  /**\n>   * \\fn PipelineHandler::start()\n>   * \\brief Start capturing from a group of streams\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":"<niklas.soderlund@ragnatech.se>","Received":["from mail-lf1-x134.google.com (mail-lf1-x134.google.com\n\t[IPv6:2a00:1450:4864:20::134])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 1102E6041A\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Mar 2020 16:48:44 +0100 (CET)","by mail-lf1-x134.google.com with SMTP id a28so2649498lfr.13\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tMon, 16 Mar 2020 08:48:44 -0700 (PDT)","from localhost (h-200-138.A463.priv.bahnhof.se. [176.10.200.138])\n\tby smtp.gmail.com with ESMTPSA id\n\ta9sm125699ljm.90.2020.03.16.08.48.42\n\t(version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n\tMon, 16 Mar 2020 08:48:42 -0700 (PDT)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=ragnatech-se.20150623.gappssmtp.com; s=20150623;\n\th=date:from:to:cc:subject:message-id:references:mime-version\n\t:content-disposition:content-transfer-encoding:in-reply-to;\n\tbh=JSFP3TmolY9LWIxDOhMCazCnjs2V7NA1TPMxBuXjr9w=;\n\tb=UtXRZ4orQLC41qRBeA2mjdp5krxj73/AkIy4SHEYb3bDwljeFcGuSebvWO03Vu8dU3\n\t3E6jav2rx5BeZiWkucxJOasNkvE9WZGVmd8U5Y23sm0wNyntdv+VoG8QfSnNNucs809Z\n\tBWjMLANA3f0HNopU2LyfyFDPFOjR5plGoavZYafDL8xpkOiaxwkbboIEzLYRNKsg4wkN\n\ty06INJkUlLiTzq9Ok7JuqoPBb53rwxUe/ZgXrKKFlho72FYzV8s6u/3ZUQn4TlKUlY0u\n\t/0WUkTwWjrHNF+2Lh+gI8K7knpPE10uN8RDHcyc0kiTJEBI9+/o7CVT7Wb5zNbz9hGxl\n\t/Axw==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:date:from:to:cc:subject:message-id:references\n\t:mime-version:content-disposition:content-transfer-encoding\n\t:in-reply-to;\n\tbh=JSFP3TmolY9LWIxDOhMCazCnjs2V7NA1TPMxBuXjr9w=;\n\tb=te/Ep+gkcxypYbFnHbZ5TW2Fy19Yfh/ope/UPYjtwsi+24/qFXH/ChcMlmuMmEPubN\n\tnEPIVqriyB97cMd35d32nZ2m+2TbcFj2Y0i/3EgUOPN2VVDar271EjHJ+XS26fRrh/7A\n\t8ilyDY3jRzdPTd5omF7BL0opQEHiToMchstB/dbqWPuQ6+KZ4UcJTxbWvWj0Hok66dAP\n\t1mfPJ9m2QDobiHHkErn6/NWxItJZosz8Yh2tZULyN9DBHSuvTswLyNdGgKMf6KCFVqGG\n\tz51XLbXXch37v7VZtY4RL/GDUPhTJGPXUutTLeqpMbBjB4zB59TUdfZ5z4V+BdKsj+X8\n\twGuQ==","X-Gm-Message-State":"ANhLgQ02G/gfYiUvV4OhUqziQWfOpMnhzG6091O7wuJTGHMTvDBbiLnK\n\tEq/zzdAxSiHaw/r6XvvcBVG5Rg==","X-Google-Smtp-Source":"ADFU+vuQODKOQci3a76TvvRF7ei0N3DBgZATsSL/ClGeKLIXGDyBItB4eVl9y5ZUuYW+MYNaiDPWOA==","X-Received":"by 2002:ac2:4145:: with SMTP id c5mr18881lfi.71.1584373723187;\n\tMon, 16 Mar 2020 08:48:43 -0700 (PDT)","Date":"Mon, 16 Mar 2020 16:48:41 +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":"<20200316154841.GH2260535@oden.dyn.berto.se>","References":"<20200314235728.15495-1-laurent.pinchart@ideasonboard.com>\n\t<20200314235728.15495-9-laurent.pinchart@ideasonboard.com>","MIME-Version":"1.0","Content-Type":"text/plain; charset=iso-8859-1","Content-Disposition":"inline","Content-Transfer-Encoding":"8bit","In-Reply-To":"<20200314235728.15495-9-laurent.pinchart@ideasonboard.com>","Subject":"Re: [libcamera-devel] [PATCH 8/9] libcamera: pipeline_handler: Fold\n\tbuffer management with start/stop","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Mon, 16 Mar 2020 15:48:44 -0000"}}]