#include #include #include #include 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& 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 selectYuvCaptureFormat( const std::vector& 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