Allow specifying protection pattern for pattern encryption
Added --crypt_byte_block, --skip_byte_block to allow users to specify protection pattern other than 1:9 for pattern based encryption scheme, e.g. cbcs and cens. Closes #710. b/147307451 Change-Id: I9f64a7639170c737f138572689b28d17286325c7
This commit is contained in:
parent
1ca873f453
commit
4028bf727b
|
@ -6,6 +6,24 @@ General encryption options
|
|||
Specify a protection scheme, 'cenc' or 'cbc1' or pattern-based protection
|
||||
schemes 'cens' or 'cbcs'.
|
||||
|
||||
--crypt_byte_block
|
||||
|
||||
Specify the count of the encrypted blocks in the protection pattern, where
|
||||
block is of size 16-bytes.
|
||||
|
||||
There are three common patterns (crypt_byte_block:skip_byte_block):
|
||||
1:9 (default), 5:5, 10:0.
|
||||
|
||||
Apply to video streams with 'cbcs' and 'cens' protection schemes only;
|
||||
ignored otherwise.
|
||||
|
||||
--skip_byte_block
|
||||
|
||||
Specify the count of the unencrypted blocks in the protection pattern.
|
||||
|
||||
Apply to video streams with 'cbcs' and 'cens' protection schemes only;
|
||||
ignored otherwise.
|
||||
|
||||
--vp9_subsample_encryption, --novp9_subsample_encryption
|
||||
|
||||
Enable / disable VP9 subsample encryption. Enabled by default.
|
||||
|
|
|
@ -12,4 +12,33 @@ DEFINE_string(protection_scheme,
|
|||
"cenc",
|
||||
"Specify a protection scheme, 'cenc' or 'cbc1' or pattern-based "
|
||||
"protection schemes 'cens' or 'cbcs'.");
|
||||
DEFINE_int32(
|
||||
crypt_byte_block,
|
||||
1,
|
||||
"Specify the count of the encrypted blocks in the protection pattern, "
|
||||
"where block is of size 16-bytes. There are three common "
|
||||
"patterns (crypt_byte_block:skip_byte_block): 1:9 (default), 5:5, 10:0. "
|
||||
"Apply to video streams with 'cbcs' and 'cens' protection schemes only; "
|
||||
"ignored otherwise.");
|
||||
DEFINE_int32(
|
||||
skip_byte_block,
|
||||
9,
|
||||
"Specify the count of the unencrypted blocks in the protection pattern. "
|
||||
"Apply to video streams with 'cbcs' and 'cens' protection schemes only; "
|
||||
"ignored otherwise.");
|
||||
DEFINE_bool(vp9_subsample_encryption, true, "Enable VP9 subsample encryption.");
|
||||
|
||||
bool ValueNotGreaterThanTen(const char* flagname, int32_t value) {
|
||||
if (value > 10) {
|
||||
fprintf(stderr, "ERROR: %s must not be greater than 10.\n", flagname);
|
||||
return false;
|
||||
}
|
||||
if (value < 0) {
|
||||
fprintf(stderr, "ERROR: %s must be non-negative.\n", flagname);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DEFINE_validator(crypt_byte_block, &ValueNotGreaterThanTen);
|
||||
DEFINE_validator(skip_byte_block, &ValueNotGreaterThanTen);
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
#include <gflags/gflags.h>
|
||||
|
||||
DECLARE_string(protection_scheme);
|
||||
DECLARE_int32(crypt_byte_block);
|
||||
DECLARE_int32(skip_byte_block);
|
||||
DECLARE_bool(vp9_subsample_encryption);
|
||||
|
||||
#endif // PACKAGER_APP_CRYPTO_FLAGS_H_
|
||||
|
|
|
@ -343,6 +343,9 @@ base::Optional<PackagingParams> GetPackagingParams() {
|
|||
encryption_params.clear_lead_in_seconds = FLAGS_clear_lead;
|
||||
if (!GetProtectionScheme(&encryption_params.protection_scheme))
|
||||
return base::nullopt;
|
||||
encryption_params.crypt_byte_block = FLAGS_crypt_byte_block;
|
||||
encryption_params.skip_byte_block = FLAGS_skip_byte_block;
|
||||
|
||||
encryption_params.crypto_period_duration_in_seconds =
|
||||
FLAGS_crypto_period_duration;
|
||||
encryption_params.vp9_subsample_encryption = FLAGS_vp9_subsample_encryption;
|
||||
|
|
|
@ -417,6 +417,8 @@ class PackagerAppTest(unittest.TestCase):
|
|||
encryption=False,
|
||||
protection_systems=None,
|
||||
protection_scheme=None,
|
||||
crypt_byte_block=None,
|
||||
skip_byte_block=None,
|
||||
vp9_subsample_encryption=True,
|
||||
decryption=False,
|
||||
random_iv=False,
|
||||
|
@ -469,6 +471,11 @@ class PackagerAppTest(unittest.TestCase):
|
|||
|
||||
if protection_scheme:
|
||||
flags += ['--protection_scheme', protection_scheme]
|
||||
if crypt_byte_block is not None and skip_byte_block is not None:
|
||||
flags += [
|
||||
'--crypt_byte_block={0}'.format(crypt_byte_block),
|
||||
'--skip_byte_block={0}'.format(skip_byte_block)
|
||||
]
|
||||
if not vp9_subsample_encryption:
|
||||
flags += ['--vp9_subsample_encryption=false']
|
||||
|
||||
|
@ -1042,6 +1049,18 @@ class PackagerFunctionalTest(PackagerAppTest):
|
|||
encryption=True, protection_scheme='cbcs', output_dash=True))
|
||||
self._CheckTestResults('encryption-cbcs', verify_decryption=True)
|
||||
|
||||
def testEncryptionCbcsWithFullProtection(self):
|
||||
self.assertPackageSuccess(
|
||||
self._GetStreams(['audio', 'video']),
|
||||
self._GetFlags(
|
||||
encryption=True,
|
||||
protection_scheme='cbcs',
|
||||
crypt_byte_block=10,
|
||||
skip_byte_block=0,
|
||||
output_dash=True))
|
||||
self._CheckTestResults(
|
||||
'encryption-cbcs-with-full-protection', verify_decryption=True)
|
||||
|
||||
def testEncryptionAndAdCues(self):
|
||||
self.assertPackageSuccess(
|
||||
self._GetStreams(['audio', 'video'], hls=True),
|
||||
|
@ -1774,6 +1793,17 @@ class PackagerCommandParsingTest(PackagerAppTest):
|
|||
# Expect the test to fail but we do not expect a crash.
|
||||
self.assertEqual(packaging_result, 1)
|
||||
|
||||
def testIncorrectEncryptionPattern(self):
|
||||
packaging_result = self.packager.Package(
|
||||
self._GetStreams(['audio', 'video']),
|
||||
self._GetFlags(
|
||||
encryption=True,
|
||||
protection_scheme='cbcs',
|
||||
crypt_byte_block=12,
|
||||
skip_byte_block=13,
|
||||
output_dash=True))
|
||||
self.assertEqual(packaging_result, 1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
BIN
packager/app/test/testdata/encryption-cbcs-with-full-protection/bear-640x360-audio.mp4
vendored
Normal file
BIN
packager/app/test/testdata/encryption-cbcs-with-full-protection/bear-640x360-audio.mp4
vendored
Normal file
Binary file not shown.
BIN
packager/app/test/testdata/encryption-cbcs-with-full-protection/bear-640x360-video.mp4
vendored
Normal file
BIN
packager/app/test/testdata/encryption-cbcs-with-full-protection/bear-640x360-video.mp4
vendored
Normal file
Binary file not shown.
BIN
packager/app/test/testdata/encryption-cbcs-with-full-protection/decrypted-bear-640x360-audio-0.mp4
vendored
Normal file
BIN
packager/app/test/testdata/encryption-cbcs-with-full-protection/decrypted-bear-640x360-audio-0.mp4
vendored
Normal file
Binary file not shown.
BIN
packager/app/test/testdata/encryption-cbcs-with-full-protection/decrypted-bear-640x360-video-0.mp4
vendored
Normal file
BIN
packager/app/test/testdata/encryption-cbcs-with-full-protection/decrypted-bear-640x360-video-0.mp4
vendored
Normal file
Binary file not shown.
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--Generated with https://github.com/google/shaka-packager version <tag>-<hash>-<test>-->
|
||||
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-on-demand:2011" minBufferTime="PT2S" type="static" mediaPresentationDuration="PT2.7360665798187256S">
|
||||
<Period id="0">
|
||||
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" subsegmentAlignment="true" par="16:9">
|
||||
<ContentProtection value="cbcs" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
|
||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
|
||||
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
|
||||
</ContentProtection>
|
||||
<Representation id="0" bandwidth="975825" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||
<BaseURL>bear-640x360-video.mp4</BaseURL>
|
||||
<SegmentBase indexRange="1136-1203" timescale="30000">
|
||||
<Initialization range="0-1135"/>
|
||||
</SegmentBase>
|
||||
</Representation>
|
||||
</AdaptationSet>
|
||||
<AdaptationSet id="1" contentType="audio" subsegmentAlignment="true">
|
||||
<ContentProtection value="cbcs" schemeIdUri="urn:mpeg:dash:mp4protection:2011" cenc:default_KID="31323334-3536-3738-3930-313233343536"/>
|
||||
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b">
|
||||
<cenc:pssh>AAAANHBzc2gBAAAAEHfv7MCyTQKs4zweUuL7SwAAAAExMjM0NTY3ODkwMTIzNDU2AAAAAA==</cenc:pssh>
|
||||
</ContentProtection>
|
||||
<Representation id="1" bandwidth="133334" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||
<BaseURL>bear-640x360-audio.mp4</BaseURL>
|
||||
<SegmentBase indexRange="1012-1079" timescale="44100">
|
||||
<Initialization range="0-1011"/>
|
||||
</SegmentBase>
|
||||
</Representation>
|
||||
</AdaptationSet>
|
||||
</Period>
|
||||
</MPD>
|
|
@ -253,9 +253,8 @@ Status EncryptionHandler::ProcessMediaSample(
|
|||
void EncryptionHandler::SetupProtectionPattern(StreamType stream_type) {
|
||||
if (stream_type == kStreamVideo &&
|
||||
IsPatternEncryptionScheme(protection_scheme_)) {
|
||||
// Use 1:9 pattern.
|
||||
crypt_byte_block_ = 1u;
|
||||
skip_byte_block_ = 9u;
|
||||
crypt_byte_block_ = encryption_params_.crypt_byte_block;
|
||||
skip_byte_block_ = encryption_params_.skip_byte_block;
|
||||
} else {
|
||||
// Audio stream in pattern encryption scheme does not use pattern; it uses
|
||||
// whole-block full sample encryption instead. Non-pattern encryption does
|
||||
|
|
|
@ -134,6 +134,16 @@ struct EncryptionParams {
|
|||
static constexpr uint32_t kProtectionSchemeCens = 0x63656E73;
|
||||
static constexpr uint32_t kProtectionSchemeCbcs = 0x63626373;
|
||||
uint32_t protection_scheme = kProtectionSchemeCenc;
|
||||
/// The count of the encrypted blocks in the protection pattern, where each
|
||||
/// block is of size 16-bytes. There are three common patterns
|
||||
/// (crypt_byte_block:skip_byte_block): 1:9 (default), 5:5, 10:0.
|
||||
/// Applies to video streams with "cbcs" and "cens" protection schemes only;
|
||||
/// Ignored otherwise.
|
||||
uint8_t crypt_byte_block = 1;
|
||||
/// The count of the unencrypted blocks in the protection pattern.
|
||||
/// Applies to video streams with "cbcs" and "cens" protection schemes only;
|
||||
/// Ignored otherwise.
|
||||
uint8_t skip_byte_block = 9;
|
||||
/// Crypto period duration in seconds. A positive value means key rotation is
|
||||
/// enabled, the key provider must support key rotation in this case.
|
||||
static constexpr double kNoKeyRotation = 0;
|
||||
|
|
Loading…
Reference in New Issue