Files
salmanoff/commonLibs/lcameraDev/sessionModeConfigure.cpp
T
hayodea 7a47f2bd49 lcameraDev: honor opt-planar when selecting YUV capture format.
Pass fullPlanarIsOptional through session configure so optional planar
mode can succeed with packed YUYV; extend unit and configure HIL coverage.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-14 11:01:40 -04:00

146 lines
4.1 KiB
C++

#include <boostAsioLinkageFix.h>
#include <cameraModeRequest.h>
#include <planarYuvFormatPolicy.h>
#include <sessionModeConfigure.h>
#include <libcamera/camera.h>
#include <libcamera/stream.h>
#include <stdexcept>
#include <utility>
namespace lcamera_dev {
namespace {
LcameraDevConfiguredCameraMode buildConfiguredModeFromStreamConfig(
const LcameraDevCameraModeRequest& request,
const libcamera::StreamConfiguration& streamConfig)
{
LcameraDevConfiguredCameraMode configuredMode;
configuredMode.width = streamConfig.size.width;
configuredMode.height = streamConfig.size.height;
configuredMode.colourSpace = request.colourSpace;
configuredMode.pixelFormatName = streamConfig.pixelFormat.toString();
configuredMode.isFullyPlanar =
isFullyPlanarYuv(streamConfig.pixelFormat);
configuredMode.planeCount =
yuvCapturePlaneCount(streamConfig.pixelFormat);
return configuredMode;
}
std::unique_ptr<libcamera::CameraConfiguration> generateCaptureConfiguration(
const std::shared_ptr<libcamera::Camera>& camera)
{
std::unique_ptr<libcamera::CameraConfiguration> config =
camera->generateConfiguration(
{libcamera::StreamRole::VideoRecording});
if (!config || config->empty())
{
config = camera->generateConfiguration(
{libcamera::StreamRole::Viewfinder});
}
if (!config || config->empty())
{
throw std::runtime_error(
"lcameraDev: camera does not support VideoRecording or "
"Viewfinder stream roles");
}
return config;
}
void validateConfigurationStatus(
libcamera::CameraConfiguration::Status status,
const std::string& cameraId)
{
if (status == libcamera::CameraConfiguration::Valid
|| status == libcamera::CameraConfiguration::Adjusted)
{
return;
}
throw std::runtime_error(
"lcameraDev: libcamera configuration invalid for camera "
+ cameraId);
}
} // namespace
ConfigureSessionModeStatus applyModeRequestToSessionState(
CameraSessionResources& resources,
const LcameraDevCameraModeRequest& request,
const LcameraDevConfiguredCameraMode& resolvedMode,
std::shared_ptr<libcamera::CameraConfiguration> heldConfiguration)
{
if (resources.configuredMode.has_value())
{
if (cameraModeRequestsEqual(resources.configuredRequest, request)) {
return ConfigureSessionModeStatus::NoOpAlreadyConfigured;
}
throw std::runtime_error(
"lcameraDev: conflicting camera mode request on configured "
"session");
}
resources.configuredRequest = request;
resources.configuredMode = resolvedMode;
resources.heldConfiguration = heldConfiguration;
++resources.libcameraConfigureCallCount;
return ConfigureSessionModeStatus::Configured;
}
LcameraDevConfiguredCameraMode configureLibcameraSessionMode(
const std::shared_ptr<libcamera::Camera>& camera,
const LcameraDevCameraModeRequest& request,
std::shared_ptr<libcamera::CameraConfiguration>& heldConfiguration)
{
if (!camera)
{
throw std::runtime_error(
"lcameraDev: configureSessionModeCReq camera is null");
}
std::unique_ptr<libcamera::CameraConfiguration> config =
generateCaptureConfiguration(camera);
libcamera::StreamConfiguration& streamConfig = config->at(0);
streamConfig.size = libcamera::Size(request.width, request.height);
const std::vector<libcamera::PixelFormat> pixelFormatCandidates =
streamConfig.formats().pixelformats();
const std::optional<libcamera::PixelFormat> selectedPixelFormat =
selectYuvCaptureFormat(
pixelFormatCandidates,
request.fullPlanarIsOptional);
if (!selectedPixelFormat.has_value())
{
throw std::runtime_error(
"lcameraDev: failed to select YUV capture format");
}
streamConfig.pixelFormat = *selectedPixelFormat;
const libcamera::CameraConfiguration::Status validateStatus =
config->validate();
validateConfigurationStatus(validateStatus, camera->id());
const int configureRc = camera->configure(config.get());
if (configureRc != 0)
{
throw std::runtime_error(
"lcameraDev: libcamera configure failed for camera "
+ camera->id());
}
const LcameraDevConfiguredCameraMode configuredMode =
buildConfiguredModeFromStreamConfig(request, streamConfig);
heldConfiguration = std::move(config);
return configuredMode;
}
} // namespace lcamera_dev