Fix pattern signaling in seig for key rotation with cbcs
Closes #460. Bug: 112769382 Change-Id: Id2277edf9ac1ca637354f3a585666ad139ed8ee2
This commit is contained in:
parent
3cf9b912d8
commit
18492a2613
|
@ -1409,6 +1409,16 @@ class PackagerFunctionalTest(PackagerAppTest):
|
||||||
self._GetFlags(encryption=True, key_rotation=True, output_dash=True))
|
self._GetFlags(encryption=True, key_rotation=True, output_dash=True))
|
||||||
self._CheckTestResults('live-profile-and-key-rotation')
|
self._CheckTestResults('live-profile-and-key-rotation')
|
||||||
|
|
||||||
|
def testLiveProfileAndKeyRotationCbcs(self):
|
||||||
|
self.assertPackageSuccess(
|
||||||
|
self._GetStreams(['audio', 'video'], segmented=True),
|
||||||
|
self._GetFlags(
|
||||||
|
encryption=True,
|
||||||
|
protection_scheme='cbcs',
|
||||||
|
key_rotation=True,
|
||||||
|
output_dash=True))
|
||||||
|
self._CheckTestResults('live-profile-and-key-rotation-cbcs')
|
||||||
|
|
||||||
def testLiveProfileAndKeyRotationAndNoPsshInStream(self):
|
def testLiveProfileAndKeyRotationAndNoPsshInStream(self):
|
||||||
self.assertPackageSuccess(
|
self.assertPackageSuccess(
|
||||||
self._GetStreams(['audio', 'video'], segmented=True),
|
self._GetStreams(['audio', 'video'], segmented=True),
|
||||||
|
|
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-audio-1.m4s
vendored
Normal file
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-audio-1.m4s
vendored
Normal file
Binary file not shown.
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-audio-2.m4s
vendored
Normal file
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-audio-2.m4s
vendored
Normal file
Binary file not shown.
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-audio-3.m4s
vendored
Normal file
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-audio-3.m4s
vendored
Normal file
Binary file not shown.
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-audio-init.mp4
vendored
Normal file
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-audio-init.mp4
vendored
Normal file
Binary file not shown.
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-video-1.m4s
vendored
Normal file
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-video-1.m4s
vendored
Normal file
Binary file not shown.
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-video-2.m4s
vendored
Normal file
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-video-2.m4s
vendored
Normal file
Binary file not shown.
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-video-3.m4s
vendored
Normal file
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-video-3.m4s
vendored
Normal file
Binary file not shown.
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-video-init.mp4
vendored
Normal file
BIN
packager/app/test/testdata/live-profile-and-key-rotation-cbcs/bear-640x360-video-init.mp4
vendored
Normal file
Binary file not shown.
|
@ -0,0 +1,32 @@
|
||||||
|
<?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" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns:cenc="urn:mpeg:cenc:2013" profiles="urn:mpeg:dash:profile:isoff-live:2011" minBufferTime="PT2S" type="dynamic" publishTime="some_time" availabilityStartTime="some_time" minimumUpdatePeriod="PT5S" timeShiftBufferDepth="PT1800S">
|
||||||
|
<Period id="0" start="PT0S">
|
||||||
|
<AdaptationSet id="0" contentType="video" width="640" height="360" frameRate="30000/1001" segmentAlignment="true" par="16:9">
|
||||||
|
<ContentProtection value="cbcs" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
||||||
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
||||||
|
<Representation id="0" bandwidth="977527" codecs="avc1.64001e" mimeType="video/mp4" sar="1:1">
|
||||||
|
<SegmentTemplate timescale="30000" initialization="bear-640x360-video-init.mp4" media="bear-640x360-video-$Number$.m4s" startNumber="1">
|
||||||
|
<SegmentTimeline>
|
||||||
|
<S t="0" d="30030" r="1"/>
|
||||||
|
<S t="60060" d="22022"/>
|
||||||
|
</SegmentTimeline>
|
||||||
|
</SegmentTemplate>
|
||||||
|
</Representation>
|
||||||
|
</AdaptationSet>
|
||||||
|
<AdaptationSet id="1" contentType="audio" segmentAlignment="true">
|
||||||
|
<ContentProtection value="cbcs" schemeIdUri="urn:mpeg:dash:mp4protection:2011"/>
|
||||||
|
<ContentProtection schemeIdUri="urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b"/>
|
||||||
|
<Representation id="1" bandwidth="134336" codecs="mp4a.40.2" mimeType="audio/mp4" audioSamplingRate="44100">
|
||||||
|
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
|
||||||
|
<SegmentTemplate timescale="44100" initialization="bear-640x360-audio-init.mp4" media="bear-640x360-audio-$Number$.m4s" startNumber="1">
|
||||||
|
<SegmentTimeline>
|
||||||
|
<S t="0" d="45056"/>
|
||||||
|
<S t="45056" d="44032"/>
|
||||||
|
<S t="89088" d="31744"/>
|
||||||
|
</SegmentTimeline>
|
||||||
|
</SegmentTemplate>
|
||||||
|
</Representation>
|
||||||
|
</AdaptationSet>
|
||||||
|
</Period>
|
||||||
|
</MPD>
|
|
@ -22,6 +22,7 @@
|
||||||
#include "packager/media/codecs/vp8_parser.h"
|
#include "packager/media/codecs/vp8_parser.h"
|
||||||
#include "packager/media/codecs/vp9_parser.h"
|
#include "packager/media/codecs/vp9_parser.h"
|
||||||
#include "packager/media/crypto/sample_aes_ec3_cryptor.h"
|
#include "packager/media/crypto/sample_aes_ec3_cryptor.h"
|
||||||
|
#include "packager/status_macros.h"
|
||||||
|
|
||||||
namespace shaka {
|
namespace shaka {
|
||||||
namespace media {
|
namespace media {
|
||||||
|
@ -32,10 +33,17 @@ const size_t kCencBlockSize = 16u;
|
||||||
// The encryption handler only supports a single output.
|
// The encryption handler only supports a single output.
|
||||||
const size_t kStreamIndex = 0;
|
const size_t kStreamIndex = 0;
|
||||||
|
|
||||||
// The default KID for key rotation is all 0s.
|
// The default KID, KEY and IV for key rotation are all 0s.
|
||||||
|
// They are placeholders and are not really being used to encrypt data.
|
||||||
const uint8_t kKeyRotationDefaultKeyId[] = {
|
const uint8_t kKeyRotationDefaultKeyId[] = {
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
};
|
};
|
||||||
|
const uint8_t kKeyRotationDefaultKey[] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
const uint8_t kKeyRotationDefaultIv[] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
// Adds one or more subsamples to |*decrypt_config|. This may add more than one
|
// Adds one or more subsamples to |*decrypt_config|. This may add more than one
|
||||||
// if one of the values overflows the integer in the subsample.
|
// if one of the values overflows the integer in the subsample.
|
||||||
|
@ -179,25 +187,21 @@ Status EncryptionHandler::ProcessStreamInfo(const StreamInfo& clear_info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Status status = SetupProtectionPattern(stream_info->stream_type());
|
RETURN_IF_ERROR(SetupProtectionPattern(stream_info->stream_type()));
|
||||||
if (!status.ok())
|
|
||||||
return status;
|
|
||||||
|
|
||||||
EncryptionKey encryption_key;
|
EncryptionKey encryption_key;
|
||||||
const bool key_rotation_enabled = crypto_period_duration_ != 0;
|
const bool key_rotation_enabled = crypto_period_duration_ != 0;
|
||||||
if (key_rotation_enabled) {
|
if (key_rotation_enabled) {
|
||||||
check_new_crypto_period_ = true;
|
check_new_crypto_period_ = true;
|
||||||
// Setup dummy key id and key to signal encryption for key rotation.
|
// Setup dummy key id, key and iv to signal encryption for key rotation.
|
||||||
encryption_key.key_id.assign(
|
encryption_key.key_id.assign(std::begin(kKeyRotationDefaultKeyId),
|
||||||
kKeyRotationDefaultKeyId,
|
std::end(kKeyRotationDefaultKeyId));
|
||||||
kKeyRotationDefaultKeyId + sizeof(kKeyRotationDefaultKeyId));
|
encryption_key.key.assign(std::begin(kKeyRotationDefaultKey),
|
||||||
// The key is not really used to encrypt any data. It is there just for
|
std::end(kKeyRotationDefaultKey));
|
||||||
// convenience.
|
encryption_key.iv.assign(std::begin(kKeyRotationDefaultIv),
|
||||||
encryption_key.key = encryption_key.key_id;
|
std::end(kKeyRotationDefaultIv));
|
||||||
} else {
|
} else {
|
||||||
status = key_source_->GetKey(stream_label_, &encryption_key);
|
RETURN_IF_ERROR(key_source_->GetKey(stream_label_, &encryption_key));
|
||||||
if (!status.ok())
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
if (!CreateEncryptor(encryption_key))
|
if (!CreateEncryptor(encryption_key))
|
||||||
return Status(error::ENCRYPTION_FAILURE, "Failed to create encryptor");
|
return Status(error::ENCRYPTION_FAILURE, "Failed to create encryptor");
|
||||||
|
@ -233,10 +237,8 @@ Status EncryptionHandler::ProcessMediaSample(
|
||||||
const int64_t current_crypto_period_index = dts / crypto_period_duration_;
|
const int64_t current_crypto_period_index = dts / crypto_period_duration_;
|
||||||
if (current_crypto_period_index != prev_crypto_period_index_) {
|
if (current_crypto_period_index != prev_crypto_period_index_) {
|
||||||
EncryptionKey encryption_key;
|
EncryptionKey encryption_key;
|
||||||
Status status = key_source_->GetCryptoPeriodKey(
|
RETURN_IF_ERROR(key_source_->GetCryptoPeriodKey(
|
||||||
current_crypto_period_index, stream_label_, &encryption_key);
|
current_crypto_period_index, stream_label_, &encryption_key));
|
||||||
if (!status.ok())
|
|
||||||
return status;
|
|
||||||
if (!CreateEncryptor(encryption_key))
|
if (!CreateEncryptor(encryption_key))
|
||||||
return Status(error::ENCRYPTION_FAILURE, "Failed to create encryptor");
|
return Status(error::ENCRYPTION_FAILURE, "Failed to create encryptor");
|
||||||
prev_crypto_period_index_ = current_crypto_period_index;
|
prev_crypto_period_index_ = current_crypto_period_index;
|
||||||
|
@ -355,14 +357,13 @@ Status EncryptionHandler::SetupProtectionPattern(StreamType stream_type) {
|
||||||
skip_byte_block_ = 9u;
|
skip_byte_block_ = 9u;
|
||||||
} else {
|
} else {
|
||||||
// Tracks other than video are protected using whole-block full-sample
|
// Tracks other than video are protected using whole-block full-sample
|
||||||
// encryption, which is essentially a pattern of 1:0. Note that this may
|
// encryption. Note that this may not be the same as the non-pattern
|
||||||
// not be the same as the non-pattern based encryption counterparts,
|
// based encryption counterparts, e.g. in 'cens' whole-block full sample
|
||||||
// e.g. in 'cens' for full sample encryption, the whole sample is
|
// encryption, the whole sample is encrypted up to the last 16-byte
|
||||||
// encrypted up to the last 16-byte boundary, see 23001-7:2016(E) 9.7;
|
// boundary, see 23001-7:2016(E) 9.7; while in 'cenc' full sample
|
||||||
// while in 'cenc' for full sample encryption, the last partial 16-byte
|
// encryption, the last partial 16-byte block is also encrypted, see
|
||||||
// block is also encrypted, see 23001-7:2016(E) 9.4.2. Another
|
// 23001-7:2016(E) 9.4.2. Another difference is the use of constant iv.
|
||||||
// difference is the use of constant iv.
|
crypt_byte_block_ = 0u;
|
||||||
crypt_byte_block_ = 1u;
|
|
||||||
skip_byte_block_ = 0u;
|
skip_byte_block_ = 0u;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -406,7 +406,7 @@ class EncryptionHandlerEncryptionTest
|
||||||
return 0;
|
return 0;
|
||||||
case FOURCC_cens:
|
case FOURCC_cens:
|
||||||
case FOURCC_cbcs:
|
case FOURCC_cbcs:
|
||||||
return 1;
|
return codec_ == kCodecAAC ? 0 : 1;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,11 +114,6 @@ void GenerateSinf(FourCC old_type,
|
||||||
break;
|
break;
|
||||||
case FOURCC_cbcs:
|
case FOURCC_cbcs:
|
||||||
case FOURCC_cens:
|
case FOURCC_cens:
|
||||||
if (track_encryption.default_skip_byte_block == 0) {
|
|
||||||
// Some clients, e.g. Safari v11.0.3 does not like having
|
|
||||||
// crypt_byte_block as a non-zero value when skip_byte_block is zero.
|
|
||||||
track_encryption.default_crypt_byte_block = 0;
|
|
||||||
}
|
|
||||||
// CENCv3 10.3 ‘cens’ AES-CTR subsample pattern encryption scheme and
|
// CENCv3 10.3 ‘cens’ AES-CTR subsample pattern encryption scheme and
|
||||||
// 10.4 ‘cbcs’ AES-CBC subsample pattern encryption scheme:
|
// 10.4 ‘cbcs’ AES-CBC subsample pattern encryption scheme:
|
||||||
// The version of the Track Encryption Box (‘tenc’) SHALL be 1.
|
// The version of the Track Encryption Box (‘tenc’) SHALL be 1.
|
||||||
|
|
Loading…
Reference in New Issue