@@ -182,6 +182,7 @@ public:
std::vector<std::unique_ptr<FrameBuffer>> converterBuffers_;
bool useConverter_;
std::queue<std::map<unsigned int, FrameBuffer *>> converterQueue_;
+ Fraction frameInterval_;
};
class SimpleCameraConfiguration : public CameraConfiguration
@@ -458,6 +459,7 @@ int SimpleCameraData::setupFormats(V4L2SubdeviceFormat *format,
V4L2Subdevice::Whence whence)
{
SimplePipelineHandler *pipe = static_cast<SimplePipelineHandler *>(pipe_);
+ Fraction frameInterval;
int ret;
/*
@@ -478,6 +480,14 @@ int SimpleCameraData::setupFormats(V4L2SubdeviceFormat *format,
ret = subdev->getFormat(source->index(), format, whence);
if (ret < 0)
return ret;
+ } else {
+ V4L2Subdevice *subdev = pipe->subdev(source->entity());
+ ret = subdev->getFrameInterval(source->index(), &frameInterval);
+ if (ret < 0)
+ LOG(SimplePipeline, Debug) << "Getting frame interval from sensor failed";
+ else
+ LOG(SimplePipeline, Debug) << "Sensor frame interval: "
+ << frameInterval.toString();
}
if (sink->entity()->function() != MEDIA_ENT_F_IO_V4L) {
@@ -488,6 +498,18 @@ int SimpleCameraData::setupFormats(V4L2SubdeviceFormat *format,
if (ret < 0)
return ret;
+ /* set frameinterval on all subdevs if we got one from the sensor */
+ if (frameInterval.numerator != 0 && frameInterval.denominator != 0) {
+ ret = subdev->setFrameInterval(sink->index(), &frameInterval);
+ if (ret == 0) {
+ LOG(SimplePipeline, Debug) << "Set frame interval: "
+ << frameInterval.toString();
+ /* Always remember the last frame interval we successfully
+ * set, as this determines the final frame interval at the end */
+ frameInterval_ = frameInterval;
+ }
+ }
+
if (format->mbus_code != sourceFormat.mbus_code ||
format->size != sourceFormat.size) {
LOG(SimplePipeline, Debug)
@@ -668,6 +690,7 @@ CameraConfiguration *SimplePipelineHandler::generateConfiguration(Camera *camera
StreamConfiguration cfg{ StreamFormats{ formats } };
cfg.pixelFormat = formats.begin()->first;
cfg.size = formats.begin()->second[0].max;
+ cfg.frameInterval = data->frameInterval_;
config->addConfiguration(cfg);
}
By propagating the frame interval from the sensor to the camera interface, userspace applications can query the frame interval there. This is useful for example with the gstreamer libcamerasrc, which can integrate this information into the Gstreamer pipeline, which is a valuable information for other elements. Signed-off-by: Marian Cichy <m.cichy@pengutronix.de> --- src/libcamera/pipeline/simple/simple.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)