/** * gst_buffer_copy_metadata: * @dest: a destination #GstBuffer * @src: a source #GstBuffer * @flags: flags indicating what metadata fields should be copied. * * Copies the metadata from @src into @dest. The data, size and mallocdata * fields are not copied. * * @flags indicate which fields will be copied. Use #GST_BUFFER_COPY_ALL to copy * all the metadata fields. * * This function is typically called from a custom buffer copy function after * creating @dest and setting the data, size, mallocdata. * * Since: 0.10.13 */ void gst_buffer_copy_metadata (GstBuffer * dest, const GstBuffer * src, GstBufferCopyFlags flags) { g_return_if_fail (dest != NULL); g_return_if_fail (src != NULL); GST_CAT_LOG (GST_CAT_BUFFER, "copy %p to %p", src, dest); if (flags & GST_BUFFER_COPY_FLAGS) { guint mask; /* copy relevant flags */ mask = GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS | GST_BUFFER_FLAG_DELTA_UNIT | GST_BUFFER_FLAG_DISCONT | GST_BUFFER_FLAG_GAP; GST_MINI_OBJECT_FLAGS (dest) |= GST_MINI_OBJECT_FLAGS (src) & mask; } if (flags & GST_BUFFER_COPY_TIMESTAMPS) { GST_BUFFER_TIMESTAMP (dest) = GST_BUFFER_TIMESTAMP (src); GST_BUFFER_DURATION (dest) = GST_BUFFER_DURATION (src); GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET (src); GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_END (src); } if (flags & GST_BUFFER_COPY_CAPS) { if (GST_BUFFER_CAPS (src)) GST_BUFFER_CAPS (dest) = gst_caps_ref (GST_BUFFER_CAPS (src)); else GST_BUFFER_CAPS (dest) = NULL; } }
static GstMemory * gst_fd_mem_share (GstMemory * gmem, gssize offset, gssize size) { #ifdef HAVE_MMAP GstFdMemory *mem = (GstFdMemory *) gmem; GstFdMemory *sub; GstMemory *parent; GST_DEBUG ("%p: share %" G_GSSIZE_FORMAT " %" G_GSIZE_FORMAT, mem, offset, size); /* find the real parent */ if ((parent = mem->mem.parent) == NULL) parent = (GstMemory *) mem; if (size == -1) size = gmem->maxsize - offset; sub = g_slice_new0 (GstFdMemory); /* the shared memory is always readonly */ gst_memory_init (GST_MEMORY_CAST (sub), GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->mem.allocator, parent, mem->mem.maxsize, mem->mem.align, mem->mem.offset + offset, size); sub->fd = mem->fd; g_mutex_init (&sub->lock); return GST_MEMORY_CAST (sub); #else /* !HAVE_MMAP */ return NULL; #endif }
static MyMemory * _my_mem_share (MyMemory * mem, gssize offset, gsize size) { MyMemory *sub; GstMemory *parent; GST_DEBUG ("%p: share %" G_GSSIZE_FORMAT " %" G_GSIZE_FORMAT, mem, offset, size); /* find the real parent */ if ((parent = mem->mem.parent) == NULL) parent = (GstMemory *) mem; if (size == -1) size = mem->mem.size - offset; sub = g_slice_new (MyMemory); /* the shared memory is always readonly */ gst_memory_init (GST_MEMORY_CAST (sub), GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->mem.allocator, parent, mem->mem.maxsize, mem->mem.align, mem->mem.offset + offset, size); /* install pointer */ sub->data = _my_mem_map (mem, mem->mem.maxsize, GST_MAP_READ); return sub; }
static MozGfxMemory * moz_gfx_memory_share (MozGfxMemory * mem, gssize offset, gsize size) { MozGfxMemory *sub; GstMemory *parent; /* find the real parent */ if ((parent = mem->memory.parent) == NULL) parent = (GstMemory *) mem; if (size == (gsize) -1) size = mem->memory.size - offset; /* the shared memory is always readonly */ sub = g_slice_new (MozGfxMemory); gst_memory_init (GST_MEMORY_CAST (sub), (GstMemoryFlags) (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY), mem->memory.allocator, &mem->memory, mem->memory.maxsize, mem->memory.align, mem->memory.offset + offset, size); sub->image = mem->image; sub->data = mem->data; return sub; }
static GstMemory * gst_mir_image_mem_share (GstMemory * mem, gssize offset, gssize size) { GstMemory *sub; GstMemory *parent; GST_WARNING ("%s", __PRETTY_FUNCTION__); if (offset != 0) return NULL; if (size != -1 && size != mem->size) return NULL; /* find the real parent */ if ((parent = mem->parent) == NULL) parent = (GstMemory *) mem; if (size == -1) size = mem->size - offset; sub = (GstMemory *) g_slice_new (GstMirImageMemory); /* the shared memory is always readonly */ gst_memory_init (GST_MEMORY_CAST (sub), GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->allocator, parent, mem->maxsize, mem->align, mem->offset + offset, size); return sub; }
static void default_release_buffer (GstBufferPool * pool, GstBuffer * buffer) { GST_LOG_OBJECT (pool, "released buffer %p %d", buffer, GST_MINI_OBJECT_FLAGS (buffer)); /* memory should be untouched */ if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY)) goto discard; /* size should have been reset. This is not a catch all, pool with * size requirement per memory should do their own check. */ if (gst_buffer_get_size (buffer) != pool->priv->size) goto discard; /* all memory should be exclusive to this buffer (and thus be writable) */ if (!gst_buffer_is_all_memory_writable (buffer)) goto discard; /* keep it around in our queue */ gst_atomic_queue_push (pool->priv->queue, buffer); gst_poll_write_control (pool->priv->poll); return; discard: { do_free_buffer (pool, buffer); return; } }
/** * gst_buffer_copy_metadata: * @dest: a destination #GstBuffer * @src: a source #GstBuffer * @flags: flags indicating what metadata fields should be copied. * * Copies the metadata from @src into @dest. The data, size and mallocdata * fields are not copied. * * @flags indicate which fields will be copied. Use #GST_BUFFER_COPY_ALL to copy * all the metadata fields. * * This function is typically called from a custom buffer copy function after * creating @dest and setting the data, size, mallocdata. * * Since: 0.10.13 */ void gst_buffer_copy_metadata (GstBuffer * dest, const GstBuffer * src, GstBufferCopyFlags flags) { g_return_if_fail (dest != NULL); g_return_if_fail (src != NULL); /* nothing to copy if the buffers are the same */ if (G_UNLIKELY (dest == src)) return; #if GST_VERSION_NANO == 1 /* we enable this extra debugging in git versions only for now */ g_warn_if_fail (gst_buffer_is_metadata_writable (dest)); #endif GST_CAT_LOG (GST_CAT_BUFFER, "copy %p to %p", src, dest); if (flags & GST_BUFFER_COPY_FLAGS) { guint mask; /* copy relevant flags */ mask = GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS | GST_BUFFER_FLAG_DELTA_UNIT | GST_BUFFER_FLAG_DISCONT | GST_BUFFER_FLAG_GAP | GST_BUFFER_FLAG_MEDIA1 | GST_BUFFER_FLAG_MEDIA2 | GST_BUFFER_FLAG_MEDIA3; GST_MINI_OBJECT_FLAGS (dest) |= GST_MINI_OBJECT_FLAGS (src) & mask; } if (flags & GST_BUFFER_COPY_TIMESTAMPS) { GST_BUFFER_TIMESTAMP (dest) = GST_BUFFER_TIMESTAMP (src); GST_BUFFER_DURATION (dest) = GST_BUFFER_DURATION (src); GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET (src); GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_END (src); } if (flags & GST_BUFFER_COPY_CAPS) { gst_caps_replace (&GST_BUFFER_CAPS (dest), GST_BUFFER_CAPS (src)); } if ((flags & GST_BUFFER_COPY_QDATA)) { GST_CAT_TRACE (GST_CAT_BUFFER, "copying qdata from %p to %p", src, dest); gst_buffer_copy_qdata (dest, src); } }
static void default_release_buffer (GstBufferPool * pool, GstBuffer * buffer) { GST_LOG_OBJECT (pool, "released buffer %p %d", buffer, GST_MINI_OBJECT_FLAGS (buffer)); /* memory should be untouched */ if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_TAG_MEMORY))) goto memory_tagged; /* size should have been reset. This is not a catch all, pool with * size requirement per memory should do their own check. */ if (G_UNLIKELY (gst_buffer_get_size (buffer) != pool->priv->size)) goto size_changed; /* all memory should be exclusive to this buffer (and thus be writable) */ if (G_UNLIKELY (!gst_buffer_is_all_memory_writable (buffer))) goto not_writable; /* keep it around in our queue */ gst_atomic_queue_push (pool->priv->queue, buffer); gst_poll_write_control (pool->priv->poll); return; memory_tagged: { GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, pool, "discarding buffer %p: memory tag set", buffer); goto discard; } size_changed: { GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, pool, "discarding buffer %p: size %" G_GSIZE_FORMAT " != %u", buffer, gst_buffer_get_size (buffer), pool->priv->size); goto discard; } not_writable: { GST_CAT_DEBUG_OBJECT (GST_CAT_PERFORMANCE, pool, "discarding buffer %p: memory not writable", buffer); goto discard; } discard: { do_free_buffer (pool, buffer); return; } }
static GstMemory* gst_test_phys_mem_allocator_share(GstMemory *mem, gssize offset, gssize size) { GstTestPhysMemory *phys_mem; GstTestPhysMemory *sub; GstMemory *parent; phys_mem = (GstTestPhysMemory *)mem; if (size == -1) size = ((gssize)(phys_mem->mem.size) > offset) ? (phys_mem->mem.size - offset) : 0; if ((parent = phys_mem->mem.parent) == NULL) parent = (GstMemory *)mem; sub = gst_test_phys_mem_new_internal( GST_TEST_PHYS_MEM_ALLOCATOR(phys_mem->mem.allocator), parent, phys_mem->mem.maxsize, GST_MINI_OBJECT_FLAGS(parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY, phys_mem->mem.align, phys_mem->mem.offset + offset, size ); if (sub == NULL) { GST_ERROR_OBJECT(mem->allocator, "could not create new physmem substructure"); return NULL; } /* not copying mapped virt addr or mapping ref count, since * mapping is individual to all buffers */ sub->phys_addr = phys_mem->phys_addr; sub->internal = phys_mem->internal; GST_INFO_OBJECT( mem->allocator, "shared block %p, new sub block %p; offset: %d, size: %d; source block maxsize: %u, align: %u, offset: %u, size: %u", (gpointer)mem, (gpointer)sub, offset, size, mem->maxsize, mem->align, mem->offset, mem->size ); return (GstMemory *)sub; }
static GstMemoryFastMalloc* gst_allocator_fast_malloc_mem_share(GstMemoryFastMalloc* mem, gssize offset, gsize size) { GstMemory* parent = mem->base.parent; if (!parent) parent = GST_MEMORY_CAST(mem); if (size == static_cast<gsize>(-1)) size = mem->base.size - offset; GstMemoryFastMalloc* sharedMem = static_cast<GstMemoryFastMalloc*>(fastMalloc(sizeof(GstMemoryFastMalloc))); gst_memory_init(GST_MEMORY_CAST(sharedMem), static_cast<GstMemoryFlags>(GST_MINI_OBJECT_FLAGS(parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY), mem->base.allocator, parent, mem->base.maxsize, mem->base.align, mem->base.offset + offset, size); sharedMem->data = mem->data; return sharedMem; }
static GstV4l2Memory * _v4l2mem_share (GstV4l2Memory * mem, gssize offset, gsize size) { GstV4l2Memory *sub; GstMemory *parent; /* find the real parent */ if ((parent = mem->mem.parent) == NULL) parent = (GstMemory *) mem; if (size == -1) size = mem->mem.size - offset; /* the shared memory is always readonly */ sub = _v4l2mem_new (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->mem.allocator, parent, mem->mem.maxsize, mem->mem.align, offset, size, mem->plane, mem->data, -1, mem->group); return sub; }
static GstMemorySystem * _sysmem_share (GstMemorySystem * mem, gssize offset, gsize size) { GstMemorySystem *sub; GstMemory *parent; /* find the real parent */ if ((parent = mem->mem.parent) == NULL) parent = (GstMemory *) mem; if (size == -1) size = mem->mem.size - offset; /* the shared memory is always readonly */ sub = _sysmem_new (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY, parent, mem->data, mem->mem.maxsize, mem->mem.align, mem->mem.offset + offset, size, NULL, NULL); return sub; }
static GstXImageMemory * ximage_memory_share (GstXImageMemory * mem, gssize offset, gsize size) { GstXImageMemory *sub; GstMemory *parent; /* We can only share the complete memory */ if (offset != 0) return NULL; if (size != -1 && size != mem->size) return NULL; /* find the real parent */ if ((parent = mem->parent.parent) == NULL) parent = (GstMemory *) mem; if (size == -1) size = mem->parent.size - offset; /* the shared memory is always readonly */ sub = g_slice_new (GstXImageMemory); gst_memory_init (GST_MEMORY_CAST (sub), GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY, mem->parent.allocator, &mem->parent, mem->parent.maxsize, mem->parent.align, mem->parent.offset + offset, size); sub->sink = mem->sink; sub->ximage = mem->ximage; #ifdef HAVE_XSHM sub->SHMInfo = mem->SHMInfo; #endif sub->x = mem->x; sub->y = mem->y; sub->width = mem->width; sub->height = mem->height; return sub; }
static GstMemory * gst_shm_sink_allocator_mem_share (GstMemory * mem, gssize offset, gssize size) { GstShmSinkMemory *mymem = (GstShmSinkMemory *) mem; GstShmSinkMemory *mysub; GstMemory *parent; /* find the real parent */ if ((parent = mem->parent) == NULL) parent = mem; if (size == -1) size = mem->size - offset; mysub = g_slice_new0 (GstShmSinkMemory); /* the shared memory is always readonly */ gst_memory_init (GST_MEMORY_CAST (mysub), GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY, gst_object_ref (mem->allocator), parent, mem->maxsize, mem->align, mem->offset + offset, size); mysub->data = mymem->data; return (GstMemory *) mysub; }
static GstMemory * gst_apple_core_video_mem_share (GstMemory * gmem, gssize offset, gssize size) { GstAppleCoreVideoMemory *mem; GstMemory *parent, *sub; mem = (GstAppleCoreVideoMemory *) gmem; /* find the real parent */ parent = gmem->parent; if (parent == NULL) parent = gmem; if (size == -1) size = gmem->size - offset; /* the shared memory is always readonly */ sub = GST_MEMORY_CAST (gst_apple_core_video_memory_new (GST_MINI_OBJECT_FLAGS (parent) | GST_MINI_OBJECT_FLAG_LOCK_READONLY, parent, mem->gpixbuf, mem->plane, gmem->maxsize, gmem->align, gmem->offset + offset, size)); return sub; }