diff --git a/include/libcamera/internal/v4l2_pixelformat.h b/include/libcamera/internal/v4l2_pixelformat.h
index c836346bdc04..543eb21b3c07 100644
--- a/include/libcamera/internal/v4l2_pixelformat.h
+++ b/include/libcamera/internal/v4l2_pixelformat.h
@@ -49,6 +49,8 @@ public:
 	static const std::vector<V4L2PixelFormat> &
 	fromPixelFormat(const PixelFormat &pixelFormat);
 
+	bool isGenericLineBasedMetadata() const;
+
 private:
 	uint32_t fourcc_;
 };
diff --git a/src/libcamera/v4l2_pixelformat.cpp b/src/libcamera/v4l2_pixelformat.cpp
index eb9ac2224fd1..e8b3eb9c1394 100644
--- a/src/libcamera/v4l2_pixelformat.cpp
+++ b/src/libcamera/v4l2_pixelformat.cpp
@@ -372,6 +372,40 @@ V4L2PixelFormat::fromPixelFormat(const PixelFormat &pixelFormat)
 	return info.v4l2Formats;
 }
 
+/**
+ * \brief Test if a V4L2PixelFormat is one of the line based generic metadata
+ * formats
+ *
+ * A limited number of metadata formats, the ones that represents generic
+ * line-based metadata buffers, need to have their width, height and
+ * bytesperline set by userspace.
+ *
+ * This function tests if the current V4L2PixelFormat is one of those.
+ *
+ * Note: It would have been nicer to store this information in a
+ * V4L2PixelFormat::Info instance, but as metadata format are not exposed to
+ * applications, there are no PixelFormat and DRM fourcc codes associated to
+ * them.
+ *
+ * \return True if the V4L2PixelFormat() is a generic line based format, false
+ * otherwise
+ */
+bool V4L2PixelFormat::isGenericLineBasedMetadata() const
+{
+	switch (fourcc_) {
+	case V4L2_META_FMT_GENERIC_8:
+	case V4L2_META_FMT_GENERIC_CSI2_10:
+	case V4L2_META_FMT_GENERIC_CSI2_12:
+	case V4L2_META_FMT_GENERIC_CSI2_14:
+	case V4L2_META_FMT_GENERIC_CSI2_16:
+	case V4L2_META_FMT_GENERIC_CSI2_20:
+	case V4L2_META_FMT_GENERIC_CSI2_24:
+		return true;
+	default:
+		return false;
+	}
+}
+
 /**
  * \brief Insert a text representation of a V4L2PixelFormat into an output
  * stream
diff --git a/src/libcamera/v4l2_videodevice.cpp b/src/libcamera/v4l2_videodevice.cpp
index 14eba0561d6a..87cdbc3edf52 100644
--- a/src/libcamera/v4l2_videodevice.cpp
+++ b/src/libcamera/v4l2_videodevice.cpp
@@ -888,7 +888,7 @@ int V4L2VideoDevice::setFormat(V4L2DeviceFormat *format)
 int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format)
 {
 	struct v4l2_format v4l2Format = {};
-	struct v4l2_meta_format *pix = &v4l2Format.fmt.meta;
+	struct v4l2_meta_format *meta = &v4l2Format.fmt.meta;
 	int ret;
 
 	v4l2Format.type = bufferType_;
@@ -898,25 +898,42 @@ int V4L2VideoDevice::getFormatMeta(V4L2DeviceFormat *format)
 		return ret;
 	}
 
-	format->size.width = 0;
-	format->size.height = 0;
-	format->fourcc = V4L2PixelFormat(pix->dataformat);
+	format->fourcc = V4L2PixelFormat(meta->dataformat);
+	format->planes[0].size = meta->buffersize;
 	format->planesCount = 1;
-	format->planes[0].bpl = pix->buffersize;
-	format->planes[0].size = pix->buffersize;
+
+	bool genericLineBased = caps_.isMetaCapture() &&
+				format->fourcc.isGenericLineBasedMetadata();
+
+	if (genericLineBased) {
+		format->size.width = meta->width;
+		format->size.height = meta->height;
+		format->planes[0].bpl = meta->bytesperline;
+	} else {
+		format->size.width = 0;
+		format->size.height = 0;
+		format->planes[0].bpl = meta->buffersize;
+	}
 
 	return 0;
 }
 
 int V4L2VideoDevice::trySetFormatMeta(V4L2DeviceFormat *format, bool set)
 {
+	bool genericLineBased = caps_.isMetaCapture() &&
+				format->fourcc.isGenericLineBasedMetadata();
 	struct v4l2_format v4l2Format = {};
-	struct v4l2_meta_format *pix = &v4l2Format.fmt.meta;
+	struct v4l2_meta_format *meta = &v4l2Format.fmt.meta;
 	int ret;
 
 	v4l2Format.type = bufferType_;
-	pix->dataformat = format->fourcc;
-	pix->buffersize = format->planes[0].size;
+	meta->dataformat = format->fourcc;
+	meta->buffersize = format->planes[0].size;
+	if (genericLineBased) {
+		meta->width = format->size.width;
+		meta->height = format->size.height;
+		meta->bytesperline = format->planes[0].bpl;
+	}
 	ret = ioctl(set ? VIDIOC_S_FMT : VIDIOC_TRY_FMT, &v4l2Format);
 	if (ret) {
 		LOG(V4L2, Error)
@@ -929,12 +946,18 @@ int V4L2VideoDevice::trySetFormatMeta(V4L2DeviceFormat *format, bool set)
 	 * Return to caller the format actually applied on the video device,
 	 * which might differ from the requested one.
 	 */
-	format->size.width = 0;
-	format->size.height = 0;
-	format->fourcc = V4L2PixelFormat(pix->dataformat);
+	format->fourcc = V4L2PixelFormat(meta->dataformat);
 	format->planesCount = 1;
-	format->planes[0].bpl = pix->buffersize;
-	format->planes[0].size = pix->buffersize;
+	format->planes[0].size = meta->buffersize;
+	if (genericLineBased) {
+		format->size.width = meta->width;
+		format->size.height = meta->height;
+		format->planes[0].bpl = meta->bytesperline;
+	} else {
+		format->size.width = 0;
+		format->size.height = 0;
+		format->planes[0].bpl = meta->buffersize;
+	}
 
 	return 0;
 }
