rtsp: Port to GIO
[platform/upstream/gstreamer.git] / gst-libs / gst / pbutils / gstdiscoverer-types.c
1 /* GStreamer
2  * Copyright (C) 2010 Collabora Multimedia
3  *               2010 Nokia Corporation
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "pbutils.h"
26 #include "pbutils-private.h"
27
28 static GstDiscovererStreamInfo
29     * gst_discoverer_info_copy_int (GstDiscovererStreamInfo * info,
30     GHashTable * stream_map);
31
32 static GstDiscovererContainerInfo
33     * gst_stream_container_info_copy_int (GstDiscovererContainerInfo * ptr,
34     GHashTable * stream_map);
35
36 static GstDiscovererAudioInfo
37     * gst_discoverer_audio_info_copy_int (GstDiscovererAudioInfo * ptr);
38
39 static GstDiscovererVideoInfo
40     * gst_discoverer_video_info_copy_int (GstDiscovererVideoInfo * ptr);
41
42 static GstDiscovererSubtitleInfo
43     * gst_discoverer_subtitle_info_copy_int (GstDiscovererSubtitleInfo * ptr);
44
45 /* Per-stream information */
46
47 G_DEFINE_TYPE (GstDiscovererStreamInfo, gst_discoverer_stream_info,
48     G_TYPE_OBJECT);
49
50 static void
51 gst_discoverer_stream_info_init (GstDiscovererStreamInfo * info)
52 {
53   /* Nothing needs initialization */
54 }
55
56 static void
57 gst_discoverer_stream_info_finalize (GObject * object)
58 {
59   GstDiscovererStreamInfo *info = (GstDiscovererStreamInfo *) object;
60
61   if (info->next)
62     g_object_unref ((GObject *) info->next);
63
64   if (info->caps)
65     gst_caps_unref (info->caps);
66
67   if (info->tags)
68     gst_tag_list_free (info->tags);
69
70   if (info->misc)
71     gst_structure_free (info->misc);
72 }
73
74 static void
75 gst_discoverer_stream_info_class_init (GObjectClass * klass)
76 {
77   klass->finalize = gst_discoverer_stream_info_finalize;
78 }
79
80 static GstDiscovererStreamInfo *
81 gst_discoverer_stream_info_new (void)
82 {
83   return (GstDiscovererStreamInfo *)
84       g_object_new (GST_TYPE_DISCOVERER_STREAM_INFO, NULL);
85 }
86
87 static GstDiscovererStreamInfo *
88 gst_discoverer_info_copy_int (GstDiscovererStreamInfo * info,
89     GHashTable * stream_map)
90 {
91   GstDiscovererStreamInfo *ret;
92   GType ltyp;
93
94   g_return_val_if_fail (info != NULL, NULL);
95
96   ltyp = G_TYPE_FROM_INSTANCE (info);
97
98   if (ltyp == GST_TYPE_DISCOVERER_CONTAINER_INFO) {
99     ret = (GstDiscovererStreamInfo *)
100         gst_stream_container_info_copy_int (
101         (GstDiscovererContainerInfo *) info, stream_map);
102   } else if (ltyp == GST_TYPE_DISCOVERER_AUDIO_INFO) {
103     ret = (GstDiscovererStreamInfo *)
104         gst_discoverer_audio_info_copy_int ((GstDiscovererAudioInfo *) info);
105
106   } else if (ltyp == GST_TYPE_DISCOVERER_VIDEO_INFO) {
107     ret = (GstDiscovererStreamInfo *)
108         gst_discoverer_video_info_copy_int ((GstDiscovererVideoInfo *) info);
109
110   } else if (ltyp == GST_TYPE_DISCOVERER_SUBTITLE_INFO) {
111     ret = (GstDiscovererStreamInfo *)
112         gst_discoverer_subtitle_info_copy_int ((GstDiscovererSubtitleInfo *)
113         info);
114
115   } else
116     ret = gst_discoverer_stream_info_new ();
117
118   if (info->next) {
119     ret->next = gst_discoverer_info_copy_int (info->next, stream_map);
120     ret->next->previous = ret;
121   }
122
123   if (info->caps)
124     ret->caps = gst_caps_copy (info->caps);
125
126   if (info->tags)
127     ret->tags = gst_tag_list_copy (info->tags);
128
129   if (info->misc)
130     ret->misc = gst_structure_copy (info->misc);
131
132   if (stream_map)
133     g_hash_table_insert (stream_map, info, ret);
134
135   return ret;
136 }
137
138 /* Container information */
139 G_DEFINE_TYPE (GstDiscovererContainerInfo, gst_discoverer_container_info,
140     GST_TYPE_DISCOVERER_STREAM_INFO);
141
142 static void
143 gst_discoverer_container_info_init (GstDiscovererContainerInfo * info)
144 {
145   /* Nothing to initialize */
146 }
147
148 static GstDiscovererContainerInfo *
149 gst_discoverer_container_info_new (void)
150 {
151   return (GstDiscovererContainerInfo *)
152       g_object_new (GST_TYPE_DISCOVERER_CONTAINER_INFO, NULL);
153 }
154
155 static void
156 gst_discoverer_container_info_finalize (GObject * object)
157 {
158   GstDiscovererContainerInfo *info = (GstDiscovererContainerInfo *) object;
159   GList *tmp;
160
161   for (tmp = ((GstDiscovererContainerInfo *) info)->streams; tmp;
162       tmp = tmp->next)
163     g_object_unref ((GObject *) tmp->data);
164
165   gst_discoverer_stream_info_list_free (info->streams);
166
167   gst_discoverer_stream_info_finalize ((GObject *) info);
168 }
169
170 static void
171 gst_discoverer_container_info_class_init (GObjectClass * klass)
172 {
173   klass->finalize = gst_discoverer_container_info_finalize;
174 }
175
176 static GstDiscovererContainerInfo *
177 gst_stream_container_info_copy_int (GstDiscovererContainerInfo * ptr,
178     GHashTable * stream_map)
179 {
180   GstDiscovererContainerInfo *ret;
181   GList *tmp;
182
183   g_return_val_if_fail (ptr != NULL, NULL);
184
185   ret = gst_discoverer_container_info_new ();
186
187   for (tmp = ((GstDiscovererContainerInfo *) ptr)->streams; tmp;
188       tmp = tmp->next) {
189     GstDiscovererStreamInfo *subtop = gst_discoverer_info_copy_int (tmp->data,
190         stream_map);
191     ret->streams = g_list_append (ret->streams, subtop);
192     if (stream_map)
193       g_hash_table_insert (stream_map, tmp->data, subtop);
194   }
195
196   return ret;
197 }
198
199 /* Audio information */
200 G_DEFINE_TYPE (GstDiscovererAudioInfo, gst_discoverer_audio_info,
201     GST_TYPE_DISCOVERER_STREAM_INFO);
202
203 static void
204 gst_discoverer_audio_info_finalize (GObject * object)
205 {
206   GstDiscovererAudioInfo *info = (GstDiscovererAudioInfo *) object;
207
208   g_free (info->language);
209
210   G_OBJECT_CLASS (gst_discoverer_audio_info_parent_class)->finalize (object);
211 }
212
213 static void
214 gst_discoverer_audio_info_class_init (GObjectClass * klass)
215 {
216   klass->finalize = gst_discoverer_audio_info_finalize;
217 }
218
219 static void
220 gst_discoverer_audio_info_init (GstDiscovererAudioInfo * info)
221 {
222   info->language = NULL;
223 }
224
225 static GstDiscovererAudioInfo *
226 gst_discoverer_audio_info_new (void)
227 {
228   return (GstDiscovererAudioInfo *)
229       g_object_new (GST_TYPE_DISCOVERER_AUDIO_INFO, NULL);
230 }
231
232 static GstDiscovererAudioInfo *
233 gst_discoverer_audio_info_copy_int (GstDiscovererAudioInfo * ptr)
234 {
235   GstDiscovererAudioInfo *ret;
236
237   ret = gst_discoverer_audio_info_new ();
238
239   ret->channels = ptr->channels;
240   ret->sample_rate = ptr->sample_rate;
241   ret->depth = ptr->depth;
242   ret->bitrate = ptr->bitrate;
243   ret->max_bitrate = ptr->max_bitrate;
244   ret->language = g_strdup (ptr->language);
245
246   return ret;
247 }
248
249 /* Subtitle information */
250 G_DEFINE_TYPE (GstDiscovererSubtitleInfo, gst_discoverer_subtitle_info,
251     GST_TYPE_DISCOVERER_STREAM_INFO);
252
253 static void
254 gst_discoverer_subtitle_info_init (GstDiscovererSubtitleInfo * info)
255 {
256   info->language = NULL;
257 }
258
259 static void
260 gst_discoverer_subtitle_info_finalize (GObject * object)
261 {
262   GstDiscovererSubtitleInfo *info = (GstDiscovererSubtitleInfo *) object;
263
264   g_free (info->language);
265
266   G_OBJECT_CLASS (gst_discoverer_subtitle_info_parent_class)->finalize (object);
267 }
268
269 static void
270 gst_discoverer_subtitle_info_class_init (GObjectClass * klass)
271 {
272   klass->finalize = gst_discoverer_subtitle_info_finalize;
273 }
274
275 static GstDiscovererSubtitleInfo *
276 gst_discoverer_subtitle_info_new (void)
277 {
278   return (GstDiscovererSubtitleInfo *)
279       g_object_new (GST_TYPE_DISCOVERER_SUBTITLE_INFO, NULL);
280 }
281
282 static GstDiscovererSubtitleInfo *
283 gst_discoverer_subtitle_info_copy_int (GstDiscovererSubtitleInfo * ptr)
284 {
285   GstDiscovererSubtitleInfo *ret;
286
287   ret = gst_discoverer_subtitle_info_new ();
288
289   ret->language = g_strdup (ptr->language);
290
291   return ret;
292 }
293
294 /* Video information */
295 G_DEFINE_TYPE (GstDiscovererVideoInfo, gst_discoverer_video_info,
296     GST_TYPE_DISCOVERER_STREAM_INFO);
297
298 static void
299 gst_discoverer_video_info_class_init (GObjectClass * klass)
300 {
301   /* Nothing to initialize */
302 }
303
304 static void
305 gst_discoverer_video_info_init (GstDiscovererVideoInfo * info)
306 {
307   /* Nothing to initialize */
308 }
309
310 static GstDiscovererVideoInfo *
311 gst_discoverer_video_info_new (void)
312 {
313   return (GstDiscovererVideoInfo *)
314       g_object_new (GST_TYPE_DISCOVERER_VIDEO_INFO, NULL);
315 }
316
317 static GstDiscovererVideoInfo *
318 gst_discoverer_video_info_copy_int (GstDiscovererVideoInfo * ptr)
319 {
320   GstDiscovererVideoInfo *ret;
321
322   ret = gst_discoverer_video_info_new ();
323
324   ret->width = ptr->width;
325   ret->height = ptr->height;
326   ret->depth = ptr->depth;
327   ret->framerate_num = ptr->framerate_num;
328   ret->framerate_denom = ptr->framerate_denom;
329   ret->par_num = ptr->par_num;
330   ret->par_denom = ptr->par_denom;
331   ret->interlaced = ptr->interlaced;
332   ret->bitrate = ptr->bitrate;
333   ret->max_bitrate = ptr->max_bitrate;
334   ret->is_image = ptr->is_image;
335
336   return ret;
337 }
338
339 /* Global stream information */
340 G_DEFINE_TYPE (GstDiscovererInfo, gst_discoverer_info, G_TYPE_OBJECT);
341
342 static void
343 gst_discoverer_info_init (GstDiscovererInfo * info)
344 {
345   /* Nothing needs initialization */
346 }
347
348 static void
349 gst_discoverer_info_finalize (GObject * object)
350 {
351   GstDiscovererInfo *info = (GstDiscovererInfo *) object;
352   g_free (info->uri);
353
354   if (info->stream_info)
355     g_object_unref ((GObject *) info->stream_info);
356
357   if (info->misc)
358     gst_structure_free (info->misc);
359
360   g_list_free (info->stream_list);
361
362   if (info->tags)
363     gst_tag_list_free (info->tags);
364 }
365
366 static GstDiscovererInfo *
367 gst_discoverer_info_new (void)
368 {
369   return (GstDiscovererInfo *) g_object_new (GST_TYPE_DISCOVERER_INFO, NULL);
370 }
371
372 /**
373  * gst_discoverer_info_copy:
374  * @ptr: (transfer none): a #GstDiscovererInfo
375  *
376  * Returns: (transfer full): A copy of the #GstDiscovererInfo
377  */
378 GstDiscovererInfo *
379 gst_discoverer_info_copy (GstDiscovererInfo * ptr)
380 {
381   GstDiscovererInfo *ret;
382   GHashTable *stream_map;
383   GList *tmp;
384
385   g_return_val_if_fail (ptr != NULL, NULL);
386
387   stream_map = g_hash_table_new (g_direct_hash, NULL);
388
389   ret = gst_discoverer_info_new ();
390
391   ret->uri = g_strdup (ptr->uri);
392   if (ptr->stream_info) {
393     ret->stream_info = gst_discoverer_info_copy_int (ptr->stream_info,
394         stream_map);
395   }
396   ret->duration = ptr->duration;
397   if (ptr->misc)
398     ret->misc = gst_structure_copy (ptr->misc);
399
400   /* We need to set up the new list of streams to correspond to old one. The
401    * list just contains a set of pointers to streams in the stream_info tree,
402    * so we keep a map of old stream info objects to the corresponding new
403    * ones and use that to figure out correspondence in stream_list. */
404   for (tmp = ptr->stream_list; tmp; tmp = tmp->next) {
405     GstDiscovererStreamInfo *old_stream = (GstDiscovererStreamInfo *) tmp->data;
406     GstDiscovererStreamInfo *new_stream = g_hash_table_lookup (stream_map,
407         old_stream);
408     g_assert (new_stream != NULL);
409     ret->stream_list = g_list_append (ret->stream_list, new_stream);
410   }
411
412   if (ptr->tags)
413     ret->tags = gst_tag_list_copy (ptr->tags);
414
415   g_hash_table_destroy (stream_map);
416   return ret;
417 }
418
419 static void
420 gst_discoverer_info_class_init (GObjectClass * klass)
421 {
422   klass->finalize = gst_discoverer_info_finalize;
423 }
424
425 /**
426  * gst_discoverer_stream_info_list_free:
427  * @infos: (element-type GstPbutils.DiscovererStreamInfo): a #GList of #GstDiscovererStreamInfo
428  *
429  * Decrements the reference count of all contained #GstDiscovererStreamInfo
430  * and fress the #GList.
431  */
432 void
433 gst_discoverer_stream_info_list_free (GList * infos)
434 {
435   GList *tmp;
436
437   for (tmp = infos; tmp; tmp = tmp->next)
438     gst_discoverer_stream_info_unref ((GstDiscovererStreamInfo *) tmp->data);
439   g_list_free (infos);
440 }
441
442 /**
443  * gst_discoverer_info_get_streams:
444  * @info: a #GstDiscovererInfo
445  * @streamtype: a #GType derived from #GstDiscovererStreamInfo
446  *
447  * Finds the #GstDiscovererStreamInfo contained in @info that match the
448  * given @streamtype.
449  *
450  * Returns: (transfer full) (element-type GstPbutils.DiscovererStreamInfo): A #GList of
451  * matching #GstDiscovererStreamInfo. The caller should free it with
452  * gst_discoverer_stream_info_list_free().
453  *
454  * Since: 0.10.31
455  */
456 GList *
457 gst_discoverer_info_get_streams (GstDiscovererInfo * info, GType streamtype)
458 {
459   GList *tmp, *res = NULL;
460
461   for (tmp = info->stream_list; tmp; tmp = tmp->next) {
462     GstDiscovererStreamInfo *stmp = (GstDiscovererStreamInfo *) tmp->data;
463
464     if (G_TYPE_CHECK_INSTANCE_TYPE (stmp, streamtype))
465       res = g_list_append (res, gst_discoverer_stream_info_ref (stmp));
466   }
467
468   return res;
469 }
470
471 /**
472  * gst_discoverer_info_get_audio_streams:
473  * @info: a #GstDiscovererInfo
474  *
475  * Finds all the #GstDiscovererAudioInfo contained in @info
476  *
477  * Returns: (transfer full) (element-type GstPbutils.DiscovererStreamInfo): A #GList of
478  * matching #GstDiscovererStreamInfo. The caller should free it with
479  * gst_discoverer_stream_info_list_free().
480  *
481  * Since: 0.10.31
482  */
483 GList *
484 gst_discoverer_info_get_audio_streams (GstDiscovererInfo * info)
485 {
486   return gst_discoverer_info_get_streams (info, GST_TYPE_DISCOVERER_AUDIO_INFO);
487 }
488
489 /**
490  * gst_discoverer_info_get_video_streams:
491  * @info: a #GstDiscovererInfo
492  *
493  * Finds all the #GstDiscovererVideoInfo contained in @info
494  *
495  * Returns: (transfer full) (element-type GstPbutils.DiscovererStreamInfo): A #GList of
496  * matching #GstDiscovererStreamInfo. The caller should free it with
497  * gst_discoverer_stream_info_list_free().
498  *
499  * Since: 0.10.31
500  */
501 GList *
502 gst_discoverer_info_get_video_streams (GstDiscovererInfo * info)
503 {
504   return gst_discoverer_info_get_streams (info, GST_TYPE_DISCOVERER_VIDEO_INFO);
505 }
506
507 /**
508  * gst_discoverer_info_get_subtitle_streams:
509  * @info: a #GstDiscovererInfo
510  *
511  * Finds all the #GstDiscovererSubtitleInfo contained in @info
512  *
513  * Returns: (transfer full) (element-type GstPbutils.DiscovererStreamInfo): A #GList of
514  * matching #GstDiscovererStreamInfo. The caller should free it with
515  * gst_discoverer_stream_info_list_free().
516  *
517  * Since: 0.10.36
518  */
519 GList *
520 gst_discoverer_info_get_subtitle_streams (GstDiscovererInfo * info)
521 {
522   return gst_discoverer_info_get_streams (info,
523       GST_TYPE_DISCOVERER_SUBTITLE_INFO);
524 }
525
526 /**
527  * gst_discoverer_info_get_container_streams:
528  * @info: a #GstDiscovererInfo
529  *
530  * Finds all the #GstDiscovererContainerInfo contained in @info
531  *
532  * Returns: (transfer full) (element-type GstPbutils.DiscovererStreamInfo): A #GList of
533  * matching #GstDiscovererStreamInfo. The caller should free it with
534  * gst_discoverer_stream_info_list_free().
535  *
536  * Since: 0.10.31
537  */
538 GList *
539 gst_discoverer_info_get_container_streams (GstDiscovererInfo * info)
540 {
541   return gst_discoverer_info_get_streams (info,
542       GST_TYPE_DISCOVERER_CONTAINER_INFO);
543 }
544
545 /**
546  * gst_discoverer_stream_info_get_stream_type_nick:
547  * @info: a #GstDiscovererStreamInfo
548  *
549  * Returns: a human readable name for the stream type of the given @info (ex : "audio",
550  * "container",...).
551  *
552  * Since: 0.10.31
553  */
554 const gchar *
555 gst_discoverer_stream_info_get_stream_type_nick (GstDiscovererStreamInfo * info)
556 {
557   if (GST_IS_DISCOVERER_CONTAINER_INFO (info))
558     return "container";
559   if (GST_IS_DISCOVERER_AUDIO_INFO (info))
560     return "audio";
561   if (GST_IS_DISCOVERER_VIDEO_INFO (info)) {
562     if (gst_discoverer_video_info_is_image ((GstDiscovererVideoInfo *)
563             info))
564       return "video(image)";
565     else
566       return "video";
567   }
568   if (GST_IS_DISCOVERER_SUBTITLE_INFO (info))
569     return "subtitles";
570   return "unknown";
571 }
572
573 /* ACCESSORS */
574
575
576 #define GENERIC_ACCESSOR_CODE(parent, parenttype, parentgtype, fieldname, type, failval) \
577   type parent##_get_##fieldname(const parenttype info) {                        \
578     g_return_val_if_fail(G_TYPE_CHECK_INSTANCE_TYPE((info), parentgtype), failval); \
579     return (info)->fieldname;                           \
580   }
581
582 /**
583  * gst_discoverer_stream_info_get_previous:
584  * @info: a #GstDiscovererStreamInfo
585  *
586  * Returns: (transfer full): the previous #GstDiscovererStreamInfo in a chain.
587  * %NULL for starting points. Unref with #gst_discoverer_stream_info_unref
588  * after usage.
589  *
590  * Since: 0.10.31
591  */
592 GstDiscovererStreamInfo *
593 gst_discoverer_stream_info_get_previous (GstDiscovererStreamInfo * info)
594 {
595   g_return_val_if_fail (GST_IS_DISCOVERER_STREAM_INFO (info), NULL);
596
597   if (info->previous)
598     return gst_discoverer_stream_info_ref (info->previous);
599   return NULL;
600 }
601
602 /**
603  * gst_discoverer_stream_info_get_next:
604  * @info: a #GstDiscovererStreamInfo
605  *
606  * Returns: (transfer full): the next #GstDiscovererStreamInfo in a chain. %NULL
607  * for final streams.
608  * Unref with #gst_discoverer_stream_info_unref after usage.
609  *
610  * Since: 0.10.31
611  */
612 GstDiscovererStreamInfo *
613 gst_discoverer_stream_info_get_next (GstDiscovererStreamInfo * info)
614 {
615   g_return_val_if_fail (GST_IS_DISCOVERER_STREAM_INFO (info), NULL);
616
617   if (info->next)
618     return gst_discoverer_stream_info_ref (info->next);
619   return NULL;
620 }
621
622
623 /**
624  * gst_discoverer_stream_info_get_caps:
625  * @info: a #GstDiscovererStreamInfo
626  *
627  * Returns: (transfer full): the #GstCaps of the stream. Unref with
628  * #gst_caps_unref after usage.
629  *
630  * Since: 0.10.31
631  */
632 GstCaps *
633 gst_discoverer_stream_info_get_caps (GstDiscovererStreamInfo * info)
634 {
635   g_return_val_if_fail (GST_IS_DISCOVERER_STREAM_INFO (info), NULL);
636
637   if (info->caps)
638     return gst_caps_ref (info->caps);
639   return NULL;
640 }
641
642 /**
643  * gst_discoverer_stream_info_get_tags:
644  * @info: a #GstDiscovererStreamInfo
645  *
646  * Returns: (transfer none): the tags contained in this stream. If you wish to
647  * use the tags after the life-time of @info you will need to copy them.
648  *
649  * Since: 0.10.31
650  */
651
652 const GstTagList *
653 gst_discoverer_stream_info_get_tags (GstDiscovererStreamInfo * info)
654 {
655   g_return_val_if_fail (GST_IS_DISCOVERER_STREAM_INFO (info), NULL);
656
657   return info->tags;
658 }
659
660 /**
661  * gst_discoverer_stream_info_get_misc:
662  * @info: a #GstDiscovererStreamInfo
663  *
664  * Returns: (transfer none): additional information regarding the stream (for
665  * example codec version, profile, etc..). If you wish to use the #GstStructure
666  * after the life-time of @info you will need to copy it.
667  *
668  * Since: 0.10.31
669  */
670 const GstStructure *
671 gst_discoverer_stream_info_get_misc (GstDiscovererStreamInfo * info)
672 {
673   g_return_val_if_fail (GST_IS_DISCOVERER_STREAM_INFO (info), NULL);
674
675   return info->misc;
676 }
677
678 /* GstDiscovererContainerInfo */
679
680 /**
681  * gst_discoverer_container_info_get_streams:
682  * @info: a #GstDiscovererStreamInfo
683  *
684  * Returns: (transfer full) (element-type GstPbutils.DiscovererStreamInfo): the list of
685  * #GstDiscovererStreamInfo this container stream offers.
686  * Free with gst_discoverer_stream_info_list_free() after usage.
687  *
688  * Since: 0.10.31
689  */
690
691 GList *
692 gst_discoverer_container_info_get_streams (GstDiscovererContainerInfo * info)
693 {
694   GList *res = NULL, *tmp;
695
696   g_return_val_if_fail (GST_IS_DISCOVERER_CONTAINER_INFO (info), NULL);
697
698   for (tmp = info->streams; tmp; tmp = tmp->next)
699     res =
700         g_list_append (res,
701         gst_discoverer_stream_info_ref ((GstDiscovererStreamInfo *) tmp->data));
702
703   return res;
704 }
705
706 /* GstDiscovererAudioInfo */
707
708 #define AUDIO_INFO_ACCESSOR_CODE(fieldname, type, failval)              \
709   GENERIC_ACCESSOR_CODE(gst_discoverer_audio_info, GstDiscovererAudioInfo*, \
710                         GST_TYPE_DISCOVERER_AUDIO_INFO,         \
711                         fieldname, type, failval)
712
713 /**
714  * gst_discoverer_audio_info_get_channels:
715  * @info: a #GstDiscovererAudioInfo
716  *
717  * Returns: the number of channels in the stream.
718  *
719  * Since: 0.10.31
720  */
721
722 AUDIO_INFO_ACCESSOR_CODE (channels, guint, 0);
723
724 /**
725  * gst_discoverer_audio_info_get_sample_rate:
726  * @info: a #GstDiscovererAudioInfo
727  *
728  * Returns: the sample rate of the stream in Hertz.
729  *
730  * Since: 0.10.31
731  */
732
733 AUDIO_INFO_ACCESSOR_CODE (sample_rate, guint, 0);
734
735 /**
736  * gst_discoverer_audio_info_get_depth:
737  * @info: a #GstDiscovererAudioInfo
738  *
739  * Returns: the number of bits used per sample in each channel.
740  *
741  * Since: 0.10.31
742  */
743
744 AUDIO_INFO_ACCESSOR_CODE (depth, guint, 0);
745
746 /**
747  * gst_discoverer_audio_info_get_bitrate:
748  * @info: a #GstDiscovererAudioInfo
749  *
750  * Returns: the average or nominal bitrate of the stream in bits/second.
751  *
752  * Since: 0.10.31
753  */
754
755 AUDIO_INFO_ACCESSOR_CODE (bitrate, guint, 0);
756
757 /**
758  * gst_discoverer_audio_info_get_max_bitrate:
759  * @info: a #GstDiscovererAudioInfo
760  *
761  * Returns: the maximum bitrate of the stream in bits/second.
762  *
763  * Since: 0.10.31
764  */
765
766 AUDIO_INFO_ACCESSOR_CODE (max_bitrate, guint, 0);
767
768 /**
769  * gst_discoverer_audio_info_get_language:
770  * @info: a #GstDiscovererAudioInfo
771  *
772  * Returns: the language of the stream, or NULL if unknown.
773  *
774  * Since: 0.10.36
775  */
776
777 AUDIO_INFO_ACCESSOR_CODE (language, const gchar *, NULL);
778
779 /* GstDiscovererVideoInfo */
780
781 #define VIDEO_INFO_ACCESSOR_CODE(fieldname, type, failval)              \
782   GENERIC_ACCESSOR_CODE(gst_discoverer_video_info, GstDiscovererVideoInfo*, \
783                         GST_TYPE_DISCOVERER_VIDEO_INFO,                 \
784                         fieldname, type, failval)
785
786 /**
787  * gst_discoverer_video_info_get_width:
788  * @info: a #GstDiscovererVideoInfo
789  *
790  * Returns: the width of the video stream in pixels.
791  *
792  * Since: 0.10.31
793  */
794
795 VIDEO_INFO_ACCESSOR_CODE (width, guint, 0);
796
797 /**
798  * gst_discoverer_video_info_get_height:
799  * @info: a #GstDiscovererVideoInfo
800  *
801  * Returns: the height of the video stream in pixels.
802  *
803  * Since: 0.10.31
804  */
805
806 VIDEO_INFO_ACCESSOR_CODE (height, guint, 0);
807
808 /**
809  * gst_discoverer_video_info_get_depth:
810  * @info: a #GstDiscovererVideoInfo
811  *
812  * Returns: the depth in bits of the video stream.
813  *
814  * Since: 0.10.31
815  */
816
817 VIDEO_INFO_ACCESSOR_CODE (depth, guint, 0);
818
819 /**
820  * gst_discoverer_video_info_get_framerate_num:
821  * @info: a #GstDiscovererVideoInfo
822  *
823  * Returns: the framerate of the video stream (numerator).
824  *
825  * Since: 0.10.31
826  */
827
828 VIDEO_INFO_ACCESSOR_CODE (framerate_num, guint, 0);
829
830 /**
831  * gst_discoverer_video_info_get_framerate_denom:
832  * @info: a #GstDiscovererVideoInfo
833  *
834  * Returns: the framerate of the video stream (denominator).
835  *
836  * Since: 0.10.31
837  */
838
839 VIDEO_INFO_ACCESSOR_CODE (framerate_denom, guint, 0);
840
841 /**
842  * gst_discoverer_video_info_get_par_num:
843  * @info: a #GstDiscovererVideoInfo
844  *
845  * Returns: the Pixel Aspect Ratio (PAR) of the video stream (numerator).
846  *
847  * Since: 0.10.31
848  */
849
850 VIDEO_INFO_ACCESSOR_CODE (par_num, guint, 0);
851
852 /**
853  * gst_discoverer_video_info_get_par_denom:
854  * @info: a #GstDiscovererVideoInfo
855  *
856  * Returns: the Pixel Aspect Ratio (PAR) of the video stream (denominator).
857  *
858  * Since: 0.10.31
859  */
860
861 VIDEO_INFO_ACCESSOR_CODE (par_denom, guint, 0);
862
863 /**
864  * gst_discoverer_video_info_is_interlaced:
865  * @info: a #GstDiscovererVideoInfo
866  *
867  * Returns: %TRUE if the stream is interlaced, else %FALSE.
868  *
869  * Since: 0.10.31
870  */
871 gboolean
872 gst_discoverer_video_info_is_interlaced (const GstDiscovererVideoInfo * info)
873 {
874   g_return_val_if_fail (GST_IS_DISCOVERER_VIDEO_INFO (info), FALSE);
875
876   return info->interlaced;
877 }
878
879 /**
880  * gst_discoverer_video_info_get_bitrate:
881  * @info: a #GstDiscovererVideoInfo
882  *
883  * Returns: the average or nominal bitrate of the video stream in bits/second.
884  *
885  * Since: 0.10.31
886  */
887
888 VIDEO_INFO_ACCESSOR_CODE (bitrate, guint, 0);
889
890 /**
891  * gst_discoverer_video_info_get_max_bitrate:
892  * @info: a #GstDiscovererVideoInfo
893  *
894  * Returns: the maximum bitrate of the video stream in bits/second.
895  *
896  * Since: 0.10.31
897  */
898
899 VIDEO_INFO_ACCESSOR_CODE (max_bitrate, guint, 0);
900
901 /**
902  * gst_discoverer_video_info_is_image:
903  * @info: a #GstDiscovererVideoInfo
904  *
905  * Returns: #TRUE if the video stream corresponds to an image (i.e. only contains
906  * one frame).
907  *
908  * Since: 0.10.31
909  */
910 gboolean
911 gst_discoverer_video_info_is_image (const GstDiscovererVideoInfo * info)
912 {
913   g_return_val_if_fail (GST_IS_DISCOVERER_VIDEO_INFO (info), FALSE);
914
915   return info->is_image;
916 }
917
918 /* GstDiscovererSubtitleInfo */
919
920 #define SUBTITLE_INFO_ACCESSOR_CODE(fieldname, type, failval)                     \
921   GENERIC_ACCESSOR_CODE(gst_discoverer_subtitle_info, GstDiscovererSubtitleInfo*, \
922                         GST_TYPE_DISCOVERER_SUBTITLE_INFO,                        \
923                         fieldname, type, failval)
924
925 /**
926  * gst_discoverer_subtitle_info_get_language:
927  * @info: a #GstDiscovererSubtitleInfo
928  *
929  * Returns: the language of the stream, or NULL if unknown.
930  *
931  * Since: 0.10.36
932  */
933
934 SUBTITLE_INFO_ACCESSOR_CODE (language, const gchar *, NULL);
935
936 /* GstDiscovererInfo */
937
938 #define DISCOVERER_INFO_ACCESSOR_CODE(fieldname, type, failval)         \
939   GENERIC_ACCESSOR_CODE(gst_discoverer_info, GstDiscovererInfo*,        \
940                         GST_TYPE_DISCOVERER_INFO,                       \
941                         fieldname, type, failval)
942
943 /**
944  * gst_discoverer_info_get_uri:
945  * @info: a #GstDiscovererInfo
946  *
947  * Returns: (transfer none): the URI to which this information corresponds to.
948  * Copy it if you wish to use it after the life-time of @info.
949  *
950  * Since: 0.10.31
951  */
952
953 DISCOVERER_INFO_ACCESSOR_CODE (uri, const gchar *, NULL);
954
955 /**
956  * gst_discoverer_info_get_result:
957  * @info: a #GstDiscovererInfo
958  *
959  * Returns: the result of the discovery as a #GstDiscovererResult.
960  *
961  * Since: 0.10.31
962  */
963
964 DISCOVERER_INFO_ACCESSOR_CODE (result, GstDiscovererResult, GST_DISCOVERER_OK);
965
966 /**
967  * gst_discoverer_info_get_stream_info:
968  * @info: a #GstDiscovererInfo
969  *
970  * Returns: (transfer full): the structure (or topology) of the URI as a
971  * #GstDiscovererStreamInfo.
972  * This structure can be traversed to see the original hierarchy. Unref with
973  * gst_discoverer_stream_info_unref() after usage.
974  *
975  * Since: 0.10.31
976  */
977
978 GstDiscovererStreamInfo *
979 gst_discoverer_info_get_stream_info (GstDiscovererInfo * info)
980 {
981   g_return_val_if_fail (GST_IS_DISCOVERER_INFO (info), NULL);
982
983   if (info->stream_info)
984     return gst_discoverer_stream_info_ref (info->stream_info);
985   return NULL;
986 }
987
988 /**
989  * gst_discoverer_info_get_stream_list:
990  * @info: a #GstDiscovererInfo
991  *
992  * Returns: (transfer full) (element-type GstPbutils.DiscovererStreamInfo): the list of
993  * all streams contained in the #info. Free after usage
994  * with gst_discoverer_stream_info_list_free().
995  *
996  * Since: 0.10.31
997  */
998 GList *
999 gst_discoverer_info_get_stream_list (GstDiscovererInfo * info)
1000 {
1001   GList *res = NULL, *tmp;
1002
1003   g_return_val_if_fail (GST_IS_DISCOVERER_INFO (info), NULL);
1004
1005   for (tmp = info->stream_list; tmp; tmp = tmp->next)
1006     res =
1007         g_list_append (res,
1008         gst_discoverer_stream_info_ref ((GstDiscovererStreamInfo *) tmp->data));
1009
1010   return res;
1011 }
1012
1013 /**
1014  * gst_discoverer_info_get_duration:
1015  * @info: a #GstDiscovererInfo
1016  *
1017  * Returns: the duration of the URI in #GstClockTime (nanoseconds).
1018  *
1019  * Since: 0.10.31
1020  */
1021
1022 DISCOVERER_INFO_ACCESSOR_CODE (duration, GstClockTime, GST_CLOCK_TIME_NONE);
1023
1024 /**
1025  * gst_discoverer_info_get_seekable:
1026  * @info: a #GstDiscovererInfo
1027  *
1028  * Returns: the whether the URI is seekable.
1029  *
1030  * Since: 0.10.32
1031  */
1032
1033 DISCOVERER_INFO_ACCESSOR_CODE (seekable, gboolean, FALSE);
1034
1035 /**
1036  * gst_discoverer_info_get_misc:
1037  * @info: a #GstDiscovererInfo
1038  *
1039  * Returns: (transfer none): Miscellaneous information stored as a #GstStructure
1040  * (for example: information about missing plugins). If you wish to use the
1041  * #GstStructure after the life-time of @info, you will need to copy it.
1042  *
1043  * Since: 0.10.31
1044  */
1045
1046 DISCOVERER_INFO_ACCESSOR_CODE (misc, const GstStructure *, NULL);
1047
1048 /**
1049  * gst_discoverer_info_get_tags:
1050  * @info: a #GstDiscovererInfo
1051  *
1052  * Returns: (transfer none): all tags contained in the URI. If you wish to use
1053  * the tags after the life-time of @info, you will need to copy them.
1054  *
1055  * Since: 0.10.31
1056  */
1057
1058 DISCOVERER_INFO_ACCESSOR_CODE (tags, const GstTagList *, NULL);
1059
1060 /**
1061  * gst_discoverer_info_ref:
1062  * @info: a #GstDiscovererInfo
1063  *
1064  * Increments the reference count of @info.
1065  *
1066  * Returns: the same #GstDiscovererInfo object
1067  *
1068  * Since: 0.10.31
1069  */
1070
1071 /**
1072  * gst_discoverer_info_unref:
1073  * @info: a #GstDiscovererInfo
1074  *
1075  * Decrements the reference count of @info.
1076  *
1077  * Since: 0.10.31
1078  */
1079
1080 /**
1081  * gst_discoverer_stream_info_ref:
1082  * @info: a #GstDiscovererStreamInfo
1083  *
1084  * Increments the reference count of @info.
1085  *
1086  * Returns: the same #GstDiscovererStreamInfo object
1087  *
1088  * Since: 0.10.31
1089  */
1090
1091 /**
1092  * gst_discoverer_stream_info_unref:
1093  * @info: a #GstDiscovererStreamInfo
1094  *
1095  * Decrements the reference count of @info.
1096  *
1097  * Since: 0.10.31
1098  */