Do not partially encrypt a segment
Mimic iso-bmff behavior: either all the samples in a segment are encrypted or all the samples are clear. Change-Id: I03bdbbf5a4b690f4d87c4dceb0f8155e6fae941e
This commit is contained in:
parent
23f2913248
commit
de9667080f
Binary file not shown.
|
@ -19,7 +19,6 @@ const std::string kKeyId = "4c6f72656d20697073756d20646f6c6f";
|
|||
const std::string kIv = "0123456789012345";
|
||||
const std::string kKey = "01234567890123456789012345678901";
|
||||
const std::string kPsshData = "";
|
||||
|
||||
const uint8_t kBasicSupportData[] = {
|
||||
// ID: EBML Header, Payload Size: 31
|
||||
0x1a, 0x45, 0xdf, 0xa3, 0x9f,
|
||||
|
@ -37,8 +36,8 @@ const uint8_t kBasicSupportData[] = {
|
|||
0x42, 0x87, 0x81, 0x02,
|
||||
// DocTypeReadVersion: 2
|
||||
0x42, 0x85, 0x81, 0x02,
|
||||
// ID: Segment, Payload Size: 411
|
||||
0x18, 0x53, 0x80, 0x67, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9b,
|
||||
// ID: Segment, Payload Size: 432
|
||||
0x18, 0x53, 0x80, 0x67, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb0,
|
||||
// ID: SeekHead, Payload Size: 58
|
||||
0x11, 0x4d, 0x9b, 0x74, 0xba,
|
||||
// ID: Seek, Payload Size: 11
|
||||
|
@ -63,8 +62,8 @@ const uint8_t kBasicSupportData[] = {
|
|||
0x4d, 0xbb, 0x8c,
|
||||
// SeekID: binary(4) (Cues)
|
||||
0x53, 0xab, 0x84, 0x1c, 0x53, 0xbb, 0x6b,
|
||||
// SeekPosition: 392
|
||||
0x53, 0xac, 0x82, 0x01, 0x88,
|
||||
// SeekPosition: 398
|
||||
0x53, 0xac, 0x82, 0x01, 0x8e,
|
||||
// ID: Void, Payload Size: 24
|
||||
0xec, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -131,8 +130,8 @@ const uint8_t kBasicSupportData[] = {
|
|||
0x54, 0xb0, 0x81, 0x64,
|
||||
// DisplayHeight: 100
|
||||
0x54, 0xba, 0x81, 0x64,
|
||||
// ID: Cluster, Payload Size: 101
|
||||
0x1f, 0x43, 0xb6, 0x75, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65,
|
||||
// ID: Cluster, Payload Size: 45
|
||||
0x1f, 0x43, 0xb6, 0x75, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d,
|
||||
// Timecode: 0
|
||||
0xe7, 0x81, 0x00,
|
||||
// ID: SimpleBlock, Payload Size: 10
|
||||
|
@ -141,44 +140,48 @@ const uint8_t kBasicSupportData[] = {
|
|||
0x00,
|
||||
// Frame Data:
|
||||
0xde, 0xad, 0xbe, 0xef, 0x00,
|
||||
// ID: SimpleBlock, Payload Size: 18
|
||||
0xa3, 0x92, 0x81, 0x03, 0xe8, 0x80,
|
||||
// ID: SimpleBlock, Payload Size: 10
|
||||
0xa3, 0x8a, 0x81, 0x03, 0xe8, 0x80,
|
||||
// Signal Byte: Clear
|
||||
0x00,
|
||||
// Frame Data:
|
||||
0xde, 0xad, 0xbe, 0xef, 0x00,
|
||||
// ID: BlockGroup, Payload Size: 16
|
||||
0xa0, 0x90,
|
||||
// ID: Block, Payload Size: 10
|
||||
0xa1, 0x8a, 0x81, 0x07, 0xd0, 0x00,
|
||||
// Signal Byte: Clear
|
||||
0x00,
|
||||
// Frame Data:
|
||||
0xde, 0xad, 0xbe, 0xef, 0x00,
|
||||
// BlockDuration: 1000
|
||||
0x9b, 0x82, 0x03, 0xe8,
|
||||
// ID: Cluster, Payload Size: 50
|
||||
0x1f, 0x43, 0xb6, 0x75, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32,
|
||||
// Timecode: 3000
|
||||
0xe7, 0x82, 0x0b, 0xb8,
|
||||
// ID: SimpleBlock: Payload Size: 18
|
||||
0xa3, 0x92, 0x81, 0x00,0x00, 0x80,
|
||||
// Signal Byte: Encrypted
|
||||
0x01,
|
||||
// IV:
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x23, 0x45,
|
||||
// Frame Data:
|
||||
0xcc, 0x03, 0xef, 0xc4, 0xf4,
|
||||
// ID: SimpleBlock, Payload Size: 18
|
||||
0xa3, 0x92, 0x81, 0x07, 0xd0, 0x80,
|
||||
// Signal Byte: Encrypted
|
||||
0x01,
|
||||
// IV:
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x23, 0x46,
|
||||
// Frame Data:
|
||||
0xbf, 0x38, 0x72, 0x20, 0xac,
|
||||
// ID: SimpleBlock, Payload Size: 18
|
||||
0xa3, 0x92, 0x81, 0x0b, 0xb8, 0x80,
|
||||
// Signal Byte: Encrypted
|
||||
0x01,
|
||||
// IV:
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x23, 0x47,
|
||||
// Frame Data:
|
||||
0x0d, 0x8e, 0xae, 0xbe, 0xd0,
|
||||
// ID: BlockGroup, Payload Size: 24
|
||||
0xa0, 0x98,
|
||||
// ID: Block, Payload Size: 18
|
||||
0xa1, 0x92, 0x81, 0x0f, 0xa0, 0x00,
|
||||
0xa1, 0x92, 0x81, 0x03, 0xe8, 0x00,
|
||||
// Signal Byte: Encrypted
|
||||
0x01,
|
||||
// IV:
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x23, 0x48,
|
||||
0x01, 0x23, 0x45, 0x67, 0x89, 0x01, 0x23, 0x46,
|
||||
// Frame Data:
|
||||
0xa5, 0x97, 0xf8, 0x9e, 0x87,
|
||||
0xbf, 0x38, 0x72, 0x20, 0xac,
|
||||
// BlockDuration: 1000
|
||||
0x9b, 0x82, 0x03, 0xe8,
|
||||
// ID: Cues, Payload Size: 14
|
||||
0x1c, 0x53, 0xbb, 0x6b, 0x8e,
|
||||
// ID: Cues, Payload Size: 29
|
||||
0x1c, 0x53, 0xbb, 0x6b, 0x9d,
|
||||
// ID: CuePoint, Payload Size: 12
|
||||
0xbb, 0x8c,
|
||||
// CueTime: 0
|
||||
|
@ -188,7 +191,17 @@ const uint8_t kBasicSupportData[] = {
|
|||
// CueTrack: 1
|
||||
0xf7, 0x81, 0x01,
|
||||
// CueClusterPosition: 279
|
||||
0xf1, 0x82, 0x01, 0x17
|
||||
0xf1, 0x82, 0x01, 0x17,
|
||||
// ID: CuePoint, Payload Size: 13
|
||||
0xbb, 0x8d,
|
||||
// CueTime: 3000
|
||||
0xb3, 0x82, 0x0b, 0xb8,
|
||||
// ID: CueTrackPositions, Payload Size: 7
|
||||
0xb7, 0x87,
|
||||
// CueTrack: 1
|
||||
0xf7, 0x81, 0x01,
|
||||
// CueClusterPosition: 336
|
||||
0xf1, 0x82, 0x01, 0x50,
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
@ -213,9 +226,12 @@ class EncrypedSegmenterTest : public SegmentTestBase {
|
|||
|
||||
TEST_F(EncrypedSegmenterTest, BasicSupport) {
|
||||
MuxerOptions options = CreateMuxerOptions();
|
||||
options.segment_duration = 3.0;
|
||||
ASSERT_NO_FATAL_FAILURE(InitializeSegmenter(options));
|
||||
|
||||
// Write the samples to the Segmenter.
|
||||
// There should be 2 segments with the first segment in clear and the second
|
||||
// segment encrypted.
|
||||
for (int i = 0; i < 5; i++) {
|
||||
scoped_refptr<MediaSample> sample =
|
||||
CreateSample(kKeyFrame, kDuration, kNoSideData);
|
||||
|
@ -228,4 +244,3 @@ TEST_F(EncrypedSegmenterTest, BasicSupport) {
|
|||
|
||||
} // namespace media
|
||||
} // namespace shaka
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@ int64_t kSecondsToNs = 1000000000L;
|
|||
Segmenter::Segmenter(const MuxerOptions& options)
|
||||
: reference_frame_timestamp_(0),
|
||||
options_(options),
|
||||
clear_lead_(0),
|
||||
enable_encryption_(false),
|
||||
info_(NULL),
|
||||
muxer_listener_(NULL),
|
||||
progress_listener_(NULL),
|
||||
|
@ -144,6 +146,15 @@ Status Segmenter::AddSample(scoped_refptr<MediaSample> sample) {
|
|||
segment_length_sec_ = 0;
|
||||
cluster_length_sec_ = 0;
|
||||
wrote_frame = true;
|
||||
|
||||
if (encryptor_ && !enable_encryption_) {
|
||||
if (sample->pts() - first_timestamp_ >=
|
||||
clear_lead_ * info_->time_scale()) {
|
||||
enable_encryption_ = true;
|
||||
if (muxer_listener_)
|
||||
muxer_listener_->OnEncryptionStart();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (cluster_length_sec_ >= options_.fragment_duration) {
|
||||
if (sample->is_key_frame() || !options_.fragment_sap_aligned) {
|
||||
|
@ -161,20 +172,13 @@ Status Segmenter::AddSample(scoped_refptr<MediaSample> sample) {
|
|||
|
||||
// Encrypt the frame.
|
||||
if (encryptor_) {
|
||||
const bool encrypt_frame =
|
||||
static_cast<double>(sample->pts() - first_timestamp_) /
|
||||
info_->time_scale() >=
|
||||
clear_lead_;
|
||||
status = encryptor_->EncryptFrame(sample, encrypt_frame);
|
||||
status = encryptor_->EncryptFrame(sample, enable_encryption_);
|
||||
if (!status.ok()) {
|
||||
LOG(ERROR) << "Error encrypting frame.";
|
||||
return status;
|
||||
}
|
||||
if (encrypt_frame && muxer_listener_)
|
||||
muxer_listener_->OnEncryptionStart();
|
||||
}
|
||||
|
||||
|
||||
// Add the sample to the durations even though we have not written the frame
|
||||
// yet. This is needed to make sure we split Clusters at the correct point.
|
||||
// These are only used in this method.
|
||||
|
|
|
@ -135,6 +135,7 @@ class Segmenter {
|
|||
const MuxerOptions& options_;
|
||||
std::unique_ptr<Encryptor> encryptor_;
|
||||
double clear_lead_;
|
||||
bool enable_encryption_; // Encryption is enabled only after clear_lead_.
|
||||
|
||||
std::unique_ptr<mkvmuxer::Cluster> cluster_;
|
||||
mkvmuxer::Cues cues_;
|
||||
|
|
Loading…
Reference in New Issue