static gboolean gst_imx_blitter_video_sink_propose_allocation(GstBaseSink *sink, GstQuery *query) { GstCaps *caps; GstVideoInfo info; GstBufferPool *pool; guint size; gst_query_parse_allocation(query, &caps, NULL); if (caps == NULL) { GST_DEBUG_OBJECT(sink, "no caps specified"); return FALSE; } if (!gst_video_info_from_caps(&info, caps)) return FALSE; size = GST_VIDEO_INFO_SIZE(&info); if (gst_query_get_n_allocation_pools(query) == 0) { GstStructure *structure; GstAllocationParams params; GstAllocator *allocator = NULL; memset(¶ms, 0, sizeof(params)); params.flags = 0; params.align = 15; params.prefix = 0; params.padding = 0; if (gst_query_get_n_allocation_params(query) > 0) gst_query_parse_nth_allocation_param(query, 0, &allocator, ¶ms); else gst_query_add_allocation_param(query, allocator, ¶ms); pool = gst_video_buffer_pool_new(); structure = gst_buffer_pool_get_config(pool); gst_buffer_pool_config_set_params(structure, caps, size, 0, 0); gst_buffer_pool_config_set_allocator(structure, allocator, ¶ms); if (allocator) gst_object_unref(allocator); if (!gst_buffer_pool_set_config(pool, structure)) { GST_ERROR_OBJECT(sink, "failed to set config"); gst_object_unref(pool); return FALSE; } gst_query_add_allocation_pool(query, pool, size, 0, 0); gst_object_unref(pool); gst_query_add_allocation_meta(query, GST_VIDEO_META_API_TYPE, NULL); } return TRUE; }
static gboolean gst_imx_v4l2src_decide_allocation(GstBaseSrc *bsrc, GstQuery *query) { GstImxV4l2Src *v4l2src = GST_IMX_V4L2SRC(bsrc); struct v4l2_format fmt; GstBufferPool *pool; guint size, min, max; gboolean update; GstStructure *config; GstCaps *caps; gst_query_parse_allocation(query, &caps, NULL); /* Determine min and max */ if (gst_query_get_n_allocation_pools(query) > 0) { gst_query_parse_nth_allocation_pool(query, 0, NULL, NULL, &min, &max); update = TRUE; } else { min = max = 0; update = FALSE; } if (min != 0) /* Need an extra buffer to capture while other buffers * are downstream */ min += 1; else min = v4l2src->queue_size; fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(GST_IMX_FD_OBJECT_GET_FD(v4l2src->fd_obj_v4l), VIDIOC_G_FMT, &fmt) < 0) { GST_ERROR_OBJECT(v4l2src, "VIDIOC_G_FMT failed"); return FALSE; } size = fmt.fmt.pix.sizeimage; /* no repooling; leads to stream off situation due to pool start/stop */ pool = gst_base_src_get_buffer_pool(bsrc); if (!pool) { pool = gst_imx_v4l2_buffer_pool_new(v4l2src->fd_obj_v4l); config = gst_buffer_pool_get_config(pool); gst_buffer_pool_config_set_params(config, caps, size, min, max); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); gst_buffer_pool_set_config(pool, config); } if (update) gst_query_set_nth_allocation_pool(query, 0, pool, size, min, max); else gst_query_add_allocation_pool(query, pool, size, min, max); gst_object_unref(pool); return TRUE; }
GstBufferPool* gst_imx_blitter_create_bufferpool(GstImxBlitter *blitter, GstCaps *caps, guint size, guint min_buffers, guint max_buffers, GstAllocator *allocator, GstAllocationParams *alloc_params) { GstBufferPool *pool; GstStructure *config; GstImxBlitterClass *klass; g_assert(blitter != NULL); klass = GST_IMX_BLITTER_CLASS(G_OBJECT_GET_CLASS(blitter)); g_assert(klass->get_phys_mem_allocator != NULL); pool = gst_imx_phys_mem_buffer_pool_new(FALSE); config = gst_buffer_pool_get_config(pool); gst_buffer_pool_config_set_params(config, caps, size, min_buffers, max_buffers); /* If the allocator value is NULL, get an allocator * it is unref'd by the buffer pool when it is unref'd */ if (allocator == NULL) allocator = klass->get_phys_mem_allocator(blitter); if (allocator == NULL) { GST_ERROR_OBJECT(blitter, "could not create physical memory bufferpool allocator"); return NULL; } gst_buffer_pool_config_set_allocator(config, allocator, alloc_params); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_IMX_PHYS_MEM); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); gst_buffer_pool_set_config(pool, config); return pool; }
static void gst_buffer_pool_init (GstBufferPool * pool) { GstBufferPoolPrivate *priv; priv = pool->priv = GST_BUFFER_POOL_GET_PRIVATE (pool); g_rec_mutex_init (&priv->rec_lock); priv->poll = gst_poll_new_timer (); priv->queue = gst_atomic_queue_new (10); pool->flushing = 1; priv->active = FALSE; priv->configured = FALSE; priv->started = FALSE; priv->config = gst_structure_new_id_empty (GST_QUARK (BUFFER_POOL_CONFIG)); gst_buffer_pool_config_set_params (priv->config, NULL, 0, 0, 0); priv->allocator = NULL; gst_allocation_params_init (&priv->params); gst_buffer_pool_config_set_allocator (priv->config, priv->allocator, &priv->params); gst_poll_write_control (priv->poll); GST_DEBUG_OBJECT (pool, "created"); }
/** * gst_v4l2_buffer_pool_new: * @obj: the v4l2 object owning the pool * * Construct a new buffer pool. * * Returns: the new pool, use gst_object_unref() to free resources */ GstBufferPool * gst_v4l2_buffer_pool_new (GstV4l2Object * obj, GstCaps * caps) { GstV4l2BufferPool *pool; GstStructure *s; gint fd; fd = v4l2_dup (obj->video_fd); if (fd < 0) goto dup_failed; pool = (GstV4l2BufferPool *) g_object_new (GST_TYPE_V4L2_BUFFER_POOL, NULL); pool->video_fd = fd; pool->obj = obj; s = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool)); gst_buffer_pool_config_set_params (s, caps, obj->sizeimage, 2, 0); gst_buffer_pool_set_config (GST_BUFFER_POOL_CAST (pool), s); return GST_BUFFER_POOL (pool); /* ERRORS */ dup_failed: { GST_DEBUG ("failed to dup fd %d (%s)", errno, g_strerror (errno)); return NULL; } }
/** * ensure_sinkpad_buffer_pool: * @plugin: a #GstVaapiPluginBase * @caps: the initial #GstCaps for the resulting buffer pool * * Makes sure the sink pad video buffer pool is created with the * appropriate @caps. * * Returns: %TRUE if successful, %FALSE otherwise. */ static gboolean ensure_sinkpad_buffer_pool (GstVaapiPluginBase * plugin, GstCaps * caps) { GstBufferPool *pool; GstCaps *pool_caps; GstStructure *config; GstVideoInfo vi; gboolean need_pool; if (!gst_vaapi_plugin_base_ensure_display (plugin)) return FALSE; if (plugin->sinkpad_buffer_pool) { config = gst_buffer_pool_get_config (plugin->sinkpad_buffer_pool); gst_buffer_pool_config_get_params (config, &pool_caps, NULL, NULL, NULL); need_pool = !gst_caps_is_equal (caps, pool_caps); gst_structure_free (config); if (!need_pool) return TRUE; g_clear_object (&plugin->sinkpad_buffer_pool); plugin->sinkpad_buffer_size = 0; } pool = gst_vaapi_video_buffer_pool_new (plugin->display); if (!pool) goto error_create_pool; gst_video_info_init (&vi); gst_video_info_from_caps (&vi, caps); if (GST_VIDEO_INFO_FORMAT (&vi) == GST_VIDEO_FORMAT_ENCODED) { GST_DEBUG ("assume video buffer pool format is NV12"); gst_video_info_set_format (&vi, GST_VIDEO_FORMAT_NV12, GST_VIDEO_INFO_WIDTH (&vi), GST_VIDEO_INFO_HEIGHT (&vi)); } plugin->sinkpad_buffer_size = vi.size; config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, plugin->sinkpad_buffer_size, 0, 0); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VAAPI_VIDEO_META); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); if (!gst_buffer_pool_set_config (pool, config)) goto error_pool_config; plugin->sinkpad_buffer_pool = pool; return TRUE; /* ERRORS */ error_create_pool: { GST_ERROR ("failed to create buffer pool"); return FALSE; } error_pool_config: { GST_ERROR ("failed to reset buffer pool config"); gst_object_unref (pool); return FALSE; } }
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_decklink_video_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) { GstCaps *caps; GstVideoInfo info; GstBufferPool *pool; guint size; gst_query_parse_allocation (query, &caps, NULL); if (caps == NULL) return FALSE; if (!gst_video_info_from_caps (&info, caps)) return FALSE; size = GST_VIDEO_INFO_SIZE (&info); if (gst_query_get_n_allocation_pools (query) == 0) { GstStructure *structure; GstAllocator *allocator = NULL; GstAllocationParams params = { (GstMemoryFlags) 0, 15, 0, 0 }; if (gst_query_get_n_allocation_params (query) > 0) gst_query_parse_nth_allocation_param (query, 0, &allocator, ¶ms); else gst_query_add_allocation_param (query, allocator, ¶ms); pool = gst_video_buffer_pool_new (); structure = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (structure, caps, size, 0, 0); gst_buffer_pool_config_set_allocator (structure, allocator, ¶ms); if (allocator) gst_object_unref (allocator); if (!gst_buffer_pool_set_config (pool, structure)) goto config_failed; gst_query_add_allocation_pool (query, pool, size, 0, 0); gst_object_unref (pool); gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); } return TRUE; // ERRORS config_failed: { GST_ERROR_OBJECT (bsink, "failed to set config"); gst_object_unref (pool); return FALSE; } }
static gboolean gst_gdk_pixbuf_dec_setup_pool (GstGdkPixbufDec * filter, GstVideoInfo * info) { GstCaps *target; GstQuery *query; GstBufferPool *pool; GstStructure *config; guint size, min, max; target = gst_pad_get_current_caps (filter->srcpad); /* try to get a bufferpool now */ /* find a pool for the negotiated caps now */ query = gst_query_new_allocation (target, TRUE); if (!gst_pad_peer_query (filter->srcpad, query)) { /* not a problem, we use the query defaults */ GST_DEBUG_OBJECT (filter, "ALLOCATION query failed"); } if (gst_query_get_n_allocation_pools (query) > 0) { /* we got configuration from our peer, parse them */ gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); } else { pool = NULL; size = info->size; min = max = 0; } gst_query_unref (query); if (pool == NULL) { /* we did not get a pool, make one ourselves then */ pool = gst_buffer_pool_new (); } /* and configure */ config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, target, size, min, max); gst_buffer_pool_set_config (pool, config); if (filter->pool) { gst_buffer_pool_set_active (filter->pool, FALSE); gst_object_unref (filter->pool); } filter->pool = pool; /* and activate */ gst_buffer_pool_set_active (filter->pool, TRUE); gst_caps_unref (target); return TRUE; }
static gboolean gst_wayland_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) { GstWaylandSink *sink = GST_WAYLAND_SINK (bsink); GstBufferPool *newpool, *oldpool; GstVideoInfo info; GstStructure *structure; static GstAllocationParams params = { 0, 0, 0, 15, }; guint size; sink = GST_WAYLAND_SINK (bsink); GST_LOG_OBJECT (sink, "set caps %" GST_PTR_FORMAT, caps); if (!gst_video_info_from_caps (&info, caps)) goto invalid_format; sink->video_width = info.width; sink->video_height = info.height; size = info.size; /* create a new pool for the new configuration */ newpool = gst_wayland_buffer_pool_new (sink); if (!newpool) { GST_DEBUG_OBJECT (sink, "Failed to create new pool"); return FALSE; } structure = gst_buffer_pool_get_config (newpool); gst_buffer_pool_config_set_params (structure, caps, size, 2, 0); gst_buffer_pool_config_set_allocator (structure, NULL, ¶ms); if (!gst_buffer_pool_set_config (newpool, structure)) goto config_failed; oldpool = sink->pool; sink->pool = newpool; if (oldpool) gst_object_unref (oldpool); return TRUE; invalid_format: { GST_DEBUG_OBJECT (sink, "Could not locate image format from caps %" GST_PTR_FORMAT, caps); return FALSE; } config_failed: { GST_DEBUG_OBJECT (bsink, "failed setting config"); return FALSE; } }
static GstFlowReturn gst_rtp_vraw_depay_negotiate_pool (GstRtpVRawDepay * depay, GstCaps * caps, GstVideoInfo * info) { GstQuery *query; GstBufferPool *pool = NULL; guint size, min, max; GstStructure *config; /* find a pool for the negotiated caps now */ query = gst_query_new_allocation (caps, TRUE); if (!gst_pad_peer_query (GST_RTP_BASE_DEPAYLOAD_SRCPAD (depay), query)) { /* not a problem, we use the defaults of query */ GST_DEBUG_OBJECT (depay, "could not get downstream ALLOCATION hints"); } if (gst_query_get_n_allocation_pools (query) > 0) { /* we got configuration from our peer, parse them */ gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); } else { GST_DEBUG_OBJECT (depay, "didn't get downstream pool hints"); size = info->size; min = max = 0; } if (pool == NULL) { /* we did not get a pool, make one ourselves then */ pool = gst_video_buffer_pool_new (); } if (depay->pool) gst_object_unref (depay->pool); depay->pool = pool; config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, min, max); if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) { /* just set the metadata, if the pool can support it we will transparently use * it through the video info API. We could also see if the pool support this * metadata and only activate it then. */ gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); } gst_buffer_pool_set_config (pool, config); /* and activate */ gst_buffer_pool_set_active (pool, TRUE); gst_query_unref (query); return GST_FLOW_OK; }
static void gst_dvdec_negotiate_pool (GstDVDec * dec, GstCaps * caps, GstVideoInfo * info) { GstQuery *query; GstBufferPool *pool; guint size, min, max; GstStructure *config; /* find a pool for the negotiated caps now */ query = gst_query_new_allocation (caps, TRUE); if (!gst_pad_peer_query (dec->srcpad, query)) { GST_DEBUG_OBJECT (dec, "didn't get downstream ALLOCATION hints"); } if (gst_query_get_n_allocation_pools (query) > 0) { /* we got configuration from our peer, parse them */ gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); size = MAX (size, info->size); } else { pool = NULL; size = info->size; min = max = 0; } if (pool == NULL) { /* we did not get a pool, make one ourselves then */ pool = gst_video_buffer_pool_new (); } if (dec->pool) { gst_buffer_pool_set_active (dec->pool, FALSE); gst_object_unref (dec->pool); } dec->pool = pool; config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, min, max); if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) { /* just set the option, if the pool can support it we will transparently use * it through the video info API. We could also see if the pool support this * option and only activate it then. */ gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); } gst_buffer_pool_set_config (pool, config); /* and activate */ gst_buffer_pool_set_active (pool, TRUE); gst_query_unref (query); }
static GstBufferPool * create_pool (guint size, guint min_buf, guint max_buf) { GstBufferPool *pool = gst_buffer_pool_new (); GstStructure *conf = gst_buffer_pool_get_config (pool); GstCaps *caps = gst_caps_new_empty_simple ("test/data"); gst_buffer_pool_config_set_params (conf, caps, size, min_buf, max_buf); gst_buffer_pool_set_config (pool, conf); gst_caps_unref (caps); return pool; }
gboolean gst_droidcamsrc_dev_init (GstDroidCamSrcDev * dev) { GstStructure *config; GST_DEBUG ("dev init"); g_rec_mutex_lock (dev->lock); /* first the buffer pool */ config = gst_buffer_pool_get_config (dev->pool); gst_buffer_pool_config_set_params (config, NULL, 0, GST_DROIDCAMSRC_NUM_BUFFERS, GST_DROIDCAMSRC_NUM_BUFFERS); if (!gst_buffer_pool_set_config (dev->pool, config)) { GST_ERROR ("Failed to configure buffer pool"); return FALSE; } /* now the callbacks */ { DroidMediaCameraCallbacks cb; cb.shutter_cb = gst_droidcamsrc_dev_shutter_callback; cb.focus_cb = gst_droidcamsrc_dev_focus_callback; cb.focus_move_cb = gst_droidcamsrc_dev_focus_move_callback; cb.error_cb = gst_droidcamsrc_dev_error_callback; cb.zoom_cb = gst_droidcamsrc_dev_zoom_callback; cb.raw_image_cb = gst_droidcamsrc_dev_raw_image_callback; cb.compressed_image_cb = gst_droidcamsrc_dev_compressed_image_callback; cb.postview_frame_cb = gst_droidcamsrc_dev_postview_frame_callback; cb.raw_image_notify_cb = gst_droidcamsrc_dev_raw_image_notify_callback; cb.preview_frame_cb = gst_droidcamsrc_dev_preview_frame_callback; cb.video_frame_cb = gst_droidcamsrc_dev_video_frame_callback; cb.preview_metadata_cb = gst_droidcamsrc_dev_preview_metadata_callback; droid_media_camera_set_callbacks (dev->cam, &cb, dev); } { DroidMediaBufferQueueCallbacks cb; cb.buffers_released = gst_droidcamsrc_dev_buffers_released; cb.frame_available = gst_droidcamsrc_dev_frame_available; droid_media_buffer_queue_set_callbacks (dev->queue, &cb, dev); } gst_droidcamsrc_dev_update_params_locked (dev); g_rec_mutex_unlock (dev->lock); return TRUE; }
static gboolean gst_openni2src_decide_allocation (GstBaseSrc * bsrc, GstQuery * query) { GstBufferPool *pool; guint size, min, max; gboolean update; GstStructure *config; GstCaps *caps; GstVideoInfo info; gst_query_parse_allocation (query, &caps, NULL); gst_video_info_from_caps (&info, caps); if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); update = TRUE; } else { pool = NULL; min = max = 0; size = info.size; update = FALSE; } GST_DEBUG_OBJECT (bsrc, "allocation: size:%u min:%u max:%u pool:%" GST_PTR_FORMAT " caps:%" GST_PTR_FORMAT, size, min, max, pool, caps); if (!pool) pool = gst_video_buffer_pool_new (); config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, min, max); if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) { GST_DEBUG_OBJECT (pool, "activate Video Meta"); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); } gst_buffer_pool_set_config (pool, config); if (update) gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); else gst_query_add_allocation_pool (query, pool, size, min, max); gst_object_unref (pool); return GST_BASE_SRC_CLASS (parent_class)->decide_allocation (bsrc, query); }
static gboolean theora_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query) { GstTheoraDec *dec = GST_THEORA_DEC (decoder); GstVideoCodecState *state; GstBufferPool *pool; guint size, min, max; GstStructure *config; if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (decoder, query)) return FALSE; state = gst_video_decoder_get_output_state (decoder); gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); dec->can_crop = FALSE; config = gst_buffer_pool_get_config (pool); if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) { gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); dec->can_crop = gst_query_find_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL); } if (dec->can_crop) { GstVideoInfo info = state->info; GstCaps *caps; /* Calculate uncropped size */ gst_video_info_set_format (&info, info.finfo->format, dec->info.frame_width, dec->info.frame_height); size = MAX (size, info.size); caps = gst_video_info_to_caps (&info); gst_buffer_pool_config_set_params (config, caps, size, min, max); gst_caps_unref (caps); } gst_buffer_pool_set_config (pool, config); gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); gst_object_unref (pool); gst_video_codec_state_unref (state); return TRUE; }
static gboolean gst_mfc_dec_decide_allocation (GstVideoDecoder * decoder, GstQuery * query) { GstMFCDec *self = GST_MFC_DEC (decoder); GstBufferPool *pool; GstStructure *config; guint size, min, max; if (!GST_VIDEO_DECODER_CLASS (parent_class)->decide_allocation (decoder, query)) return FALSE; g_assert (gst_query_get_n_allocation_pools (query) > 0); gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); g_assert (pool != NULL); self->has_cropping = FALSE; config = gst_buffer_pool_get_config (pool); if (gst_query_find_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL)) { gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); self->has_cropping = gst_query_find_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL); } if (self->has_cropping) { GstVideoInfo info; GstCaps *caps; /* Calculate uncropped size */ gst_buffer_pool_config_get_params (config, &caps, &size, &min, &max); gst_video_info_from_caps (&info, caps); gst_video_info_set_format (&info, self->format, self->width, self->height); size = MAX (size, info.size); caps = gst_video_info_to_caps (&info); gst_buffer_pool_config_set_params (config, caps, size, min, max); gst_caps_unref (caps); } gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); gst_buffer_pool_set_config (pool, config); gst_object_unref (pool); return TRUE; }
static GstBufferPool* gst_imx_video_compositor_create_bufferpool(GstImxVideoCompositor *compositor, GstCaps *caps, guint size, guint min_buffers, guint max_buffers, GstAllocator *allocator, GstAllocationParams *alloc_params) { GstBufferPool *pool; GstStructure *config; GstImxVideoCompositorClass *klass; g_assert(compositor != NULL); klass = GST_IMX_VIDEO_COMPOSITOR_CLASS(G_OBJECT_GET_CLASS(compositor)); g_assert(klass->get_phys_mem_allocator != NULL); if (size == 0) { GstVideoInfo info; if (!gst_video_info_from_caps(&info, caps)) { GST_ERROR_OBJECT(compositor, "could not parse caps for dma bufferpool"); return NULL; } } pool = gst_imx_phys_mem_buffer_pool_new(FALSE); config = gst_buffer_pool_get_config(pool); gst_buffer_pool_config_set_params(config, caps, size, min_buffers, max_buffers); /* If the allocator value is NULL, get an allocator * it is unref'd by the buffer pool when it is unref'd */ if (allocator == NULL) allocator = klass->get_phys_mem_allocator(compositor); if (allocator == NULL) { GST_ERROR_OBJECT(compositor, "could not create physical memory bufferpool allocator"); return NULL; } gst_buffer_pool_config_set_allocator(config, allocator, alloc_params); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_IMX_PHYS_MEM); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); gst_buffer_pool_set_config(pool, config); gst_object_unref(allocator); return pool; }
static gboolean gst_rfb_src_decide_allocation (GstBaseSrc * bsrc, GstQuery * query) { GstBufferPool *pool = NULL; guint size, min = 1, max = 0; GstStructure *config; GstCaps *caps; GstVideoInfo info; gboolean ret; gst_query_parse_allocation (query, &caps, NULL); if (!caps || !gst_video_info_from_caps (&info, caps)) return FALSE; while (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); /* TODO We restrict to the exact size as we don't support strides or * special padding */ if (size == info.size) break; gst_query_remove_nth_allocation_pool (query, 0); gst_object_unref (pool); pool = NULL; } if (pool == NULL) { /* we did not get a pool, make one ourselves then */ pool = gst_video_buffer_pool_new (); size = info.size; min = 1; max = 0; gst_query_add_allocation_pool (query, pool, size, min, max); } config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, min, max); ret = gst_buffer_pool_set_config (pool, config); gst_object_unref (pool); return ret; }
static GstBufferPool * gst_mpeg2dec_create_generic_pool (GstAllocator * allocator, GstAllocationParams * params, GstCaps * caps, guint size, guint min, guint max, GstStructure ** out_config) { GstBufferPool *pool; GstStructure *config; pool = gst_video_buffer_pool_new (); config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_allocator (config, allocator, params); gst_buffer_pool_config_set_params (config, caps, size, min, max); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); *out_config = config; return pool; }
/* configure the allocation query that was answered downstream, we can configure * some properties on it. Only called when not in passthrough mode. */ static gboolean gst_video_filter_decide_allocation (GstBaseTransform * trans, GstQuery * query) { GstBufferPool *pool = NULL; GstStructure *config; guint min, max, size; gboolean update_pool; GstCaps *outcaps = NULL; if (gst_query_get_n_allocation_pools (query) > 0) { gst_query_parse_nth_allocation_pool (query, 0, &pool, &size, &min, &max); update_pool = TRUE; } else { GstVideoInfo vinfo; gst_query_parse_allocation (query, &outcaps, NULL); gst_video_info_init (&vinfo); gst_video_info_from_caps (&vinfo, outcaps); size = vinfo.size; min = max = 0; update_pool = FALSE; } if (!pool) pool = gst_video_buffer_pool_new (); config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); if (outcaps) gst_buffer_pool_config_set_params (config, outcaps, size, 0, 0); gst_buffer_pool_set_config (pool, config); if (update_pool) gst_query_set_nth_allocation_pool (query, 0, pool, size, min, max); else gst_query_add_allocation_pool (query, pool, size, min, max); gst_object_unref (pool); return GST_BASE_TRANSFORM_CLASS (parent_class)->decide_allocation (trans, query); }
GstBufferPool* gst_imx_ipu_blitter_create_bufferpool(GstImxIpuBlitter *ipu_blitter, GstCaps *caps, guint size, guint min_buffers, guint max_buffers, GstAllocator *allocator, GstAllocationParams *alloc_params) { GstBufferPool *pool; GstStructure *config; pool = gst_imx_phys_mem_buffer_pool_new(FALSE); config = gst_buffer_pool_get_config(pool); gst_buffer_pool_config_set_params(config, caps, size, min_buffers, max_buffers); /* If the allocator value is NULL, create an allocator */ if (allocator == NULL) { allocator = gst_imx_ipu_allocator_new(ipu_blitter->priv->ipu_fd); gst_buffer_pool_config_set_allocator(config, allocator, alloc_params); } gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_IMX_PHYS_MEM); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); gst_buffer_pool_set_config(pool, config); return pool; }
static GstVlcVideoPool* gst_vlc_video_sink_create_pool( GstVlcVideoSink *p_vsink, GstCaps *p_caps, gsize i_size, gint i_min ) { GstVlcVideoPool *p_pool; GstStructure *p_config; p_pool = gst_vlc_video_pool_new( p_vsink->p_allocator, p_vsink->p_dec ); p_config = gst_buffer_pool_get_config( GST_BUFFER_POOL_CAST( p_pool )); gst_buffer_pool_config_set_params( p_config, p_caps, i_size, i_min, 0); if( !gst_buffer_pool_set_config( GST_BUFFER_POOL_CAST( p_pool ), p_config )) goto config_failed; return p_pool; config_failed: { gst_object_unref (p_pool); return NULL; } }
static gboolean gst_imx_vpu_encoder_base_propose_allocation(GstVideoEncoder *encoder, GstQuery *query) { GstStructure *config; GstCaps *caps; gboolean need_pool; GstVideoInfo info; GstBufferPool *pool; gst_query_parse_allocation (query, &caps, &need_pool); if (need_pool) { if (caps == NULL) { GST_WARNING_OBJECT(encoder, "no caps"); return FALSE; } if (!gst_video_info_from_caps(&info, caps)) { GST_WARNING_OBJECT(encoder, "invalid caps"); return FALSE; } pool = gst_imx_phys_mem_buffer_pool_new(FALSE); config = gst_buffer_pool_get_config(pool); gst_buffer_pool_config_set_params(config, caps, info.size, 2, 0); gst_buffer_pool_config_set_allocator(config, encoder->phys_mem_allocator, NULL); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_IMX_PHYS_MEM); gst_buffer_pool_config_add_option(config, GST_BUFFER_POOL_OPTION_VIDEO_META); gst_buffer_pool_set_config(pool, config); gst_query_add_allocation_pool(query, pool, info.size, 2, 0); gst_object_unref (pool); } return TRUE; }
static GstBufferPool * gst_kms_sink_create_pool (GstKMSSink * self, GstCaps * caps, gsize size, gint min) { GstBufferPool *pool; GstStructure *config; pool = gst_kms_buffer_pool_new (); if (!pool) goto pool_failed; config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, min, 0); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); ensure_kms_allocator (self); gst_buffer_pool_config_set_allocator (config, self->allocator, NULL); if (!gst_buffer_pool_set_config (pool, config)) goto config_failed; return pool; /* ERRORS */ pool_failed: { GST_ERROR_OBJECT (self, "failed to create buffer pool"); return NULL; } config_failed: { GST_ERROR_OBJECT (self, "failed to set config"); gst_object_unref (pool); return NULL; } }
static GstBufferPool * gst_msdkvpp_create_buffer_pool (GstMsdkVPP * thiz, GstPadDirection direction, GstCaps * caps, guint min_num_buffers) { GstBufferPool *pool = NULL; GstStructure *config; GstAllocator *allocator = NULL; GstVideoInfo info; GstVideoInfo *pool_info = NULL; GstVideoAlignment align; GstAllocationParams params = { 0, 31, 0, 0, }; mfxFrameAllocResponse *alloc_resp = NULL; gboolean use_dmabuf = FALSE; if (direction == GST_PAD_SINK) { alloc_resp = &thiz->in_alloc_resp; pool_info = &thiz->sinkpad_buffer_pool_info; use_dmabuf = thiz->use_sinkpad_dmabuf; } else if (direction == GST_PAD_SRC) { alloc_resp = &thiz->out_alloc_resp; pool_info = &thiz->srcpad_buffer_pool_info; use_dmabuf = thiz->use_srcpad_dmabuf; } pool = gst_msdk_buffer_pool_new (thiz->context, alloc_resp); if (!pool) goto error_no_pool; if (!gst_video_info_from_caps (&info, caps)) goto error_no_video_info; gst_msdk_set_video_alignment (&info, &align); gst_video_info_align (&info, &align); if (use_dmabuf) allocator = gst_msdk_dmabuf_allocator_new (thiz->context, &info, alloc_resp); else if (thiz->use_video_memory) allocator = gst_msdk_video_allocator_new (thiz->context, &info, alloc_resp); else allocator = gst_msdk_system_allocator_new (&info); if (!allocator) goto error_no_allocator; config = gst_buffer_pool_get_config (GST_BUFFER_POOL_CAST (pool)); gst_buffer_pool_config_set_params (config, caps, info.size, min_num_buffers, 0); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_META); gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_VIDEO_ALIGNMENT); if (thiz->use_video_memory) { gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_MSDK_USE_VIDEO_MEMORY); if (use_dmabuf) gst_buffer_pool_config_add_option (config, GST_BUFFER_POOL_OPTION_MSDK_USE_DMABUF); } gst_buffer_pool_config_set_video_alignment (config, &align); gst_buffer_pool_config_set_allocator (config, allocator, ¶ms); gst_object_unref (allocator); if (!gst_buffer_pool_set_config (pool, config)) goto error_pool_config; /* Updating pool_info with algined info of allocator */ *pool_info = info; return pool; error_no_pool: { GST_INFO_OBJECT (thiz, "Failed to create bufferpool"); return NULL; } error_no_video_info: { GST_INFO_OBJECT (thiz, "Failed to get Video info from caps"); return NULL; } error_no_allocator: { GST_INFO_OBJECT (thiz, "Failed to create allocator"); if (pool) gst_object_unref (pool); return NULL; } error_pool_config: { GST_INFO_OBJECT (thiz, "Failed to set config"); if (pool) gst_object_unref (pool); if (allocator) gst_object_unref (allocator); return NULL; } }
static GstPadProbeReturn query_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data) { APP_STATE_T *state = (APP_STATE_T *) user_data; GstQuery *query = GST_PAD_PROBE_INFO_QUERY (info); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_ALLOCATION:{ GstBufferPool *pool; GstStructure *config; GstCaps *caps; GstVideoInfo info; gboolean need_pool; guint size; GstAllocator *allocator; GstAllocationParams params; gst_allocation_params_init (¶ms); gst_query_parse_allocation (query, &caps, &need_pool); if (!caps) { GST_ERROR ("allocation query without caps"); return GST_PAD_PROBE_OK; } if (!gst_video_info_from_caps (&info, caps)) { GST_ERROR ("allocation query with invalid caps"); return GST_PAD_PROBE_OK; } g_mutex_lock (state->queue_lock); pool = state->pool ? gst_object_ref (state->pool) : NULL; g_mutex_unlock (state->queue_lock); if (pool) { GstCaps *pcaps; /* we had a pool, check caps */ config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL); GST_DEBUG ("check existing pool caps %" GST_PTR_FORMAT " with new caps %" GST_PTR_FORMAT, pcaps, caps); if (!gst_caps_is_equal (caps, pcaps)) { GST_DEBUG ("pool has different caps"); /* different caps, we can't use this pool */ gst_object_unref (pool); pool = NULL; } gst_structure_free (config); } GST_DEBUG ("pool %p", pool); if (pool == NULL && need_pool) { GstVideoInfo info; if (!gst_video_info_from_caps (&info, caps)) { GST_ERROR ("allocation query has invalid caps %" GST_PTR_FORMAT, caps); return GST_PAD_PROBE_OK; } GST_DEBUG ("create new pool"); state->pool = pool = gst_egl_image_buffer_pool_new (state, state->display); GST_DEBUG ("done create new pool %p", pool); /* the normal size of a frame */ size = info.size; config = gst_buffer_pool_get_config (pool); /* we need at least 2 buffer because we hold on to the last one */ gst_buffer_pool_config_set_params (config, caps, size, 2, 0); gst_buffer_pool_config_set_allocator (config, NULL, ¶ms); if (!gst_buffer_pool_set_config (pool, config)) { gst_object_unref (pool); GST_ERROR ("failed to set pool configuration"); return GST_PAD_PROBE_OK; } } if (pool) { /* we need at least 2 buffer because we hold on to the last one */ gst_query_add_allocation_pool (query, pool, size, 2, 0); gst_object_unref (pool); } /* First the default allocator */ if (!gst_egl_image_memory_is_mappable ()) { allocator = gst_allocator_find (NULL); gst_query_add_allocation_param (query, allocator, ¶ms); gst_object_unref (allocator); } allocator = gst_egl_image_allocator_obtain (); GST_WARNING ("Allocator obtained %p", allocator); if (!gst_egl_image_memory_is_mappable ()) params.flags |= GST_MEMORY_FLAG_NOT_MAPPABLE; gst_query_add_allocation_param (query, allocator, ¶ms); gst_object_unref (allocator); gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, NULL); gst_query_add_allocation_meta (query, GST_VIDEO_CROP_META_API_TYPE, NULL); gst_query_add_allocation_meta (query, GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, NULL); GST_DEBUG ("done alocation"); return GST_PAD_PROBE_OK; } break; default: break; } return GST_PAD_PROBE_OK; }
static gboolean gst_wayland_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) { GstWaylandSink *sink = GST_WAYLAND_SINK (bsink); GstBufferPool *pool; GstStructure *config; GstCaps *caps; guint size; gboolean need_pool; gst_query_parse_allocation (query, &caps, &need_pool); if (caps == NULL) goto no_caps; g_mutex_lock (&sink->wayland_lock); if ((pool = sink->pool)) gst_object_ref (pool); g_mutex_unlock (&sink->wayland_lock); if (pool != NULL) { GstCaps *pcaps; /* we had a pool, check caps */ config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL); if (!gst_caps_is_equal (caps, pcaps)) { /* different caps, we can't use this pool */ gst_object_unref (pool); pool = NULL; } gst_structure_free (config); } if (pool == NULL && need_pool) { GstVideoInfo info; if (!gst_video_info_from_caps (&info, caps)) goto invalid_caps; GST_DEBUG_OBJECT (sink, "create new pool"); pool = gst_wayland_buffer_pool_new (sink); /* the normal size of a frame */ size = info.size; config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, 2, 0); if (!gst_buffer_pool_set_config (pool, config)) goto config_failed; } if (pool) { gst_query_add_allocation_pool (query, pool, size, 2, 0); gst_object_unref (pool); } return TRUE; /* ERRORS */ no_caps: { GST_DEBUG_OBJECT (bsink, "no caps specified"); return FALSE; } invalid_caps: { GST_DEBUG_OBJECT (bsink, "invalid caps specified"); return FALSE; } config_failed: { GST_DEBUG_OBJECT (bsink, "failed setting config"); gst_object_unref (pool); return FALSE; } }
static gboolean gst_glimage_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) { GstGLImageSink *glimage_sink; gint width; gint height; gboolean ok; gint par_n, par_d; gint display_par_n, display_par_d; guint display_ratio_num, display_ratio_den; GstVideoInfo vinfo; GstStructure *structure; GstBufferPool *newpool, *oldpool; GST_DEBUG ("set caps with %" GST_PTR_FORMAT, caps); glimage_sink = GST_GLIMAGE_SINK (bsink); ok = gst_video_info_from_caps (&vinfo, caps); if (!ok) return FALSE; width = GST_VIDEO_INFO_WIDTH (&vinfo); height = GST_VIDEO_INFO_HEIGHT (&vinfo); if (glimage_sink->tex_id) gst_gl_context_del_texture (glimage_sink->context, &glimage_sink->tex_id); //FIXME: this texture seems to be never deleted when going to STATE_NULL gst_gl_context_gen_texture (glimage_sink->context, &glimage_sink->tex_id, GST_VIDEO_INFO_FORMAT (&vinfo), width, height); par_n = GST_VIDEO_INFO_PAR_N (&vinfo); par_d = GST_VIDEO_INFO_PAR_D (&vinfo); if (!par_n) par_n = 1; /* get display's PAR */ if (glimage_sink->par_n != 0 && glimage_sink->par_d != 0) { display_par_n = glimage_sink->par_n; display_par_d = glimage_sink->par_d; } else { display_par_n = 1; display_par_d = 1; } ok = gst_video_calculate_display_ratio (&display_ratio_num, &display_ratio_den, width, height, par_n, par_d, display_par_n, display_par_d); if (!ok) return FALSE; GST_TRACE ("PAR: %u/%u DAR:%u/%u", par_n, par_d, display_par_n, display_par_d); if (height % display_ratio_den == 0) { GST_DEBUG ("keeping video height"); GST_VIDEO_SINK_WIDTH (glimage_sink) = (guint) gst_util_uint64_scale_int (height, display_ratio_num, display_ratio_den); GST_VIDEO_SINK_HEIGHT (glimage_sink) = height; } else if (width % display_ratio_num == 0) { GST_DEBUG ("keeping video width"); GST_VIDEO_SINK_WIDTH (glimage_sink) = width; GST_VIDEO_SINK_HEIGHT (glimage_sink) = (guint) gst_util_uint64_scale_int (width, display_ratio_den, display_ratio_num); } else { GST_DEBUG ("approximating while keeping video height"); GST_VIDEO_SINK_WIDTH (glimage_sink) = (guint) gst_util_uint64_scale_int (height, display_ratio_num, display_ratio_den); GST_VIDEO_SINK_HEIGHT (glimage_sink) = height; } GST_DEBUG ("scaling to %dx%d", GST_VIDEO_SINK_WIDTH (glimage_sink), GST_VIDEO_SINK_HEIGHT (glimage_sink)); glimage_sink->info = vinfo; newpool = gst_gl_buffer_pool_new (glimage_sink->context); structure = gst_buffer_pool_get_config (newpool); gst_buffer_pool_config_set_params (structure, caps, vinfo.size, 2, 0); gst_buffer_pool_set_config (newpool, structure); oldpool = glimage_sink->pool; /* we don't activate the pool yet, this will be done by downstream after it * has configured the pool. If downstream does not want our pool we will * activate it when we render into it */ glimage_sink->pool = newpool; /* unref the old sink */ if (oldpool) { /* we don't deactivate, some elements might still be using it, it will * be deactivated when the last ref is gone */ gst_object_unref (oldpool); } return TRUE; }
static gboolean gst_glimage_sink_propose_allocation (GstBaseSink * bsink, GstQuery * query) { GstGLImageSink *glimage_sink = GST_GLIMAGE_SINK (bsink); GstBufferPool *pool; GstStructure *config; GstCaps *caps; guint size; gboolean need_pool; GstStructure *gl_context; gchar *platform, *gl_apis; gpointer handle; if (!_ensure_gl_setup (glimage_sink)) return FALSE; gst_query_parse_allocation (query, &caps, &need_pool); if (caps == NULL) goto no_caps; if ((pool = glimage_sink->pool)) gst_object_ref (pool); if (pool != NULL) { GstCaps *pcaps; /* we had a pool, check caps */ GST_DEBUG_OBJECT (glimage_sink, "check existing pool caps"); config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_get_params (config, &pcaps, &size, NULL, NULL); if (!gst_caps_is_equal (caps, pcaps)) { GST_DEBUG_OBJECT (glimage_sink, "pool has different caps"); /* different caps, we can't use this pool */ gst_object_unref (pool); pool = NULL; } gst_structure_free (config); } if (pool == NULL && need_pool) { GstVideoInfo info; if (!gst_video_info_from_caps (&info, caps)) goto invalid_caps; GST_DEBUG_OBJECT (glimage_sink, "create new pool"); pool = gst_gl_buffer_pool_new (glimage_sink->context); /* the normal size of a frame */ size = info.size; config = gst_buffer_pool_get_config (pool); gst_buffer_pool_config_set_params (config, caps, size, 0, 0); if (!gst_buffer_pool_set_config (pool, config)) goto config_failed; } /* we need at least 2 buffer because we hold on to the last one */ gst_query_add_allocation_pool (query, pool, size, 2, 0); /* we also support various metadata */ gst_query_add_allocation_meta (query, GST_VIDEO_META_API_TYPE, 0); gst_object_unref (pool); gl_apis = gst_gl_api_to_string (gst_gl_context_get_gl_api (glimage_sink->context)); platform = gst_gl_platform_to_string (gst_gl_context_get_gl_platform (glimage_sink->context)); handle = (gpointer) gst_gl_context_get_gl_context (glimage_sink->context); gl_context = gst_structure_new ("GstVideoGLTextureUploadMeta", "gst.gl.GstGLContext", GST_GL_TYPE_CONTEXT, glimage_sink->context, "gst.gl.context.handle", G_TYPE_POINTER, handle, "gst.gl.context.type", G_TYPE_STRING, platform, "gst.gl.context.apis", G_TYPE_STRING, gl_apis, NULL); gst_query_add_allocation_meta (query, GST_VIDEO_GL_TEXTURE_UPLOAD_META_API_TYPE, gl_context); g_free (gl_apis); g_free (platform); gst_structure_free (gl_context); return TRUE; /* ERRORS */ no_caps: { GST_DEBUG_OBJECT (bsink, "no caps specified"); return FALSE; } invalid_caps: { GST_DEBUG_OBJECT (bsink, "invalid caps specified"); return FALSE; } config_failed: { GST_DEBUG_OBJECT (bsink, "failed setting config"); return FALSE; } }