bufferlist: fix a comment
[platform/upstream/gstreamer.git] / gst / gstparse.c
1 /* GStreamer
2  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
3  *                    2000 Wim Taymans <wtay@chello.be>
4  *                    2002 Andy Wingo <wingo@pobox.com>
5  *                    2008 Tim-Philipp Müller <tim centricular net>
6  *
7  * gstparse.c: get a pipeline from a text pipeline description
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Library General Public
11  * License as published by the Free Software Foundation; either
12  * version 2 of the License, or (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Library General Public License for more details.
18  *
19  * You should have received a copy of the GNU Library General Public
20  * License along with this library; if not, write to the
21  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22  * Boston, MA 02111-1307, USA.
23  */
24
25 /**
26  * SECTION:gstparse
27  * @short_description: Get a pipeline from a text pipeline description
28  *
29  * These function allow to create a pipeline based on the syntax used in the
30  * gst-launch utility.
31  */
32
33
34 #include "gst_private.h"
35 #include <string.h>
36
37 #include "gstparse.h"
38 #include "gsterror.h"
39 #include "gstinfo.h"
40
41 extern GstElement *_gst_parse_launch (const gchar *, GError **,
42     GstParseContext *, GstParseFlags);
43
44 /**
45  * gst_parse_error_quark:
46  *
47  * Get the error quark used by the parsing subsystem.
48  *
49  * Returns: the quark of the parse errors.
50  */
51 GQuark
52 gst_parse_error_quark (void)
53 {
54   static GQuark quark = 0;
55
56   if (!quark)
57     quark = g_quark_from_static_string ("gst_parse_error");
58   return quark;
59 }
60
61
62 /**
63  * gst_parse_context_new:
64  *
65  * Allocates a parse context for use with gst_parse_launch_full() or
66  * gst_parse_launchv_full().
67  *
68  * Returns: a newly-allocated parse context. Free with gst_parse_context_free()
69  *     when no longer needed.
70  *
71  * Since: 0.10.20
72  */
73 GstParseContext *
74 gst_parse_context_new (void)
75 {
76 #ifndef GST_DISABLE_PARSE
77   GstParseContext *ctx;
78
79   ctx = g_slice_new (GstParseContext);
80   ctx->missing_elements = NULL;
81
82   return ctx;
83 #else
84   return NULL;
85 #endif
86 }
87
88 /**
89  * gst_parse_context_free:
90  * @context: a #GstParseContext
91  *
92  * Frees a parse context previously allocated with gst_parse_context_new().
93  *
94  * Since: 0.10.20
95  */
96 void
97 gst_parse_context_free (GstParseContext * context)
98 {
99 #ifndef GST_DISABLE_PARSE
100   if (context) {
101     g_list_foreach (context->missing_elements, (GFunc) g_free, NULL);
102     g_list_free (context->missing_elements);
103     g_slice_free (GstParseContext, context);
104   }
105 #endif
106 }
107
108 /**
109  * gst_parse_context_get_missing_elements:
110  * @context: a #GstParseContext
111  *
112  * Retrieve missing elements from a previous run of gst_parse_launch_full()
113  * or gst_parse_launchv_full(). Will only return results if an error code
114  * of %GST_PARSE_ERROR_NO_SUCH_ELEMENT was returned.
115  *
116  * Returns: a NULL-terminated array of element factory name strings of
117  *     missing elements. Free with g_strfreev() when no longer needed.
118  *
119  * Since: 0.10.20
120  */
121 gchar **
122 gst_parse_context_get_missing_elements (GstParseContext * context)
123 {
124 #ifndef GST_DISABLE_PARSE
125   gchar **arr;
126   GList *l;
127   guint len, i;
128
129   g_return_val_if_fail (context != NULL, NULL);
130
131   len = g_list_length (context->missing_elements);
132
133   if (G_UNLIKELY (len == 0))
134     return NULL;
135
136   arr = g_new (gchar *, len + 1);
137
138   for (i = 0, l = context->missing_elements; l != NULL; l = l->next, ++i)
139     arr[i] = g_strdup (l->data);
140
141   arr[i] = NULL;
142
143   return arr;
144 #else
145   return NULL;
146 #endif
147 }
148
149 #ifndef GST_DISABLE_PARSE
150 static gchar *
151 _gst_parse_escape (const gchar * str)
152 {
153   GString *gstr = NULL;
154
155   g_return_val_if_fail (str != NULL, NULL);
156
157   gstr = g_string_sized_new (strlen (str));
158
159   while (*str) {
160     if (*str == ' ')
161       g_string_append_c (gstr, '\\');
162     g_string_append_c (gstr, *str);
163     str++;
164   }
165
166   return g_string_free (gstr, FALSE);
167 }
168 #endif /* !GST_DISABLE_PARSE */
169
170 /**
171  * gst_parse_launchv:
172  * @argv: null-terminated array of arguments
173  * @error: pointer to a #GError
174  *
175  * Create a new element based on command line syntax.
176  * @error will contain an error message if an erroneuos pipeline is specified.
177  * An error does not mean that the pipeline could not be constructed.
178  *
179  * Returns: a new element on success and %NULL on failure.
180  */
181 GstElement *
182 gst_parse_launchv (const gchar ** argv, GError ** error)
183 {
184   return gst_parse_launchv_full (argv, NULL, 0, error);
185 }
186
187 /**
188  * gst_parse_launchv_full:
189  * @argv: null-terminated array of arguments
190  * @context: a parse context allocated with gst_parse_context_new(), or %NULL
191  * @flags: parsing options, or #GST_PARSE_FLAG_NONE
192  * @error: pointer to a #GError (which must be initialised to %NULL)
193  *
194  * Create a new element based on command line syntax.
195  * @error will contain an error message if an erroneous pipeline is specified.
196  * An error does not mean that the pipeline could not be constructed.
197  *
198  * Returns: a new element on success; on failure, either %NULL or a
199  * partially-constructed bin or element will be returned and @error will be set
200  * (unless you passed #GST_PARSE_FLAG_FATAL_ERRORS in @flags, then %NULL will
201  * always be returned on failure)
202  *
203  * Since: 0.10.20
204  */
205 GstElement *
206 gst_parse_launchv_full (const gchar ** argv, GstParseContext * context,
207     GstParseFlags flags, GError ** error)
208 {
209 #ifndef GST_DISABLE_PARSE
210   GstElement *element;
211   GString *str;
212   const gchar **argvp, *arg;
213   gchar *tmp;
214
215   g_return_val_if_fail (argv != NULL, NULL);
216   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
217
218   /* let's give it a nice size. */
219   str = g_string_sized_new (1024);
220
221   argvp = argv;
222   while (*argvp) {
223     arg = *argvp;
224     tmp = _gst_parse_escape (arg);
225     g_string_append (str, tmp);
226     g_free (tmp);
227     g_string_append_c (str, ' ');
228     argvp++;
229   }
230
231   element = gst_parse_launch_full (str->str, context, flags, error);
232
233   g_string_free (str, TRUE);
234
235   return element;
236 #else
237   /* gst_parse_launch_full() will set a GST_CORE_ERROR_DISABLED error for us */
238   return gst_parse_launch_full ("", NULL, 0, error);
239 #endif
240 }
241
242 /**
243  * gst_parse_launch:
244  * @pipeline_description: the command line describing the pipeline
245  * @error: the error message in case of an erroneous pipeline.
246  *
247  * Create a new pipeline based on command line syntax.
248  * Please note that you might get a return value that is not %NULL even though
249  * the @error is set. In this case there was a recoverable parsing error and you
250  * can try to play the pipeline.
251  *
252  * Returns: a new element on success, %NULL on failure. If more than one toplevel
253  * element is specified by the @pipeline_description, all elements are put into
254  * a #GstPipeline, which than is returned.
255  */
256 GstElement *
257 gst_parse_launch (const gchar * pipeline_description, GError ** error)
258 {
259   return gst_parse_launch_full (pipeline_description, NULL, 0, error);
260 }
261
262 /**
263  * gst_parse_launch_full:
264  * @pipeline_description: the command line describing the pipeline
265  * @context: a parse context allocated with gst_parse_context_new(), or %NULL
266  * @flags: parsing options, or #GST_PARSE_FLAG_NONE
267  * @error: the error message in case of an erroneous pipeline.
268  *
269  * Create a new pipeline based on command line syntax.
270  * Please note that you might get a return value that is not %NULL even though
271  * the @error is set. In this case there was a recoverable parsing error and you
272  * can try to play the pipeline.
273  *
274  * Returns: a new element on success, %NULL on failure. If more than one toplevel
275  * element is specified by the @pipeline_description, all elements are put into
276  * a #GstPipeline, which then is returned.
277  *
278  * Since: 0.10.20
279  */
280 GstElement *
281 gst_parse_launch_full (const gchar * pipeline_description,
282     GstParseContext * context, GstParseFlags flags, GError ** error)
283 {
284 #ifndef GST_DISABLE_PARSE
285   GstElement *element;
286
287   g_return_val_if_fail (pipeline_description != NULL, NULL);
288   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
289
290   GST_CAT_INFO (GST_CAT_PIPELINE, "parsing pipeline description '%s'",
291       pipeline_description);
292
293   element = _gst_parse_launch (pipeline_description, error, context, flags);
294
295   /* don't return partially constructed pipeline if FATAL_ERRORS was given */
296   if (G_UNLIKELY (error != NULL && *error != NULL && element != NULL)) {
297     if ((flags & GST_PARSE_FLAG_FATAL_ERRORS)) {
298       gst_object_unref (element);
299       element = NULL;
300     }
301   }
302
303   return element;
304 #else
305   gchar *msg;
306
307   GST_WARNING ("Disabled API called");
308
309   msg = gst_error_get_message (GST_CORE_ERROR, GST_CORE_ERROR_DISABLED);
310   g_set_error (error, GST_CORE_ERROR, GST_CORE_ERROR_DISABLED, "%s", msg);
311   g_free (msg);
312
313   return NULL;
314 #endif
315 }