Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(238)

Side by Side Diff: media/formats/mp4/box_definitions.cc

Issue 1998333002: MP4 support for Common Encryption 'cbcs' scheme. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix a problem in hasty change before upload Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/formats/mp4/box_definitions.h" 5 #include "media/formats/mp4/box_definitions.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "media/base/video_types.h" 12 #include "media/base/video_types.h"
13 #include "media/base/video_util.h" 13 #include "media/base/video_util.h"
14 #include "media/formats/mp4/avc.h" 14 #include "media/formats/mp4/avc.h"
15 #include "media/formats/mp4/es_descriptor.h" 15 #include "media/formats/mp4/es_descriptor.h"
16 #include "media/formats/mp4/rcheck.h" 16 #include "media/formats/mp4/rcheck.h"
17 #include "media/media_features.h" 17 #include "media/media_features.h"
18 18
19 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 19 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
20 #include "media/formats/mp4/hevc.h" 20 #include "media/formats/mp4/hevc.h"
21 #endif 21 #endif
22 22
23 namespace media { 23 namespace media {
24 namespace mp4 { 24 namespace mp4 {
25 25
26 namespace {
27
28 const size_t kKeyIdSize = 16;
29
30 } // namespace
31
26 FileType::FileType() {} 32 FileType::FileType() {}
27 FileType::FileType(const FileType& other) = default; 33 FileType::FileType(const FileType& other) = default;
28 FileType::~FileType() {} 34 FileType::~FileType() {}
29 FourCC FileType::BoxType() const { return FOURCC_FTYP; } 35 FourCC FileType::BoxType() const { return FOURCC_FTYP; }
30 36
31 bool FileType::Parse(BoxReader* reader) { 37 bool FileType::Parse(BoxReader* reader) {
32 RCHECK(reader->ReadFourCC(&major_brand) && reader->Read4(&minor_version)); 38 RCHECK(reader->ReadFourCC(&major_brand) && reader->Read4(&minor_version));
33 size_t num_brands = (reader->size() - reader->pos()) / sizeof(FourCC); 39 size_t num_brands = (reader->size() - reader->pos()) / sizeof(FourCC);
34 return reader->SkipBytes(sizeof(FourCC) * num_brands); // compatible_brands 40 return reader->SkipBytes(sizeof(FourCC) * num_brands); // compatible_brands
35 } 41 }
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 239
234 TrackEncryption::TrackEncryption() 240 TrackEncryption::TrackEncryption()
235 : is_encrypted(false), default_iv_size(0) { 241 : is_encrypted(false), default_iv_size(0) {
236 } 242 }
237 TrackEncryption::TrackEncryption(const TrackEncryption& other) = default; 243 TrackEncryption::TrackEncryption(const TrackEncryption& other) = default;
238 TrackEncryption::~TrackEncryption() {} 244 TrackEncryption::~TrackEncryption() {}
239 FourCC TrackEncryption::BoxType() const { return FOURCC_TENC; } 245 FourCC TrackEncryption::BoxType() const { return FOURCC_TENC; }
240 246
241 bool TrackEncryption::Parse(BoxReader* reader) { 247 bool TrackEncryption::Parse(BoxReader* reader) {
242 uint8_t flag; 248 uint8_t flag;
243 RCHECK(reader->ReadFullBoxHeader() && 249 uint8_t possible_pattern_info;
244 reader->SkipBytes(2) && 250 RCHECK(reader->ReadFullBoxHeader() && reader->SkipBytes(1) &&
245 reader->Read1(&flag) && 251 reader->Read1(&possible_pattern_info) && reader->Read1(&flag) &&
246 reader->Read1(&default_iv_size) && 252 reader->Read1(&default_iv_size) && reader->ReadVec(&default_kid, 16));
kqyang 2016/05/23 20:57:34 s/16/kKeyIdSize/
dougsteed 2016/05/25 17:23:21 Done.
247 reader->ReadVec(&default_kid, 16));
248 is_encrypted = (flag != 0); 253 is_encrypted = (flag != 0);
249 if (is_encrypted) { 254 if (default_iv_size != 0) {
250 RCHECK(default_iv_size == 8 || default_iv_size == 16); 255 RCHECK(default_iv_size == 8 || default_iv_size == 16);
256 #if BUILDFLAG(ENABLE_CENC_NEW_EDITIONS)
kqyang 2016/05/23 20:57:34 I'd prefer as less preprocessor primitive in the c
ddorwin 2016/05/24 23:25:03 I'm worried about all the ifdef'd code being added
dougsteed 2016/05/25 17:23:21 Changed the name as suggested.
257 } else if (is_encrypted) {
258 if (reader->version() > 0) {
259 default_crypt_byte_block = (possible_pattern_info >> 4) & 0x0f;
260 default_skip_byte_block = possible_pattern_info & 0x0f;
261 }
262 RCHECK(reader->Read1(&default_constant_iv_size) &&
263 (default_constant_iv_size == 8 || default_constant_iv_size == 16));
264 memset(default_constant_iv, 0, sizeof(default_constant_iv));
265 for (uint8_t i = 0; i < default_constant_iv_size; i++)
266 RCHECK(reader->Read1(default_constant_iv + i));
267 #endif
251 } else { 268 } else {
252 RCHECK(default_iv_size == 0); 269 RCHECK(!is_encrypted);
253 } 270 }
254 return true; 271 return true;
255 } 272 }
256 273
257 SchemeInfo::SchemeInfo() {} 274 SchemeInfo::SchemeInfo() {}
258 SchemeInfo::SchemeInfo(const SchemeInfo& other) = default; 275 SchemeInfo::SchemeInfo(const SchemeInfo& other) = default;
259 SchemeInfo::~SchemeInfo() {} 276 SchemeInfo::~SchemeInfo() {}
260 FourCC SchemeInfo::BoxType() const { return FOURCC_SCHI; } 277 FourCC SchemeInfo::BoxType() const { return FOURCC_SCHI; }
261 278
262 bool SchemeInfo::Parse(BoxReader* reader) { 279 bool SchemeInfo::Parse(BoxReader* reader) {
263 return reader->ScanChildren() && reader->ReadChild(&track_encryption); 280 return reader->ScanChildren() && reader->ReadChild(&track_encryption);
264 } 281 }
265 282
266 ProtectionSchemeInfo::ProtectionSchemeInfo() {} 283 ProtectionSchemeInfo::ProtectionSchemeInfo() {}
267 ProtectionSchemeInfo::ProtectionSchemeInfo(const ProtectionSchemeInfo& other) = 284 ProtectionSchemeInfo::ProtectionSchemeInfo(const ProtectionSchemeInfo& other) =
268 default; 285 default;
269 ProtectionSchemeInfo::~ProtectionSchemeInfo() {} 286 ProtectionSchemeInfo::~ProtectionSchemeInfo() {}
270 FourCC ProtectionSchemeInfo::BoxType() const { return FOURCC_SINF; } 287 FourCC ProtectionSchemeInfo::BoxType() const { return FOURCC_SINF; }
271 288
272 bool ProtectionSchemeInfo::Parse(BoxReader* reader) { 289 bool ProtectionSchemeInfo::Parse(BoxReader* reader) {
273 RCHECK(reader->ScanChildren() && 290 RCHECK(reader->ScanChildren() &&
274 reader->ReadChild(&format) && 291 reader->ReadChild(&format) &&
275 reader->ReadChild(&type)); 292 reader->ReadChild(&type));
276 if (type.type == FOURCC_CENC) 293 if (HasSupportedScheme())
277 RCHECK(reader->ReadChild(&info)); 294 RCHECK(reader->ReadChild(&info));
278 // Other protection schemes are silently ignored. Since the protection scheme 295 // Other protection schemes are silently ignored. Since the protection scheme
279 // type can't be determined until this box is opened, we return 'true' for 296 // type can't be determined until this box is opened, we return 'true' for
280 // non-CENC protection scheme types. It is the parent box's responsibility to 297 // non-CENC protection scheme types. It is the parent box's responsibility to
281 // ensure that this scheme type is a supported one. 298 // ensure that this scheme type is a supported one.
282 return true; 299 return true;
283 } 300 }
284 301
302 bool ProtectionSchemeInfo::HasSupportedScheme() const {
303 FourCC fourCC = type.type;
304 if (fourCC == FOURCC_CENC)
305 return true;
306 #if BUILDFLAG(ENABLE_CENC_NEW_EDITIONS)
307 return fourCC == FOURCC_CBC1 || fourCC == FOURCC_CBCS ||
ddorwin 2016/05/24 23:25:03 Are there actual use cases for the other two? If n
dougsteed 2016/05/25 17:23:21 Done.
308 fourCC == FOURCC_CENS;
309 #else
310 return false;
311 #endif
312 }
313
285 MovieHeader::MovieHeader() 314 MovieHeader::MovieHeader()
286 : creation_time(0), 315 : creation_time(0),
287 modification_time(0), 316 modification_time(0),
288 timescale(0), 317 timescale(0),
289 duration(0), 318 duration(0),
290 rate(-1), 319 rate(-1),
291 volume(-1), 320 volume(-1),
292 next_track_id(0) {} 321 next_track_id(0) {}
293 MovieHeader::MovieHeader(const MovieHeader& other) = default; 322 MovieHeader::MovieHeader(const MovieHeader& other) = default;
294 MovieHeader::~MovieHeader() {} 323 MovieHeader::~MovieHeader() {}
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 reader->Read2(&width) && 631 reader->Read2(&width) &&
603 reader->Read2(&height) && 632 reader->Read2(&height) &&
604 reader->SkipBytes(50)); 633 reader->SkipBytes(50));
605 634
606 RCHECK(reader->ScanChildren() && 635 RCHECK(reader->ScanChildren() &&
607 reader->MaybeReadChild(&pixel_aspect)); 636 reader->MaybeReadChild(&pixel_aspect));
608 637
609 if (format == FOURCC_ENCV) { 638 if (format == FOURCC_ENCV) {
610 // Continue scanning until a recognized protection scheme is found, or until 639 // Continue scanning until a recognized protection scheme is found, or until
611 // we run out of protection schemes. 640 // we run out of protection schemes.
612 while (sinf.type.type != FOURCC_CENC) { 641 while (!sinf.HasSupportedScheme()) {
613 if (!reader->ReadChild(&sinf)) 642 if (!reader->ReadChild(&sinf))
614 return false; 643 return false;
615 } 644 }
616 } 645 }
617 646
618 const FourCC actual_format = 647 const FourCC actual_format =
619 format == FOURCC_ENCV ? sinf.format.format : format; 648 format == FOURCC_ENCV ? sinf.format.format : format;
620 switch (actual_format) { 649 switch (actual_format) {
621 case FOURCC_AVC1: 650 case FOURCC_AVC1:
622 case FOURCC_AVC3: { 651 case FOURCC_AVC3: {
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 reader->Read2(&samplesize) && 771 reader->Read2(&samplesize) &&
743 reader->SkipBytes(4) && 772 reader->SkipBytes(4) &&
744 reader->Read4(&samplerate)); 773 reader->Read4(&samplerate));
745 // Convert from 16.16 fixed point to integer 774 // Convert from 16.16 fixed point to integer
746 samplerate >>= 16; 775 samplerate >>= 16;
747 776
748 RCHECK(reader->ScanChildren()); 777 RCHECK(reader->ScanChildren());
749 if (format == FOURCC_ENCA) { 778 if (format == FOURCC_ENCA) {
750 // Continue scanning until a recognized protection scheme is found, or until 779 // Continue scanning until a recognized protection scheme is found, or until
751 // we run out of protection schemes. 780 // we run out of protection schemes.
752 while (sinf.type.type != FOURCC_CENC) { 781 while (!sinf.HasSupportedScheme()) {
753 if (!reader->ReadChild(&sinf)) 782 if (!reader->ReadChild(&sinf))
754 return false; 783 return false;
755 } 784 }
756 } 785 }
757 786
758 // ESDS is not valid in case of EAC3. 787 // ESDS is not valid in case of EAC3.
759 RCHECK(reader->MaybeReadChild(&esds)); 788 RCHECK(reader->MaybeReadChild(&esds));
760 return true; 789 return true;
761 } 790 }
762 791
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 } 1116 }
1088 return true; 1117 return true;
1089 } 1118 }
1090 1119
1091 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry() 1120 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
1092 : is_encrypted(false), iv_size(0) {} 1121 : is_encrypted(false), iv_size(0) {}
1093 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry( 1122 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry(
1094 const CencSampleEncryptionInfoEntry& other) = default; 1123 const CencSampleEncryptionInfoEntry& other) = default;
1095 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {} 1124 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {}
1096 1125
1126 bool CencSampleEncryptionInfoEntry::Parse(BoxReader* reader) {
1127 uint8_t flag;
1128 uint8_t possible_pattern_info;
1129 RCHECK(reader->SkipBytes(1) && // reserved.
1130 reader->Read1(&possible_pattern_info) && reader->Read1(&flag) &&
1131 reader->Read1(&iv_size) && reader->ReadVec(&key_id, kKeyIdSize));
1132
1133 is_encrypted = (flag != 0);
1134 if (iv_size != 0) {
1135 RCHECK(iv_size == 8 || iv_size == 16);
1136 #if BUILDFLAG(ENABLE_CENC_NEW_EDITIONS)
1137 } else if (is_encrypted) {
1138 crypt_byte_block = (possible_pattern_info >> 4) & 0x0f;
1139 skip_byte_block = possible_pattern_info & 0x0f;
1140 RCHECK(reader->Read1(&constant_iv_size) &&
1141 (constant_iv_size == 8 || constant_iv_size == 16));
1142 memset(constant_iv, 0, sizeof(constant_iv));
1143 for (uint8_t i = 0; i < constant_iv_size; i++)
1144 RCHECK(reader->Read1(constant_iv + i));
1145 #endif
1146 } else {
1147 RCHECK(!is_encrypted);
1148 }
1149 return true;
1150 }
1151
1097 SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {} 1152 SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {}
1098 SampleGroupDescription::SampleGroupDescription( 1153 SampleGroupDescription::SampleGroupDescription(
1099 const SampleGroupDescription& other) = default; 1154 const SampleGroupDescription& other) = default;
1100 SampleGroupDescription::~SampleGroupDescription() {} 1155 SampleGroupDescription::~SampleGroupDescription() {}
1101 FourCC SampleGroupDescription::BoxType() const { return FOURCC_SGPD; } 1156 FourCC SampleGroupDescription::BoxType() const { return FOURCC_SGPD; }
1102 1157
1103 bool SampleGroupDescription::Parse(BoxReader* reader) { 1158 bool SampleGroupDescription::Parse(BoxReader* reader) {
1104 RCHECK(reader->ReadFullBoxHeader() && 1159 RCHECK(reader->ReadFullBoxHeader() &&
1105 reader->Read4(&grouping_type)); 1160 reader->Read4(&grouping_type));
1106 1161
1107 if (grouping_type != FOURCC_SEIG) { 1162 if (grouping_type != FOURCC_SEIG) {
1108 DLOG(WARNING) << "SampleGroupDescription box with grouping_type '" 1163 DLOG(WARNING) << "SampleGroupDescription box with grouping_type '"
1109 << grouping_type << "' is not supported."; 1164 << grouping_type << "' is not supported.";
1110 return true; 1165 return true;
1111 } 1166 }
1112 1167
1113 const uint8_t version = reader->version(); 1168 const uint8_t version = reader->version();
1114 1169
1115 const size_t kKeyIdSize = 16;
1116 const size_t kEntrySize = sizeof(uint32_t) + kKeyIdSize; 1170 const size_t kEntrySize = sizeof(uint32_t) + kKeyIdSize;
1117 uint32_t default_length = 0; 1171 uint32_t default_length = 0;
1118 if (version == 1) { 1172 if (version == 1) {
1119 RCHECK(reader->Read4(&default_length)); 1173 RCHECK(reader->Read4(&default_length));
1120 RCHECK(default_length == 0 || default_length >= kEntrySize); 1174 RCHECK(default_length == 0 || default_length >= kEntrySize);
1121 } 1175 }
1122 1176
1123 uint32_t count; 1177 uint32_t count;
1124 RCHECK(reader->Read4(&count)); 1178 RCHECK(reader->Read4(&count));
1125 entries.resize(count); 1179 entries.resize(count);
1126 for (uint32_t i = 0; i < count; ++i) { 1180 for (uint32_t i = 0; i < count; ++i) {
1127 if (version == 1) { 1181 if (version == 1) {
1128 if (default_length == 0) { 1182 if (default_length == 0) {
1129 uint32_t description_length = 0; 1183 uint32_t description_length = 0;
1130 RCHECK(reader->Read4(&description_length)); 1184 RCHECK(reader->Read4(&description_length));
1131 RCHECK(description_length >= kEntrySize); 1185 RCHECK(description_length >= kEntrySize);
1132 } 1186 }
1133 } 1187 }
1134 1188 RCHECK(entries[i].Parse(reader));
1135 uint8_t flag;
1136 RCHECK(reader->SkipBytes(2) && // reserved.
1137 reader->Read1(&flag) &&
1138 reader->Read1(&entries[i].iv_size) &&
1139 reader->ReadVec(&entries[i].key_id, kKeyIdSize));
1140
1141 entries[i].is_encrypted = (flag != 0);
1142 if (entries[i].is_encrypted) {
1143 RCHECK(entries[i].iv_size == 8 || entries[i].iv_size == 16);
1144 } else {
1145 RCHECK(entries[i].iv_size == 0);
1146 }
1147 } 1189 }
1148 return true; 1190 return true;
1149 } 1191 }
1150 1192
1151 TrackFragment::TrackFragment() {} 1193 TrackFragment::TrackFragment() {}
1152 TrackFragment::TrackFragment(const TrackFragment& other) = default; 1194 TrackFragment::TrackFragment(const TrackFragment& other) = default;
1153 TrackFragment::~TrackFragment() {} 1195 TrackFragment::~TrackFragment() {}
1154 FourCC TrackFragment::BoxType() const { return FOURCC_TRAF; } 1196 FourCC TrackFragment::BoxType() const { return FOURCC_TRAF; }
1155 1197
1156 bool TrackFragment::Parse(BoxReader* reader) { 1198 bool TrackFragment::Parse(BoxReader* reader) {
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1224 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on( 1266 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on(
1225 size_t i) const { 1267 size_t i) const {
1226 if (i >= sample_depends_on_.size()) 1268 if (i >= sample_depends_on_.size())
1227 return kSampleDependsOnUnknown; 1269 return kSampleDependsOnUnknown;
1228 1270
1229 return sample_depends_on_[i]; 1271 return sample_depends_on_[i];
1230 } 1272 }
1231 1273
1232 } // namespace mp4 1274 } // namespace mp4
1233 } // namespace media 1275 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698