Bump GLib requirement to >= 2.62
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-good / ext / adaptivedemux2 / 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  * Copyright (C) 2021-2022 Centricular Ltd
7  *   Author: Edward Hervey <edward@centricular.com>
8  *   Author: Jan Schmidt <jan@centricular.com>
9  *
10  * m3u8.h:
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Library General Public
14  * License as published by the Free Software Foundation; either
15  * version 2 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public
23  * License along with this library; if not, write to the
24  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
25  * Boston, MA 02110-1301, USA.
26  */
27
28 #ifndef __M3U8_H__
29 #define __M3U8_H__
30
31 #include <gst/gst.h>
32
33 G_BEGIN_DECLS
34
35 typedef struct _GstHLSMediaPlaylist GstHLSMediaPlaylist;
36 typedef struct _GstHLSTimeMap GstHLSTimeMap;
37 typedef struct _GstM3U8MediaSegment GstM3U8MediaSegment;
38 typedef struct _GstM3U8InitFile GstM3U8InitFile;
39 typedef struct _GstHLSRenditionStream GstHLSRenditionStream;
40 typedef struct _GstM3U8Client GstM3U8Client;
41 typedef struct _GstHLSVariantStream GstHLSVariantStream;
42 typedef struct _GstHLSMasterPlaylist GstHLSMasterPlaylist;
43
44 #define GST_HLS_MEDIA_PLAYLIST(m) ((GstHLSMediaPlaylist*)m)
45 #define GST_M3U8_MEDIA_SEGMENT(f) ((GstM3U8MediaSegment*)f)
46
47 #define GST_HLS_MEDIA_PLAYLIST_LOCK(m) g_mutex_lock (&m->lock);
48 #define GST_HLS_MEDIA_PLAYLIST_UNLOCK(m) g_mutex_unlock (&m->lock);
49
50 #define GST_HLS_MEDIA_PLAYLIST_IS_LIVE(m) ((m)->endlist == FALSE)
51
52 /* hlsdemux must not get closer to the end of a live stream than
53    GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE fragments. Section 6.3.3
54    "Playing the Playlist file" of the HLS draft states that this
55    value is three fragments */
56 #define GST_M3U8_LIVE_MIN_FRAGMENT_DISTANCE 3
57
58 typedef enum {
59   GST_HLS_PLAYLIST_TYPE_UNDEFINED,
60   GST_HLS_PLAYLIST_TYPE_EVENT,
61   GST_HLS_PLAYLIST_TYPE_VOD,
62 } GstHLSPlaylistType;
63
64 /**
65  * GstHLSMediaPlaylist:
66  *
67  * Official term in RFC : "Media Playlist". A List of Media Segments.
68  *
69  * It can be used by either a variant stream (GstHLSVariantStream) or an
70  * alternate rendition (GstHLSMedia).
71  *
72  * Note: Was called `GstM3u8` in legacy elements
73  */
74
75 struct _GstHLSMediaPlaylist
76 {
77   gchar *uri;                   /* actually downloaded URI */
78   gchar *base_uri;              /* URI to use as base for resolving relative URIs.
79                                  * This will be different to uri in case of redirects */
80   /* Base Tag */
81   gint version;                 /* EXT-X-VERSION (default 1) */
82
83   /* Media Playlist Tags */
84   GstClockTime targetduration;  /* EXT-X-TARGETDURATION, default GST_CLOCK_TIME_NONE */
85   gint64 media_sequence;        /* EXT-X-MEDIA-SEQUENCE, MSN of the first Media
86                                    Segment in the playlist. */
87   gint64 discont_sequence;      /* EXT-X-DISCONTINUITY-SEQUENCE. Default : 0 */
88   gboolean has_ext_x_dsn;       /* EXT-X-DISCONTINUITY-SEQUENCE present and specified */
89   gboolean endlist;             /* EXT-X-ENDLIST present */
90   GstHLSPlaylistType type;      /* EXT-X-PLAYLIST-TYPE. Default:
91                                    GST_HLS_PLAYLIST_TYE_UNDEFINED */
92   gboolean i_frame;             /* EXT-X-I-FRAMES-ONLY present. */
93
94   gboolean allowcache;          /* deprecated EXT-X-ALLOW-CACHE */
95
96   /* Overview of contained media segments */
97   gboolean ext_x_key_present;   /* a valid EXT-X-KEY is present on at least one
98                                    media segment */
99   gboolean ext_x_pdt_present;   /* a valid EXT-X-PROGRAM-DATE-TIME is present on
100                                    at least one media segment */
101
102   GPtrArray *segments;          /* Array of GstM3U8MediaSegment */
103
104   /* Generated information */
105   GstClockTime duration;        /* The estimated total duration of all segments
106                                    contained in this playlist */
107
108   gboolean reloaded;            /* If TRUE, this indicates that this playlist
109                                  * was reloaded but had identical content */
110
111   /*< private > */
112   GMutex lock;
113
114   /* Copy of the incoming data that created this media playlist.
115    * See gst_hls_media_playlist_has_same_data()  */
116   gchar   *last_data;
117
118   gint ref_count;               /* ATOMIC */
119 };
120
121 /* gst_hls_media_playlist_new: Internal function : Do not use from demuxer code, only for unit
122  *               testing purposes */
123 GstHLSMediaPlaylist * gst_hls_media_playlist_new (const gchar * uri,
124                                                   const gchar * base_uri);
125
126 GstHLSMediaPlaylist * gst_hls_media_playlist_ref (GstHLSMediaPlaylist * m3u8);
127
128 void                  gst_hls_media_playlist_unref (GstHLSMediaPlaylist * m3u8);
129
130 /**
131  * GstM3U8MediaSegment:
132  *
133  * Official term in RFC : "Media Segment"
134  *
135  * Note : Naming in legacy elements was GstM3U8MediaFile
136  */
137 struct _GstM3U8MediaSegment
138 {
139   gchar *title;
140   GstClockTimeDiff stream_time; /* Computed stream time */
141   GstClockTime duration;
142   gchar *uri;
143   gint64 sequence;              /* the sequence number of this segment */
144   gint64 discont_sequence;      /* The Discontinuity Sequence Number of this segment */
145   gboolean discont;             /* this file marks a discontinuity */
146   gchar *key;
147   guint8 iv[16];
148   gint64 offset, size;
149   gint ref_count;               /* ATOMIC */
150   GstM3U8InitFile *init_file;   /* Media Initialization (hold ref) */
151   GDateTime *datetime;          /* EXT-X-PROGRAM-DATE-TIME */
152 };
153
154 struct _GstM3U8InitFile
155 {
156   gchar *uri;
157   gint64 offset, size;
158   guint ref_count;      /* ATOMIC */
159 };
160
161 GstM3U8MediaSegment *
162 gst_m3u8_media_segment_ref   (GstM3U8MediaSegment * mfile);
163
164 void
165 gst_m3u8_media_segment_unref (GstM3U8MediaSegment * mfile);
166
167
168 gboolean
169 gst_hls_media_playlist_has_same_data (GstHLSMediaPlaylist * m3u8,
170                                       gchar   * playlist_data);
171
172 GstHLSMediaPlaylist *
173 gst_hls_media_playlist_parse (gchar        * data,
174                               const gchar  * uri,
175                               const gchar  * base_uri);
176
177 void
178 gst_hls_media_playlist_recalculate_stream_time (GstHLSMediaPlaylist *playlist,
179                                                 GstM3U8MediaSegment *anchor);
180
181 GstM3U8MediaSegment *
182 gst_hls_media_playlist_sync_to_segment      (GstHLSMediaPlaylist * m3u8,
183                                              GstM3U8MediaSegment * segment);
184
185 gboolean
186 gst_hls_media_playlist_has_next_fragment    (GstHLSMediaPlaylist * m3u8,
187                                              GstM3U8MediaSegment * current,
188                                              gboolean  forward);
189
190 GstM3U8MediaSegment *
191 gst_hls_media_playlist_advance_fragment     (GstHLSMediaPlaylist * m3u8,
192                                              GstM3U8MediaSegment * current,
193                                              gboolean  forward);
194
195 GstM3U8MediaSegment *
196 gst_hls_media_playlist_get_starting_segment (GstHLSMediaPlaylist *self);
197
198 GstClockTime
199 gst_hls_media_playlist_get_duration         (GstHLSMediaPlaylist * m3u8);
200
201 gchar *
202 gst_hls_media_playlist_get_uri              (GstHLSMediaPlaylist * m3u8);
203
204 gboolean
205 gst_hls_media_playlist_is_live              (GstHLSMediaPlaylist * m3u8);
206
207 gboolean
208 gst_hls_media_playlist_get_seek_range       (GstHLSMediaPlaylist * m3u8,
209                                              gint64  * start,
210                                              gint64  * stop);
211
212 GstM3U8MediaSegment *
213 gst_hls_media_playlist_seek                 (GstHLSMediaPlaylist *playlist,
214                                              gboolean forward,
215                                              GstSeekFlags flags,
216                                              GstClockTimeDiff ts);
217 void
218 gst_hls_media_playlist_dump                 (GstHLSMediaPlaylist* self);
219
220 typedef enum
221 {
222   GST_HLS_RENDITION_STREAM_TYPE_INVALID = -1,
223   GST_HLS_RENDITION_STREAM_TYPE_AUDIO,
224   GST_HLS_RENDITION_STREAM_TYPE_VIDEO,
225   GST_HLS_RENDITION_STREAM_TYPE_SUBTITLES,
226   GST_HLS_RENDITION_STREAM_TYPE_CLOSED_CAPTIONS,
227   GST_HLS_N_MEDIA_TYPES
228 } GstHLSRenditionStreamType;
229
230 /**
231  * GstHLSRenditionStream:
232  *
233  * Official term in RFC : "Renditions are alternate versions of the content,
234  *   such as audio produced in different languages or video recorded from
235  *   different camera angles."
236  *
237  * Note: Was named GstHLSMedia in legacy elements
238  */
239
240 struct _GstHLSRenditionStream {
241   GstHLSRenditionStreamType mtype;
242   gchar *group_id;
243   gchar *name;
244   gchar *lang;
245   gchar *uri;
246   GstCaps *caps;
247   gboolean is_default;
248   gboolean autoselect;
249   gboolean forced;
250
251   gint ref_count;               /* ATOMIC */
252 };
253
254 GstHLSRenditionStream *
255 gst_hls_rendition_stream_ref   (GstHLSRenditionStream * media);
256
257 void
258 gst_hls_rendition_stream_unref (GstHLSRenditionStream * media);
259
260 const gchar *
261 gst_hls_rendition_stream_type_get_name (GstHLSRenditionStreamType mtype);
262
263
264 /**
265  * GstHLSVariantStream:
266  *
267  * Official term in RFC :
268  * """
269  * A Master Playlist provides a set of Variant Streams, each of which describes
270  *   a different version of the same content.
271  *
272  * A Variant Stream includes a Media Playlist that specifies media encoded at a
273  *  particular bit rate, in a particular format, and at a particular resolution
274  *  for media containing video.
275  * """
276  */
277 struct _GstHLSVariantStream {
278   gchar *name;         /* This will be the "name" of the playlist, the original
279                         * relative/absolute uri in a variant playlist */
280   gchar *uri;
281   gchar *codecs;
282   GstCaps *caps;
283   GstStreamType codecs_stream_type;     /* As defined by codecs */
284   gint bandwidth;                       /* bits per second */
285   gint program_id;
286   gint width;
287   gint height;
288   gboolean iframe;
289
290   gint refcount;       /* ATOMIC */
291
292   /* alternative renditions (names) */
293   gchar *media_groups[GST_HLS_N_MEDIA_TYPES];
294
295   /* List of gchar* fallback uri */
296   GList *fallback;
297 };
298
299 /* Notes: #define are to avoid symbol clashes with legacy hlsdemux */
300
301 #define gst_hls_variant_stream_ref hls_variant_stream_ref
302 GstHLSVariantStream * hls_variant_stream_ref (GstHLSVariantStream * stream);
303
304 #define gst_hls_variant_stream_unref hls_variant_stream_unref
305 void                  hls_variant_stream_unref (GstHLSVariantStream * stream);
306
307 /**
308  * GstHLSMasterPlaylist:
309  *
310  * Official term in RFC : "A Playlist is either a Media Playlist or a Master
311  * Playlist."
312  *
313  * This is the top-level object, constructed by a manifest provided by external
314  * means.
315  */
316 struct _GstHLSMasterPlaylist
317 {
318   /* Available variant streams, sorted by bitrate (low -> high) */
319   GList    *variants;           /* GstHLSVariantStream */
320   GList    *iframe_variants;    /* GstHLSVariantStream */
321
322   /* Default variant, first in the list (originally, before sorting) */
323   GstHLSVariantStream *default_variant;
324
325   /* Full list of Available Alternative Rendition (GstHLSRenditionStream) */
326   GList    *renditions;
327
328   /* EXT-X-VERSION. 0 if unspecified */
329   gint      version;
330
331   /* TRUE if this playlist is a simple media playlist (and not a master
332    * playlist). Implies that there is only a single variant and no alternate
333    * rendition groups */
334   gboolean  is_simple;
335
336   /* TRUE if all variants have codecs specified */
337   gboolean have_codecs;
338
339   /*< private > */
340   gchar   *last_data;           /* Copy of the incoming data that created this master playlist */
341
342   gint      refcount;                    /* ATOMIC */
343 };
344
345 /* Notes: #define are to avoid symbol clashes with legacy hlsdemux */
346
347 #define gst_hls_master_playlist_new_from_data hls_master_playlist_new_from_data
348 GstHLSMasterPlaylist * hls_master_playlist_new_from_data (gchar       * data,
349                                                           const gchar * base_uri);
350
351 #define gst_hls_master_playlist_get_variant_for_bitrate hls_master_playlist_get_variant_for_bitrate
352 GstHLSVariantStream *  hls_master_playlist_get_variant_for_bitrate (GstHLSMasterPlaylist * playlist,
353                                                                     GstHLSVariantStream  * current_variant,
354                                                                     guint                  bitrate,
355                                                                     guint                  min_bitrate);
356
357 #define gst_hls_master_playlist_get_common_caps hls_master_playlist_get_common_caps
358 GstCaps *              hls_master_playlist_get_common_caps (GstHLSMasterPlaylist *playlist);
359
360 #define gst_hls_master_playlist_unref hls_master_playlist_unref
361 void                   hls_master_playlist_unref (GstHLSMasterPlaylist * playlist);
362
363
364 /* Time Mapping
365  *
366  * Used to map GStreamer times to internal segment timestamps
367  */
368 struct _GstHLSTimeMap {
369   /* DISCONT SEQUENCE NUMBER */
370   gint64 dsn;
371
372   /* The stream time (used for gst timestamps, gst segments, seeking ...) */
373   GstClockTime stream_time;
374
375   /* The optional Program Date Time reference */
376   GDateTime *pdt;
377
378   /* The internal time (ex: mpeg-ts PTS) */
379   GstClockTime internal_time;
380 };
381
382 GstStreamType          gst_stream_type_from_hls_type (GstHLSRenditionStreamType stype);
383 GstStreamType          gst_hls_get_stream_type_from_structure (GstStructure *structure);
384 GstStreamType          gst_hls_get_stream_type_from_caps (GstCaps *caps);
385
386 G_END_DECLS
387
388 #endif /* __M3U8_H__ */