Files

155 lines
4.3 KiB
C++
Raw Permalink Normal View History

#include <yuvStimProducer.h>
#include <yuvChannelStimulusBuffer.h>
#include <lcameraBuffInternal.h>
#include <config.h>
#include <stdexcept>
#define CL_TARGET_OPENCL_VERSION 120
#include <CL/cl.h>
#include <spinscale/syncCancelerForAsyncWork.h>
namespace smo {
namespace stim_buff {
namespace lcamera_buff {
YuvStimProducer::YuvStimProducer(
const std::shared_ptr<device::DeviceAttachmentSpec>& deviceAttachmentSpec,
boost::asio::io_context& ioContext,
const std::shared_ptr<lcamera_dev::CameraSession>& _deviceSession,
const lcamera_dev::CameraIdentityRecord& resolvedIdentity,
const LcameraBuffParsedParams& _parsedParams,
const lcamera_dev::LcameraDevConfiguredCameraMode& _configuredMode)
: StimulusProducer(deviceAttachmentSpec, ioContext),
deviceSession(_deviceSession),
resolvedCameraId(resolvedIdentity.id),
parsedParams(_parsedParams),
configuredMode(_configuredMode),
layoutPath(classifyYuvCaptureLayoutPath(_configuredMode)),
chromaSubsampling(classifyYuvChromaSubsampling(_configuredMode)),
channelBackingPlan(getChannelBackingPlanForLayoutPath(layoutPath))
{}
bool YuvStimProducer::supportsQualeIfaceApi(const std::string& qualeIfaceApi)
{
return qualeIfaceApi == "colour-yuv-y"
|| qualeIfaceApi == "colour-yuv-u"
|| qualeIfaceApi == "colour-yuv-v";
}
bool YuvStimProducer::exportsQualeIfaceApi(
const std::string& qualeIfaceApi) const
{
return supportsQualeIfaceApi(qualeIfaceApi);
}
std::shared_ptr<StimulusBuffer> YuvStimProducer::getOrCreateAttachedStimulusBuffer(
const std::shared_ptr<device::DeviceAttachmentSpec>& attachSpec)
{
if (!lcameraBuffSmoHooksPtr)
{
throw std::runtime_error(
"lcameraBuff: SMO hooks not initialized");
}
if (!supportsQualeIfaceApi(attachSpec->qualeIfaceApi))
{
throw std::runtime_error(
"lcameraBuff: unsupported qualeIfaceApi '"
+ attachSpec->qualeIfaceApi + "'");
}
const LcameraBuffParsedParams attachParsedParams =
parseLcameraBuffParams(*attachSpec);
if (!lcameraBuffParamsEqual(attachParsedParams, parsedParams))
{
throw std::runtime_error(
"lcameraBuff: conflicting stimbuff-api params across Y/U/V "
"attachments for camera '" + resolvedCameraId + "'");
}
auto existingBuffer = getAttachedStimulusBuffer(attachSpec);
if (existingBuffer) {
return existingBuffer;
}
/* One YuvStimProducer == one libcamera session. A second DAP line may use
* a different deviceSelector yet resolve to this same session; it must not
* attach the same qualeIface API twice.
*/
if (hasBufferWithQualeIfaceApi(attachSpec->qualeIfaceApi))
{
throw std::runtime_error(
"lcameraBuff: qualeIface '" + attachSpec->qualeIfaceApi
+ "' is already attached for camera session '"
+ resolvedCameraId + "'; each producer allows one buffer per "
"qualeIface API");
}
const YuvChannelKind channelKind =
YuvChannelStimulusBuffer::yuvChannelKindFromQualeIfaceApi(
attachSpec->qualeIfaceApi);
const size_t channelByteSize = computeDeinterleavedChannelByteSize(
channelKind,
configuredMode.width,
configuredMode.height,
chromaSubsampling);
auto channelBuffer = std::make_shared<YuvChannelStimulusBuffer>(
*this,
attachSpec,
CONFIG_STIMBUFF_FRAME_PERIOD_MS,
channelKind,
channelByteSize,
*lcameraBuffSmoHooksPtr,
CL_MEM_READ_WRITE);
if (!addAttachedStimulusBufferIfNotExists(channelBuffer))
{
if (hasBufferWithQualeIfaceApi(attachSpec->qualeIfaceApi))
{
throw std::runtime_error(
"lcameraBuff: qualeIface '"
+ attachSpec->qualeIfaceApi
+ "' is already attached for camera session '"
+ resolvedCameraId + "'");
}
throw std::runtime_error(
"lcameraBuff: duplicate stimbuff attachment for "
+ attachSpec->stringify());
}
return channelBuffer;
}
void YuvStimProducer::destroyAttachedStimulusBuffer(
const std::shared_ptr<StimulusBuffer>& buffer)
{
StimulusProducer::destroyAttachedStimulusBuffer(buffer);
}
void YuvStimProducer::start()
{
// Stage 2: setup-only attach; capture daemon deferred to Stage 8.
}
void YuvStimProducer::stop()
{
// Stage 2: setup-only attach; capture daemon deferred to Stage 8.
}
sscl::co::ViralNonPostingInvoker<void>
YuvStimProducer::stimFrameProductionTimesliceCInd(
sscl::SyncCancelerForAsyncWork& canceler)
{
(void)canceler;
throw std::logic_error(
"lcameraBuff: capture daemon not implemented in Stage 2");
co_return;
}
} // namespace lcamera_buff
} // namespace stim_buff
} // namespace smo