Add lcameraBuff Stage 2 plugin with YUV attach and unit tests.
Introduce params parsing, pixel/format decisions, capture layout, shared YuvStimProducer per camera, and channel stimulus buffers with attach flow. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
#include <pixelAndColorFormatDecisions.h>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
namespace smo {
|
||||
namespace stim_buff {
|
||||
namespace lcamera_buff {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string normalizeFourccToken(std::string token)
|
||||
{
|
||||
for (char& character : token)
|
||||
{
|
||||
character = static_cast<char>(
|
||||
std::toupper(static_cast<unsigned char>(character)));
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
bool fourccInSet(
|
||||
const std::string& fourcc,
|
||||
const std::unordered_set<std::string>& candidates)
|
||||
{
|
||||
return candidates.find(fourcc) != candidates.end();
|
||||
}
|
||||
|
||||
const std::unordered_set<std::string>& yuv420FourccSet()
|
||||
{
|
||||
static const std::unordered_set<std::string> fourccs = {
|
||||
"YU12", "YV12", "YUV420", "YVU420", "NV12", "NV21",
|
||||
};
|
||||
return fourccs;
|
||||
}
|
||||
|
||||
const std::unordered_set<std::string>& yuv422FourccSet()
|
||||
{
|
||||
static const std::unordered_set<std::string> fourccs = {
|
||||
"YUYV", "YVYU", "UYVY", "VYUY", "YUV422", "YVU422",
|
||||
"NV16", "NV61", "YU16", "YV16",
|
||||
};
|
||||
return fourccs;
|
||||
}
|
||||
|
||||
const std::unordered_set<std::string>& yuv444FourccSet()
|
||||
{
|
||||
static const std::unordered_set<std::string> fourccs = {
|
||||
"YUV444", "YVU444",
|
||||
};
|
||||
return fourccs;
|
||||
}
|
||||
|
||||
unsigned chromaPlaneWidth(unsigned frameWidth, YuvChromaSubsampling subsampling)
|
||||
{
|
||||
switch (subsampling)
|
||||
{
|
||||
case YuvChromaSubsampling::Yuv420:
|
||||
case YuvChromaSubsampling::Yuv422:
|
||||
return (frameWidth + 1u) / 2u;
|
||||
|
||||
case YuvChromaSubsampling::Yuv444:
|
||||
return frameWidth;
|
||||
}
|
||||
|
||||
throw std::logic_error(
|
||||
"lcameraBuff: unhandled YuvChromaSubsampling in chromaPlaneWidth");
|
||||
}
|
||||
|
||||
unsigned chromaPlaneHeight(unsigned frameHeight, YuvChromaSubsampling subsampling)
|
||||
{
|
||||
switch (subsampling)
|
||||
{
|
||||
case YuvChromaSubsampling::Yuv420:
|
||||
return (frameHeight + 1u) / 2u;
|
||||
|
||||
case YuvChromaSubsampling::Yuv422:
|
||||
case YuvChromaSubsampling::Yuv444:
|
||||
return frameHeight;
|
||||
}
|
||||
|
||||
throw std::logic_error(
|
||||
"lcameraBuff: unhandled YuvChromaSubsampling in chromaPlaneHeight");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
YuvChromaSubsampling classifyYuvChromaSubsampling(
|
||||
const lcamera_dev::LcameraDevConfiguredCameraMode& configuredMode)
|
||||
{
|
||||
const std::string fourcc =
|
||||
normalizeFourccToken(configuredMode.pixelFormatName);
|
||||
|
||||
if (fourccInSet(fourcc, yuv420FourccSet())) {
|
||||
return YuvChromaSubsampling::Yuv420;
|
||||
}
|
||||
|
||||
if (fourccInSet(fourcc, yuv422FourccSet())) {
|
||||
return YuvChromaSubsampling::Yuv422;
|
||||
}
|
||||
|
||||
if (fourccInSet(fourcc, yuv444FourccSet())) {
|
||||
return YuvChromaSubsampling::Yuv444;
|
||||
}
|
||||
|
||||
throw std::runtime_error(
|
||||
"lcameraBuff: unsupported YUV pixel format for chroma geometry: "
|
||||
+ configuredMode.pixelFormatName);
|
||||
}
|
||||
|
||||
size_t computeDeinterleavedChannelByteSize(
|
||||
YuvChannelKind channel,
|
||||
unsigned width, unsigned height,
|
||||
YuvChromaSubsampling subsampling)
|
||||
{
|
||||
switch (channel)
|
||||
{
|
||||
case YuvChannelKind::Y:
|
||||
return static_cast<size_t>(width) * static_cast<size_t>(height);
|
||||
|
||||
case YuvChannelKind::U:
|
||||
case YuvChannelKind::V:
|
||||
{
|
||||
const unsigned chromaWidth = chromaPlaneWidth(width, subsampling);
|
||||
const unsigned chromaHeight =
|
||||
chromaPlaneHeight(height, subsampling);
|
||||
return static_cast<size_t>(chromaWidth)
|
||||
* static_cast<size_t>(chromaHeight);
|
||||
}
|
||||
}
|
||||
|
||||
throw std::logic_error(
|
||||
"lcameraBuff: unhandled YuvChannelKind in computeDeinterleavedChannelByteSize");
|
||||
}
|
||||
|
||||
} // namespace lcamera_buff
|
||||
} // namespace stim_buff
|
||||
} // namespace smo
|
||||
Reference in New Issue
Block a user