Merge branch 'tizen' into tizen_gst_1.19.2
[platform/upstream/gstreamer.git] / ext / hls / gsthlsdemux.h
index da02529..16bcaf3 100644 (file)
@@ -1,6 +1,7 @@
 /* GStreamer
  * Copyright (C) 2010 Marc-Andre Lureau <marcandre.lureau@gmail.com>
  * Copyright (C) 2010 Andoni Morales Alastruey <ylatuya@gmail.com>
+ * Copyright (C) 2015 Tim-Philipp Müller <tim@centricular.com>
  *
  * gsthlsdemux.h:
  *
 
 #include <gst/gst.h>
 #include "m3u8.h"
-#include "gsthls.h"
 #include <gst/adaptivedemux/gstadaptivedemux.h>
 #if defined(HAVE_OPENSSL)
 #include <openssl/evp.h>
 #elif defined(HAVE_NETTLE)
 #include <nettle/aes.h>
 #include <nettle/cbc.h>
-#else
+#elif defined(HAVE_LIBGCRYPT)
 #include <gcrypt.h>
 #endif
 
@@ -57,12 +57,37 @@ G_BEGIN_DECLS
 typedef struct _GstHLSDemux GstHLSDemux;
 typedef struct _GstHLSDemuxClass GstHLSDemuxClass;
 typedef struct _GstHLSDemuxStream GstHLSDemuxStream;
+typedef struct _GstHLSTSReader GstHLSTSReader;
 
 #define GST_HLS_DEMUX_STREAM_CAST(stream) ((GstHLSDemuxStream *)(stream))
 
+typedef enum {
+  GST_HLS_TSREADER_NONE,
+  GST_HLS_TSREADER_MPEGTS,
+  GST_HLS_TSREADER_ID3
+} GstHLSTSReaderType;
+
+struct _GstHLSTSReader
+{
+  GstHLSTSReaderType rtype;
+  gboolean have_id3;
+
+  gint packet_size;
+  gint pmt_pid;
+  gint pcr_pid;
+
+  GstClockTime last_pcr;
+  GstClockTime first_pcr;
+};
+
 struct _GstHLSDemuxStream
 {
-  GstAdaptiveDemux adaptive_demux_stream;
+  GstAdaptiveDemuxStream adaptive_demux_stream;
+
+  GstHLSTSReaderType stream_type;
+
+  GstM3U8 *playlist;
+  gboolean is_primary_playlist;
 
   gboolean do_typefind;         /* Whether we need to typefind the next buffer */
   GstBuffer *pending_typefind_buffer; /* for collecting data until typefind succeeds */
@@ -72,8 +97,41 @@ struct _GstHLSDemuxStream
                                           We only know that it is the last at EOS */
   guint64 current_offset;              /* offset we're currently at */
   gboolean reset_pts;
+#ifdef TIZEN_FEATURE_HLSDEMUX_DISCONT
+  GstClockTime sequence_pos;
+  GstClockTime last_pcr;
+#endif
+
+  /* decryption tooling */
+#if defined(HAVE_OPENSSL)
+# if OPENSSL_VERSION_NUMBER < 0x10100000L
+  EVP_CIPHER_CTX aes_ctx;
+# else
+  EVP_CIPHER_CTX *aes_ctx;
+# endif
+#elif defined(HAVE_NETTLE)
+  struct CBC_CTX (struct aes128_ctx, AES_BLOCK_SIZE) aes_ctx;
+#elif defined(HAVE_LIBGCRYPT)
+  gcry_cipher_hd_t aes_ctx;
+#endif
+
+  gchar     *current_key;
+  guint8    *current_iv;
+
+  /* Accumulator for reading PAT/PMT/PCR from
+   * the stream so we can set timestamps/segments
+   * and switch cleanly */
+  GstBuffer *pending_pcr_buffer;
+#ifdef TIZEN_FEATURE_HLSDEMUX_DISCONT_SEQUENCE
+  gint failed_count;
+#endif
+  GstHLSTSReader tsreader;
 };
 
+typedef struct {
+  guint8 data[16];
+} GstHLSKey;
+
 /**
  * GstHLSDemux:
  *
@@ -85,23 +143,19 @@ struct _GstHLSDemux
 
   gint srcpad_counter;
 
-  gchar *uri;                   /* Original playlist URI */
-  GstM3U8Client *client;        /* M3U8 client */
+  /* Decryption key cache: url => GstHLSKey */
+  GHashTable *keys;
+  GMutex      keys_lock;
 
-  /* Cache for the last key */
-  gchar *key_url;
-  GstFragment *key_fragment;
+  /* FIXME: check locking, protected automatically by manifest_lock already? */
+  /* The master playlist with the available variant streams */
+  GstHLSMasterPlaylist *master;
 
-  /* decryption tooling */
-#if defined(HAVE_OPENSSL)
-  EVP_CIPHER_CTX aes_ctx;
-#elif defined(HAVE_NETTLE)
-  struct CBC_CTX (struct aes_ctx, AES_BLOCK_SIZE) aes_ctx;
-#else
-  gcry_cipher_hd_t aes_ctx;
-#endif
-  gchar *current_key;
-  guint8 *current_iv;
+  GstHLSVariantStream  *current_variant;
+  /* The previous variant, used to transition streams over */
+  GstHLSVariantStream  *previous_variant;
+
+  gboolean streams_aware;
 };
 
 struct _GstHLSDemuxClass
@@ -109,6 +163,13 @@ struct _GstHLSDemuxClass
   GstAdaptiveDemuxClass parent_class;
 };
 
+
+void gst_hlsdemux_tsreader_init (GstHLSTSReader *r);
+void gst_hlsdemux_tsreader_set_type (GstHLSTSReader *r, GstHLSTSReaderType rtype);
+
+gboolean gst_hlsdemux_tsreader_find_pcrs (GstHLSTSReader *r, GstBuffer **buffer,
+    GstClockTime *first_pcr, GstClockTime *last_pcr, GstTagList **tags);
+
 GType gst_hls_demux_get_type (void);
 
 G_END_DECLS