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

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: another ddorwin comment Created 4 years 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
« no previous file with comments | « media/formats/mp4/box_definitions.h ('k') | media/formats/mp4/fourccs.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/command_line.h" 10 #include "base/command_line.h"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "media/base/media_switches.h" 13 #include "media/base/media_switches.h"
14 #include "media/base/video_types.h" 14 #include "media/base/video_types.h"
15 #include "media/base/video_util.h" 15 #include "media/base/video_util.h"
16 #include "media/filters/h264_parser.h" 16 #include "media/filters/h264_parser.h"
17 #include "media/formats/mp4/avc.h" 17 #include "media/formats/mp4/avc.h"
18 #include "media/formats/mp4/es_descriptor.h" 18 #include "media/formats/mp4/es_descriptor.h"
19 #include "media/formats/mp4/rcheck.h" 19 #include "media/formats/mp4/rcheck.h"
20 #include "media/media_features.h" 20 #include "media/media_features.h"
21 21
22 #if BUILDFLAG(ENABLE_HEVC_DEMUXING) 22 #if BUILDFLAG(ENABLE_HEVC_DEMUXING)
23 #include "media/formats/mp4/hevc.h" 23 #include "media/formats/mp4/hevc.h"
24 #endif 24 #endif
25 25
26 namespace media { 26 namespace media {
27 namespace mp4 { 27 namespace mp4 {
28 28
29 namespace {
30
31 const size_t kKeyIdSize = 16;
32
33 } // namespace
34
29 FileType::FileType() {} 35 FileType::FileType() {}
30 FileType::FileType(const FileType& other) = default; 36 FileType::FileType(const FileType& other) = default;
31 FileType::~FileType() {} 37 FileType::~FileType() {}
32 FourCC FileType::BoxType() const { return FOURCC_FTYP; } 38 FourCC FileType::BoxType() const { return FOURCC_FTYP; }
33 39
34 bool FileType::Parse(BoxReader* reader) { 40 bool FileType::Parse(BoxReader* reader) {
35 RCHECK(reader->ReadFourCC(&major_brand) && reader->Read4(&minor_version)); 41 RCHECK(reader->ReadFourCC(&major_brand) && reader->Read4(&minor_version));
36 size_t num_brands = (reader->size() - reader->pos()) / sizeof(FourCC); 42 size_t num_brands = (reader->size() - reader->pos()) / sizeof(FourCC);
37 return reader->SkipBytes(sizeof(FourCC) * num_brands); // compatible_brands 43 return reader->SkipBytes(sizeof(FourCC) * num_brands); // compatible_brands
38 } 44 }
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 159
154 SampleEncryptionEntry::SampleEncryptionEntry() {} 160 SampleEncryptionEntry::SampleEncryptionEntry() {}
155 SampleEncryptionEntry::SampleEncryptionEntry( 161 SampleEncryptionEntry::SampleEncryptionEntry(
156 const SampleEncryptionEntry& other) = default; 162 const SampleEncryptionEntry& other) = default;
157 SampleEncryptionEntry::~SampleEncryptionEntry() {} 163 SampleEncryptionEntry::~SampleEncryptionEntry() {}
158 164
159 bool SampleEncryptionEntry::Parse(BufferReader* reader, 165 bool SampleEncryptionEntry::Parse(BufferReader* reader,
160 uint8_t iv_size, 166 uint8_t iv_size,
161 bool has_subsamples) { 167 bool has_subsamples) {
162 // According to ISO/IEC FDIS 23001-7: CENC spec, IV should be either 168 // According to ISO/IEC FDIS 23001-7: CENC spec, IV should be either
163 // 64-bit (8-byte) or 128-bit (16-byte). 169 // 64-bit (8-byte) or 128-bit (16-byte). The 3rd Edition allows |iv_size|
164 RCHECK(iv_size == 8 || iv_size == 16); 170 // to be 0, for the case of a "constant IV". In this case, the existence of
171 // the constant IV must be ensured by the caller.
172 RCHECK(iv_size == 0 || iv_size == 8 || iv_size == 16);
165 173
166 memset(initialization_vector, 0, sizeof(initialization_vector)); 174 memset(initialization_vector, 0, sizeof(initialization_vector));
167 for (uint8_t i = 0; i < iv_size; i++) 175 for (uint8_t i = 0; i < iv_size; i++)
168 RCHECK(reader->Read1(initialization_vector + i)); 176 RCHECK(reader->Read1(initialization_vector + i));
169 177
170 if (!has_subsamples) { 178 if (!has_subsamples) {
171 subsamples.clear(); 179 subsamples.clear();
172 return true; 180 return true;
173 } 181 }
174 182
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 FourCC SchemeType::BoxType() const { return FOURCC_SCHM; } 236 FourCC SchemeType::BoxType() const { return FOURCC_SCHM; }
229 237
230 bool SchemeType::Parse(BoxReader* reader) { 238 bool SchemeType::Parse(BoxReader* reader) {
231 RCHECK(reader->ReadFullBoxHeader() && 239 RCHECK(reader->ReadFullBoxHeader() &&
232 reader->ReadFourCC(&type) && 240 reader->ReadFourCC(&type) &&
233 reader->Read4(&version)); 241 reader->Read4(&version));
234 return true; 242 return true;
235 } 243 }
236 244
237 TrackEncryption::TrackEncryption() 245 TrackEncryption::TrackEncryption()
238 : is_encrypted(false), default_iv_size(0) { 246 : is_encrypted(false),
247 default_iv_size(0)
248 #if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
249 ,
250 default_crypt_byte_block(0),
251 default_skip_byte_block(0),
252 default_constant_iv_size(0)
253 #endif
254 {
239 } 255 }
240 TrackEncryption::TrackEncryption(const TrackEncryption& other) = default; 256 TrackEncryption::TrackEncryption(const TrackEncryption& other) = default;
241 TrackEncryption::~TrackEncryption() {} 257 TrackEncryption::~TrackEncryption() {}
242 FourCC TrackEncryption::BoxType() const { return FOURCC_TENC; } 258 FourCC TrackEncryption::BoxType() const { return FOURCC_TENC; }
243 259
244 bool TrackEncryption::Parse(BoxReader* reader) { 260 bool TrackEncryption::Parse(BoxReader* reader) {
245 uint8_t flag; 261 uint8_t flag;
262 uint8_t possible_pattern_info;
246 RCHECK(reader->ReadFullBoxHeader() && 263 RCHECK(reader->ReadFullBoxHeader() &&
247 reader->SkipBytes(2) && 264 reader->SkipBytes(1) && // skip reserved byte
248 reader->Read1(&flag) && 265 reader->Read1(&possible_pattern_info) && reader->Read1(&flag) &&
249 reader->Read1(&default_iv_size) && 266 reader->Read1(&default_iv_size) &&
250 reader->ReadVec(&default_kid, 16)); 267 reader->ReadVec(&default_kid, kKeyIdSize));
251 is_encrypted = (flag != 0); 268 is_encrypted = (flag != 0);
252 if (is_encrypted) { 269 if (is_encrypted) {
270 #if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
271 if (reader->version() > 0) {
272 default_crypt_byte_block = (possible_pattern_info >> 4) & 0x0f;
273 default_skip_byte_block = possible_pattern_info & 0x0f;
274 }
275 if (default_iv_size == 0) {
276 RCHECK(reader->Read1(&default_constant_iv_size));
277 RCHECK(default_constant_iv_size == 8 || default_constant_iv_size == 16);
278 memset(default_constant_iv, 0, sizeof(default_constant_iv));
279 for (uint8_t i = 0; i < default_constant_iv_size; i++)
280 RCHECK(reader->Read1(default_constant_iv + i));
281 } else {
282 RCHECK(default_iv_size == 8 || default_iv_size == 16);
283 }
284 #else
253 RCHECK(default_iv_size == 8 || default_iv_size == 16); 285 RCHECK(default_iv_size == 8 || default_iv_size == 16);
286 #endif
254 } else { 287 } else {
255 RCHECK(default_iv_size == 0); 288 RCHECK(default_iv_size == 0);
256 } 289 }
257 return true; 290 return true;
258 } 291 }
259 292
260 SchemeInfo::SchemeInfo() {} 293 SchemeInfo::SchemeInfo() {}
261 SchemeInfo::SchemeInfo(const SchemeInfo& other) = default; 294 SchemeInfo::SchemeInfo(const SchemeInfo& other) = default;
262 SchemeInfo::~SchemeInfo() {} 295 SchemeInfo::~SchemeInfo() {}
263 FourCC SchemeInfo::BoxType() const { return FOURCC_SCHI; } 296 FourCC SchemeInfo::BoxType() const { return FOURCC_SCHI; }
264 297
265 bool SchemeInfo::Parse(BoxReader* reader) { 298 bool SchemeInfo::Parse(BoxReader* reader) {
266 return reader->ScanChildren() && reader->ReadChild(&track_encryption); 299 return reader->ScanChildren() && reader->ReadChild(&track_encryption);
267 } 300 }
268 301
269 ProtectionSchemeInfo::ProtectionSchemeInfo() {} 302 ProtectionSchemeInfo::ProtectionSchemeInfo() {}
270 ProtectionSchemeInfo::ProtectionSchemeInfo(const ProtectionSchemeInfo& other) = 303 ProtectionSchemeInfo::ProtectionSchemeInfo(const ProtectionSchemeInfo& other) =
271 default; 304 default;
272 ProtectionSchemeInfo::~ProtectionSchemeInfo() {} 305 ProtectionSchemeInfo::~ProtectionSchemeInfo() {}
273 FourCC ProtectionSchemeInfo::BoxType() const { return FOURCC_SINF; } 306 FourCC ProtectionSchemeInfo::BoxType() const { return FOURCC_SINF; }
274 307
275 bool ProtectionSchemeInfo::Parse(BoxReader* reader) { 308 bool ProtectionSchemeInfo::Parse(BoxReader* reader) {
276 RCHECK(reader->ScanChildren() && 309 RCHECK(reader->ScanChildren() &&
277 reader->ReadChild(&format) && 310 reader->ReadChild(&format) &&
278 reader->ReadChild(&type)); 311 reader->ReadChild(&type));
279 if (type.type == FOURCC_CENC) 312 if (HasSupportedScheme())
280 RCHECK(reader->ReadChild(&info)); 313 RCHECK(reader->ReadChild(&info));
281 // Other protection schemes are silently ignored. Since the protection scheme 314 // Other protection schemes are silently ignored. Since the protection scheme
282 // type can't be determined until this box is opened, we return 'true' for 315 // type can't be determined until this box is opened, we return 'true' for
283 // non-CENC protection scheme types. It is the parent box's responsibility to 316 // unsupported protection schemes. It is the parent box's responsibility to
284 // ensure that this scheme type is a supported one. 317 // ensure that this scheme type is a supported one.
285 return true; 318 return true;
286 } 319 }
287 320
321 bool ProtectionSchemeInfo::HasSupportedScheme() const {
322 FourCC fourCC = type.type;
323 if (fourCC == FOURCC_CENC)
324 return true;
325 #if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
326 if (fourCC == FOURCC_CBCS)
327 return true;
328 #endif
329 return false;
330 }
331
288 MovieHeader::MovieHeader() 332 MovieHeader::MovieHeader()
289 : version(0), 333 : version(0),
290 creation_time(0), 334 creation_time(0),
291 modification_time(0), 335 modification_time(0),
292 timescale(0), 336 timescale(0),
293 duration(0), 337 duration(0),
294 rate(-1), 338 rate(-1),
295 volume(-1), 339 volume(-1),
296 next_track_id(0) {} 340 next_track_id(0) {}
297 MovieHeader::MovieHeader(const MovieHeader& other) = default; 341 MovieHeader::MovieHeader(const MovieHeader& other) = default;
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
645 reader->Read2(&width) && 689 reader->Read2(&width) &&
646 reader->Read2(&height) && 690 reader->Read2(&height) &&
647 reader->SkipBytes(50)); 691 reader->SkipBytes(50));
648 692
649 RCHECK(reader->ScanChildren() && 693 RCHECK(reader->ScanChildren() &&
650 reader->MaybeReadChild(&pixel_aspect)); 694 reader->MaybeReadChild(&pixel_aspect));
651 695
652 if (format == FOURCC_ENCV) { 696 if (format == FOURCC_ENCV) {
653 // Continue scanning until a recognized protection scheme is found, or until 697 // Continue scanning until a recognized protection scheme is found, or until
654 // we run out of protection schemes. 698 // we run out of protection schemes.
655 while (sinf.type.type != FOURCC_CENC) { 699 while (!sinf.HasSupportedScheme()) {
656 if (!reader->ReadChild(&sinf)) 700 if (!reader->ReadChild(&sinf))
657 return false; 701 return false;
658 } 702 }
659 } 703 }
660 704
661 const FourCC actual_format = 705 const FourCC actual_format =
662 format == FOURCC_ENCV ? sinf.format.format : format; 706 format == FOURCC_ENCV ? sinf.format.format : format;
663 switch (actual_format) { 707 switch (actual_format) {
664 case FOURCC_AVC1: 708 case FOURCC_AVC1:
665 case FOURCC_AVC3: { 709 case FOURCC_AVC3: {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 reader->Read2(&samplesize) && 839 reader->Read2(&samplesize) &&
796 reader->SkipBytes(4) && 840 reader->SkipBytes(4) &&
797 reader->Read4(&samplerate)); 841 reader->Read4(&samplerate));
798 // Convert from 16.16 fixed point to integer 842 // Convert from 16.16 fixed point to integer
799 samplerate >>= 16; 843 samplerate >>= 16;
800 844
801 RCHECK(reader->ScanChildren()); 845 RCHECK(reader->ScanChildren());
802 if (format == FOURCC_ENCA) { 846 if (format == FOURCC_ENCA) {
803 // Continue scanning until a recognized protection scheme is found, or until 847 // Continue scanning until a recognized protection scheme is found, or until
804 // we run out of protection schemes. 848 // we run out of protection schemes.
805 while (sinf.type.type != FOURCC_CENC) { 849 while (!sinf.HasSupportedScheme()) {
806 if (!reader->ReadChild(&sinf)) 850 if (!reader->ReadChild(&sinf))
807 return false; 851 return false;
808 } 852 }
809 } 853 }
810 854
811 // ESDS is not valid in case of EAC3. 855 // ESDS is not valid in case of EAC3.
812 RCHECK(reader->MaybeReadChild(&esds)); 856 RCHECK(reader->MaybeReadChild(&esds));
813 return true; 857 return true;
814 } 858 }
815 859
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1135 RCHECK(reader->Read4(&count)); 1179 RCHECK(reader->Read4(&count));
1136 entries.resize(count); 1180 entries.resize(count);
1137 for (uint32_t i = 0; i < count; ++i) { 1181 for (uint32_t i = 0; i < count; ++i) {
1138 RCHECK(reader->Read4(&entries[i].sample_count) && 1182 RCHECK(reader->Read4(&entries[i].sample_count) &&
1139 reader->Read4(&entries[i].group_description_index)); 1183 reader->Read4(&entries[i].group_description_index));
1140 } 1184 }
1141 return true; 1185 return true;
1142 } 1186 }
1143 1187
1144 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry() 1188 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry()
1145 : is_encrypted(false), iv_size(0) {} 1189 : is_encrypted(false),
1190 iv_size(0)
1191 #if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
1192 ,
1193 crypt_byte_block(0),
1194 skip_byte_block(0),
1195 constant_iv_size(0)
1196 #endif
1197 {
1198 }
1146 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry( 1199 CencSampleEncryptionInfoEntry::CencSampleEncryptionInfoEntry(
1147 const CencSampleEncryptionInfoEntry& other) = default; 1200 const CencSampleEncryptionInfoEntry& other) = default;
1148 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {} 1201 CencSampleEncryptionInfoEntry::~CencSampleEncryptionInfoEntry() {}
1149 1202
1203 bool CencSampleEncryptionInfoEntry::Parse(BoxReader* reader) {
1204 uint8_t flag;
1205 uint8_t possible_pattern_info;
1206 RCHECK(reader->SkipBytes(1) && // reserved.
1207 reader->Read1(&possible_pattern_info) && reader->Read1(&flag) &&
1208 reader->Read1(&iv_size) && reader->ReadVec(&key_id, kKeyIdSize));
1209
1210 is_encrypted = (flag != 0);
1211 if (is_encrypted) {
1212 #if BUILDFLAG(ENABLE_CBCS_ENCRYPTION_SCHEME)
1213 crypt_byte_block = (possible_pattern_info >> 4) & 0x0f;
1214 skip_byte_block = possible_pattern_info & 0x0f;
1215 if (iv_size == 0) {
1216 RCHECK(reader->Read1(&constant_iv_size));
1217 RCHECK(constant_iv_size == 8 || constant_iv_size == 16);
1218 memset(constant_iv, 0, sizeof(constant_iv));
1219 for (uint8_t i = 0; i < constant_iv_size; i++)
1220 RCHECK(reader->Read1(constant_iv + i));
1221 } else {
1222 RCHECK(iv_size == 8 || iv_size == 16);
1223 }
1224 #else
1225 RCHECK(iv_size == 8 || iv_size == 16);
1226 #endif
1227 } else {
1228 RCHECK(iv_size == 0);
1229 }
1230 return true;
1231 }
1232
1150 SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {} 1233 SampleGroupDescription::SampleGroupDescription() : grouping_type(0) {}
1151 SampleGroupDescription::SampleGroupDescription( 1234 SampleGroupDescription::SampleGroupDescription(
1152 const SampleGroupDescription& other) = default; 1235 const SampleGroupDescription& other) = default;
1153 SampleGroupDescription::~SampleGroupDescription() {} 1236 SampleGroupDescription::~SampleGroupDescription() {}
1154 FourCC SampleGroupDescription::BoxType() const { return FOURCC_SGPD; } 1237 FourCC SampleGroupDescription::BoxType() const { return FOURCC_SGPD; }
1155 1238
1156 bool SampleGroupDescription::Parse(BoxReader* reader) { 1239 bool SampleGroupDescription::Parse(BoxReader* reader) {
1157 RCHECK(reader->ReadFullBoxHeader() && 1240 RCHECK(reader->ReadFullBoxHeader() &&
1158 reader->Read4(&grouping_type)); 1241 reader->Read4(&grouping_type));
1159 1242
1160 if (grouping_type != FOURCC_SEIG) { 1243 if (grouping_type != FOURCC_SEIG) {
1161 DLOG(WARNING) << "SampleGroupDescription box with grouping_type '" 1244 DLOG(WARNING) << "SampleGroupDescription box with grouping_type '"
1162 << grouping_type << "' is not supported."; 1245 << grouping_type << "' is not supported.";
1163 return true; 1246 return true;
1164 } 1247 }
1165 1248
1166 const uint8_t version = reader->version(); 1249 const uint8_t version = reader->version();
1167 1250
1168 const size_t kKeyIdSize = 16;
1169 const size_t kEntrySize = sizeof(uint32_t) + kKeyIdSize; 1251 const size_t kEntrySize = sizeof(uint32_t) + kKeyIdSize;
1170 uint32_t default_length = 0; 1252 uint32_t default_length = 0;
1171 if (version == 1) { 1253 if (version == 1) {
1172 RCHECK(reader->Read4(&default_length)); 1254 RCHECK(reader->Read4(&default_length));
1173 RCHECK(default_length == 0 || default_length >= kEntrySize); 1255 RCHECK(default_length == 0 || default_length >= kEntrySize);
1174 } 1256 }
1175 1257
1176 uint32_t count; 1258 uint32_t count;
1177 RCHECK(reader->Read4(&count)); 1259 RCHECK(reader->Read4(&count));
1178 entries.resize(count); 1260 entries.resize(count);
1179 for (uint32_t i = 0; i < count; ++i) { 1261 for (uint32_t i = 0; i < count; ++i) {
1180 if (version == 1) { 1262 if (version == 1) {
1181 if (default_length == 0) { 1263 if (default_length == 0) {
1182 uint32_t description_length = 0; 1264 uint32_t description_length = 0;
1183 RCHECK(reader->Read4(&description_length)); 1265 RCHECK(reader->Read4(&description_length));
1184 RCHECK(description_length >= kEntrySize); 1266 RCHECK(description_length >= kEntrySize);
1185 } 1267 }
1186 } 1268 }
1187 1269 RCHECK(entries[i].Parse(reader));
1188 uint8_t flag;
1189 RCHECK(reader->SkipBytes(2) && // reserved.
1190 reader->Read1(&flag) &&
1191 reader->Read1(&entries[i].iv_size) &&
1192 reader->ReadVec(&entries[i].key_id, kKeyIdSize));
1193
1194 entries[i].is_encrypted = (flag != 0);
1195 if (entries[i].is_encrypted) {
1196 RCHECK(entries[i].iv_size == 8 || entries[i].iv_size == 16);
1197 } else {
1198 RCHECK(entries[i].iv_size == 0);
1199 }
1200 } 1270 }
1201 return true; 1271 return true;
1202 } 1272 }
1203 1273
1204 TrackFragment::TrackFragment() {} 1274 TrackFragment::TrackFragment() {}
1205 TrackFragment::TrackFragment(const TrackFragment& other) = default; 1275 TrackFragment::TrackFragment(const TrackFragment& other) = default;
1206 TrackFragment::~TrackFragment() {} 1276 TrackFragment::~TrackFragment() {}
1207 FourCC TrackFragment::BoxType() const { return FOURCC_TRAF; } 1277 FourCC TrackFragment::BoxType() const { return FOURCC_TRAF; }
1208 1278
1209 bool TrackFragment::Parse(BoxReader* reader) { 1279 bool TrackFragment::Parse(BoxReader* reader) {
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1276 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on( 1346 SampleDependsOn IndependentAndDisposableSamples::sample_depends_on(
1277 size_t i) const { 1347 size_t i) const {
1278 if (i >= sample_depends_on_.size()) 1348 if (i >= sample_depends_on_.size())
1279 return kSampleDependsOnUnknown; 1349 return kSampleDependsOnUnknown;
1280 1350
1281 return sample_depends_on_[i]; 1351 return sample_depends_on_[i];
1282 } 1352 }
1283 1353
1284 } // namespace mp4 1354 } // namespace mp4
1285 } // namespace media 1355 } // namespace media
OLDNEW
« no previous file with comments | « media/formats/mp4/box_definitions.h ('k') | media/formats/mp4/fourccs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698