Added gst-plugins-base-subtitles0.10-0.10.34 for Meego Harmattan 1.2
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / tests / examples / encoding / gstcapslist.c
1 /* GStreamer
2  * Copyright (C) <2010> Edward Hervey <edward.hervey@collabora.co.uk>
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 #include "gstcapslist.h"
21
22 /*
23  * Caps listing convenience functions
24  */
25
26 static gboolean
27 remove_range_foreach (GQuark field_id, const GValue * value, GstStructure * st)
28 {
29   GType ftype = G_VALUE_TYPE (value);
30   /* const gchar *fname; */
31
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));
35     return FALSE;
36   }
37
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)); */
42   /*   return FALSE; */
43   /* } */
44
45   return TRUE;
46 }
47
48 static void
49 clear_caps (GstCaps * caps, GstCaps * rescaps)
50 {
51   GstCaps *res;
52   GstStructure *st;
53   guint i;
54
55   res = gst_caps_make_writable (caps);
56
57   GST_DEBUG ("incoming caps %" GST_PTR_FORMAT, res);
58
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);
62
63     /* Remove range fields */
64     while (!gst_structure_foreach (st,
65             (GstStructureForeachFunc) remove_range_foreach, st));
66   }
67
68   GST_DEBUG ("stripped %" GST_PTR_FORMAT, res);
69
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);
79       continue;
80     }
81
82     gst_caps_append_structure (rescaps, st);
83   }
84
85   gst_caps_unref (res);
86 }
87
88 static GstCaps *
89 get_all_caps (GList * elements, GstPadDirection direction)
90 {
91   GstCaps *res = NULL, *res2;
92   GList *tmp;
93
94   res = gst_caps_new_empty ();
95
96   for (tmp = elements; tmp; tmp = tmp->next) {
97     GstElementFactory *factory = (GstElementFactory *) tmp->data;
98     const GList *templates;
99     GList *walk;
100
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);
106     }
107   }
108
109   res2 = gst_caps_normalize (res);
110   gst_caps_unref (res);
111   return res2;
112 }
113
114 /**
115  * gst_caps_list_container_formats:
116  * @minrank: The minimum #GstRank
117  *
118  * Returns a #GstCaps corresponding to all the container formats
119  * one can mux to on this system.
120  *
121  * Returns: A #GstCaps. Unref with %gst_caps_unref when done with it.
122  */
123 GstCaps *
124 gst_caps_list_container_formats (GstRank minrank)
125 {
126   GstCaps *res;
127   GList *muxers;
128
129   muxers =
130       gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER,
131       minrank);
132   res = get_all_caps (muxers, GST_PAD_SRC);
133   gst_plugin_feature_list_free (muxers);
134
135   return res;
136 }
137
138 static GstCaps *
139 gst_caps_list_encoding_formats (GstRank minrank)
140 {
141   GstCaps *res;
142   GList *encoders;
143
144   encoders =
145       gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_ENCODER,
146       minrank);
147   res = get_all_caps (encoders, GST_PAD_SRC);
148   gst_plugin_feature_list_free (encoders);
149
150   return res;
151 }
152
153 /**
154  * gst_caps_list_video_encoding_formats:
155  * @minrank: The minimum #GstRank
156  *
157  * Returns a #GstCaps corresponding to all the video or image formats one
158  * can encode to on this system.
159  *
160  * Returns: A #GstCaps. Unref with %gst_caps_unref when done with it.
161  */
162 GstCaps *
163 gst_caps_list_video_encoding_formats (GstRank minrank)
164 {
165   GstCaps *res;
166   GList *encoders;
167
168   encoders =
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);
173
174   return res;
175 }
176
177
178 /**
179  * gst_caps_list_audio_encoding_formats:
180  * @minrank: The minimum #GstRank
181  *
182  * Returns a #GstCaps corresponding to all the audio formats one
183  * can encode to on this system.
184  *
185  * Returns: A  #GstCaps. Unref with %gst_caps_unref when done with it.
186  */
187 GstCaps *
188 gst_caps_list_audio_encoding_formats (GstRank minrank)
189 {
190   GstCaps *res;
191   GList *encoders;
192
193   encoders =
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);
198
199   return res;
200 }
201
202 /**
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.
207  *
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.
210  *
211  * If specified, only the #GstCaps contained in @codecformats will be checked
212  * against, else all compatible audio/video formats will be returned.
213  *
214  * If specified, only the #GstElementFactory contained in @muxers will be checked,
215  * else all available muxers on the system will be checked.
216  *
217  * Returns: A #GstCaps containing all compatible formats. Unref with %gst_caps_unref
218  * when done.
219  */
220 GstCaps *
221 gst_caps_list_compatible_codecs (const GstCaps * containerformat,
222     GstCaps * codecformats, GList * muxers)
223 {
224   const GList *templates;
225   GstElementFactory *factory;
226   GList *walk;
227   GstCaps *res = NULL;
228   GstCaps *tmpcaps;
229   GList *tmp;
230   gboolean hadmuxers = (muxers != NULL);
231   gboolean hadcodecs = (codecformats != NULL);
232
233   GST_DEBUG ("containerformat: %" GST_PTR_FORMAT, containerformat);
234   GST_DEBUG ("codecformats: %" GST_PTR_FORMAT, codecformats);
235
236   if (!hadmuxers)
237     muxers =
238         gst_element_factory_list_get_elements (GST_ELEMENT_FACTORY_TYPE_MUXER,
239         GST_RANK_NONE);
240   if (!hadcodecs)
241     codecformats = gst_caps_list_encoding_formats (GST_RANK_NONE);
242
243   /* Get the highest rank muxer matching containerformat */
244   tmp =
245       gst_element_factory_list_filter (muxers, containerformat, GST_PAD_SRC,
246       TRUE);
247   if (G_UNLIKELY (tmp == NULL))
248     goto beach;
249
250   factory = (GstElementFactory *) tmp->data;
251
252   GST_DEBUG ("Trying with factory %s",
253       gst_element_factory_get_longname (factory));
254
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);
258
259   tmpcaps = gst_caps_new_empty ();
260
261   for (walk = (GList *) templates; walk; walk = walk->next) {
262     GstStaticPadTemplate *templ = walk->data;
263
264     if (templ->direction == GST_PAD_SINK) {
265       GstCaps *templ_caps;
266
267       templ_caps = gst_static_caps_get (&templ->static_caps);
268       gst_caps_append (tmpcaps, gst_caps_copy (templ_caps));
269     }
270   }
271
272   res = gst_caps_intersect (tmpcaps, codecformats);
273   gst_caps_unref (tmpcaps);
274
275 beach:
276   if (!hadmuxers)
277     gst_plugin_feature_list_free (muxers);
278   if (!hadcodecs)
279     gst_caps_unref (codecformats);
280
281   tmpcaps = gst_caps_normalize (res);
282   gst_caps_unref (res);
283
284   return tmpcaps;
285 }