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; }