OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |