cam: drm: Support per-plane stride values
The stride is not always identical for all planes for multi-planar formats. Semi-planar YUV formats without horizontal subsampling often have a chroma stride equal to twice the luma stride, and tri-planar YUV formats with a 1/2 horizontal subsampling often have a chroma stride equal to half the luma stride. This isn't correctly taken into account when creating a DRM frame buffer, as the same stride is set for all planes. libcamera doesn't report per-plane stride values yet, but uses chroma strides that match the above description for all currently supported platforms. Calculation the chrome strides appropriately in the KMSSink class, and pass them to DRM::createFrameBuffer(). Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jean-Michel Hautbois <jeanmichel.hautbois@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
This commit is contained in:
parent
f8f6bc657d
commit
843048499f
3 changed files with 34 additions and 6 deletions
|
@ -7,10 +7,12 @@
|
|||
|
||||
#include "kms_sink.h"
|
||||
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libcamera/camera.h>
|
||||
|
@ -65,8 +67,32 @@ KMSSink::KMSSink(const std::string &connectorName)
|
|||
|
||||
void KMSSink::mapBuffer(libcamera::FrameBuffer *buffer)
|
||||
{
|
||||
std::array<uint32_t, 4> strides = {};
|
||||
|
||||
/* \todo Should libcamera report per-plane strides ? */
|
||||
unsigned int uvStrideMultiplier;
|
||||
|
||||
switch (format_) {
|
||||
case libcamera::formats::NV24:
|
||||
case libcamera::formats::NV42:
|
||||
uvStrideMultiplier = 4;
|
||||
break;
|
||||
case libcamera::formats::YUV420:
|
||||
case libcamera::formats::YVU420:
|
||||
case libcamera::formats::YUV422:
|
||||
uvStrideMultiplier = 1;
|
||||
break;
|
||||
default:
|
||||
uvStrideMultiplier = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
strides[0] = stride_;
|
||||
for (unsigned int i = 1; i < buffer->planes().size(); ++i)
|
||||
strides[i] = stride_ * uvStrideMultiplier / 2;
|
||||
|
||||
std::unique_ptr<DRM::FrameBuffer> drmBuffer =
|
||||
dev_.createFrameBuffer(*buffer, format_, size_, stride_);
|
||||
dev_.createFrameBuffer(*buffer, format_, size_, strides);
|
||||
if (!drmBuffer)
|
||||
return;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue