static gboolean gst_rtp_dtmf_src_query (GstBaseSrc * basesrc, GstQuery * query) { GstRTPDTMFSrc *dtmfsrc = GST_RTP_DTMF_SRC (basesrc); gboolean res = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime latency; latency = dtmfsrc->ptime * GST_MSECOND; gst_query_set_latency (query, gst_base_src_is_live (basesrc), latency, GST_CLOCK_TIME_NONE); GST_DEBUG_OBJECT (dtmfsrc, "Reporting latency of %" GST_TIME_FORMAT, GST_TIME_ARGS (latency)); res = TRUE; } break; default: res = GST_BASE_SRC_CLASS (gst_rtp_dtmf_src_parent_class)->query (basesrc, query); break; } return res; }
static gboolean gst_mio_video_src_query (GstBaseSrc * basesrc, GstQuery * query) { GstMIOVideoSrc *self = GST_MIO_VIDEO_SRC_CAST (basesrc); gboolean result = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY:{ GstClockTime min_latency, max_latency; if (self->device == NULL) goto beach; if (gst_mio_video_device_get_selected_format (self->device) == NULL) goto beach; min_latency = max_latency = gst_mio_video_device_get_duration (self->device); GST_DEBUG_OBJECT (self, "reporting latency of min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); gst_query_set_latency (query, TRUE, min_latency, max_latency); result = TRUE; break; } default: result = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); break; } beach: return result; }
static gboolean gst_wasapi_src_query (GstBaseSrc * src, GstQuery * query) { GstWasapiSrc *self = GST_WASAPI_SRC (src); gboolean ret = FALSE; GST_DEBUG_OBJECT (self, "query for %s", gst_query_type_get_name (GST_QUERY_TYPE (query))); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY:{ GstClockTime min_latency, max_latency; min_latency = self->latency + self->period_time; max_latency = min_latency; GST_DEBUG_OBJECT (self, "reporting latency of min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); gst_query_set_latency (query, TRUE, min_latency, max_latency); ret = TRUE; break; } default: ret = GST_BASE_SRC_CLASS (parent_class)->query (src, query); break; } return ret; }
static gboolean gst_rdt_manager_query_src (GstPad * pad, GstObject * parent, GstQuery * query) { GstRDTManager *rdtmanager; gboolean res; rdtmanager = GST_RDT_MANAGER (parent); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime latency; latency = rdtmanager->latency * GST_MSECOND; /* we pretend to be live with a 3 second latency */ gst_query_set_latency (query, TRUE, latency, -1); GST_DEBUG_OBJECT (rdtmanager, "reporting %" GST_TIME_FORMAT " of latency", GST_TIME_ARGS (latency)); res = TRUE; break; } default: res = gst_pad_query_default (pad, parent, query); break; } return res; }
static gboolean gst_cel_video_src_query (GstBaseSrc * basesrc, GstQuery * query) { GstCelVideoSrc *self = GST_CEL_VIDEO_SRC_CAST (basesrc); gboolean result = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY:{ GstClockTime min_latency, max_latency; if (self->device == NULL || !GST_CLOCK_TIME_IS_VALID (self->duration)) goto beach; min_latency = max_latency = self->duration; GST_DEBUG_OBJECT (self, "reporting latency of min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); gst_query_set_latency (query, TRUE, min_latency, max_latency); result = TRUE; break; } default: result = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); break; } beach: return result; }
static gboolean gst_app_src_query (GstBaseSrc * src, GstQuery * query) { GstAppSrc *appsrc = GST_APP_SRC_CAST (src); GstAppSrcPrivate *priv = appsrc->priv; gboolean res; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min, max; gboolean live; /* Query the parent class for the defaults */ res = gst_base_src_query_latency (src, &live, &min, &max); /* overwrite with our values when we need to */ g_mutex_lock (priv->mutex); if (priv->min_latency != -1) min = priv->min_latency; if (priv->max_latency != -1) max = priv->max_latency; g_mutex_unlock (priv->mutex); gst_query_set_latency (query, live, min, max); break; } default: res = GST_BASE_SRC_CLASS (parent_class)->query (src, query); break; } return res; }
static gboolean gst_decklink_video_src_query (GstBaseSrc * bsrc, GstQuery * query) { GstDecklinkVideoSrc *self = GST_DECKLINK_VIDEO_SRC_CAST (bsrc); gboolean ret = TRUE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY:{ if (self->input) { GstClockTime min, max; const GstDecklinkMode *mode; g_mutex_lock (&self->lock); mode = gst_decklink_get_mode (self->caps_mode); g_mutex_unlock (&self->lock); min = gst_util_uint64_scale_ceil (GST_SECOND, mode->fps_d, mode->fps_n); max = self->buffer_size * min; gst_query_set_latency (query, TRUE, min, max); ret = TRUE; } else { ret = FALSE; } break; } default: ret = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query); break; } return ret; }
static gboolean gst_niimaqsrc_query (GstBaseSrc * bsrc, GstQuery * query) { GstNiImaqSrc *src = GST_NIIMAQSRC (bsrc); gboolean res; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY:{ if (!src->session_started) { GST_WARNING_OBJECT (src, "Can't give latency since device isn't open!"); res = FALSE; } else { GstClockTime min_latency, max_latency; /* TODO: this is a ballpark figure, estimate from FVAL times */ min_latency = 33 * GST_MSECOND; max_latency = 33 * GST_MSECOND * src->bufsize; GST_LOG_OBJECT (src, "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); gst_query_set_latency (query, TRUE, min_latency, max_latency); res = TRUE; } } default: res = GST_BASE_SRC_CLASS (gst_niimaqsrc_parent_class)->query (bsrc, query); break; } return res; }
static gboolean gst_inter_audio_src_query (GstBaseSrc * src, GstQuery * query) { GstInterAudioSrc *interaudiosrc = GST_INTER_AUDIO_SRC (src); gboolean ret; GST_DEBUG_OBJECT (src, "query"); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY:{ GstClockTime min_latency, max_latency; min_latency = interaudiosrc->latency_time; max_latency = interaudiosrc->buffer_time; GST_DEBUG_OBJECT (src, "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); gst_query_set_latency (query, gst_base_src_is_live (src), min_latency, max_latency); ret = TRUE; break; } default: ret = GST_BASE_SRC_CLASS (gst_inter_audio_src_parent_class)->query (src, query); break; } return ret; }
static gboolean gst_ks_video_src_query (GstBaseSrc * basesrc, GstQuery * query) { GstKsVideoSrc *self = GST_KS_VIDEO_SRC (basesrc); GstKsVideoSrcPrivate *priv = GST_KS_VIDEO_SRC_GET_PRIVATE (self); gboolean result = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY:{ GstClockTime min_latency, max_latency; if (priv->device == NULL) goto beach; result = gst_ks_video_device_get_latency (priv->device, &min_latency, &max_latency); if (!result) goto beach; GST_DEBUG_OBJECT (self, "reporting latency of min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); gst_query_set_latency (query, TRUE, min_latency, max_latency); break; } default: result = GST_BASE_SRC_CLASS (parent_class)->query (basesrc, query); break; } beach: return result; }
static gboolean gst_goom_src_query (GstPad * pad, GstQuery * query) { gboolean res = FALSE; GstGoom *goom; goom = GST_GOOM (gst_pad_get_parent (pad)); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { /* We need to send the query upstream and add the returned latency to our * own */ GstClockTime min_latency, max_latency; gboolean us_live; GstClockTime our_latency; guint max_samples; if (goom->rate == 0) break; if ((res = gst_pad_peer_query (goom->sinkpad, query))) { gst_query_parse_latency (query, &us_live, &min_latency, &max_latency); GST_DEBUG_OBJECT (goom, "Peer latency: min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); /* the max samples we must buffer buffer */ max_samples = MAX (GOOM_SAMPLES, goom->spf); our_latency = gst_util_uint64_scale_int (max_samples, GST_SECOND, goom->rate); GST_DEBUG_OBJECT (goom, "Our latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (our_latency)); /* we add some latency but only if we need to buffer more than what * upstream gives us */ min_latency += our_latency; if (max_latency != -1) max_latency += our_latency; GST_DEBUG_OBJECT (goom, "Calculated total latency : min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); gst_query_set_latency (query, TRUE, min_latency, max_latency); } break; } default: res = gst_pad_peer_query (goom->sinkpad, query); break; } gst_object_unref (goom); return res; }
static gboolean audioresample_query (GstPad * pad, GstQuery * query) { GstAudioresample *audioresample = GST_AUDIORESAMPLE (gst_pad_get_parent (pad)); GstBaseTransform *trans = GST_BASE_TRANSFORM (audioresample); gboolean res = TRUE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min, max; gboolean live; guint64 latency; GstPad *peer; gint rate = audioresample->i_rate; gint resampler_latency = audioresample->filter_length / 2; if (gst_base_transform_is_passthrough (trans)) resampler_latency = 0; if ((peer = gst_pad_get_peer (trans->sinkpad))) { if ((res = gst_pad_query (peer, query))) { gst_query_parse_latency (query, &live, &min, &max); GST_DEBUG ("Peer latency: min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); /* add our own latency */ if (rate != 0 && resampler_latency != 0) latency = gst_util_uint64_scale (resampler_latency, GST_SECOND, rate); else latency = 0; GST_DEBUG ("Our latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (latency)); min += latency; if (max != GST_CLOCK_TIME_NONE) max += latency; GST_DEBUG ("Calculated total latency : min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); gst_query_set_latency (query, live, min, max); } gst_object_unref (peer); } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (audioresample); return res; }
static gboolean gst_audio_fx_base_fir_filter_query (GstPad * pad, GstQuery * query) { GstAudioFXBaseFIRFilter *self = GST_AUDIO_FX_BASE_FIR_FILTER (gst_pad_get_parent (pad)); gboolean res = TRUE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min, max; gboolean live; guint64 latency; GstPad *peer; gint rate = GST_AUDIO_FILTER (self)->format.rate; if (rate == 0) { res = FALSE; } else if ((peer = gst_pad_get_peer (GST_BASE_TRANSFORM (self)->sinkpad))) { if ((res = gst_pad_query (peer, query))) { gst_query_parse_latency (query, &live, &min, &max); GST_DEBUG_OBJECT (self, "Peer latency: min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); if (self->fft && !self->low_latency) latency = self->block_length - self->kernel_length + 1; else latency = self->latency; /* add our own latency */ latency = gst_util_uint64_scale_round (latency, GST_SECOND, rate); GST_DEBUG_OBJECT (self, "Our latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (latency)); min += latency; if (max != GST_CLOCK_TIME_NONE) max += latency; GST_DEBUG_OBJECT (self, "Calculated total latency : min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min), GST_TIME_ARGS (max)); gst_query_set_latency (query, live, min, max); } gst_object_unref (peer); } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (self); return res; }
static gboolean gst_inter_audio_sink_query (GstBaseSink * sink, GstQuery * query) { GstInterAudioSink *interaudiosink = GST_INTER_AUDIO_SINK (sink); gboolean ret; GST_DEBUG_OBJECT (sink, "query"); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY:{ gboolean live, us_live; GstClockTime min_l, max_l; GST_DEBUG_OBJECT (sink, "latency query"); if ((ret = gst_base_sink_query_latency (GST_BASE_SINK_CAST (sink), &live, &us_live, &min_l, &max_l))) { GstClockTime base_latency, min_latency, max_latency; /* we and upstream are both live, adjust the min_latency */ if (live && us_live) { /* FIXME: The other side can change this value when it starts */ base_latency = interaudiosink->surface->audio_latency_time; /* we cannot go lower than the buffer size and the min peer latency */ min_latency = base_latency + min_l; /* the max latency is the max of the peer, we can delay an infinite * amount of time. */ max_latency = (max_l == -1) ? -1 : (base_latency + max_l); GST_DEBUG_OBJECT (sink, "peer min %" GST_TIME_FORMAT ", our min latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (min_l), GST_TIME_ARGS (min_latency)); GST_DEBUG_OBJECT (sink, "peer max %" GST_TIME_FORMAT ", our max latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (max_l), GST_TIME_ARGS (max_latency)); } else { GST_DEBUG_OBJECT (sink, "peer or we are not live, don't care about latency"); min_latency = min_l; max_latency = max_l; } gst_query_set_latency (query, live, min_latency, max_latency); } break; } default: ret = GST_BASE_SINK_CLASS (gst_inter_audio_sink_parent_class)->query (sink, query); break; } return ret; }
static gboolean gst_base_video_encoder_src_query (GstPad * pad, GstQuery * query) { GstBaseVideoEncoder *enc; gboolean res; GstPad *peerpad; enc = GST_BASE_VIDEO_ENCODER (gst_pad_get_parent (pad)); peerpad = gst_pad_get_peer (GST_BASE_VIDEO_CODEC_SINK_PAD (enc)); switch GST_QUERY_TYPE (query) { 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); res = gst_base_video_encoded_video_convert (&GST_BASE_VIDEO_CODEC (enc)->state, src_fmt, src_val, &dest_fmt, &dest_val); if (!res) goto error; gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val); break; } case GST_QUERY_LATENCY: { gboolean live; GstClockTime min_latency, max_latency; res = gst_pad_query (peerpad, query); if (res) { gst_query_parse_latency (query, &live, &min_latency, &max_latency); min_latency += enc->min_latency; if (max_latency != GST_CLOCK_TIME_NONE) { max_latency += enc->max_latency; } gst_query_set_latency (query, live, min_latency, max_latency); } } break; default: res = gst_pad_query_default (pad, query); } gst_object_unref (peerpad); gst_object_unref (enc); return res; error: GST_DEBUG_OBJECT (enc, "query failed"); gst_object_unref (peerpad); gst_object_unref (enc); return res; }
static gboolean gst_rtp_jitter_buffer_query (GstPad * pad, GstQuery * query) { GstRtpJitterBuffer *jitterbuffer; GstRtpJitterBufferPrivate *priv; gboolean res = FALSE; jitterbuffer = GST_RTP_JITTER_BUFFER (gst_pad_get_parent (pad)); priv = jitterbuffer->priv; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { /* We need to send the query upstream and add the returned latency to our * own */ GstClockTime min_latency, max_latency; gboolean us_live; GstClockTime our_latency; if ((res = gst_pad_peer_query (priv->sinkpad, query))) { gst_query_parse_latency (query, &us_live, &min_latency, &max_latency); GST_DEBUG_OBJECT (jitterbuffer, "Peer latency: min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); /* store this so that we can safely sync on the peer buffers. */ JBUF_LOCK (priv); priv->peer_latency = min_latency; our_latency = ((guint64) priv->latency_ms) * GST_MSECOND; JBUF_UNLOCK (priv); GST_DEBUG_OBJECT (jitterbuffer, "Our latency: %" GST_TIME_FORMAT, GST_TIME_ARGS (our_latency)); /* we add some latency but can buffer an infinite amount of time */ min_latency += our_latency; max_latency = -1; GST_DEBUG_OBJECT (jitterbuffer, "Calculated total latency : min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); gst_query_set_latency (query, TRUE, min_latency, max_latency); } break; } default: res = gst_pad_query_default (pad, query); break; } gst_object_unref (jitterbuffer); return res; }
static gboolean gst_dc1394_query (GstBaseSrc * bsrc, GstQuery * query) { gboolean res = TRUE; GstDc1394 *src = GST_DC1394 (bsrc); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min_latency, max_latency; if (!src->camera) { GST_WARNING_OBJECT (src, "Can't give latency since device isn't open !"); res = FALSE; goto done; } if (src->rate_denominator <= 0 || src->rate_numerator <= 0) { GST_WARNING_OBJECT (bsrc, "Can't give latency since framerate isn't fixated !"); res = FALSE; goto done; } /* min latency is the time to capture one frame */ min_latency = gst_util_uint64_scale (GST_SECOND, src->rate_denominator, src->rate_numerator); /* max latency is total duration of the frame buffer */ max_latency = gst_util_uint64_scale (src->bufsize, GST_SECOND * src->rate_denominator, src->rate_numerator); GST_DEBUG_OBJECT (bsrc, "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); /* we are always live, the min latency is 1 frame and the max latency is * the complete buffer of frames. */ gst_query_set_latency (query, TRUE, min_latency, max_latency); res = TRUE; break; } default: res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query); break; } done: return res; }
static gboolean gst_decklink_src_video_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstDecklinkSrc *decklinksrc; gboolean ret = FALSE; decklinksrc = GST_DECKLINK_SRC (parent); GST_DEBUG_OBJECT (pad, "query: %" GST_PTR_FORMAT, query); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY:{ GstClockTime min_latency, max_latency; const GstDecklinkMode *mode; /* device must be open */ if (decklinksrc->decklink == NULL) { GST_WARNING_OBJECT (decklinksrc, "Can't give latency since device isn't open !"); goto done; } mode = gst_decklink_get_mode (decklinksrc->mode); /* min latency is the time to capture one frame */ min_latency = gst_util_uint64_scale_int (GST_SECOND, mode->fps_d, mode->fps_n); /* max latency is total duration of the frame buffer */ max_latency = 2 * min_latency; GST_DEBUG_OBJECT (decklinksrc, "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); /* we are always live, the min latency is 1 frame and the max latency is * the complete buffer of frames. */ gst_query_set_latency (query, TRUE, min_latency, max_latency); ret = TRUE; break; } default: ret = gst_pad_query_default (pad, parent, query); break; } done: return ret; }
static gboolean gst_app_src_query (GstBaseSrc * src, GstQuery * query) { GstAppSrc *appsrc = GST_APP_SRC_CAST (src); GstAppSrcPrivate *priv = appsrc->priv; gboolean res; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min, max; gboolean live; /* Query the parent class for the defaults */ res = gst_base_src_query_latency (src, &live, &min, &max); /* overwrite with our values when we need to */ g_mutex_lock (&priv->mutex); if (priv->min_latency != -1) min = priv->min_latency; if (priv->max_latency != -1) max = priv->max_latency; g_mutex_unlock (&priv->mutex); gst_query_set_latency (query, live, min, max); break; } case GST_QUERY_SCHEDULING: { gst_query_set_scheduling (query, GST_SCHEDULING_FLAG_SEEKABLE, 1, -1, 0); gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH); switch (priv->stream_type) { case GST_APP_STREAM_TYPE_STREAM: case GST_APP_STREAM_TYPE_SEEKABLE: break; case GST_APP_STREAM_TYPE_RANDOM_ACCESS: gst_query_add_scheduling_mode (query, GST_PAD_MODE_PULL); break; } res = TRUE; break; } default: res = GST_BASE_SRC_CLASS (parent_class)->query (src, query); break; } return res; }
static gboolean gst_base_audio_src_query (GstBaseSrc * bsrc, GstQuery * query) { GstBaseAudioSrc *src = GST_BASE_AUDIO_SRC (bsrc); gboolean res = FALSE; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min_latency, max_latency; GstRingBufferSpec *spec; GST_OBJECT_LOCK (src); if (G_UNLIKELY (src->ringbuffer == NULL || src->ringbuffer->spec.rate == 0)) { GST_OBJECT_UNLOCK (src); goto done; } spec = &src->ringbuffer->spec; /* we have at least 1 segment of latency */ min_latency = gst_util_uint64_scale_int (spec->segsize, GST_SECOND, spec->rate * spec->bytes_per_sample); /* we cannot delay more than the buffersize else we lose data */ max_latency = gst_util_uint64_scale_int (spec->segtotal * spec->segsize, GST_SECOND, spec->rate * spec->bytes_per_sample); GST_OBJECT_UNLOCK (src); GST_DEBUG_OBJECT (src, "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); /* we are always live, the min latency is 1 segment and the max latency is * the complete buffer of segments. */ gst_query_set_latency (query, TRUE, min_latency, max_latency); res = TRUE; break; } default: res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query); break; } done: return res; }
static GstPadProbeReturn cb_latency (GstPad * pad, GstPadProbeInfo * info, gpointer data) { if (GST_QUERY_TYPE (GST_PAD_PROBE_INFO_QUERY (info)) != GST_QUERY_LATENCY) { return GST_PAD_PROBE_OK; } GST_LOG_OBJECT (pad, "Modifing latency query. New latency %" G_GUINT64_FORMAT, (guint64) (LATENCY * GST_MSECOND)); gst_query_set_latency (GST_PAD_PROBE_INFO_QUERY (info), TRUE, 0, LATENCY * GST_MSECOND); return GST_PAD_PROBE_HANDLED; }
static gboolean gst_v4lsrc_query (GstBaseSrc * bsrc, GstQuery * query) { GstV4lSrc *v4lsrc; gboolean res = FALSE; v4lsrc = GST_V4LSRC (bsrc); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min_latency, max_latency; gint fps_n, fps_d; /* device must be open */ if (!GST_V4L_IS_OPEN (v4lsrc)) goto done; /* we must have a framerate */ if (!(res = gst_v4lsrc_get_fps (v4lsrc, &fps_n, &fps_d))) goto done; /* min latency is the time to capture one frame */ min_latency = gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n); /* max latency is total duration of the frame buffer */ max_latency = v4lsrc->mbuf.frames * min_latency; GST_DEBUG_OBJECT (bsrc, "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); /* we are always live, the min latency is 1 frame and the max latency is * the complete buffer of frames. */ gst_query_set_latency (query, TRUE, min_latency, max_latency); res = TRUE; break; } default: res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query); break; } done: return res; }
static gboolean kms_agnostic_bin2_sink_query (GstPad * pad, GstObject * parent, GstQuery * query) { gboolean ret; ret = gst_pad_query_default (pad, parent, query); if (ret && GST_QUERY_TYPE (query) == GST_QUERY_LATENCY) { GstClockTime min_latency; GstClockTime max_latency; gst_query_parse_latency (query, NULL, &min_latency, &max_latency); gst_query_set_latency (query, TRUE, min_latency, max_latency); } return ret; }
static gboolean gst_rtp_dec_query_src (GstPad * pad, GstObject * parent, GstQuery * query) { gboolean res; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { /* we pretend to be live with a 3 second latency */ gst_query_set_latency (query, TRUE, 3 * GST_SECOND, -1); res = TRUE; break; } default: res = gst_pad_query_default (pad, parent, query); break; } return res; }
static gboolean gst_aggregator_query_latency (GstAggregator * self, GstQuery * query) { LatencyData data; data.min = 0; data.max = GST_CLOCK_TIME_NONE; data.live = FALSE; /* query upstream's latency */ gst_aggregator_iterate_sinkpads (self, (GstAggregatorPadForeachFunc) _latency_query, &data); if (data.live && GST_CLOCK_TIME_IS_VALID (self->timeout) && self->timeout > data.max) { GST_ELEMENT_WARNING (self, CORE, NEGOTIATION, ("%s", "Timeout too big"), ("The requested timeout value is too big for the latency in the " "current pipeline. Limiting to %" G_GINT64_FORMAT, data.max)); self->timeout = data.max; } self->priv->latency_live = data.live; self->priv->latency_min = data.min; self->priv->latency_max = data.max; /* add our own */ if (GST_CLOCK_TIME_IS_VALID (self->timeout)) { if (GST_CLOCK_TIME_IS_VALID (data.min)) data.min += self->timeout; if (GST_CLOCK_TIME_IS_VALID (data.max)) data.max += self->timeout; } GST_DEBUG_OBJECT (self, "configured latency live:%s min:%" G_GINT64_FORMAT " max:%" G_GINT64_FORMAT, data.live ? "true" : "false", data.min, data.max); gst_query_set_latency (query, data.live, data.min, data.max); return TRUE; }
static gboolean gst_osx_video_src_query (GstBaseSrc * bsrc, GstQuery * query) { GstOSXVideoSrc *self; gboolean res = FALSE; self = GST_OSX_VIDEO_SRC (bsrc); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { GstClockTime min_latency, max_latency; gint fps_n, fps_d; fps_n = FRAMERATE; fps_d = 1; /* min latency is the time to capture one frame */ min_latency = gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n); /* max latency is total duration of the frame buffer */ // FIXME: we don't know what this is, so we'll just say 2 frames max_latency = 2 * min_latency; GST_DEBUG_OBJECT (bsrc, "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); /* we are always live, the min latency is 1 frame and the max latency is * the complete buffer of frames. */ gst_query_set_latency (query, TRUE, min_latency, max_latency); res = TRUE; break; } default: res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query); break; } return res; }
static gboolean gst_identity_query (GstBaseTransform * base, GstPadDirection direction, GstQuery * query) { GstIdentity *identity; gboolean ret; identity = GST_IDENTITY (base); ret = GST_BASE_TRANSFORM_CLASS (parent_class)->query (base, direction, query); if (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY) { gboolean live = FALSE; GstClockTime min = 0, max = 0; if (ret) { gst_query_parse_latency (query, &live, &min, &max); if (identity->sync && max < min) { GST_ELEMENT_WARNING (base, CORE, CLOCK, (NULL), ("Impossible to configure latency before identity sync=true:" " max %" GST_TIME_FORMAT " < min %" GST_TIME_FORMAT ". Add queues or other buffering elements.", GST_TIME_ARGS (max), GST_TIME_ARGS (min))); } } /* Ignore the upstream latency if it is not live */ GST_OBJECT_LOCK (identity); if (live) identity->upstream_latency = min; else identity->upstream_latency = 0; GST_OBJECT_UNLOCK (identity); gst_query_set_latency (query, live || identity->sync, min, max); ret = TRUE; } return ret; }
static gboolean gst_rtp_ssrc_demux_src_query (GstPad * pad, GstObject * parent, GstQuery * query) { GstRtpSsrcDemux *demux; gboolean res = FALSE; demux = GST_RTP_SSRC_DEMUX (parent); switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY: { if ((res = gst_pad_peer_query (demux->rtp_sink, query))) { gboolean live; GstClockTime min_latency, max_latency; GstRtpSsrcDemuxPad *demuxpad; demuxpad = gst_pad_get_element_private (pad); gst_query_parse_latency (query, &live, &min_latency, &max_latency); GST_DEBUG_OBJECT (demux, "peer min latency %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency)); GST_DEBUG_OBJECT (demux, "latency for SSRC %08x", demuxpad->ssrc); gst_query_set_latency (query, live, min_latency, max_latency); } break; } default: res = gst_pad_query_default (pad, parent, query); break; } return res; }
static gboolean gst_adder_query_latency (GstAdder * adder, GstQuery * query) { GstClockTime min, max; gboolean live; gboolean res; GstIterator *it; gboolean done; res = TRUE; done = FALSE; live = FALSE; min = 0; max = GST_CLOCK_TIME_NONE; /* Take maximum of all latency values */ it = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (adder)); while (!done) { GstIteratorResult ires; gpointer item; ires = gst_iterator_next (it, &item); switch (ires) { case GST_ITERATOR_DONE: done = TRUE; break; case GST_ITERATOR_OK: { GstPad *pad = GST_PAD_CAST (item); GstQuery *peerquery; GstClockTime min_cur, max_cur; gboolean live_cur; peerquery = gst_query_new_latency (); /* Ask peer for latency */ res &= gst_pad_peer_query (pad, peerquery); /* take max from all valid return values */ if (res) { gst_query_parse_latency (peerquery, &live_cur, &min_cur, &max_cur); if (min_cur > min) min = min_cur; if (max_cur != GST_CLOCK_TIME_NONE && ((max != GST_CLOCK_TIME_NONE && max_cur > max) || (max == GST_CLOCK_TIME_NONE))) max = max_cur; live = live || live_cur; } gst_query_unref (peerquery); gst_object_unref (pad); break; } case GST_ITERATOR_RESYNC: live = FALSE; min = 0; max = GST_CLOCK_TIME_NONE; res = TRUE; gst_iterator_resync (it); break; default: res = FALSE; done = TRUE; break; } } gst_iterator_free (it); if (res) { /* store the results */ GST_DEBUG_OBJECT (adder, "Calculated total latency: live %s, min %" GST_TIME_FORMAT ", max %" GST_TIME_FORMAT, (live ? "yes" : "no"), GST_TIME_ARGS (min), GST_TIME_ARGS (max)); gst_query_set_latency (query, live, min, max); } return res; }
static gboolean gst_v4l2src_query (GstBaseSrc * bsrc, GstQuery * query) { GstV4l2Src *src; GstV4l2Object *obj; gboolean res = FALSE; src = GST_V4L2SRC (bsrc); obj = src->v4l2object; switch (GST_QUERY_TYPE (query)) { case GST_QUERY_LATENCY:{ GstClockTime min_latency, max_latency; guint32 fps_n, fps_d; guint num_buffers = 0; /* device must be open */ if (!GST_V4L2_IS_OPEN (obj)) { GST_WARNING_OBJECT (src, "Can't give latency since device isn't open !"); goto done; } fps_n = GST_V4L2_FPS_N (obj); fps_d = GST_V4L2_FPS_D (obj); /* we must have a framerate */ if (fps_n <= 0 || fps_d <= 0) { GST_WARNING_OBJECT (src, "Can't give latency since framerate isn't fixated !"); goto done; } /* min latency is the time to capture one frame */ min_latency = gst_util_uint64_scale_int (GST_SECOND, fps_d, fps_n); /* max latency is total duration of the frame buffer */ if (obj->pool != NULL) num_buffers = GST_V4L2_BUFFER_POOL_CAST (obj->pool)->max_latency; if (num_buffers == 0) max_latency = -1; else max_latency = num_buffers * min_latency; GST_DEBUG_OBJECT (bsrc, "report latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT, GST_TIME_ARGS (min_latency), GST_TIME_ARGS (max_latency)); /* we are always live, the min latency is 1 frame and the max latency is * the complete buffer of frames. */ gst_query_set_latency (query, TRUE, min_latency, max_latency); res = TRUE; break; } default: res = GST_BASE_SRC_CLASS (parent_class)->query (bsrc, query); break; } done: return res; }