v4l2: v4l2_camera: Don't use libcamera::Semaphore for available buffers
In V4L2, a blocked dqbuf should not not also block a streamoff. This means that on streamoff, the blocked dqbuf must return (with error). We cannot do this with the libcamera semaphore, so pull out the necessary components of a semaphore, and put them into V4L2Camera, so that dqbuf from V4L2CameraProxy can wait on a disjunct condition of the availability of the semaphore or the stopping of the stream. Signed-off-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
f155e63816
commit
566ccd75ca
3 changed files with 47 additions and 7 deletions
|
@ -18,7 +18,7 @@ LOG_DECLARE_CATEGORY(V4L2Compat);
|
|||
|
||||
V4L2Camera::V4L2Camera(std::shared_ptr<Camera> camera)
|
||||
: camera_(camera), isRunning_(false), bufferAllocator_(nullptr),
|
||||
efd_(-1)
|
||||
efd_(-1), bufferAvailableCount_(0)
|
||||
{
|
||||
camera_->requestCompleted.connect(this, &V4L2Camera::requestComplete);
|
||||
}
|
||||
|
@ -100,7 +100,11 @@ void V4L2Camera::requestComplete(Request *request)
|
|||
if (ret != sizeof(data))
|
||||
LOG(V4L2Compat, Error) << "Failed to signal eventfd POLLIN";
|
||||
|
||||
bufferSema_.release();
|
||||
{
|
||||
MutexLocker locker(bufferMutex_);
|
||||
bufferAvailableCount_++;
|
||||
}
|
||||
bufferCV_.notify_all();
|
||||
}
|
||||
|
||||
int V4L2Camera::configure(StreamConfiguration *streamConfigOut,
|
||||
|
@ -192,7 +196,11 @@ int V4L2Camera::streamOff()
|
|||
if (ret < 0)
|
||||
return ret == -EACCES ? -EBUSY : ret;
|
||||
|
||||
isRunning_ = false;
|
||||
{
|
||||
MutexLocker locker(bufferMutex_);
|
||||
isRunning_ = false;
|
||||
}
|
||||
bufferCV_.notify_all();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -228,6 +236,26 @@ int V4L2Camera::qbuf(unsigned int index)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void V4L2Camera::waitForBufferAvailable()
|
||||
{
|
||||
MutexLocker locker(bufferMutex_);
|
||||
bufferCV_.wait(locker, [&] {
|
||||
return bufferAvailableCount_ >= 1 || !isRunning_;
|
||||
});
|
||||
if (isRunning_)
|
||||
bufferAvailableCount_--;
|
||||
}
|
||||
|
||||
bool V4L2Camera::isBufferAvailable()
|
||||
{
|
||||
MutexLocker locker(bufferMutex_);
|
||||
if (bufferAvailableCount_ < 1)
|
||||
return false;
|
||||
|
||||
bufferAvailableCount_--;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool V4L2Camera::isRunning()
|
||||
{
|
||||
return isRunning_;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue