• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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