LCamDev: implement configureSessionModeCReq
We can, theoretically, now change the v4l camera's mode.
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
#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
|
||||
Reference in New Issue
Block a user