pipeline: rpi: Rework internal buffer allocations
In order to clear the V4L2VideoDevice cache, we must call V4L2VideoDevice::releaseBuffers() when stopping the camera. To do this without releasing the allocated buffers, we have to rework the internal buffer allocation logic. Remove calls to V4L2VideoDevice::importBuffers() and releaseBuffers() from within the RPi::Stream class. Instead, move these calls to the PipelineHandlerBase class, where we can call releaseBuffers(), i.e. clear the V4L2VideoDevice cache unconditionally on stop without de-allocating the internal buffers. The code in Stream::clearBuffers() can be then moved into releaseBuffers() which will actually de-allocate the internal buffers when required. Closes: https://gitlab.freedesktop.org/camera/libcamera/-/issues/265 Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Tested-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com> # rpi4 Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Barnabás Pőcze <barnabas.pocze@ideasonboard.com>
This commit is contained in:
committed by
Barnabás Pőcze
parent
9bb64d2c8e
commit
d9d265cfce
@@ -719,8 +719,10 @@ void PipelineHandlerBase::stopDevice(Camera *camera)
|
||||
data->state_ = CameraData::State::Stopped;
|
||||
data->platformStop();
|
||||
|
||||
for (auto const stream : data->streams_)
|
||||
for (auto const stream : data->streams_) {
|
||||
stream->dev()->streamOff();
|
||||
stream->dev()->releaseBuffers();
|
||||
}
|
||||
|
||||
/* Disable SOF event generation. */
|
||||
data->frontendDevice()->setFrameStartEnabled(false);
|
||||
@@ -901,6 +903,10 @@ int PipelineHandlerBase::queueAllBuffers(Camera *camera)
|
||||
int ret;
|
||||
|
||||
for (auto const stream : data->streams_) {
|
||||
ret = stream->dev()->importBuffers(VIDEO_MAX_FRAME);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (stream->getFlags() & StreamFlag::External)
|
||||
continue;
|
||||
|
||||
|
||||
@@ -12,9 +12,6 @@
|
||||
|
||||
#include <libcamera/base/log.h>
|
||||
|
||||
/* Maximum number of buffer slots to allocate in the V4L2 device driver. */
|
||||
static constexpr unsigned int maxV4L2BufferCount = 32;
|
||||
|
||||
namespace libcamera {
|
||||
|
||||
LOG_DEFINE_CATEGORY(RPISTREAM)
|
||||
@@ -108,7 +105,7 @@ void Stream::setExportedBuffer(FrameBuffer *buffer)
|
||||
|
||||
int Stream::allocateBuffers(unsigned int count)
|
||||
{
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
if (!(flags_ & StreamFlag::ImportOnly)) {
|
||||
/* Export some frame buffers for internal use. */
|
||||
@@ -121,7 +118,7 @@ int Stream::allocateBuffers(unsigned int count)
|
||||
resetBuffers();
|
||||
}
|
||||
|
||||
return dev_->importBuffers(maxV4L2BufferCount);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Stream::queueBuffer(FrameBuffer *buffer)
|
||||
@@ -243,8 +240,11 @@ int Stream::queueAllBuffers()
|
||||
|
||||
void Stream::releaseBuffers()
|
||||
{
|
||||
dev_->releaseBuffers();
|
||||
clearBuffers();
|
||||
availableBuffers_ = std::queue<FrameBuffer *>{};
|
||||
requestBuffers_ = std::queue<FrameBuffer *>{};
|
||||
internalBuffers_.clear();
|
||||
bufferMap_.clear();
|
||||
id_ = 0;
|
||||
}
|
||||
|
||||
void Stream::bufferEmplace(unsigned int id, FrameBuffer *buffer)
|
||||
@@ -257,15 +257,6 @@ void Stream::bufferEmplace(unsigned int id, FrameBuffer *buffer)
|
||||
std::forward_as_tuple(buffer, false));
|
||||
}
|
||||
|
||||
void Stream::clearBuffers()
|
||||
{
|
||||
availableBuffers_ = std::queue<FrameBuffer *>{};
|
||||
requestBuffers_ = std::queue<FrameBuffer *>{};
|
||||
internalBuffers_.clear();
|
||||
bufferMap_.clear();
|
||||
id_ = 0;
|
||||
}
|
||||
|
||||
int Stream::queueToDevice(FrameBuffer *buffer)
|
||||
{
|
||||
LOG(RPISTREAM, Debug) << "Queuing buffer " << getBufferId(buffer)
|
||||
|
||||
@@ -140,7 +140,6 @@ public:
|
||||
|
||||
private:
|
||||
void bufferEmplace(unsigned int id, FrameBuffer *buffer);
|
||||
void clearBuffers();
|
||||
int queueToDevice(FrameBuffer *buffer);
|
||||
|
||||
StreamFlags flags_;
|
||||
|
||||
Reference in New Issue
Block a user