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