v4l2bufferpool: queue back the buffer flagged LAST but empty

Some decoder drivers need to wait enough capture buffers before
starting to decode. But the dequeued buffer flag LAST but empty
has no chance to queue back to driver, which makes decode hang
after seek. So need to queue back such kind of buffer to driver.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6579>
This commit is contained in:
Hou Qi 2024-04-09 11:29:46 +09:00 committed by GStreamer Marge Bot
parent e1f5bacf8d
commit 105d232fde

View file

@ -1238,6 +1238,7 @@ static GstFlowReturn
gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer, gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
gboolean * outstanding, gboolean wait) gboolean * outstanding, gboolean wait)
{ {
GstBufferPool *bpool = GST_BUFFER_POOL_CAST (pool);
GstFlowReturn res; GstFlowReturn res;
GstBuffer *outbuf = NULL; GstBuffer *outbuf = NULL;
GstV4l2Object *obj = pool->obj; GstV4l2Object *obj = pool->obj;
@ -1281,12 +1282,6 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
group->buffer.index); group->buffer.index);
} }
if (group->buffer.flags & V4L2_BUF_FLAG_LAST &&
group->planes[0].bytesused == 0) {
GST_DEBUG_OBJECT (pool, "Empty last buffer, signalling eos.");
goto eos;
}
outbuf = pool->buffers[group->buffer.index]; outbuf = pool->buffers[group->buffer.index];
if (outbuf == NULL) if (outbuf == NULL)
goto no_buffer; goto no_buffer;
@ -1298,6 +1293,16 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
GST_OBJECT_UNLOCK (pool); GST_OBJECT_UNLOCK (pool);
} }
if (group->buffer.flags & V4L2_BUF_FLAG_LAST &&
group->planes[0].bytesused == 0) {
GST_DEBUG_OBJECT (pool, "Empty last buffer, signalling eos.");
*buffer = outbuf;
outbuf = NULL;
gst_buffer_ref (*buffer);
gst_v4l2_buffer_pool_complete_release_buffer (bpool, *buffer, FALSE);
goto eos;
}
timestamp = GST_TIMEVAL_TO_TIME (group->buffer.timestamp); timestamp = GST_TIMEVAL_TO_TIME (group->buffer.timestamp);
for (i = 0; i < group->n_mem; i++) { for (i = 0; i < group->n_mem; i++) {