2 * Copyright (C) <2010> Edward Hervey <edward.hervey@collabora.co.uk>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include "gstcapslist.h"
23 * Caps listing convenience functions
27 remove_range_foreach (GQuark field_id, const GValue * value, GstStructure * st)
29 GType ftype = G_VALUE_TYPE (value);
30 /* const gchar *fname; */
32 if (ftype == GST_TYPE_INT_RANGE || ftype == GST_TYPE_DOUBLE_RANGE ||
33 ftype == GST_TYPE_FRACTION_RANGE) {
34 gst_structure_remove_field (st, g_quark_to_string (field_id));
38 /* fname = g_quark_to_string (field_id); */
39 /* if (strstr (fname, "framerate") || strstr (fname, "pixel-aspect-ratio") || */
40 /* strstr (fname, "rate")) { */
41 /* gst_structure_remove_field (st, g_quark_to_string (field_id)); */
49 clear_caps (GstCaps * caps, GstCaps * rescaps)
55 res = gst_caps_make_writable (caps);
57 GST_DEBUG ("incoming caps %" GST_PTR_FORMAT, res);
59 /* Remove width/height/framerate/depth/width fields */
60 for (i = gst_caps_get_size (res); i; i--) {
61 st = gst_caps_get_structure (res, i - 1);
63 /* Remove range fields */
64 while (!gst_structure_foreach (st,
65 (GstStructureForeachFunc) remove_range_foreach, st));
68 GST_DEBUG ("stripped %" GST_PTR_FORMAT, res);
70 /* And append to list without duplicates */
71 while ((st = gst_caps_steal_structure (res, 0))) {
72 /* Skip fake codecs/containers */
73 if (gst_structure_has_name (st, "audio/x-raw-int") ||
74 gst_structure_has_name (st, "audio/x-raw-float") ||
75 gst_structure_has_name (st, "video/x-raw-yuv") ||
76 gst_structure_has_name (st, "video/x-raw-rgb") ||
77 gst_structure_has_name (st, "unknown/unknown")) {
78 gst_structure_free (st);
82 gst_caps_append_structure (rescaps, st);
89 get_all_caps (GList * elements, GstPadDirection direction)
91 GstCaps *res = NULL, *res2;
94 res = gst_caps_new_empty ();
96 for (tmp = elements; tmp; tmp = tmp->next) {
97 GstElementFactory *factory = (GstElementFactory *) tmp->data;
98 const GList *templates;
101 templates = gst_element_factory_get_static_pad_templates (factory);
102 for (walk = (GList *) templates; walk; walk = g_list_next (walk)) {
103 GstStaticPadTemplate *templ = walk->data;
104 if (templ->direction == direction)
105 clear_caps (gst_static_caps_get (&templ->static_caps), res);
109 res2 = gst_caps_normalize (res);
110 gst_caps_unref (res);
115 * gst_caps_list_container_formats:
116 * @minrank: The minimum #GstRank
118 * Returns a #GstCaps corresponding to all the container formats
119 * one can mux to on this system.
121 * Returns: A #GstCaps. Unref with %gst_caps_unref when done with it.
124 gst_caps_list_container_formats (GstRank minrank)
130 gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER,
132 res = get_all_caps (muxers, GST_PAD_SRC);
133 gst_plugin_feature_list_free (muxers);
139 gst_caps_list_encoding_formats (GstRank minrank)
145 gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_ENCODER,
147 res = get_all_caps (encoders, GST_PAD_SRC);
148 gst_plugin_feature_list_free (encoders);
154 * gst_caps_list_video_encoding_formats:
155 * @minrank: The minimum #GstRank
157 * Returns a #GstCaps corresponding to all the video or image formats one
158 * can encode to on this system.
160 * Returns: A #GstCaps. Unref with %gst_caps_unref when done with it.
163 gst_caps_list_video_encoding_formats (GstRank minrank)
169 gst_element_factory_list_get_elements
170 (GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER, minrank);
171 res = get_all_caps (encoders, GST_PAD_SRC);
172 gst_plugin_feature_list_free (encoders);
179 * gst_caps_list_audio_encoding_formats:
180 * @minrank: The minimum #GstRank
182 * Returns a #GstCaps corresponding to all the audio formats one
183 * can encode to on this system.
185 * Returns: A #GstCaps. Unref with %gst_caps_unref when done with it.
188 gst_caps_list_audio_encoding_formats (GstRank minrank)
194 gst_element_factory_list_get_elements
195 (GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER, minrank);
196 res = get_all_caps (encoders, GST_PAD_SRC);
197 gst_plugin_feature_list_free (encoders);
203 * gst_caps_list_compatible_codecs:
204 * @containerformat: A #GstCaps corresponding to a container format
205 * @codecformats: An optional #GstCaps of codec formats
206 * @muxers: An optional #GList of muxer #GstElementFactory.
208 * Returns an array of #GstCaps corresponding to the audio/video/text formats
209 * one can encode to and that can be muxed in the provided @containerformat.
211 * If specified, only the #GstCaps contained in @codecformats will be checked
212 * against, else all compatible audio/video formats will be returned.
214 * If specified, only the #GstElementFactory contained in @muxers will be checked,
215 * else all available muxers on the system will be checked.
217 * Returns: A #GstCaps containing all compatible formats. Unref with %gst_caps_unref
221 gst_caps_list_compatible_codecs (const GstCaps * containerformat,
222 GstCaps * codecformats, GList * muxers)
224 const GList *templates;
225 GstElementFactory *factory;
230 gboolean hadmuxers = (muxers != NULL);
231 gboolean hadcodecs = (codecformats != NULL);
233 GST_DEBUG ("containerformat: %" GST_PTR_FORMAT, containerformat);
234 GST_DEBUG ("codecformats: %" GST_PTR_FORMAT, codecformats);
238 gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER,
241 codecformats = gst_caps_list_encoding_formats (GST_RANK_NONE);
243 /* Get the highest rank muxer matching containerformat */
245 gst_element_factory_list_filter (muxers, containerformat, GST_PAD_SRC,
247 if (G_UNLIKELY (tmp == NULL))
250 factory = (GstElementFactory *) tmp->data;
252 GST_DEBUG ("Trying with factory %s",
253 gst_element_factory_get_longname (factory));
255 /* Match all muxer sink pad templates against the available codec formats */
256 templates = gst_element_factory_get_static_pad_templates (factory);
257 gst_plugin_feature_list_free (tmp);
259 tmpcaps = gst_caps_new_empty ();
261 for (walk = (GList *) templates; walk; walk = walk->next) {
262 GstStaticPadTemplate *templ = walk->data;
264 if (templ->direction == GST_PAD_SINK) {
267 templ_caps = gst_static_caps_get (&templ->static_caps);
268 gst_caps_append (tmpcaps, gst_caps_copy (templ_caps));
272 res = gst_caps_intersect (tmpcaps, codecformats);
273 gst_caps_unref (tmpcaps);
277 gst_plugin_feature_list_free (muxers);
279 gst_caps_unref (codecformats);
281 tmpcaps = gst_caps_normalize (res);
282 gst_caps_unref (res);