• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2010 Marc-Andre Lureau <marcandre.lureau@gmail.com>
3  * Copyright (C) 2010 Andoni Morales Alastruey <ylatuya@gmail.com>
4  * Copyright (C) 2015 Tim-Philipp Müller <tim@centricular.com>
5  *
6  * m3u8.h:
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Library General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Library General Public License for more details.
17  *
18  * You should have received a copy of the GNU Library General Public
19  * License along with this library; if not, write to the
20  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
21  * Boston, MA 02110-1301, USA.
22  */
23 
24 #ifndef __M3U8_H__
25 #define __M3U8_H__
26 
27 #include <glib.h>
28 
29 G_BEGIN_DECLS
30 
31 typedef struct _GstM3U8 GstM3U8;
32 typedef struct _GstM3U8MediaFile GstM3U8MediaFile;
33 typedef struct _GstHLSMedia GstHLSMedia;
34 typedef struct _GstM3U8Client GstM3U8Client;
35 typedef struct _GstHLSVariantStream GstHLSVariantStream;
36 typedef struct _GstHLSMasterPlaylist GstHLSMasterPlaylist;
37 
38 #define GST_M3U8(m) ((GstM3U8*)m)
39 #define GST_M3U8_MEDIA_FILE(f) ((GstM3U8MediaFile*)f)
40 
41 #define GST_M3U8_LOCK(m) g_mutex_lock (&m->lock);
42 #define GST_M3U8_UNLOCK(m) g_mutex_unlock (&m->lock);
43 
44 #define GST_M3U8_IS_LIVE(m) ((m)->endlist == FALSE)
45 
46 /* hlsdemux must not get closer to the end of a live stream than
47    GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE fragments. Section 6.3.3
48    "Playing the Playlist file" of the HLS draft states that this
49    value is three fragments */
50 #define GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE 3
51 
52 struct _GstM3U8
53 {
54   gchar *uri;                   /* actually downloaded URI */
55   gchar *base_uri;              /* URI to use as base for resolving relative URIs.
56                                  * This will be different to uri in case of redirects */
57   gchar *name;                  /* This will be the "name" of the playlist, the original
58                                  * relative/absolute uri in a variant playlist */
59 
60   /* parsed info */
61   gboolean endlist;             /* if ENDLIST has been reached */
62   gint version;                 /* last EXT-X-VERSION */
63   GstClockTime targetduration;  /* last EXT-X-TARGETDURATION */
64   gboolean allowcache;          /* last EXT-X-ALLOWCACHE */
65 
66   GList *files;
67 
68   /* state */
69   GList *current_file;
70   GstClockTime current_file_duration; /* Duration of current fragment */
71   gint64 sequence;                    /* the next sequence for this client */
72   GstClockTime sequence_position;     /* position of this sequence */
73   gint64 highest_sequence_number;     /* largest seen sequence number */
74   GstClockTime first_file_start;      /* timecode of the start of the first fragment in the current media playlist */
75   GstClockTime last_file_end;         /* timecode of the end of the last fragment in the current media playlist */
76   GstClockTime duration;              /* cached total duration */
77   gint discont_sequence;              /* currently expected EXT-X-DISCONTINUITY-SEQUENCE */
78 
79   /*< private > */
80   gchar *last_data;
81   GMutex lock;
82 
83   gint ref_count;               /* ATOMIC */
84 };
85 
86 GstM3U8 *          gst_m3u8_ref   (GstM3U8 * m3u8);
87 
88 void               gst_m3u8_unref (GstM3U8 * m3u8);
89 
90 
91 struct _GstM3U8MediaFile
92 {
93   gchar *title;
94   GstClockTime duration;
95   gchar *uri;
96   gint64 sequence;               /* the sequence nb of this file */
97   gboolean discont;             /* this file marks a discontinuity */
98   gchar *key;
99   guint8 iv[16];
100   gint64 offset, size;
101   gint ref_count;               /* ATOMIC */
102 };
103 
104 GstM3U8MediaFile * gst_m3u8_media_file_ref   (GstM3U8MediaFile * mfile);
105 
106 void               gst_m3u8_media_file_unref (GstM3U8MediaFile * mfile);
107 
108 GstM3U8 *          gst_m3u8_new (void);
109 
110 gboolean           gst_m3u8_update               (GstM3U8  * m3u8,
111                                                   gchar    * data);
112 
113 void               gst_m3u8_set_uri              (GstM3U8      * m3u8,
114                                                   const gchar  * uri,
115                                                   const gchar  * base_uri,
116                                                   const gchar  * name);
117 
118 GstM3U8MediaFile * gst_m3u8_get_next_fragment    (GstM3U8      * m3u8,
119                                                   gboolean       forward,
120                                                   GstClockTime * sequence_position,
121                                                   gboolean     * discont);
122 
123 gboolean           gst_m3u8_has_next_fragment    (GstM3U8 * m3u8,
124                                                   gboolean  forward);
125 
126 void               gst_m3u8_advance_fragment     (GstM3U8 * m3u8,
127                                                   gboolean  forward);
128 
129 GstClockTime       gst_m3u8_get_duration         (GstM3U8 * m3u8);
130 
131 GstClockTime       gst_m3u8_get_target_duration  (GstM3U8 * m3u8);
132 
133 gchar *            gst_m3u8_get_uri              (GstM3U8 * m3u8);
134 
135 gboolean           gst_m3u8_is_live              (GstM3U8 * m3u8);
136 
137 gboolean           gst_m3u8_get_seek_range       (GstM3U8 * m3u8,
138                                                   gint64  * start,
139                                                   gint64  * stop);
140 
141 typedef enum
142 {
143   GST_HLS_MEDIA_TYPE_INVALID = -1,
144   GST_HLS_MEDIA_TYPE_AUDIO,
145   GST_HLS_MEDIA_TYPE_VIDEO,
146   GST_HLS_MEDIA_TYPE_SUBTITLES,
147   GST_HLS_MEDIA_TYPE_CLOSED_CAPTIONS,
148   GST_HLS_N_MEDIA_TYPES
149 } GstHLSMediaType;
150 
151 struct _GstHLSMedia {
152   GstHLSMediaType mtype;
153   gchar *group_id;
154   gchar *name;
155   gchar *lang;
156   gchar *uri;
157   gboolean is_default;
158   gboolean autoselect;
159   gboolean forced;
160 
161   GstM3U8 *playlist;            /* media playlist */
162 
163   gint ref_count;               /* ATOMIC */
164 };
165 
166 GstHLSMedia * gst_hls_media_ref   (GstHLSMedia * media);
167 
168 void          gst_hls_media_unref (GstHLSMedia * media);
169 
170 
171 struct _GstHLSVariantStream {
172   gchar *name;         /* This will be the "name" of the playlist, the original
173                         * relative/absolute uri in a variant playlist */
174   gchar *uri;
175   gchar *codecs;
176   gint bandwidth;
177   gint program_id;
178   gint width;
179   gint height;
180   gboolean iframe;
181 
182   gint refcount;       /* ATOMIC */
183 
184   GstM3U8 *m3u8;       /* media playlist */
185 
186   /* alternative renditions */
187   gchar *media_groups[GST_HLS_N_MEDIA_TYPES];
188   GList *media[GST_HLS_N_MEDIA_TYPES];
189 };
190 
191 GstHLSVariantStream * gst_hls_variant_stream_ref (GstHLSVariantStream * stream);
192 
193 void                  gst_hls_variant_stream_unref (GstHLSVariantStream * stream);
194 
195 gboolean              gst_hls_variant_stream_is_live (GstHLSVariantStream * stream);
196 
197 GstHLSMedia *         gst_hls_variant_find_matching_media (GstHLSVariantStream  * stream,
198                           GstHLSMedia *media);
199 
200 
201 struct _GstHLSMasterPlaylist
202 {
203   /* Available variant streams, sorted by bitrate (low -> high) */
204   GList    *variants;
205   GList    *iframe_variants;
206 
207   GstHLSVariantStream *default_variant;  /* first in the list */
208 
209   gint      version;                     /* EXT-X-VERSION */
210 
211   gint      refcount;                    /* ATOMIC */
212 
213   gboolean  is_simple;                   /* TRUE if simple main media playlist,
214                                           * FALSE if variant playlist (either
215                                           * way the variants list will be set) */
216 
217   /*< private > */
218   gchar   *last_data;
219 };
220 
221 GstHLSMasterPlaylist * gst_hls_master_playlist_new_from_data (gchar       * data,
222                                                               const gchar * base_uri);
223 
224 GstHLSVariantStream *  gst_hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist * playlist,
225                                                                         GstHLSVariantStream  * current_variant,
226                                                                         guint                  bitrate);
227 GstHLSVariantStream *  gst_hls_master_playlist_get_matching_variant (GstHLSMasterPlaylist * playlist,
228                                                                      GstHLSVariantStream  * current_variant);
229 
230 void                   gst_hls_master_playlist_unref (GstHLSMasterPlaylist * playlist);
231 
232 G_END_DECLS
233 
234 #endif /* __M3U8_H__ */
235