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