Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "media/mp4/box_definitions.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "media/mp4/box_reader.h" | |
| 9 #include "media/mp4/fourccs.h" | |
| 10 #include "media/mp4/rcheck.h" | |
| 11 | |
| 12 namespace media { | |
| 13 namespace mp4 { | |
| 14 | |
| 15 bool FileType::Parse(BoxReader* reader) { | |
| 16 RCHECK(reader->ReadFourCC(&major_brand) && reader->Read4(&minor_version)); | |
| 17 size_t num_brands = (reader->size() - reader->pos()) / sizeof(FourCC); | |
| 18 return reader->SkipBytes(sizeof(FourCC) * num_brands); // compatible_brands | |
| 19 } | |
| 20 | |
| 21 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() {} | |
| 22 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() {} | |
| 23 FourCC ProtectionSystemSpecificHeader::BoxType() const { return FOURCC_PSSH; } | |
| 24 | |
| 25 bool ProtectionSystemSpecificHeader::Parse(BoxReader* reader) { | |
| 26 uint32 size; | |
| 27 return reader->SkipBytes(4) && | |
| 28 reader->ReadVec(&system_id, 16) && | |
| 29 reader->Read4(&size) && | |
| 30 reader->ReadVec(&data, size); | |
| 31 } | |
| 32 | |
| 33 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() {} | |
| 34 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {} | |
| 35 FourCC SampleAuxiliaryInformationOffset::BoxType() const { return FOURCC_SAIO; } | |
| 36 | |
| 37 bool SampleAuxiliaryInformationOffset::Parse(BoxReader* reader) { | |
| 38 RCHECK(reader->ReadFullBoxHeader()); | |
| 39 if (reader->flags() & 1) | |
| 40 RCHECK(reader->SkipBytes(8)); | |
| 41 | |
| 42 uint32 count; | |
| 43 RCHECK(reader->Read4(&count) && | |
| 44 reader->HasBytes(count * (reader->version() == 1 ? 8 : 4))); | |
| 45 offsets.resize(count); | |
| 46 | |
| 47 for (uint32 i = 0; i < count; i++) { | |
| 48 if (reader->version() == 1) { | |
| 49 RCHECK(reader->Read8(&offsets[i])); | |
| 50 } else { | |
| 51 RCHECK(reader->Read4Into8(&offsets[i])); | |
| 52 } | |
| 53 } | |
| 54 return true; | |
| 55 } | |
| 56 | |
| 57 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize() | |
| 58 : default_sample_info_size(0), sample_count(0) { | |
| 59 } | |
| 60 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() {} | |
| 61 FourCC SampleAuxiliaryInformationSize::BoxType() const { return FOURCC_SAIZ; } | |
| 62 | |
| 63 bool SampleAuxiliaryInformationSize::Parse(BoxReader* reader) { | |
| 64 RCHECK(reader->ReadFullBoxHeader()); | |
| 65 if (reader->flags() & 1) | |
| 66 RCHECK(reader->SkipBytes(8)); | |
| 67 | |
| 68 RCHECK(reader->Read1(&default_sample_info_size) && | |
| 69 reader->Read4(&sample_count)); | |
| 70 if (default_sample_info_size == 0) | |
| 71 return reader->ReadVec(&sample_info_sizes, sample_count); | |
| 72 return true; | |
| 73 } | |
| 74 | |
| 75 OriginalFormat::OriginalFormat() {} | |
| 76 OriginalFormat::~OriginalFormat() {} | |
| 77 FourCC OriginalFormat::BoxType() const { return FOURCC_FRMA; } | |
| 78 | |
| 79 bool OriginalFormat::Parse(BoxReader* reader) { | |
| 80 return reader->ReadFourCC(&format); | |
| 81 } | |
| 82 | |
| 83 SchemeType::SchemeType() {} | |
| 84 SchemeType::~SchemeType() {} | |
| 85 FourCC SchemeType::BoxType() const { return FOURCC_SCHM; } | |
| 86 | |
| 87 bool SchemeType::Parse(BoxReader* reader) { | |
| 88 RCHECK(reader->SkipBytes(4) && | |
| 89 reader->ReadFourCC(&type) && | |
| 90 reader->Read4(&version)); | |
| 91 RCHECK(type == FOURCC_CENC); | |
| 92 return true; | |
| 93 } | |
| 94 | |
| 95 TrackEncryption::TrackEncryption() | |
| 96 : is_encrypted(false), default_iv_size(0) { | |
| 97 } | |
| 98 TrackEncryption::~TrackEncryption() {} | |
| 99 FourCC TrackEncryption::BoxType() const { return FOURCC_TENC; } | |
| 100 | |
| 101 bool TrackEncryption::Parse(BoxReader* reader) { | |
| 102 uint8 flag; | |
| 103 RCHECK(reader->SkipBytes(2) && | |
| 104 reader->Read1(&flag) && | |
| 105 reader->Read1(&default_iv_size) && | |
| 106 reader->ReadVec(&default_kid, 16)); | |
| 107 is_encrypted = (flag != 0); | |
| 108 if (is_encrypted) { | |
| 109 RCHECK(default_iv_size == 8 || default_iv_size == 16); | |
| 110 } else { | |
| 111 RCHECK(default_iv_size == 0); | |
| 112 } | |
| 113 return true; | |
| 114 } | |
| 115 | |
| 116 SchemeInfo::SchemeInfo() {} | |
| 117 SchemeInfo::~SchemeInfo() {} | |
| 118 FourCC SchemeInfo::BoxType() const { return FOURCC_SCHI; } | |
| 119 | |
| 120 bool SchemeInfo::Parse(BoxReader* reader) { | |
| 121 return reader->ScanChildren() && reader->ReadChild(&track_encryption); | |
| 122 } | |
| 123 | |
| 124 ProtectionSchemeInfo::ProtectionSchemeInfo() {} | |
| 125 ProtectionSchemeInfo::~ProtectionSchemeInfo() {} | |
| 126 FourCC ProtectionSchemeInfo::BoxType() const { return FOURCC_SINF; } | |
| 127 | |
| 128 bool ProtectionSchemeInfo::Parse(BoxReader* reader) { | |
| 129 return reader->ScanChildren() && | |
| 130 reader->ReadChild(&type) && | |
| 131 reader->ReadChild(&info); | |
| 132 } | |
| 133 | |
| 134 MovieHeader::MovieHeader() {} | |
| 135 MovieHeader::~MovieHeader() {} | |
| 136 FourCC MovieHeader::BoxType() const { return FOURCC_MVHD; } | |
| 137 | |
| 138 bool MovieHeader::Parse(BoxReader* reader) { | |
| 139 RCHECK(reader->ReadFullBoxHeader()); | |
| 140 | |
| 141 if (reader->version() == 1) { | |
| 142 RCHECK(reader->Read8(&creation_time) && | |
| 143 reader->Read8(&modification_time) && | |
| 144 reader->Read4(×cale) && | |
| 145 reader->Read8(&duration)); | |
| 146 } else { | |
| 147 RCHECK(reader->Read4Into8(&creation_time) && | |
| 148 reader->Read4Into8(&modification_time) && | |
| 149 reader->Read4(×cale) && | |
| 150 reader->Read4Into8(&duration)); | |
| 151 } | |
| 152 | |
| 153 RCHECK(reader->Read4s(&rate) && | |
| 154 reader->Read2s(&volume) && | |
| 155 reader->SkipBytes(10) && // reserved | |
| 156 reader->SkipBytes(36) && // matrix | |
| 157 reader->SkipBytes(24) && // predefined zero | |
| 158 reader->Read4(&next_track_id)); | |
| 159 return true; | |
| 160 } | |
| 161 | |
| 162 TrackHeader::TrackHeader() {} | |
| 163 TrackHeader::~TrackHeader() {} | |
| 164 FourCC TrackHeader::BoxType() const { return FOURCC_TKHD; } | |
| 165 | |
| 166 bool TrackHeader::Parse(BoxReader* reader) { | |
| 167 RCHECK(reader->ReadFullBoxHeader()); | |
| 168 if (reader->version() == 1) { | |
| 169 RCHECK(reader->Read8(&creation_time) && | |
| 170 reader->Read8(&modification_time) && | |
| 171 reader->Read4(&track_id) && | |
| 172 reader->SkipBytes(4) && // reserved | |
| 173 reader->Read8(&duration)); | |
| 174 } else { | |
| 175 RCHECK(reader->Read4Into8(&creation_time) && | |
| 176 reader->Read4Into8(&modification_time) && | |
| 177 reader->Read4(&track_id) && | |
| 178 reader->SkipBytes(4) && // reserved | |
| 179 reader->Read4Into8(&duration)); | |
| 180 } | |
| 181 | |
| 182 RCHECK(reader->SkipBytes(8) && // reserved | |
| 183 reader->Read2s(&layer) && | |
| 184 reader->Read2s(&alternate_group) && | |
| 185 reader->Read2s(&volume) && | |
| 186 reader->SkipBytes(2) && // reserved | |
| 187 reader->SkipBytes(36) && // matrix | |
| 188 reader->Read4(&width) && | |
| 189 reader->Read4(&height)); | |
| 190 width >>= 16; | |
| 191 height >>= 16; | |
| 192 return true; | |
| 193 } | |
| 194 | |
| 195 SampleDescription::SampleDescription() {} | |
| 196 SampleDescription::~SampleDescription() {} | |
| 197 FourCC SampleDescription::BoxType() const { return FOURCC_STSD; } | |
| 198 | |
| 199 bool SampleDescription::Parse(BoxReader* reader) { | |
| 200 uint32 count; | |
| 201 RCHECK(reader->SkipBytes(4) && | |
| 202 reader->Read4(&count) && | |
| 203 reader->ScanChildren()); | |
| 204 video_entries.clear(); | |
| 205 audio_entries.clear(); | |
| 206 | |
| 207 // Note: this value is preset before scanning begins. See comments in the | |
| 208 // Parse(Media*) function. | |
| 209 if (type == kVideo) { | |
| 210 RCHECK(reader->ReadAllChildren(&video_entries)); | |
| 211 } else if (type == kAudio) { | |
| 212 RCHECK(reader->ReadAllChildren(&audio_entries)); | |
| 213 } | |
| 214 return true; | |
| 215 } | |
| 216 | |
| 217 SampleTable::SampleTable() {} | |
| 218 SampleTable::~SampleTable() {} | |
| 219 FourCC SampleTable::BoxType() const { return FOURCC_STBL; } | |
| 220 | |
| 221 bool SampleTable::Parse(BoxReader* reader) { | |
| 222 return reader->ScanChildren() && | |
| 223 reader->ReadChild(&description); | |
| 224 } | |
| 225 | |
| 226 EditList::EditList() {} | |
| 227 EditList::~EditList() {} | |
| 228 FourCC EditList::BoxType() const { return FOURCC_ELST; } | |
| 229 | |
| 230 bool EditList::Parse(BoxReader* reader) { | |
| 231 uint32 count; | |
| 232 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&count)); | |
| 233 | |
| 234 if (reader->version() == 1) { | |
| 235 RCHECK(reader->HasBytes(count * 20)); | |
| 236 } else { | |
| 237 RCHECK(reader->HasBytes(count * 12)); | |
| 238 } | |
| 239 edits.resize(count); | |
| 240 | |
| 241 for (auto edit = edits.begin(); edit != edits.end(); ++edit) { | |
| 242 if (reader->version() == 1) { | |
| 243 RCHECK(reader->Read8(&edit->segment_duration) && | |
| 244 reader->Read8s(&edit->media_time)); | |
| 245 } else { | |
| 246 RCHECK(reader->Read4Into8(&edit->segment_duration) && | |
| 247 reader->Read4sInto8s(&edit->media_time)); | |
| 248 } | |
| 249 RCHECK(reader->Read2s(&edit->media_rate_integer) && | |
| 250 reader->Read2s(&edit->media_rate_fraction)); | |
| 251 } | |
| 252 return true; | |
| 253 } | |
| 254 | |
| 255 Edit::Edit() {} | |
| 256 Edit::~Edit() {} | |
| 257 FourCC Edit::BoxType() const { return FOURCC_EDTS; } | |
| 258 | |
| 259 bool Edit::Parse(BoxReader* reader) { | |
| 260 return reader->ScanChildren() && reader->ReadChild(&list); | |
| 261 } | |
| 262 | |
| 263 HandlerReference::HandlerReference() {} | |
| 264 HandlerReference::~HandlerReference() {} | |
| 265 FourCC HandlerReference::BoxType() const { return FOURCC_HDLR; } | |
| 266 | |
| 267 bool HandlerReference::Parse(BoxReader* reader) { | |
| 268 FourCC hdlr_type; | |
| 269 RCHECK(reader->SkipBytes(8) && reader->ReadFourCC(&hdlr_type)); | |
| 270 // Note: remaining fields in box ignored | |
| 271 if (hdlr_type == FOURCC_VIDE) { | |
| 272 type = kVideo; | |
| 273 } else if (hdlr_type == FOURCC_SOUN) { | |
| 274 type = kAudio; | |
| 275 } else { | |
| 276 type = kInvalid; | |
| 277 } | |
| 278 return true; | |
| 279 } | |
| 280 | |
| 281 AVCDecoderConfigurationRecord::AVCDecoderConfigurationRecord() {}; | |
|
acolwell GONE FROM CHROMIUM
2012/06/08 16:10:38
lint nit: remove ;
strobe_
2012/06/11 18:44:21
Done.
| |
| 282 AVCDecoderConfigurationRecord::~AVCDecoderConfigurationRecord() {}; | |
|
acolwell GONE FROM CHROMIUM
2012/06/08 16:10:38
lint nit: remove ;
strobe_
2012/06/11 18:44:21
Done.
| |
| 283 FourCC AVCDecoderConfigurationRecord::BoxType() const { return FOURCC_AVCC; } | |
| 284 | |
| 285 bool AVCDecoderConfigurationRecord::Parse(BoxReader* readereader) { | |
| 286 RCHECK(readereader->Read1(&version) && version == 1 && | |
|
acolwell GONE FROM CHROMIUM
2012/06/08 16:10:38
Oops :) readereader -> reader
strobe_
2012/06/11 18:44:21
Heh. Done.
| |
| 287 readereader->Read1(&profile_indication) && | |
| 288 readereader->Read1(&profile_compatibility) && | |
| 289 readereader->Read1(&avc_level)); | |
| 290 | |
| 291 uint8 length_size_minus_one; | |
| 292 RCHECK(readereader->Read1(&length_size_minus_one) && | |
| 293 (length_size_minus_one & 0xfc) == 0xfc); | |
| 294 length_size = (length_size_minus_one & 0x3) + 1; | |
| 295 | |
| 296 uint8 num_sps; | |
| 297 RCHECK(readereader->Read1(&num_sps) && (num_sps & 0xe0) == 0xe0); | |
| 298 num_sps &= 0x1f; | |
| 299 | |
| 300 sps_list.resize(num_sps); | |
| 301 for (int i = 0; i < num_sps; i++) { | |
| 302 uint16 sps_length; | |
| 303 RCHECK(readereader->Read2(&sps_length) && | |
| 304 readereader->ReadVec(&sps_list[i], sps_length)); | |
| 305 } | |
| 306 | |
| 307 uint8 num_pps; | |
| 308 RCHECK(readereader->Read1(&num_pps)); | |
| 309 | |
| 310 pps_list.resize(num_pps); | |
| 311 for (int i = 0; i < num_pps; i++) { | |
| 312 uint16 pps_length; | |
| 313 RCHECK(readereader->Read2(&pps_length) && | |
| 314 readereader->ReadVec(&pps_list[i], pps_length)); | |
| 315 } | |
| 316 | |
| 317 return true; | |
| 318 } | |
| 319 | |
| 320 VideoSampleEntry::VideoSampleEntry() {} | |
| 321 VideoSampleEntry::~VideoSampleEntry() {} | |
| 322 FourCC VideoSampleEntry::BoxType() const { | |
| 323 DCHECK(false) << "VideoSampleEntry should be parsed according to the " | |
| 324 << "handler type recovered in its Media ancestor."; | |
| 325 return FOURCC_NULL; | |
| 326 } | |
| 327 | |
| 328 bool VideoSampleEntry::Parse(BoxReader* reader) { | |
| 329 format = reader->type(); | |
| 330 RCHECK(reader->SkipBytes(6) && | |
| 331 reader->Read2(&data_reference_index) && | |
| 332 reader->SkipBytes(16) && | |
| 333 reader->Read2(&width) && | |
| 334 reader->Read2(&height) && | |
| 335 reader->SkipBytes(50)); | |
| 336 | |
| 337 RCHECK(reader->ScanChildren()); | |
| 338 if (format == FOURCC_ENCV) { | |
| 339 RCHECK(reader->ReadChild(&sinf)); | |
| 340 } | |
| 341 | |
| 342 // TODO(strobe): Widevine test files do not follow spec here; check disabled | |
|
acolwell GONE FROM CHROMIUM
2012/06/08 16:10:38
lint nit: 2 spaces after // here and below
strobe_
2012/06/11 18:44:21
Done.
| |
| 343 //if (format == FOURCC_AVC1 || | |
| 344 // (format == FOURCC_ENCV && | |
| 345 // sinf.format.format == FOURCC_AVC1)) { | |
| 346 RCHECK(reader->ReadChild(&avcc)); | |
| 347 //} | |
| 348 return true; | |
| 349 } | |
| 350 | |
| 351 AudioSampleEntry::AudioSampleEntry() {} | |
| 352 AudioSampleEntry::~AudioSampleEntry() {} | |
| 353 FourCC AudioSampleEntry::BoxType() const { | |
| 354 DCHECK(false) << "AudioSampleEntry should be parsed according to the " | |
| 355 << "handler type recovered in its Media ancestor."; | |
| 356 return FOURCC_NULL; | |
| 357 } | |
| 358 | |
| 359 bool AudioSampleEntry::Parse(BoxReader* reader) { | |
| 360 format = reader->type(); | |
| 361 RCHECK(reader->SkipBytes(6) && | |
| 362 reader->Read2(&data_reference_index) && | |
| 363 reader->SkipBytes(8) && | |
| 364 reader->Read2(&channelcount) && | |
| 365 reader->Read2(&samplesize) && | |
| 366 reader->SkipBytes(4) && | |
| 367 reader->Read4(&samplerate)); | |
| 368 // Convert from 16.16 fixed point to integer | |
| 369 samplerate >>= 16; | |
|
acolwell GONE FROM CHROMIUM
2012/06/08 16:10:38
How does mp4 handle 96kHz audio?
strobe_
2012/06/11 18:44:21
Poorly. ;)
BMFF supports a lot of crazy things, b
acolwell GONE FROM CHROMIUM
2012/06/13 14:16:06
Ok. I'm fine with leaving this code as is for now.
| |
| 370 | |
| 371 RCHECK(reader->ScanChildren()); | |
| 372 if (format == FOURCC_ENCA) { | |
| 373 RCHECK(reader->ReadChild(&sinf)); | |
| 374 } | |
| 375 return true; | |
| 376 } | |
| 377 | |
| 378 MediaHeader::MediaHeader() {} | |
| 379 MediaHeader::~MediaHeader() {} | |
| 380 FourCC MediaHeader::BoxType() const { return FOURCC_MDHD; } | |
| 381 | |
| 382 bool MediaHeader::Parse(BoxReader* reader) { | |
| 383 RCHECK(reader->ReadFullBoxHeader()); | |
| 384 | |
| 385 if (reader->version() == 1) { | |
| 386 RCHECK(reader->Read8(&creation_time) && | |
| 387 reader->Read8(&modification_time) && | |
| 388 reader->Read4(×cale) && | |
| 389 reader->Read8(&duration)); | |
| 390 } else { | |
| 391 RCHECK(reader->Read4Into8(&creation_time) && | |
| 392 reader->Read4Into8(&modification_time) && | |
| 393 reader->Read4(×cale) && | |
| 394 reader->Read4Into8(&duration)); | |
| 395 } | |
| 396 // Skip language information | |
| 397 return reader->SkipBytes(4); | |
| 398 } | |
| 399 | |
| 400 MediaInformation::MediaInformation() {} | |
| 401 MediaInformation::~MediaInformation() {} | |
| 402 FourCC MediaInformation::BoxType() const { return FOURCC_MINF; } | |
| 403 | |
| 404 bool MediaInformation::Parse(BoxReader* reader) { | |
| 405 return reader->ScanChildren() && | |
| 406 reader->ReadChild(&sample_table); | |
| 407 } | |
| 408 | |
| 409 Media::Media() {} | |
| 410 Media::~Media() {} | |
| 411 FourCC Media::BoxType() const { return FOURCC_MDIA; } | |
| 412 | |
| 413 bool Media::Parse(BoxReader* reader) { | |
| 414 RCHECK(reader->ScanChildren() && | |
| 415 reader->ReadChild(&header) && | |
| 416 reader->ReadChild(&handler)); | |
| 417 | |
| 418 // Maddeningly, the HandlerReference box specifies how to parse the | |
| 419 // SampleDescription box, making the latter the only box (of those that we | |
| 420 // support) which cannot be parsed correctly on its own (or even with | |
| 421 // information from its strict ancestor tree). We thus copy the handler type | |
| 422 // to the sample description box *before* parsing it to provide this | |
| 423 // information while parsing. | |
| 424 information.sample_table.description.type = handler.type; | |
| 425 RCHECK(reader->ReadChild(&information)); | |
| 426 return true; | |
| 427 } | |
| 428 | |
| 429 Track::Track() {} | |
| 430 Track::~Track() {} | |
| 431 FourCC Track::BoxType() const { return FOURCC_TRAK; } | |
| 432 | |
| 433 bool Track::Parse(BoxReader* reader) { | |
| 434 RCHECK(reader->ScanChildren() && | |
| 435 reader->ReadChild(&header) && | |
| 436 reader->ReadChild(&media) && | |
| 437 reader->MaybeReadChild(&edit)); | |
| 438 return true; | |
| 439 } | |
| 440 | |
| 441 MovieExtendsHeader::MovieExtendsHeader() {} | |
| 442 MovieExtendsHeader::~MovieExtendsHeader() {} | |
| 443 FourCC MovieExtendsHeader::BoxType() const { return FOURCC_MEHD; } | |
| 444 | |
| 445 bool MovieExtendsHeader::Parse(BoxReader* reader) { | |
| 446 RCHECK(reader->Read8(&fragment_duration)); | |
| 447 return true; | |
| 448 } | |
| 449 | |
| 450 TrackExtends::TrackExtends() {} | |
| 451 TrackExtends::~TrackExtends() {} | |
| 452 FourCC TrackExtends::BoxType() const { return FOURCC_TREX; } | |
| 453 | |
| 454 bool TrackExtends::Parse(BoxReader* reader) { | |
| 455 RCHECK(reader->ReadFullBoxHeader() && | |
| 456 reader->Read4(&track_id) && | |
| 457 reader->Read4(&default_sample_description_index) && | |
| 458 reader->Read4(&default_sample_duration) && | |
| 459 reader->Read4(&default_sample_size) && | |
| 460 reader->Read4(&default_sample_flags)); | |
| 461 return true; | |
| 462 } | |
| 463 | |
| 464 MovieExtends::MovieExtends() {} | |
| 465 MovieExtends::~MovieExtends() {} | |
| 466 FourCC MovieExtends::BoxType() const { return FOURCC_MVEX; } | |
| 467 | |
| 468 bool MovieExtends::Parse(BoxReader* reader) { | |
| 469 header.fragment_duration = 0; | |
| 470 return reader->ScanChildren() && | |
| 471 reader->MaybeReadChild(&header) && | |
| 472 // TODO(strobe): does not detect correspondence rule (trex must match | |
| 473 // one-to-one with trak) | |
| 474 reader->ReadChildren(&tracks); | |
| 475 } | |
| 476 | |
| 477 Movie::Movie() {}; | |
|
acolwell GONE FROM CHROMIUM
2012/06/08 16:10:38
lint nit: remove ;
strobe_
2012/06/11 18:44:21
Done.
| |
| 478 Movie::~Movie() {}; | |
|
acolwell GONE FROM CHROMIUM
2012/06/08 16:10:38
lint nit: remove ;
strobe_
2012/06/11 18:44:21
Done.
| |
| 479 FourCC Movie::BoxType() const { return FOURCC_MOOV; } | |
| 480 | |
| 481 bool Movie::Parse(BoxReader* reader) { | |
| 482 return reader->ScanChildren() && | |
| 483 reader->ReadChild(&header) && | |
| 484 reader->ReadChildren(&tracks) && | |
| 485 // Media Source specific: 'mvex' required | |
| 486 reader->ReadChild(&extends) && | |
| 487 reader->MaybeReadChildren(&pssh); | |
| 488 } | |
| 489 | |
| 490 TrackFragmentDecodeTime::TrackFragmentDecodeTime() {} | |
| 491 TrackFragmentDecodeTime::~TrackFragmentDecodeTime() {} | |
| 492 FourCC TrackFragmentDecodeTime::BoxType() const { return FOURCC_TFDT; } | |
| 493 | |
| 494 bool TrackFragmentDecodeTime::Parse(BoxReader* reader) { | |
| 495 RCHECK(reader->ReadFullBoxHeader()); | |
| 496 if (reader->version() == 1) | |
| 497 return reader->Read8(&decode_time); | |
| 498 else | |
| 499 return reader->Read4Into8(&decode_time); | |
| 500 } | |
| 501 | |
| 502 MovieFragmentHeader::MovieFragmentHeader() {} | |
| 503 MovieFragmentHeader::~MovieFragmentHeader() {} | |
| 504 FourCC MovieFragmentHeader::BoxType() const { return FOURCC_MFHD; } | |
| 505 | |
| 506 bool MovieFragmentHeader::Parse(BoxReader* reader) { | |
| 507 return reader->SkipBytes(4) && reader->Read4(&sequence_number); | |
| 508 } | |
| 509 | |
| 510 TrackFragmentHeader::TrackFragmentHeader() {} | |
| 511 TrackFragmentHeader::~TrackFragmentHeader() {} | |
| 512 FourCC TrackFragmentHeader::BoxType() const { return FOURCC_TFHD; } | |
| 513 | |
| 514 bool TrackFragmentHeader::Parse(BoxReader* reader) { | |
| 515 RCHECK(reader->ReadFullBoxHeader() && reader->Read4(&track_id)); | |
| 516 | |
| 517 // Media Source specific: we require that 'default-base-is-moof' (14496-12 | |
| 518 // Amendment 2) be set, and reject tracks that set 'base-data-offset-present'. | |
| 519 // | |
| 520 // TODO(strobe): Test files do not have 'default-base-is-moof' set explicitly | |
| 521 // (although they are structured as if it is set). Because this flag is hidden | |
| 522 // in Amendment 2, it might not be set by all implementors. Should we reject | |
| 523 // such files, or try them anyway? | |
| 524 // | |
| 525 // RCHECK((flags & 0x020000) && !(flags & 0x1)); | |
| 526 RCHECK(!(reader->flags() & 0x1)); | |
| 527 | |
| 528 if (reader->flags() & 0x2) | |
| 529 RCHECK(reader->SkipBytes(4)); // sample_description_index | |
| 530 | |
| 531 if (reader->flags() & 0x8) { | |
| 532 RCHECK(reader->Read4(&default_sample_duration)); | |
| 533 } else { | |
| 534 default_sample_duration = 0; | |
| 535 } | |
| 536 | |
| 537 if (reader->flags() & 0x10) { | |
| 538 RCHECK(reader->Read4(&default_sample_size)); | |
| 539 } else { | |
| 540 default_sample_size = 0; | |
| 541 } | |
| 542 | |
| 543 if (reader->flags() & 0x20) { | |
| 544 RCHECK(reader->Read4(&default_sample_flags)); | |
| 545 has_default_sample_flags = true; | |
| 546 } else { | |
| 547 has_default_sample_flags = false; | |
| 548 } | |
| 549 | |
| 550 return true; | |
| 551 } | |
| 552 | |
| 553 TrackFragmentRun::TrackFragmentRun() {} | |
| 554 TrackFragmentRun::~TrackFragmentRun() {} | |
| 555 FourCC TrackFragmentRun::BoxType() const { return FOURCC_TRUN; } | |
| 556 | |
| 557 bool TrackFragmentRun::Parse(BoxReader* reader) { | |
| 558 RCHECK(reader->ReadFullBoxHeader() && | |
| 559 reader->Read4(&sample_count)); | |
| 560 const uint32 flags = reader->flags(); | |
| 561 | |
| 562 bool data_offset_present = flags & 0x1; | |
| 563 bool first_sample_flags_present = flags & 0x4; | |
| 564 bool sample_duration_present = flags & 0x100; | |
| 565 bool sample_size_present = flags & 0x200; | |
| 566 bool sample_flags_present = flags & 0x400; | |
| 567 bool sample_composition_time_offsets_present = flags & 0x800; | |
| 568 | |
| 569 if (data_offset_present) { | |
| 570 RCHECK(reader->Read4(&data_offset)); | |
| 571 } else { | |
| 572 data_offset = 0; | |
| 573 } | |
| 574 | |
| 575 uint32 first_sample_flags; | |
| 576 if (first_sample_flags_present) | |
| 577 RCHECK(reader->Read4(&first_sample_flags)); | |
| 578 | |
| 579 int fields = sample_duration_present + sample_size_present + | |
| 580 sample_flags_present + sample_composition_time_offsets_present; | |
| 581 RCHECK(reader->HasBytes(fields * sample_count)); | |
| 582 | |
| 583 if (sample_duration_present) | |
| 584 sample_durations.resize(sample_count); | |
| 585 if (sample_size_present) | |
| 586 sample_sizes.resize(sample_count); | |
| 587 if (sample_flags_present) | |
| 588 sample_flags.resize(sample_count); | |
| 589 if (sample_composition_time_offsets_present) | |
| 590 sample_composition_time_offsets.resize(sample_count); | |
| 591 | |
| 592 for (uint32 i = 0; i < sample_count; ++i) { | |
| 593 if (sample_duration_present) | |
| 594 RCHECK(reader->Read4(&sample_durations[i])); | |
| 595 if (sample_size_present) | |
| 596 RCHECK(reader->Read4(&sample_sizes[i])); | |
| 597 if (sample_flags_present) | |
| 598 RCHECK(reader->Read4(&sample_flags[i])); | |
| 599 if (sample_composition_time_offsets_present) | |
| 600 RCHECK(reader->Read4(&sample_composition_time_offsets[i])); | |
| 601 } | |
| 602 | |
| 603 if (first_sample_flags_present) { | |
| 604 if (sample_flags.size() == 0) { | |
| 605 sample_flags.push_back(first_sample_flags); | |
| 606 } else { | |
| 607 sample_flags[0] = first_sample_flags; | |
| 608 } | |
| 609 } | |
| 610 return true; | |
| 611 } | |
| 612 | |
| 613 TrackFragment::TrackFragment() {} | |
| 614 TrackFragment::~TrackFragment() {} | |
| 615 FourCC TrackFragment::BoxType() const { return FOURCC_TRAF; } | |
| 616 | |
| 617 bool TrackFragment::Parse(BoxReader* reader) { | |
| 618 return reader->ScanChildren() && | |
| 619 reader->ReadChild(&header) && | |
| 620 // Media Source specific: 'tfdt' required | |
| 621 reader->ReadChild(&decode_time) && | |
| 622 reader->MaybeReadChildren(&runs) && | |
| 623 reader->MaybeReadChild(&auxiliary_offset) && | |
| 624 reader->MaybeReadChild(&auxiliary_size); | |
| 625 } | |
| 626 | |
| 627 MovieFragment::MovieFragment() {} | |
| 628 MovieFragment::~MovieFragment() {} | |
| 629 FourCC MovieFragment::BoxType() const { return FOURCC_MOOF; } | |
| 630 | |
| 631 bool MovieFragment::Parse(BoxReader* reader) { | |
| 632 RCHECK(reader->ScanChildren() && | |
| 633 reader->ReadChild(&header) && | |
| 634 reader->ReadChildren(&tracks) && | |
| 635 reader->MaybeReadChildren(&pssh)); | |
| 636 return true; | |
| 637 } | |
| 638 | |
| 639 } // namespace mp4 | |
| 640 } // namespace media | |
| OLD | NEW |