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,27 @@
|
||||
add_executable(lcameraBuff_unit_tests
|
||||
lcameraBuffParams_tests.cpp
|
||||
pixelAndColorFormatDecisions_tests.cpp
|
||||
yuvLayoutClassification_tests.cpp
|
||||
)
|
||||
|
||||
target_include_directories(lcameraBuff_unit_tests PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_SOURCE_DIR}/stimBuffApis/lcameraBuff
|
||||
${CMAKE_SOURCE_DIR}/commonLibs/lcameraDev
|
||||
${CMAKE_SOURCE_DIR}/libspinscale/tests
|
||||
${CMAKE_SOURCE_DIR}/tests/fixtures
|
||||
${CMAKE_SOURCE_DIR}/include
|
||||
${CMAKE_BINARY_DIR}/include
|
||||
)
|
||||
|
||||
target_link_libraries(lcameraBuff_unit_tests
|
||||
gtest_main
|
||||
lcameraBuff
|
||||
spinscale_test_support
|
||||
${Boost_LIBRARIES}
|
||||
${OPENCL_LIBRARIES}
|
||||
)
|
||||
|
||||
add_dependencies(lcameraBuff_unit_tests gtest_main spinscale_test_support)
|
||||
|
||||
add_test(NAME lcameraBuff_unit_tests COMMAND lcameraBuff_unit_tests)
|
||||
@@ -0,0 +1,131 @@
|
||||
#include <lcameraBuffParams.h>
|
||||
#include <gtest/gtest.h>
|
||||
#include <support/exceptionAssertions.h>
|
||||
#include <user/deviceAttachmentSpec.h>
|
||||
|
||||
namespace smo {
|
||||
namespace stim_buff {
|
||||
namespace lcamera_buff {
|
||||
namespace {
|
||||
|
||||
device::DeviceAttachmentSpec makeSpecWithParams(
|
||||
std::vector<std::pair<std::string, std::string>> params)
|
||||
{
|
||||
device::DeviceAttachmentSpec spec;
|
||||
spec.stimBuffApi = "lcameraBuff";
|
||||
spec.provider = "lcameraDev";
|
||||
spec.stimBuffApiParams = std::move(params);
|
||||
return spec;
|
||||
}
|
||||
|
||||
TEST(LcameraBuffParamsTest, DimWidthHeightSynonymsParseExplicitResolution)
|
||||
{
|
||||
device::DeviceAttachmentSpec spec = makeSpecWithParams({
|
||||
{"dim-w", "640"},
|
||||
{"dimension-h", "480"},
|
||||
{"colour-space", "yuv"},
|
||||
});
|
||||
|
||||
const LcameraBuffParsedParams parsed = parseLcameraBuffParams(spec);
|
||||
|
||||
EXPECT_EQ(parsed.width, 640u);
|
||||
EXPECT_EQ(parsed.height, 480u);
|
||||
EXPECT_EQ(
|
||||
parsed.colourSpace,
|
||||
lcamera_dev::LcameraDevColourSpace::Yuv);
|
||||
EXPECT_FALSE(parsed.fullPlanarIsOptional);
|
||||
}
|
||||
|
||||
TEST(LcameraBuffParamsTest, VerticalResolutionShorthand480p)
|
||||
{
|
||||
device::DeviceAttachmentSpec spec = makeSpecWithParams({
|
||||
{"v-res", "480p"},
|
||||
{"colour-space", "yuv"},
|
||||
{"opt-planar", ""},
|
||||
});
|
||||
|
||||
const LcameraBuffParsedParams parsed = parseLcameraBuffParams(spec);
|
||||
|
||||
EXPECT_EQ(parsed.width, 640u);
|
||||
EXPECT_EQ(parsed.height, 480u);
|
||||
EXPECT_TRUE(parsed.fullPlanarIsOptional);
|
||||
}
|
||||
|
||||
TEST(LcameraBuffParamsTest, OptPlanarSynonymEmptyValueMeansTrue)
|
||||
{
|
||||
device::DeviceAttachmentSpec spec = makeSpecWithParams({
|
||||
{"v-res", "480p"},
|
||||
{"full-planar-is-optional", ""},
|
||||
});
|
||||
|
||||
EXPECT_TRUE(parseLcameraBuffParams(spec).fullPlanarIsOptional);
|
||||
}
|
||||
|
||||
TEST(LcameraBuffParamsTest, OptPlanarExplicitFalseDisables)
|
||||
{
|
||||
device::DeviceAttachmentSpec spec = makeSpecWithParams({
|
||||
{"dim-w", "640"},
|
||||
{"dim-h", "480"},
|
||||
{"opt-planar", "false"},
|
||||
});
|
||||
|
||||
EXPECT_FALSE(parseLcameraBuffParams(spec).fullPlanarIsOptional);
|
||||
}
|
||||
|
||||
TEST(LcameraBuffParamsTest, OptPlanarAbsentDefaultsFalse)
|
||||
{
|
||||
device::DeviceAttachmentSpec spec = makeSpecWithParams({
|
||||
{"v-res", "480p"},
|
||||
});
|
||||
|
||||
EXPECT_FALSE(parseLcameraBuffParams(spec).fullPlanarIsOptional);
|
||||
}
|
||||
|
||||
TEST(LcameraBuffParamsTest, MixedResolutionGroupsThrow)
|
||||
{
|
||||
device::DeviceAttachmentSpec spec = makeSpecWithParams({
|
||||
{"v-res", "480p"},
|
||||
{"dim-w", "640"},
|
||||
});
|
||||
|
||||
try {
|
||||
parseLcameraBuffParams(spec);
|
||||
FAIL() << "Expected runtime_error";
|
||||
}
|
||||
catch (const std::runtime_error& exception)
|
||||
{
|
||||
sscl::tests::expectExceptionMessageContains(
|
||||
exception,
|
||||
"cannot be combined");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LcameraBuffParamsTest, UnsupportedColourSpaceThrows)
|
||||
{
|
||||
device::DeviceAttachmentSpec spec = makeSpecWithParams({
|
||||
{"v-res", "480"},
|
||||
{"colour-space", "rgb"},
|
||||
});
|
||||
|
||||
EXPECT_THROW(parseLcameraBuffParams(spec), std::runtime_error);
|
||||
}
|
||||
|
||||
TEST(LcameraBuffParamsTest, ToCameraModeRequestCopiesFields)
|
||||
{
|
||||
LcameraBuffParsedParams parsed;
|
||||
parsed.width = 1280;
|
||||
parsed.height = 720;
|
||||
parsed.fullPlanarIsOptional = true;
|
||||
|
||||
const lcamera_dev::LcameraDevCameraModeRequest request =
|
||||
toCameraModeRequest(parsed);
|
||||
|
||||
EXPECT_EQ(request.width, 1280u);
|
||||
EXPECT_EQ(request.height, 720u);
|
||||
EXPECT_TRUE(request.fullPlanarIsOptional);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace lcamera_buff
|
||||
} // namespace stim_buff
|
||||
} // namespace smo
|
||||
@@ -0,0 +1,82 @@
|
||||
#include <pixelAndColorFormatDecisions.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace smo {
|
||||
namespace stim_buff {
|
||||
namespace lcamera_buff {
|
||||
namespace {
|
||||
|
||||
lcamera_dev::LcameraDevConfiguredCameraMode makeConfiguredMode(
|
||||
const char *pixelFormatName)
|
||||
{
|
||||
lcamera_dev::LcameraDevConfiguredCameraMode mode;
|
||||
mode.width = 640;
|
||||
mode.height = 480;
|
||||
mode.pixelFormatName = pixelFormatName;
|
||||
return mode;
|
||||
}
|
||||
|
||||
TEST(PixelAndColorFormatDecisionsTest, YuyvClassifiesAsYuv422)
|
||||
{
|
||||
const lcamera_dev::LcameraDevConfiguredCameraMode mode =
|
||||
makeConfiguredMode("YUYV");
|
||||
|
||||
EXPECT_EQ(
|
||||
classifyYuvChromaSubsampling(mode),
|
||||
YuvChromaSubsampling::Yuv422);
|
||||
}
|
||||
|
||||
TEST(PixelAndColorFormatDecisionsTest, Yuv420ChannelSizes)
|
||||
{
|
||||
EXPECT_EQ(
|
||||
computeDeinterleavedChannelByteSize(
|
||||
YuvChannelKind::Y,
|
||||
640,
|
||||
480,
|
||||
YuvChromaSubsampling::Yuv420),
|
||||
640u * 480u);
|
||||
EXPECT_EQ(
|
||||
computeDeinterleavedChannelByteSize(
|
||||
YuvChannelKind::U,
|
||||
640,
|
||||
480,
|
||||
YuvChromaSubsampling::Yuv420),
|
||||
320u * 240u);
|
||||
EXPECT_EQ(
|
||||
computeDeinterleavedChannelByteSize(
|
||||
YuvChannelKind::V,
|
||||
640,
|
||||
480,
|
||||
YuvChromaSubsampling::Yuv420),
|
||||
320u * 240u);
|
||||
}
|
||||
|
||||
TEST(PixelAndColorFormatDecisionsTest, Yuv422ChannelSizesForDellLaptopYuyv)
|
||||
{
|
||||
EXPECT_EQ(
|
||||
computeDeinterleavedChannelByteSize(
|
||||
YuvChannelKind::Y,
|
||||
640,
|
||||
480,
|
||||
YuvChromaSubsampling::Yuv422),
|
||||
640u * 480u);
|
||||
EXPECT_EQ(
|
||||
computeDeinterleavedChannelByteSize(
|
||||
YuvChannelKind::U,
|
||||
640,
|
||||
480,
|
||||
YuvChromaSubsampling::Yuv422),
|
||||
320u * 480u);
|
||||
EXPECT_EQ(
|
||||
computeDeinterleavedChannelByteSize(
|
||||
YuvChannelKind::V,
|
||||
640,
|
||||
480,
|
||||
YuvChromaSubsampling::Yuv422),
|
||||
320u * 480u);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace lcamera_buff
|
||||
} // namespace stim_buff
|
||||
} // namespace smo
|
||||
@@ -0,0 +1,44 @@
|
||||
#include <yuvCaptureLayout.h>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
namespace smo {
|
||||
namespace stim_buff {
|
||||
namespace lcamera_buff {
|
||||
namespace {
|
||||
|
||||
TEST(YuvCaptureLayoutTest, PackedYuyvUsesMmapDeinterleavedBacking)
|
||||
{
|
||||
lcamera_dev::LcameraDevConfiguredCameraMode mode;
|
||||
mode.pixelFormatName = "YUYV";
|
||||
mode.isFullyPlanar = false;
|
||||
mode.planeCount = 1;
|
||||
|
||||
EXPECT_EQ(
|
||||
classifyYuvCaptureLayoutPath(mode),
|
||||
YuvCaptureLayoutPath::PackedDeinterleave);
|
||||
EXPECT_EQ(
|
||||
getChannelBackingPlanForLayoutPath(
|
||||
YuvCaptureLayoutPath::PackedDeinterleave),
|
||||
YuvChannelBackingPlan::MmapDeinterleaved);
|
||||
}
|
||||
|
||||
TEST(YuvCaptureLayoutTest, FullPlanarUsesDirectBacking)
|
||||
{
|
||||
lcamera_dev::LcameraDevConfiguredCameraMode mode;
|
||||
mode.pixelFormatName = "YU12";
|
||||
mode.isFullyPlanar = true;
|
||||
mode.planeCount = 3;
|
||||
|
||||
EXPECT_EQ(
|
||||
classifyYuvCaptureLayoutPath(mode),
|
||||
YuvCaptureLayoutPath::FullPlanarDirect);
|
||||
EXPECT_EQ(
|
||||
getChannelBackingPlanForLayoutPath(
|
||||
YuvCaptureLayoutPath::FullPlanarDirect),
|
||||
YuvChannelBackingPlan::LCameraDirect);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace lcamera_buff
|
||||
} // namespace stim_buff
|
||||
} // namespace smo
|
||||
Reference in New Issue
Block a user