mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-29 13:11:06 +00:00
v4l2: bufferpool: Drop writable check on output pool process
Output buffers don't have to be writable. Accepting read-only buffers from the V4L2 buffer pool allows upstream elements to write directly into the V4L2 buffers without triggering a CPU copy into a new buffer from the same V4L2 buffer pool every time. Tested with the vivid output device: GST_DEBUG=GST_PERFORMANCE:7 gst-launch-1.0 videotestsrc ! v4l2sink device=/dev/video5 With this change, gst_v4l2_buffer_pool_dqbuf() must be allowed to not resize read-only memories of output buffers. Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/6648>
This commit is contained in:
parent
ebd27cb2d2
commit
7ae6c203cb
1 changed files with 25 additions and 20 deletions
|
@ -84,7 +84,8 @@ static void gst_v4l2_buffer_pool_complete_release_buffer (GstBufferPool * bpool,
|
|||
GstBuffer * buffer, gboolean queued);
|
||||
|
||||
static gboolean
|
||||
gst_v4l2_is_buffer_valid (GstBuffer * buffer, GstV4l2MemoryGroup ** out_group)
|
||||
gst_v4l2_is_buffer_valid (GstBuffer * buffer, GstV4l2MemoryGroup ** out_group,
|
||||
gboolean check_writable)
|
||||
{
|
||||
GstMemory *mem = gst_buffer_peek_memory (buffer, 0);
|
||||
gboolean valid = FALSE;
|
||||
|
@ -108,7 +109,7 @@ gst_v4l2_is_buffer_valid (GstBuffer * buffer, GstV4l2MemoryGroup ** out_group)
|
|||
if (group->mem[i] != gst_buffer_peek_memory (buffer, i))
|
||||
goto done;
|
||||
|
||||
if (!gst_memory_is_writable (group->mem[i]))
|
||||
if (check_writable && !gst_memory_is_writable (group->mem[i]))
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -127,7 +128,7 @@ gst_v4l2_buffer_pool_resize_buffer (GstBufferPool * bpool, GstBuffer * buffer)
|
|||
GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool);
|
||||
GstV4l2MemoryGroup *group;
|
||||
|
||||
if (gst_v4l2_is_buffer_valid (buffer, &group)) {
|
||||
if (gst_v4l2_is_buffer_valid (buffer, &group, TRUE)) {
|
||||
gst_v4l2_allocator_reset_group (pool->vallocator, group);
|
||||
} else {
|
||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
|
||||
|
@ -238,7 +239,7 @@ gst_v4l2_buffer_pool_import_userptr (GstV4l2BufferPool * pool,
|
|||
GST_LOG_OBJECT (pool, "importing userptr");
|
||||
|
||||
/* get the group */
|
||||
if (!gst_v4l2_is_buffer_valid (dest, &group))
|
||||
if (!gst_v4l2_is_buffer_valid (dest, &group, TRUE))
|
||||
goto not_our_buffer;
|
||||
|
||||
if (V4L2_TYPE_IS_OUTPUT (pool->obj->type))
|
||||
|
@ -355,7 +356,7 @@ gst_v4l2_buffer_pool_import_dmabuf (GstV4l2BufferPool * pool,
|
|||
|
||||
GST_LOG_OBJECT (pool, "importing dmabuf");
|
||||
|
||||
if (!gst_v4l2_is_buffer_valid (dest, &group))
|
||||
if (!gst_v4l2_is_buffer_valid (dest, &group, TRUE))
|
||||
goto not_our_buffer;
|
||||
|
||||
if (n_mem > GST_VIDEO_MAX_PLANES)
|
||||
|
@ -1312,6 +1313,8 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
|
|||
if (GST_VIDEO_INFO_FORMAT (&pool->caps_info) == GST_VIDEO_FORMAT_ENCODED)
|
||||
break;
|
||||
|
||||
if (obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE ||
|
||||
obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
|
||||
/* Ensure our offset matches the expected plane size, or image size if
|
||||
* there is only one memory */
|
||||
if (group->n_mem == 1) {
|
||||
|
@ -1322,6 +1325,7 @@ gst_v4l2_buffer_pool_dqbuf (GstV4l2BufferPool * pool, GstBuffer ** buffer,
|
|||
if (!GST_VIDEO_FORMAT_INFO_IS_TILED (finfo))
|
||||
gst_memory_resize (group->mem[i], 0, obj->plane_size[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Ignore timestamp and field for OUTPUT device */
|
||||
if (V4L2_TYPE_IS_OUTPUT (obj->type))
|
||||
|
@ -1520,7 +1524,7 @@ done:
|
|||
/* Mark buffer as outstanding */
|
||||
if (ret == GST_FLOW_OK) {
|
||||
GstV4l2MemoryGroup *group;
|
||||
if (gst_v4l2_is_buffer_valid (*buffer, &group)) {
|
||||
if (gst_v4l2_is_buffer_valid (*buffer, &group, TRUE)) {
|
||||
GST_LOG_OBJECT (pool, "mark buffer %u outstanding", group->buffer.index);
|
||||
g_atomic_int_or (&pool->buffer_state[group->buffer.index],
|
||||
BUFFER_STATE_OUTSTANDING);
|
||||
|
@ -1571,7 +1575,7 @@ gst_v4l2_buffer_pool_complete_release_buffer (GstBufferPool * bpool,
|
|||
case GST_V4L2_IO_DMABUF_IMPORT:
|
||||
{
|
||||
GstV4l2MemoryGroup *group;
|
||||
if (gst_v4l2_is_buffer_valid (buffer, &group)) {
|
||||
if (gst_v4l2_is_buffer_valid (buffer, &group, TRUE)) {
|
||||
GstFlowReturn ret = GST_FLOW_OK;
|
||||
|
||||
gst_v4l2_allocator_reset_group (pool->vallocator, group);
|
||||
|
@ -1612,7 +1616,7 @@ gst_v4l2_buffer_pool_complete_release_buffer (GstBufferPool * bpool,
|
|||
GstV4l2MemoryGroup *group;
|
||||
guint index;
|
||||
|
||||
if (!gst_v4l2_is_buffer_valid (buffer, &group)) {
|
||||
if (!gst_v4l2_is_buffer_valid (buffer, &group, TRUE)) {
|
||||
/* Simply release invalid/modified buffer, the allocator will
|
||||
* give it back later */
|
||||
GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY);
|
||||
|
@ -1663,7 +1667,7 @@ gst_v4l2_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer)
|
|||
GstV4l2MemoryGroup *group;
|
||||
gboolean queued = FALSE;
|
||||
|
||||
if (gst_v4l2_is_buffer_valid (buffer, &group)) {
|
||||
if (gst_v4l2_is_buffer_valid (buffer, &group, TRUE)) {
|
||||
gint old_buffer_state =
|
||||
g_atomic_int_and (&pool->buffer_state[group->buffer.index],
|
||||
~BUFFER_STATE_OUTSTANDING);
|
||||
|
@ -2065,7 +2069,8 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf,
|
|||
if ((*buf)->pool != bpool)
|
||||
goto copying;
|
||||
|
||||
if (!gst_v4l2_is_buffer_valid (*buf, &group))
|
||||
/* Output buffers don't have to be writable */
|
||||
if (!gst_v4l2_is_buffer_valid (*buf, &group, FALSE))
|
||||
goto copying;
|
||||
|
||||
index = group->buffer.index;
|
||||
|
@ -2102,7 +2107,7 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf,
|
|||
}
|
||||
|
||||
/* retrieve the group */
|
||||
gst_v4l2_is_buffer_valid (to_queue, &group);
|
||||
gst_v4l2_is_buffer_valid (to_queue, &group, TRUE);
|
||||
}
|
||||
|
||||
if ((ret =
|
||||
|
@ -2115,7 +2120,7 @@ gst_v4l2_buffer_pool_process (GstV4l2BufferPool * pool, GstBuffer ** buf,
|
|||
* streaming now */
|
||||
if (!gst_v4l2_buffer_pool_streamon (pool)) {
|
||||
/* don't check return value because qbuf would have failed */
|
||||
gst_v4l2_is_buffer_valid (to_queue, &group);
|
||||
gst_v4l2_is_buffer_valid (to_queue, &group, TRUE);
|
||||
|
||||
/* qbuf has stored to_queue buffer but we are not in
|
||||
* streaming state, so the flush logic won't be performed.
|
||||
|
|
Loading…
Reference in a new issue