/* Data probe cb to drop everything but count buffers and events */
static GstPadProbeReturn
probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  gint count = 0;
  const gchar *count_type = NULL;
  GstMiniObject *obj = GST_PAD_PROBE_INFO_DATA (info);

  GST_LOG_OBJECT (pad, "got data");

  if (GST_IS_BUFFER (obj)) {
    count_type = "buffer_count";
  } else if (GST_IS_EVENT (obj)) {
    count_type = "event_count";
  } else {
    g_assert_not_reached ();
  }

  /* increment and store count */
  count = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pad), count_type));
  count++;
  g_object_set_data (G_OBJECT (pad), count_type, GINT_TO_POINTER (count));

  /* drop every buffer */
  return GST_IS_BUFFER (obj) ? GST_PAD_PROBE_DROP : GST_PAD_PROBE_PASS;
}
static GstPadProbeReturn
event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer udata)
{
  GstPadProbeReturn ret = GST_PAD_PROBE_OK;
  GstEvent *event = GST_PAD_PROBE_INFO_DATA (info);

  switch (GST_EVENT_TYPE (event)) {
    case GST_EVENT_STREAM_START:{
      guint group_id;

      g_mutex_lock (&test_mutex);
      fail_unless (gst_event_parse_group_id (event, &group_id));

      if (have_group_id) {
        if (group_id_pre != group_id) {
          event = gst_event_copy (event);
          gst_event_set_group_id (event, group_id_pre);
          gst_event_replace ((GstEvent **) & info->data, event);
          gst_event_unref (event);
        }
      } else {
        group_id_pre = group_id;
        have_group_id = TRUE;
      }
      g_mutex_unlock (&test_mutex);
      break;
    }
    default:
      break;
  }

  return ret;
}
static GstPadProbeReturn
on_video_sink_data_flow (GstPad * pad, GstPadProbeInfo * info,
    gpointer user_data)
{
  GstMiniObject *mini_obj = GST_PAD_PROBE_INFO_DATA (info);
  GstFPSDisplaySink *self = GST_FPS_DISPLAY_SINK (user_data);

  if (GST_IS_BUFFER (mini_obj)) {
    GstClockTime ts;

    /* assume the frame is going to be rendered. If it isnt', we'll get a qos
     * message and reset ->frames_rendered from there.
     */
    g_atomic_int_inc (&self->frames_rendered);

    ts = gst_util_get_timestamp ();
    if (G_UNLIKELY (!GST_CLOCK_TIME_IS_VALID (self->start_ts))) {
      self->interval_ts = self->last_ts = self->start_ts = ts;
    }
    if (GST_CLOCK_DIFF (self->interval_ts, ts) > self->fps_update_interval) {
      display_current_fps (self);
      self->interval_ts = ts;
    }
  }

  return GST_PAD_PROBE_OK;
}
/* reconfiguration is not supported by all sources and can be disruptive
 * we will handle reconfiguration manually
 * FIXME: implement source reconfiguration support :) */
static GstPadProbeReturn drop_reconfigure_cb(GstPad *pad, GstPadProbeInfo *info, gpointer user_data)
{
    OWR_UNUSED(pad);
    OWR_UNUSED(user_data);

    if (GST_IS_EVENT(GST_PAD_PROBE_INFO_DATA(info))
        && GST_EVENT_TYPE(GST_PAD_PROBE_INFO_EVENT(info)) == GST_EVENT_RECONFIGURE) {
        GST_DEBUG("Dropping reconfigure event");
        return GST_PAD_PROBE_DROP;
    }

    return GST_PAD_PROBE_OK;
}
static GstPadProbeReturn
stop_notification_cb (GstPad * srcpad, GstPadProbeInfo * info,
    gpointer user_data)
{
  KmsRecorderEndpoint *recorder = KMS_RECORDER_ENDPOINT (user_data);

  if (GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) != GST_EVENT_EOS)
    return GST_PAD_PROBE_OK;

  kms_loop_idle_add_full (recorder->priv->loop, G_PRIORITY_HIGH_IDLE,
      set_to_null_state_on_EOS, g_object_ref (recorder), g_object_unref);

  return GST_PAD_PROBE_OK;
}
static GstPadProbeReturn
pay_event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  rtp_pipeline *p = (rtp_pipeline *) user_data;
  GstEvent *event = GST_PAD_PROBE_INFO_DATA (info);

  if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_DOWNSTREAM) {
    const GstStructure *s0 = gst_event_get_structure (p->custom_event);
    const GstStructure *s1 = gst_event_get_structure (event);
    if (gst_structure_is_equal (s0, s1)) {
      return GST_PAD_PROBE_DROP;
    }
  }

  return GST_PAD_PROBE_OK;
}
Beispiel #7
0
GstPadProbeReturn
eos_event_cb (GstPad *pad, GstPadProbeInfo *info, gpointer data)
{
  if (GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) == GST_EVENT_EOS)
  {
    GstElement *bin = NULL;
    GstMessage *message = NULL;
    GstStructure *msg_struct = NULL;
    MbMedia *media;
    gchar *uri = NULL;
    int pads = 0;

    media = (MbMedia *) data;

    bin = gst_bin_get_by_name (GST_BIN(_mb_global_data.pipeline), media->name);
    g_assert(bin);

    g_mutex_lock (&(media->mutex));
    pads = --media->valid_pads;
    g_mutex_unlock (&(media->mutex));

    g_object_get (media->decoder, "uri", &uri, NULL);
    g_debug ("EOS received (%s): %s.\n", media->name, uri);
    g_debug ("%s still has %d valid pad(s).\n", media->name, pads);

    if (pads == 0)
    {
      MbEvent *event = create_state_change_event (MB_END, media->name);
      notify_handler (event);
      free (event);
      
      g_hash_table_remove (_mb_global_data.media_table, media->name);
      
      msg_struct = gst_structure_new ("end-media", "event_type", G_TYPE_INT,
          APP_EVT_MEDIA_END, "data", G_TYPE_POINTER,
          media,
          /* FILL ME IF NECESSARY */
          NULL);

      message = gst_message_new_application (GST_OBJECT(bin), msg_struct);
      g_debug ("Posting event\n");
      gst_bus_post (_mb_global_data.bus, message);
    }
    g_free (uri);
  }
  return GST_PAD_PROBE_OK;
}
static GstPadProbeReturn
event_probe_cb (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GMainLoop *loop = user_data;
  GstElement *next;

  if (GST_EVENT_TYPE (GST_PAD_PROBE_INFO_DATA (info)) != GST_EVENT_EOS)
    return GST_PAD_PROBE_OK;

  gst_pad_remove_probe (pad, GST_PAD_PROBE_INFO_ID (info));

  /* push current event back into the queue */
  g_queue_push_tail (&effects, gst_object_ref (cur_effect));
  /* take next effect from the queue */
  next = g_queue_pop_head (&effects);
  if (next == NULL) {
    GST_DEBUG_OBJECT (pad, "no more effects");
    g_main_loop_quit (loop);
    return GST_PAD_PROBE_DROP;
  }

  g_print ("Switching from '%s' to '%s'..\n", GST_OBJECT_NAME (cur_effect),
      GST_OBJECT_NAME (next));

  gst_element_set_state (cur_effect, GST_STATE_NULL);

  /* remove unlinks automatically */
  GST_DEBUG_OBJECT (pipeline, "removing %" GST_PTR_FORMAT, cur_effect);
  gst_bin_remove (GST_BIN (pipeline), cur_effect);

  GST_DEBUG_OBJECT (pipeline, "adding   %" GST_PTR_FORMAT, next);
  gst_bin_add (GST_BIN (pipeline), next);

  GST_DEBUG_OBJECT (pipeline, "linking..");
  gst_element_link_many (conv_before, next, conv_after, NULL);

  gst_element_set_state (next, GST_STATE_PLAYING);

  cur_effect = next;
  GST_DEBUG_OBJECT (pipeline, "done");

  return GST_PAD_PROBE_DROP;
}
Beispiel #9
0
static GstPadProbeReturn
event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer user_data)
{
  GstMiniObject *data = GST_PAD_PROBE_INFO_DATA (info);
  gboolean before_q = (gboolean) GPOINTER_TO_INT (user_data);

  GST_DEBUG ("event probe called %p", data);

  fail_unless (GST_IS_EVENT (data));

  if (before_q) {
    switch (GST_EVENT_TYPE (GST_EVENT (data))) {
      case GST_EVENT_CUSTOM_UPSTREAM:
      case GST_EVENT_CUSTOM_BOTH:
      case GST_EVENT_CUSTOM_BOTH_OOB:
        if (got_event_before_q != NULL)
          break;
        gst_event_ref ((GstEvent *) data);
        g_get_current_time (&got_event_time);
        got_event_before_q = GST_EVENT (data);
        break;
      default:
        break;
    }
  } else {
    switch (GST_EVENT_TYPE (GST_EVENT (data))) {
      case GST_EVENT_CUSTOM_DOWNSTREAM:
      case GST_EVENT_CUSTOM_DOWNSTREAM_OOB:
      case GST_EVENT_CUSTOM_BOTH:
      case GST_EVENT_CUSTOM_BOTH_OOB:
        if (got_event_after_q != NULL)
          break;
        gst_event_ref ((GstEvent *) data);
        g_get_current_time (&got_event_time);
        got_event_after_q = GST_EVENT (data);
        break;
      default:
        break;
    }
  }

  return GST_PAD_PROBE_OK;
}
Beispiel #10
0
static GstPadProbeReturn
_appsrc_event_probe (GstPad * pad, GstPadProbeInfo * info, gpointer udata)
{
  GstEvent *event = GST_PAD_PROBE_INFO_DATA (info);
  GstElement *appsrc = udata;
  const GstStructure *s;
  gchar *sstr;
  App *app = &s_app;

  GST_DEBUG ("element:%s got an event:%s", GST_ELEMENT_NAME (appsrc),
      GST_EVENT_TYPE_NAME (event));

  if (GST_EVENT_TYPE (event) == GST_EVENT_CUSTOM_UPSTREAM) {
    s = gst_event_get_structure (event);
    sstr = gst_structure_to_string (s);
    if (g_str_equal (sstr, "application/x-custom;"))
      app->nb_received_event++;
    g_free (sstr);
  } else if (GST_EVENT_TYPE (event) == GST_EVENT_SEEK) {
    app->nb_received_event++;
  }

  return GST_PAD_PROBE_OK;
}
/* Probe on the output of a parser chain (the last
 * src pad) */
static GstPadProbeReturn
parse_chain_output_probe (GstPad * pad, GstPadProbeInfo * info,
    DecodebinInputStream * input)
{
  GstPadProbeReturn ret = GST_PAD_PROBE_OK;

  if (GST_IS_EVENT (GST_PAD_PROBE_INFO_DATA (info))) {
    GstEvent *ev = GST_PAD_PROBE_INFO_EVENT (info);

    GST_DEBUG_OBJECT (pad, "Got event %s", GST_EVENT_TYPE_NAME (ev));
    switch (GST_EVENT_TYPE (ev)) {
      case GST_EVENT_STREAM_START:
      {
        GstStream *stream = NULL;
        guint group_id = G_MAXUINT32;
        gst_event_parse_group_id (ev, &group_id);
        GST_DEBUG_OBJECT (pad, "Got stream-start, group_id:%d, input %p",
            group_id, input->input);
        if (set_input_group_id (input->input, &group_id)) {
          ev = gst_event_make_writable (ev);
          gst_event_set_group_id (ev, group_id);
          GST_PAD_PROBE_INFO_DATA (info) = ev;
        }
        input->saw_eos = FALSE;

        gst_event_parse_stream (ev, &stream);
        /* FIXME : Would we ever end up with a stream already set on the input ?? */
        if (stream) {
          if (input->active_stream != stream) {
            MultiQueueSlot *slot;
            if (input->active_stream)
              gst_object_unref (input->active_stream);
            input->active_stream = stream;
            /* We have the beginning of a stream, get a multiqueue slot and link to it */
            g_mutex_lock (&input->dbin->selection_lock);
            slot = get_slot_for_input (input->dbin, input);
            link_input_to_slot (input, slot);
            g_mutex_unlock (&input->dbin->selection_lock);
          } else
            gst_object_unref (stream);
        }
      }
        break;
      case GST_EVENT_CAPS:
      {
        GstCaps *caps = NULL;
        gst_event_parse_caps (ev, &caps);
        GST_DEBUG_OBJECT (pad, "caps %" GST_PTR_FORMAT, caps);
        if (caps && input->active_stream)
          gst_stream_set_caps (input->active_stream, caps);
      }
        break;
      case GST_EVENT_EOS:
        input->saw_eos = TRUE;
        if (all_inputs_are_eos (input->dbin)) {
          GST_DEBUG_OBJECT (pad, "real input pad, marking as EOS");
          check_all_streams_for_eos (input->dbin);
        } else {
          GstPad *peer = gst_pad_get_peer (input->srcpad);
          if (peer) {
            /* Send custom-eos event to multiqueue slot */
            GstStructure *s;
            GstEvent *event;

            GST_DEBUG_OBJECT (pad,
                "Got EOS end of input stream, post custom-eos");
            s = gst_structure_new_empty ("decodebin3-custom-eos");
            event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
            gst_pad_send_event (peer, event);
            gst_object_unref (peer);
          } else {
            GST_FIXME_OBJECT (pad, "No peer, what should we do ?");
          }
        }
        ret = GST_PAD_PROBE_DROP;
        break;
      case GST_EVENT_FLUSH_STOP:
        GST_DEBUG_OBJECT (pad, "Clear saw_eos flag");
        input->saw_eos = FALSE;
      default:
        break;
    }
  } else if (GST_IS_QUERY (GST_PAD_PROBE_INFO_DATA (info))) {
    GstQuery *q = GST_PAD_PROBE_INFO_QUERY (info);
    GST_DEBUG_OBJECT (pad, "Seeing query %s", GST_QUERY_TYPE_NAME (q));
    /* If we have a parser, we want to reply to the caps query */
    /* FIXME: Set a flag when the input stream is created for
     * streams where we shouldn't reply to these queries */
    if (GST_QUERY_TYPE (q) == GST_QUERY_CAPS
        && (info->type & GST_PAD_PROBE_TYPE_PULL)) {
      GstCaps *filter = NULL;
      GstCaps *allowed;
      gst_query_parse_caps (q, &filter);
      allowed = get_parser_caps_filter (input->dbin, filter);
      GST_DEBUG_OBJECT (pad,
          "Intercepting caps query, setting %" GST_PTR_FORMAT, allowed);
      gst_query_set_caps_result (q, allowed);
      gst_caps_unref (allowed);
      ret = GST_PAD_PROBE_HANDLED;
    } else if (GST_QUERY_TYPE (q) == GST_QUERY_ACCEPT_CAPS) {
      GstCaps *prop = NULL;
      gst_query_parse_accept_caps (q, &prop);
      /* Fast check against target caps */
      if (gst_caps_can_intersect (prop, input->dbin->caps))
        gst_query_set_accept_caps_result (q, TRUE);
      else {
        gboolean accepted = check_parser_caps_filter (input->dbin, prop);
        /* check against caps filter */
        gst_query_set_accept_caps_result (q, accepted);
        GST_DEBUG_OBJECT (pad, "ACCEPT_CAPS query, returning %d", accepted);
      }
      ret = GST_PAD_PROBE_HANDLED;
    }
  }

  return ret;
}