void gst_v4l2_allocator_flush (GstV4l2Allocator * allocator) { gint i; GST_OBJECT_LOCK (allocator); if (!g_atomic_int_get (&allocator->active)) goto done; for (i = 0; i < allocator->count; i++) { GstV4l2MemoryGroup *group = allocator->groups[i]; gint n; if (IS_QUEUED (group->buffer)) { UNSET_QUEUED (group->buffer); gst_v4l2_allocator_reset_group (allocator, group); for (n = 0; n < group->n_mem; n++) gst_memory_unref (group->mem[n]); } } done: GST_OBJECT_UNLOCK (allocator); }
static void gst_v4l2_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer) { GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool); GstBufferPoolClass *pclass = GST_BUFFER_POOL_CLASS (parent_class); GstV4l2Object *obj = pool->obj; GST_DEBUG_OBJECT (pool, "release buffer %p", buffer); switch (obj->type) { case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE: /* capture, put the buffer back in the queue so that we can refill it * later. */ switch (obj->mode) { case GST_V4L2_IO_RW: /* release back in the pool */ pclass->release_buffer (bpool, buffer); break; case GST_V4L2_IO_DMABUF: case GST_V4L2_IO_MMAP: case GST_V4L2_IO_USERPTR: case GST_V4L2_IO_DMABUF_IMPORT: { if (gst_v4l2_is_buffer_valid (buffer, NULL)) { /* queue back in the device */ if (pool->other_pool) gst_v4l2_buffer_pool_prepare_buffer (pool, buffer, NULL); if (gst_v4l2_buffer_pool_qbuf (pool, buffer) != GST_FLOW_OK) pclass->release_buffer (bpool, buffer); } else { /* Simply release invalide/modified buffer, the allocator will * give it back later */ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY); pclass->release_buffer (bpool, buffer); } break; } default: g_assert_not_reached (); break; } break; case V4L2_BUF_TYPE_VIDEO_OUTPUT: case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE: switch (obj->mode) { case GST_V4L2_IO_RW: /* release back in the pool */ pclass->release_buffer (bpool, buffer); break; case GST_V4L2_IO_MMAP: case GST_V4L2_IO_DMABUF: case GST_V4L2_IO_USERPTR: case GST_V4L2_IO_DMABUF_IMPORT: { GstV4l2MemoryGroup *group; guint index; if (!gst_v4l2_is_buffer_valid (buffer, &group)) { /* Simply release invalide/modified buffer, the allocator will * give it back later */ GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY); pclass->release_buffer (bpool, buffer); break; } index = group->buffer.index; if (pool->buffers[index] == NULL) { GST_LOG_OBJECT (pool, "buffer %u not queued, putting on free list", index); /* Remove qdata, this will unmap any map data in userptr */ gst_mini_object_set_qdata (GST_MINI_OBJECT (buffer), GST_V4L2_IMPORT_QUARK, NULL, NULL); /* reset to default size */ gst_v4l2_allocator_reset_group (pool->vallocator, group); /* playback, put the buffer back in the queue to refill later. */ pclass->release_buffer (bpool, buffer); } else { /* We keep a ref on queued buffer, so this should never happen */ g_assert_not_reached (); } break; } default: g_assert_not_reached (); break; } break; default: g_assert_not_reached (); break; } }