Esempio n. 1
0
/* NB: try to mirror decodebin behavior */
static gboolean
swfdec_gst_feature_filter (GstPluginFeature *feature, gpointer caps, const gchar* klassname, gboolean autoplugonly)
{
  const GList *walk;
  const gchar *klass;

  /* we only care about element factories */
  if (!GST_IS_ELEMENT_FACTORY (feature))
    return FALSE;


  /* only decoders are interesting */
  klass = gst_element_factory_get_klass (GST_ELEMENT_FACTORY (feature));
  if (strstr (klass, klassname) == NULL)
    return FALSE;


  /* only select elements with autoplugging rank */
  if (autoplugonly && gst_plugin_feature_get_rank (feature) < GST_RANK_MARGINAL)
    return FALSE;

  /* only care about the right sink caps */
  for (walk = gst_element_factory_get_static_pad_templates (GST_ELEMENT_FACTORY (feature));
       walk; walk = walk->next) {
    GstStaticPadTemplate *template = walk->data;
static gboolean
check_parser_caps_filter (GstDecodebin3 * dbin, GstCaps * caps)
{
  GList *tmp;
  gboolean res = FALSE;

  g_mutex_lock (&dbin->factories_lock);
  gst_decode_bin_update_factories_list (dbin);
  for (tmp = dbin->decoder_factories; tmp; tmp = tmp->next) {
    GstElementFactory *factory = (GstElementFactory *) tmp->data;
    GstCaps *tcaps;
    const GList *tmps;

    GST_LOG ("Trying factory %s",
        gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
    for (tmps = gst_element_factory_get_static_pad_templates (factory); tmps;
        tmps = tmps->next) {
      GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data;
      if (st->direction != GST_PAD_SINK || st->presence != GST_PAD_ALWAYS)
        continue;
      tcaps = gst_static_pad_template_get_caps (st);
      if (gst_caps_can_intersect (tcaps, caps)) {
        res = TRUE;
        gst_caps_unref (tcaps);
        goto beach;
      }
      gst_caps_unref (tcaps);
    }
  }
beach:
  g_mutex_unlock (&dbin->factories_lock);
  GST_DEBUG_OBJECT (dbin, "Can intersect : %d", res);
  return res;
}
/**
 * Returns true if any |aFactory| caps intersect with |aCaps|
 */
static bool SupportsCaps(GstElementFactory *aFactory, GstCaps *aCaps)
{
  for (const GList *iter = gst_element_factory_get_static_pad_templates(aFactory); iter; iter = iter->next) {
    GstStaticPadTemplate *templ = static_cast<GstStaticPadTemplate *>(iter->data);

    if (templ->direction == GST_PAD_SRC) {
      continue;
    }

    GstCaps *caps = gst_static_caps_get(&templ->static_caps);
    if (!caps) {
      continue;
    }

    bool supported = gst_caps_can_intersect(caps, aCaps);
	
	gst_caps_unref(caps);
	
	if (supported) {
      return true;
    }
  }

  return false;
}
Esempio n. 4
0
static gboolean match_element(GstPluginFeature *feature, gpointer gdata)
{
    struct typeinfo *data = (struct typeinfo*)gdata;
    GstElementFactory *factory;
    const GList *list;

    if (!GST_IS_ELEMENT_FACTORY(feature))
        return FALSE;
    factory = GST_ELEMENT_FACTORY(feature);
    if (!strstr(gst_element_factory_get_klass(factory), data->type))
        return FALSE;
    for (list = gst_element_factory_get_static_pad_templates(factory); list; list = list->next) {
        GstStaticPadTemplate *pad = (GstStaticPadTemplate*)list->data;
        GstCaps *caps;
        gboolean ret;
        if (pad->direction != GST_PAD_SINK)
            continue;
        caps = gst_static_caps_get(&pad->static_caps);
        ret = gst_caps_is_always_compatible(caps, data->caps);
        gst_caps_unref(caps);
        if (ret)
            return TRUE;
    }
    return FALSE;
}
/* Get the intersection of parser caps and available (sorted) decoders */
static GstCaps *
get_parser_caps_filter (GstDecodebin3 * dbin, GstCaps * caps)
{
  GList *tmp;
  GstCaps *filter_caps = gst_caps_new_empty ();

  g_mutex_lock (&dbin->factories_lock);
  gst_decode_bin_update_factories_list (dbin);
  for (tmp = dbin->decoder_factories; tmp; tmp = tmp->next) {
    GstElementFactory *factory = (GstElementFactory *) tmp->data;
    GstCaps *tcaps, *intersection;
    const GList *tmps;

    GST_LOG ("Trying factory %s",
        gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
    for (tmps = gst_element_factory_get_static_pad_templates (factory); tmps;
        tmps = tmps->next) {
      GstStaticPadTemplate *st = (GstStaticPadTemplate *) tmps->data;
      if (st->direction != GST_PAD_SINK || st->presence != GST_PAD_ALWAYS)
        continue;
      tcaps = gst_static_pad_template_get_caps (st);
      intersection =
          gst_caps_intersect_full (tcaps, caps, GST_CAPS_INTERSECT_FIRST);
      filter_caps = gst_caps_merge (filter_caps, intersection);
      gst_caps_unref (tcaps);
    }
  }
  g_mutex_unlock (&dbin->factories_lock);
  GST_DEBUG_OBJECT (dbin, "Got filter caps %" GST_PTR_FORMAT, filter_caps);
  return filter_caps;
}
/**
 * gst_factory_list_filter:
 * @array: a #GValueArray to filter
 * @caps: a #GstCaps
 *
 * Filter out all the elementfactories in @array that can handle @caps as
 * input.
 *
 * Returns: a #GValueArray of #GstElementFactory elements. Use
 * g_value_array_free() after usage.
 */
GValueArray *
gst_factory_list_filter (GValueArray * array, const GstCaps * caps)
{
  GValueArray *result;
  gint i;

  result = g_value_array_new (0);

  GST_DEBUG ("finding factories");

  /* loop over all the factories */
  for (i = 0; i < array->n_values; i++) {
    GValue *value;
    GstElementFactory *factory;
    const GList *templates;
    GList *walk;

    value = g_value_array_get_nth (array, i);
    factory = g_value_get_object (value);

    /* get the templates from the element factory */
    templates = gst_element_factory_get_static_pad_templates (factory);
    for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
      GstStaticPadTemplate *templ = walk->data;

      /* we only care about the sink templates */
      if (templ->direction == GST_PAD_SINK) {
        GstCaps *intersect;
        GstCaps *tmpl_caps;

        /* try to intersect the caps with the caps of the template */
        tmpl_caps = gst_static_caps_get (&templ->static_caps);

        /* FIXME, intersect is not the right method, we ideally want to check
         * for a subset here */
        intersect = gst_caps_intersect (caps, tmpl_caps);
        gst_caps_unref (tmpl_caps);

        /* check if the intersection is empty */
        if (!gst_caps_is_empty (intersect)) {
          /* non empty intersection, we can use this element */
          GValue resval = { 0, };
          g_value_init (&resval, G_TYPE_OBJECT);
          g_value_set_object (&resval, factory);
          g_value_array_append (result, &resval);
          g_value_unset (&resval);
          gst_caps_unref (intersect);
          break;
        }
        gst_caps_unref (intersect);
      }
    }
  }
  return result;
}
/* check if caps are found on given element */
static gboolean
check_caps_compatibility (GstElementFactory *factory,
                          GstCaps *caps, GstCaps **matched_caps)
{
  const GList *pads;
  GstStaticPadTemplate *padtemplate;
  GstCaps *padtemplate_caps = NULL;

  if (!gst_element_factory_get_num_pad_templates (factory))
  {
    return FALSE;
  }

  pads = gst_element_factory_get_static_pad_templates (factory);
  while (pads)
  {
    padtemplate = (GstStaticPadTemplate *) (pads->data);
    pads = g_list_next (pads);

    padtemplate_caps = gst_static_caps_get (&padtemplate->static_caps);
    if (gst_caps_is_any (padtemplate_caps))
    {
      goto next;
    }

    if (caps)
    {
      GstCaps *intersection = gst_caps_intersect (padtemplate_caps, caps);
      gboolean have_intersection = !gst_caps_is_empty (intersection);

      if (have_intersection)
      {
        *matched_caps = intersection;
        gst_caps_unref (padtemplate_caps);
        return TRUE;
      }

      gst_caps_unref (intersection);
    }

next:
    if (padtemplate_caps)
    {
      gst_caps_unref (padtemplate_caps);
    }
  }

  *matched_caps = NULL;
  return FALSE;
}
static gboolean
factory_can_intersect (GstAutoConvert * autoconvert,
    GstElementFactory * factory, GstPadDirection direction, GstCaps * caps)
{
  const GList *templates;
  gint has_direction = FALSE;
  gboolean ret = FALSE;

  g_return_val_if_fail (factory != NULL, FALSE);
  g_return_val_if_fail (caps != NULL, FALSE);

  templates = gst_element_factory_get_static_pad_templates (factory);

  while (templates) {
    GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data;
Esempio n. 9
0
/**
 * gst_element_factory_list_filter:
 * @list: (transfer none) (element-type Gst.ElementFactory): a #GList of
 *     #GstElementFactory to filter
 * @caps: a #GstCaps
 * @direction: a #GstPadDirection to filter on
 * @subsetonly: whether to filter on caps subsets or not.
 *
 * Filter out all the elementfactories in @list that can handle @caps in
 * the given direction.
 *
 * If @subsetonly is %TRUE, then only the elements whose pads templates
 * are a complete superset of @caps will be returned. Else any element
 * whose pad templates caps can intersect with @caps will be returned.
 *
 * Returns: (transfer full) (element-type Gst.ElementFactory): a #GList of
 *     #GstElementFactory elements that match the given requisits.
 *     Use #gst_plugin_feature_list_free after usage.
 *
 * Since: 0.10.31
 */
GList *
gst_element_factory_list_filter (GList * list,
    const GstCaps * caps, GstPadDirection direction, gboolean subsetonly)
{
  GQueue results = G_QUEUE_INIT;

  GST_DEBUG ("finding factories");

  /* loop over all the factories */
  for (; list; list = list->next) {
    GstElementFactory *factory;
    const GList *templates;
    GList *walk;

    factory = (GstElementFactory *) list->data;

    GST_DEBUG ("Trying %s",
        gst_plugin_feature_get_name ((GstPluginFeature *) factory));

    /* get the templates from the element factory */
    templates = gst_element_factory_get_static_pad_templates (factory);
    for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
      GstStaticPadTemplate *templ = walk->data;

      /* we only care about the sink templates */
      if (templ->direction == direction) {
        GstCaps *tmpl_caps;

        /* try to intersect the caps with the caps of the template */
        tmpl_caps = gst_static_caps_get (&templ->static_caps);

        /* FIXME, intersect is not the right method, we ideally want to check
         * for a subset here */

        /* check if the intersection is empty */
        if ((subsetonly && gst_caps_is_subset (caps, tmpl_caps)) ||
            (!subsetonly && gst_caps_can_intersect (caps, tmpl_caps))) {
          /* non empty intersection, we can use this element */
          g_queue_push_tail (&results, gst_object_ref (factory));
          gst_caps_unref (tmpl_caps);
          break;
        }
        gst_caps_unref (tmpl_caps);
      }
    }
  }
  return results.head;
}
Esempio n. 10
0
/***
 * !reimp
 */
QStringList Backend::availableMimeTypes() const
{
    QStringList availableMimeTypes;

    if (!isValid())
        return availableMimeTypes;

    GstElementFactory *mpegFactory;
    // Add mp3 as a separate mime type as people are likely to look for it.
    if ((mpegFactory = gst_element_factory_find ("ffmpeg")) || 
        (mpegFactory = gst_element_factory_find ("mad"))) {
        availableMimeTypes << QLatin1String("audio/x-mp3");
        gst_object_unref(GST_OBJECT(mpegFactory));
    }

    // Iterate over all audio and video decoders and extract mime types from sink caps
    GList* factoryList = gst_registry_get_feature_list(gst_registry_get_default (), GST_TYPE_ELEMENT_FACTORY);
    for (GList* iter = g_list_first(factoryList) ; iter != NULL ; iter = g_list_next(iter)) {
        GstPluginFeature *feature = GST_PLUGIN_FEATURE(iter->data);
        QString klass = gst_element_factory_get_klass(GST_ELEMENT_FACTORY(feature));

        if (klass == QLatin1String("Codec/Decoder/Audio") || 
            klass == QLatin1String("Codec/Decoder/Video")) {

            const GList *static_templates;
            GstElementFactory *factory = GST_ELEMENT_FACTORY(feature);
            static_templates = gst_element_factory_get_static_pad_templates(factory);

            for (; static_templates != NULL ; static_templates = static_templates->next) {
                GstStaticPadTemplate *padTemplate = (GstStaticPadTemplate *) static_templates->data;
                if (padTemplate && padTemplate->direction == GST_PAD_SINK) {
                    GstCaps *caps = gst_static_pad_template_get_caps (padTemplate);

                    if (caps) {
                        const GstStructure* capsStruct = gst_caps_get_structure (caps, 0);
                        QString mime = QString::fromUtf8(gst_structure_get_name (capsStruct));
                        if (!availableMimeTypes.contains(mime))
                              availableMimeTypes.append(mime);
                    }
                }
            }
        }
    }
    g_list_free(factoryList);
    availableMimeTypes.sort();
    return availableMimeTypes;
}
Esempio n. 11
0
static void
print_pad_templates_info (GstElement * element, GstElementFactory * factory)
{
  GstElementClass *gstelement_class;
  const GList *pads;
  GstStaticPadTemplate *padtemplate;

  n_print ("Pad Templates:\n");
  if (gst_element_factory_get_num_pad_templates (factory) == 0) {
    n_print ("  none\n");
    return;
  }

  gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element));

  pads = gst_element_factory_get_static_pad_templates (factory);
  while (pads) {
    padtemplate = (GstStaticPadTemplate *) (pads->data);
    pads = g_list_next (pads);

    if (padtemplate->direction == GST_PAD_SRC)
      n_print ("  SRC template: '%s'\n", padtemplate->name_template);
    else if (padtemplate->direction == GST_PAD_SINK)
      n_print ("  SINK template: '%s'\n", padtemplate->name_template);
    else
      n_print ("  UNKNOWN!!! template: '%s'\n", padtemplate->name_template);

    if (padtemplate->presence == GST_PAD_ALWAYS)
      n_print ("    Availability: Always\n");
    else if (padtemplate->presence == GST_PAD_SOMETIMES)
      n_print ("    Availability: Sometimes\n");
    else if (padtemplate->presence == GST_PAD_REQUEST) {
      n_print ("    Availability: On request\n");
      n_print ("      Has request_new_pad() function: %s\n",
          GST_DEBUG_FUNCPTR_NAME (gstelement_class->request_new_pad));
    } else
      n_print ("    Availability: UNKNOWN!!!\n");

    if (padtemplate->static_caps.string) {
      n_print ("    Capabilities:\n");
      print_caps (gst_static_caps_get (&padtemplate->static_caps), "      ");
    }

    n_print ("\n");
  }
}
Esempio n. 12
0
/*
 * Method: pad_templates
 *
 * Requests all pad templates of factory.
 *
 * Returns: an array of Gst::PadTemplate objects.
 */
static VALUE
rb_gst_elementfactory_get_pad_templates (VALUE self)
{
    GstElementFactory *factory;
    const GList *list;
    VALUE arr;

    arr = rb_ary_new();
    factory = RGST_ELEMENT_FACTORY(self);
    for (list = gst_element_factory_get_static_pad_templates(factory);
         list != NULL;
         list = g_list_next(list)) {
        GstStaticPadTemplate *pad = list->data;
        rb_ary_push(arr, GST_STATIC_PAD_TEMPLATE2RVAL(pad));
    }
    return arr;
}
Esempio n. 13
0
gboolean sink_factory_filter(GstPluginFeature* feature, gpointer data) {
  GstCaps* caps = (GstCaps*)data;
  if (!GST_IS_ELEMENT_FACTORY(feature)) return FALSE;
  const GList* static_pads =
      gst_element_factory_get_static_pad_templates(GST_ELEMENT_FACTORY(feature));
  int not_any_number = 0;
  for (GList* item = (GList*)static_pads; item; item = item->next) {
    GstStaticPadTemplate* padTemplate = (GstStaticPadTemplate*)item->data;
    GstPadTemplate* pad = gst_static_pad_template_get(padTemplate);
    GstCaps* padCaps = gst_pad_template_get_caps(pad);
    if (!gst_caps_is_any(padCaps)) not_any_number++;
  }
  if (not_any_number == 0) return FALSE;
  if (!gst_element_factory_list_is_type(GST_ELEMENT_FACTORY(feature),
                                        GST_ELEMENT_FACTORY_TYPE_DECODABLE))
    return FALSE;
  if (!gst_element_factory_can_sink_all_caps(GST_ELEMENT_FACTORY(feature), caps)) return FALSE;
  return TRUE;
}
Esempio n. 14
0
static void
print_plugin_automatic_install_info_codecs (GstElementFactory * factory)
{
  GstPadDirection direction;
  const gchar *type_name;
  const gchar *klass;
  const GList *static_templates, *l;
  GstCaps *caps = NULL;
  guint i, num;

  klass =
      gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
  g_return_if_fail (klass != NULL);

  if (strstr (klass, "Demuxer") ||
      strstr (klass, "Decoder") ||
      strstr (klass, "Depay") || strstr (klass, "Parser")) {
    type_name = "decoder";
    direction = GST_PAD_SINK;
  } else if (strstr (klass, "Muxer") ||
      strstr (klass, "Encoder") || strstr (klass, "Pay")) {
    type_name = "encoder";
    direction = GST_PAD_SRC;
  } else {
    return;
  }

  /* decoder/demuxer sink pads should always be static and there should only
   * be one, the same applies to encoders/muxers and source pads */
  static_templates = gst_element_factory_get_static_pad_templates (factory);
  for (l = static_templates; l != NULL; l = l->next) {
    GstStaticPadTemplate *tmpl = NULL;

    tmpl = (GstStaticPadTemplate *) l->data;
    if (tmpl->direction == direction) {
      caps = gst_static_pad_template_get_caps (tmpl);
      break;
    }
  }

  if (caps == NULL) {
    g_printerr ("Couldn't find static pad template for %s '%s'\n",
        type_name, GST_OBJECT_NAME (factory));
    return;
  }

  caps = gst_caps_make_writable (caps);
  num = gst_caps_get_size (caps);
  for (i = 0; i < num; ++i) {
    GstStructure *s;
    gchar *s_str;

    s = gst_caps_get_structure (caps, i);
    /* remove fields that are almost always just MIN-MAX of some sort
     * in order to make the caps look less messy */
    gst_structure_remove_field (s, "pixel-aspect-ratio");
    gst_structure_remove_field (s, "framerate");
    gst_structure_remove_field (s, "channels");
    gst_structure_remove_field (s, "width");
    gst_structure_remove_field (s, "height");
    gst_structure_remove_field (s, "rate");
    gst_structure_remove_field (s, "depth");
    gst_structure_remove_field (s, "clock-rate");
    s_str = gst_structure_to_string (s);
    g_print ("%s-%s\n", type_name, s_str);
    g_free (s_str);
  }
  gst_caps_unref (caps);
}
Esempio n. 15
0
int
main (int argc,
      char *argv[])
{
    gst_init (&argc, &argv);
    
    GstElementFactory *factory = gst_element_factory_find("ffmpegcolorspace"); 
    const GList *list = gst_element_factory_get_static_pad_templates(factory);  
    while (NULL != list) {  
      GstStaticPadTemplate *templ = (GstStaticPadTemplate *)list->data;  
      // name  
      g_print("+++ template name %s\n", templ->name_template);  
      // direction  
      g_print ("direction: ");  
      switch (templ->direction) {  
        case GST_PAD_UNKNOWN:  
          g_print ("unknown\n");  
          break;  
        case GST_PAD_SRC:  
          g_print ("src\n");  
          break;  
        case GST_PAD_SINK:  
          g_print ("sink\n");  
          break;  
        default:  
          g_print ("this is a bug\n");  
          break;  
      }  

      // presence  
      g_print ("presence: ");  
      switch (templ->presence) {  
        case GST_PAD_ALWAYS:  
          g_print ("always\n");  
          break;  
        case GST_PAD_SOMETIMES:  
          g_print ("sometimes\n");  
          break;  
        case GST_PAD_REQUEST:  
          g_print ("request\n");  
          break;  
        default:  
          g_print ("this is a bug\n");  
          break;  
      }  

      // caps  
      GstCaps *caps = gst_static_caps_get(&templ->static_caps);  
      // copying for removing fields in struture  
      GstCaps *copy = gst_caps_copy(caps);  
      gst_caps_unref(caps);  

      guint size = gst_caps_get_size(copy);  
      guint i = 0;  
      g_print("size %u\n", size);  
      for (; i < size; i++) {  
        GstStructure *structure = gst_caps_get_structure(copy, i);  
        gst_structure_remove_fields(structure,  
                                    "format", "width", "height", "framerate",  
                                    NULL);  
        GstCaps *copy_nth = gst_caps_copy_nth(copy, i);   
        gchar *caps_str = gst_caps_to_string(copy_nth);   
        g_print("    caps num %u is %s\n", i, caps_str);   
        g_free(caps_str);   
        gst_caps_unref(copy_nth);   
      }  
      gst_caps_unref(copy);  
      list = g_list_next(list);  
    }  
    gst_object_unref(factory); 

    gst_deinit();  // for memory testing  
    return 0;
}
Esempio n. 16
0
static gboolean
rsndec_factory_filter (GstPluginFeature * feature, RsnDecFactoryFilterCtx * ctx)
{
  GstElementFactory *factory;
  guint rank;
  const gchar *klass;
  const GList *templates;
  GList *walk;
  gboolean can_sink = FALSE;

  /* we only care about element factories */
  if (!GST_IS_ELEMENT_FACTORY (feature))
    return FALSE;

  factory = GST_ELEMENT_FACTORY (feature);

  klass = gst_element_factory_get_klass (factory);
  /* only decoders can play */
  if (strstr (klass, "Decoder") == NULL)
    return FALSE;

  /* only select elements with autoplugging rank */
  rank = gst_plugin_feature_get_rank (feature);
  if (rank < GST_RANK_MARGINAL)
    return FALSE;

  /* See if the element has a sink pad that can possibly sink this caps */

  /* get the templates from the element factory */
  templates = gst_element_factory_get_static_pad_templates (factory);
  for (walk = (GList *) templates; walk && !can_sink; walk = g_list_next (walk)) {
    GstStaticPadTemplate *templ = walk->data;

    /* we only care about the sink templates */
    if (templ->direction == GST_PAD_SINK) {
      GstCaps *intersect;
      GstCaps *tmpl_caps;

      /* try to intersect the caps with the caps of the template */
      tmpl_caps = gst_static_caps_get (&templ->static_caps);

      intersect = gst_caps_intersect (ctx->desired_caps, tmpl_caps);
      gst_caps_unref (tmpl_caps);

      /* check if the intersection is empty */
      if (!gst_caps_is_empty (intersect)) {
        /* non empty intersection, we can use this element */
        can_sink = TRUE;
        ctx->decoder_caps = gst_caps_merge (ctx->decoder_caps, intersect);
      } else
        gst_caps_unref (intersect);
    }
  }

  if (can_sink) {
    GST_DEBUG ("Found decoder element %s (%s)",
        gst_element_factory_get_longname (factory),
        gst_plugin_feature_get_name (feature));
  }

  return can_sink;
}
Esempio n. 17
0
/* if element caps already in list, will make sure Transform elements have
 * priority and replace old ones */
static GList *
create_codec_cap_list (GstElementFactory *factory,
                       GstPadDirection direction,
                       GList *list,
                       GstCaps *rtp_caps)
{
  const GList *pads = gst_element_factory_get_static_pad_templates (factory);
  gint i;


  /* Let us look at each pad for stuff to add*/
  while (pads)
  {
    GstCaps *caps = NULL;
    GstStaticPadTemplate *padtemplate = NULL;

    padtemplate = (GstStaticPadTemplate *) (pads->data);
    pads = g_list_next (pads);

    if (padtemplate->direction != direction)
      continue;

    if (padtemplate->presence != GST_PAD_ALWAYS) {
      continue;
    }

    caps = gst_static_pad_template_get_caps (padtemplate);
    /*
      DEBUG ("%s caps are %s", gst_plugin_feature_get_name (GST_PLUGIN_FEATURE
      (factory)), gst_caps_to_string (caps));
    */

    /* skips caps ANY */
    if (!caps || gst_caps_is_any (caps))
    {
      goto done;
    }

    /* let us add one entry to the list per media type */
    for (i = 0; i < gst_caps_get_size (caps); i++)
    {
      CodecCap *entry = NULL;
      GList *found_item = NULL;
      GstStructure *structure = gst_caps_get_structure (caps, i);
      GstCaps *cur_caps = NULL;

      /* FIXME fix this in gstreamer! The rtpdepay element is bogus, it claims to
       * be a depayloader yet has application/x-rtp on both sides and does
       * absolutely nothing */
      /* Let's check if media caps are really media caps, this is to deal with
       * wierd elements such as rtpdepay that says it's a depayloader but has
       * application/x-rtp on src and sink pads */
      const gchar *name = gst_structure_get_name (structure);
      if (g_ascii_strcasecmp (name, "application/x-rtp") == 0)
      {
        GST_DEBUG ("skipping %s : %s",
            gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)), name);
        continue;
      }

      cur_caps = gst_caps_new_full (gst_structure_copy (structure), NULL);

      /* let's check if this caps is already in the list, if so let's replace
       * that CodecCap list instead of creating a new one */
      /* we need to compare both media caps and rtp caps */
      found_item = g_list_find_custom (list, cur_caps,
          (GCompareFunc)compare_media_caps);
      if (found_item)
      {
        entry = (CodecCap *)found_item->data;
        /* if RTP caps exist and don't match nullify entry */
        if (rtp_caps && compare_rtp_caps (found_item->data, rtp_caps))
        {
          entry = NULL;
        }
      }

      if (!entry)
      {
        entry = g_slice_new0 (CodecCap);

        entry->caps = cur_caps;
        if (rtp_caps)
        {
          entry->rtp_caps = rtp_caps;
          gst_caps_ref (rtp_caps);
        }
        list = g_list_append (list, entry);
        entry->element_list1 = g_list_prepend (NULL,
          g_list_prepend (NULL, factory));
        gst_object_ref (factory);
      }
      else
      {
        entry->element_list1->data =
          g_list_append (entry->element_list1->data, factory);
        gst_object_ref (factory);

        if (rtp_caps) {
          if (entry->rtp_caps) {
            GstCaps *tmp = gst_caps_intersect (rtp_caps, entry->rtp_caps);
            gst_caps_unref (entry->rtp_caps);
            entry->rtp_caps = tmp;
          } else {
            entry->rtp_caps = gst_caps_ref (rtp_caps);
            /* This shouldn't happen, its we're looking at rtp elements
             * or we're not */
            g_assert_not_reached ();
          }
        }
        entry->caps = gst_caps_merge (cur_caps, entry->caps);
      }
    }
  done:
    if (caps != NULL) {
      gst_caps_unref (caps);
    }

  }

  return list;
}
Esempio n. 18
0
int
main (int argc,
      char *argv[])
{
    
  /* Initialisation */
  gst_init (&argc, &argv);

  GList *element_list = gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_DEPAYLOADER, 
							       GST_RANK_NONE);
  GList *iter = element_list;
  while (iter != NULL)
    {
      g_print ("+++++\n");
      g_print ("%s -- ", gst_element_factory_get_longname ((GstElementFactory *)iter->data));
      g_print ("%s\n", gst_plugin_feature_get_name ((GstPluginFeature *)iter->data));
	 
      const GList *static_pads = 
	gst_element_factory_get_static_pad_templates ((GstElementFactory *)iter->data);
	 
      while (NULL != static_pads)
	{
	  GstStaticPadTemplate *pad = (GstStaticPadTemplate *)static_pads->data; 
	  //the following is EMPTY gchar *caps_str = gst_caps_to_string (&pad->static_caps.caps); 
	  //g_free (caps_str); 
	  /* g_print ("string: %s\n",  */
	  /* 	      pad->static_caps.string);  */
	  GstCaps *caps = gst_caps_from_string (pad->static_caps.string);
	  guint caps_size = gst_caps_get_size (caps);
	  if (! gst_caps_is_any (caps))
	    for (guint i = caps_size; i > 0; i--) 
	      {
		GstStructure *caps_struct = gst_caps_get_structure (caps, i-1);
		if (gst_structure_has_name (caps_struct,"application/x-rtp")) 
		  {
		    g_print ("string: %s\n",   
			     gst_structure_to_string (caps_struct));   
		    
		    {//payload 
		      const GValue *val = gst_structure_get_value (caps_struct, "payload");  
		      if (NULL != val) 
			{ 
			  //g_print ("payload struct type %s\n", G_VALUE_TYPE_NAME (val));  
			  if(GST_VALUE_HOLDS_INT_RANGE(val)) 
			    { 
			      g_print ("payload min %d\n", gst_value_get_int_range_min (val));  
			    } 
			  if (GST_VALUE_HOLDS_LIST(val)) 
			    { 
			      for (guint i = 0; i < gst_value_list_get_size (val); i++) 
				{ 
				  const GValue *item_val = gst_value_list_get_value (val, i); 
				  g_print ("payload list %d\n", g_value_get_int (item_val)); 
				} 
			    } 
			  if (G_VALUE_HOLDS_INT (val)) 
			    { 
			      g_print ("payload int %d\n", g_value_get_int (val)); 
			    } 
			} 
		    } 
		    { //encodeing-name
		      const GValue *val = gst_structure_get_value (caps_struct, "encoding-name");  
		      if (NULL != val) 
			{
			  //g_print ("encoding-name struct type %s\n", G_VALUE_TYPE_NAME (val));  
			  if (GST_VALUE_HOLDS_LIST(val)) 
			    { 
			      for (guint i = 0; i < gst_value_list_get_size (val); i++) 
				{ 
				  const GValue *item_val = gst_value_list_get_value (val, i); 
				  g_print ("encoding-name list %s\n", g_value_get_string (item_val)); 
				} 
			    } 
			  if (G_VALUE_HOLDS_STRING (val)) 
			    { 
			      g_print ("encoding-name string %s\n", g_value_get_string (val)); 
			    } 
				      
			}
		    } 
		    {//media
		      const GValue *val = gst_structure_get_value (caps_struct, "media");  
		      if (NULL != val) 
			{
			  if (GST_VALUE_HOLDS_LIST(val)) 
			    { 
			      for (guint i = 0; i < gst_value_list_get_size (val); i++) 
				{ 
				  const GValue *item_val = gst_value_list_get_value (val, i); 
				  g_print ("media list %s\n", g_value_get_string (item_val)); 
				} 
			    } 
			  if (G_VALUE_HOLDS_STRING (val)) 
			    { 
			      g_print ("media string %s\n", g_value_get_string (val)); 
			    } 
				      
			}
		    } 

		    {//clock rate 
		      const GValue *val = gst_structure_get_value (caps_struct, "clock-rate");  
		      if (NULL != val) 
			{ 
			  //g_print ("payload struct type %s\n", G_VALUE_TYPE_NAME (val));  
			  if(GST_VALUE_HOLDS_INT_RANGE(val)) 
			    { 
			      g_print ("clock-rate min %d\n", gst_value_get_int_range_min (val));  
			    } 
			  if (GST_VALUE_HOLDS_LIST(val)) 
			    { 
			      for (guint i = 0; i < gst_value_list_get_size (val); i++) 
				{ 
				  const GValue *item_val = gst_value_list_get_value (val, i); 
				  g_print ("clock-rate list %d\n", g_value_get_int (item_val)); 
				} 
			    } 
			  if (G_VALUE_HOLDS_INT (val)) 
			    { 
			      g_print ("clock-rate int %d\n", g_value_get_int (val)); 
			    } 
			} 
		    } 

		    /* g_print ("\nencoding-name %s\n",   */
		    /* 	 gst_structure_get_string (caps_struct,  */
		    /* 				   "encoding-name"));  */
			
		  }
	      }
	  static_pads = g_list_next (static_pads); 
	  gst_caps_unref (caps);
	}
	 
      iter = g_list_next (iter);
    }
  gst_plugin_feature_list_free (element_list);
    
  return 0;
}
Esempio n. 19
0
static void
try_to_plug (GstPad        *pad,
	     const GstCaps *caps)
{
  GstObject *parent = GST_OBJECT (GST_OBJECT_PARENT (pad));
  const gchar *mime;
  const GList *item;
  GstCaps *res, *audiocaps;

  /* don't plug if we're already plugged - FIXME: memleak for pad */
  if (GST_PAD_IS_LINKED (gst_element_get_pad (audiosink, "sink"))) {
    g_print ("Omitting link for pad %s:%s because we're already linked\n",
	     GST_OBJECT_NAME (parent), GST_OBJECT_NAME (pad));
    return;
  }

  /* as said above, we only try to plug audio... Omit video */
  mime = gst_structure_get_name (gst_caps_get_structure (caps, 0));
  if (g_strrstr (mime, "video")) {
    g_print ("Omitting link for pad %s:%s because mimetype %s is non-audio\n",
	     GST_OBJECT_NAME (parent), GST_OBJECT_NAME (pad), mime);
    return;
  }

  /* can it link to the audiopad? */
  audiocaps = gst_pad_get_caps (gst_element_get_pad (audiosink, "sink"));
  res = gst_caps_intersect (caps, audiocaps);
  if (res && !gst_caps_is_empty (res)) {
    g_print ("Found pad to link to audiosink - plugging is now done\n");
    close_link (pad, audiosink, "sink", NULL);
    gst_caps_unref (audiocaps);
    gst_caps_unref (res);
    return;
  }
  gst_caps_unref (audiocaps);
  gst_caps_unref (res);

  /* try to plug from our list */
  for (item = factories; item != NULL; item = item->next) {
    GstElementFactory *factory = GST_ELEMENT_FACTORY (item->data);
    const GList *pads;

    for (pads = gst_element_factory_get_static_pad_templates (factory);
         pads != NULL; pads = pads->next) {
      GstStaticPadTemplate *templ = pads->data;

      /* find the sink template - need an always pad*/
      if (templ->direction != GST_PAD_SINK ||
          templ->presence != GST_PAD_ALWAYS) {
        continue;
      }

      /* can it link? */
      res = gst_caps_intersect (caps,
          gst_static_caps_get (&templ->static_caps));
      if (res && !gst_caps_is_empty (res)) {
        GstElement *element;
        gchar *name_template = g_strdup (templ->name_template);

        /* close link and return */
        gst_caps_unref (res);
        element = gst_element_factory_create (factory, NULL);
        close_link (pad, element, name_template,
		    gst_element_factory_get_static_pad_templates (factory));
        g_free (name_template);
        return;
      }
      gst_caps_unref (res);

      /* we only check one sink template per factory, so move on to the
       * next factory now */
      break;
    }
  }

  /* if we get here, no item was found */
  g_print ("No compatible pad found to decode %s on %s:%s\n",
	   mime, GST_OBJECT_NAME (parent), GST_OBJECT_NAME (pad));
}