⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gstcollectpads.c

📁 gnash 在pc和嵌入式下开发需要的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* GStreamer * Copyright (C) 2005 Wim Taymans <wim@fluendo.com> * * gstcollectpads.c: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//** * SECTION:gstcollectpads * @short_description: manages a set of pads that operate in collect mode * @see_also: * * Manages a set of pads that operate in collect mode. This means that control * is given to the manager of this object when all pads have data. * <itemizedlist> *   <listitem><para> *     Collectpads are created with gst_collect_pads_new(). A callback should then *     be installed with gst_collect_pads_set_function ().  *   </para></listitem> *   <listitem><para> *     Pads are added to the collection with gst_collect_pads_add_pad()/ *     gst_collect_pads_remove_pad(). The pad *     has to be a sinkpad. The chain and event functions of the pad are *     overridden. The element_private of the pad is used to store *     private information for the collectpads. *   </para></listitem> *   <listitem><para> *     For each pad, data is queued in the _chain function or by *     performing a pull_range. *   </para></listitem> *   <listitem><para> *     When data is queued on all pads, the callback function is called. *   </para></listitem> *   <listitem><para> *     Data can be dequeued from the pad with the gst_collect_pads_pop() method. *     One can peek at the data with the gst_collect_pads_peek() function. *     These functions will return NULL if the pad received an EOS event. When all *     pads return NULL from a gst_collect_pads_peek(), the element can emit an EOS *     event itself. *   </para></listitem> *   <listitem><para> *     Data can also be dequeued in byte units using the gst_collect_pads_available(),  *     gst_collect_pads_read() and gst_collect_pads_flush() calls. *   </para></listitem> *   <listitem><para> *     Elements should call gst_collect_pads_start() and gst_collect_pads_stop() in *     their state change functions to start and stop the processing of the collecpads. *     The gst_collect_pads_stop() call should be called before calling the parent *     element state change function in the PAUSED_TO_READY state change to ensure *     no pad is blocked and the element can finish streaming. *   </para></listitem> *   <listitem><para> *     gst_collect_pads_collect() and gst_collect_pads_collect_range() can be used by *     elements that start a #GstTask to drive the collect_pads. This feature is however *     not yet implemented. *   </para></listitem> * </itemizedlist> * * Last reviewed on 2006-05-10 (0.10.6) */#include "gstcollectpads.h"GST_DEBUG_CATEGORY_STATIC (collect_pads_debug);#define GST_CAT_DEFAULT collect_pads_debugGST_BOILERPLATE (GstCollectPads, gst_collect_pads, GstObject, GST_TYPE_OBJECT);static void gst_collect_pads_clear (GstCollectPads * pads,    GstCollectData * data);static GstFlowReturn gst_collect_pads_chain (GstPad * pad, GstBuffer * buffer);static gboolean gst_collect_pads_event (GstPad * pad, GstEvent * event);static void gst_collect_pads_finalize (GObject * object);static void gst_collect_pads_init (GstCollectPads * pads,    GstCollectPadsClass * g_class);static void ref_data (GstCollectData * data);static void unref_data (GstCollectData * data);static voidgst_collect_pads_base_init (gpointer g_class){  GST_DEBUG_CATEGORY_INIT (collect_pads_debug, "collectpads", 0,      "GstCollectPads");}static voidgst_collect_pads_class_init (GstCollectPadsClass * klass){  GObjectClass *gobject_class = (GObjectClass *) klass;  gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_collect_pads_finalize);}static voidgst_collect_pads_init (GstCollectPads * pads, GstCollectPadsClass * g_class){  pads->cond = g_cond_new ();  pads->data = NULL;  pads->cookie = 0;  pads->numpads = 0;  pads->queuedpads = 0;  pads->eospads = 0;  pads->started = FALSE;  /* members to manage the pad list */  pads->abidata.ABI.pad_lock = g_mutex_new ();  pads->abidata.ABI.pad_cookie = 0;  pads->abidata.ABI.pad_list = NULL;}static voidgst_collect_pads_finalize (GObject * object){  GSList *collected;  GstCollectPads *pads = GST_COLLECT_PADS (object);  GST_DEBUG ("finalize");  g_cond_free (pads->cond);  g_mutex_free (pads->abidata.ABI.pad_lock);  /* Remove pads */  collected = pads->abidata.ABI.pad_list;  for (; collected; collected = g_slist_next (collected)) {    GstCollectData *pdata = (GstCollectData *) collected->data;    unref_data (pdata);  }  /* Free pads list */  g_slist_foreach (pads->data, (GFunc) unref_data, NULL);  g_slist_free (pads->data);  g_slist_free (pads->abidata.ABI.pad_list);  G_OBJECT_CLASS (parent_class)->finalize (object);}/** * gst_collect_pads_new: * * Create a new instance of #GstCollectsPads. * * Returns: a new #GstCollectPads, or NULL in case of an error. * * MT safe. */GstCollectPads *gst_collect_pads_new (void){  GstCollectPads *newcoll;  newcoll = g_object_new (GST_TYPE_COLLECT_PADS, NULL);  return newcoll;}/** * gst_collect_pads_set_function: * @pads: the collectspads to use * @func: the function to set * @user_data: user data passed to the function * * Set the callback function and user data that will be called when * all the pads added to the collection have buffers queued. * * MT safe. */voidgst_collect_pads_set_function (GstCollectPads * pads,    GstCollectPadsFunction func, gpointer user_data){  g_return_if_fail (pads != NULL);  g_return_if_fail (GST_IS_COLLECT_PADS (pads));  GST_OBJECT_LOCK (pads);  pads->func = func;  pads->user_data = user_data;  GST_OBJECT_UNLOCK (pads);}static voidref_data (GstCollectData * data){  g_assert (data != NULL);  g_atomic_int_inc (&(data->abidata.ABI.refcount));}static voidunref_data (GstCollectData * data){  GstCollectDataDestroyNotify destroy_notify;  g_assert (data != NULL);  g_assert (data->abidata.ABI.refcount > 0);  if (!g_atomic_int_dec_and_test (&(data->abidata.ABI.refcount)))    return;  /* FIXME: Ugly hack as we can't add more fields to GstCollectData */  destroy_notify = (GstCollectDataDestroyNotify)      g_object_get_data (G_OBJECT (data->pad),      "gst-collect-data-destroy-notify");  if (destroy_notify)    destroy_notify (data);  g_object_unref (data->pad);  if (data->buffer) {    gst_buffer_unref (data->buffer);  }  g_free (data);}/** * gst_collect_pads_add_pad: * @pads: the collectspads to use * @pad: the pad to add * @size: the size of the returned #GstCollectData structure * * Add a pad to the collection of collect pads. The pad has to be * a sinkpad. The refcount of the pad is incremented. Use * gst_collect_pads_remove_pad() to remove the pad from the collection * again. * * You specify a size for the returned #GstCollectData structure * so that you can use it to store additional information. * * The pad will be automatically activated in push mode when @pads is * started. * * This function calls gst_collect_pads_add_pad() passing a value of NULL * for destroy_notify. * * Returns: a new #GstCollectData to identify the new pad. Or NULL *   if wrong parameters are supplied. * * MT safe. */GstCollectData *gst_collect_pads_add_pad (GstCollectPads * pads, GstPad * pad, guint size){  return gst_collect_pads_add_pad_full (pads, pad, size, NULL);}/** * gst_collect_pads_add_pad_full: * @pads: the collectspads to use * @pad: the pad to add * @size: the size of the returned #GstCollectData structure * @destroy_notify: function to be called before the returned #GstCollectData * structure is freed * * Add a pad to the collection of collect pads. The pad has to be * a sinkpad. The refcount of the pad is incremented. Use * gst_collect_pads_remove_pad() to remove the pad from the collection * again. * * You specify a size for the returned #GstCollectData structure * so that you can use it to store additional information. * * You can also specify a #GstCollectDataDestroyNotify that will be called * just before the #GstCollectData structure is freed. It is passed the * pointer to the structure and should free any custom memory and resources * allocated for it. * * The pad will be automatically activated in push mode when @pads is * started. * * Since: 0.10.12 * * Returns: a new #GstCollectData to identify the new pad. Or NULL *   if wrong parameters are supplied. * * MT safe. */GstCollectData *gst_collect_pads_add_pad_full (GstCollectPads * pads, GstPad * pad, guint size,    GstCollectDataDestroyNotify destroy_notify){  GstCollectData *data;  g_return_val_if_fail (pads != NULL, NULL);  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), NULL);  g_return_val_if_fail (pad != NULL, NULL);  g_return_val_if_fail (GST_PAD_IS_SINK (pad), NULL);  g_return_val_if_fail (size >= sizeof (GstCollectData), NULL);  GST_DEBUG ("adding pad %s:%s", GST_DEBUG_PAD_NAME (pad));  data = g_malloc0 (size);  data->collect = pads;  data->pad = gst_object_ref (pad);  data->buffer = NULL;  data->pos = 0;  gst_segment_init (&data->segment, GST_FORMAT_UNDEFINED);  data->abidata.ABI.flushing = FALSE;  data->abidata.ABI.new_segment = FALSE;  data->abidata.ABI.eos = FALSE;  data->abidata.ABI.refcount = 1;  /* FIXME: Ugly hack as we can't add more fields to GstCollectData */  g_object_set_data (G_OBJECT (pad), "gst-collect-data-destroy-notify",      (void *) destroy_notify);  GST_COLLECT_PADS_PAD_LOCK (pads);  GST_OBJECT_LOCK (pad);  gst_pad_set_element_private (pad, data);  GST_OBJECT_UNLOCK (pad);  pads->abidata.ABI.pad_list =      g_slist_append (pads->abidata.ABI.pad_list, data);  gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_collect_pads_chain));  gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_collect_pads_event));  /* activate the pad when needed */  if (pads->started)    gst_pad_set_active (pad, TRUE);  pads->abidata.ABI.pad_cookie++;  GST_COLLECT_PADS_PAD_UNLOCK (pads);  return data;}static gintfind_pad (GstCollectData * data, GstPad * pad){  if (data->pad == pad)    return 0;  return 1;}/** * gst_collect_pads_remove_pad: * @pads: the collectspads to use * @pad: the pad to remove * * Remove a pad from the collection of collect pads. This function will also * free the #GstCollectData and all the resources that were allocated with  * gst_collect_pads_add_pad(). * * The pad will be deactivated automatically when @pads is stopped. * * Returns: %TRUE if the pad could be removed. * * MT safe. */gbooleangst_collect_pads_remove_pad (GstCollectPads * pads, GstPad * pad){  GstCollectData *data;  GSList *list;  g_return_val_if_fail (pads != NULL, FALSE);  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), FALSE);  g_return_val_if_fail (pad != NULL, FALSE);  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);  GST_DEBUG ("removing pad %s:%s", GST_DEBUG_PAD_NAME (pad));  GST_COLLECT_PADS_PAD_LOCK (pads);  list =      g_slist_find_custom (pads->abidata.ABI.pad_list, pad,      (GCompareFunc) find_pad);  if (!list)    goto unknown_pad;  data = (GstCollectData *) list->data;  GST_DEBUG ("found pad %s:%s at %p", GST_DEBUG_PAD_NAME (pad), data);  /* clear the stuff we configured */  gst_pad_set_chain_function (pad, NULL);  gst_pad_set_event_function (pad, NULL);  GST_OBJECT_LOCK (pad);  gst_pad_set_element_private (pad, NULL);  GST_OBJECT_UNLOCK (pad);  /* backward compat, also remove from data if stopped, note that this function   * can only be called when we are stopped because we don't take the LOCK to   * protect the pads->data list. */  if (!pads->started) {    GSList *dlist;    dlist = g_slist_find_custom (pads->data, pad, (GCompareFunc) find_pad);    if (dlist) {      GstCollectData *pdata = dlist->data;      pads->data = g_slist_delete_link (pads->data, dlist);      unref_data (pdata);    }  }  /* remove from the pad list */  pads->abidata.ABI.pad_list =      g_slist_delete_link (pads->abidata.ABI.pad_list, list);  pads->abidata.ABI.pad_cookie++;  /* signal waiters because something changed */  GST_COLLECT_PADS_BROADCAST (pads);  /* deactivate the pad when needed */  if (!pads->started)    gst_pad_set_active (pad, FALSE);  /* clean and free the collect data */  unref_data (data);  GST_COLLECT_PADS_PAD_UNLOCK (pads);  return TRUE;unknown_pad:  {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -