[libcamera-devel] [RFC PATCH 08/10] libcamera: v4l2_videodevice: Create color-format planes in CreateBuffer()

Hirokazu Honda hiroh at chromium.org
Mon Aug 16 06:31:36 CEST 2021


V4L2VideDevice::CreateBuffer() creates the same number of
FrameBuffer::Planes as V4L2 format planes. Therefore, if the v4l2
format single is single-planar format, the created number of
FrameBuffer::Planes is 1.
It should rather create the same number of FrameBuffer::Planes as the
color format planes.

Signed-off-by: Hirokazu Honda <hiroh at chromium.org>
---
 include/libcamera/internal/v4l2_videodevice.h |  4 ++-
 src/libcamera/v4l2_videodevice.cpp            | 28 +++++++++++++++++--
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/include/libcamera/internal/v4l2_videodevice.h b/include/libcamera/internal/v4l2_videodevice.h
index e767ec84..d0aeb614 100644
--- a/include/libcamera/internal/v4l2_videodevice.h
+++ b/include/libcamera/internal/v4l2_videodevice.h
@@ -136,11 +136,13 @@ private:
 	private:
 		struct Plane {
 			Plane(const FrameBuffer::Plane &plane)
-				: fd(plane.fd.fd()), length(plane.length)
+				: fd(plane.fd.fd()), offset(plane.offset),
+				  length(plane.length)
 			{
 			}
 
 			int fd;
+			unsigned int offset;
 			unsigned int length;
 		};
 
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index ce60dff6..549418c8 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -25,6 +25,7 @@
 
 #include <libcamera/file_descriptor.h>
 
+#include "libcamera/internal/formats.h"
 #include "libcamera/internal/media_device.h"
 #include "libcamera/internal/media_object.h"
 
@@ -273,6 +274,7 @@ bool V4L2BufferCache::Entry::operator==(const FrameBuffer &buffer) const
 
 	for (unsigned int i = 0; i < planes.size(); i++)
 		if (planes_[i].fd != planes[i].fd.fd() ||
+		    planes_[i].offset != planes_[i].offset ||
 		    planes_[i].length != planes[i].length)
 			return false;
 	return true;
@@ -1283,12 +1285,34 @@ std::unique_ptr<FrameBuffer> V4L2VideoDevice::createBuffer(unsigned int index)
 
 		FrameBuffer::Plane plane;
 		plane.fd = std::move(fd);
-		plane.length = multiPlanar ?
-			buf.m.planes[nplane].length : buf.length;
+		plane.offset = multiPlanar ? buf.m.planes[nplane].data_offset : 0;
+		plane.length = multiPlanar ? buf.m.planes[nplane].length : buf.length;
 
 		planes.push_back(std::move(plane));
 	}
 
+	V4L2DeviceFormat format{};
+	ret = getFormat(&format);
+	if (ret < 0) {
+		LOG(V4L2, Error)
+			<< "Failed to get format: " << strerror(-ret);
+		return nullptr;
+	}
+
+	const auto &info = PixelFormatInfo::info(format.fourcc);
+	if (info.isValid() && info.numPlanes() != numPlanes) {
+		ASSERT(numPlanes == 1u);
+		planes.resize(info.numPlanes());
+		const FileDescriptor &fd = planes[0].fd;
+		size_t offset = 0;
+		for (size_t i = 0; i < info.numPlanes(); ++i) {
+			planes[i].fd = fd;
+			planes[i].offset = offset;
+			planes[i].length = info.frameSize(format.size);
+			offset += planes[i].length;
+		}
+	}
+
 	return std::make_unique<FrameBuffer>(std::move(planes));
 }
 
-- 
2.33.0.rc1.237.g0d66db33f3-goog



More information about the libcamera-devel mailing list