コード例 #1
0
static gboolean
_latency_query (GstAggregator * self, GstPad * pad, gpointer user_data)
{
  LatencyData *data = user_data;
  GstClockTime min, max;
  GstQuery *query;
  gboolean live, res;

  query = gst_query_new_latency ();
  res = gst_pad_peer_query (pad, query);

  if (res) {
    gst_query_parse_latency (query, &live, &min, &max);

    GST_LOG_OBJECT (self, "got latency live:%s min:%" G_GINT64_FORMAT
        " max:%" G_GINT64_FORMAT, live ? "true" : "false", min, max);

    if (min > data->min)
      data->min = min;

    if (max != GST_CLOCK_TIME_NONE &&
        ((data->max != GST_CLOCK_TIME_NONE && max < data->max) ||
            (data->max == GST_CLOCK_TIME_NONE)))
      data->max = max;

    data->live |= live;
  }

  gst_query_unref (query);

  return TRUE;
}
コード例 #2
0
ファイル: rbgst-query.c プロジェクト: Mazwak/ruby-gnome2
static VALUE
latency_initialize(VALUE self)
{
    GstQuery *query;

    query = gst_query_new_latency();

    G_INITIALIZE(self, query);
    return Qnil;
}
コード例 #3
0
ファイル: ofGstUtils.cpp プロジェクト: AsmaM/openFrameworks
uint64_t ofGstUtils::getMaxLatencyNanos(){
	GstClockTime minlat=0, maxlat=0;
	GstQuery * q = gst_query_new_latency();
	if (gst_element_query (gstPipeline, q)) {
		 gboolean live;
		 gst_query_parse_latency (q, &live, &minlat, &maxlat);
	}
	gst_query_unref (q);
	return maxlat;
}
コード例 #4
0
ファイル: mpegtsbase.c プロジェクト: PeterXu/gst-mobile
static void
query_upstream_latency (MpegTSBase * base)
{
  GstQuery *query;

  query = gst_query_new_latency ();
  if (gst_pad_peer_query (base->sinkpad, query)) {
    gst_query_parse_latency (query, &base->upstream_live, NULL, NULL);
    GST_DEBUG_OBJECT (base, "Upstream is %s",
        base->upstream_live ? "LIVE" : "NOT LIVE");
  } else
    GST_WARNING_OBJECT (base, "Failed to query upstream latency");
  gst_query_unref (query);
  base->queried_latency = TRUE;
}
コード例 #5
0
static gboolean
gst_webrtc_echo_probe_src_event (GstBaseTransform * btrans, GstEvent * event)
{
  GstBaseTransformClass *klass;
  GstWebrtcEchoProbe *self = GST_WEBRTC_ECHO_PROBE (btrans);
  GstClockTime latency;
  GstClockTime upstream_latency = 0;
  GstQuery *query;

  klass = GST_BASE_TRANSFORM_CLASS (gst_webrtc_echo_probe_parent_class);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_LATENCY:
      gst_event_parse_latency (event, &latency);
      query = gst_query_new_latency ();

      if (gst_pad_query (btrans->srcpad, query)) {
        gst_query_parse_latency (query, NULL, &upstream_latency, NULL);

        if (!GST_CLOCK_TIME_IS_VALID (upstream_latency))
          upstream_latency = 0;
      }

      GST_WEBRTC_ECHO_PROBE_LOCK (self);
      self->latency = latency;
      self->delay = upstream_latency / GST_MSECOND;
      GST_WEBRTC_ECHO_PROBE_UNLOCK (self);

      GST_DEBUG_OBJECT (self, "We have a latency of %" GST_TIME_FORMAT
          " and delay of %ims", GST_TIME_ARGS (latency),
          (gint) (upstream_latency / GST_MSECOND));
      break;
    default:
      break;
  }

  return klass->src_event (btrans, event);
}
コード例 #6
0
ファイル: gstadder.c プロジェクト: matsu/gst-plugins-base
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;
}
コード例 #7
0
static gboolean
gst_pipeline_do_latency (GstBin * bin)
{
  GstPipeline *pipeline = GST_PIPELINE (bin);
  GstQuery *query;
  GstClockTime latency;
  GstClockTime min_latency, max_latency;
  gboolean res;

  GST_OBJECT_LOCK (pipeline);
  latency = pipeline->priv->latency;
  GST_OBJECT_UNLOCK (pipeline);

  if (latency == GST_CLOCK_TIME_NONE)
    return GST_BIN_CLASS (parent_class)->do_latency (bin);

  GST_DEBUG_OBJECT (pipeline, "querying latency");

  query = gst_query_new_latency ();
  if ((res = gst_element_query (GST_ELEMENT_CAST (pipeline), query))) {
    gboolean live;

    gst_query_parse_latency (query, &live, &min_latency, &max_latency);

    GST_DEBUG_OBJECT (pipeline,
        "got min latency %" GST_TIME_FORMAT ", max latency %"
        GST_TIME_FORMAT ", live %d", GST_TIME_ARGS (min_latency),
        GST_TIME_ARGS (max_latency), live);

    if (max_latency < min_latency) {
      /* this is an impossible situation, some parts of the pipeline might not
       * work correctly. We post a warning for now. */
      GST_ELEMENT_WARNING (pipeline, CORE, CLOCK, (NULL),
          ("Impossible to configure latency: max %" GST_TIME_FORMAT " < min %"
              GST_TIME_FORMAT ". Add queues or other buffering elements.",
              GST_TIME_ARGS (max_latency), GST_TIME_ARGS (min_latency)));
    }

    if (latency < min_latency) {
      /* This is a problematic situation as we will most likely drop lots of
       * data if we configure a too low latency */
      GST_ELEMENT_WARNING (pipeline, CORE, CLOCK, (NULL),
          ("Configured latency is lower than detected minimum latency: configured %"
              GST_TIME_FORMAT " < min %" GST_TIME_FORMAT,
              GST_TIME_ARGS (latency), GST_TIME_ARGS (min_latency)));
    }
  } else {
    /* this is not a real problem, we just don't configure any latency. */
    GST_WARNING_OBJECT (pipeline, "failed to query latency");
  }
  gst_query_unref (query);


  /* configure latency on elements */
  res =
      gst_element_send_event (GST_ELEMENT_CAST (pipeline),
      gst_event_new_latency (latency));
  if (res) {
    GST_INFO_OBJECT (pipeline, "configured latency of %" GST_TIME_FORMAT,
        GST_TIME_ARGS (latency));
  } else {
    GST_WARNING_OBJECT (pipeline,
        "did not really configure latency of %" GST_TIME_FORMAT,
        GST_TIME_ARGS (latency));
  }

  return res;
}
static gboolean
hls_test_bus_message (InsanityGstPipelineTest * ptest, GstMessage * msg)
{
  switch (GST_MESSAGE_TYPE (msg)) {
    case GST_MESSAGE_BUFFERING:
    {
      gint per;

      gst_message_parse_buffering (msg, &per);

      /* First buffering happend properly, this is requiered to be able to
       * start seeking */
      if (G_UNLIKELY (glob_buffered == FALSE)) {
        if (per == 100) {
          insanity_test_validate_checklist_item (INSANITY_TEST (ptest),
              "done-buffering", TRUE, NULL);
          glob_buffered = TRUE;

          if (glob_buffering_timeout != 0) {
            g_source_remove (glob_buffering_timeout);
            glob_buffering_timeout = 0;
          }
        } else {
          glob_buffering_timeout = g_timeout_add (250,
              (GSourceFunc) buffering_timeout, INSANITY_TEST (ptest));
        }
      }

      break;
    }
    case GST_MESSAGE_STATE_CHANGED:
      if (GST_MESSAGE_SRC (msg) == GST_OBJECT (glob_pipeline)) {
        const char *validate_checklist_item = glob_validate_on_playing;
        GstState oldstate, newstate, pending;

        gst_message_parse_state_changed (msg, &oldstate, &newstate, &pending);
        if (newstate == GST_STATE_PAUSED && oldstate == GST_STATE_READY) {
          GstIterator *it;
          GValue v = { 0, };
          gboolean queried;
          InsanityTest *test = INSANITY_TEST (ptest);
          GstQuery *query = gst_query_new_latency ();
          const gchar *step_message = "Could not query seeking\n";

          if ((queried = gst_element_query (glob_pipeline, query))) {
            gst_query_parse_latency (query, &glob_is_live, NULL, NULL);
            step_message = NULL;
          } else
            insanity_test_printf (test, "Could not query\n");

          insanity_gst_pipeline_test_set_live (ptest, glob_is_live);
          insanity_test_validate_checklist_item (test, "queried-live", queried,
              step_message);
          gst_query_unref (query);

          step_message = "Could not query seekable\n";
          query = gst_query_new_seeking (GST_FORMAT_TIME);
          if ((queried = gst_element_query (glob_pipeline, query))) {
            gst_query_parse_seeking (query, NULL, &glob_is_seekable, NULL,
                NULL);
            step_message = NULL;
          } else
            insanity_test_printf (test, "Could not query\n");

          insanity_test_validate_checklist_item (test, "queried-seekable",
              queried, step_message);
          gst_query_unref (query);

          /* Iterate over the bins to find a hlsdemux */
          it = gst_bin_iterate_recurse (GST_BIN (glob_pipeline));
          if (gst_iterator_find_custom (it, (GCompareFunc) find_hlsdemux, &v,
                  NULL)) {
            glob_hlsdemux = g_value_dup_object (&v);
          }
          g_value_unset (&v);
          gst_iterator_free (it);

          if (glob_hlsdemux != NULL) {
            insanity_test_validate_checklist_item (test, "protocol-is-hls",
                TRUE, "HLS protocol in use");

            gst_object_unref (glob_hlsdemux);
          } else {
            insanity_test_validate_checklist_item (test, "protocol-is-hls",
                FALSE, "HLS protocol in use");
            insanity_test_done (test);
          }

          /* Watch pipeline only if seekable */
          if (glob_is_seekable)
            watch_pipeline (ptest);

        } else if (newstate == GST_STATE_PLAYING
            && pending == GST_STATE_VOID_PENDING && validate_checklist_item) {
          glob_validate_on_playing = NULL;
          insanity_test_validate_checklist_item (INSANITY_TEST (ptest),
              validate_checklist_item, TRUE, NULL);
          /* let it run a couple seconds */
          glob_wait_time = hls_test_get_wait_time (INSANITY_TEST (ptest));
          glob_timer_id =
              g_timeout_add (250, (GSourceFunc) & wait_and_end_step,
              INSANITY_TEST (ptest));
        }
      }
      break;
    case GST_MESSAGE_EOS:
      return FALSE;
    default:
      break;
  }

  return TRUE;

}
コード例 #9
0
ファイル: query.cpp プロジェクト: xohm/qt-gstreamer
LatencyQueryPtr LatencyQuery::create()
{
    return LatencyQueryPtr::wrap(gst_query_new_latency(), false);
}