1 /*
2  * DASH MPD parsing library
3  *
4  * gstmpdparser.h
5  *
6  * Copyright (C) 2012 STMicroelectronics
7  *
8  * Authors:
9  *   Gianluca Gennari <gennarone@gmail.com>
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Library General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  * Library General Public License for more details.
20  *
21  * You should have received a copy of the GNU Library General Public
22  * License along with this library (COPYING); if not, write to the
23  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24  * Boston, MA 02111-1307, USA.
25  */
26 
27 #ifndef __GST_MPDPARSER_H__
28 #define __GST_MPDPARSER_H__
29 
30 #include <gst/gst.h>
31 #include <gst/uridownloader/gsturidownloader.h>
32 #include <gst/base/gstadapter.h>
33 
34 G_BEGIN_DECLS
35 
36 typedef struct _GstMpdClient              GstMpdClient;
37 typedef struct _GstActiveStream           GstActiveStream;
38 typedef struct _GstStreamPeriod           GstStreamPeriod;
39 typedef struct _GstMediaFragmentInfo      GstMediaFragmentInfo;
40 typedef struct _GstMediaSegment           GstMediaSegment;
41 typedef struct _GstMPDNode                GstMPDNode;
42 typedef struct _GstPeriodNode             GstPeriodNode;
43 typedef struct _GstRepresentationBaseType GstRepresentationBaseType;
44 typedef struct _GstDescriptorType         GstDescriptorType;
45 typedef struct _GstContentComponentNode   GstContentComponentNode;
46 typedef struct _GstAdaptationSetNode      GstAdaptationSetNode;
47 typedef struct _GstRepresentationNode     GstRepresentationNode;
48 typedef struct _GstSubRepresentationNode  GstSubRepresentationNode;
49 typedef struct _GstSegmentListNode        GstSegmentListNode;
50 typedef struct _GstSegmentTemplateNode    GstSegmentTemplateNode;
51 typedef struct _GstSegmentURLNode         GstSegmentURLNode;
52 typedef struct _GstBaseURL                GstBaseURL;
53 typedef struct _GstRange                  GstRange;
54 typedef struct _GstRatio                  GstRatio;
55 typedef struct _GstFrameRate              GstFrameRate;
56 typedef struct _GstConditionalUintType    GstConditionalUintType;
57 typedef struct _GstSubsetNode             GstSubsetNode;
58 typedef struct _GstProgramInformationNode GstProgramInformationNode;
59 typedef struct _GstMetricsRangeNode       GstMetricsRangeNode;
60 typedef struct _GstMetricsNode            GstMetricsNode;
61 typedef struct _GstUTCTimingNode          GstUTCTimingNode;
62 typedef struct _GstSNode                  GstSNode;
63 typedef struct _GstSegmentTimelineNode    GstSegmentTimelineNode;
64 typedef struct _GstSegmentBaseType        GstSegmentBaseType;
65 typedef struct _GstURLType                GstURLType;
66 typedef struct _GstMultSegmentBaseType    GstMultSegmentBaseType;
67 
68 #define GST_MPD_CLIENT_LOCK(c) g_mutex_lock (&c->lock);
69 #define GST_MPD_CLIENT_UNLOCK(c) g_mutex_unlock (&c->lock);
70 
71 #define GST_MPD_DURATION_NONE ((guint64)-1)
72 
73 typedef enum
74 {
75   GST_STREAM_UNKNOWN,
76   GST_STREAM_VIDEO,           /* video stream (the main one) */
77   GST_STREAM_AUDIO,           /* audio stream (optional) */
78   GST_STREAM_APPLICATION      /* application stream (optional): for timed text/subtitles */
79 } GstStreamMimeType;
80 
81 typedef enum
82 {
83   GST_MPD_FILE_TYPE_STATIC,
84   GST_MPD_FILE_TYPE_DYNAMIC
85 } GstMPDFileType;
86 
87 typedef enum
88 {
89   GST_SAP_TYPE_0 = 0,
90   GST_SAP_TYPE_1,
91   GST_SAP_TYPE_2,
92   GST_SAP_TYPE_3,
93   GST_SAP_TYPE_4,
94   GST_SAP_TYPE_5,
95   GST_SAP_TYPE_6
96 } GstSAPType;
97 
98 typedef enum
99 {
100   GST_XLINK_ACTUATE_ON_REQUEST,
101   GST_XLINK_ACTUATE_ON_LOAD
102 } GstXLinkActuate;
103 
104 typedef enum
105 {
106   GST_MPD_UTCTIMING_TYPE_UNKNOWN     = 0x00,
107   GST_MPD_UTCTIMING_TYPE_NTP         = 0x01,
108   GST_MPD_UTCTIMING_TYPE_SNTP        = 0x02,
109   GST_MPD_UTCTIMING_TYPE_HTTP_HEAD   = 0x04,
110   GST_MPD_UTCTIMING_TYPE_HTTP_XSDATE = 0x08,
111   GST_MPD_UTCTIMING_TYPE_HTTP_ISO    = 0x10,
112   GST_MPD_UTCTIMING_TYPE_HTTP_NTP    = 0x20,
113   GST_MPD_UTCTIMING_TYPE_DIRECT      = 0x40
114 } GstMPDUTCTimingType;
115 
116 struct _GstBaseURL
117 {
118   gchar *baseURL;
119   gchar *serviceLocation;
120   gchar *byteRange;
121 };
122 
123 struct _GstRange
124 {
125   guint64 first_byte_pos;
126   guint64 last_byte_pos;
127 };
128 
129 struct _GstRatio
130 {
131   guint num;
132   guint den;
133 };
134 
135 struct _GstFrameRate
136 {
137   guint num;
138   guint den;
139 };
140 
141 struct _GstConditionalUintType
142 {
143   gboolean flag;
144   guint value;
145 };
146 
147 struct _GstSNode
148 {
149   guint64 t;
150   guint64 d;
151   gint r;
152 };
153 
154 struct _GstSegmentTimelineNode
155 {
156   /* list of S nodes */
157   GQueue S;
158 };
159 
160 struct _GstURLType
161 {
162   gchar *sourceURL;
163   GstRange *range;
164 };
165 
166 struct _GstSegmentBaseType
167 {
168   guint timescale;
169   guint64 presentationTimeOffset;
170   GstRange *indexRange;
171   gboolean indexRangeExact;
172   /* Initialization node */
173   GstURLType *Initialization;
174   /* RepresentationIndex node */
175   GstURLType *RepresentationIndex;
176 };
177 
178 struct _GstMultSegmentBaseType
179 {
180   guint duration;                  /* in seconds */
181   guint startNumber;
182   /* SegmentBaseType extension */
183   GstSegmentBaseType *SegBaseType;
184   /* SegmentTimeline node */
185   GstSegmentTimelineNode *SegmentTimeline;
186   /* BitstreamSwitching node */
187   GstURLType *BitstreamSwitching;
188 };
189 
190 struct _GstSegmentListNode
191 {
192   /* extension */
193   GstMultSegmentBaseType *MultSegBaseType;
194   /* list of SegmentURL nodes */
195   GList *SegmentURL;
196 
197   gchar *xlink_href;
198   GstXLinkActuate actuate;
199 };
200 
201 struct _GstSegmentTemplateNode
202 {
203   /* extension */
204   GstMultSegmentBaseType *MultSegBaseType;
205   gchar *media;
206   gchar *index;
207   gchar *initialization;
208   gchar *bitstreamSwitching;
209 };
210 
211 struct _GstSegmentURLNode
212 {
213   gchar *media;
214   GstRange *mediaRange;
215   gchar *index;
216   GstRange *indexRange;
217 };
218 
219 struct _GstRepresentationBaseType
220 {
221   gchar *profiles;
222   guint width;
223   guint height;
224   GstRatio *sar;
225   GstFrameRate *minFrameRate;
226   GstFrameRate *maxFrameRate;
227   GstFrameRate *frameRate;
228   gchar *audioSamplingRate;
229   gchar *mimeType;
230   gchar *segmentProfiles;
231   gchar *codecs;
232   gdouble maximumSAPPeriod;
233   GstSAPType startWithSAP;
234   gdouble maxPlayoutRate;
235   gboolean codingDependency;
236   gchar *scanType;
237   /* list of FramePacking DescriptorType nodes */
238   GList *FramePacking;
239   /* list of AudioChannelConfiguration DescriptorType nodes */
240   GList *AudioChannelConfiguration;
241   /* list of ContentProtection DescriptorType nodes */
242   GList *ContentProtection;
243 };
244 
245 struct _GstSubRepresentationNode
246 {
247   /* RepresentationBase extension */
248   GstRepresentationBaseType *RepresentationBase;
249   guint level;
250   guint *dependencyLevel;            /* UIntVectorType */
251   guint size;                        /* size of "dependencyLevel" array */
252   guint bandwidth;
253   gchar **contentComponent;          /* StringVectorType */
254 };
255 
256 struct _GstRepresentationNode
257 {
258   gchar *id;
259   guint bandwidth;
260   guint qualityRanking;
261   gchar **dependencyId;              /* StringVectorType */
262   gchar **mediaStreamStructureId;    /* StringVectorType */
263   /* RepresentationBase extension */
264   GstRepresentationBaseType *RepresentationBase;
265   /* list of BaseURL nodes */
266   GList *BaseURLs;
267   /* list of SubRepresentation nodes */
268   GList *SubRepresentations;
269   /* SegmentBase node */
270   GstSegmentBaseType *SegmentBase;
271   /* SegmentTemplate node */
272   GstSegmentTemplateNode *SegmentTemplate;
273   /* SegmentList node */
274   GstSegmentListNode *SegmentList;
275 };
276 
277 struct _GstDescriptorType
278 {
279   gchar *schemeIdUri;
280   gchar *value;
281 };
282 
283 struct _GstContentComponentNode
284 {
285   guint id;
286   gchar *lang;                      /* LangVectorType RFC 5646 */
287   gchar *contentType;
288   GstRatio *par;
289   /* list of Accessibility DescriptorType nodes */
290   GList *Accessibility;
291   /* list of Role DescriptorType nodes */
292   GList *Role;
293   /* list of Rating DescriptorType nodes */
294   GList *Rating;
295   /* list of Viewpoint DescriptorType nodes */
296   GList *Viewpoint;
297 };
298 
299 struct _GstAdaptationSetNode
300 {
301   guint id;
302   guint group;
303   gchar *lang;                      /* LangVectorType RFC 5646 */
304   gchar *contentType;
305   GstRatio *par;
306   guint minBandwidth;
307   guint maxBandwidth;
308   guint minWidth;
309   guint maxWidth;
310   guint minHeight;
311   guint maxHeight;
312   GstConditionalUintType *segmentAlignment;
313   GstConditionalUintType *subsegmentAlignment;
314   GstSAPType subsegmentStartsWithSAP;
315   gboolean bitstreamSwitching;
316   /* list of Accessibility DescriptorType nodes */
317   GList *Accessibility;
318   /* list of Role DescriptorType nodes */
319   GList *Role;
320   /* list of Rating DescriptorType nodes */
321   GList *Rating;
322   /* list of Viewpoint DescriptorType nodes */
323   GList *Viewpoint;
324   /* RepresentationBase extension */
325   GstRepresentationBaseType *RepresentationBase;
326   /* SegmentBase node */
327   GstSegmentBaseType *SegmentBase;
328   /* SegmentList node */
329   GstSegmentListNode *SegmentList;
330   /* SegmentTemplate node */
331   GstSegmentTemplateNode *SegmentTemplate;
332   /* list of BaseURL nodes */
333   GList *BaseURLs;
334   /* list of Representation nodes */
335   GList *Representations;
336   /* list of ContentComponent nodes */
337   GList *ContentComponents;
338 
339   gchar *xlink_href;
340   GstXLinkActuate actuate;
341 };
342 
343 struct _GstSubsetNode
344 {
345   guint *contains;                   /* UIntVectorType */
346   guint size;                        /* size of the "contains" array */
347 };
348 
349 struct _GstPeriodNode
350 {
351   gchar *id;
352   guint64 start;                     /* [ms] */
353   guint64 duration;                  /* [ms] */
354   gboolean bitstreamSwitching;
355   /* SegmentBase node */
356   GstSegmentBaseType *SegmentBase;
357   /* SegmentList node */
358   GstSegmentListNode *SegmentList;
359   /* SegmentTemplate node */
360   GstSegmentTemplateNode *SegmentTemplate;
361   /* list of Adaptation Set nodes */
362   GList *AdaptationSets;
363   /* list of Representation nodes */
364   GList *Subsets;
365   /* list of BaseURL nodes */
366   GList *BaseURLs;
367 
368   gchar *xlink_href;
369   GstXLinkActuate actuate;
370 };
371 
372 struct _GstProgramInformationNode
373 {
374   gchar *lang;                      /* LangVectorType RFC 5646 */
375   gchar *moreInformationURL;
376   /* children nodes */
377   gchar *Title;
378   gchar *Source;
379   gchar *Copyright;
380 };
381 
382 struct _GstMetricsRangeNode
383 {
384   guint64 starttime;                 /* [ms] */
385   guint64 duration;                  /* [ms] */
386 };
387 
388 struct _GstMetricsNode
389 {
390   gchar *metrics;
391   /* list of Metrics Range nodes */
392   GList *MetricsRanges;
393   /* list of Reporting nodes */
394   GList *Reportings;
395 };
396 
397 struct _GstUTCTimingNode {
398   GstMPDUTCTimingType method;
399   /* NULL terminated array of strings */
400   gchar **urls;
401 };
402 
403 struct _GstMPDNode
404 {
405   gchar *default_namespace;
406   gchar *namespace_xsi;
407   gchar *namespace_ext;
408   gchar *schemaLocation;
409   gchar *id;
410   gchar *profiles;
411   GstMPDFileType type;
412   GstDateTime *availabilityStartTime;
413   GstDateTime *availabilityEndTime;
414   guint64 mediaPresentationDuration;  /* [ms] */
415   guint64 minimumUpdatePeriod;        /* [ms] */
416   guint64 minBufferTime;              /* [ms] */
417   guint64 timeShiftBufferDepth;       /* [ms] */
418   guint64 suggestedPresentationDelay; /* [ms] */
419   guint64 maxSegmentDuration;         /* [ms] */
420   guint64 maxSubsegmentDuration;      /* [ms] */
421   /* list of BaseURL nodes */
422   GList *BaseURLs;
423   /* list of Location nodes */
424   GList *Locations;
425   /* List of ProgramInformation nodes */
426   GList *ProgramInfo;
427   /* list of Periods nodes */
428   GList *Periods;
429   /* list of Metrics nodes */
430   GList *Metrics;
431   /* list of GstUTCTimingNode nodes */
432   GList *UTCTiming;
433 };
434 
435 /**
436  * GstStreamPeriod:
437  *
438  * Stream period data structure
439  */
440 struct _GstStreamPeriod
441 {
442   GstPeriodNode *period;                      /* Stream period */
443   guint number;                               /* Period number */
444   GstClockTime start;                         /* Period start time */
445   GstClockTime duration;                      /* Period duration */
446 };
447 
448 /**
449  * GstMediaSegment:
450  *
451  * Media segment data structure
452  */
453 struct _GstMediaSegment
454 {
455   GstSegmentURLNode *SegmentURL;              /* this is NULL when using a SegmentTemplate */
456   guint number;                               /* segment number */
457   gint repeat;                                /* number of extra repetitions (0 = played only once) */
458   guint64 scale_start;                        /* start time in timescale units */
459   guint64 scale_duration;                     /* duration in timescale units */
460   GstClockTime start;                         /* segment start time */
461   GstClockTime duration;                      /* segment duration */
462 };
463 
464 struct _GstMediaFragmentInfo
465 {
466   gchar *uri;
467   gint64 range_start;
468   gint64 range_end;
469 
470   gchar *index_uri;
471   gint64 index_range_start;
472   gint64 index_range_end;
473 
474   gboolean discontinuity;
475   GstClockTime timestamp;
476   GstClockTime duration;
477 };
478 
479 /**
480  * GstActiveStream:
481  *
482  * Active stream data structure
483  */
484 struct _GstActiveStream
485 {
486   GstStreamMimeType mimeType;                 /* video/audio/application */
487 
488   guint baseURL_idx;                          /* index of the baseURL used for last request */
489   gchar *baseURL;                             /* active baseURL used for last request */
490   gchar *queryURL;                            /* active queryURL used for last request */
491   guint max_bandwidth;                        /* max bandwidth allowed for this mimeType */
492 
493   GstAdaptationSetNode *cur_adapt_set;        /* active adaptation set */
494   gint representation_idx;                    /* index of current representation */
495   GstRepresentationNode *cur_representation;  /* active representation */
496   GstSegmentBaseType *cur_segment_base;       /* active segment base */
497   GstSegmentListNode *cur_segment_list;       /* active segment list */
498   GstSegmentTemplateNode *cur_seg_template;   /* active segment template */
499   gint segment_index;                         /* index of next sequence chunk */
500   guint segment_repeat_index;                 /* index of the repeat count of a segment */
501   GPtrArray *segments;                        /* array of GstMediaSegment */
502   GstClockTime presentationTimeOffset;        /* presentation time offset of the current segment */
503 };
504 
505 struct _GstMpdClient
506 {
507   GstMPDNode *mpd_node;                       /* active MPD manifest file */
508 
509   GList *periods;                             /* list of GstStreamPeriod */
510   guint period_idx;                           /* index of current Period */
511 
512   GList *active_streams;                      /* list of GstActiveStream */
513 
514   guint update_failed_count;
515   gchar *mpd_uri;                             /* manifest file URI */
516   gchar *mpd_base_uri;                        /* base URI for resolving relative URIs.
517                                                * this will be different for redirects */
518 
519   /* profiles */
520   gboolean profile_isoff_ondemand;
521 
522   GstUriDownloader * downloader;
523 };
524 
525 /* Basic initialization/deinitialization functions */
526 GstMpdClient *gst_mpd_client_new (void);
527 void gst_active_streams_free (GstMpdClient * client);
528 void gst_mpd_client_free (GstMpdClient * client);
529 void gst_media_fragment_info_clear (GstMediaFragmentInfo * fragment);
530 
531 void gst_mpd_client_set_uri_downloader (GstMpdClient * client, GstUriDownloader * download);
532 
533 /* MPD file parsing */
534 gboolean gst_mpd_parse (GstMpdClient *client, const gchar *data, gint size);
535 
536 /* Streaming management */
537 gboolean gst_mpd_client_setup_media_presentation (GstMpdClient *client, GstClockTime time, gint period_index, const gchar *period_id);
538 gboolean gst_mpd_client_setup_streaming (GstMpdClient * client, GstAdaptationSetNode * adapt_set);
539 gboolean gst_mpd_client_setup_representation (GstMpdClient *client, GstActiveStream *stream, GstRepresentationNode *representation);
540 GstClockTime gst_mpd_client_get_next_fragment_duration (GstMpdClient * client, GstActiveStream * stream);
541 GstClockTime gst_mpd_client_get_media_presentation_duration (GstMpdClient *client);
542 GstClockTime gst_mpd_client_get_maximum_segment_duration (GstMpdClient * client);
543 gboolean gst_mpd_client_get_last_fragment_timestamp_end (GstMpdClient * client, guint stream_idx, GstClockTime * ts);
544 gboolean gst_mpd_client_get_next_fragment_timestamp (GstMpdClient * client, guint stream_idx, GstClockTime * ts);
545 gboolean gst_mpd_client_get_next_fragment (GstMpdClient *client, guint indexStream, GstMediaFragmentInfo * fragment);
546 gboolean gst_mpd_client_get_next_header (GstMpdClient *client, gchar **uri, guint stream_idx, gint64 * range_start, gint64 * range_end);
547 gboolean gst_mpd_client_get_next_header_index (GstMpdClient *client, gchar **uri, guint stream_idx, gint64 * range_start, gint64 * range_end);
548 gboolean gst_mpd_client_is_live (GstMpdClient * client);
549 gboolean gst_mpd_client_stream_seek (GstMpdClient * client, GstActiveStream * stream, gboolean forward, GstSeekFlags flags, GstClockTime ts, GstClockTime * final_ts);
550 gboolean gst_mpd_client_seek_to_time (GstMpdClient * client, GDateTime * time);
551 GstClockTime gst_mpd_parser_get_stream_presentation_offset (GstMpdClient *client, guint stream_idx);
552 gchar** gst_mpd_client_get_utc_timing_sources (GstMpdClient *client, guint methods, GstMPDUTCTimingType *selected_method);
553 GstClockTime gst_mpd_parser_get_period_start_time (GstMpdClient *client);
554 
555 /* Period selection */
556 guint gst_mpd_client_get_period_index_at_time (GstMpdClient * client, GstDateTime * time);
557 gboolean gst_mpd_client_set_period_index (GstMpdClient *client, guint period_idx);
558 gboolean gst_mpd_client_set_period_id (GstMpdClient *client, const gchar * period_id);
559 guint gst_mpd_client_get_period_index (GstMpdClient *client);
560 const gchar *gst_mpd_client_get_period_id (GstMpdClient *client);
561 gboolean gst_mpd_client_has_next_period (GstMpdClient *client);
562 gboolean gst_mpd_client_has_previous_period (GstMpdClient * client);
563 
564 /* Representation selection */
565 gint gst_mpdparser_get_rep_idx_with_max_bandwidth (GList *Representations, gint64 max_bandwidth, gint max_video_width, gint max_video_height, gint max_video_framerate_n, gint max_video_framerate_d);
566 gint gst_mpdparser_get_rep_idx_with_min_bandwidth (GList * Representations);
567 
568 /* URL management */
569 const gchar *gst_mpdparser_get_baseURL (GstMpdClient *client, guint indexStream);
570 
571 /* Active stream */
572 guint gst_mpdparser_get_nb_active_stream (GstMpdClient *client);
573 GstActiveStream *gst_mpdparser_get_active_stream_by_index (GstMpdClient *client, guint stream_idx);
574 gboolean gst_mpd_client_active_stream_contains_subtitles (GstActiveStream * stream);
575 
576 /* AdaptationSet */
577 guint gst_mpdparser_get_nb_adaptationSet (GstMpdClient *client);
578 GList * gst_mpd_client_get_adaptation_sets (GstMpdClient * client);
579 
580 /* Segment */
581 gboolean gst_mpd_client_has_next_segment (GstMpdClient * client, GstActiveStream * stream, gboolean forward);
582 GstFlowReturn gst_mpd_client_advance_segment (GstMpdClient * client, GstActiveStream * stream, gboolean forward);
583 void gst_mpd_client_seek_to_first_segment (GstMpdClient * client);
584 GstDateTime *gst_mpd_client_get_next_segment_availability_start_time (GstMpdClient * client, GstActiveStream * stream);
585 
586 /* Get audio/video stream parameters (caps, width, height, rate, number of channels) */
587 GstCaps * gst_mpd_client_get_stream_caps (GstActiveStream * stream);
588 gboolean gst_mpd_client_get_bitstream_switching_flag (GstActiveStream * stream);
589 guint gst_mpd_client_get_video_stream_width (GstActiveStream * stream);
590 guint gst_mpd_client_get_video_stream_height (GstActiveStream * stream);
591 gboolean gst_mpd_client_get_video_stream_framerate (GstActiveStream * stream, gint * fps_num, gint * fps_den);
592 guint gst_mpd_client_get_audio_stream_rate (GstActiveStream * stream);
593 guint gst_mpd_client_get_audio_stream_num_channels (GstActiveStream * stream);
594 
595 /* Support multi language */
596 guint gst_mpdparser_get_list_and_nb_of_audio_language (GstMpdClient *client, GList **lang);
597 
598 gint64 gst_mpd_client_calculate_time_difference (const GstDateTime * t1, const GstDateTime * t2);
599 GstDateTime *gst_mpd_client_add_time_difference (GstDateTime * t1, gint64 usecs);
600 gint64 gst_mpd_client_parse_default_presentation_delay(GstMpdClient * client, const gchar * default_presentation_delay);
601 
602 /* profiles */
603 gboolean gst_mpd_client_has_isoff_ondemand_profile (GstMpdClient *client);
604 
605 G_END_DECLS
606 
607 #endif /* __GST_MPDPARSER_H__ */
608 
609