Rename webm_subsample_encryption flag to vp9_subsample_encryption

This is what webm_subsample_encryption flag actually does.

- Fixes the flag not working problem introduced by previous CLs.
- Also mark flag webm_subsample_encryption as deprecated.

Closes #220

Change-Id: I03ff843786572a91c01b8bd346a3ce50b129118f
This commit is contained in:
Kongqun Yang 2017-03-28 08:19:15 -07:00 committed by KongQun Yang
parent 92280bf214
commit 1af8f04e40
17 changed files with 82 additions and 26 deletions

View File

@ -0,0 +1,15 @@
// Copyright 2017 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#include "packager/app/crypto_flags.h"
#include <stdio.h>
DEFINE_string(protection_scheme,
"cenc",
"Specify a protection scheme, 'cenc' or 'cbc1' or pattern-based "
"protection schemes 'cens' or 'cbcs'.");
DEFINE_bool(vp9_subsample_encryption, true, "Enable VP9 subsample encryption.");

View File

@ -0,0 +1,18 @@
// Copyright 2017 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
//
// Defines common command line flags for encryption and decryption, which
// applies to all key sources, i.e. fixed key, widevine and playready.
#ifndef PACKAGER_APP_CRYPTO_FLAGS_H_
#define PACKAGER_APP_CRYPTO_FLAGS_H_
#include <gflags/gflags.h>
DECLARE_string(protection_scheme);
DECLARE_bool(vp9_subsample_encryption);
#endif // PACKAGER_APP_CRYPTO_FLAGS_H_

View File

@ -41,5 +41,3 @@ DEFINE_string(temp_dir,
"", "",
"Specify a directory in which to store temporary (intermediate) " "Specify a directory in which to store temporary (intermediate) "
" files. Used only if single_segment=true."); " files. Used only if single_segment=true.");
DEFINE_bool(webm_subsample_encryption, true,
"Enable WebM subsample encryption.");

View File

@ -18,6 +18,5 @@ DECLARE_double(fragment_duration);
DECLARE_bool(fragment_sap_aligned); DECLARE_bool(fragment_sap_aligned);
DECLARE_int32(num_subsegments_per_sidx); DECLARE_int32(num_subsegments_per_sidx);
DECLARE_string(temp_dir); DECLARE_string(temp_dir);
DECLARE_bool(webm_subsample_encryption);
#endif // APP_MUXER_FLAGS_H_ #endif // APP_MUXER_FLAGS_H_

View File

@ -9,6 +9,7 @@
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <iostream> #include <iostream>
#include "packager/app/crypto_flags.h"
#include "packager/app/fixed_key_encryption_flags.h" #include "packager/app/fixed_key_encryption_flags.h"
#include "packager/app/playready_key_encryption_flags.h" #include "packager/app/playready_key_encryption_flags.h"
#include "packager/app/mpd_flags.h" #include "packager/app/mpd_flags.h"
@ -185,13 +186,13 @@ EncryptionOptions GetEncryptionOptions() {
encryption_options.max_uhd1_pixels = FLAGS_max_uhd1_pixels; encryption_options.max_uhd1_pixels = FLAGS_max_uhd1_pixels;
encryption_options.crypto_period_duration_in_seconds = encryption_options.crypto_period_duration_in_seconds =
FLAGS_crypto_period_duration; FLAGS_crypto_period_duration;
encryption_options.vp9_subsample_encryption = FLAGS_vp9_subsample_encryption;
return encryption_options; return encryption_options;
} }
MuxerOptions GetMuxerOptions() { MuxerOptions GetMuxerOptions() {
MuxerOptions muxer_options; MuxerOptions muxer_options;
muxer_options.num_subsegments_per_sidx = FLAGS_num_subsegments_per_sidx; muxer_options.num_subsegments_per_sidx = FLAGS_num_subsegments_per_sidx;
muxer_options.webm_subsample_encryption = FLAGS_webm_subsample_encryption;
if (FLAGS_mp4_use_decoding_timestamp_in_timeline) { if (FLAGS_mp4_use_decoding_timestamp_in_timeline) {
LOG(WARNING) << "Flag --mp4_use_decoding_timestamp_in_timeline is set. " LOG(WARNING) << "Flag --mp4_use_decoding_timestamp_in_timeline is set. "
"Note that it is a temporary hack to workaround Chromium " "Note that it is a temporary hack to workaround Chromium "

View File

@ -13,6 +13,9 @@
DEFINE_string(profile, "", "This flag is deprecated. Do not use."); DEFINE_string(profile, "", "This flag is deprecated. Do not use.");
DEFINE_bool(single_segment, true, "This flag is deprecated. Do not use."); DEFINE_bool(single_segment, true, "This flag is deprecated. Do not use.");
DEFINE_bool(webm_subsample_encryption,
true,
"This flag is deprecated. Use vp9_subsample_encryption instead.");
// The current gflags library does not provide a way to check whether a flag is // 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, // set in command line. If a flag has a different value to its default value,
@ -32,3 +35,4 @@ bool InformRetiredDefaultTrueFlag(const char* flagname, bool value) {
DEFINE_validator(profile, &InformRetiredStringFlag); DEFINE_validator(profile, &InformRetiredStringFlag);
DEFINE_validator(single_segment, &InformRetiredDefaultTrueFlag); DEFINE_validator(single_segment, &InformRetiredDefaultTrueFlag);
DEFINE_validator(webm_subsample_encryption, &InformRetiredDefaultTrueFlag);

View File

@ -8,3 +8,4 @@
DECLARE_string(profile); DECLARE_string(profile);
DECLARE_bool(single_segment); DECLARE_bool(single_segment);
DECLARE_bool(webm_subsample_encryption);

View File

@ -230,6 +230,17 @@ class PackagerAppTest(unittest.TestCase):
self._VerifyDecryption(self.output[0], self._VerifyDecryption(self.output[0],
'bear-640x360-vp9-altref-dec-golden.webm') 'bear-640x360-vp9-altref-dec-golden.webm')
def testPackageWithWebmVp9FullSampleEncryption(self):
self.packager.Package(
self._GetStreams(['video'],
output_format='webm',
test_files=['bear-640x360-vp9-altref.webm']),
self._GetFlags(encryption=True, vp9_subsample_encryption=False))
self._DiffGold(self.output[0],
'bear-640x360-vp9-fullsample-enc-golden.webm')
self._VerifyDecryption(self.output[0],
'bear-640x360-vp9-altref-dec-golden.webm')
def testPackageAvcTsWithEncryption(self): def testPackageAvcTsWithEncryption(self):
# Currently we only support live packaging for ts. # Currently we only support live packaging for ts.
self.packager.Package( self.packager.Package(
@ -532,6 +543,7 @@ class PackagerAppTest(unittest.TestCase):
def _GetFlags(self, def _GetFlags(self,
encryption=False, encryption=False,
protection_scheme=None, protection_scheme=None,
vp9_subsample_encryption=True,
decryption=False, decryption=False,
encryption_key='32333435363738393021323334353637', encryption_key='32333435363738393021323334353637',
encryption_iv='3334353637383930', encryption_iv='3334353637383930',
@ -564,6 +576,8 @@ class PackagerAppTest(unittest.TestCase):
flags.append('--iv=' + encryption_iv) flags.append('--iv=' + encryption_iv)
if protection_scheme: if protection_scheme:
flags += ['--protection_scheme', protection_scheme] flags += ['--protection_scheme', protection_scheme]
if not vp9_subsample_encryption:
flags += ['--vp9_subsample_encryption=false']
if decryption: if decryption:
flags += ['--enable_fixed_key_decryption', flags += ['--enable_fixed_key_decryption',

View File

@ -65,10 +65,6 @@ DEFINE_int32(crypto_period_duration,
0, 0,
"Crypto period duration in seconds. If it is non-zero, key " "Crypto period duration in seconds. If it is non-zero, key "
"rotation is enabled."); "rotation is enabled.");
DEFINE_string(protection_scheme,
"cenc",
"Choose protection scheme, 'cenc' or 'cbc1' or pattern-based "
"protection schemes 'cens' or 'cbcs'.");
namespace shaka { namespace shaka {

View File

@ -25,7 +25,6 @@ DECLARE_string(aes_signing_key);
DECLARE_string(aes_signing_iv); DECLARE_string(aes_signing_iv);
DECLARE_string(rsa_signing_key_path); DECLARE_string(rsa_signing_key_path);
DECLARE_int32(crypto_period_duration); DECLARE_int32(crypto_period_duration);
DECLARE_string(protection_scheme);
namespace shaka { namespace shaka {

View File

@ -50,9 +50,6 @@ struct MuxerOptions {
/// User-specified bit rate for the media stream. If zero, the muxer will /// User-specified bit rate for the media stream. If zero, the muxer will
/// attempt to estimate. /// attempt to estimate.
uint32_t bandwidth = 0; uint32_t bandwidth = 0;
// Enable/disable subsample encryption for WebM containers.
bool webm_subsample_encryption = true;
}; };
} // namespace media } // namespace media

View File

@ -146,6 +146,7 @@ Status EncryptionHandler::ProcessStreamInfo(StreamInfo* stream_info) {
encryption_options_.max_hd_pixels, encryption_options_.max_uhd1_pixels); encryption_options_.max_hd_pixels, encryption_options_.max_uhd1_pixels);
switch (codec_) { switch (codec_) {
case kCodecVP9: case kCodecVP9:
if (encryption_options_.vp9_subsample_encryption)
vpx_parser_.reset(new VP9Parser); vpx_parser_.reset(new VP9Parser);
break; break;
case kCodecH264: case kCodecH264:
@ -246,8 +247,6 @@ Status EncryptionHandler::ProcessMediaSample(MediaSample* sample) {
sample->data_size()); sample->data_size());
} }
} else { } else {
DCHECK_LE(crypt_byte_block_, 1u);
DCHECK_EQ(skip_byte_block_, 0u);
if (sample->data_size() > leading_clear_bytes_size_) { if (sample->data_size() > leading_clear_bytes_size_) {
EncryptBytes(sample->writable_data() + leading_clear_bytes_size_, EncryptBytes(sample->writable_data() + leading_clear_bytes_size_,
sample->data_size() - leading_clear_bytes_size_); sample->data_size() - leading_clear_bytes_size_);

View File

@ -41,6 +41,8 @@ struct EncryptionOptions {
/// Crypto period duration in seconds. A positive value means key rotation is /// Crypto period duration in seconds. A positive value means key rotation is
/// enabled, the key source must support key rotation in this case. /// enabled, the key source must support key rotation in this case.
double crypto_period_duration_in_seconds = 0; double crypto_period_duration_in_seconds = 0;
// Enable/disable subsample encryption for VP9.
bool vp9_subsample_encryption = true;
}; };
class EncryptionHandler : public MediaHandler { class EncryptionHandler : public MediaHandler {

View File

@ -133,6 +133,7 @@ TEST_F(EncryptionHandlerTest, OnlyOneInput) {
namespace { namespace {
const bool kVp9SubsampleEncryption = true;
const bool kIsKeyFrame = true; const bool kIsKeyFrame = true;
const bool kIsSubsegment = true; const bool kIsSubsegment = true;
const bool kEncrypted = true; const bool kEncrypted = true;
@ -205,11 +206,12 @@ inline bool operator==(const SubsampleEntry& lhs, const SubsampleEntry& rhs) {
class EncryptionHandlerEncryptionTest class EncryptionHandlerEncryptionTest
: public EncryptionHandlerTest, : public EncryptionHandlerTest,
public WithParamInterface<std::tr1::tuple<FourCC, Codec>> { public WithParamInterface<std::tr1::tuple<FourCC, Codec, bool>> {
public: public:
void SetUp() override { void SetUp() override {
protection_scheme_ = std::tr1::get<0>(GetParam()); protection_scheme_ = std::tr1::get<0>(GetParam());
codec_ = std::tr1::get<1>(GetParam()); codec_ = std::tr1::get<1>(GetParam());
vp9_subsample_encryption_ = std::tr1::get<2>(GetParam());
} }
std::vector<VPxFrameInfo> GetMockVpxFrameInfo() { std::vector<VPxFrameInfo> GetMockVpxFrameInfo() {
@ -225,8 +227,10 @@ class EncryptionHandlerEncryptionTest
// The subsamples values should match |GetMockVpxFrameInfo| above. // The subsamples values should match |GetMockVpxFrameInfo| above.
std::vector<SubsampleEntry> GetExpectedSubsamples() { std::vector<SubsampleEntry> GetExpectedSubsamples() {
std::vector<SubsampleEntry> subsamples; std::vector<SubsampleEntry> subsamples;
if (codec_ == kCodecAAC) if (codec_ == kCodecAAC ||
(codec_ == kCodecVP9 && !vp9_subsample_encryption_)) {
return subsamples; return subsamples;
}
if (protection_scheme_ == kAppleSampleAesProtectionScheme) { if (protection_scheme_ == kAppleSampleAesProtectionScheme) {
subsamples.emplace_back(static_cast<uint16_t>(kSampleAesClearSize1), subsamples.emplace_back(static_cast<uint16_t>(kSampleAesClearSize1),
static_cast<uint32_t>(kSampleAesCipherSize1)); static_cast<uint32_t>(kSampleAesCipherSize1));
@ -265,14 +269,15 @@ class EncryptionHandlerEncryptionTest
// Inject vpx parser / video slice header parser if needed. // Inject vpx parser / video slice header parser if needed.
void InjectCodecParser() { void InjectCodecParser() {
switch (codec_) { switch (codec_) {
case kCodecVP9: { case kCodecVP9:
if (vp9_subsample_encryption_) {
std::unique_ptr<MockVpxParser> mock_vpx_parser(new MockVpxParser); std::unique_ptr<MockVpxParser> mock_vpx_parser(new MockVpxParser);
EXPECT_CALL(*mock_vpx_parser, Parse(_, sizeof(kData), _)) EXPECT_CALL(*mock_vpx_parser, Parse(_, sizeof(kData), _))
.WillRepeatedly( .WillRepeatedly(
DoAll(SetArgPointee<2>(GetMockVpxFrameInfo()), Return(true))); DoAll(SetArgPointee<2>(GetMockVpxFrameInfo()), Return(true)));
InjectVpxParserForTesting(std::move(mock_vpx_parser)); InjectVpxParserForTesting(std::move(mock_vpx_parser));
break;
} }
break;
case kCodecH264: { case kCodecH264: {
std::unique_ptr<MockVideoSliceHeaderParser> mock_header_parser( std::unique_ptr<MockVideoSliceHeaderParser> mock_header_parser(
new MockVideoSliceHeaderParser); new MockVideoSliceHeaderParser);
@ -441,6 +446,7 @@ class EncryptionHandlerEncryptionTest
protected: protected:
FourCC protection_scheme_; FourCC protection_scheme_;
Codec codec_; Codec codec_;
bool vp9_subsample_encryption_;
}; };
TEST_P(EncryptionHandlerEncryptionTest, ClearLeadWithNoKeyRotation) { TEST_P(EncryptionHandlerEncryptionTest, ClearLeadWithNoKeyRotation) {
@ -448,6 +454,7 @@ TEST_P(EncryptionHandlerEncryptionTest, ClearLeadWithNoKeyRotation) {
EncryptionOptions encryption_options; EncryptionOptions encryption_options;
encryption_options.protection_scheme = protection_scheme_; encryption_options.protection_scheme = protection_scheme_;
encryption_options.clear_lead_in_seconds = kClearLeadInSeconds; encryption_options.clear_lead_in_seconds = kClearLeadInSeconds;
encryption_options.vp9_subsample_encryption = vp9_subsample_encryption_;
SetUpEncryptionHandler(encryption_options); SetUpEncryptionHandler(encryption_options);
const EncryptionKey mock_encryption_key = GetMockEncryptionKey(); const EncryptionKey mock_encryption_key = GetMockEncryptionKey();
@ -498,6 +505,7 @@ TEST_P(EncryptionHandlerEncryptionTest, ClearLeadWithKeyRotation) {
encryption_options.clear_lead_in_seconds = kClearLeadInSeconds; encryption_options.clear_lead_in_seconds = kClearLeadInSeconds;
encryption_options.crypto_period_duration_in_seconds = encryption_options.crypto_period_duration_in_seconds =
kCryptoPeriodDurationInSeconds; kCryptoPeriodDurationInSeconds;
encryption_options.vp9_subsample_encryption = vp9_subsample_encryption_;
SetUpEncryptionHandler(encryption_options); SetUpEncryptionHandler(encryption_options);
ASSERT_OK(Process(GetStreamInfoStreamData(kStreamIndex, codec_, kTimeScale))); ASSERT_OK(Process(GetStreamInfoStreamData(kStreamIndex, codec_, kTimeScale)));
@ -549,6 +557,7 @@ TEST_P(EncryptionHandlerEncryptionTest, ClearLeadWithKeyRotation) {
TEST_P(EncryptionHandlerEncryptionTest, Encrypt) { TEST_P(EncryptionHandlerEncryptionTest, Encrypt) {
EncryptionOptions encryption_options; EncryptionOptions encryption_options;
encryption_options.protection_scheme = protection_scheme_; encryption_options.protection_scheme = protection_scheme_;
encryption_options.vp9_subsample_encryption = vp9_subsample_encryption_;
SetUpEncryptionHandler(encryption_options); SetUpEncryptionHandler(encryption_options);
const EncryptionKey mock_encryption_key = GetMockEncryptionKey(); const EncryptionKey mock_encryption_key = GetMockEncryptionKey();
@ -597,11 +606,13 @@ INSTANTIATE_TEST_CASE_P(
CencProtectionSchemes, CencProtectionSchemes,
EncryptionHandlerEncryptionTest, EncryptionHandlerEncryptionTest,
Combine(Values(FOURCC_cenc, FOURCC_cens, FOURCC_cbc1, FOURCC_cbcs), Combine(Values(FOURCC_cenc, FOURCC_cens, FOURCC_cbc1, FOURCC_cbcs),
Values(kCodecAAC, kCodecH264, kCodecVP9))); Values(kCodecAAC, kCodecH264, kCodecVP9),
Values(kVp9SubsampleEncryption, !kVp9SubsampleEncryption)));
INSTANTIATE_TEST_CASE_P(AppleSampleAes, INSTANTIATE_TEST_CASE_P(AppleSampleAes,
EncryptionHandlerEncryptionTest, EncryptionHandlerEncryptionTest,
Combine(Values(kAppleSampleAesProtectionScheme), Combine(Values(kAppleSampleAesProtectionScheme),
Values(kCodecAAC, kCodecH264))); Values(kCodecAAC, kCodecH264),
Values(kVp9SubsampleEncryption)));
namespace { namespace {

View File

@ -13,6 +13,8 @@
'target_name': 'packager', 'target_name': 'packager',
'type': 'executable', 'type': 'executable',
'sources': [ 'sources': [
'app/crypto_flags.cc',
'app/crypto_flags.h',
'app/fixed_key_encryption_flags.cc', 'app/fixed_key_encryption_flags.cc',
'app/fixed_key_encryption_flags.h', 'app/fixed_key_encryption_flags.h',
'app/hls_flags.cc', 'app/hls_flags.cc',