#include #include #include #include #include #include #include #include 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 generateCaptureConfiguration( const std::shared_ptr& camera) { std::unique_ptr 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 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& camera, const LcameraDevCameraModeRequest& request, std::shared_ptr& heldConfiguration) { if (!camera) { throw std::runtime_error( "lcameraDev: configureSessionModeCReq camera is null"); } std::unique_ptr config = generateCaptureConfiguration(camera); libcamera::StreamConfiguration& streamConfig = config->at(0); streamConfig.size = libcamera::Size(request.width, request.height); const std::vector pixelFormatCandidates = streamConfig.formats().pixelformats(); const std::optional selectedPixelFormat = selectYuvCaptureFormat(pixelFormatCandidates, false); 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