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

📄 gstbasesink.c

📁 GStreamer是一个开源的多媒体框架库。利用它
💻 C
📖 第 1 页 / 共 5 页
字号:
}static GstFlowReturngst_base_sink_pad_buffer_alloc (GstPad * pad, guint64 offset, guint size,    GstCaps * caps, GstBuffer ** buf){  GstBaseSinkClass *bclass;  GstBaseSink *bsink;  GstFlowReturn result = GST_FLOW_OK;  bsink = GST_BASE_SINK (gst_pad_get_parent (pad));  bclass = GST_BASE_SINK_GET_CLASS (bsink);  if (bclass->buffer_alloc)    result = bclass->buffer_alloc (bsink, offset, size, caps, buf);  else    *buf = NULL;                /* fallback in gstpad.c will allocate generic buffer */  gst_object_unref (bsink);  return result;}static voidgst_base_sink_init (GstBaseSink * basesink, gpointer g_class){  GstPadTemplate *pad_template;  GstBaseSinkPrivate *priv;  basesink->priv = priv = GST_BASE_SINK_GET_PRIVATE (basesink);  pad_template =      gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "sink");  g_return_if_fail (pad_template != NULL);  basesink->sinkpad = gst_pad_new_from_template (pad_template, "sink");  gst_pad_set_getcaps_function (basesink->sinkpad,      GST_DEBUG_FUNCPTR (gst_base_sink_pad_getcaps));  gst_pad_set_setcaps_function (basesink->sinkpad,      GST_DEBUG_FUNCPTR (gst_base_sink_pad_setcaps));  gst_pad_set_fixatecaps_function (basesink->sinkpad,      GST_DEBUG_FUNCPTR (gst_base_sink_pad_fixate));  gst_pad_set_bufferalloc_function (basesink->sinkpad,      GST_DEBUG_FUNCPTR (gst_base_sink_pad_buffer_alloc));  gst_pad_set_activate_function (basesink->sinkpad,      GST_DEBUG_FUNCPTR (gst_base_sink_pad_activate));  gst_pad_set_activatepush_function (basesink->sinkpad,      GST_DEBUG_FUNCPTR (gst_base_sink_pad_activate_push));  gst_pad_set_activatepull_function (basesink->sinkpad,      GST_DEBUG_FUNCPTR (gst_base_sink_pad_activate_pull));  gst_pad_set_event_function (basesink->sinkpad,      GST_DEBUG_FUNCPTR (gst_base_sink_event));  gst_pad_set_chain_function (basesink->sinkpad,      GST_DEBUG_FUNCPTR (gst_base_sink_chain));  gst_element_add_pad (GST_ELEMENT_CAST (basesink), basesink->sinkpad);  basesink->pad_mode = GST_ACTIVATE_NONE;  basesink->preroll_queue = g_queue_new ();  basesink->abidata.ABI.clip_segment = gst_segment_new ();  basesink->can_activate_push = DEFAULT_CAN_ACTIVATE_PUSH;  basesink->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL;  basesink->sync = DEFAULT_SYNC;  basesink->abidata.ABI.max_lateness = DEFAULT_MAX_LATENESS;  gst_atomic_int_set (&priv->qos_enabled, DEFAULT_QOS);  GST_OBJECT_FLAG_SET (basesink, GST_ELEMENT_IS_SINK);}static voidgst_base_sink_finalize (GObject * object){  GstBaseSink *basesink;  basesink = GST_BASE_SINK (object);  g_queue_free (basesink->preroll_queue);  gst_segment_free (basesink->abidata.ABI.clip_segment);  G_OBJECT_CLASS (parent_class)->finalize (object);}/** * gst_base_sink_set_sync: * @sink: the sink * @sync: the new sync value. * * Configures @sink to synchronize on the clock or not. When * @sync is FALSE, incomming samples will be played as fast as * possible. If @sync is TRUE, the timestamps of the incomming * buffers will be used to schedule the exact render time of its * contents. * * Since: 0.10.4 */voidgst_base_sink_set_sync (GstBaseSink * sink, gboolean sync){  GST_OBJECT_LOCK (sink);  sink->sync = sync;  GST_OBJECT_UNLOCK (sink);}/** * gst_base_sink_get_sync: * @sink: the sink * * Checks if @sink is currently configured to synchronize against the * clock. * * Returns: TRUE if the sink is configured to synchronize against the clock. * * Since: 0.10.4 */gbooleangst_base_sink_get_sync (GstBaseSink * sink){  gboolean res;  GST_OBJECT_LOCK (sink);  res = sink->sync;  GST_OBJECT_UNLOCK (sink);  return res;}/** * gst_base_sink_set_max_lateness: * @sink: the sink * @max_lateness: the new max lateness value. * * Sets the new max lateness value to @max_lateness. This value is * used to decide if a buffer should be dropped or not based on the * buffer timestamp and the current clock time. A value of -1 means * an unlimited time. * * Since: 0.10.4 */voidgst_base_sink_set_max_lateness (GstBaseSink * sink, gint64 max_lateness){  GST_OBJECT_LOCK (sink);  sink->abidata.ABI.max_lateness = max_lateness;  GST_OBJECT_UNLOCK (sink);}/** * gst_base_sink_get_max_lateness: * @sink: the sink * * Gets the max lateness value. See gst_base_sink_set_max_lateness for * more details. * * Returns: The maximum time in nanoseconds that a buffer can be late * before it is dropped and not rendered. A value of -1 means an * unlimited time. * * Since: 0.10.4 */gint64gst_base_sink_get_max_lateness (GstBaseSink * sink){  gint64 res;  GST_OBJECT_LOCK (sink);  res = sink->abidata.ABI.max_lateness;  GST_OBJECT_UNLOCK (sink);  return res;}/** * gst_base_sink_set_qos_enabled: * @sink: the sink * @enabled: the new qos value. * * Configures @sink to send Quality-of-Service events upstream. * * Since: 0.10.5 */voidgst_base_sink_set_qos_enabled (GstBaseSink * sink, gboolean enabled){  gst_atomic_int_set (&sink->priv->qos_enabled, enabled);}/** * gst_base_sink_is_qos_enabled: * @sink: the sink * * Checks if @sink is currently configured to send Quality-of-Service events * upstream. * * Returns: TRUE if the sink is configured to perform Quality-of-Service. * * Since: 0.10.5 */gbooleangst_base_sink_is_qos_enabled (GstBaseSink * sink){  gboolean res;  res = g_atomic_int_get (&sink->priv->qos_enabled);  return res;}/** * gst_base_sink_get_latency: * @sink: the sink * * Get the currently configured latency. * * Returns: The configured latency. * * Since: 0.10.12 */GstClockTimegst_base_sink_get_latency (GstBaseSink * sink){  GstClockTime res;  GST_OBJECT_LOCK (sink);  res = sink->priv->latency;  GST_OBJECT_UNLOCK (sink);  return res;}/** * gst_base_sink_query_latency: * @sink: the sink * @live: if the sink is live * @upstream_live: if an upstream element is live * @min_latency: the min latency of the upstream elements * @max_latency: the max latency of the upstream elements * * Query the sink for the latency parameters. The latency will be queried from * the upstream elements. @live will be TRUE if @sink is configured to * synchronize against the clock. @upstream_live will be TRUE if an upstream * element is live.  * * If both @live and @upstream_live are TRUE, the sink will want to compensate * for the latency introduced by the upstream elements by setting the * @min_latency to a strictly possitive value. * * This function is mostly used by subclasses.  * * Returns: TRUE if the query succeeded. * * Since: 0.10.12 */gbooleangst_base_sink_query_latency (GstBaseSink * sink, gboolean * live,    gboolean * upstream_live, GstClockTime * min_latency,    GstClockTime * max_latency){  gboolean l, us_live, res;  GstClockTime min, max;  GstQuery *query;  GstClockTime us_min, us_max;  /* we are live when we sync to the clock */  l = gst_base_sink_get_sync (sink);  /* assume no latency */  min = 0;  max = -1;  us_live = FALSE;  query = gst_query_new_latency ();  /* ask the peer for the latency */  if (!(res = gst_base_sink_peer_query (sink, query)))    goto query_failed;  /* get upstream min and max latency */  gst_query_parse_latency (query, &us_live, &us_min, &us_max);  if (us_live) {    /* upstream live, use its latency, subclasses should use these     * values to create the complete latency. */    min = us_min;    max = us_max;  }  GST_DEBUG_OBJECT (sink, "latency query: live: %d, upstream: %d, min %"      GST_TIME_FORMAT ", max %" GST_TIME_FORMAT, l, us_live,      GST_TIME_ARGS (min), GST_TIME_ARGS (max));  if (live)    *live = l;  if (upstream_live)    *upstream_live = us_live;  if (min_latency)    *min_latency = min;  if (max_latency)    *max_latency = max;done:  gst_query_unref (query);  return res;  /* ERRORS */query_failed:  {    GST_DEBUG_OBJECT (sink, "latency query failed");    goto done;  }}static voidgst_base_sink_set_property (GObject * object, guint prop_id,    const GValue * value, GParamSpec * pspec){  GstBaseSink *sink = GST_BASE_SINK (object);  switch (prop_id) {    case PROP_PREROLL_QUEUE_LEN:      /* preroll lock necessary to serialize with finish_preroll */      GST_PAD_PREROLL_LOCK (sink->sinkpad);      sink->preroll_queue_max_len = g_value_get_uint (value);      GST_PAD_PREROLL_UNLOCK (sink->sinkpad);      break;    case PROP_SYNC:      gst_base_sink_set_sync (sink, g_value_get_boolean (value));      break;    case PROP_MAX_LATENESS:      gst_base_sink_set_max_lateness (sink, g_value_get_int64 (value));      break;    case PROP_QOS:      gst_base_sink_set_qos_enabled (sink, g_value_get_boolean (value));      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);      break;  }}static voidgst_base_sink_get_property (GObject * object, guint prop_id, GValue * value,    GParamSpec * pspec){  GstBaseSink *sink = GST_BASE_SINK (object);  switch (prop_id) {    case PROP_PREROLL_QUEUE_LEN:      GST_PAD_PREROLL_LOCK (sink->sinkpad);      g_value_set_uint (value, sink->preroll_queue_max_len);      GST_PAD_PREROLL_UNLOCK (sink->sinkpad);      break;    case PROP_SYNC:      g_value_set_boolean (value, gst_base_sink_get_sync (sink));      break;    case PROP_MAX_LATENESS:      g_value_set_int64 (value, gst_base_sink_get_max_lateness (sink));      break;    case PROP_QOS:      g_value_set_boolean (value, gst_base_sink_is_qos_enabled (sink));      break;    default:      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);      break;  }}static GstCaps *gst_base_sink_get_caps (GstBaseSink * sink){  return NULL;}static gbooleangst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps){  return TRUE;}static GstFlowReturngst_base_sink_buffer_alloc (GstBaseSink * sink, guint64 offset, guint size,    GstCaps * caps, GstBuffer ** buf){  *buf = NULL;  return GST_FLOW_OK;}/* with PREROLL_LOCK, STREAM_LOCK */static voidgst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad){  GstMiniObject *obj;  GST_DEBUG_OBJECT (basesink, "flushing queue %p", basesink);  while ((obj = g_queue_pop_head (basesink->preroll_queue))) {    GST_DEBUG_OBJECT (basesink, "popped %p", obj);    gst_mini_object_unref (obj);  }  /* we can't have EOS anymore now */  basesink->eos = FALSE;  basesink->eos_queued = FALSE;  basesink->preroll_queued = 0;  basesink->buffers_queued = 0;  basesink->events_queued = 0;  basesink->have_preroll = FALSE;  /* and signal any waiters now */  GST_PAD_PREROLL_SIGNAL (pad);}/* with STREAM_LOCK, configures given segment with the event information. */static voidgst_base_sink_configure_segment (GstBaseSink * basesink, GstPad * pad,    GstEvent * event, GstSegment * segment){  gboolean update;  gdouble rate, arate;  GstFormat format;  gint64 start;  gint64 stop;  gint64 time;  /* the newsegment event is needed to bring the buffer timestamps to the   * stream time and to drop samples outside of the playback segment. */  gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,      &start, &stop, &time);  /* The segment is protected with both the STREAM_LOCK and the OBJECT_LOCK.   * We protect with the OBJECT_LOCK so that we can use the values to   * safely answer a POSITION query. */  GST_OBJECT_LOCK (basesink);  gst_segment_set_newsegment_full (segment, update, rate, arate, format, start,      stop, time);

⌨️ 快捷键说明

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