7 #include "packager/media/formats/mp4/encrypting_fragmenter.h"
9 #include "packager/media/base/aes_encryptor.h"
10 #include "packager/media/base/buffer_reader.h"
11 #include "packager/media/base/key_source.h"
12 #include "packager/media/base/media_sample.h"
13 #include "packager/media/formats/mp4/box_definitions.h"
14 #include "packager/media/formats/mp4/cenc.h"
18 const size_t kDefaultIvSize = 8u;
21 namespace edash_packager {
27 scoped_ptr<EncryptionKey> encryption_key,
29 uint8_t nalu_length_size)
31 encryption_key_(encryption_key.Pass()),
32 nalu_length_size_(nalu_length_size),
33 clear_time_(clear_time) {
34 DCHECK(encryption_key_);
36 EncryptingFragmenter::~EncryptingFragmenter() {}
41 if (!fragment_initialized()) {
47 Status status = EncryptSample(sample);
59 traf()->auxiliary_size.sample_info_sizes.clear();
60 traf()->auxiliary_offset.offsets.clear();
62 const bool enable_encryption = clear_time_ <= 0;
63 if (!enable_encryption) {
67 const uint32_t kClearSampleDescriptionIndex = 2;
69 traf()->header.flags |=
70 TrackFragmentHeader::kSampleDescriptionIndexPresentMask;
71 traf()->header.sample_description_index = kClearSampleDescriptionIndex;
78 DCHECK_LE(clear_time_, 0);
81 DCHECK_GT(clear_time_, 0);
82 clear_time_ -= fragment_duration();
88 bool enable_encryption) {
89 return (!enable_encryption || encryptor_) ? Status::OK :
CreateEncryptor();
94 traf()->auxiliary_offset.offsets.push_back(0);
98 saiz.sample_count = traf()->runs[0].sample_sizes.size();
99 if (!saiz.sample_info_sizes.empty()) {
101 &saiz.default_sample_info_size)) {
102 saiz.default_sample_info_size = 0;
107 DCHECK(!IsSubsampleEncryptionRequired());
108 saiz.default_sample_info_size = encryptor_->iv().size();
113 DCHECK(encryption_key_);
116 const bool initialized = encryption_key_->iv.empty()
117 ? encryptor->InitializeWithRandomIv(
118 encryption_key_->key, kDefaultIvSize)
119 : encryptor->InitializeWithIv(
120 encryption_key_->key, encryption_key_->iv);
122 return Status(error::MUXER_FAILURE,
"Failed to create the encryptor.");
123 encryptor_ = encryptor.Pass();
127 void EncryptingFragmenter::EncryptBytes(uint8_t* data, uint32_t size) {
129 CHECK(encryptor_->Encrypt(data, size, data));
132 Status EncryptingFragmenter::EncryptSample(scoped_refptr<MediaSample> sample) {
135 FrameCENCInfo cenc_info(encryptor_->iv());
136 uint8_t* data = sample->writable_data();
137 if (!IsSubsampleEncryptionRequired()) {
138 EncryptBytes(data, sample->data_size());
140 BufferReader reader(data, sample->data_size());
141 while (reader.HasBytes(1)) {
142 uint64_t nalu_length;
143 if (!reader.ReadNBytesInto8(&nalu_length, nalu_length_size_))
144 return Status(error::MUXER_FAILURE,
"Fail to read nalu_length.");
146 SubsampleEntry subsample;
147 subsample.clear_bytes = nalu_length_size_ + 1;
148 subsample.cipher_bytes = nalu_length - 1;
149 if (!reader.SkipBytes(nalu_length)) {
150 return Status(error::MUXER_FAILURE,
151 "Sample size does not match nalu_length.");
154 EncryptBytes(data + subsample.clear_bytes, subsample.cipher_bytes);
155 cenc_info.AddSubsample(subsample);
156 data += nalu_length_size_ + nalu_length;
160 traf()->auxiliary_size.sample_info_sizes.push_back(cenc_info.ComputeSize());
163 cenc_info.Write(aux_data());
164 encryptor_->UpdateIv();