コード例 #1
0
static void
gst_type_find_element_emit_have_type (GstTypeFindElement * typefind,
    guint probability, GstCaps * caps)
{
  GstEvent *event;

  /* Update caps field immediatly so that caps queries and properties can be
   * honored in all "have-type" signal handlers.
   */
  GST_OBJECT_LOCK (typefind);
  if (typefind->caps)
    gst_caps_unref (typefind->caps);
  typefind->caps = gst_caps_ref (caps);
  GST_OBJECT_UNLOCK (typefind);

  /* Only store the caps event at this point. We give signal handlers
   * the chance to look at the caps before they are sent downstream.
   * They are only forwarded downstream later in the default signal
   * handler after all application signal handlers
   */
  event = gst_event_new_caps (caps);
  gst_pad_store_sticky_event (typefind->src, event);
  gst_event_unref (event);

  g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
      probability, caps);
}
コード例 #2
0
static gboolean copy_sticky_events(GstPad *pad, GstEvent **event, gpointer user_data)
{
    GstPad *new_pad = user_data;

    if (GST_EVENT_TYPE(*event) != GST_EVENT_CAPS && GST_EVENT_TYPE(*event) != GST_EVENT_STREAM_START)
        gst_pad_store_sticky_event(new_pad, *event);

    return TRUE;
}
コード例 #3
0
static gboolean
forward_sticky_events (GstPad * pad, GstEvent ** event, gpointer user_data)
{
  GstPad *srcpad = GST_PAD_CAST (user_data);
  GstFlowReturn ret;

  ret = gst_pad_store_sticky_event (srcpad, *event);
  if (ret != GST_FLOW_OK) {
    GST_DEBUG_OBJECT (srcpad, "storing sticky event %p (%s) failed: %s", *event,
        GST_EVENT_TYPE_NAME (*event), gst_flow_get_name (ret));
  }

  return TRUE;
}
コード例 #4
0
static GList *
_flush_events (GstPad * pad, GList * events)
{
  GList *tmp;

  for (tmp = events; tmp; tmp = tmp->next) {
    if (GST_EVENT_TYPE (tmp->data) == GST_EVENT_EOS ||
        GST_EVENT_TYPE (tmp->data) == GST_EVENT_SEGMENT ||
        !GST_EVENT_IS_STICKY (tmp->data) || pad == NULL) {
      gst_event_unref (tmp->data);
    } else {
      gst_pad_store_sticky_event (pad, GST_EVENT_CAST (tmp->data));
    }
  }
  g_list_free (events);

  return NULL;
}
コード例 #5
0
static gboolean
gst_type_find_element_sink_event (GstPad * pad, GstObject * parent,
    GstEvent * event)
{
  gboolean res = FALSE;
  GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (parent);

  GST_DEBUG_OBJECT (typefind, "got %s event in mode %d",
      GST_EVENT_TYPE_NAME (event), typefind->mode);

  switch (typefind->mode) {
    case MODE_TYPEFIND:
      switch (GST_EVENT_TYPE (event)) {
        case GST_EVENT_CAPS:
        {
          GstCaps *caps;

          /* Parse and push out our caps and data */
          gst_event_parse_caps (event, &caps);
          res = gst_type_find_element_setcaps (typefind, caps);

          gst_event_unref (event);
          break;
        }
        case GST_EVENT_GAP:
        {
          GST_FIXME_OBJECT (typefind,
              "GAP events during typefinding not handled properly");

          /* FIXME: These would need to be inserted in the stream at
           * the right position between buffers, but we combine all
           * buffers with a GstAdapter. Drop the GAP event for now,
           * which will only cause an implicit GAP between buffers.
           */
          gst_event_unref (event);
          res = TRUE;
          break;
        }
        case GST_EVENT_EOS:
        {
          GST_INFO_OBJECT (typefind, "Got EOS and no type found yet");
          gst_type_find_element_chain_do_typefinding (typefind, FALSE, TRUE);

          res = gst_pad_push_event (typefind->src, event);
          break;
        }
        case GST_EVENT_FLUSH_STOP:{
          GList *l;

          GST_OBJECT_LOCK (typefind);

          for (l = typefind->cached_events; l; l = l->next) {
            if (GST_EVENT_IS_STICKY (l->data) &&
                GST_EVENT_TYPE (l->data) != GST_EVENT_SEGMENT &&
                GST_EVENT_TYPE (l->data) != GST_EVENT_EOS) {
              gst_pad_store_sticky_event (typefind->src, l->data);
            }
            gst_event_unref (l->data);
          }

          g_list_free (typefind->cached_events);
          typefind->cached_events = NULL;
          gst_adapter_clear (typefind->adapter);
          GST_OBJECT_UNLOCK (typefind);
          /* fall through */
        }
        case GST_EVENT_FLUSH_START:
          res = gst_pad_push_event (typefind->src, event);
          break;
        default:
          /* Forward events that would happen before the caps event
           * directly instead of storing them. There's no reason not
           * to send them directly and we should only store events
           * for later sending that would need to come after the caps
           * event */
          if (GST_EVENT_TYPE (event) < GST_EVENT_CAPS) {
            res = gst_pad_push_event (typefind->src, event);
          } else {
            GST_DEBUG_OBJECT (typefind, "Saving %s event to send later",
                GST_EVENT_TYPE_NAME (event));
            GST_OBJECT_LOCK (typefind);
            typefind->cached_events =
                g_list_append (typefind->cached_events, event);
            GST_OBJECT_UNLOCK (typefind);
            res = TRUE;
          }
          break;
      }
      break;
    case MODE_NORMAL:
      res = gst_pad_push_event (typefind->src, event);
      break;
    case MODE_ERROR:
      break;
    default:
      g_assert_not_reached ();
  }
  return res;
}
コード例 #6
0
static GstMultipartPad *
gst_multipart_find_pad_by_mime (GstMultipartDemux * demux, gchar * mime,
    gboolean * created)
{
  GSList *walk;

  walk = demux->srcpads;
  while (walk) {
    GstMultipartPad *pad = (GstMultipartPad *) walk->data;

    if (!strcmp (pad->mime, mime)) {
      if (created) {
        *created = FALSE;
      }
      return pad;
    }

    walk = walk->next;
  }
  /* pad not found, create it */
  {
    GstPad *pad;
    GstMultipartPad *mppad;
    gchar *name;
    const gchar *capsname;
    GstCaps *caps;
    gchar *stream_id;
    GstEvent *event;

    mppad = g_new0 (GstMultipartPad, 1);

    GST_DEBUG_OBJECT (demux, "creating pad with mime: %s", mime);

    name = g_strdup_printf ("src_%u", demux->numpads);
    pad =
        gst_pad_new_from_static_template (&multipart_demux_src_template_factory,
        name);
    g_free (name);

    mppad->pad = pad;
    mppad->mime = g_strdup (mime);
    mppad->last_ret = GST_FLOW_OK;
    mppad->last_ts = GST_CLOCK_TIME_NONE;
    mppad->discont = TRUE;

    demux->srcpads = g_slist_prepend (demux->srcpads, mppad);
    demux->numpads++;

    gst_pad_use_fixed_caps (pad);
    gst_pad_set_active (pad, TRUE);

    /* prepare and send stream-start */
    if (!demux->have_group_id) {
      event = gst_pad_get_sticky_event (demux->sinkpad,
          GST_EVENT_STREAM_START, 0);

      if (event) {
        demux->have_group_id =
            gst_event_parse_group_id (event, &demux->group_id);
        gst_event_unref (event);
      } else if (!demux->have_group_id) {
        demux->have_group_id = TRUE;
        demux->group_id = gst_util_group_id_next ();
      }
    }

    stream_id = gst_pad_create_stream_id (pad,
        GST_ELEMENT_CAST (demux), demux->mime_type);

    event = gst_event_new_stream_start (stream_id);
    if (demux->have_group_id)
      gst_event_set_group_id (event, demux->group_id);

    gst_pad_store_sticky_event (pad, event);
    g_free (stream_id);
    gst_event_unref (event);

    /* take the mime type, convert it to the caps name */
    capsname = gst_multipart_demux_get_gstname (demux, mime);
    caps = gst_caps_from_string (capsname);
    GST_DEBUG_OBJECT (demux, "caps for pad: %s", capsname);
    gst_pad_set_caps (pad, caps);
    gst_element_add_pad (GST_ELEMENT_CAST (demux), pad);
    gst_caps_unref (caps);

    if (created) {
      *created = TRUE;
    }

    if (demux->singleStream) {
      gst_element_no_more_pads (GST_ELEMENT_CAST (demux));
    }

    return mppad;
  }
}