vlc | branch: master | Francois Cartegnie <[email protected]> | 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(); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
