📄 gstbasesrc.c
字号:
gst_pad_set_fixatecaps_function (pad, GST_DEBUG_FUNCPTR (gst_base_src_fixate)); /* hold pointer to pad */ basesrc->srcpad = pad; GST_DEBUG_OBJECT (basesrc, "adding src pad"); gst_element_add_pad (GST_ELEMENT (basesrc), pad); basesrc->blocksize = DEFAULT_BLOCKSIZE; basesrc->clock_id = NULL; /* we operate in BYTES by default */ gst_base_src_set_format (basesrc, GST_FORMAT_BYTES); basesrc->data.ABI.typefind = DEFAULT_TYPEFIND; basesrc->priv->do_timestamp = DEFAULT_DO_TIMESTAMP; GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED); GST_DEBUG_OBJECT (basesrc, "init done");}static voidgst_base_src_finalize (GObject * object){ GstBaseSrc *basesrc; GstEvent **event_p; basesrc = GST_BASE_SRC (object); g_mutex_free (basesrc->live_lock); g_cond_free (basesrc->live_cond); event_p = &basesrc->data.ABI.pending_seek; gst_event_replace (event_p, NULL); G_OBJECT_CLASS (parent_class)->finalize (object);}/** * gst_base_src_wait_playing: * @src: the src * * If the #GstBaseSrcClass::create method performs its own synchronisation against * the clock it must unblock when going from PLAYING to the PAUSED state and call * this method before continuing to produce the remaining data. * * This function will block until a state change to PLAYING happens (in which * case this function returns #GST_FLOW_OK) or the processing must be stopped due * to a state change to READY or a FLUSH event (in which case this function * returns #GST_FLOW_WRONG_STATE). * * Since: 0.10.12 * * Returns: #GST_FLOW_OK if @src is PLAYING and processing can * continue. Any other return value should be returned from the create vmethod. */GstFlowReturngst_base_src_wait_playing (GstBaseSrc * src){ /* block until the state changes, or we get a flush, or something */ if (src->is_live) { while (G_UNLIKELY (!src->live_running)) { GST_DEBUG ("live source signal waiting"); GST_LIVE_SIGNAL (src); GST_DEBUG ("live source waiting for running state"); GST_LIVE_WAIT (src); GST_DEBUG ("live source unlocked"); } if (src->priv->flushing) goto flushing; } return GST_FLOW_OK; /* ERRORS */flushing: { GST_DEBUG_OBJECT (src, "we are flushing"); return GST_FLOW_WRONG_STATE; }}/** * gst_base_src_set_live: * @src: base source instance * @live: new live-mode * * If the element listens to a live source, @live should * be set to %TRUE. * * A live source will not produce data in the PAUSED state and * will therefore not be able to participate in the PREROLL phase * of a pipeline. To signal this fact to the application and the * pipeline, the state change return value of the live source will * be GST_STATE_CHANGE_NO_PREROLL. */voidgst_base_src_set_live (GstBaseSrc * src, gboolean live){ GST_OBJECT_LOCK (src); src->is_live = live; GST_OBJECT_UNLOCK (src);}/** * gst_base_src_is_live: * @src: base source instance * * Check if an element is in live mode. * * Returns: %TRUE if element is in live mode. */gbooleangst_base_src_is_live (GstBaseSrc * src){ gboolean result; GST_OBJECT_LOCK (src); result = src->is_live; GST_OBJECT_UNLOCK (src); return result;}/** * gst_base_src_set_format: * @src: base source instance * @format: the format to use * * Sets the default format of the source. This will be the format used * for sending NEW_SEGMENT events and for performing seeks. * * If a format of GST_FORMAT_BYTES is set, the element will be able to * operate in pull mode if the #GstBaseSrc::is_seekable returns TRUE. * * Since: 0.10.1 */voidgst_base_src_set_format (GstBaseSrc * src, GstFormat format){ gst_segment_init (&src->segment, format);}/** * gst_base_src_query_latency: * @src: the source * @live: if the source is live * @min_latency: the min latency of the source * @max_latency: the max latency of the source * * Query the source for the latency parameters. @live will be TRUE when @src is * configured as a live source. @min_latency will be set to the difference * between the running time and the timestamp of the first buffer. * @max_latency is always the undefined value of -1. * * This function is mostly used by subclasses. * * Returns: TRUE if the query succeeded. * * Since: 0.10.13 */gbooleangst_base_src_query_latency (GstBaseSrc * src, gboolean * live, GstClockTime * min_latency, GstClockTime * max_latency){ GstClockTime min; GST_OBJECT_LOCK (src); if (live) *live = src->is_live; /* if we have a startup latency, report this one, else report 0. Subclasses * are supposed to override the query function if they want something * else. */ if (src->priv->latency != -1) min = src->priv->latency; else min = 0; if (min_latency) *min_latency = min; if (max_latency) *max_latency = -1; GST_LOG_OBJECT (src, "latency: live %d, min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT, src->is_live, GST_TIME_ARGS (min), GST_TIME_ARGS (-1)); GST_OBJECT_UNLOCK (src); return TRUE;}/** * gst_base_src_set_do_timestamp: * @src: the source * @timestamp: enable or disable timestamping * * Configure @src to automatically timestamp outgoing buffers based on the * current running_time of the pipeline. This property is mostly useful for live * sources. * * Since: 0.10.15 */voidgst_base_src_set_do_timestamp (GstBaseSrc * src, gboolean timestamp){ GST_OBJECT_LOCK (src); src->priv->do_timestamp = timestamp; GST_OBJECT_UNLOCK (src);}/** * gst_base_src_get_do_timestamp: * @src: the source * * Query if @src timestamps outgoing buffers based on the current running_time. * * Returns: %TRUE if the base class will automatically timestamp outgoing buffers. * * Since: 0.10.15 */gbooleangst_base_src_get_do_timestamp (GstBaseSrc * src){ gboolean res; GST_OBJECT_LOCK (src); res = src->priv->do_timestamp; GST_OBJECT_UNLOCK (src); return res;}static gbooleangst_base_src_setcaps (GstPad * pad, GstCaps * caps){ GstBaseSrcClass *bclass; GstBaseSrc *bsrc; gboolean res = TRUE; bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad)); bclass = GST_BASE_SRC_GET_CLASS (bsrc); if (bclass->set_caps) res = bclass->set_caps (bsrc, caps); return res;}static GstCaps *gst_base_src_getcaps (GstPad * pad){ GstBaseSrcClass *bclass; GstBaseSrc *bsrc; GstCaps *caps = NULL; bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad)); bclass = GST_BASE_SRC_GET_CLASS (bsrc); if (bclass->get_caps) caps = bclass->get_caps (bsrc); if (caps == NULL) { GstPadTemplate *pad_template; pad_template = gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src"); if (pad_template != NULL) { caps = gst_caps_ref (gst_pad_template_get_caps (pad_template)); } } return caps;}static voidgst_base_src_fixate (GstPad * pad, GstCaps * caps){ GstBaseSrcClass *bclass; GstBaseSrc *bsrc; bsrc = GST_BASE_SRC (gst_pad_get_parent (pad)); bclass = GST_BASE_SRC_GET_CLASS (bsrc); if (bclass->fixate) bclass->fixate (bsrc, caps); gst_object_unref (bsrc);}static gbooleangst_base_src_default_query (GstBaseSrc * src, GstQuery * query){ gboolean res; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_POSITION: { GstFormat format; gst_query_parse_position (query, &format, NULL); switch (format) { case GST_FORMAT_PERCENT: { gint64 percent; gint64 position; gint64 duration; position = src->segment.last_stop; duration = src->segment.duration; if (position != -1 && duration != -1) { if (position < duration) percent = gst_util_uint64_scale (GST_FORMAT_PERCENT_MAX, position, duration); else percent = GST_FORMAT_PERCENT_MAX; } else percent = -1; gst_query_set_position (query, GST_FORMAT_PERCENT, percent); res = TRUE; break; } default: { gint64 position; position = src->segment.last_stop; if (position != -1) { /* convert to requested format */ res = gst_pad_query_convert (src->srcpad, src->segment.format, position, &format, &position); } else res = TRUE; gst_query_set_position (query, format, position); break; } } break; } case GST_QUERY_DURATION: { GstFormat format; gst_query_parse_duration (query, &format, NULL); GST_DEBUG_OBJECT (src, "duration query in format %s", gst_format_get_name (format)); switch (format) { case GST_FORMAT_PERCENT: gst_query_set_duration (query, GST_FORMAT_PERCENT, GST_FORMAT_PERCENT_MAX); res = TRUE; break; default: { gint64 duration; /* this is the duration as configured by the subclass. */ duration = src->segment.duration; if (duration != -1) { /* convert to requested format, if this fails, we have a duration * but we cannot answer the query, we must return FALSE. */ res = gst_pad_query_convert (src->srcpad, src->segment.format, duration, &format, &duration); } else { /* The subclass did not configure a duration, we assume that the * media has an unknown duration then and we return TRUE to report * this. Note that this is not the same as returning FALSE, which * means that we cannot report the duration at all. */ res = TRUE; } gst_query_set_duration (query, format, duration); break; } } break; } case GST_QUERY_SEEKING: { gst_query_set_seeking (query, src->segment.format, src->seekable, 0, src->segment.duration); res = TRUE; break; } case GST_QUERY_SEGMENT: { gint64 start, stop; /* no end segment configured, current duration then */ if ((stop = src->segment.stop) == -1) stop = src->segment.duration; start = src->segment.start; /* adjust to stream time */ if (src->segment.time != -1) { start -= src->segment.time; if (stop != -1) stop -= src->segment.time; } gst_query_set_segment (query, src->segment.rate, src->segment.format, start, stop); res = TRUE; break; } case GST_QUERY_FORMATS: { gst_query_set_formats (query, 3, GST_FORMAT_DEFAULT, GST_FORMAT_BYTES, GST_FORMAT_PERCENT); res = TRUE; break; } case GST_QUERY_CONVERT: { GstFormat src_fmt, dest_fmt; gint64 src_val, dest_val; gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val); /* we can only convert between equal formats... */ if (src_fmt == dest_fmt) { dest_val = src_val;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -