• 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 <gst/gst.h>
28 
29 G_BEGIN_DECLS
30 
31 typedef struct _GstM3U8 GstM3U8;
32 typedef struct _GstM3U8MediaFile GstM3U8MediaFile;
33 typedef struct _GstM3U8InitFile GstM3U8InitFile;
34 typedef struct _GstHLSMedia GstHLSMedia;
35 typedef struct _GstM3U8Client GstM3U8Client;
36 typedef struct _GstHLSVariantStream GstHLSVariantStream;
37 typedef struct _GstHLSMasterPlaylist GstHLSMasterPlaylist;
38 
39 #define GST_M3U8(m) ((GstM3U8*)m)
40 #define GST_M3U8_MEDIA_FILE(f) ((GstM3U8MediaFile*)f)
41 
42 #define GST_M3U8_LOCK(m) g_mutex_lock (&m->lock);
43 #define GST_M3U8_UNLOCK(m) g_mutex_unlock (&m->lock);
44 
45 #define GST_M3U8_IS_LIVE(m) ((m)->endlist == FALSE)
46 
47 /* hlsdemux must not get closer to the end of a live stream than
48    GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE fragments. Section 6.3.3
49    "Playing the Playlist file" of the HLS draft states that this
50    value is three fragments */
51 #define GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE 3
52 
53 struct _GstM3U8
54 {
55   gchar *uri;                   /* actually downloaded URI */
56   gchar *base_uri;              /* URI to use as base for resolving relative URIs.
57                                  * This will be different to uri in case of redirects */
58   gchar *name;                  /* This will be the "name" of the playlist, the original
59                                  * relative/absolute uri in a variant playlist */
60 
61   /* parsed info */
62   gboolean endlist;             /* if ENDLIST has been reached */
63   gint version;                 /* last EXT-X-VERSION */
64   GstClockTime targetduration;  /* last EXT-X-TARGETDURATION */
65   gboolean allowcache;          /* last EXT-X-ALLOWCACHE */
66 
67   GList *files;
68 
69   /* state */
70   GList *current_file;
71   GstClockTime current_file_duration; /* Duration of current fragment */
72   gint64 sequence;                    /* the next sequence for this client */
73   GstClockTime sequence_position;     /* position of this sequence */
74   gint64 highest_sequence_number;     /* largest seen sequence number */
75   GstClockTime first_file_start;      /* timecode of the start of the first fragment in the current media playlist */
76   GstClockTime last_file_end;         /* timecode of the end of the last fragment in the current media playlist */
77   GstClockTime duration;              /* cached total duration */
78   gint discont_sequence;              /* currently expected EXT-X-DISCONTINUITY-SEQUENCE */
79 
80   /*< private > */
81   gchar *last_data;
82   GMutex lock;
83 
84   gint ref_count;               /* ATOMIC */
85 };
86 
87 GstM3U8 *          gst_m3u8_ref   (GstM3U8 * m3u8);
88 
89 void               gst_m3u8_unref (GstM3U8 * m3u8);
90 
91 
92 struct _GstM3U8MediaFile
93 {
94   gchar *title;
95   GstClockTime duration;
96   gchar *uri;
97   gint64 sequence;               /* the sequence nb of this file */
98   gboolean discont;             /* this file marks a discontinuity */
99   gchar *key;
100   guint8 iv[16];
101   gint64 offset, size;
102   gint ref_count;               /* ATOMIC */
103   GstM3U8InitFile *init_file;   /* Media Initialization (hold ref) */
104 };
105 
106 struct _GstM3U8InitFile
107 {
108   gchar *uri;
109   gint64 offset, size;
110   guint ref_count;      /* ATOMIC */
111 };
112 
113 GstM3U8MediaFile * gst_m3u8_media_file_ref   (GstM3U8MediaFile * mfile);
114 
115 void               gst_m3u8_media_file_unref (GstM3U8MediaFile * mfile);
116 
117 GstM3U8 *          gst_m3u8_new (void);
118 
119 gboolean           gst_m3u8_update               (GstM3U8  * m3u8,
120                                                   gchar    * data);
121 
122 void               gst_m3u8_set_uri              (GstM3U8      * m3u8,
123                                                   const gchar  * uri,
124                                                   const gchar  * base_uri,
125                                                   const gchar  * name);
126 
127 GstM3U8MediaFile * gst_m3u8_get_next_fragment    (GstM3U8      * m3u8,
128                                                   gboolean       forward,
129                                                   GstClockTime * sequence_position,
130                                                   gboolean     * discont);
131 
132 gboolean           gst_m3u8_has_next_fragment    (GstM3U8 * m3u8,
133                                                   gboolean  forward);
134 
135 void               gst_m3u8_advance_fragment     (GstM3U8 * m3u8,
136                                                   gboolean  forward);
137 
138 GstClockTime       gst_m3u8_get_duration         (GstM3U8 * m3u8);
139 
140 GstClockTime       gst_m3u8_get_target_duration  (GstM3U8 * m3u8);
141 
142 gchar *            gst_m3u8_get_uri              (GstM3U8 * m3u8);
143 
144 gboolean           gst_m3u8_is_live              (GstM3U8 * m3u8);
145 
146 gboolean           gst_m3u8_get_seek_range       (GstM3U8 * m3u8,
147                                                   gint64  * start,
148                                                   gint64  * stop);
149 
150 typedef enum
151 {
152   GST_HLS_MEDIA_TYPE_INVALID = -1,
153   GST_HLS_MEDIA_TYPE_AUDIO,
154   GST_HLS_MEDIA_TYPE_VIDEO,
155   GST_HLS_MEDIA_TYPE_SUBTITLES,
156   GST_HLS_MEDIA_TYPE_CLOSED_CAPTIONS,
157   GST_HLS_N_MEDIA_TYPES
158 } GstHLSMediaType;
159 
160 struct _GstHLSMedia {
161   GstHLSMediaType mtype;
162   gchar *group_id;
163   gchar *name;
164   gchar *lang;
165   gchar *uri;
166   gboolean is_default;
167   gboolean autoselect;
168   gboolean forced;
169 
170   GstM3U8 *playlist;            /* media playlist */
171 
172   gint ref_count;               /* ATOMIC */
173 };
174 
175 GstHLSMedia * gst_hls_media_ref   (GstHLSMedia * media);
176 
177 void          gst_hls_media_unref (GstHLSMedia * media);
178 
179 const gchar * gst_hls_media_type_get_name (GstHLSMediaType mtype);
180 
181 
182 struct _GstHLSVariantStream {
183   gchar *name;         /* This will be the "name" of the playlist, the original
184                         * relative/absolute uri in a variant playlist */
185   gchar *uri;
186   gchar *codecs;
187   gint bandwidth;
188   gint program_id;
189   gint width;
190   gint height;
191   gboolean iframe;
192 
193   gint refcount;       /* ATOMIC */
194 
195   GstM3U8 *m3u8;       /* media playlist */
196 
197   /* alternative renditions */
198   gchar *media_groups[GST_HLS_N_MEDIA_TYPES];
199   GList *media[GST_HLS_N_MEDIA_TYPES];
200 };
201 
202 GstHLSVariantStream * gst_hls_variant_stream_ref (GstHLSVariantStream * stream);
203 
204 void                  gst_hls_variant_stream_unref (GstHLSVariantStream * stream);
205 
206 gboolean              gst_hls_variant_stream_is_live (GstHLSVariantStream * stream);
207 
208 GstHLSMedia *         gst_hls_variant_find_matching_media (GstHLSVariantStream  * stream,
209                           GstHLSMedia *media);
210 
211 
212 struct _GstHLSMasterPlaylist
213 {
214   /* Available variant streams, sorted by bitrate (low -> high) */
215   GList    *variants;
216   GList    *iframe_variants;
217 
218   GstHLSVariantStream *default_variant;  /* first in the list */
219 
220   gint      version;                     /* EXT-X-VERSION */
221 
222   gint      refcount;                    /* ATOMIC */
223 
224   gboolean  is_simple;                   /* TRUE if simple main media playlist,
225                                           * FALSE if variant playlist (either
226                                           * way the variants list will be set) */
227 
228   /*< private > */
229   gchar   *last_data;
230 };
231 
232 GstHLSMasterPlaylist * gst_hls_master_playlist_new_from_data (gchar       * data,
233                                                               const gchar * base_uri);
234 
235 GstHLSVariantStream *  gst_hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist * playlist,
236                                                                         GstHLSVariantStream  * current_variant,
237                                                                         guint                  bitrate);
238 GstHLSVariantStream *  gst_hls_master_playlist_get_matching_variant (GstHLSMasterPlaylist * playlist,
239                                                                      GstHLSVariantStream  * current_variant);
240 
241 void                   gst_hls_master_playlist_unref (GstHLSMasterPlaylist * playlist);
242 
243 G_END_DECLS
244 
245 #endif /* __M3U8_H__ */
246