diff --git a/packager/app/packager_main.cc b/packager/app/packager_main.cc index f1d9eb6c0f..b8308c3950 100644 --- a/packager/app/packager_main.cc +++ b/packager/app/packager_main.cc @@ -268,18 +268,17 @@ bool ParseAdCues(const std::string& ad_cues, std::vector* cuepoints) { return true; } -bool ParseProtectionSystems( - const std::string& protection_systems_str, - std::vector* protection_systems) { - protection_systems->clear(); +bool ParseProtectionSystems(const std::string& protection_systems_str, + ProtectionSystem* protection_systems) { + *protection_systems = ProtectionSystem::kNone; - std::map mapping = { - {"common", EncryptionParams::ProtectionSystem::kCommonSystem}, - {"commonsystem", EncryptionParams::ProtectionSystem::kCommonSystem}, - {"fairplay", EncryptionParams::ProtectionSystem::kFairPlay}, - {"marlin", EncryptionParams::ProtectionSystem::kMarlin}, - {"playready", EncryptionParams::ProtectionSystem::kPlayReady}, - {"widevine", EncryptionParams::ProtectionSystem::kWidevine}, + std::map mapping = { + {"common", ProtectionSystem::kCommon}, + {"commonsystem", ProtectionSystem::kCommon}, + {"fairplay", ProtectionSystem::kFairPlay}, + {"marlin", ProtectionSystem::kMarlin}, + {"playready", ProtectionSystem::kPlayReady}, + {"widevine", ProtectionSystem::kWidevine}, }; for (const std::string& protection_system : @@ -291,7 +290,7 @@ bool ParseProtectionSystems( << protection_system; return false; } - protection_systems->push_back(iter->second); + *protection_systems |= iter->second; } return true; } diff --git a/packager/app/packager_util.cc b/packager/app/packager_util.cc index afa70c50d8..4bbc498edc 100644 --- a/packager/app/packager_util.cc +++ b/packager/app/packager_util.cc @@ -42,39 +42,11 @@ std::unique_ptr CreateSigner(const WidevineSigner& signer) { return request_signer; } -int GetProtectionSystemsFlag( - const std::vector& protection_systems) { - int protection_systems_flags = 0; - for (const auto protection_system : protection_systems) { - switch (protection_system) { - case EncryptionParams::ProtectionSystem::kCommonSystem: - protection_systems_flags |= COMMON_PROTECTION_SYSTEM_FLAG; - break; - case EncryptionParams::ProtectionSystem::kFairPlay: - protection_systems_flags |= FAIRPLAY_PROTECTION_SYSTEM_FLAG; - break; - case EncryptionParams::ProtectionSystem::kMarlin: - protection_systems_flags |= MARLIN_PROTECTION_SYSTEM_FLAG; - break; - case EncryptionParams::ProtectionSystem::kPlayReady: - protection_systems_flags |= PLAYREADY_PROTECTION_SYSTEM_FLAG; - break; - case EncryptionParams::ProtectionSystem::kWidevine: - protection_systems_flags |= WIDEVINE_PROTECTION_SYSTEM_FLAG; - break; - } - } - return protection_systems_flags; -} - } // namespace std::unique_ptr CreateEncryptionKeySource( FourCC protection_scheme, const EncryptionParams& encryption_params) { - int protection_systems_flags = - GetProtectionSystemsFlag(encryption_params.protection_systems); - std::unique_ptr encryption_key_source; switch (encryption_params.key_provider) { case KeyProvider::kWidevine: { @@ -89,7 +61,8 @@ std::unique_ptr CreateEncryptionKeySource( } std::unique_ptr widevine_key_source( new WidevineKeySource(widevine.key_server_url, - protection_systems_flags, protection_scheme)); + encryption_params.protection_systems, + protection_scheme)); if (!widevine.signer.signer_name.empty()) { std::unique_ptr request_signer( CreateSigner(widevine.signer)); @@ -112,9 +85,9 @@ std::unique_ptr CreateEncryptionKeySource( break; } case KeyProvider::kRawKey: { - encryption_key_source = - RawKeySource::Create(encryption_params.raw_key, - protection_systems_flags, protection_scheme); + encryption_key_source = RawKeySource::Create( + encryption_params.raw_key, encryption_params.protection_systems, + protection_scheme); break; } case KeyProvider::kPlayReady: { @@ -141,10 +114,10 @@ std::unique_ptr CreateEncryptionKeySource( playready.key_server_url, playready.client_cert_file, playready.client_cert_private_key_file, playready.client_cert_private_key_password, - protection_systems_flags, protection_scheme)); + encryption_params.protection_systems, protection_scheme)); } else { playready_key_source.reset(new PlayReadyKeySource( - playready.key_server_url, protection_systems_flags, + playready.key_server_url, encryption_params.protection_systems, protection_scheme)); } if (!playready.ca_file.empty()) { @@ -164,7 +137,7 @@ std::unique_ptr CreateEncryptionKeySource( } break; } - case KeyProvider::kNone: + default: break; } return encryption_key_source; @@ -183,7 +156,7 @@ std::unique_ptr CreateDecryptionKeySource( std::unique_ptr widevine_key_source( new WidevineKeySource( widevine.key_server_url, - WIDEVINE_PROTECTION_SYSTEM_FLAG /* value does not matter here */, + ProtectionSystem::kWidevine /* value does not matter here */, FOURCC_NULL /* value does not matter here */)); if (!widevine.signer.signer_name.empty()) { std::unique_ptr request_signer( @@ -199,12 +172,11 @@ std::unique_ptr CreateDecryptionKeySource( case KeyProvider::kRawKey: { decryption_key_source = RawKeySource::Create( decryption_params.raw_key, - COMMON_PROTECTION_SYSTEM_FLAG /* value does not matter here */, + ProtectionSystem::kCommon /* value does not matter here */, FOURCC_NULL /* value does not matter here */); break; } - case KeyProvider::kNone: - case KeyProvider::kPlayReady: + default: break; } return decryption_key_source; diff --git a/packager/media/base/key_source.cc b/packager/media/base/key_source.cc index 6679f91088..bbbec69a68 100644 --- a/packager/media/base/key_source.cc +++ b/packager/media/base/key_source.cc @@ -16,28 +16,29 @@ namespace shaka { namespace media { -KeySource::KeySource(int protection_systems_flags, FourCC protection_scheme) { - if (protection_systems_flags & COMMON_PROTECTION_SYSTEM_FLAG) { +KeySource::KeySource(ProtectionSystem protection_systems, + FourCC protection_scheme) { + if (has_flag(protection_systems, ProtectionSystem::kCommon)) { pssh_generators_.emplace_back(new CommonPsshGenerator()); } - if (protection_systems_flags & PLAYREADY_PROTECTION_SYSTEM_FLAG) { + if (has_flag(protection_systems, ProtectionSystem::kPlayReady)) { pssh_generators_.emplace_back( new PlayReadyPsshGenerator(protection_scheme)); } - if (protection_systems_flags & WIDEVINE_PROTECTION_SYSTEM_FLAG) { + if (has_flag(protection_systems, ProtectionSystem::kWidevine)) { pssh_generators_.emplace_back(new WidevinePsshGenerator(protection_scheme)); } - if (protection_systems_flags & FAIRPLAY_PROTECTION_SYSTEM_FLAG) { + if (has_flag(protection_systems, ProtectionSystem::kFairPlay)) { no_pssh_systems_.emplace_back(std::begin(kFairPlaySystemId), std::end(kFairPlaySystemId)); } // We only support Marlin Adaptive Streaming Specification – Simple Profile // with Implicit Content ID Mapping, which does not need a PSSH. Marlin // specific PSSH with Explicit Content ID Mapping is not generated. - if (protection_systems_flags & MARLIN_PROTECTION_SYSTEM_FLAG) { + if (has_flag(protection_systems, ProtectionSystem::kMarlin)) { no_pssh_systems_.emplace_back(std::begin(kMarlinSystemId), std::end(kMarlinSystemId)); } diff --git a/packager/media/base/key_source.h b/packager/media/base/key_source.h index 7523186a86..3c4da0ec15 100644 --- a/packager/media/base/key_source.h +++ b/packager/media/base/key_source.h @@ -47,7 +47,7 @@ typedef std::map> EncryptionKeyMap; /// KeySource is responsible for encryption key acquisition. class KeySource { public: - KeySource(int protection_systems_flags, FourCC protection_scheme); + KeySource(ProtectionSystem protection_systems, FourCC protection_scheme); virtual ~KeySource(); diff --git a/packager/media/base/playready_key_source.cc b/packager/media/base/playready_key_source.cc index bc30a2ead7..e80a750a5c 100644 --- a/packager/media/base/playready_key_source.cc +++ b/packager/media/base/playready_key_source.cc @@ -63,16 +63,16 @@ bool Base64StringToBytes(const std::string& base64_string, } PlayReadyKeySource::PlayReadyKeySource(const std::string& server_url, - int protection_system_flags, + ProtectionSystem protection_systems, FourCC protection_scheme) // PlayReady PSSH is retrived from PlayReady server response. - : KeySource(protection_system_flags & ~PLAYREADY_PROTECTION_SYSTEM_FLAG, + : KeySource(protection_systems & ~ProtectionSystem::kPlayReady, protection_scheme), generate_playready_protection_system_( // Generate PlayReady protection system if there are no other // protection system specified. - protection_system_flags == NO_PROTECTION_SYSTEM_FLAG || - protection_system_flags & PLAYREADY_PROTECTION_SYSTEM_FLAG), + protection_systems == ProtectionSystem::kNone || + has_flag(protection_systems, ProtectionSystem::kPlayReady)), encryption_key_(new EncryptionKey), server_url_(server_url) {} @@ -81,10 +81,10 @@ PlayReadyKeySource::PlayReadyKeySource( const std::string& client_cert_file, const std::string& client_cert_private_key_file, const std::string& client_cert_private_key_password, - int protection_system_flags, + ProtectionSystem protection_systems, FourCC protection_scheme) // PlayReady PSSH is retrived from PlayReady server response. - : KeySource(protection_system_flags & ~PLAYREADY_PROTECTION_SYSTEM_FLAG, + : KeySource(protection_systems & ~ProtectionSystem::kPlayReady, protection_scheme), encryption_key_(new EncryptionKey), server_url_(server_url), diff --git a/packager/media/base/playready_key_source.h b/packager/media/base/playready_key_source.h index 058ed3995d..6f0e79a1e7 100644 --- a/packager/media/base/playready_key_source.h +++ b/packager/media/base/playready_key_source.h @@ -21,13 +21,13 @@ class PlayReadyKeySource : public KeySource { public: /// Creates a new PlayReadyKeySource from the given packaging information. /// @param server_url PlayReady packaging server url. - /// @param protection_systems_flags is the flags indicating which PSSH should + /// @param protection_systems is the enum indicating which PSSH should /// be included. /// @param protection_scheme is the Protection Scheme to be used for /// encryption. It needs to be signalled in Widevine PSSH. This /// argument can be ignored if Widevine PSSH is not generated. PlayReadyKeySource(const std::string& server_url, - int protection_systems_flags, + ProtectionSystem protection_systems, FourCC protection_scheme); /// Creates a new PlayReadyKeySource from the given packaging information. /// @param server_url PlayReady packaging server url. @@ -35,7 +35,7 @@ class PlayReadyKeySource : public KeySource { /// @param client_cert_private_key_file absolute path to the private file /// for the client certificate. /// @param client_cert_private_key_password password for the private key. - /// @param protection_systems_flags is the flags indicating which PSSH should + /// @param protection_systems is the enum indicating which PSSH should /// be included. /// @param protection_scheme is the Protection Scheme to be used for /// encryption. It needs to be signalled in Widevine PSSH. This @@ -44,7 +44,7 @@ class PlayReadyKeySource : public KeySource { const std::string& client_cert_file, const std::string& client_cert_private_key_file, const std::string& client_cert_private_key_password, - int protection_systems_flags, + ProtectionSystem protection_systems, FourCC protection_scheme); ~PlayReadyKeySource() override; diff --git a/packager/media/base/protection_system_specific_info.h b/packager/media/base/protection_system_specific_info.h index 6df39458c2..8ae438a2dc 100644 --- a/packager/media/base/protection_system_specific_info.h +++ b/packager/media/base/protection_system_specific_info.h @@ -12,13 +12,7 @@ #include #include "packager/base/logging.h" - -#define NO_PROTECTION_SYSTEM_FLAG 0x00 -#define COMMON_PROTECTION_SYSTEM_FLAG 0x01 -#define PLAYREADY_PROTECTION_SYSTEM_FLAG 0x02 -#define WIDEVINE_PROTECTION_SYSTEM_FLAG 0x04 -#define FAIRPLAY_PROTECTION_SYSTEM_FLAG 0x08 -#define MARLIN_PROTECTION_SYSTEM_FLAG 0x10 +#include "packager/media/public/crypto_params.h" namespace shaka { namespace media { diff --git a/packager/media/base/raw_key_source.cc b/packager/media/base/raw_key_source.cc index a2a76f35d9..47ae834f06 100644 --- a/packager/media/base/raw_key_source.cc +++ b/packager/media/base/raw_key_source.cc @@ -96,9 +96,10 @@ Status RawKeySource::GetCryptoPeriodKey(uint32_t crypto_period_index, return Status::OK; } -std::unique_ptr RawKeySource::Create(const RawKeyParams& raw_key, - int protection_systems_flags, - FourCC protection_scheme) { +std::unique_ptr RawKeySource::Create( + const RawKeyParams& raw_key, + ProtectionSystem protection_systems, + FourCC protection_scheme) { std::vector key_system_info; bool pssh_provided = false; if (!raw_key.pssh.empty()) { @@ -137,22 +138,21 @@ std::unique_ptr RawKeySource::Create(const RawKeyParams& raw_key, // Generate common protection system if no other protection system is // specified. - if (!pssh_provided && protection_systems_flags == NO_PROTECTION_SYSTEM_FLAG) { - protection_systems_flags = COMMON_PROTECTION_SYSTEM_FLAG; + if (!pssh_provided && protection_systems == ProtectionSystem::kNone) { + protection_systems = ProtectionSystem::kCommon; } - return std::unique_ptr( - new RawKeySource(std::move(encryption_key_map), protection_systems_flags, - protection_scheme)); + return std::unique_ptr(new RawKeySource( + std::move(encryption_key_map), protection_systems, protection_scheme)); } RawKeySource::RawKeySource() - : KeySource(NO_PROTECTION_SYSTEM_FLAG, FOURCC_NULL) {} + : KeySource(ProtectionSystem::kNone, FOURCC_NULL) {} RawKeySource::RawKeySource(EncryptionKeyMap&& encryption_key_map, - int protection_systems_flags, + ProtectionSystem protection_systems, FourCC protection_scheme) - : KeySource(protection_systems_flags, protection_scheme), + : KeySource(protection_systems, protection_scheme), encryption_key_map_(std::move(encryption_key_map)) { UpdateProtectionSystemInfo(&encryption_key_map_); } diff --git a/packager/media/base/raw_key_source.h b/packager/media/base/raw_key_source.h index 0c6ea0b478..2646f4495c 100644 --- a/packager/media/base/raw_key_source.h +++ b/packager/media/base/raw_key_source.h @@ -38,14 +38,15 @@ class RawKeySource : public KeySource { /// Creates a new RawKeySource from the given data. Returns null /// if the parameter is malformed. /// @param raw_key contains parameters to setup the key source. - /// @param protection_systems_flags is the flags indicating which PSSH should + /// @param protection_systems is the enum indicating which PSSH should /// be included. /// @param protection_scheme is the Protection Scheme to be used for /// encryption. It needs to be signalled in Widevine PSSH. This /// argument can be ignored if Widevine PSSH is not generated. - static std::unique_ptr Create(const RawKeyParams& raw_key, - int protection_system_flags, - FourCC protection_scheme); + static std::unique_ptr Create( + const RawKeyParams& raw_key, + ProtectionSystem protection_systems, + FourCC protection_scheme); protected: // Allow default constructor for mock key sources. @@ -53,7 +54,7 @@ class RawKeySource : public KeySource { private: RawKeySource(EncryptionKeyMap&& encryption_key_map, - int protection_systems_flags, + ProtectionSystem protection_systems, FourCC protection_scheme); RawKeySource(const RawKeySource&) = delete; RawKeySource& operator=(const RawKeySource&) = delete; diff --git a/packager/media/base/raw_key_source_unittest.cc b/packager/media/base/raw_key_source_unittest.cc index 59f587c2c8..014f1f58a4 100644 --- a/packager/media/base/raw_key_source_unittest.cc +++ b/packager/media/base/raw_key_source_unittest.cc @@ -52,8 +52,6 @@ const char kDrmLabel[] = "SomeDrmLabel"; const char kAnotherDrmLabel[] = "AnotherDrmLabel"; const char kEmptyDrmLabel[] = ""; -const int kNoProtectionSystemFlag = NO_PROTECTION_SYSTEM_FLAG; - std::vector HexStringToVector(const std::string& str) { std::vector vec; CHECK(base::HexStringToBytes(str, &vec)); @@ -71,7 +69,7 @@ TEST(RawKeySourceTest, Success) { raw_key_params.pssh = HexStringToVector(std::string(kPsshBox1Hex) + kPsshBox2Hex); std::unique_ptr key_source = RawKeySource::Create( - raw_key_params, kNoProtectionSystemFlag, FOURCC_NULL); + raw_key_params, ProtectionSystem::kNone, FOURCC_NULL); ASSERT_NE(nullptr, key_source); EncryptionKey key_from_drm_label; @@ -109,7 +107,7 @@ TEST(RawKeySourceTest, EmptyPssh) { raw_key_params.key_map[kAnotherDrmLabel].key = HexStringToVector(kKey2Hex); raw_key_params.iv = HexStringToVector(kIvHex); std::unique_ptr key_source = RawKeySource::Create( - raw_key_params, kNoProtectionSystemFlag, FOURCC_NULL); + raw_key_params, ProtectionSystem::kNone, FOURCC_NULL); ASSERT_NE(nullptr, key_source); EncryptionKey key; @@ -130,13 +128,13 @@ TEST(RawKeySourceTest, Failure) { raw_key_params.pssh = HexStringToVector(kPsshBox1Hex); raw_key_params.iv = HexStringToVector(kIvHex); std::unique_ptr key_source = RawKeySource::Create( - raw_key_params, kNoProtectionSystemFlag, FOURCC_NULL); + raw_key_params, ProtectionSystem::kNone, FOURCC_NULL); EXPECT_EQ(nullptr, key_source); // Invalid pssh box. raw_key_params.key_map[kEmptyDrmLabel].key_id = HexStringToVector(kKeyIdHex); raw_key_params.pssh = HexStringToVector("000102030405"); - key_source = RawKeySource::Create(raw_key_params, kNoProtectionSystemFlag, + key_source = RawKeySource::Create(raw_key_params, ProtectionSystem::kNone, FOURCC_NULL); EXPECT_EQ(nullptr, key_source); } diff --git a/packager/media/base/widevine_key_source.cc b/packager/media/base/widevine_key_source.cc index df91b55a50..2d0326f30e 100644 --- a/packager/media/base/widevine_key_source.cc +++ b/packager/media/base/widevine_key_source.cc @@ -84,16 +84,16 @@ ProtectionSystemSpecificInfo ProtectionSystemInfoFromPsshProto( } // namespace WidevineKeySource::WidevineKeySource(const std::string& server_url, - int protection_system_flags, + ProtectionSystem protection_systems, FourCC protection_scheme) // Widevine PSSH is fetched from Widevine license server. - : KeySource(protection_system_flags & ~WIDEVINE_PROTECTION_SYSTEM_FLAG, + : KeySource(protection_systems & ~ProtectionSystem::kWidevine, protection_scheme), generate_widevine_protection_system_( // Generate Widevine protection system if there are no other // protection system specified. - protection_system_flags == NO_PROTECTION_SYSTEM_FLAG || - protection_system_flags & WIDEVINE_PROTECTION_SYSTEM_FLAG), + protection_systems == ProtectionSystem::kNone || + has_flag(protection_systems, ProtectionSystem::kWidevine)), key_production_thread_("KeyProductionThread", base::Bind(&WidevineKeySource::FetchKeysTask, base::Unretained(this))), diff --git a/packager/media/base/widevine_key_source.h b/packager/media/base/widevine_key_source.h index f28c56b856..ac16aab7f5 100644 --- a/packager/media/base/widevine_key_source.h +++ b/packager/media/base/widevine_key_source.h @@ -29,13 +29,13 @@ template class ProducerConsumerQueue; class WidevineKeySource : public KeySource { public: /// @param server_url is the Widevine common encryption server url. - /// @param protection_systems_flags is the flags indicating which PSSH should + /// @param protection_systems is the enum indicating which PSSH should /// be included. /// @param protection_scheme is the Protection Scheme to be used for /// encryption. It needs to be signalled in Widevine PSSH. This /// argument can be ignored if Widevine PSSH is not generated. WidevineKeySource(const std::string& server_url, - int protection_systems_flags, + ProtectionSystem protection_systems, FourCC protection_scheme); ~WidevineKeySource() override; diff --git a/packager/media/base/widevine_key_source_unittest.cc b/packager/media/base/widevine_key_source_unittest.cc index 8799f96839..fdc6694791 100644 --- a/packager/media/base/widevine_key_source_unittest.cc +++ b/packager/media/base/widevine_key_source_unittest.cc @@ -252,13 +252,13 @@ class WidevineKeySourceTest : public Test { } void CreateWidevineKeySource() { - int protection_system_flags = NO_PROTECTION_SYSTEM_FLAG; + ProtectionSystem protection_system = ProtectionSystem::kNone; if (add_widevine_pssh_) - protection_system_flags |= WIDEVINE_PROTECTION_SYSTEM_FLAG; + protection_system |= ProtectionSystem::kWidevine; if (add_common_pssh_) - protection_system_flags |= COMMON_PROTECTION_SYSTEM_FLAG; + protection_system |= ProtectionSystem::kCommon; widevine_key_source_.reset(new WidevineKeySource( - kServerUrl, protection_system_flags, protection_scheme_)); + kServerUrl, protection_system, protection_scheme_)); widevine_key_source_->set_key_fetcher(std::move(mock_key_fetcher_)); } diff --git a/packager/media/public/crypto_params.h b/packager/media/public/crypto_params.h index 97fff1892a..ca21f80b96 100644 --- a/packager/media/public/crypto_params.h +++ b/packager/media/public/crypto_params.h @@ -12,16 +12,53 @@ #include #include +#include "packager/status.h" + namespace shaka { -/// Encryption / decryption key providers. +/// Encryption key providers. These provide keys to decrypt the content if the +/// source content is encrypted, or used to encrypt the content. enum class KeyProvider { - kNone = 0, - kWidevine = 1, - kPlayReady = 2, - kRawKey = 3, + kNone, + kRawKey, + kWidevine, + kPlayReady, }; +/// Protection systems that handle decryption during playback. This affects the +/// protection info that is stored in the content. Multiple protection systems +/// can be combined using OR. +enum class ProtectionSystem : uint16_t { + kNone = 0, + /// The common key system from EME: https://goo.gl/s8RIhr + kCommon = (1 << 0), + kWidevine = (1 << 1), + kPlayReady = (1 << 2), + kFairPlay = (1 << 3), + kMarlin = (1 << 4), +}; + +inline ProtectionSystem operator|(ProtectionSystem a, ProtectionSystem b) { + return static_cast(static_cast(a) | + static_cast(b)); +} +inline ProtectionSystem& operator|=(ProtectionSystem& a, ProtectionSystem b) { + return a = a | b; +} +inline ProtectionSystem operator&(ProtectionSystem a, ProtectionSystem b) { + return static_cast(static_cast(a) & + static_cast(b)); +} +inline ProtectionSystem& operator&=(ProtectionSystem& a, ProtectionSystem b) { + return a = a & b; +} +inline ProtectionSystem operator~(ProtectionSystem a) { + return static_cast(~static_cast(a)); +} +inline bool has_flag(ProtectionSystem value, ProtectionSystem flag) { + return (value & flag) == flag; +} + /// Signer credential for Widevine license server. struct WidevineSigner { /// Name of the signer / content provider. @@ -115,16 +152,8 @@ struct EncryptionParams { PlayReadyEncryptionParams playready; RawKeyParams raw_key; - /// Supported protection systems. - enum class ProtectionSystem { - kCommonSystem, - kFairPlay, - kMarlin, - kPlayReady, - kWidevine, - }; - /// Protection systems to be generated. - std::vector protection_systems; + /// The protection systems to generate, multiple can be OR'd together. + ProtectionSystem protection_systems; /// Clear lead duration in seconds. double clear_lead_in_seconds = 0;