@@ -220,6 +220,7 @@ public:
int queueBuffer(FrameBuffer *buffer);
Signal<FrameBuffer *> bufferReady;
+ Signal<std::pair<FrameBuffer *, int>> requestBufferReady;
int streamOn();
int streamOff();
@@ -265,7 +266,7 @@ private:
UniqueFD exportDmabufFd(unsigned int index, unsigned int plane);
void bufferAvailable();
- FrameBuffer *dequeueBuffer();
+ std::pair<FrameBuffer *, int> dequeueBuffer();
void watchdogExpired();
@@ -1773,18 +1773,23 @@ int V4L2VideoDevice::queueBuffer(FrameBuffer *buffer)
*
* When this slot is called, a Buffer has become available from the device, and
* will be emitted through the bufferReady Signal.
+ * If the buffer is queued with a media Request, emit a requestBufferReady
+ * signal.
*
* For Capture video devices the FrameBuffer will contain valid data.
* For Output video devices the FrameBuffer can be considered empty.
*/
void V4L2VideoDevice::bufferAvailable()
{
- FrameBuffer *buffer = dequeueBuffer();
+ auto [buffer, mediaRequest] = dequeueBuffer();
if (!buffer)
return;
/* Notify anyone listening to the device. */
bufferReady.emit(buffer);
+
+ if (mediaRequest > 0)
+ requestBufferReady.emit({ buffer, mediaRequest });
}
/**
@@ -1793,9 +1798,12 @@ void V4L2VideoDevice::bufferAvailable()
* This function dequeues the next available buffer from the device. If no
* buffer is available to be dequeued it will return nullptr immediately.
*
- * \return A pointer to the dequeued buffer on success, or nullptr otherwise
+ * \return A pair where the first element is a pointer to the dequeued buffer
+ * on success, or nullptr otherwise. The second is the media request fd if
+ * applicable
+ *
*/
-FrameBuffer *V4L2VideoDevice::dequeueBuffer()
+std::pair<FrameBuffer *, int> V4L2VideoDevice::dequeueBuffer()
{
struct v4l2_buffer buf = {};
struct v4l2_plane planes[VIDEO_MAX_PLANES] = {};
@@ -1815,7 +1823,7 @@ FrameBuffer *V4L2VideoDevice::dequeueBuffer()
if (ret < 0) {
LOG(V4L2, Error)
<< "Failed to dequeue buffer: " << strerror(-ret);
- return nullptr;
+ return { nullptr, -1 };
}
LOG(V4L2, Debug) << "Dequeuing buffer " << buf.index;
@@ -1837,7 +1845,7 @@ FrameBuffer *V4L2VideoDevice::dequeueBuffer()
LOG(V4L2, Error)
<< "Dequeued unexpected buffer index " << buf.index;
- return nullptr;
+ return { nullptr, -1 };
}
cache_->put(buf.index);
@@ -1866,7 +1874,7 @@ FrameBuffer *V4L2VideoDevice::dequeueBuffer()
+ buf.timestamp.tv_usec * 1000ULL;
if (V4L2_TYPE_IS_OUTPUT(buf.type))
- return buffer;
+ return { buffer, buf.request_fd };
/*
* Detect kernel drivers which do not reset the sequence number to zero
@@ -1896,7 +1904,7 @@ FrameBuffer *V4L2VideoDevice::dequeueBuffer()
<< " != " << buffer->planes().size() << ")";
metadata.status = FrameMetadata::FrameError;
- return buffer;
+ return { buffer, buf.request_fd };
}
/*
@@ -1921,7 +1929,7 @@ FrameBuffer *V4L2VideoDevice::dequeueBuffer()
});
metadata.status = FrameMetadata::FrameError;
- return buffer;
+ return { buffer, buf.request_fd };
}
metadata.planes()[i].bytesused =
@@ -1940,7 +1948,7 @@ FrameBuffer *V4L2VideoDevice::dequeueBuffer()
metadata.planes()[0].bytesused = buf.bytesused;
}
- return buffer;
+ return { buffer, buf.request_fd };
}
/**
@@ -1948,6 +1956,12 @@ FrameBuffer *V4L2VideoDevice::dequeueBuffer()
* \brief A Signal emitted when a framebuffer completes
*/
+/**
+ * \var V4L2VideoDevice::requestBufferReady
+ * \brief A Signal emitted when a framebuffer completes, which includes both the
+ * frameBuffer and the media request fd.
+ */
+
/**
* \brief Start the video stream
* \return 0 on success or a negative error code otherwise
@@ -2012,6 +2026,7 @@ int V4L2VideoDevice::streamOff()
cache_->put(it.first);
metadata.status = FrameMetadata::FrameCancelled;
bufferReady.emit(buffer);
+ requestBufferReady.emit({ buffer, -1 });
}
ASSERT(cache_->isEmpty());