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