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