142 lines
3.2 KiB
C++
142 lines
3.2 KiB
C++
|
|
#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
|