Пример #1
0
static void
check_caps (const gchar * set, const gchar * subset)
{
  GstCaps *one, *two, *test, *test2;

  g_print ("        A  =  %s\n", set);
  one = gst_caps_from_string (set);
  g_print ("        B  =  %s\n", subset);
  two = gst_caps_from_string (subset);
  /* basics */
  test = gst_caps_subtract (one, one);
  g_assert (gst_caps_is_empty (test));
  gst_caps_unref (test);
  test = gst_caps_subtract (two, two);
  g_assert (gst_caps_is_empty (test));
  gst_caps_unref (test);
  test = gst_caps_subtract (two, one);
  g_assert (gst_caps_is_empty (test));
  gst_caps_unref (test);
  /* now the nice part */
  test = gst_caps_subtract (one, two);
  g_assert (!gst_caps_is_empty (test));
  g_print ("    A - B  =  %s\n", gst_caps_to_string (test));
  test2 = gst_caps_union (test, two);
  g_print ("A - B + B  =  %s\n", gst_caps_to_string (test2));
  gst_caps_unref (test);
  test = gst_caps_subtract (test2, one);
  g_assert (gst_caps_is_empty (test));
  gst_caps_unref (test);
}
Пример #2
0
CapsPtr Caps::getUnion(const CapsPtr & caps2) const
{
    return CapsPtr::wrap(gst_caps_union(object<GstCaps>(), caps2), false);
}
/* 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 = factory->staticpadtemplates;
  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 (GST_PAD_TEMPLATE_PRESENCE (padtemplate) != GST_PAD_ALWAYS) {
      continue;
    }

    caps = gst_static_caps_get (&padtemplate->static_caps);
    /*
      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 =
          gst_caps_new_full (gst_structure_copy (structure), 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",
            gst_plugin_feature_get_name (GST_PLUGIN_FEATURE (factory)));
        continue;
      }

      /* 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
      {
        GstCaps *newcaps;

        entry->element_list1->data =
          g_list_append (entry->element_list1->data, factory);
        gst_object_ref (factory);

        if (rtp_caps) {
          if (entry->rtp_caps) {
            GstCaps *new_rtp_caps;
            new_rtp_caps = gst_caps_union (rtp_caps, entry->rtp_caps);
            gst_caps_unref (entry->rtp_caps);
            entry->rtp_caps = new_rtp_caps;
          } else {
            entry->rtp_caps = rtp_caps;
            /* This shouldn't happen, its we're looking at rtp elements
             * or we're not */
            g_assert_not_reached ();
          }
          gst_caps_unref (rtp_caps);
        }

        newcaps = gst_caps_union (cur_caps, entry->caps);
        gst_caps_unref (entry->caps);
        gst_caps_unref (cur_caps);
        entry->caps = newcaps;

      }
    }
  done:
    if (caps != NULL) {
      gst_caps_unref (caps);
    }

  }

  return list;
}
/* returns the intersection of two lists */
static GList *
codec_cap_list_intersect (GList *list1, GList *list2)
{
  GList *walk1, *walk2;
  CodecCap *codec_cap1, *codec_cap2;
  GstCaps *caps1, *caps2;
  GstCaps *rtp_caps1, *rtp_caps2;
  GList *intersection_list = NULL;

  for (walk1 = g_list_first (list1); walk1; walk1 = g_list_next (walk1))
  {
    CodecCap *item = NULL;

    codec_cap1 = (CodecCap *)(walk1->data);
    caps1 = codec_cap1->caps;
    rtp_caps1 = codec_cap1->rtp_caps;
    for (walk2 = list2; walk2; walk2 = g_list_next (walk2))
    {
      GstCaps *intersection = NULL;
      GstCaps *rtp_intersection = NULL;

      codec_cap2 = (CodecCap *)(walk2->data);
      caps2 = codec_cap2->caps;
      rtp_caps2 = codec_cap2->rtp_caps;

      //g_debug ("intersecting %s AND %s", gst_caps_to_string (caps1), gst_caps_to_string (caps2));
      intersection = gst_caps_intersect (caps1, caps2);
      if (rtp_caps1 && rtp_caps2)
      {
        //g_debug ("RTP intersecting %s AND %s", gst_caps_to_string (rtp_caps1), gst_caps_to_string (rtp_caps2));
        rtp_intersection = gst_caps_intersect (rtp_caps1, rtp_caps2);
      }
      if (!gst_caps_is_empty (intersection) &&
          (rtp_intersection == NULL || !gst_caps_is_empty (rtp_intersection)))
      {
        if (item) {
          GstCaps *new_caps = gst_caps_union (item->caps, intersection);
          GList *tmplist;

          gst_caps_unref (item->caps);
          item->caps = new_caps;

          for (tmplist = g_list_first (codec_cap2->element_list1->data);
               tmplist;
               tmplist = g_list_next (tmplist)) {
            if (g_list_index (item->element_list2->data, tmplist->data) < 0) {
              item->element_list2->data = g_list_concat (
                  item->element_list2->data,
                  g_list_copy (codec_cap2->element_list1->data));
              g_list_foreach (codec_cap2->element_list1->data,
                (GFunc) gst_object_ref, NULL);
            }
          }
        } else {

          item = g_slice_new0 (CodecCap);
          item->caps = gst_caps_ref (intersection);

          if (rtp_caps1 && rtp_caps2)
          {
            item->rtp_caps = rtp_intersection;
          }
          else if (rtp_caps1)
          {
            item->rtp_caps = rtp_caps1;
            gst_caps_ref (rtp_caps1);
          }
          else if (rtp_caps2)
          {
            item->rtp_caps = rtp_caps2;
            gst_caps_ref (rtp_caps2);
          }

          /* during an intersect, we concat/copy previous lists together and put them
           * into 1 and 2 */


          item->element_list1 = g_list_concat (
              copy_element_list (codec_cap1->element_list1),
              copy_element_list (codec_cap1->element_list2));
          item->element_list2 = g_list_concat (
              copy_element_list (codec_cap2->element_list1),
              copy_element_list (codec_cap2->element_list2));

          intersection_list = g_list_append (intersection_list, item);
          if (rtp_intersection)
            break;
        }
      } else {
        if (rtp_intersection)
          gst_caps_unref (rtp_intersection);
      }
      gst_caps_unref (intersection);
    }
  }

  return intersection_list;
}
Пример #5
0
/*
 * Method: union(caps)
 * caps: another Gst::Caps.
 *
 * Creates a new Gst::Caps that contains all the formats that are in 
either
 * self and the given caps.
 *
 * Returns: a new Gst::Caps object.
 */
static VALUE
rg_union (VALUE self, VALUE caps)
{
    return RGST_CAPS_NEW (gst_caps_union (RGST_CAPS (self), RGST_CAPS (caps)));
}