@@ -792,6 +792,24 @@ controls:
\todo Define how the sensor timestamp has to be used in the reprocessing
use case.
+ - SensorSequence:
+ type: int64_t
+ direction: out
+ description: |
+ The monotonic sequence number from the sensor capture device.
+
+ Pipeline handlers populate this metadata control with the sequence
+ number reported by the sensor-facing capture device (for example the
+ CSI-2 receiver or V4L2 video node). Any break in this sequence number
+ indicates that frames were dropped or not captured before the previous
+ request completed.
+
+ While per-buffer FrameMetadata::sequence identifies frames in each
+ completed stream, SensorSequence reflects the sensor-side capture path
+ and is intended for diagnosing frame continuity.
+
+ The SensorSequence control can only be returned in metadata.
+
- AfMode:
type: int32_t
direction: inout
@@ -1130,6 +1130,9 @@ void PipelineHandlerISI::bufferReady(FrameBuffer *buffer)
if (!metadata.contains(controls::SensorTimestamp.id()))
metadata.set(controls::SensorTimestamp,
buffer->metadata().timestamp);
+ if (!metadata.contains(controls::SensorSequence.id()))
+ metadata.set(controls::SensorSequence,
+ static_cast<int64_t>(buffer->metadata().sequence));
if (completeBuffer(request, buffer))
completeRequest(request);
@@ -1317,6 +1317,8 @@ void IPU3CameraData::cio2BufferReady(FrameBuffer *buffer)
*/
request->_d()->metadata().set(controls::SensorTimestamp,
buffer->metadata().timestamp);
+ request->_d()->metadata().set(controls::SensorSequence,
+ static_cast<int64_t>(buffer->metadata().sequence));
info->effectiveSensorControls = delayedCtrls_->get(buffer->metadata().sequence);
@@ -1704,6 +1704,8 @@ void PipelineHandlerMaliC55::cruBufferReady(FrameBuffer *buffer)
Request *request = info->request;
request->_d()->metadata().set(controls::SensorTimestamp,
buffer->metadata().timestamp);
+ request->_d()->metadata().set(controls::SensorSequence,
+ static_cast<int64_t>(buffer->metadata().sequence));
MaliC55CameraData *data = cameraData(request->_d()->camera());
data->ipa_->fillParams(request->sequence(), info->paramBuffer->cookie());
@@ -1647,6 +1647,8 @@ void PipelineHandlerRkISP1::imageBufferReady(FrameBuffer *buffer)
*/
request->_d()->metadata().set(controls::SensorTimestamp,
metadata.timestamp);
+ request->_d()->metadata().set(controls::SensorSequence,
+ static_cast<int64_t>(metadata.sequence));
if (isRaw_) {
const ControlList &ctrls =
@@ -1514,6 +1514,8 @@ void CameraData::fillRequestMetadata(const ControlList &bufferControls, Request
{
if (auto x = bufferControls.get(controls::SensorTimestamp))
request->_d()->metadata().set(controls::SensorTimestamp, *x);
+ if (auto x = bufferControls.get(controls::SensorSequence))
+ request->_d()->metadata().set(controls::SensorSequence, *x);
if (auto x = bufferControls.get(controls::FrameWallClock))
request->_d()->metadata().set(controls::FrameWallClock, *x);
@@ -1766,6 +1766,8 @@ void PiSPCameraData::cfeBufferDequeue(FrameBuffer *buffer)
ctrl.set(controls::SensorTimestamp, sensorTimestamp);
ctrl.set(controls::FrameWallClock, wallClockTimestamp);
+ ctrl.set(controls::SensorSequence,
+ static_cast<int64_t>(buffer->metadata().sequence));
job.sensorControls = std::move(ctrl);
job.delayContext = delayContext;
} else if (stream == &cfe_[Cfe::Config]) {
@@ -787,6 +787,8 @@ void Vc4CameraData::unicamBufferDequeue(FrameBuffer *buffer)
ctrl.set(controls::SensorTimestamp, sensorTimestamp);
ctrl.set(controls::FrameWallClock, wallClockTimestamp);
+ ctrl.set(controls::SensorSequence,
+ static_cast<int64_t>(buffer->metadata().sequence));
bayerQueue_.push({ buffer, std::move(ctrl), delayContext });
} else {
embeddedQueue_.push(buffer);
@@ -939,9 +939,12 @@ void SimpleCameraData::imageBufferReady(FrameBuffer *buffer)
}
}
- if (request)
+ if (request) {
request->_d()->metadata().set(controls::SensorTimestamp,
buffer->metadata().timestamp);
+ request->_d()->metadata().set(controls::SensorSequence,
+ static_cast<int64_t>(buffer->metadata().sequence));
+ }
/*
* Queue the captured and the request buffer to the converter or Software
@@ -897,6 +897,8 @@ void UVCCameraData::imageBufferReady(FrameBuffer *buffer)
/* \todo Use the UVC metadata to calculate a more precise timestamp */
request->_d()->metadata().set(controls::SensorTimestamp,
buffer->metadata().timestamp);
+ request->_d()->metadata().set(controls::SensorSequence,
+ static_cast<int64_t>(buffer->metadata().sequence));
pipe()->completeBuffer(request, buffer);
pipe()->completeRequest(request);
@@ -617,6 +617,8 @@ void VimcCameraData::imageBufferReady(FrameBuffer *buffer)
/* Record the sensor's timestamp in the request metadata. */
request->_d()->metadata().set(controls::SensorTimestamp,
buffer->metadata().timestamp);
+ request->_d()->metadata().set(controls::SensorSequence,
+ static_cast<int64_t>(buffer->metadata().sequence));
pipe->completeBuffer(request, buffer);
pipe->completeRequest(request);
Add controls::SensorSequence (int64_t, out) to report the monotonic sequence number from the sensor-facing capture device in request metadata. Populate the control in all pipeline handlers that already report SensorTimestamp. Signed-off-by: Bruce Allen <ballen4705@googlemail.com> --- src/libcamera/control_ids_core.yaml | 18 ++++++++++++++++++ src/libcamera/pipeline/imx8-isi/imx8-isi.cpp | 3 +++ src/libcamera/pipeline/ipu3/ipu3.cpp | 2 ++ src/libcamera/pipeline/mali-c55/mali-c55.cpp | 2 ++ src/libcamera/pipeline/rkisp1/rkisp1.cpp | 2 ++ src/libcamera/pipeline/rpi/common/pipeline_base.cpp | 2 ++ src/libcamera/pipeline/rpi/pisp/pisp.cpp | 2 ++ src/libcamera/pipeline/rpi/vc4/vc4.cpp | 2 ++ src/libcamera/pipeline/simple/simple.cpp | 5 ++++- src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 2 ++ src/libcamera/pipeline/vimc/vimc.cpp | 2 ++ 11 files changed, 41 insertions(+), 1 deletion(-)