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