LCamDev: implement configureSessionModeCReq
We can, theoretically, now change the v4l camera's mode.
This commit is contained in:
+79
-8
@@ -36,8 +36,10 @@ Channel splitting, colourspace conversion, threshold masks, and stencils belong
|
||||
in a separate shared raster library (`rasterStimulus`, future) and in
|
||||
`lcameraBuff`; `lcameraDev` stops at selector resolution, `CameraManager`
|
||||
lifecycle, and a refcounted, **acquired** `libcamera::Camera` handle per
|
||||
resolved device. Stream negotiation, pixel-format selection, frame buffers,
|
||||
and capture timing belong in `lcameraBuff` (and supporting libraries), not here.
|
||||
resolved device. Session mode negotiation (width, height, colour-space,
|
||||
fully-planar YUV requirement) happens in `lcameraDev` before capture starts.
|
||||
Frame buffers, request queues, and capture timing belong in `lcameraBuff` (and
|
||||
supporting libraries), not here.
|
||||
|
||||
## Why libcamera (for now)
|
||||
|
||||
@@ -228,9 +230,39 @@ Rules:
|
||||
the same physical device from SMO’s perspective; channel differences come from
|
||||
the qualeIface name on each DAP line.
|
||||
|
||||
Streaming, frame delivery, and colourspace work are **out of scope** for
|
||||
`lcameraDev`; `lcameraBuff` uses the session’s acquired camera handle to set up
|
||||
capture on attach.
|
||||
## Session mode configuration (Stage 1)
|
||||
|
||||
Before `lcameraBuff` starts capture, each producer calls
|
||||
`lcameraDev_configureSessionModeCReq` on the shared `CameraSession` with the
|
||||
requested mode:
|
||||
|
||||
| Field | Role |
|
||||
|---|---|
|
||||
| `width` / `height` | Requested capture dimensions (non-zero) |
|
||||
| `colourSpace` | Semantic colour model (`Yuv` in v1) |
|
||||
| `fullPlanarIsOptional` | Default `false` — must select fully planar YUV |
|
||||
|
||||
`lcameraDev` chooses a concrete libcamera pixel format (e.g. YUV420) from the
|
||||
camera’s supported formats. DAPS lines name the semantic colour-space, not a
|
||||
raw fourcc.
|
||||
|
||||
Rules:
|
||||
|
||||
* Configure only while the session exists and capture has not started.
|
||||
* **Identical** configure request on an already-configured session is a **no-op**
|
||||
(multiple `lcameraBuff` producers sharing the same device selector each call
|
||||
get-or-create then configure with the same mode).
|
||||
* **Different** configure request on an already-configured session throws
|
||||
(conflicting mode requests on the same physical camera).
|
||||
* `fullPlanarIsOptional == false` (default): must select a fully planar YUV
|
||||
format or throw with candidate-format diagnostics.
|
||||
* `fullPlanarIsOptional == true`: rejected at the configure API until
|
||||
`lcameraBuff` implements non-planar producer deinterleaving (Stage 2). The
|
||||
policy helper still accepts optional planar selection for future use.
|
||||
|
||||
Streaming, frame delivery, and per-frame colourspace work remain **out of scope**
|
||||
for `lcameraDev`; `lcameraBuff` uses the configured session to allocate buffers
|
||||
and start capture on attach.
|
||||
|
||||
## dlopen API
|
||||
|
||||
@@ -273,8 +305,42 @@ typedef sscl::co::ViralNonPostingInvoker<void>
|
||||
|
||||
Failures throw `std::exception`. `lcameraBuff` holds the returned
|
||||
`shared_ptr<CameraSession>` and passes it back to `releaseDeviceCReq`. The
|
||||
session wraps the acquired `libcamera::Camera`; higher layers configure and
|
||||
stream from that handle — `lcameraDev` does not expose frame or stream APIs.
|
||||
session wraps the acquired `libcamera::Camera`; higher layers configure the mode
|
||||
then stream from that handle.
|
||||
|
||||
### Session mode configuration
|
||||
|
||||
```cpp
|
||||
enum class LcameraDevColourSpace { Yuv };
|
||||
|
||||
struct LcameraDevCameraModeRequest
|
||||
{
|
||||
unsigned width = 0;
|
||||
unsigned height = 0;
|
||||
LcameraDevColourSpace colourSpace = LcameraDevColourSpace::Yuv;
|
||||
bool fullPlanarIsOptional = false;
|
||||
};
|
||||
|
||||
struct LcameraDevConfiguredCameraMode
|
||||
{
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
LcameraDevColourSpace colourSpace;
|
||||
std::string pixelFormatName;
|
||||
bool isFullyPlanar;
|
||||
unsigned planeCount;
|
||||
};
|
||||
|
||||
typedef sscl::co::ViralNonPostingInvoker<LcameraDevConfiguredCameraMode>
|
||||
lcameraDev_configureSessionModeCReqFn(
|
||||
const std::shared_ptr<CameraSession>& deviceSession,
|
||||
const LcameraDevCameraModeRequest& request);
|
||||
```
|
||||
|
||||
`lcameraDev_configureSessionModeCReq` delegates to
|
||||
`CameraSession::configureSessionModeCReq`, which runs libcamera
|
||||
`generateConfiguration` + `configure` and stores the result on the session.
|
||||
Identical reconfigure is a no-op; conflicting reconfigure throws.
|
||||
|
||||
### Enumeration (discovery)
|
||||
|
||||
@@ -298,6 +364,10 @@ When built with `-DENABLE_LIB_lcameraDev=ON`:
|
||||
`ComponentThread`.
|
||||
* `lcameraDev_probe <deviceSelector>` — `getOrCreateDeviceCReq`, then
|
||||
`releaseDeviceCReq` (selector and session attach/detach only).
|
||||
* `lcameraDev_configure_probe <deviceSelector> <width> <height> [options]` —
|
||||
`getOrCreateDeviceCReq`, `configureSessionModeCReq`, print resolved mode (or
|
||||
exception), then `releaseDeviceCReq`. Options: `--colour-space=yuv`,
|
||||
`--opt-planar` / `--full-planar-is-optional`, `--reconfigure-twice`.
|
||||
|
||||
## Module layout
|
||||
|
||||
@@ -310,7 +380,8 @@ commonLibs/lcameraDev/
|
||||
cameraIdentity.h / .cpp Discovery identity records
|
||||
selectorParse.h / .cpp Compound selector parsing
|
||||
selectorResolve.h / .cpp AND-match resolution
|
||||
tools/ lcameraDev_list_cameras, lcameraDev_probe
|
||||
tools/ lcameraDev_list_cameras, lcameraDev_probe,
|
||||
lcameraDev_configure_probe
|
||||
```
|
||||
|
||||
Build links against `libcamera` (pkg-config). Does **not** link Salmanoff
|
||||
|
||||
Reference in New Issue
Block a user