Resolve device selector on detach and add YuvStimProducer state tests.
Detach finds the shared producer via lcameraDev_resolveDeviceSelectorCReq then removes buffers by attach identity; unit tests cover quale guards. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -28,6 +28,7 @@ LcameraDevDllState::LcameraDevDllState()
|
|||||||
lcameraDev_main(nullptr),
|
lcameraDev_main(nullptr),
|
||||||
lcameraDev_exit(nullptr),
|
lcameraDev_exit(nullptr),
|
||||||
lcameraDev_getOrCreateDeviceCReq(nullptr),
|
lcameraDev_getOrCreateDeviceCReq(nullptr),
|
||||||
|
lcameraDev_resolveDeviceSelectorCReq(nullptr),
|
||||||
lcameraDev_releaseDeviceCReq(nullptr),
|
lcameraDev_releaseDeviceCReq(nullptr),
|
||||||
lcameraDev_configureSessionModeCReq(nullptr)
|
lcameraDev_configureSessionModeCReq(nullptr)
|
||||||
{}
|
{}
|
||||||
@@ -47,23 +48,6 @@ std::shared_ptr<YuvStimProducer> findStimProducerByCameraId(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<YuvStimProducer> findStimProducerWithAttachedBuffer(
|
|
||||||
const std::shared_ptr<device::DeviceAttachmentSpec>& desc)
|
|
||||||
{
|
|
||||||
for (const std::shared_ptr<YuvStimProducer>& producer :
|
|
||||||
attachedStimulusProducers)
|
|
||||||
{
|
|
||||||
assert(producer != nullptr);
|
|
||||||
if (producer->getAttachedStimulusBufferByAttachIdentity(
|
|
||||||
desc->deviceIdentifier, desc->qualeIfaceApi))
|
|
||||||
{
|
|
||||||
return producer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool validateAttachRequest(
|
bool validateAttachRequest(
|
||||||
const std::shared_ptr<device::DeviceAttachmentSpec>& spec)
|
const std::shared_ptr<device::DeviceAttachmentSpec>& spec)
|
||||||
{
|
{
|
||||||
@@ -110,6 +94,11 @@ void loadLcameraDevSymbols()
|
|||||||
dlsym(
|
dlsym(
|
||||||
lcameraDevDll.dlopenHandle.get(),
|
lcameraDevDll.dlopenHandle.get(),
|
||||||
"lcameraDev_getOrCreateDeviceCReq"));
|
"lcameraDev_getOrCreateDeviceCReq"));
|
||||||
|
lcameraDevDll.lcameraDev_resolveDeviceSelectorCReq = reinterpret_cast<
|
||||||
|
lcameraDev_resolveDeviceSelectorCReqFn *>(
|
||||||
|
dlsym(
|
||||||
|
lcameraDevDll.dlopenHandle.get(),
|
||||||
|
"lcameraDev_resolveDeviceSelectorCReq"));
|
||||||
lcameraDevDll.lcameraDev_releaseDeviceCReq = reinterpret_cast<
|
lcameraDevDll.lcameraDev_releaseDeviceCReq = reinterpret_cast<
|
||||||
lcameraDev_releaseDeviceCReqFn *>(
|
lcameraDev_releaseDeviceCReqFn *>(
|
||||||
dlsym(
|
dlsym(
|
||||||
@@ -124,6 +113,7 @@ void loadLcameraDevSymbols()
|
|||||||
if (!lcameraDevDll.lcameraDev_main
|
if (!lcameraDevDll.lcameraDev_main
|
||||||
|| !lcameraDevDll.lcameraDev_exit
|
|| !lcameraDevDll.lcameraDev_exit
|
||||||
|| !lcameraDevDll.lcameraDev_getOrCreateDeviceCReq
|
|| !lcameraDevDll.lcameraDev_getOrCreateDeviceCReq
|
||||||
|
|| !lcameraDevDll.lcameraDev_resolveDeviceSelectorCReq
|
||||||
|| !lcameraDevDll.lcameraDev_releaseDeviceCReq
|
|| !lcameraDevDll.lcameraDev_releaseDeviceCReq
|
||||||
|| !lcameraDevDll.lcameraDev_configureSessionModeCReq)
|
|| !lcameraDevDll.lcameraDev_configureSessionModeCReq)
|
||||||
{
|
{
|
||||||
@@ -276,7 +266,11 @@ lcameraBuff_detachDeviceCReq(
|
|||||||
co_return StimBuffDeviceOpResult{false, desc};
|
co_return StimBuffDeviceOpResult{false, desc};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto producer = findStimProducerWithAttachedBuffer(desc);
|
const lcamera_dev::CameraIdentityRecord resolvedIdentity =
|
||||||
|
co_await (*lcameraDevDll.lcameraDev_resolveDeviceSelectorCReq)(
|
||||||
|
desc->deviceSelector);
|
||||||
|
|
||||||
|
auto producer = findStimProducerByCameraId(resolvedIdentity.id);
|
||||||
if (!producer) {
|
if (!producer) {
|
||||||
co_return StimBuffDeviceOpResult{true, desc};
|
co_return StimBuffDeviceOpResult{true, desc};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ struct LcameraDevDllState
|
|||||||
lcameraDev_mainFn *lcameraDev_main;
|
lcameraDev_mainFn *lcameraDev_main;
|
||||||
lcameraDev_exitFn *lcameraDev_exit;
|
lcameraDev_exitFn *lcameraDev_exit;
|
||||||
lcameraDev_getOrCreateDeviceCReqFn *lcameraDev_getOrCreateDeviceCReq;
|
lcameraDev_getOrCreateDeviceCReqFn *lcameraDev_getOrCreateDeviceCReq;
|
||||||
|
lcameraDev_resolveDeviceSelectorCReqFn *lcameraDev_resolveDeviceSelectorCReq;
|
||||||
lcameraDev_releaseDeviceCReqFn *lcameraDev_releaseDeviceCReq;
|
lcameraDev_releaseDeviceCReqFn *lcameraDev_releaseDeviceCReq;
|
||||||
lcameraDev_configureSessionModeCReqFn *lcameraDev_configureSessionModeCReq;
|
lcameraDev_configureSessionModeCReqFn *lcameraDev_configureSessionModeCReq;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ add_executable(lcameraBuff_unit_tests
|
|||||||
lcameraBuffParams_tests.cpp
|
lcameraBuffParams_tests.cpp
|
||||||
pixelAndColorFormatDecisions_tests.cpp
|
pixelAndColorFormatDecisions_tests.cpp
|
||||||
yuvLayoutClassification_tests.cpp
|
yuvLayoutClassification_tests.cpp
|
||||||
|
yuvStimProducer_state_tests.cpp
|
||||||
|
hilSmoCallbacksStub.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_include_directories(lcameraBuff_unit_tests PRIVATE
|
target_include_directories(lcameraBuff_unit_tests PRIVATE
|
||||||
|
|||||||
@@ -0,0 +1,95 @@
|
|||||||
|
#include <hilSmoCallbacksStub.h>
|
||||||
|
#include <opts.h>
|
||||||
|
#include <user/comparatorApiDesc.h>
|
||||||
|
#include <spinscale/componentThread.h>
|
||||||
|
|
||||||
|
namespace lcamera_buff_tests {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::optional<std::string> searchForLibInSmoSearchPathsStub(
|
||||||
|
const std::string& libraryPath)
|
||||||
|
{
|
||||||
|
(void)libraryPath;
|
||||||
|
|
||||||
|
const char *overridePath = std::getenv("LCAMERADEV_LIB_PATH");
|
||||||
|
if (overridePath != nullptr && std::string(overridePath).size() > 0) {
|
||||||
|
return overridePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<sscl::ComponentThread> componentThreadGetSelfStub()
|
||||||
|
{
|
||||||
|
return sscl::ComponentThread::getSelf();
|
||||||
|
}
|
||||||
|
|
||||||
|
OptionParser& optionParserGetOptionsStub()
|
||||||
|
{
|
||||||
|
return OptionParser::getOptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
void releaseUseHostPtrBufferStub(
|
||||||
|
std::shared_ptr<smo::compute::ClBuffer> buffer)
|
||||||
|
{
|
||||||
|
(void)buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<smo::compute::ComputeDevice> computeManagerGetDeviceStub()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void computeManagerReleaseDeviceStub(
|
||||||
|
std::shared_ptr<smo::compute::ComputeDevice> device)
|
||||||
|
{
|
||||||
|
(void)device;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<smo::cologex::ExportedComparatorTypeDesc>
|
||||||
|
comparatorManagerGetComparatorTypeStub(smo::cologex::ComparatorTypeId typeId)
|
||||||
|
{
|
||||||
|
(void)typeId;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<smo::cologex::Comparator> comparatorGetNewInstanceStub(
|
||||||
|
const std::shared_ptr<smo::cologex::ExportedComparatorTypeDesc>& comparatorType)
|
||||||
|
{
|
||||||
|
(void)comparatorType;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const smo::stim_buff::SmoCallbacks hilCallbacks = {
|
||||||
|
.searchForLibInSmoSearchPaths = searchForLibInSmoSearchPathsStub,
|
||||||
|
.ComponentThread_getSelf = componentThreadGetSelfStub,
|
||||||
|
.OptionParser_getOptions = optionParserGetOptionsStub,
|
||||||
|
.ComputeManager_createUseHostPtrBuffer = createUseHostPtrBufferStub,
|
||||||
|
.ComputeManager_releaseUseHostPtrBuffer = releaseUseHostPtrBufferStub,
|
||||||
|
.ComputeManager_getDevice = computeManagerGetDeviceStub,
|
||||||
|
.ComputeManager_releaseDevice = computeManagerReleaseDeviceStub,
|
||||||
|
.ComparatorManager_getComparatorType =
|
||||||
|
comparatorManagerGetComparatorTypeStub,
|
||||||
|
.Comparator_getNewInstance = comparatorGetNewInstanceStub,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
std::shared_ptr<smo::compute::ClBuffer> createUseHostPtrBufferStub(
|
||||||
|
void* hostPtr,
|
||||||
|
size_t size,
|
||||||
|
cl_mem_flags flags)
|
||||||
|
{
|
||||||
|
static const std::vector<std::shared_ptr<smo::compute::ComputeDevice>>
|
||||||
|
emptyDevices;
|
||||||
|
return std::make_shared<smo::compute::ClBuffer>(
|
||||||
|
hostPtr, size, flags, emptyDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
const smo::stim_buff::SmoCallbacks& hilSmoCallbacksStub()
|
||||||
|
{
|
||||||
|
return hilCallbacks;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace lcamera_buff_tests
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef LCAMERA_BUFF_TESTS_HIL_SMO_CALLBACKS_STUB_H
|
||||||
|
#define LCAMERA_BUFF_TESTS_HIL_SMO_CALLBACKS_STUB_H
|
||||||
|
|
||||||
|
#include <user/compute.h>
|
||||||
|
#include <user/smoHooks.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace lcamera_buff_tests {
|
||||||
|
|
||||||
|
const smo::stim_buff::SmoCallbacks& hilSmoCallbacksStub();
|
||||||
|
|
||||||
|
std::shared_ptr<smo::compute::ClBuffer> createUseHostPtrBufferStub(
|
||||||
|
void* hostPtr,
|
||||||
|
size_t size,
|
||||||
|
cl_mem_flags flags);
|
||||||
|
|
||||||
|
} // namespace lcamera_buff_tests
|
||||||
|
|
||||||
|
#endif // LCAMERA_BUFF_TESTS_HIL_SMO_CALLBACKS_STUB_H
|
||||||
@@ -0,0 +1,244 @@
|
|||||||
|
#include <boost/asio/io_context.hpp>
|
||||||
|
#include <cameraIdentity.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
#include <hilSmoCallbacksStub.h>
|
||||||
|
#include <lcameraBuffInternal.h>
|
||||||
|
#include <support/exceptionAssertions.h>
|
||||||
|
#include <yuvChannelStimulusBuffer.h>
|
||||||
|
#include <yuvStimProducer.h>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace smo {
|
||||||
|
namespace stim_buff {
|
||||||
|
namespace lcamera_buff {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr const char *usbExternalSelector =
|
||||||
|
"model-substr:USB;location:external";
|
||||||
|
constexpr const char *usbAliasSelector =
|
||||||
|
"model-substr:USB Video Device;location:external";
|
||||||
|
|
||||||
|
std::shared_ptr<device::DeviceAttachmentSpec> makeLcameraAttachSpec(
|
||||||
|
const std::string& deviceSelector,
|
||||||
|
const std::string& qualeIfaceApi,
|
||||||
|
const std::string& deviceIdentifier = "cam0")
|
||||||
|
{
|
||||||
|
auto spec = std::make_shared<device::DeviceAttachmentSpec>();
|
||||||
|
spec->deviceIdentifier = deviceIdentifier;
|
||||||
|
spec->sensorType = 'e';
|
||||||
|
spec->qualeIfaceApi = qualeIfaceApi;
|
||||||
|
spec->stimBuffApi = "lcameraBuff";
|
||||||
|
spec->provider = "lcameraDev";
|
||||||
|
spec->deviceSelector = deviceSelector;
|
||||||
|
spec->stimBuffApiParams = {
|
||||||
|
{"v-res", "480p"},
|
||||||
|
{"colour-space", "yuv"},
|
||||||
|
{"opt-planar", ""},
|
||||||
|
};
|
||||||
|
return spec;
|
||||||
|
}
|
||||||
|
|
||||||
|
LcameraBuffParsedParams makeDefaultParsedParams()
|
||||||
|
{
|
||||||
|
LcameraBuffParsedParams parsedParams;
|
||||||
|
parsedParams.width = 640;
|
||||||
|
parsedParams.height = 480;
|
||||||
|
parsedParams.colourSpace = lcamera_dev::LcameraDevColourSpace::Yuv;
|
||||||
|
parsedParams.fullPlanarIsOptional = true;
|
||||||
|
return parsedParams;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcamera_dev::LcameraDevConfiguredCameraMode makeYuyv480ConfiguredMode()
|
||||||
|
{
|
||||||
|
lcamera_dev::LcameraDevConfiguredCameraMode configuredMode;
|
||||||
|
configuredMode.width = 640;
|
||||||
|
configuredMode.height = 480;
|
||||||
|
configuredMode.colourSpace = lcamera_dev::LcameraDevColourSpace::Yuv;
|
||||||
|
configuredMode.pixelFormatName = "YUYV";
|
||||||
|
configuredMode.isFullyPlanar = false;
|
||||||
|
configuredMode.planeCount = 1;
|
||||||
|
return configuredMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
lcamera_dev::CameraIdentityRecord makeTestCameraIdentity()
|
||||||
|
{
|
||||||
|
lcamera_dev::CameraIdentityRecord identity;
|
||||||
|
identity.id = "unit-test-camera-1";
|
||||||
|
identity.model = "UnitTestCam";
|
||||||
|
return identity;
|
||||||
|
}
|
||||||
|
|
||||||
|
class YuvStimProducerQualeIfaceTest
|
||||||
|
: public ::testing::Test
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
void SetUp() override
|
||||||
|
{
|
||||||
|
lcameraBuffSmoHooksPtr = &lcamera_buff_tests::hilSmoCallbacksStub();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown() override
|
||||||
|
{
|
||||||
|
lcameraBuffSmoHooksPtr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::asio::io_context ioContext;
|
||||||
|
const LcameraBuffParsedParams parsedParams = makeDefaultParsedParams();
|
||||||
|
const lcamera_dev::LcameraDevConfiguredCameraMode configuredMode =
|
||||||
|
makeYuyv480ConfiguredMode();
|
||||||
|
const lcamera_dev::CameraIdentityRecord cameraIdentity =
|
||||||
|
makeTestCameraIdentity();
|
||||||
|
|
||||||
|
YuvStimProducer makeProducer(
|
||||||
|
const std::shared_ptr<device::DeviceAttachmentSpec>& producerSpec)
|
||||||
|
{
|
||||||
|
return YuvStimProducer(
|
||||||
|
producerSpec,
|
||||||
|
ioContext,
|
||||||
|
nullptr,
|
||||||
|
cameraIdentity,
|
||||||
|
parsedParams,
|
||||||
|
configuredMode);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(YuvStimProducerQualeIfaceTest, GetOrCreateSameSpecReturnsExistingBuffer)
|
||||||
|
{
|
||||||
|
auto producerSpec = makeLcameraAttachSpec(
|
||||||
|
usbExternalSelector, "colour-yuv-y");
|
||||||
|
YuvStimProducer producer = makeProducer(producerSpec);
|
||||||
|
|
||||||
|
const auto firstBuffer =
|
||||||
|
producer.getOrCreateAttachedStimulusBuffer(producerSpec);
|
||||||
|
ASSERT_NE(firstBuffer, nullptr);
|
||||||
|
|
||||||
|
const auto secondBuffer =
|
||||||
|
producer.getOrCreateAttachedStimulusBuffer(producerSpec);
|
||||||
|
|
||||||
|
EXPECT_EQ(firstBuffer, secondBuffer);
|
||||||
|
EXPECT_EQ(producer.attachedStimulusBuffers.size(), 1u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(YuvStimProducerQualeIfaceTest,
|
||||||
|
RejectDuplicateQualeWhenAlternateSelectorResolvesToSameSession)
|
||||||
|
{
|
||||||
|
/* One YuvStimProducer == one resolved libcamera camera id / session.
|
||||||
|
* A second DAP line may spell a different deviceSelector yet resolve to
|
||||||
|
* that same session via attachToExistingProducer; it must not attach the
|
||||||
|
* same qualeIface API twice.
|
||||||
|
*/
|
||||||
|
auto producerSpec = makeLcameraAttachSpec(
|
||||||
|
usbExternalSelector, "colour-yuv-y");
|
||||||
|
YuvStimProducer producer = makeProducer(producerSpec);
|
||||||
|
|
||||||
|
const auto firstSpec = makeLcameraAttachSpec(
|
||||||
|
usbExternalSelector, "colour-yuv-y", "cam-y-line0");
|
||||||
|
ASSERT_NE(producer.getOrCreateAttachedStimulusBuffer(firstSpec), nullptr);
|
||||||
|
|
||||||
|
const auto duplicateQualeAlternateSelectorSpec = makeLcameraAttachSpec(
|
||||||
|
usbAliasSelector, "colour-yuv-y", "cam-y-line1");
|
||||||
|
|
||||||
|
try {
|
||||||
|
producer.getOrCreateAttachedStimulusBuffer(
|
||||||
|
duplicateQualeAlternateSelectorSpec);
|
||||||
|
FAIL() << "Expected std::runtime_error";
|
||||||
|
}
|
||||||
|
catch (const std::runtime_error& exception)
|
||||||
|
{
|
||||||
|
sscl::tests::expectExceptionMessageContains(
|
||||||
|
exception,
|
||||||
|
"already attached for camera session");
|
||||||
|
sscl::tests::expectExceptionMessageContains(
|
||||||
|
exception,
|
||||||
|
"colour-yuv-y");
|
||||||
|
}
|
||||||
|
|
||||||
|
EXPECT_EQ(producer.attachedStimulusBuffers.size(), 1u);
|
||||||
|
EXPECT_NE(
|
||||||
|
firstSpec->deviceSelector,
|
||||||
|
duplicateQualeAlternateSelectorSpec->deviceSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(YuvStimProducerQualeIfaceTest,
|
||||||
|
AllowDistinctQualeIfacesForAlternateSelectorsOnSameSession)
|
||||||
|
{
|
||||||
|
auto producerSpec = makeLcameraAttachSpec(
|
||||||
|
usbExternalSelector, "colour-yuv-y");
|
||||||
|
YuvStimProducer producer = makeProducer(producerSpec);
|
||||||
|
|
||||||
|
const auto ySpec = makeLcameraAttachSpec(
|
||||||
|
usbExternalSelector, "colour-yuv-y", "cam-y");
|
||||||
|
const auto uSpec = makeLcameraAttachSpec(
|
||||||
|
usbAliasSelector, "colour-yuv-u", "cam-u");
|
||||||
|
const auto vSpec = makeLcameraAttachSpec(
|
||||||
|
usbExternalSelector, "colour-yuv-v", "cam-v");
|
||||||
|
|
||||||
|
ASSERT_NE(producer.getOrCreateAttachedStimulusBuffer(ySpec), nullptr);
|
||||||
|
ASSERT_NE(producer.getOrCreateAttachedStimulusBuffer(uSpec), nullptr);
|
||||||
|
ASSERT_NE(producer.getOrCreateAttachedStimulusBuffer(vSpec), nullptr);
|
||||||
|
|
||||||
|
EXPECT_EQ(producer.attachedStimulusBuffers.size(), 3u);
|
||||||
|
EXPECT_TRUE(producer.hasBufferWithQualeIfaceApi("colour-yuv-y"));
|
||||||
|
EXPECT_TRUE(producer.hasBufferWithQualeIfaceApi("colour-yuv-u"));
|
||||||
|
EXPECT_TRUE(producer.hasBufferWithQualeIfaceApi("colour-yuv-v"));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(YuvStimProducerQualeIfaceTest,
|
||||||
|
RejectDuplicateQualeAfterYViaSelectorAAndUViaSelectorB)
|
||||||
|
{
|
||||||
|
auto producerSpec = makeLcameraAttachSpec(
|
||||||
|
usbExternalSelector, "colour-yuv-y");
|
||||||
|
YuvStimProducer producer = makeProducer(producerSpec);
|
||||||
|
|
||||||
|
ASSERT_NE(producer.getOrCreateAttachedStimulusBuffer(
|
||||||
|
makeLcameraAttachSpec(usbExternalSelector, "colour-yuv-y", "cam-y")),
|
||||||
|
nullptr);
|
||||||
|
ASSERT_NE(producer.getOrCreateAttachedStimulusBuffer(
|
||||||
|
makeLcameraAttachSpec(usbAliasSelector, "colour-yuv-u", "cam-u")),
|
||||||
|
nullptr);
|
||||||
|
|
||||||
|
const auto duplicateYViaAlternateSelector = makeLcameraAttachSpec(
|
||||||
|
usbAliasSelector, "colour-yuv-y", "cam-y-second-dap-line");
|
||||||
|
|
||||||
|
EXPECT_THROW(
|
||||||
|
producer.getOrCreateAttachedStimulusBuffer(
|
||||||
|
duplicateYViaAlternateSelector),
|
||||||
|
std::runtime_error);
|
||||||
|
EXPECT_EQ(producer.attachedStimulusBuffers.size(), 2u);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(YuvStimProducerQualeIfaceTest,
|
||||||
|
FindAttachedBufferByAttachIdentityWithAlternateSelector)
|
||||||
|
{
|
||||||
|
auto producerSpec = makeLcameraAttachSpec(
|
||||||
|
usbExternalSelector, "colour-yuv-y");
|
||||||
|
YuvStimProducer producer = makeProducer(producerSpec);
|
||||||
|
|
||||||
|
const auto uSpec = makeLcameraAttachSpec(
|
||||||
|
usbExternalSelector, "colour-yuv-u", "cam-u");
|
||||||
|
ASSERT_NE(producer.getOrCreateAttachedStimulusBuffer(uSpec), nullptr);
|
||||||
|
|
||||||
|
const auto foundBuffer =
|
||||||
|
producer.getAttachedStimulusBufferByAttachIdentity(
|
||||||
|
"cam-u", "colour-yuv-u");
|
||||||
|
ASSERT_NE(foundBuffer, nullptr);
|
||||||
|
EXPECT_EQ(
|
||||||
|
foundBuffer->deviceAttachmentSpec->deviceSelector,
|
||||||
|
usbExternalSelector);
|
||||||
|
|
||||||
|
EXPECT_EQ(
|
||||||
|
producer.getAttachedStimulusBuffer(
|
||||||
|
makeLcameraAttachSpec(
|
||||||
|
usbAliasSelector, "colour-yuv-u", "cam-u")),
|
||||||
|
nullptr);
|
||||||
|
EXPECT_NE(
|
||||||
|
producer.getAttachedStimulusBufferByAttachIdentity(
|
||||||
|
"cam-u", "colour-yuv-u"),
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace lcamera_buff
|
||||||
|
} // namespace stim_buff
|
||||||
|
} // namespace smo
|
||||||
Reference in New Issue
Block a user