pipeline: raspberrypi: Add a Unicam dequeue timeout
Enable the V4L2VideoDevice dequeue timeout for the Unicam Image node, and connect the timeout signal to a slot in the pipeline handler. This slot will log an error message informing the user of a possible hardware stall. The timeout is calculated as 2x the maximum frame length possible for a given mode, returned by the IPA. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
16f3d2de50
commit
04faa8477a
3 changed files with 22 additions and 0 deletions
|
@ -41,6 +41,7 @@ struct IPAConfig {
|
||||||
struct StartConfig {
|
struct StartConfig {
|
||||||
libcamera.ControlList controls;
|
libcamera.ControlList controls;
|
||||||
int32 dropFrameCount;
|
int32 dropFrameCount;
|
||||||
|
uint32 maxSensorFrameLengthMs;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IPARPiInterface {
|
interface IPARPiInterface {
|
||||||
|
|
|
@ -280,6 +280,8 @@ void IPARPi::start(const ControlList &controls, ipa::RPi::StartConfig *startConf
|
||||||
}
|
}
|
||||||
|
|
||||||
startConfig->dropFrameCount = dropFrameCount_;
|
startConfig->dropFrameCount = dropFrameCount_;
|
||||||
|
const Duration maxSensorFrameDuration = mode_.max_frame_length * mode_.line_length;
|
||||||
|
startConfig->maxSensorFrameLengthMs = maxSensorFrameDuration.get<std::milli>();
|
||||||
|
|
||||||
firstStart_ = false;
|
firstStart_ = false;
|
||||||
lastRunTimestamp_ = 0;
|
lastRunTimestamp_ = 0;
|
||||||
|
|
|
@ -45,6 +45,8 @@
|
||||||
#include "dma_heaps.h"
|
#include "dma_heaps.h"
|
||||||
#include "rpi_stream.h"
|
#include "rpi_stream.h"
|
||||||
|
|
||||||
|
using namespace std::chrono_literals;
|
||||||
|
|
||||||
namespace libcamera {
|
namespace libcamera {
|
||||||
|
|
||||||
LOG_DEFINE_CATEGORY(RPI)
|
LOG_DEFINE_CATEGORY(RPI)
|
||||||
|
@ -208,6 +210,7 @@ public:
|
||||||
void setIspControls(const ControlList &controls);
|
void setIspControls(const ControlList &controls);
|
||||||
void setDelayedControls(const ControlList &controls);
|
void setDelayedControls(const ControlList &controls);
|
||||||
void setSensorControls(ControlList &controls);
|
void setSensorControls(ControlList &controls);
|
||||||
|
void unicamTimeout();
|
||||||
|
|
||||||
/* bufferComplete signal handlers. */
|
/* bufferComplete signal handlers. */
|
||||||
void unicamBufferDequeue(FrameBuffer *buffer);
|
void unicamBufferDequeue(FrameBuffer *buffer);
|
||||||
|
@ -1050,6 +1053,14 @@ int PipelineHandlerRPi::start(Camera *camera, const ControlList *controls)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set the dequeue timeout to the larger of 2x the maximum possible
|
||||||
|
* frame duration or 1 second.
|
||||||
|
*/
|
||||||
|
utils::Duration timeout =
|
||||||
|
std::max<utils::Duration>(1s, 2 * startConfig.maxSensorFrameLengthMs * 1ms);
|
||||||
|
data->unicam_[Unicam::Image].dev()->setDequeueTimeout(timeout);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1192,6 +1203,7 @@ int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp, Me
|
||||||
data->isp_[Isp::Stats] = RPi::Stream("ISP Stats", ispCapture3);
|
data->isp_[Isp::Stats] = RPi::Stream("ISP Stats", ispCapture3);
|
||||||
|
|
||||||
/* Wire up all the buffer connections. */
|
/* Wire up all the buffer connections. */
|
||||||
|
data->unicam_[Unicam::Image].dev()->dequeueTimeout.connect(data.get(), &RPiCameraData::unicamTimeout);
|
||||||
data->unicam_[Unicam::Image].dev()->frameStart.connect(data.get(), &RPiCameraData::frameStarted);
|
data->unicam_[Unicam::Image].dev()->frameStart.connect(data.get(), &RPiCameraData::frameStarted);
|
||||||
data->unicam_[Unicam::Image].dev()->bufferReady.connect(data.get(), &RPiCameraData::unicamBufferDequeue);
|
data->unicam_[Unicam::Image].dev()->bufferReady.connect(data.get(), &RPiCameraData::unicamBufferDequeue);
|
||||||
data->isp_[Isp::Input].dev()->bufferReady.connect(data.get(), &RPiCameraData::ispInputDequeue);
|
data->isp_[Isp::Input].dev()->bufferReady.connect(data.get(), &RPiCameraData::ispInputDequeue);
|
||||||
|
@ -1773,6 +1785,13 @@ void RPiCameraData::setSensorControls(ControlList &controls)
|
||||||
sensor_->setControls(&controls);
|
sensor_->setControls(&controls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RPiCameraData::unicamTimeout()
|
||||||
|
{
|
||||||
|
LOG(RPI, Error) << "Unicam has timed out!";
|
||||||
|
LOG(RPI, Error) << "Please check that your camera sensor connector is attached securely.";
|
||||||
|
LOG(RPI, Error) << "Alternatively, try another cable and/or sensor.";
|
||||||
|
}
|
||||||
|
|
||||||
void RPiCameraData::unicamBufferDequeue(FrameBuffer *buffer)
|
void RPiCameraData::unicamBufferDequeue(FrameBuffer *buffer)
|
||||||
{
|
{
|
||||||
RPi::Stream *stream = nullptr;
|
RPi::Stream *stream = nullptr;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue