Esempio n. 1
0
static GstCaps *
_set_caps_features_with_passthrough (const GstCaps * caps,
    const gchar * feature_name, GstCapsFeatures * passthrough)
{
  guint i, j, m, n;
  GstCaps *tmp;

  tmp = gst_caps_new_empty ();

  n = gst_caps_get_size (caps);
  for (i = 0; i < n; i++) {
    GstCapsFeatures *features, *orig_features;
    GstStructure *s = gst_caps_get_structure (caps, i);

    orig_features = gst_caps_get_features (caps, i);
    features = gst_caps_features_new (feature_name, NULL);

    if (gst_caps_features_is_any (orig_features)) {
      /* if we have any features, we add both the features with and without @passthrough */
      gst_caps_append_structure_full (tmp, gst_structure_copy (s),
          gst_caps_features_copy (features));

      m = gst_caps_features_get_size (passthrough);
      for (j = 0; j < m; j++) {
        const gchar *feature = gst_caps_features_get_nth (passthrough, j);

        /* if we already have the features */
        if (gst_caps_features_contains (features, feature))
          continue;

        gst_caps_features_add (features, feature);
      }
    } else {
      m = gst_caps_features_get_size (orig_features);
      for (j = 0; j < m; j++) {
        const gchar *feature = gst_caps_features_get_nth (orig_features, j);

        /* if we already have the features */
        if (gst_caps_features_contains (features, feature))
          continue;

        if (g_strcmp0 (feature, GST_CAPS_FEATURE_MEMORY_SYSTEM_MEMORY) == 0)
          continue;

        if (gst_caps_features_contains (passthrough, feature)) {
          gst_caps_features_add (features, feature);
        }
      }
    }

    gst_caps_append_structure_full (tmp, gst_structure_copy (s), features);
  }

  return tmp;
}
/* copies the given caps */
static GstCaps *
gst_video_convert_caps_remove_format_info (GstCaps * caps)
{
  GstStructure *st;
  GstCapsFeatures *f;
  gint i, n;
  GstCaps *res;

  res = gst_caps_new_empty ();

  n = gst_caps_get_size (caps);
  for (i = 0; i < n; i++) {
    st = gst_caps_get_structure (caps, i);
    f = gst_caps_get_features (caps, i);

    /* If this is already expressed by the existing caps
     * skip this structure */
    if (i > 0 && gst_caps_is_subset_structure_full (res, st, f))
      continue;

    st = gst_structure_copy (st);
    /* Only remove format info for the cases when we can actually convert */
    if (!gst_caps_features_is_any (f)
        && gst_caps_features_is_equal (f,
            GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY))
      gst_structure_remove_fields (st, "format", "colorimetry", "chroma-site",
          NULL);

    gst_caps_append_structure_full (res, st, gst_caps_features_copy (f));
  }

  return res;
}
static GstCaps *
gst_video_scale_transform_caps (GstBaseTransform * trans,
                                GstPadDirection direction, GstCaps * caps, GstCaps * filter)
{
    GstCaps *ret;
    GstStructure *structure;
    GstCapsFeatures *features;
    gint i, n;

    GST_DEBUG_OBJECT (trans,
                      "Transforming caps %" GST_PTR_FORMAT " in direction %s", caps,
                      (direction == GST_PAD_SINK) ? "sink" : "src");

    ret = gst_caps_new_empty ();
    n = gst_caps_get_size (caps);
    for (i = 0; i < n; i++) {
        structure = gst_caps_get_structure (caps, i);
        features = gst_caps_get_features (caps, i);

        /* If this is already expressed by the existing caps
         * skip this structure */
        if (i > 0 && gst_caps_is_subset_structure_full (ret, structure, features))
            continue;

        /* make copy */
        structure = gst_structure_copy (structure);

        /* If the features are non-sysmem we can only do passthrough */
        if (!gst_caps_features_is_any (features)
                && gst_caps_features_is_equal (features,
                                               GST_CAPS_FEATURES_MEMORY_SYSTEM_MEMORY)) {
            gst_structure_set (structure, "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
                               "height", GST_TYPE_INT_RANGE, 1, G_MAXINT, NULL);

            /* if pixel aspect ratio, make a range of it */
            if (gst_structure_has_field (structure, "pixel-aspect-ratio")) {
                gst_structure_set (structure, "pixel-aspect-ratio",
                                   GST_TYPE_FRACTION_RANGE, 1, G_MAXINT, G_MAXINT, 1, NULL);
            }
        }
        gst_caps_append_structure_full (ret, structure,
                                        gst_caps_features_copy (features));
    }

    if (filter) {
        GstCaps *intersection;

        intersection =
            gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
        gst_caps_unref (ret);
        ret = intersection;
    }

    GST_DEBUG_OBJECT (trans, "returning caps: %" GST_PTR_FORMAT, ret);

    return ret;
}
/* For each raw video structure, adds a variant with framerate unset */
static gboolean
fix_video_caps_framerate(GstCapsFeatures *f, GstStructure *s, gpointer user_data)
{
    GstCaps *ret = GST_CAPS(user_data);
    gint fps_n, fps_d;

    gst_caps_append_structure_full(ret, gst_structure_copy(s), f ? gst_caps_features_copy(f) : NULL);

    /* Don't mess with non-raw structures */
    if (!gst_structure_has_name(s, "video/x-raw"))
        goto done;

    /* If possible try to limit the framerate at the source already */
    if (gst_structure_get_fraction(s, "framerate", &fps_n, &fps_d)) {
        GstStructure *tmp = gst_structure_copy(s);
        gst_structure_remove_field(tmp, "framerate");
        gst_caps_append_structure_full(ret, tmp, f ? gst_caps_features_copy(f) : NULL);
    }

done:
    return TRUE;
}
/*
 * Takes caps and copies its video fields to tmpl_caps
 */
static GstCaps *
__gst_video_element_proxy_caps (GstElement * element, GstCaps * templ_caps,
    GstCaps * caps)
{
  GstCaps *result = gst_caps_new_empty ();
  gint i, j;
  gint templ_caps_size = gst_caps_get_size (templ_caps);
  gint caps_size = gst_caps_get_size (caps);

  for (i = 0; i < templ_caps_size; i++) {
    GQuark q_name =
        gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i));
    GstCapsFeatures *features = gst_caps_get_features (templ_caps, i);

    for (j = 0; j < caps_size; j++) {
      const GstStructure *caps_s = gst_caps_get_structure (caps, j);
      const GValue *val;
      GstStructure *s;
      GstCaps *tmp = gst_caps_new_empty ();

      s = gst_structure_new_id_empty (q_name);
      if ((val = gst_structure_get_value (caps_s, "width")))
        gst_structure_set_value (s, "width", val);
      if ((val = gst_structure_get_value (caps_s, "height")))
        gst_structure_set_value (s, "height", val);
      if ((val = gst_structure_get_value (caps_s, "framerate")))
        gst_structure_set_value (s, "framerate", val);
      if ((val = gst_structure_get_value (caps_s, "pixel-aspect-ratio")))
        gst_structure_set_value (s, "pixel-aspect-ratio", val);
      if ((val = gst_structure_get_value (caps_s, "colorimetry")))
        gst_structure_set_value (s, "colorimetry", val);
      if ((val = gst_structure_get_value (caps_s, "chroma-site")))
        gst_structure_set_value (s, "chroma-site", val);

      gst_caps_append_structure_full (tmp, s,
          gst_caps_features_copy (features));
      result = gst_caps_merge (result, tmp);
    }
  }

  return result;
}
/*
 * Takes caps and copies its audio fields to tmpl_caps
 */
static GstCaps *
__gst_audio_element_proxy_caps (GstElement * element, GstCaps * templ_caps,
                                GstCaps * caps)
{
    GstCaps *result = gst_caps_new_empty ();
    gint i, j;
    gint templ_caps_size = gst_caps_get_size (templ_caps);
    gint caps_size = gst_caps_get_size (caps);

    for (i = 0; i < templ_caps_size; i++) {
        GQuark q_name =
            gst_structure_get_name_id (gst_caps_get_structure (templ_caps, i));
        GstCapsFeatures *features = gst_caps_get_features (templ_caps, i);

        for (j = 0; j < caps_size; j++) {
            const GstStructure *caps_s = gst_caps_get_structure (caps, j);
            const GValue *val;
            GstStructure *s;
            GstCaps *tmp = gst_caps_new_empty ();

            s = gst_structure_new_id_empty (q_name);
            if ((val = gst_structure_get_value (caps_s, "rate")))
                gst_structure_set_value (s, "rate", val);
            if ((val = gst_structure_get_value (caps_s, "channels")))
                gst_structure_set_value (s, "channels", val);
            if ((val = gst_structure_get_value (caps_s, "channels-mask")))
                gst_structure_set_value (s, "channels-mask", val);

            gst_caps_append_structure_full (tmp, s,
                                            gst_caps_features_copy (features));
            result = gst_caps_merge (result, tmp);
        }
    }

    return result;
}