static gboolean gst_imx_v4l2_buffer_pool_stop(GstBufferPool *bpool) { GstImxV4l2BufferPool *pool = GST_IMX_V4L2_BUFFER_POOL(bpool); enum v4l2_buf_type type; guint i; gboolean ret = TRUE; GST_DEBUG_OBJECT(pool, "stop"); type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(GST_IMX_FD_OBJECT_GET_FD(pool->fd_obj_v4l), VIDIOC_STREAMOFF, &type) < 0) { GST_ERROR_OBJECT(pool, "VIDIOC_STREAMOFF error: %s", g_strerror(errno)); return FALSE; } for (i = 0; i < pool->num_buffers; i++) { if (pool->buffers[i]) { GST_BUFFER_POOL_CLASS(gst_imx_v4l2_buffer_pool_parent_class)->release_buffer(bpool, pool->buffers[i]); pool->buffers[i] = NULL; } } g_free(pool->buffers); pool->buffers = NULL; ret = GST_BUFFER_POOL_CLASS(gst_imx_v4l2_buffer_pool_parent_class)->stop(bpool); return ret; }
static GstFlowReturn gst_gl_buffer_pool_acquire_buffer (GstBufferPool * bpool, GstBuffer ** buffer, GstBufferPoolAcquireParams * params) { GstFlowReturn ret = GST_FLOW_OK; GstGLBufferPool *glpool = NULL; ret = GST_BUFFER_POOL_CLASS (gst_gl_buffer_pool_parent_class)->acquire_buffer (bpool, buffer, params); if (ret != GST_FLOW_OK || !*buffer) return ret; glpool = GST_GL_BUFFER_POOL (bpool); /* XXX: Don't return the memory we just rendered, glEGLImageTargetTexture2DOES() * keeps the EGLImage unmappable until the next one is uploaded */ if (glpool->priv->want_eglimage && *buffer && *buffer == glpool->priv->last_buffer) { GstBuffer *oldbuf = *buffer; ret = GST_BUFFER_POOL_CLASS (gst_gl_buffer_pool_parent_class)->acquire_buffer (bpool, buffer, params); gst_object_replace ((GstObject **) & oldbuf->pool, (GstObject *) glpool); gst_buffer_unref (oldbuf); } return ret; }
static GstFlowReturn gst_egl_image_buffer_pool_acquire_buffer (GstBufferPool * bpool, GstBuffer ** buffer, GstBufferPoolAcquireParams * params) { GstFlowReturn ret; GstEGLImageBufferPool *pool; ret = GST_BUFFER_POOL_CLASS (gst_egl_image_buffer_pool_parent_class)->acquire_buffer (bpool, buffer, params); if (ret != GST_FLOW_OK || !*buffer) return ret; pool = GST_EGL_IMAGE_BUFFER_POOL (bpool); /* XXX: Don't return the memory we just rendered, glEGLImageTargetTexture2DOES() * keeps the EGLImage unmappable until the next one is uploaded */ if (*buffer && gst_buffer_peek_memory (*buffer, 0) == pool->state->current_mem) { GstBuffer *oldbuf = *buffer; ret = GST_BUFFER_POOL_CLASS (gst_egl_image_buffer_pool_parent_class)->acquire_buffer (bpool, buffer, params); gst_object_replace ((GstObject **) & oldbuf->pool, (GstObject *) pool); gst_buffer_unref (oldbuf); } return ret; }
static void gst_vaapi_video_buffer_pool_class_init (GstVaapiVideoBufferPoolClass * klass) { GObjectClass *const object_class = G_OBJECT_CLASS (klass); GstBufferPoolClass *const pool_class = GST_BUFFER_POOL_CLASS (klass); GST_DEBUG_CATEGORY_INIT (gst_debug_vaapivideopool, "vaapivideopool", 0, "VA-API video pool"); g_type_class_add_private (klass, sizeof (GstVaapiVideoBufferPoolPrivate)); object_class->finalize = gst_vaapi_video_buffer_pool_finalize; object_class->set_property = gst_vaapi_video_buffer_pool_set_property; object_class->get_property = gst_vaapi_video_buffer_pool_get_property; pool_class->get_options = gst_vaapi_video_buffer_pool_get_options; pool_class->set_config = gst_vaapi_video_buffer_pool_set_config; pool_class->alloc_buffer = gst_vaapi_video_buffer_pool_alloc_buffer; pool_class->acquire_buffer = gst_vaapi_video_buffer_pool_acquire_buffer; pool_class->reset_buffer = gst_vaapi_video_buffer_pool_reset_buffer; /** * GstVaapiVideoBufferPool:display: * * The #GstVaapiDisplay this object is bound to. */ g_object_class_install_property (object_class, PROP_DISPLAY, g_param_spec_pointer ("display", "Display", "The GstVaapiDisplay to use for this video pool", G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); }
static GstFlowReturn gst_omx_buffer_pool_acquire_buffer (GstBufferPool * bpool, GstBuffer ** buffer, GstBufferPoolAcquireParams * params) { GstFlowReturn ret; GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool); if (pool->port->port_def.eDir == OMX_DirOutput) { GstBuffer *buf; g_return_val_if_fail (pool->current_buffer_index != -1, GST_FLOW_ERROR); buf = g_ptr_array_index (pool->buffers, pool->current_buffer_index); g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); *buffer = buf; ret = GST_FLOW_OK; /* If it's our own memory we have to set the sizes */ if (!pool->other_pool) { GstMemory *mem = gst_buffer_peek_memory (*buffer, 0); g_assert (mem && g_strcmp0 (mem->allocator->mem_type, GST_OMX_MEMORY_TYPE) == 0); mem->size = ((GstOMXMemory *) mem)->buf->omx_buf->nFilledLen; mem->offset = ((GstOMXMemory *) mem)->buf->omx_buf->nOffset; } } else { /* Acquire any buffer that is available to be filled by upstream */ ret = GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->acquire_buffer (bpool, buffer, params); } return ret; }
static gboolean gst_v4l2_buffer_pool_start (GstBufferPool * bpool) { GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool); GstV4l2Object *obj = pool->obj; pool->obj = obj; pool->buffers = g_new0 (GstBuffer *, pool->num_buffers); pool->num_allocated = 0; /* now, allocate the buffers: */ if (!GST_BUFFER_POOL_CLASS (parent_class)->start (bpool)) goto start_failed; /* we can start capturing now, we wait for the playback case until we queued * the first buffer */ if (obj->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) if (!start_streaming (pool)) goto start_failed; gst_poll_set_flushing (obj->poll, FALSE); return TRUE; /* ERRORS */ start_failed: { GST_ERROR_OBJECT (pool, "failed to start streaming"); return FALSE; } }
static gboolean gst_imx_v4l2_buffer_pool_start(GstBufferPool *bpool) { GstImxV4l2BufferPool *pool = GST_IMX_V4L2_BUFFER_POOL(bpool); enum v4l2_buf_type type; GST_DEBUG_OBJECT(pool, "start"); pool->buffers = g_new0(GstBuffer *, pool->num_buffers); pool->num_allocated = 0; if (!GST_BUFFER_POOL_CLASS(gst_imx_v4l2_buffer_pool_parent_class)->start(bpool)) { GST_ERROR_OBJECT(pool, "failed to allocate start buffers"); return FALSE; } type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(GST_IMX_FD_OBJECT_GET_FD(pool->fd_obj_v4l), VIDIOC_STREAMON, &type) < 0) { GST_ERROR_OBJECT(pool, "VIDIOC_STREAMON error: %s", g_strerror(errno)); return FALSE; } return TRUE; }
static gboolean mir_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) { GstMirBufferPool *mpool = GST_MIR_BUFFER_POOL_CAST (pool); GstVideoInfo info; GstCaps *caps; GST_DEBUG_OBJECT (mpool, "%s", __PRETTY_FUNCTION__); if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) goto wrong_config; if (caps == NULL) goto no_caps; if (mpool->allocator) gst_object_unref (mpool->allocator); mpool->allocator = NULL; /* now parse the caps from the config */ if (!gst_video_info_from_caps (&info, caps)) goto wrong_caps; if (!gst_buffer_pool_config_get_allocator (config, &mpool->allocator, &mpool->params)) return FALSE; if (mpool->allocator) gst_object_ref (mpool->allocator); GST_LOG_OBJECT (mpool, "%dx%d, caps %" GST_PTR_FORMAT, info.width, info.height, caps); /*Fixme: Enable metadata checking handling based on the config of pool */ mpool->caps = gst_caps_ref (caps); mpool->info = info; mpool->width = info.width; mpool->height = info.height; GST_DEBUG_OBJECT (mpool, "Calling set_config() on the parent class"); return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config); /* ERRORS */ wrong_config: { GST_WARNING_OBJECT (pool, "invalid config"); return FALSE; } no_caps: { GST_WARNING_OBJECT (pool, "no caps in config"); return FALSE; } wrong_caps: { GST_WARNING_OBJECT (pool, "failed getting geometry from caps %" GST_PTR_FORMAT, caps); return FALSE; } }
/** * This should get called by the pool when the buffer is returned to it. * We need to release the reference that the GstMemory is holding on the MMAL * buffer header, or it won't be returned to the (MMAL) pool. */ static void gst_mmal_opaque_buffer_pool_reset_buffer (GstBufferPool * pool, GstBuffer * buffer) { gst_mmal_opaque_mem_set_mmal_header (gst_buffer_peek_memory (buffer, 0), NULL); GST_BUFFER_POOL_CLASS (parent_class)->reset_buffer (pool, buffer); }
void moz_gfx_buffer_pool_reset_buffer (GstBufferPool* aPool, GstBuffer* aBuffer) { GstMemory* mem = gst_buffer_peek_memory(aBuffer, 0); NS_ASSERTION(GST_IS_MOZ_GFX_MEMORY_ALLOCATOR(mem->allocator), "Should be a gfx image"); moz_gfx_memory_reset((MozGfxMemory *) mem); GST_BUFFER_POOL_CLASS(moz_gfx_buffer_pool_parent_class)->reset_buffer(aPool, aBuffer); }
static gboolean gst_imx_v4l2_buffer_pool_set_config(GstBufferPool *bpool, GstStructure *config) { GstImxV4l2BufferPool *pool = GST_IMX_V4L2_BUFFER_POOL(bpool); GstVideoInfo info; GstCaps *caps; gsize size; guint min, max; struct v4l2_requestbuffers req; if (!gst_buffer_pool_config_get_params(config, &caps, &size, &min, &max)) { GST_ERROR_OBJECT(pool, "pool configuration invalid"); return FALSE; } if (caps == NULL) { GST_ERROR_OBJECT(pool, "configuration contains no caps"); return FALSE; } if (!gst_video_info_from_caps(&info, caps)) { GST_ERROR_OBJECT(pool, "caps cannot be parsed for video info"); return FALSE; } GST_DEBUG_OBJECT(pool, "set_config: size %d, min %d, max %d", size, min, max); memset(&req, 0, sizeof(req)); req.count = min; req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; req.memory = V4L2_MEMORY_MMAP; if (ioctl(GST_IMX_FD_OBJECT_GET_FD(pool->fd_obj_v4l), VIDIOC_REQBUFS, &req) < 0) { GST_ERROR_OBJECT(pool, "VIDIOC_REQBUFS failed: %s", g_strerror(errno)); return FALSE; } if (req.count != min) { min = req.count; GST_WARNING_OBJECT(pool, "using %u buffers", min); } pool->num_buffers = min; pool->video_info = info; pool->add_videometa = gst_buffer_pool_config_has_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); gst_buffer_pool_config_set_params(config, caps, size, min, max); return GST_BUFFER_POOL_CLASS(gst_imx_v4l2_buffer_pool_parent_class)->set_config(bpool, config); }
static gboolean gst_gl_buffer_pool_start (GstBufferPool * pool) { GstGLBufferPool *glpool = GST_GL_BUFFER_POOL_CAST (pool); GstGLBufferPoolPrivate *priv = glpool->priv; gst_gl_upload_meta_set_format (glpool->upload, &priv->info); return GST_BUFFER_POOL_CLASS (parent_class)->start (pool); }
static void gst_vlc_video_pool_free_buffer( GstBufferPool *p_pool, GstBuffer *p_buffer ) { GstVlcVideoPool* p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool ); gst_vlc_picture_plane_allocator_release( p_vpool->p_allocator, p_buffer ); GST_BUFFER_POOL_CLASS( parent_class )->free_buffer( p_pool, p_buffer ); return; }
static gboolean gst_v4l2_buffer_pool_stop (GstBufferPool * bpool) { gboolean ret; GstV4l2BufferPool *pool = GST_V4L2_BUFFER_POOL (bpool); GstV4l2Object *obj = pool->obj; guint n; GST_DEBUG_OBJECT (pool, "stopping pool"); gst_poll_set_flushing (obj->poll, TRUE); if (pool->streaming) { switch (obj->mode) { case GST_V4L2_IO_RW: break; case GST_V4L2_IO_MMAP: case GST_V4L2_IO_USERPTR: /* we actually need to sync on all queued buffers but not * on the non-queued ones */ GST_DEBUG_OBJECT (pool, "STREAMOFF"); if (v4l2_ioctl (pool->video_fd, VIDIOC_STREAMOFF, &obj->type) < 0) goto stop_failed; break; default: g_assert_not_reached (); break; } pool->streaming = FALSE; } /* first free the buffers in the queue */ ret = GST_BUFFER_POOL_CLASS (parent_class)->stop (bpool); /* then free the remaining buffers */ for (n = 0; n < pool->num_queued; n++) { gst_v4l2_buffer_pool_free_buffer (bpool, pool->buffers[n]); } pool->num_queued = 0; g_free (pool->buffers); pool->buffers = NULL; return ret; /* ERRORS */ stop_failed: { GST_ERROR_OBJECT (pool, "error with STREAMOFF %d (%s)", errno, g_strerror (errno)); return FALSE; } }
static void gst_vaapi_video_buffer_pool_reset_buffer (GstBufferPool * pool, GstBuffer * buffer) { GstMemory *const mem = gst_buffer_peek_memory (buffer, 0); /* Release the underlying surface proxy */ if (GST_VAAPI_IS_VIDEO_MEMORY (mem)) gst_vaapi_video_memory_reset_surface (GST_VAAPI_VIDEO_MEMORY_CAST (mem)); GST_BUFFER_POOL_CLASS (gst_vaapi_video_buffer_pool_parent_class)->reset_buffer (pool, buffer); }
static gboolean gst_omx_buffer_pool_stop (GstBufferPool * bpool) { GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool); gint i = 0; /* When not using the default GstBufferPool::GstAtomicQueue then * GstBufferPool::free_buffer is not called while stopping the pool * (because the queue is empty) */ for (i = 0; i < pool->buffers->len; i++) GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->release_buffer (bpool, g_ptr_array_index (pool->buffers, i)); /* Remove any buffers that are there */ g_ptr_array_set_size (pool->buffers, 0); if (pool->caps) gst_caps_unref (pool->caps); pool->caps = NULL; pool->add_videometa = FALSE; return GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->stop (bpool); }
static void gst_droid_buffer_pool_reset_buffer (GstBufferPool * pool, GstBuffer * buffer) { GstDroidBufferPool *dpool = GST_DROID_BUFFER_POOL (pool); gst_buffer_remove_all_memory (buffer); GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_TAG_MEMORY); g_mutex_lock (&dpool->lock); ++dpool->num_buffers; GST_DEBUG_OBJECT (dpool, "num buffers: %d", dpool->num_buffers); g_cond_signal (&dpool->cond); g_mutex_unlock (&dpool->lock); return GST_BUFFER_POOL_CLASS (parent_class)->reset_buffer (pool, buffer); }
static void gst_v4l2_buffer_pool_class_init (GstV4l2BufferPoolClass * klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); GstBufferPoolClass *bufferpool_class = GST_BUFFER_POOL_CLASS (klass); object_class->finalize = gst_v4l2_buffer_pool_finalize; bufferpool_class->start = gst_v4l2_buffer_pool_start; bufferpool_class->stop = gst_v4l2_buffer_pool_stop; bufferpool_class->set_config = gst_v4l2_buffer_pool_set_config; bufferpool_class->alloc_buffer = gst_v4l2_buffer_pool_alloc_buffer; bufferpool_class->acquire_buffer = gst_v4l2_buffer_pool_acquire_buffer; bufferpool_class->release_buffer = gst_v4l2_buffer_pool_release_buffer; bufferpool_class->free_buffer = gst_v4l2_buffer_pool_free_buffer; }
static gboolean gst_omx_buffer_pool_start (GstBufferPool * bpool) { GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool); /* Only allow to start the pool if we still are attached * to a component and port */ GST_OBJECT_LOCK (pool); if (!pool->component || !pool->port) { GST_OBJECT_UNLOCK (pool); return FALSE; } GST_OBJECT_UNLOCK (pool); return GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->start (bpool); }
static gboolean wayland_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) { GstWaylandBufferPool *wpool = GST_WAYLAND_BUFFER_POOL_CAST (pool); GstVideoInfo info; GstCaps *caps; if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) goto wrong_config; if (caps == NULL) goto no_caps; /* now parse the caps from the config */ if (!gst_video_info_from_caps (&info, caps)) goto wrong_caps; GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, info.width, info.height, caps); /*Fixme: Enable metadata checking handling based on the config of pool */ wpool->caps = gst_caps_ref (caps); wpool->info = info; wpool->width = info.width; wpool->height = info.height; return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config); /* ERRORS */ wrong_config: { GST_WARNING_OBJECT (pool, "invalid config"); return FALSE; } no_caps: { GST_WARNING_OBJECT (pool, "no caps in config"); return FALSE; } wrong_caps: { GST_WARNING_OBJECT (pool, "failed getting geometry from caps %" GST_PTR_FORMAT, caps); return FALSE; } }
static GstFlowReturn gst_vlc_video_pool_acquire_buffer( GstBufferPool *p_pool, GstBuffer **p_buffer, GstBufferPoolAcquireParams *p_params ) { GstVlcVideoPool *p_vpool = GST_VLC_VIDEO_POOL_CAST( p_pool ); GstVideoInfo *p_info; GstFlowReturn result; result = GST_BUFFER_POOL_CLASS( parent_class)->acquire_buffer( p_pool, p_buffer, p_params ); if( result == GST_FLOW_OK && !gst_vlc_picture_plane_allocator_hold( p_vpool->p_allocator, *p_buffer )) result = GST_FLOW_EOS; return result; }
static gboolean gst_wayland_buffer_pool_start (GstBufferPool * pool) { GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL (pool); guint size = 0; int fd; char filename[1024]; static int init = 0; GST_DEBUG_OBJECT (self, "Initializing wayland buffer pool"); /* configure */ size = GST_VIDEO_INFO_SIZE (&self->info) * 15; /* allocate shm pool */ snprintf (filename, 1024, "%s/%s-%d-%s", g_get_user_runtime_dir (), "wayland-shm", init++, "XXXXXX"); fd = mkstemp (filename); if (fd < 0) { GST_ERROR_OBJECT (pool, "opening temp file %s failed: %s", filename, strerror (errno)); return FALSE; } if (ftruncate (fd, size) < 0) { GST_ERROR_OBJECT (pool, "ftruncate failed: %s", strerror (errno)); close (fd); return FALSE; } self->data = mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (self->data == MAP_FAILED) { GST_ERROR_OBJECT (pool, "mmap failed: %s", strerror (errno)); close (fd); return FALSE; } self->wl_pool = wl_shm_create_pool (self->display->shm, fd, size); unlink (filename); close (fd); self->size = size; self->used = 0; return GST_BUFFER_POOL_CLASS (parent_class)->start (pool); }
static void gst_mir_buffer_pool_release_buffer (GstBufferPool * pool, GstBuffer * buffer) { #if 1 GstMemory *mem = { NULL }; int err = 0; MediaCodecDelegate delegate; /* Get access to the GstMemory stored in the GstBuffer */ if (gst_buffer_n_memory (buffer) >= 1 && (mem = gst_buffer_peek_memory (buffer, 0)) && gst_is_mir_image_memory (mem)) { GST_DEBUG_OBJECT (pool, "It is Mir image memory"); } else GST_DEBUG_OBJECT (pool, "It is NOT Mir image memory"); delegate = gst_mir_image_memory_get_codec (mem); if (!delegate) { GST_WARNING_OBJECT (pool, "delegate is NULL, rendering will not function"); goto done; } GST_DEBUG_OBJECT (pool, "mem: %p", mem); GST_DEBUG_OBJECT (pool, "gst_mir_image_memory_get_codec (mem): %p", delegate); GST_DEBUG_OBJECT (pool, "gst_mir_image_memory_get_buffer_index (mem): %d", gst_mir_image_memory_get_buffer_index (mem)); GST_DEBUG_OBJECT (pool, "Rendering buffer: %d", gst_mir_image_memory_get_buffer_index (mem)); GST_DEBUG_OBJECT (pool, "Releasing output buffer index: %d", gst_mir_image_memory_get_buffer_index (mem)); /* Render and release the output buffer back to the decoder */ err = media_codec_release_output_buffer (delegate, gst_mir_image_memory_get_buffer_index (mem)); if (err < 0) GST_WARNING_OBJECT (pool, "Failed to release output buffer. Rendering will probably be affected (err: %d).", err); #endif done: GST_BUFFER_POOL_CLASS (parent_class)->release_buffer (pool, buffer); }
static void gst_omx_buffer_pool_free_buffer (GstBufferPool * bpool, GstBuffer * buffer) { GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool); /* If the buffers belong to another pool, restore them now */ GST_OBJECT_LOCK (pool); if (pool->other_pool) { gst_object_replace ((GstObject **) & buffer->pool, (GstObject *) pool->other_pool); } GST_OBJECT_UNLOCK (pool); gst_mini_object_set_qdata (GST_MINI_OBJECT_CAST (buffer), gst_omx_buffer_data_quark, NULL, NULL); GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->free_buffer (bpool, buffer); }
static void gst_omx_buffer_pool_release_buffer (GstBufferPool * bpool, GstBuffer * buffer) { GstOMXBufferPool *pool = GST_OMX_BUFFER_POOL (bpool); OMX_ERRORTYPE err; GstOMXBuffer *omx_buf; g_assert (pool->component && pool->port); if (!pool->allocating && !pool->deactivated) { omx_buf = gst_mini_object_get_qdata (GST_MINI_OBJECT_CAST (buffer), gst_omx_buffer_data_quark); if (pool->port->port_def.eDir == OMX_DirOutput && !omx_buf->used) { /* Release back to the port, can be filled again */ err = gst_omx_port_release_buffer (pool->port, omx_buf); if (err != OMX_ErrorNone) { GST_ELEMENT_ERROR (pool->element, LIBRARY, SETTINGS, (NULL), ("Failed to relase output buffer to component: %s (0x%08x)", gst_omx_error_to_string (err), err)); } } else if (!omx_buf->used) { /* TODO: Implement. * * If not used (i.e. was not passed to the component) this should do * the same as EmptyBufferDone. * If it is used (i.e. was passed to the component) this should do * nothing until EmptyBufferDone. * * EmptyBufferDone should release the buffer to the pool so it can * be allocated again * * Needs something to call back here in EmptyBufferDone, like keeping * a ref on the buffer in GstOMXBuffer until EmptyBufferDone... which * would ensure that the buffer is always unused when this is called. */ g_assert_not_reached (); GST_BUFFER_POOL_CLASS (gst_omx_buffer_pool_parent_class)->release_buffer (bpool, buffer); } } }
static void gst_imx_v4l2_buffer_pool_class_init(GstImxV4l2BufferPoolClass *klass) { GObjectClass *object_class; GstBufferPoolClass *parent_class; object_class = G_OBJECT_CLASS(klass); parent_class = GST_BUFFER_POOL_CLASS(klass); GST_DEBUG_CATEGORY_INIT(imx_v4l2_buffer_pool_debug, "imxv4l2bufferpool", 0, "Freescale i.MX V4L2 buffer pool"); object_class->finalize = GST_DEBUG_FUNCPTR(gst_imx_v4l2_buffer_pool_finalize); parent_class->get_options = GST_DEBUG_FUNCPTR(gst_imx_v4l2_buffer_pool_get_options); parent_class->set_config = GST_DEBUG_FUNCPTR(gst_imx_v4l2_buffer_pool_set_config); parent_class->start = GST_DEBUG_FUNCPTR(gst_imx_v4l2_buffer_pool_start); parent_class->stop = GST_DEBUG_FUNCPTR(gst_imx_v4l2_buffer_pool_stop); parent_class->alloc_buffer = GST_DEBUG_FUNCPTR(gst_imx_v4l2_buffer_pool_alloc_buffer); parent_class->free_buffer = GST_DEBUG_FUNCPTR(gst_imx_v4l2_buffer_pool_free_buffer); parent_class->acquire_buffer = GST_DEBUG_FUNCPTR(gst_imx_v4l2_buffer_pool_acquire_buffer); parent_class->release_buffer = GST_DEBUG_FUNCPTR(gst_imx_v4l2_buffer_pool_release_buffer); }
static gboolean gst_wayland_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config) { GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL_CAST (pool); GstCaps *caps; if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL)) goto wrong_config; if (caps == NULL) goto no_caps; /* now parse the caps from the config */ if (!gst_video_info_from_caps (&self->info, caps)) goto wrong_caps; GST_LOG_OBJECT (pool, "%dx%d, caps %" GST_PTR_FORMAT, GST_VIDEO_INFO_WIDTH (&self->info), GST_VIDEO_INFO_HEIGHT (&self->info), caps); /*Fixme: Enable metadata checking handling based on the config of pool */ return GST_BUFFER_POOL_CLASS (parent_class)->set_config (pool, config); /* ERRORS */ wrong_config: { GST_WARNING_OBJECT (pool, "invalid config"); return FALSE; } no_caps: { GST_WARNING_OBJECT (pool, "no caps in config"); return FALSE; } wrong_caps: { GST_WARNING_OBJECT (pool, "failed getting geometry from caps %" GST_PTR_FORMAT, caps); return FALSE; } }
static gboolean gst_egl_image_buffer_pool_set_config (GstBufferPool * bpool, GstStructure * config) { GstEGLImageBufferPool *pool = GST_EGL_IMAGE_BUFFER_POOL (bpool); GstCaps *caps; GstVideoInfo info; if (pool->allocator) gst_object_unref (pool->allocator); pool->allocator = NULL; if (!GST_BUFFER_POOL_CLASS (gst_egl_image_buffer_pool_parent_class)->set_config (bpool, config)) return FALSE; if (!gst_buffer_pool_config_get_params (config, &caps, NULL, NULL, NULL) || !caps) return FALSE; if (!gst_video_info_from_caps (&info, caps)) return FALSE; if (!gst_buffer_pool_config_get_allocator (config, &pool->allocator, &pool->params)) return FALSE; if (pool->allocator) gst_object_ref (pool->allocator); pool->add_metavideo = gst_buffer_pool_config_has_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); pool->want_eglimage = (pool->allocator && g_strcmp0 (pool->allocator->mem_type, GST_EGL_IMAGE_MEMORY_TYPE) == 0); pool->info = info; return TRUE; }
static gboolean gst_wayland_buffer_pool_stop (GstBufferPool * pool) { GstWaylandBufferPool *self = GST_WAYLAND_BUFFER_POOL (pool); GST_DEBUG_OBJECT (self, "Stopping wayland buffer pool"); munmap (self->data, self->size); wl_shm_pool_destroy (self->wl_pool); self->wl_pool = NULL; self->size = 0; self->used = 0; /* all buffers are about to be destroyed; * we should no longer do anything with them */ g_mutex_lock (&self->buffers_map_mutex); g_hash_table_remove_all (self->buffers_map); g_mutex_unlock (&self->buffers_map_mutex); return GST_BUFFER_POOL_CLASS (parent_class)->stop (pool); }
static GstFlowReturn gst_egl_image_buffer_pool_alloc_buffer (GstBufferPool * bpool, GstBuffer ** buffer, GstBufferPoolAcquireParams * params) { GstEGLImageBufferPool *pool = GST_EGL_IMAGE_BUFFER_POOL (bpool); *buffer = NULL; if (!pool->add_metavideo || !pool->want_eglimage) return GST_BUFFER_POOL_CLASS (gst_egl_image_buffer_pool_parent_class)->alloc_buffer (bpool, buffer, params); if (!pool->allocator) return GST_FLOW_NOT_NEGOTIATED; switch (pool->info.finfo->format) { case GST_VIDEO_FORMAT_RGBA:{ GstFlowReturn ret; GstQuery *query; GstStructure *s; const GValue *v; s = gst_structure_new ("eglglessink-allocate-eglimage", "format", GST_TYPE_VIDEO_FORMAT, pool->info.finfo->format, "width", G_TYPE_INT, pool->info.width, "height", G_TYPE_INT, pool->info.height, NULL); query = gst_query_new_custom (GST_QUERY_CUSTOM, s); ret = queue_object (state, GST_MINI_OBJECT_CAST (query), TRUE); if (ret != TRUE || !gst_structure_has_field (s, "buffer")) { GST_WARNING ("Fallback memory allocation"); gst_query_unref (query); return GST_BUFFER_POOL_CLASS (gst_egl_image_buffer_pool_parent_class)->alloc_buffer (bpool, buffer, params); } v = gst_structure_get_value (s, "buffer"); *buffer = GST_BUFFER_CAST (g_value_get_pointer (v)); gst_query_unref (query); if (!*buffer) { GST_WARNING ("Fallback memory allocation"); return GST_BUFFER_POOL_CLASS (gst_egl_image_buffer_pool_parent_class)->alloc_buffer (bpool, buffer, params); } return GST_FLOW_OK; break; } default: return GST_BUFFER_POOL_CLASS (gst_egl_image_buffer_pool_parent_class)->alloc_buffer (bpool, buffer, params); break; } return GST_FLOW_ERROR; }