[{"id":3373,"web_url":"https://patchwork.libcamera.org/comment/3373/","msgid":"<20200107221930.GQ4871@pendragon.ideasonboard.com>","date":"2020-01-07T22:19:30","subject":"Re: [libcamera-devel] [PATCH v2 10/25] libcamera: buffer: Move\n\tcaptured metadata to FrameMetadata","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 Mon, Dec 30, 2019 at 01:04:55PM +0100, Niklas Söderlund wrote:\n> Move the metadata retrieved when dequeuing a V4L2 buffer into a\n> FrameMetadata object. This is done as a step to migrate to the\n> FrameBuffer interface as the functions added to Buffer around\n> FrameMetadata match the ones in FrameBuffer.\n> \n> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>\n> ---\n> * Changes since v1\n> - Rework to match FrameMetadata being a struct instead of a class\n> - Align statements broken over multiple lines\n> - Spiffy up bytesused printing in cam\n> - Merged with patch who removes the old fields in Buffer.\n> ---\n>  include/libcamera/buffer.h               | 16 +----\n>  src/android/camera_device.cpp            |  4 +-\n>  src/cam/buffer_writer.cpp                |  2 +-\n>  src/cam/capture.cpp                      | 13 +++-\n>  src/libcamera/buffer.cpp                 | 75 ++++++------------------\n>  src/libcamera/pipeline/ipu3/ipu3.cpp     |  4 +-\n>  src/libcamera/pipeline/rkisp1/rkisp1.cpp |  8 +--\n>  src/libcamera/request.cpp                |  2 +-\n>  src/libcamera/v4l2_videodevice.cpp       | 24 ++++----\n>  src/qcam/main_window.cpp                 | 13 ++--\n>  test/camera/buffer_import.cpp            |  2 +-\n>  test/camera/capture.cpp                  |  2 +-\n>  test/v4l2_videodevice/buffer_sharing.cpp |  8 ++-\n>  13 files changed, 70 insertions(+), 103 deletions(-)\n> \n> diff --git a/include/libcamera/buffer.h b/include/libcamera/buffer.h\n> index 8dd9f91272291648..8bd61f786748af5f 100644\n> --- a/include/libcamera/buffer.h\n> +++ b/include/libcamera/buffer.h\n> @@ -93,12 +93,6 @@ private:\n>  class Buffer final\n>  {\n>  public:\n> -\tenum Status {\n> -\t\tBufferSuccess,\n> -\t\tBufferError,\n> -\t\tBufferCancelled,\n> -\t};\n> -\n>  \tBuffer(unsigned int index = -1, const Buffer *metadata = nullptr);\n>  \tBuffer(const Buffer &) = delete;\n>  \tBuffer &operator=(const Buffer &) = delete;\n> @@ -107,11 +101,8 @@ public:\n>  \tconst std::array<int, 3> &dmabufs() const { return dmabuf_; }\n>  \tBufferMemory *mem() { return mem_; }\n>  \n> -\tunsigned int bytesused() const { return bytesused_; }\n> -\tuint64_t timestamp() const { return timestamp_; }\n> -\tunsigned int sequence() const { return sequence_; }\n> +\tconst FrameMetadata &metadata() const { return metadata_; };\n>  \n> -\tStatus status() const { return status_; }\n>  \tRequest *request() const { return request_; }\n>  \tStream *stream() const { return stream_; }\n>  \n> @@ -127,11 +118,8 @@ private:\n>  \tstd::array<int, 3> dmabuf_;\n>  \tBufferMemory *mem_;\n>  \n> -\tunsigned int bytesused_;\n> -\tuint64_t timestamp_;\n> -\tunsigned int sequence_;\n> +\tFrameMetadata metadata_;\n>  \n> -\tStatus status_;\n>  \tRequest *request_;\n>  \tStream *stream_;\n>  };\n> diff --git a/src/android/camera_device.cpp b/src/android/camera_device.cpp\n> index 09588c16a6301649..ebe91ea8af4f6436 100644\n> --- a/src/android/camera_device.cpp\n> +++ b/src/android/camera_device.cpp\n> @@ -803,11 +803,11 @@ void CameraDevice::requestComplete(Request *request)\n>  \n>  \tif (status == CAMERA3_BUFFER_STATUS_OK) {\n>  \t\tnotifyShutter(descriptor->frameNumber,\n> -\t\t\t      libcameraBuffer->timestamp());\n> +\t\t\t      libcameraBuffer->metadata().timestamp);\n>  \n>  \t\tcaptureResult.partial_result = 1;\n>  \t\tresultMetadata = getResultMetadata(descriptor->frameNumber,\n> -\t\t\t\t\t\t   libcameraBuffer->timestamp());\n> +\t\t\t\t\t\t   libcameraBuffer->metadata().timestamp);\n>  \t\tcaptureResult.result = resultMetadata->get();\n>  \t}\n>  \n> diff --git a/src/cam/buffer_writer.cpp b/src/cam/buffer_writer.cpp\n> index 3e84068e66bb4dd7..7c58a1f50829f290 100644\n> --- a/src/cam/buffer_writer.cpp\n> +++ b/src/cam/buffer_writer.cpp\n> @@ -33,7 +33,7 @@ int BufferWriter::write(Buffer *buffer, const std::string &streamName)\n>  \tif (pos != std::string::npos) {\n>  \t\tstd::stringstream ss;\n>  \t\tss << streamName << \"-\" << std::setw(6)\n> -\t\t   << std::setfill('0') << buffer->sequence();\n> +\t\t   << std::setfill('0') << buffer->metadata().sequence;\n>  \t\tfilename.replace(pos, 1, ss.str());\n>  \t}\n>  \n> diff --git a/src/cam/capture.cpp b/src/cam/capture.cpp\n> index 1a4dbe7ce4a15a2d..da942f56118983bd 100644\n> --- a/src/cam/capture.cpp\n> +++ b/src/cam/capture.cpp\n> @@ -154,9 +154,18 @@ void Capture::requestComplete(Request *request)\n>  \t\tBuffer *buffer = it->second;\n>  \t\tconst std::string &name = streamName_[stream];\n>  \n> +\t\tconst FrameMetadata &metadata = buffer->metadata();\n> +\n>  \t\tinfo << \" \" << name\n> -\t\t     << \" seq: \" << std::setw(6) << std::setfill('0') << buffer->sequence()\n> -\t\t     << \" bytesused: \" << buffer->bytesused();\n> +\t\t     << \" seq: \" << std::setw(6) << std::setfill('0') << metadata.sequence\n> +\t\t     << \" bytesused: \";\n> +\n> +\t\tunsigned int nplane = 0;\n> +\t\tfor (const FrameMetadata::Plane &plane : metadata.planes) {\n> +\t\t\tinfo << plane.bytesused;\n> +\t\t\tif (++nplane < metadata.planes.size())\n> +\t\t\t\tinfo << \"/\";\n> +\t\t}\n>  \n>  \t\tif (writer_)\n>  \t\t\twriter_->write(buffer, name);\n> diff --git a/src/libcamera/buffer.cpp b/src/libcamera/buffer.cpp\n> index 4a77f20751408b7c..686d0412bf54b2c1 100644\n> --- a/src/libcamera/buffer.cpp\n> +++ b/src/libcamera/buffer.cpp\n> @@ -166,20 +166,6 @@ void BufferPool::destroyBuffers()\n>   * deleted automatically after the request complete handler returns.\n>   */\n>  \n> -/**\n> - * \\enum Buffer::Status\n> - * Buffer completion status\n> - * \\var Buffer::BufferSuccess\n> - * The buffer has completed with success and contains valid data. All its other\n> - * metadata (such as bytesused(), timestamp() or sequence() number) are valid.\n> - * \\var Buffer::BufferError\n> - * The buffer has completed with an error and doesn't contain valid data. Its\n> - * other metadata are valid.\n> - * \\var Buffer::BufferCancelled\n> - * The buffer has been cancelled due to capture stop. Its other metadata are\n> - * invalid and shall not be used.\n> - */\n> -\n>  /**\n>   * \\brief Construct a buffer not associated with any stream\n>   *\n> @@ -188,18 +174,19 @@ void BufferPool::destroyBuffers()\n>   * for a stream with Stream::createBuffer().\n>   */\n>  Buffer::Buffer(unsigned int index, const Buffer *metadata)\n> -\t: index_(index), dmabuf_({ -1, -1, -1 }),\n> -\t  status_(Buffer::BufferSuccess), request_(nullptr),\n> +\t: index_(index), dmabuf_({ -1, -1, -1 }), request_(nullptr),\n>  \t  stream_(nullptr)\n>  {\n> +\tmetadata_.status = FrameMetadata::FrameSuccess;\n> +\n>  \tif (metadata) {\n> -\t\tbytesused_ = metadata->bytesused_;\n> -\t\tsequence_ = metadata->sequence_;\n> -\t\ttimestamp_ = metadata->timestamp_;\n> +\t\tmetadata_.sequence = metadata->metadata().sequence;\n> +\t\tmetadata_.timestamp = metadata->metadata().timestamp;\n> +\t\tmetadata_.planes = metadata->metadata().planes;\n>  \t} else {\n> -\t\tbytesused_ = 0;\n> -\t\tsequence_ = 0;\n> -\t\ttimestamp_ = 0;\n> +\t\tmetadata_.sequence = 0;\n> +\t\tmetadata_.timestamp = 0;\n> +\t\tmetadata_.planes = { { 0 } };\n>  \t}\n\nI believe this code will go away, but otherwise it could have been\nwritten as\n\n\tif (metadata)\n\t\tmetadata_ = metadata->metadata();\n\telse\n\t\tmetadata_ = {};\n\n\tmetadata_.status = FrameMetadata::FrameSuccess;\n\n>  }\n>  \n> @@ -231,39 +218,13 @@ Buffer::Buffer(unsigned int index, const Buffer *metadata)\n>   */\n>  \n>  /**\n> - * \\fn Buffer::bytesused()\n> - * \\brief Retrieve the number of bytes occupied by the data in the buffer\n> - * \\return Number of bytes occupied in the buffer\n> - */\n> -\n> -/**\n> - * \\fn Buffer::timestamp()\n> - * \\brief Retrieve the time when the buffer was processed\n> - *\n> - * The timestamp is expressed as a number of nanoseconds since the epoch.\n> - *\n> - * \\return Timestamp when the buffer was processed\n> - */\n> -\n> -/**\n> - * \\fn Buffer::sequence()\n> - * \\brief Retrieve the buffer sequence number\n> - *\n> - * The sequence number is a monotonically increasing number assigned to the\n> - * buffer processed by the stream. Gaps in the sequence numbers indicate\n> - * dropped frames.\n> - *\n> - * \\return Sequence number of the buffer\n> - */\n> -\n> -/**\n> - * \\fn Buffer::status()\n> - * \\brief Retrieve the buffer status\n> + * \\fn Buffer::metadata()\n> + * \\brief Retrieve the buffer metadata\n>   *\n> - * The buffer status reports whether the buffer has completed successfully\n> - * (BufferSuccess) or if an error occurred (BufferError).\n> + * The buffer metadata is update every time the buffer contained are changed,\n\ns/update/updated/\n\n * The buffer metadata is updated when the buffer contents are modified, for\n * example when a frame has been captured to the buffer by the hardware.\n\n(not that it matters too much as this will go away)\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\n> + * for example when it is dequeued from hardware.\n>   *\n> - * \\return The buffer status\n> + * \\return Metadata for the buffer\n>   */\n>  \n>  /**\n> @@ -299,10 +260,10 @@ Buffer::Buffer(unsigned int index, const Buffer *metadata)\n>   */\n>  void Buffer::cancel()\n>  {\n> -\tbytesused_ = 0;\n> -\ttimestamp_ = 0;\n> -\tsequence_ = 0;\n> -\tstatus_ = BufferCancelled;\n> +\tmetadata_.status = FrameMetadata::FrameCancelled;\n> +\tmetadata_.sequence = 0;\n> +\tmetadata_.timestamp = 0;\n> +\tmetadata_.planes = {};\n>  }\n>  \n>  /**\n> diff --git a/src/libcamera/pipeline/ipu3/ipu3.cpp b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> index 6d8c3fada127310e..34fc792977d151be 100644\n> --- a/src/libcamera/pipeline/ipu3/ipu3.cpp\n> +++ b/src/libcamera/pipeline/ipu3/ipu3.cpp\n> @@ -928,7 +928,7 @@ int PipelineHandlerIPU3::registerCameras()\n>  void IPU3CameraData::imguInputBufferReady(Buffer *buffer)\n>  {\n>  \t/* \\todo Handle buffer failures when state is set to BufferError. */\n> -\tif (buffer->status() == Buffer::BufferCancelled)\n> +\tif (buffer->metadata().status == FrameMetadata::FrameCancelled)\n>  \t\treturn;\n>  \n>  \tcio2_.output_->queueBuffer(buffer);\n> @@ -962,7 +962,7 @@ void IPU3CameraData::imguOutputBufferReady(Buffer *buffer)\n>  void IPU3CameraData::cio2BufferReady(Buffer *buffer)\n>  {\n>  \t/* \\todo Handle buffer failures when state is set to BufferError. */\n> -\tif (buffer->status() == Buffer::BufferCancelled)\n> +\tif (buffer->metadata().status == FrameMetadata::FrameCancelled)\n>  \t\treturn;\n>  \n>  \timgu_->input_->queueBuffer(buffer);\n> diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> index bb652d0da9c6df52..46df871a51105ee4 100644\n> --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp\n> @@ -100,10 +100,10 @@ public:\n>  \t\tASSERT(frameOffset(SOE) == 0);\n>  \n>  \t\tutils::time_point soe = std::chrono::time_point<utils::clock>()\n> -\t\t\t+ std::chrono::nanoseconds(buffer->timestamp())\n> +\t\t\t+ std::chrono::nanoseconds(buffer->metadata().timestamp)\n>  \t\t\t+ timeOffset(SOE);\n>  \n> -\t\tnotifyStartOfExposure(buffer->sequence(), soe);\n> +\t\tnotifyStartOfExposure(buffer->metadata().sequence, soe);\n>  \t}\n>  \n>  \tvoid setDelay(unsigned int type, int frame, int msdelay)\n> @@ -1002,8 +1002,8 @@ void PipelineHandlerRkISP1::bufferReady(Buffer *buffer)\n>  \n>  \tdata->timeline_.bufferReady(buffer);\n>  \n> -\tif (data->frame_ <= buffer->sequence())\n> -\t\tdata->frame_ = buffer->sequence() + 1;\n> +\tif (data->frame_ <= buffer->metadata().sequence)\n> +\t\tdata->frame_ = buffer->metadata().sequence + 1;\n>  \n>  \tcompleteBuffer(activeCamera_, request, buffer);\n>  \ttryCompleteRequest(request);\n> diff --git a/src/libcamera/request.cpp b/src/libcamera/request.cpp\n> index 3b49e52510918eee..b17a6c2278361f00 100644\n> --- a/src/libcamera/request.cpp\n> +++ b/src/libcamera/request.cpp\n> @@ -260,7 +260,7 @@ bool Request::completeBuffer(Buffer *buffer)\n>  \n>  \tbuffer->request_ = nullptr;\n>  \n> -\tif (buffer->status() == Buffer::BufferCancelled)\n> +\tif (buffer->metadata().status == FrameMetadata::FrameCancelled)\n>  \t\tcancelled_ = true;\n>  \n>  \treturn !hasPendingBuffers();\n> diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp\n> index 7d585ce03ed9a45a..51112d197068cf0a 100644\n> --- a/src/libcamera/v4l2_videodevice.cpp\n> +++ b/src/libcamera/v4l2_videodevice.cpp\n> @@ -1015,10 +1015,12 @@ int V4L2VideoDevice::queueBuffer(Buffer *buffer)\n>  \t}\n>  \n>  \tif (V4L2_TYPE_IS_OUTPUT(buf.type)) {\n> -\t\tbuf.bytesused = buffer->bytesused_;\n> -\t\tbuf.sequence = buffer->sequence_;\n> -\t\tbuf.timestamp.tv_sec = buffer->timestamp_ / 1000000000;\n> -\t\tbuf.timestamp.tv_usec = (buffer->timestamp_ / 1000) % 1000000;\n> +\t\tconst FrameMetadata &metadata = buffer->metadata();\n> +\n> +\t\tbuf.bytesused = metadata.planes[0].bytesused;\n> +\t\tbuf.sequence = metadata.sequence;\n> +\t\tbuf.timestamp.tv_sec = metadata.timestamp / 1000000000;\n> +\t\tbuf.timestamp.tv_usec = (metadata.timestamp / 1000) % 1000000;\n>  \t}\n>  \n>  \tLOG(V4L2, Debug) << \"Queueing buffer \" << buf.index;\n> @@ -1125,12 +1127,14 @@ Buffer *V4L2VideoDevice::dequeueBuffer()\n>  \t\tfdEvent_->setEnabled(false);\n>  \n>  \tbuffer->index_ = buf.index;\n> -\tbuffer->bytesused_ = buf.bytesused;\n> -\tbuffer->timestamp_ = buf.timestamp.tv_sec * 1000000000ULL\n> -\t\t\t   + buf.timestamp.tv_usec * 1000ULL;\n> -\tbuffer->sequence_ = buf.sequence;\n> -\tbuffer->status_ = buf.flags & V4L2_BUF_FLAG_ERROR\n> -\t\t\t? Buffer::BufferError : Buffer::BufferSuccess;\n> +\n> +\tbuffer->metadata_.status = buf.flags & V4L2_BUF_FLAG_ERROR\n> +\t\t\t\t ? FrameMetadata::FrameError\n> +\t\t\t\t : FrameMetadata::FrameSuccess;\n> +\tbuffer->metadata_.sequence = buf.sequence;\n> +\tbuffer->metadata_.timestamp = buf.timestamp.tv_sec * 1000000000ULL\n> +\t\t\t\t    + buf.timestamp.tv_usec * 1000ULL;\n> +\tbuffer->metadata_.planes = { { buf.bytesused } };\n>  \n>  \treturn buffer;\n>  }\n> diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp\n> index 5dec9252898100db..47793702b9aa0ee9 100644\n> --- a/src/qcam/main_window.cpp\n> +++ b/src/qcam/main_window.cpp\n> @@ -259,14 +259,15 @@ void MainWindow::requestComplete(Request *request)\n>  \tframesCaptured_++;\n>  \n>  \tBuffer *buffer = buffers.begin()->second;\n> +\tconst FrameMetadata &metadata = buffer->metadata();\n>  \n> -\tdouble fps = buffer->timestamp() - lastBufferTime_;\n> +\tdouble fps = metadata.timestamp - lastBufferTime_;\n>  \tfps = lastBufferTime_ && fps ? 1000000000.0 / fps : 0.0;\n> -\tlastBufferTime_ = buffer->timestamp();\n> +\tlastBufferTime_ = metadata.timestamp;\n>  \n> -\tstd::cout << \"seq: \" << std::setw(6) << std::setfill('0') << buffer->sequence()\n> -\t\t  << \" bytesused: \" << buffer->bytesused()\n> -\t\t  << \" timestamp: \" << buffer->timestamp()\n> +\tstd::cout << \"seq: \" << std::setw(6) << std::setfill('0') << metadata.sequence\n> +\t\t  << \" bytesused: \" << metadata.planes[0].bytesused\n> +\t\t  << \" timestamp: \" << metadata.timestamp\n>  \t\t  << \" fps: \" << std::fixed << std::setprecision(2) << fps\n>  \t\t  << std::endl;\n>  \n> @@ -306,7 +307,7 @@ int MainWindow::display(Buffer *buffer)\n>  \t\t\t    plane.fd.fd(), 0);\n>  \n>  \tunsigned char *raw = static_cast<unsigned char *>(memory);\n> -\tviewfinder_->display(raw, buffer->bytesused());\n> +\tviewfinder_->display(raw, buffer->metadata().planes[0].bytesused);\n>  \n>  \tmunmap(memory, plane.length);\n>  \n> diff --git a/test/camera/buffer_import.cpp b/test/camera/buffer_import.cpp\n> index e5c010d81b8d6e0e..3ba6ce9690f29329 100644\n> --- a/test/camera/buffer_import.cpp\n> +++ b/test/camera/buffer_import.cpp\n> @@ -275,7 +275,7 @@ public:\n>  protected:\n>  \tvoid bufferComplete(Request *request, Buffer *buffer)\n>  \t{\n> -\t\tif (buffer->status() != Buffer::BufferSuccess)\n> +\t\tif (buffer->metadata().status != FrameMetadata::FrameSuccess)\n>  \t\t\treturn;\n>  \n>  \t\tunsigned int index = buffer->index();\n> diff --git a/test/camera/capture.cpp b/test/camera/capture.cpp\n> index ca1ebe419946dd4d..0d9ffc476650f414 100644\n> --- a/test/camera/capture.cpp\n> +++ b/test/camera/capture.cpp\n> @@ -28,7 +28,7 @@ protected:\n>  \n>  \tvoid bufferComplete(Request *request, Buffer *buffer)\n>  \t{\n> -\t\tif (buffer->status() != Buffer::BufferSuccess)\n> +\t\tif (buffer->metadata().status != FrameMetadata::FrameSuccess)\n>  \t\t\treturn;\n>  \n>  \t\tcompleteBuffersCount_++;\n> diff --git a/test/v4l2_videodevice/buffer_sharing.cpp b/test/v4l2_videodevice/buffer_sharing.cpp\n> index 3a56862cb2b77d38..fe48b2e98fdada8d 100644\n> --- a/test/v4l2_videodevice/buffer_sharing.cpp\n> +++ b/test/v4l2_videodevice/buffer_sharing.cpp\n> @@ -92,9 +92,11 @@ protected:\n>  \n>  \tvoid captureBufferReady(Buffer *buffer)\n>  \t{\n> +\t\tconst FrameMetadata &metadata = buffer->metadata();\n> +\n>  \t\tstd::cout << \"Received capture buffer\" << std::endl;\n>  \n> -\t\tif (buffer->status() != Buffer::BufferSuccess)\n> +\t\tif (metadata.status != FrameMetadata::FrameSuccess)\n>  \t\t\treturn;\n>  \n>  \t\toutput_->queueBuffer(buffer);\n> @@ -103,9 +105,11 @@ protected:\n>  \n>  \tvoid outputBufferReady(Buffer *buffer)\n>  \t{\n> +\t\tconst FrameMetadata &metadata = buffer->metadata();\n> +\n>  \t\tstd::cout << \"Received output buffer\" << std::endl;\n>  \n> -\t\tif (buffer->status() != Buffer::BufferSuccess)\n> +\t\tif (metadata.status != FrameMetadata::FrameSuccess)\n>  \t\t\treturn;\n>  \n>  \t\tcapture_->queueBuffer(buffer);","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 BA08C60464\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tTue,  7 Jan 2020 23:19:41 +0100 (CET)","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 3212752F;\n\tTue,  7 Jan 2020 23:19:41 +0100 (CET)"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1578435581;\n\tbh=GpiwIels5/obiRhuhgk2hfTXbjIZtEXnIIoW2/DPJRo=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=DNs5wsoVFG6x/nwDHG96p3NtdfmFqlZZtLhHYiMNVbfdjqfHgMGeSpgICicgKQREu\n\tqkJRedd+4VKdq9OUZLXlyRdbN1PJrpGyyIKhqoQqnBt0LjwNJK6d+yBmgaIuaAiRuI\n\tqe5VjDv6E4OiBaphpeiyLmylX8o4FNRAxgD5ZPjo=","Date":"Wed, 8 Jan 2020 00:19:30 +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":"<20200107221930.GQ4871@pendragon.ideasonboard.com>","References":"<20191230120510.938333-1-niklas.soderlund@ragnatech.se>\n\t<20191230120510.938333-11-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":"<20191230120510.938333-11-niklas.soderlund@ragnatech.se>","User-Agent":"Mutt/1.10.1 (2018-07-13)","Subject":"Re: [libcamera-devel] [PATCH v2 10/25] libcamera: buffer: Move\n\tcaptured metadata to FrameMetadata","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","X-List-Received-Date":"Tue, 07 Jan 2020 22:19:42 -0000"}}]