libcamera: FrameBuffer: Add a method to copy buffer content
This method may be used to memory copy a whole FrameBuffer content from another buffer. The operation is not fast and should not be used without great care by pipelines. The intended use-case is to have an option to copy out RAW buffers from the middle of a pipeline. Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
38f2efb05c
commit
417e3143a9
2 changed files with 69 additions and 0 deletions
|
@ -57,6 +57,7 @@ public:
|
||||||
unsigned int cookie() const { return cookie_; }
|
unsigned int cookie() const { return cookie_; }
|
||||||
void setCookie(unsigned int cookie) { cookie_ = cookie; }
|
void setCookie(unsigned int cookie) { cookie_ = cookie; }
|
||||||
|
|
||||||
|
int copyFrom(const FrameBuffer *src);
|
||||||
private:
|
private:
|
||||||
friend class Request; /* Needed to update request_. */
|
friend class Request; /* Needed to update request_. */
|
||||||
friend class V4L2VideoDevice; /* Needed to update metadata_. */
|
friend class V4L2VideoDevice; /* Needed to update metadata_. */
|
||||||
|
|
|
@ -211,4 +211,72 @@ FrameBuffer::FrameBuffer(const std::vector<Plane> &planes, unsigned int cookie)
|
||||||
* core never modifies the buffer cookie.
|
* core never modifies the buffer cookie.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Copy the contents from another buffer
|
||||||
|
* \param[in] src Buffer to copy
|
||||||
|
*
|
||||||
|
* Copy the buffer contents and metadata from \a src to this buffer. The
|
||||||
|
* destination FrameBuffer shall have the same number of planes as the source
|
||||||
|
* buffer, and each destination plane shall be larger than or equal to the
|
||||||
|
* corresponding source plane.
|
||||||
|
*
|
||||||
|
* The complete metadata of the source buffer is copied to the destination
|
||||||
|
* buffer. If an error occurs during the copy, the destination buffer's metadata
|
||||||
|
* status is set to FrameMetadata::FrameError, and other metadata fields are not
|
||||||
|
* modified.
|
||||||
|
*
|
||||||
|
* The operation is performed using memcpy() so is very slow, users needs to
|
||||||
|
* consider this before copying buffers.
|
||||||
|
*
|
||||||
|
* \return 0 on success or a negative error code otherwise
|
||||||
|
*/
|
||||||
|
int FrameBuffer::copyFrom(const FrameBuffer *src)
|
||||||
|
{
|
||||||
|
if (planes_.size() != src->planes_.size()) {
|
||||||
|
LOG(Buffer, Error) << "Different number of planes";
|
||||||
|
metadata_.status = FrameMetadata::FrameError;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < planes_.size(); i++) {
|
||||||
|
if (planes_[i].length < src->planes_[i].length) {
|
||||||
|
LOG(Buffer, Error) << "Plane " << i << " is too small";
|
||||||
|
metadata_.status = FrameMetadata::FrameError;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < planes_.size(); i++) {
|
||||||
|
void *dstmem = mmap(nullptr, planes_[i].length, PROT_WRITE,
|
||||||
|
MAP_SHARED, planes_[i].fd.fd(), 0);
|
||||||
|
|
||||||
|
if (dstmem == MAP_FAILED) {
|
||||||
|
LOG(Buffer, Error)
|
||||||
|
<< "Failed to map destination plane " << i;
|
||||||
|
metadata_.status = FrameMetadata::FrameError;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *srcmem = mmap(nullptr, src->planes_[i].length, PROT_READ,
|
||||||
|
MAP_SHARED, src->planes_[i].fd.fd(), 0);
|
||||||
|
|
||||||
|
if (srcmem == MAP_FAILED) {
|
||||||
|
munmap(dstmem, planes_[i].length);
|
||||||
|
LOG(Buffer, Error)
|
||||||
|
<< "Failed to map source plane " << i;
|
||||||
|
metadata_.status = FrameMetadata::FrameError;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(dstmem, srcmem, src->planes_[i].length);
|
||||||
|
|
||||||
|
munmap(srcmem, src->planes_[i].length);
|
||||||
|
munmap(dstmem, planes_[i].length);
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata_ = src->metadata_;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue