[vlc-commits] demux: adaptive: refactor keys storage

Francois Cartegnie git at videolan.org
Thu May 9 18:36:58 CEST 2019


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Apr 18 09:19:25 2019 +0200| [3c61fabf7cf97b1a5a7ebdd1a4452206575bfb10] | committer: Francois Cartegnie

demux: adaptive: refactor keys storage

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=3c61fabf7cf97b1a5a7ebdd1a4452206575bfb10
---

 modules/demux/Makefile.am                     |  2 +
 modules/demux/adaptive/SharedResources.cpp    |  8 +++
 modules/demux/adaptive/SharedResources.hpp    |  8 +++
 modules/demux/adaptive/encryption/Keyring.cpp | 87 +++++++++++++++++++++++++++
 modules/demux/adaptive/encryption/Keyring.hpp | 58 ++++++++++++++++++
 modules/demux/hls/playlist/M3U8.cpp           | 37 ------------
 modules/demux/hls/playlist/M3U8.hpp           | 15 -----
 modules/demux/hls/playlist/Parser.cpp         |  6 +-
 8 files changed, 167 insertions(+), 54 deletions(-)

diff --git a/modules/demux/Makefile.am b/modules/demux/Makefile.am
index 891c6171b9..fa049f8675 100644
--- a/modules/demux/Makefile.am
+++ b/modules/demux/Makefile.am
@@ -321,6 +321,8 @@ libadaptive_plugin_la_SOURCES = \
     demux/adaptive/playlist/Templates.hpp \
     demux/adaptive/encryption/CommonEncryption.cpp \
     demux/adaptive/encryption/CommonEncryption.hpp \
+    demux/adaptive/encryption/Keyring.cpp \
+    demux/adaptive/encryption/Keyring.hpp \
     demux/adaptive/logic/AbstractAdaptationLogic.cpp \
     demux/adaptive/logic/AbstractAdaptationLogic.h \
     demux/adaptive/logic/AlwaysBestAdaptationLogic.cpp \
diff --git a/modules/demux/adaptive/SharedResources.cpp b/modules/demux/adaptive/SharedResources.cpp
index 65016a6843..0b6e323151 100644
--- a/modules/demux/adaptive/SharedResources.cpp
+++ b/modules/demux/adaptive/SharedResources.cpp
@@ -23,6 +23,7 @@
 
 #include "SharedResources.hpp"
 #include "http/AuthStorage.hpp"
+#include "encryption/Keyring.hpp"
 
 #include <vlc_common.h>
 
@@ -31,10 +32,12 @@ using namespace adaptive;
 SharedResources::SharedResources(vlc_object_t *obj)
 {
     authStorage = new AuthStorage(obj);
+    encryptionKeyring = new Keyring(obj);
 }
 
 SharedResources::~SharedResources()
 {
+    delete encryptionKeyring;
     delete authStorage;
 }
 
@@ -42,3 +45,8 @@ AuthStorage * SharedResources::getAuthStorage()
 {
     return authStorage;
 }
+
+Keyring * SharedResources::getKeyring()
+{
+    return encryptionKeyring;
+}
diff --git a/modules/demux/adaptive/SharedResources.hpp b/modules/demux/adaptive/SharedResources.hpp
index b2fb9316cf..2a63578e3b 100644
--- a/modules/demux/adaptive/SharedResources.hpp
+++ b/modules/demux/adaptive/SharedResources.hpp
@@ -29,7 +29,13 @@ namespace adaptive
         class AuthStorage;
     }
 
+    namespace encryption
+    {
+        class Keyring;
+    }
+
     using namespace http;
+    using namespace encryption;
 
     class SharedResources
     {
@@ -37,9 +43,11 @@ namespace adaptive
             SharedResources(vlc_object_t *);
             ~SharedResources();
             AuthStorage *getAuthStorage();
+            Keyring     *getKeyring();
 
         private:
             AuthStorage *authStorage;
+            Keyring *encryptionKeyring;
     };
 }
 
diff --git a/modules/demux/adaptive/encryption/Keyring.cpp b/modules/demux/adaptive/encryption/Keyring.cpp
new file mode 100644
index 0000000000..68e2f25daf
--- /dev/null
+++ b/modules/demux/adaptive/encryption/Keyring.cpp
@@ -0,0 +1,87 @@
+/*****************************************************************************
+ * Keyring.cpp
+ *****************************************************************************
+ * Copyright (C) 2019 VideoLabs, VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "Keyring.hpp"
+#include "../http/AuthStorage.hpp"
+#include "../tools/Retrieve.hpp"
+
+#include <vlc_block.h>
+
+#include <algorithm>
+
+using namespace adaptive::encryption;
+using namespace adaptive::http;
+
+Keyring::Keyring(vlc_object_t *obj_)
+{
+    obj = obj_;
+    vlc_mutex_init(&lock);
+}
+
+Keyring::~Keyring()
+{
+    vlc_mutex_destroy(&lock);
+}
+
+KeyringKey Keyring::getKey(AuthStorage *auth, const std::string &uri)
+{
+    KeyringKey key;
+
+    vlc_mutex_lock(&lock);
+    std::map<std::string, KeyringKey>::iterator it = keys.find(uri);
+    if(it == keys.end())
+    {
+        /* Pretty bad inside the lock */
+        block_t *p_block = Retrieve::HTTP(obj, auth, uri);
+        if(p_block)
+        {
+            if(p_block->i_buffer == 16)
+            {
+                key.resize(16);
+                memcpy(&key[0], p_block->p_buffer, 16);
+                keys.insert(std::pair<std::string, KeyringKey>(uri, key));
+                lru.push_front(uri);
+                if(lru.size() > Keyring::MAX_KEYS)
+                {
+                    keys.erase(keys.find(lru.back()));
+                    lru.pop_back();
+                }
+            }
+            block_Release(p_block);
+        }
+    }
+    else
+    {
+        std::list<std::string>::iterator it2 = std::find(lru.begin(), lru.end(), uri);
+        if(it2 != lru.begin())
+        {
+            lru.erase(it2);
+            lru.push_front(uri);
+        }
+        key = (*it).second;
+    }
+    vlc_mutex_unlock(&lock);
+
+    return key;
+}
diff --git a/modules/demux/adaptive/encryption/Keyring.hpp b/modules/demux/adaptive/encryption/Keyring.hpp
new file mode 100644
index 0000000000..192cd1d9a7
--- /dev/null
+++ b/modules/demux/adaptive/encryption/Keyring.hpp
@@ -0,0 +1,58 @@
+/*****************************************************************************
+ * Keyring.hpp
+ *****************************************************************************
+ * Copyright (C) 2019 VideoLabs, VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifndef KEYRING_H
+#define KEYRING_H
+
+#include <vlc_common.h>
+
+#include <map>
+#include <list>
+#include <vector>
+#include <string>
+
+namespace adaptive
+{
+    namespace http
+    {
+        class AuthStorage;
+    }
+
+    namespace encryption
+    {
+        typedef std::vector<unsigned char> KeyringKey;
+
+        class Keyring
+        {
+            public:
+                Keyring(vlc_object_t *);
+                ~Keyring();
+                KeyringKey getKey(http::AuthStorage *, const std::string &);
+
+            private:
+                static const int MAX_KEYS = 50;
+                std::map<std::string, KeyringKey> keys;
+                std::list<std::string> lru;
+                vlc_object_t *obj;
+                vlc_mutex_t lock;
+        };
+    }
+}
+
+#endif
diff --git a/modules/demux/hls/playlist/M3U8.cpp b/modules/demux/hls/playlist/M3U8.cpp
index db61ba2495..39843a3e39 100644
--- a/modules/demux/hls/playlist/M3U8.cpp
+++ b/modules/demux/hls/playlist/M3U8.cpp
@@ -25,11 +25,6 @@
 #include "Representation.hpp"
 #include "../adaptive/playlist/BasePeriod.h"
 #include "../adaptive/playlist/BaseAdaptationSet.h"
-#include "../adaptive/tools/Retrieve.hpp"
-
-#include <vlc_common.h>
-#include <vlc_stream.h>
-#include <vlc_block.h>
 
 using namespace hls::playlist;
 
@@ -37,42 +32,10 @@ M3U8::M3U8 (vlc_object_t *p_object) :
     AbstractPlaylist(p_object)
 {
     minUpdatePeriod.Set( VLC_TICK_FROM_SEC(5) );
-    vlc_mutex_init(&keystore_lock);
 }
 
 M3U8::~M3U8()
 {
-    vlc_mutex_destroy(&keystore_lock);
-}
-
-std::vector<uint8_t> M3U8::getEncryptionKey(AuthStorage *auth, const std::string &uri)
-{
-    std::vector<uint8_t> key;
-
-    vlc_mutex_lock( &keystore_lock );
-    std::map<std::string, std::vector<uint8_t> >::iterator it = keystore.find(uri);
-    if(it == keystore.end())
-    {
-        /* Pretty bad inside the lock */
-        block_t *p_block = Retrieve::HTTP(p_object, auth, uri);
-        if(p_block)
-        {
-            if(p_block->i_buffer == 16)
-            {
-                key.resize(16);
-                memcpy(&key[0], p_block->p_buffer, 16);
-                keystore.insert(std::pair<std::string, std::vector<uint8_t> >(uri, key));
-            }
-            block_Release(p_block);
-        }
-    }
-    else
-    {
-        key = (*it).second;
-    }
-    vlc_mutex_unlock(&keystore_lock);
-
-    return key;
 }
 
 bool M3U8::isLive() const
diff --git a/modules/demux/hls/playlist/M3U8.hpp b/modules/demux/hls/playlist/M3U8.hpp
index f019044fbc..823f2b2da1 100644
--- a/modules/demux/hls/playlist/M3U8.hpp
+++ b/modules/demux/hls/playlist/M3U8.hpp
@@ -22,23 +22,12 @@
 #define M3U8_H_
 
 #include "../adaptive/playlist/AbstractPlaylist.hpp"
-#include <vlc_threads.h>
-#include <map>
-
-namespace adaptive
-{
-    namespace http
-    {
-        class AuthStorage;
-    }
-}
 
 namespace hls
 {
     namespace playlist
     {
         using namespace adaptive::playlist;
-        using namespace adaptive::http;
 
         class M3U8 : public AbstractPlaylist
         {
@@ -46,15 +35,11 @@ namespace hls
                 M3U8(vlc_object_t *);
                 virtual ~M3U8();
 
-                std::vector<uint8_t>            getEncryptionKey(AuthStorage *auth,
-                                                                 const std::string &);
                 virtual bool                    isLive() const;
                 virtual void                    debug();
 
             private:
                 std::string data;
-                vlc_mutex_t keystore_lock;
-                std::map<std::string, std::vector<uint8_t> > keystore;
         };
     }
 }
diff --git a/modules/demux/hls/playlist/Parser.cpp b/modules/demux/hls/playlist/Parser.cpp
index a5c62220a0..e3e698d747 100644
--- a/modules/demux/hls/playlist/Parser.cpp
+++ b/modules/demux/hls/playlist/Parser.cpp
@@ -28,6 +28,7 @@
 #include "../adaptive/playlist/BasePeriod.h"
 #include "../adaptive/playlist/BaseAdaptationSet.h"
 #include "../adaptive/playlist/SegmentList.h"
+#include "../adaptive/encryption/Keyring.hpp"
 #include "../adaptive/tools/Retrieve.hpp"
 #include "../adaptive/tools/Helper.h"
 #include "../adaptive/tools/Conversions.hpp"
@@ -325,8 +326,9 @@ void M3U8Parser::parseSegments(vlc_object_t *, Representation *rep, const std::l
 
                     M3U8 *m3u8 = dynamic_cast<M3U8 *>(rep->getPlaylist());
                     if(likely(m3u8))
-                        encryption.key = m3u8->getEncryptionKey(resources->getAuthStorage(),
-                                                                keyurl.toString());
+                        encryption.key = resources->getKeyring()->getKey(
+                                            resources->getAuthStorage(),
+                                            keyurl.toString());
                     if(keytag->getAttributeByName("IV"))
                     {
                         encryption.iv.clear();



More information about the vlc-commits mailing list