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 * gsthlsdemux.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 25 #ifndef __GST_HLS_DEMUX_H__ 26 #define __GST_HLS_DEMUX_H__ 27 28 #include <gst/gst.h> 29 #include "m3u8.h" 30 #include <gst/adaptivedemux/gstadaptivedemux.h> 31 32 #ifdef OHOS_EXT_FUNC 33 // ohos.ext.func.0013 34 #undef HAVE_OPENSSL 35 #undef HAVE_NETTLE 36 #undef HAVE_LIBGCRYPT 37 #endif 38 39 #if defined(HAVE_OPENSSL) 40 #include <openssl/evp.h> 41 #elif defined(HAVE_NETTLE) 42 #include <nettle/aes.h> 43 #include <nettle/cbc.h> 44 #elif defined(HAVE_LIBGCRYPT) 45 #include <gcrypt.h> 46 #endif 47 48 G_BEGIN_DECLS 49 50 #define GST_TYPE_HLS_DEMUX \ 51 (gst_hls_demux_get_type()) 52 #define GST_HLS_DEMUX(obj) \ 53 (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_HLS_DEMUX,GstHLSDemux)) 54 #define GST_HLS_DEMUX_CLASS(klass) \ 55 (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_HLS_DEMUX,GstHLSDemuxClass)) 56 #define GST_IS_HLS_DEMUX(obj) \ 57 (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_HLS_DEMUX)) 58 #define GST_IS_HLS_DEMUX_CLASS(klass) \ 59 (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_HLS_DEMUX)) 60 #define GST_HLS_DEMUX_GET_CLASS(obj) \ 61 (G_TYPE_INSTANCE_GET_CLASS ((obj),GST_TYPE_HLS_DEMUX,GstHLSDemuxClass)) 62 #define GST_HLS_DEMUX_CAST(obj) \ 63 ((GstHLSDemux *)obj) 64 65 typedef struct _GstHLSDemux GstHLSDemux; 66 typedef struct _GstHLSDemuxClass GstHLSDemuxClass; 67 typedef struct _GstHLSDemuxStream GstHLSDemuxStream; 68 typedef struct _GstHLSTSReader GstHLSTSReader; 69 70 #define GST_HLS_DEMUX_STREAM_CAST(stream) ((GstHLSDemuxStream *)(stream)) 71 72 typedef enum { 73 GST_HLS_TSREADER_NONE, 74 GST_HLS_TSREADER_MPEGTS, 75 GST_HLS_TSREADER_ID3 76 } GstHLSTSReaderType; 77 78 struct _GstHLSTSReader 79 { 80 GstHLSTSReaderType rtype; 81 gboolean have_id3; 82 83 gint packet_size; 84 gint pmt_pid; 85 gint pcr_pid; 86 87 GstClockTime last_pcr; 88 GstClockTime first_pcr; 89 }; 90 91 struct _GstHLSDemuxStream 92 { 93 GstAdaptiveDemuxStream adaptive_demux_stream; 94 95 GstHLSTSReaderType stream_type; 96 97 GstM3U8 *playlist; 98 gboolean is_primary_playlist; 99 100 gboolean do_typefind; /* Whether we need to typefind the next buffer */ 101 GstBuffer *pending_typefind_buffer; /* for collecting data until typefind succeeds */ 102 103 GstAdapter *pending_encrypted_data; /* for chunking data into 16 byte multiples for decryption */ 104 GstBuffer *pending_decrypted_buffer; /* last decrypted buffer for pkcs7 unpadding. 105 We only know that it is the last at EOS */ 106 guint64 current_offset; /* offset we're currently at */ 107 gboolean reset_pts; 108 109 /* decryption tooling */ 110 #if defined(HAVE_OPENSSL) 111 # if OPENSSL_VERSION_NUMBER < 0x10100000L 112 EVP_CIPHER_CTX aes_ctx; 113 # else 114 EVP_CIPHER_CTX *aes_ctx; 115 # endif 116 #elif defined(HAVE_NETTLE) 117 struct CBC_CTX (struct aes128_ctx, AES_BLOCK_SIZE) aes_ctx; 118 #elif defined(HAVE_LIBGCRYPT) 119 gcry_cipher_hd_t aes_ctx; 120 #endif 121 122 gchar *current_key; 123 guint8 *current_iv; 124 125 /* Accumulator for reading PAT/PMT/PCR from 126 * the stream so we can set timestamps/segments 127 * and switch cleanly */ 128 GstBuffer *pending_pcr_buffer; 129 130 GstHLSTSReader tsreader; 131 }; 132 133 typedef struct { 134 guint8 data[16]; 135 } GstHLSKey; 136 137 /** 138 * GstHLSDemux: 139 * 140 * Opaque #GstHLSDemux data structure. 141 */ 142 struct _GstHLSDemux 143 { 144 GstAdaptiveDemux parent; 145 146 gint srcpad_counter; 147 148 /* Decryption key cache: url => GstHLSKey */ 149 GHashTable *keys; 150 GMutex keys_lock; 151 152 /* FIXME: check locking, protected automatically by manifest_lock already? */ 153 /* The master playlist with the available variant streams */ 154 GstHLSMasterPlaylist *master; 155 156 GstHLSVariantStream *current_variant; 157 /* The previous variant, used to transition streams over */ 158 GstHLSVariantStream *previous_variant; 159 160 gboolean streams_aware; 161 }; 162 163 struct _GstHLSDemuxClass 164 { 165 GstAdaptiveDemuxClass parent_class; 166 }; 167 168 169 void gst_hlsdemux_tsreader_init (GstHLSTSReader *r); 170 void gst_hlsdemux_tsreader_set_type (GstHLSTSReader *r, GstHLSTSReaderType rtype); 171 172 gboolean gst_hlsdemux_tsreader_find_pcrs (GstHLSTSReader *r, GstBuffer **buffer, 173 GstClockTime *first_pcr, GstClockTime *last_pcr, GstTagList **tags); 174 175 GType gst_hls_demux_get_type (void); 176 177 G_END_DECLS 178 #endif /* __GST_HLS_DEMUX_H__ */ 179