Files
salmanoff/commonLibs/lcameraDev/planarYuvFormatPolicy.cpp
T
hayodea 3e85b920fb LCamDev: implement configureSessionModeCReq
We can, theoretically, now change the v4l camera's mode.
2026-06-13 20:56:33 -04:00

147 lines
3.5 KiB
C++

#include <planarYuvFormatPolicy.h>
#include <libcamera/formats.h>
#include <sstream>
#include <stdexcept>
namespace lcamera_dev {
namespace {
using libcamera::formats::NV12;
using libcamera::formats::NV16;
using libcamera::formats::NV21;
using libcamera::formats::NV24;
using libcamera::formats::NV42;
using libcamera::formats::NV61;
using libcamera::formats::UYVY;
using libcamera::formats::VYUY;
using libcamera::formats::YUYV;
using libcamera::formats::YUV420;
using libcamera::formats::YUV422;
using libcamera::formats::YUV444;
using libcamera::formats::YVU420;
using libcamera::formats::YVU422;
using libcamera::formats::YVU444;
using libcamera::formats::YVYU;
bool pixelFormatMatches(
const libcamera::PixelFormat& pixelFormat,
const libcamera::PixelFormat& expectedFormat)
{
return pixelFormat == expectedFormat;
}
bool isFullyPlanarYuvFourcc(const libcamera::PixelFormat& pixelFormat)
{
return pixelFormatMatches(pixelFormat, YUV420)
|| pixelFormatMatches(pixelFormat, YVU420)
|| pixelFormatMatches(pixelFormat, YUV422)
|| pixelFormatMatches(pixelFormat, YVU422)
|| pixelFormatMatches(pixelFormat, YUV444)
|| pixelFormatMatches(pixelFormat, YVU444);
}
bool isSemiPlanarYuvFourcc(const libcamera::PixelFormat& pixelFormat)
{
return pixelFormatMatches(pixelFormat, NV12)
|| pixelFormatMatches(pixelFormat, NV21)
|| pixelFormatMatches(pixelFormat, NV16)
|| pixelFormatMatches(pixelFormat, NV61)
|| pixelFormatMatches(pixelFormat, NV24)
|| pixelFormatMatches(pixelFormat, NV42);
}
bool isPackedYuvFourcc(const libcamera::PixelFormat& pixelFormat)
{
return pixelFormatMatches(pixelFormat, YUYV)
|| pixelFormatMatches(pixelFormat, YVYU)
|| pixelFormatMatches(pixelFormat, UYVY)
|| pixelFormatMatches(pixelFormat, VYUY);
}
} // namespace
bool isFullyPlanarYuv(const libcamera::PixelFormat& pixelFormat)
{
return isFullyPlanarYuvFourcc(pixelFormat);
}
bool isKnownYuvCaptureFormat(const libcamera::PixelFormat& pixelFormat)
{
return isFullyPlanarYuvFourcc(pixelFormat)
|| isSemiPlanarYuvFourcc(pixelFormat)
|| isPackedYuvFourcc(pixelFormat);
}
unsigned yuvCapturePlaneCount(const libcamera::PixelFormat& pixelFormat)
{
if (isFullyPlanarYuvFourcc(pixelFormat)) {
return 3;
}
if (isSemiPlanarYuvFourcc(pixelFormat)) {
return 2;
}
if (isPackedYuvFourcc(pixelFormat)) {
return 1;
}
return 0;
}
std::string formatCandidateListForDiagnostics(
const std::vector<libcamera::PixelFormat>& candidates)
{
std::ostringstream stream;
for (std::size_t i = 0; i < candidates.size(); ++i)
{
if (i > 0) {
stream << ", ";
}
stream << candidates[i].toString();
}
return stream.str();
}
std::optional<libcamera::PixelFormat>
selectYuvCaptureFormat(
const std::vector<libcamera::PixelFormat>& candidates,
bool fullPlanarIsOptional)
{
if (candidates.empty())
{
throw std::runtime_error(
"lcameraDev: no YUV pixel-format candidates available");
}
if (!fullPlanarIsOptional)
{
for (const libcamera::PixelFormat& candidate : candidates)
{
if (isFullyPlanarYuv(candidate)) {
return candidate;
}
}
throw std::runtime_error(
"lcameraDev: no fully planar YUV format among candidates: "
+ formatCandidateListForDiagnostics(candidates));
}
for (const libcamera::PixelFormat& candidate : candidates)
{
if (isKnownYuvCaptureFormat(candidate)) {
return candidate;
}
}
throw std::runtime_error(
"lcameraDev: no known YUV capture format among candidates: "
+ formatCandidateListForDiagnostics(candidates));
}
} // namespace lcamera_dev