Change --additional_protection_systems to --protection_systems

Issue: #245.

Change-Id: Ib7da3b874207623e3ee0b1a942ecb2509e750669
This commit is contained in:
KongQun Yang 2018-08-10 13:31:17 -07:00
parent c503db8e4d
commit 8612798de1
18 changed files with 120 additions and 110 deletions

View File

@ -14,8 +14,7 @@ General encryption options
Clear lead in seconds if encryption is enabled.
--additional_protection_systems
--protection_systems
Generate additional protection systems in addition to the native protection
system provided by the key source. Supported protection systems include
Protection systems to be generated. Supported protection systems include
Widevine, PlayReady, FairPlay, and CommonSystem (https://goo.gl/s8RIhr).

View File

@ -4,8 +4,8 @@ PlayReady encryption options
--enable_playready_encryption
Enable encryption with PlayReady key. This generates PlayReady protection
system. Additional protection systems can be generated with
--additional_protection_systems option.
system if --protection_systems is not specified. Use --protection_system to
generate multiple protection systems.
--playready_server_url <url>

View File

@ -5,9 +5,9 @@ Raw key encryption options
Enable encryption with raw key (keys provided in command line)). This
generates `Common protection system <https://goo.gl/s8RIhr>`_ if neither
--pssh nor --additional_protection_systems is specified. Use --pssh to
provide custom protection systems or use --additional_protection_systems to
generate protection systems automatically.
--pssh nor --protection_systems is specified. Use --pssh to provide custom
protection systems or use --protection_systems to generate protection
systems automatically.
--enable_raw_key_decryption
@ -36,5 +36,5 @@ Raw key encryption options
--pssh <hex string>
One or more concatenated PSSH boxes in hex string format. If neither this
flag nor --additional_protection_systems is specified, a
flag nor --protection_systems is specified, a
`v1 common PSSH box <https://goo.gl/s8RIhr>`_ will be generated.

View File

@ -5,9 +5,9 @@ Widevine encryption options
Enable encryption with Widevine key server. User should provide either
AES signing key (--aes_signing_key, --aes_signing_iv) or RSA signing key
(--rsa_signing_key_path). This generates Widevine protection system by
default. Additional protection systems can be generated with
--additional_protection_systems option.
(--rsa_signing_key_path). This generates Widevine protection system if
--protection_systems is not specified. Use --protection_systems to generate
multiple protection systems.
--enable_widevine_decryption

View File

@ -74,7 +74,7 @@ Widevine and PlayReady::
in=h264_high_1080p_6000.mp4,stream=video,output=h264_1080p.mp4,drm_label=HD \
--enable_raw_key_encryption \
--keys label=AUDIO:key_id=f3c5e0361e6654b28f8049c778b23946:key=a4631a153a443df9eed0593043db7519,label=SD:key_id=abba271e8bcf552bbd2e86a434a9a5d9:key=69eaa802a6763af979e8d1940fb88392,label=HD:key_id=6d76f25cb17f5e16b8eaef6bbf582d8e:key=cb541084c99731aef4fff74500c12ead \
--additional_protection_systems Widevine,PlayReady \
--protection_systems Widevine,PlayReady \
--mpd_output h264.mpd
.. note::

View File

@ -88,7 +88,7 @@ The examples below uses the H264 streams created in :doc:`encoding`.
--signer widevine_test \
--aes_signing_key 1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9 \
--aes_signing_iv d58ce954203b7c9a9a9d467f59839249 \
--additional_protection_systems PlayReady
--protection_systems Widevine,PlayReady
.. note::

View File

@ -322,9 +322,8 @@ base::Optional<PackagingParams> GetPackagingParams() {
return base::nullopt;
}
if (!ParseProtectionSystems(
FLAGS_additional_protection_systems,
&encryption_params.additional_protection_systems)) {
if (!ParseProtectionSystems(FLAGS_protection_systems,
&encryption_params.protection_systems)) {
return base::nullopt;
}

View File

@ -72,7 +72,7 @@ std::unique_ptr<KeySource> CreateEncryptionKeySource(
FourCC protection_scheme,
const EncryptionParams& encryption_params) {
int protection_systems_flags =
GetProtectionSystemsFlag(encryption_params.additional_protection_systems);
GetProtectionSystemsFlag(encryption_params.protection_systems);
std::unique_ptr<KeySource> encryption_key_source;
switch (encryption_params.key_provider) {

View File

@ -8,9 +8,8 @@
#include "packager/app/protection_system_flags.h"
DEFINE_string(additional_protection_systems,
"",
"Generate additional protection systems in addition to the "
"native protection system provided by the key source. Supported "
"protection systems include Widevine, PlayReady, FairPlay, and "
"CommonSystem (https://goo.gl/s8RIhr).");
DEFINE_string(
protection_systems,
"",
"Protection systems to be generated. Supported protection systems include "
"Widevine, PlayReady, FairPlay, and CommonSystem (https://goo.gl/s8RIhr).");

View File

@ -11,6 +11,6 @@
#include <gflags/gflags.h>
DECLARE_string(additional_protection_systems);
DECLARE_string(protection_systems);
#endif // PACKAGER_APP_PROTECTION_SYSTEM_FLAGS_H_

View File

@ -35,18 +35,15 @@ DEFINE_int32(
num_subsegments_per_sidx,
0,
"This flag is deprecated. Use --generate_sidx_in_media_segments instead.");
DEFINE_bool(
generate_widevine_pssh,
false,
"This flag is deprecated. Use --additional_protection_systems instead.");
DEFINE_bool(
generate_playready_pssh,
false,
"This flag is deprecated. Use --additional_protection_systems instead.");
DEFINE_bool(
generate_common_pssh,
false,
"This flag is deprecated. Use --additional_protection_systems instead.");
DEFINE_bool(generate_widevine_pssh,
false,
"This flag is deprecated. Use --protection_systems instead.");
DEFINE_bool(generate_playready_pssh,
false,
"This flag is deprecated. Use --protection_systems instead.");
DEFINE_bool(generate_common_pssh,
false,
"This flag is deprecated. Use --protection_systems instead.");
// The current gflags library does not provide a way to check whether a flag is
// set in command line. If a flag has a different value to its default value,
@ -86,7 +83,7 @@ bool InformRetiredPsshGenerationFlag(const char* flagname, bool value) {
if (value) {
fprintf(stderr,
"WARNING: %s is deprecated and ignored. Please switch to "
"--additional_protection_systems.\n",
"--protection_systems.\n",
flagname);
}
return true;

View File

@ -444,8 +444,7 @@ class PackagerAppTest(unittest.TestCase):
fairplay_key_uri = ('skd://www.license.com/'
'getkey?KeyId=31323334-3536-3738-3930-313233343536')
flags += [
'--additional_protection_systems=FairPlay',
'--hls_key_uri=' + fairplay_key_uri
'--protection_systems=FairPlay', '--hls_key_uri=' + fairplay_key_uri
]
if protection_scheme:
flags += ['--protection_scheme', protection_scheme]

View File

@ -68,6 +68,11 @@ PlayReadyKeySource::PlayReadyKeySource(const std::string& server_url,
// PlayReady PSSH is retrived from PlayReady server response.
: KeySource(protection_system_flags & ~PLAYREADY_PROTECTION_SYSTEM_FLAG,
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),
encryption_key_(new EncryptionKey),
server_url_(server_url) {}
@ -113,8 +118,10 @@ Status RetrieveTextInXMLElement(const std::string& element,
return Status::OK;
}
Status SetKeyInformationFromServerResponse(const std::string& response,
EncryptionKey* encryption_key) {
Status SetKeyInformationFromServerResponse(
const std::string& response,
bool generate_playready_protection_system,
EncryptionKey* encryption_key) {
// TODO(robinconnell): Currently all tracks are encrypted using the same
// key_id and key. Add the ability to retrieve multiple key_id/keys from
// the packager response and encrypt multiple tracks using differnt
@ -135,20 +142,23 @@ Status SetKeyInformationFromServerResponse(const std::string& response,
return Status(error::SERVER_ERROR, "Cannot parse key.");
}
std::string pssh_data_b64;
RETURN_IF_ERROR(RetrieveTextInXMLElement("Data", response, &pssh_data_b64));
std::vector<uint8_t> pssh_data;
if (!Base64StringToBytes(pssh_data_b64, &pssh_data)) {
LOG(ERROR) << "Cannot parse pssh data, " << pssh_data_b64;
return Status(error::SERVER_ERROR, "Cannot parse pssh.");
}
if (generate_playready_protection_system) {
std::string pssh_data_b64;
RETURN_IF_ERROR(RetrieveTextInXMLElement("Data", response, &pssh_data_b64));
std::vector<uint8_t> pssh_data;
if (!Base64StringToBytes(pssh_data_b64, &pssh_data)) {
LOG(ERROR) << "Cannot parse pssh data, " << pssh_data_b64;
return Status(error::SERVER_ERROR, "Cannot parse pssh.");
}
PsshBoxBuilder pssh_builder;
pssh_builder.add_key_id(encryption_key->key_id);
pssh_builder.set_system_id(kPlayReadySystemId, arraysize(kPlayReadySystemId));
pssh_builder.set_pssh_data(pssh_data);
encryption_key->key_system_info.push_back(
{pssh_builder.system_id(), pssh_builder.CreateBox()});
PsshBoxBuilder pssh_builder;
pssh_builder.add_key_id(encryption_key->key_id);
pssh_builder.set_system_id(kPlayReadySystemId,
arraysize(kPlayReadySystemId));
pssh_builder.set_pssh_data(pssh_data);
encryption_key->key_system_info.push_back(
{pssh_builder.system_id(), pssh_builder.CreateBox()});
}
return Status::OK;
}
@ -174,8 +184,9 @@ Status PlayReadyKeySource::FetchKeysWithProgramIdentifier(
VLOG(1) << "Server response: " << acquire_license_response;
RETURN_IF_ERROR(status);
RETURN_IF_ERROR(SetKeyInformationFromServerResponse(acquire_license_response,
encryption_key.get()));
RETURN_IF_ERROR(SetKeyInformationFromServerResponse(
acquire_license_response, generate_playready_protection_system_,
encryption_key.get()));
// PlayReady does not specify different streams.
const char kEmptyDrmLabel[] = "";

View File

@ -77,6 +77,9 @@ class PlayReadyKeySource : public KeySource {
Status GetKeyInternal();
Status GetCryptoPeriodKeyInternal();
// Indicates whether PlayReady protection system should be generated.
bool generate_playready_protection_system_ = true;
std::unique_ptr<EncryptionKey> encryption_key_;
std::string server_url_;
std::string ca_file_;

View File

@ -83,6 +83,11 @@ WidevineKeySource::WidevineKeySource(const std::string& server_url,
// Widevine PSSH is fetched from Widevine license server.
: KeySource(protection_system_flags & ~WIDEVINE_PROTECTION_SYSTEM_FLAG,
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),
key_production_thread_("KeyProductionThread",
base::Bind(&WidevineKeySource::FetchKeysTask,
base::Unretained(this))),
@ -90,11 +95,8 @@ WidevineKeySource::WidevineKeySource(const std::string& server_url,
server_url_(server_url),
crypto_period_count_(kDefaultCryptoPeriodCount),
protection_scheme_(protection_scheme),
key_production_started_(false),
start_key_production_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
base::WaitableEvent::InitialState::NOT_SIGNALED),
first_crypto_period_index_(0),
enable_entitlement_license_(false) {
base::WaitableEvent::InitialState::NOT_SIGNALED) {
key_production_thread_.Start();
}
@ -445,13 +447,15 @@ bool WidevineKeySource::ExtractEncryptionKey(
encryption_key->key_id.assign(track.key_id().begin(),
track.key_id().end());
if (track.pssh_size() != 1) {
LOG(ERROR) << "Expecting one and only one pssh, seeing "
<< track.pssh_size();
return false;
if (generate_widevine_protection_system_) {
if (track.pssh_size() != 1) {
LOG(ERROR) << "Expecting one and only one pssh, seeing "
<< track.pssh_size();
return false;
}
encryption_key->key_system_info.push_back(
ProtectionSystemInfoFromPsshProto(track.pssh(0)));
}
encryption_key->key_system_info.push_back(
ProtectionSystemInfoFromPsshProto(track.pssh(0)));
}
encryption_key_map[stream_label] = std::move(encryption_key);
}

View File

@ -111,6 +111,9 @@ class WidevineKeySource : public KeySource {
// Push the keys to the key pool.
bool PushToKeyPool(EncryptionKeyMap* encryption_key_map);
// Indicates whether Widevine protection system should be generated.
bool generate_widevine_protection_system_ = true;
ClosureThread key_production_thread_;
// The fetcher object used to fetch keys from the license service.
// It is initialized to a default fetcher on class initialization.
@ -121,13 +124,13 @@ class WidevineKeySource : public KeySource {
std::unique_ptr<CommonEncryptionRequest> common_encryption_request_;
const int crypto_period_count_;
FourCC protection_scheme_;
FourCC protection_scheme_ = FOURCC_NULL;
base::Lock lock_;
bool key_production_started_;
bool key_production_started_ = false;
base::WaitableEvent start_key_production_;
uint32_t first_crypto_period_index_;
uint32_t first_crypto_period_index_ = 0;
std::vector<uint8_t> group_id_;
bool enable_entitlement_license_;
bool enable_entitlement_license_ = false;
std::unique_ptr<EncryptionKeyQueue> key_pool_;
EncryptionKeyMap encryption_key_map_; // For non key rotation request.
Status common_encryption_request_status_;

View File

@ -13,7 +13,6 @@
#include "packager/base/strings/string_number_conversions.h"
#include "packager/base/strings/stringprintf.h"
#include "packager/media/base/key_fetcher.h"
#include "packager/media/base/playready_pssh_generator.h"
#include "packager/media/base/raw_key_pssh_generator.h"
#include "packager/media/base/request_signer.h"
#include "packager/media/base/widevine_key_source.h"
@ -228,11 +227,11 @@ class WidevineKeySourceTest : public Test {
}
void CreateWidevineKeySource() {
int protection_system_flags = WIDEVINE_PROTECTION_SYSTEM_FLAG;
int protection_system_flags = NO_PROTECTION_SYSTEM_FLAG;
if (add_widevine_pssh_)
protection_system_flags |= WIDEVINE_PROTECTION_SYSTEM_FLAG;
if (add_common_pssh_)
protection_system_flags |= COMMON_PROTECTION_SYSTEM_FLAG;
if (add_playready_pssh_)
protection_system_flags |= PLAYREADY_PROTECTION_SYSTEM_FLAG;
widevine_key_source_.reset(new WidevineKeySource(
kServerUrl, protection_system_flags, protection_scheme_));
widevine_key_source_->set_key_fetcher(std::move(mock_key_fetcher_));
@ -246,32 +245,31 @@ class WidevineKeySourceTest : public Test {
EXPECT_EQ(GetMockKey(stream_label), ToString(encryption_key.key));
if (!classic) {
size_t num_key_system_info =
1 + (add_common_pssh_ ? 1 : 0) + (add_playready_pssh_ ? 1 : 0);
(add_widevine_pssh_ && add_common_pssh_) ? 2 : 1;
ASSERT_EQ(num_key_system_info, encryption_key.key_system_info.size());
EXPECT_EQ(GetMockKeyId(stream_label), ToString(encryption_key.key_id));
const std::vector<uint8_t>& pssh =
encryption_key.key_system_info[0].psshs;
std::unique_ptr<PsshBoxBuilder> pssh_builder =
PsshBoxBuilder::ParseFromBox(pssh.data(), pssh.size());
ASSERT_TRUE(pssh_builder);
EXPECT_EQ(GetMockPsshData(), ToString(pssh_builder->pssh_data()));
auto key_system_info_iter = encryption_key.key_system_info.begin();
// Default to Widevine if neither are set.
if (add_widevine_pssh_ || !add_common_pssh_) {
const std::vector<uint8_t> widevine_system_id(
std::begin(kWidevineSystemId), std::end(kWidevineSystemId));
ASSERT_EQ(widevine_system_id, key_system_info_iter->system_id);
const std::vector<uint8_t>& pssh = key_system_info_iter->psshs;
std::unique_ptr<PsshBoxBuilder> pssh_builder =
PsshBoxBuilder::ParseFromBox(pssh.data(), pssh.size());
ASSERT_TRUE(pssh_builder);
EXPECT_EQ(GetMockPsshData(), ToString(pssh_builder->pssh_data()));
++key_system_info_iter;
}
if (add_common_pssh_) {
const std::vector<uint8_t> common_system_id(
kCommonSystemId, kCommonSystemId + arraysize(kCommonSystemId));
ASSERT_EQ(common_system_id,
encryption_key.key_system_info[1].system_id);
}
if (add_playready_pssh_) {
const std::vector<uint8_t> playready_system_id(
kPlayReadySystemId,
kPlayReadySystemId + arraysize(kPlayReadySystemId));
// PlayReady pssh index depends on if there has common pssh box.
const uint8_t playready_index = 1 + (add_common_pssh_ ? 1 : 0);
ASSERT_EQ(playready_system_id,
encryption_key.key_system_info[playready_index].system_id);
std::begin(kCommonSystemId), std::end(kCommonSystemId));
ASSERT_EQ(common_system_id, key_system_info_iter->system_id);
}
}
}
@ -280,8 +278,8 @@ class WidevineKeySourceTest : public Test {
std::unique_ptr<MockKeyFetcher> mock_key_fetcher_;
std::unique_ptr<WidevineKeySource> widevine_key_source_;
std::vector<uint8_t> content_id_;
bool add_widevine_pssh_ = false;
bool add_common_pssh_ = false;
bool add_playready_pssh_ = false;
FourCC protection_scheme_ = FOURCC_cenc;
private:
@ -371,8 +369,8 @@ class WidevineKeySourceParameterizedTest
public WithParamInterface<std::tr1::tuple<bool, bool, FourCC>> {
public:
WidevineKeySourceParameterizedTest() {
add_common_pssh_ = std::tr1::get<0>(GetParam());
add_playready_pssh_ = std::tr1::get<1>(GetParam());
add_widevine_pssh_ = std::tr1::get<0>(GetParam());
add_common_pssh_ = std::tr1::get<1>(GetParam());
protection_scheme_ = std::tr1::get<2>(GetParam());
}
};
@ -415,10 +413,9 @@ TEST_P(WidevineKeySourceParameterizedTest, LicenseStatusCencOK) {
VerifyKeys(false);
}
TEST_P(WidevineKeySourceParameterizedTest, LicenseStatusCencNotOK) {
TEST_P(WidevineKeySourceParameterizedTest, LicenseStatusCencMalformedResponse) {
std::string mock_response = base::StringPrintf(
kHttpResponseFormat, Base64Encode(
GenerateMockClassicLicenseResponse()).c_str());
kHttpResponseFormat, Base64Encode("malformed response").c_str());
EXPECT_CALL(*mock_key_fetcher_, FetchKeys(_, _, _))
.WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK)));
@ -444,16 +441,15 @@ TEST_P(WidevineKeySourceParameterizedTest, LicenseStatusCencWithPsshBoxOK) {
CreateWidevineKeySource();
widevine_key_source_->set_signer(std::move(mock_request_signer_));
std::vector<uint8_t> pssh_box(kRequestPsshBox,
kRequestPsshBox + arraysize(kRequestPsshBox));
std::vector<uint8_t> pssh_box(std::begin(kRequestPsshBox),
std::end(kRequestPsshBox));
ASSERT_OK(widevine_key_source_->FetchKeys(EmeInitDataType::CENC, pssh_box));
VerifyKeys(false);
}
TEST_P(WidevineKeySourceParameterizedTest, LicenseStatusCencWithKeyIdsOK) {
std::string expected_pssh_data(
kRequestPsshDataFromKeyIds,
kRequestPsshDataFromKeyIds + arraysize(kRequestPsshDataFromKeyIds));
std::string expected_pssh_data(std::begin(kRequestPsshDataFromKeyIds),
std::end(kRequestPsshDataFromKeyIds));
std::string expected_message =
base::StringPrintf(kExpectedRequestMessageWithPsshFormat,
Base64Encode(expected_pssh_data).c_str());
@ -468,8 +464,8 @@ TEST_P(WidevineKeySourceParameterizedTest, LicenseStatusCencWithKeyIdsOK) {
CreateWidevineKeySource();
widevine_key_source_->set_signer(std::move(mock_request_signer_));
std::vector<uint8_t> key_id(kRequestKeyId,
kRequestKeyId + arraysize(kRequestKeyId));
std::vector<uint8_t> key_id(std::begin(kRequestKeyId),
std::end(kRequestKeyId));
ASSERT_OK(widevine_key_source_->FetchKeys(EmeInitDataType::WEBM, key_id));
VerifyKeys(false);
}

View File

@ -122,8 +122,8 @@ struct EncryptionParams {
kPlayReady,
kWidevine,
};
/// Additional protection systems to be generated.
std::vector<ProtectionSystem> additional_protection_systems;
/// Protection systems to be generated.
std::vector<ProtectionSystem> protection_systems;
/// Clear lead duration in seconds.
double clear_lead_in_seconds = 0;