adaptive: extract variant info
[platform/upstream/gstreamer.git] / ext / hls / m3u8.h
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 #ifdef TIZEN_FEATURE_ADAPTIVE_MODIFICATION
192 typedef struct
193 {
194   gint bandwidth;
195   gint width;
196   gint height;
197 } GstM3U8VideoVariantInfo;
198 #endif
199
200 GstHLSVariantStream * gst_hls_variant_stream_ref (GstHLSVariantStream * stream);
201
202 void                  gst_hls_variant_stream_unref (GstHLSVariantStream * stream);
203
204 gboolean              gst_hls_variant_stream_is_live (GstHLSVariantStream * stream);
205
206 GstHLSMedia *         gst_hls_variant_find_matching_media (GstHLSVariantStream  * stream,
207                           GstHLSMedia *media);
208
209
210 struct _GstHLSMasterPlaylist
211 {
212   /* Available variant streams, sorted by bitrate (low -> high) */
213   GList    *variants;
214   GList    *iframe_variants;
215 #ifdef TIZEN_FEATURE_ADAPTIVE_MODIFICATION
216   GList    *variant_info;                /* stream variant info */
217 #endif
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 #ifdef TIZEN_FEATURE_ADAPTIVE_MODIFICATION
235 GstHLSVariantStream *  gst_hls_master_playlist_get_variant_for_max_limit (GstHLSMasterPlaylist *playlist,
236                                                                           GstHLSVariantStream * current_variant,
237                                                                           guint bitrate, gint bandwidth,
238                                                                           gint width, gint height);
239 #else
240 GstHLSVariantStream *  gst_hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist * playlist,
241                                                                         GstHLSVariantStream  * current_variant,
242                                                                         guint                  bitrate);
243 #endif
244 GstHLSVariantStream *  gst_hls_master_playlist_get_matching_variant (GstHLSMasterPlaylist * playlist,
245                                                                      GstHLSVariantStream  * current_variant);
246
247 void                   gst_hls_master_playlist_unref (GstHLSMasterPlaylist * playlist);
248
249 G_END_DECLS
250
251 #endif /* __M3U8_H__ */