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/rcheck.h" | |
| 10 #include "media/mp4/fourccs.h" | |
| 11 | |
| 12 namespace media { | |
| 13 namespace mp4 { | |
| 14 | |
| 15 bool Parse(BoxReader* r, FileType* type) { | |
|
acolwell GONE FROM CHROMIUM
2012/06/06 17:32:39
nit: r -> reader here and elsewhere
strobe_
2012/06/07 16:33:54
I'd argue that in this file, the reduced visual de
acolwell GONE FROM CHROMIUM
2012/06/07 19:44:02
I'm unconvinced. :) Please change it here and in a
| |
| 16 RCHECK(r->Read(&type->major_brand) && r->Read(&type->minor_version)); | |
| 17 size_t num_brands = (r->size() - r->pos()) / sizeof(FourCC); | |
| 18 return r->Skip(sizeof(FourCC) * num_brands); // compatible_brands | |
| 19 } | |
| 20 | |
| 21 ProtectionSystemSpecificHeader::ProtectionSystemSpecificHeader() {} | |
| 22 ProtectionSystemSpecificHeader::~ProtectionSystemSpecificHeader() {} | |
| 23 | |
| 24 bool Parse(BoxReader* r, ProtectionSystemSpecificHeader* pssh) { | |
| 25 uint32 size; | |
| 26 return r->Skip(4) && | |
| 27 r->Read(&pssh->system_id, 16) && | |
| 28 r->Read(&size) && | |
| 29 r->Read(&pssh->data, size); | |
| 30 } | |
| 31 | |
| 32 SampleAuxiliaryInformationOffset::SampleAuxiliaryInformationOffset() {} | |
| 33 SampleAuxiliaryInformationOffset::~SampleAuxiliaryInformationOffset() {} | |
| 34 | |
| 35 bool Parse(BoxReader* r, SampleAuxiliaryInformationOffset* saio) { | |
| 36 RCHECK(r->ReadFullBoxHeader()); | |
| 37 if (r->flags() & 1) | |
| 38 RCHECK(r->Skip(8)); | |
| 39 | |
| 40 uint32 count; | |
| 41 RCHECK(r->Read(&count) && | |
| 42 r->HasBytes(count * (r->version() == 1 ? 8 : 4))); | |
| 43 saio->offsets.resize(count); | |
| 44 | |
| 45 for (uint32 i = 0; i < count; i++) { | |
| 46 if (r->version() == 1) { | |
| 47 RCHECK(r->Read(&saio->offsets[i])); | |
| 48 } else { | |
| 49 RCHECK(r->Read4(&saio->offsets[i])); | |
| 50 } | |
| 51 } | |
| 52 return true; | |
| 53 } | |
| 54 | |
| 55 SampleAuxiliaryInformationSize::SampleAuxiliaryInformationSize() | |
| 56 : default_sample_info_size(0), sample_count(0) {} | |
|
acolwell GONE FROM CHROMIUM
2012/06/06 17:32:39
nit: } on next line
strobe_
2012/06/07 16:33:54
Done.
| |
| 57 | |
| 58 SampleAuxiliaryInformationSize::~SampleAuxiliaryInformationSize() {} | |
| 59 | |
| 60 bool Parse(BoxReader* r, SampleAuxiliaryInformationSize* saiz) { | |
| 61 RCHECK(r->ReadFullBoxHeader()); | |
| 62 if (r->flags() & 1) | |
| 63 RCHECK(r->Skip(8)); | |
| 64 | |
| 65 RCHECK(r->Read(&saiz->default_sample_info_size) && | |
| 66 r->Read(&saiz->sample_count)); | |
| 67 if (saiz->default_sample_info_size == 0) | |
| 68 return r->Read(&saiz->sample_info_sizes, saiz->sample_count); | |
| 69 return true; | |
| 70 } | |
| 71 | |
| 72 bool Parse(BoxReader* r, OriginalFormat* format) { | |
| 73 return r->Read(&format->format); | |
| 74 } | |
| 75 | |
| 76 bool Parse(BoxReader* r, SchemeType* schm) { | |
| 77 RCHECK(r->Skip(4) && r->Read(&schm->type) && r->Read(&schm->version)); | |
| 78 RCHECK(schm->type == FOURCC_CENC); | |
| 79 return true; | |
| 80 } | |
| 81 | |
| 82 TrackEncryption::TrackEncryption() | |
| 83 : is_encrypted(false), default_iv_size(0) {} | |
|
acolwell GONE FROM CHROMIUM
2012/06/06 17:32:39
nit: } on next line.
strobe_
2012/06/07 16:33:54
Done.
| |
| 84 TrackEncryption::~TrackEncryption() {} | |
| 85 | |
| 86 bool Parse(BoxReader* r, TrackEncryption* tenc) { | |
| 87 uint8 flag; | |
| 88 RCHECK(r->Skip(2) && | |
| 89 r->Read(&flag) && | |
| 90 r->Read(&tenc->default_iv_size) && | |
| 91 r->Read(&tenc->default_kid, 16)); | |
| 92 tenc->is_encrypted = (flag != 0); | |
| 93 if (tenc->is_encrypted) { | |
| 94 RCHECK(tenc->default_iv_size == 8 || tenc->default_iv_size == 16); | |
| 95 } else { | |
| 96 RCHECK(tenc->default_iv_size == 0); | |
| 97 } | |
| 98 return true; | |
| 99 } | |
| 100 | |
| 101 bool Parse(BoxReader* r, SchemeInfo* schi) { | |
| 102 return r->ScanChildren() && r->ReadChild(&schi->track_encryption); | |
| 103 } | |
| 104 | |
| 105 bool Parse(BoxReader* r, ProtectionSchemeInfo* sinf) { | |
| 106 return r->ScanChildren() && | |
| 107 r->ReadChild(&sinf->type) && | |
| 108 r->ReadChild(&sinf->info); | |
| 109 } | |
| 110 | |
| 111 bool Parse(BoxReader* r, MovieHeader* mvhd) { | |
| 112 RCHECK(r->ReadFullBoxHeader()); | |
| 113 | |
| 114 if (r->version() == 1) { | |
| 115 RCHECK(r->Read(&mvhd->creation_time) && | |
| 116 r->Read(&mvhd->modification_time) && | |
| 117 r->Read(&mvhd->timescale) && | |
| 118 r->Read(&mvhd->duration)); | |
| 119 } else { | |
| 120 RCHECK(r->Read4(&mvhd->creation_time) && | |
| 121 r->Read4(&mvhd->modification_time) && | |
| 122 r->Read(&mvhd->timescale) && | |
| 123 r->Read4(&mvhd->duration)); | |
| 124 } | |
| 125 | |
| 126 RCHECK(r->Read(&mvhd->rate) && | |
| 127 r->Read(&mvhd->volume) && | |
| 128 r->Skip(10) && // reserved | |
|
acolwell GONE FROM CHROMIUM
2012/06/06 17:32:39
WDYT about renaming this to SkipBytes so the units
strobe_
2012/06/07 16:33:54
Done.
| |
| 129 r->Skip(36) && // matrix | |
| 130 r->Skip(24) && // predefined zero | |
| 131 r->Read(&mvhd->next_track_id)); | |
| 132 return true; | |
| 133 } | |
| 134 | |
| 135 TrackHeader::TrackHeader() {} | |
| 136 TrackHeader::~TrackHeader() {} | |
| 137 | |
| 138 | |
| 139 bool Parse(BoxReader* r, TrackHeader* tkhd) { | |
| 140 RCHECK(r->ReadFullBoxHeader()); | |
| 141 if (r->version() == 1) { | |
| 142 RCHECK(r->Read(&tkhd->creation_time) && | |
| 143 r->Read(&tkhd->modification_time) && | |
| 144 r->Read(&tkhd->track_id) && | |
| 145 r->Skip(4) && // reserved | |
| 146 r->Read(&tkhd->duration)); | |
| 147 } else { | |
| 148 RCHECK(r->Read4(&tkhd->creation_time) && | |
| 149 r->Read4(&tkhd->modification_time) && | |
| 150 r->Read(&tkhd->track_id) && | |
| 151 r->Skip(4) && // reserved | |
| 152 r->Read4(&tkhd->duration)); | |
| 153 } | |
| 154 | |
| 155 RCHECK(r->Skip(8) && // reserved | |
| 156 r->Read(&tkhd->layer) && | |
| 157 r->Read(&tkhd->alternate_group) && | |
| 158 r->Read(&tkhd->volume) && | |
| 159 r->Skip(2) && // reserved | |
| 160 r->Skip(36) && // matrix | |
| 161 r->Read(&tkhd->width) && | |
| 162 r->Read(&tkhd->height)); | |
| 163 tkhd->width >>= 16; | |
| 164 tkhd->height >>= 16; | |
| 165 return true; | |
| 166 } | |
| 167 | |
| 168 SampleDescription::SampleDescription() {} | |
| 169 SampleDescription::~SampleDescription() {} | |
| 170 | |
| 171 bool Parse(BoxReader* r, SampleDescription* desc) { | |
| 172 uint32 count; | |
| 173 RCHECK(r->Skip(4) && r->Read(&count) && r->ScanChildren()); | |
| 174 desc->video_entries.clear(); | |
| 175 desc->audio_entries.clear(); | |
| 176 | |
| 177 // Note: this value is preset before scanning begins. See comments in the | |
| 178 // Parse(Media*) function. | |
| 179 if (desc->type == kVideo) { | |
| 180 RCHECK(r->ReadAllChildren(&desc->video_entries)); | |
| 181 } else if (desc->type == kAudio) { | |
| 182 RCHECK(r->ReadAllChildren(&desc->audio_entries)); | |
| 183 } | |
| 184 return true; | |
| 185 } | |
| 186 | |
| 187 SampleTable::SampleTable() {} | |
| 188 SampleTable::~SampleTable() {} | |
| 189 | |
| 190 bool Parse(BoxReader* r, SampleTable* table) { | |
| 191 return r->ScanChildren() && | |
| 192 r->ReadChild(&table->description); | |
| 193 } | |
| 194 | |
| 195 EditList::EditList() {} | |
| 196 EditList::~EditList() {} | |
| 197 | |
| 198 bool Parse(BoxReader* r, EditList* list) { | |
| 199 uint32 count; | |
| 200 RCHECK(r->ReadFullBoxHeader() && r->Read(&count)); | |
| 201 | |
| 202 if (r->version() == 1) { | |
| 203 RCHECK(r->HasBytes(count * 20)); | |
| 204 } else { | |
| 205 RCHECK(r->HasBytes(count * 12)); | |
| 206 } | |
| 207 list->edits.resize(count); | |
| 208 | |
| 209 for (auto edit = list->edits.begin(); edit != list->edits.end(); ++edit) { | |
| 210 if (r->version() == 1) { | |
| 211 RCHECK(r->Read(&edit->segment_duration) && | |
| 212 r->Read(&edit->media_time)); | |
| 213 } else { | |
| 214 RCHECK(r->Read4(&edit->segment_duration) && | |
| 215 r->Read4(&edit->media_time)); | |
| 216 } | |
| 217 RCHECK(r->Read(&edit->media_rate_integer) && | |
| 218 r->Read(&edit->media_rate_fraction)); | |
| 219 } | |
| 220 return true; | |
| 221 } | |
| 222 | |
| 223 Edit::Edit() {} | |
| 224 Edit::~Edit() {} | |
| 225 | |
| 226 bool Parse(BoxReader* r, Edit* box) { | |
| 227 return r->ScanChildren() && r->ReadChild(&box->list); | |
| 228 } | |
| 229 | |
| 230 bool Parse(BoxReader* r, HandlerReference* reference) { | |
| 231 FourCC type; | |
| 232 RCHECK(r->Skip(8) && r->Read(&type)); | |
| 233 // Note: remaining fields in box ignored | |
| 234 if (type == FOURCC_VIDE) { | |
| 235 | |
| 236 reference->type = kVideo; | |
| 237 } else if (type == FOURCC_SOUN) { | |
| 238 reference->type = kAudio; | |
| 239 } else { | |
| 240 reference->type = kInvalid; | |
| 241 } | |
| 242 return true; | |
| 243 } | |
| 244 | |
| 245 SampleEntry::SampleEntry() {} | |
| 246 SampleEntry::~SampleEntry() {} | |
| 247 | |
| 248 bool ParseSampleEntryHead(BoxReader* r, SampleEntry* entry) { | |
| 249 entry->format = r->type(); | |
| 250 return r->Skip(6) && r->Read(&entry->data_reference_index); | |
| 251 } | |
| 252 | |
| 253 AudioSampleEntry::AudioSampleEntry() {} | |
| 254 AudioSampleEntry::~AudioSampleEntry() {} | |
| 255 | |
| 256 bool Parse(BoxReader* r, AudioSampleEntry* entry) { | |
| 257 RCHECK(ParseSampleEntryHead(r, entry) && | |
| 258 r->Skip(8) && | |
| 259 r->Read(&entry->channelcount) && | |
| 260 r->Read(&entry->samplesize) && | |
| 261 r->Skip(4) && | |
| 262 r->Read(&entry->samplerate)); | |
| 263 // Convert from 16.16 fixed point to integer | |
| 264 entry->samplerate >>= 16; | |
| 265 | |
| 266 RCHECK(r->ScanChildren()); | |
| 267 if (entry->format == FOURCC_ENCA) { | |
| 268 RCHECK(r->ReadChild(&entry->sinf)); | |
| 269 } | |
| 270 return true; | |
| 271 } | |
| 272 | |
| 273 VideoSampleEntry::VideoSampleEntry() {} | |
| 274 VideoSampleEntry::~VideoSampleEntry() {} | |
| 275 | |
| 276 bool Parse(BoxReader* r, VideoSampleEntry* entry) { | |
| 277 RCHECK(ParseSampleEntryHead(r, entry) && | |
| 278 r->Skip(16) && | |
| 279 r->Read(&entry->width) && | |
| 280 r->Read(&entry->height) && | |
| 281 r->Skip(50)); | |
| 282 | |
| 283 RCHECK(r->ScanChildren()); | |
| 284 if (entry->format == FOURCC_ENCV) { | |
| 285 RCHECK(r->ReadChild(&entry->sinf)); | |
| 286 } | |
| 287 | |
| 288 // TODO(strobe): Widevine test files do not follow spec here; check disabled | |
| 289 //if (entry->format == FOURCC_AVC1 || | |
| 290 // (entry->format == FOURCC_ENCV && | |
| 291 // entry->sinf.format.format == FOURCC_AVC1)) { | |
| 292 RCHECK(r->ReadChild(&entry->avcc)); | |
| 293 //} | |
| 294 return true; | |
| 295 } | |
| 296 | |
| 297 MediaHeader::MediaHeader() {} | |
| 298 MediaHeader::~MediaHeader() {} | |
| 299 | |
| 300 bool Parse(BoxReader* r, MediaHeader* header) { | |
| 301 RCHECK(r->ReadFullBoxHeader()); | |
| 302 | |
| 303 if (r->version() == 1) { | |
| 304 RCHECK(r->Read(&header->creation_time) && | |
| 305 r->Read(&header->modification_time) && | |
| 306 r->Read(&header->timescale) && | |
| 307 r->Read(&header->duration)); | |
| 308 } else { | |
| 309 RCHECK(r->Read4(&header->creation_time) && | |
| 310 r->Read4(&header->modification_time) && | |
| 311 r->Read(&header->timescale) && | |
| 312 r->Read4(&header->duration)); | |
| 313 } | |
| 314 // Skip language information | |
| 315 return r->Skip(4); | |
| 316 } | |
| 317 | |
| 318 bool Parse(BoxReader* r, MediaInformation* information) { | |
| 319 return r->ScanChildren() && | |
| 320 r->ReadChild(&information->sample_table); | |
| 321 } | |
| 322 | |
| 323 bool Parse(BoxReader* r, Media* media) { | |
| 324 RCHECK(r->ScanChildren() && | |
| 325 r->ReadChild(&media->header) && | |
| 326 r->ReadChild(&media->handler)); | |
| 327 | |
| 328 // Maddeningly, the HandlerReference box specifies how to parse the | |
| 329 // SampleDescription box, making the latter the only box (of those that we | |
| 330 // support) which cannot be parsed correctly on its own (or even with | |
| 331 // information from its strict ancestor tree). We thus copy the handler type | |
| 332 // to the sample description box *before* parsing it to provide this | |
| 333 // information while parsing. | |
| 334 media->information.sample_table.description.type = media->handler.type; | |
| 335 RCHECK(r->ReadChild(&media->information)); | |
| 336 return true; | |
| 337 } | |
| 338 | |
| 339 bool Parse(BoxReader* r, Track* track) { | |
| 340 RCHECK(r->ScanChildren() && | |
| 341 r->ReadChild(&track->header) && | |
| 342 r->ReadChild(&track->media) && | |
| 343 r->MaybeReadChild(&track->edit)); | |
| 344 return true; | |
| 345 } | |
| 346 | |
| 347 bool Parse(BoxReader* r, MovieExtendsHeader* header) { | |
| 348 RCHECK(r->Read(&header->fragment_duration)); | |
| 349 return true; | |
| 350 } | |
| 351 | |
| 352 bool Parse(BoxReader* r, TrackExtends* extends) { | |
| 353 RCHECK(r->ReadFullBoxHeader() && | |
| 354 r->Read(&extends->track_id) && | |
| 355 r->Read(&extends->default_sample_description_index) && | |
| 356 r->Read(&extends->default_sample_duration) && | |
| 357 r->Read(&extends->default_sample_size) && | |
| 358 r->Read(&extends->default_sample_flags)); | |
| 359 return true; | |
| 360 } | |
| 361 | |
| 362 MovieExtends::MovieExtends() {}; | |
| 363 MovieExtends::~MovieExtends() {}; | |
| 364 | |
| 365 bool Parse(BoxReader* r, MovieExtends* extends) { | |
| 366 extends->header.fragment_duration = 0; | |
| 367 return r->ScanChildren() && | |
| 368 r->MaybeReadChild(&extends->header) && | |
| 369 // TODO(strobe): does not detect correspondence rule (trex must match | |
| 370 // one-to-one with trak) | |
| 371 r->ReadChildren(&extends->tracks); | |
| 372 } | |
| 373 | |
| 374 Movie::Movie() {}; | |
| 375 Movie::~Movie() {}; | |
| 376 | |
| 377 bool Parse(BoxReader* r, Movie* moov) { | |
| 378 return r->ScanChildren() && | |
| 379 r->ReadChild(&moov->header) && | |
| 380 r->ReadChildren(&moov->tracks) && | |
| 381 // Media Source specific: 'mvex' required | |
| 382 r->ReadChild(&moov->extends) && | |
| 383 r->MaybeReadChildren(&moov->pssh); | |
| 384 } | |
| 385 | |
| 386 bool Parse(BoxReader* r, TrackFragmentDecodeTime* tfdt) { | |
| 387 RCHECK(r->ReadFullBoxHeader()); | |
| 388 if (r->version() == 1) | |
| 389 return r->Read(&tfdt->decode_time); | |
| 390 else | |
| 391 return r->Read4(&tfdt->decode_time); | |
| 392 } | |
| 393 | |
| 394 bool Parse(BoxReader* r, MovieFragmentHeader* mfhd) { | |
| 395 return r->Skip(4) && r->Read(&mfhd->sequence_number); | |
| 396 } | |
| 397 | |
| 398 bool Parse(BoxReader* r, TrackFragmentHeader* tfhd) { | |
| 399 memset(tfhd, 0, sizeof(TrackFragmentHeader)); | |
| 400 | |
| 401 RCHECK(r->ReadFullBoxHeader() && r->Read(&tfhd->track_id)); | |
| 402 | |
| 403 // Media Source specific: we require that 'default-base-is-moof' (14496-12 | |
| 404 // Amendment 2) be set, and reject tracks that set 'base-data-offset-present'. | |
| 405 // | |
| 406 // TODO(strobe): Test files do not have 'default-base-is-moof' set explicitly | |
| 407 // (although they are structured as if it is set). Because this flag is hidden | |
| 408 // in Amendment 2, it might not be set by all implementors. Should we reject | |
| 409 // such files, or try them anyway? | |
| 410 // | |
| 411 // RCHECK((flags & 0x020000) && !(flags & 0x1)); | |
| 412 RCHECK(!(r->flags() & 0x1)); | |
| 413 | |
| 414 if (r->flags() & 0x2) | |
| 415 RCHECK(r->Skip(4)); // sample_description_index | |
| 416 | |
| 417 if (r->flags() & 0x8) | |
| 418 RCHECK(r->Read(&tfhd->default_sample_duration)); | |
| 419 | |
| 420 if (r->flags() & 0x10) | |
| 421 RCHECK(r->Read(&tfhd->default_sample_size)); | |
| 422 | |
| 423 if (r->flags() & 0x20) | |
| 424 RCHECK(r->Read(&tfhd->default_sample_flags)); | |
| 425 | |
| 426 return true; | |
| 427 } | |
| 428 | |
| 429 TrackFragmentRun::TrackFragmentRun() {} | |
| 430 TrackFragmentRun::~TrackFragmentRun() {} | |
| 431 | |
| 432 bool Parse(BoxReader* r, TrackFragmentRun* trun) { | |
| 433 RCHECK(r->ReadFullBoxHeader() && | |
| 434 r->Read(&trun->sample_count)); | |
| 435 const uint32 flags = r->flags(); | |
| 436 | |
| 437 bool data_offset_present = flags & 0x1; | |
| 438 bool first_sample_flags_present = flags & 0x4; | |
| 439 bool sample_duration_present = flags & 0x100; | |
| 440 bool sample_size_present = flags & 0x200; | |
| 441 bool sample_flags_present = flags & 0x400; | |
| 442 bool sample_composition_time_offsets_present = flags & 0x800; | |
| 443 | |
| 444 if (data_offset_present) { | |
| 445 RCHECK(r->Read(&trun->data_offset)); | |
| 446 } else { | |
| 447 trun->data_offset = 0; | |
| 448 } | |
| 449 | |
| 450 uint32 first_sample_flags; | |
| 451 if (first_sample_flags_present) | |
| 452 RCHECK(r->Read(&first_sample_flags)); | |
| 453 | |
| 454 int fields = sample_duration_present + sample_size_present | |
| 455 + sample_flags_present + sample_composition_time_offsets_present; | |
|
acolwell GONE FROM CHROMIUM
2012/06/06 17:32:39
nit: + goes on the end of the previous line and th
strobe_
2012/06/07 16:33:54
Done.
| |
| 456 RCHECK(r->HasBytes(fields * trun->sample_count)); | |
| 457 | |
| 458 if (sample_duration_present) | |
| 459 trun->sample_durations.resize(trun->sample_count); | |
| 460 if (sample_size_present) | |
| 461 trun->sample_sizes.resize(trun->sample_count); | |
| 462 if (sample_flags_present) | |
| 463 trun->sample_flags.resize(trun->sample_count); | |
| 464 if (sample_composition_time_offsets_present) | |
| 465 trun->sample_composition_time_offsets.resize(trun->sample_count); | |
| 466 | |
| 467 for (uint32 i = 0; i < trun->sample_count; ++i) { | |
| 468 if (sample_duration_present) | |
| 469 RCHECK(r->Read(&trun->sample_durations[i])); | |
| 470 if (sample_size_present) | |
| 471 RCHECK(r->Read(&trun->sample_sizes[i])); | |
| 472 if (sample_flags_present) | |
| 473 RCHECK(r->Read(&trun->sample_flags[i])); | |
| 474 if (sample_composition_time_offsets_present) | |
| 475 RCHECK(r->Read(&trun->sample_composition_time_offsets[i])); | |
| 476 } | |
| 477 | |
| 478 if (first_sample_flags_present) { | |
| 479 if (trun->sample_flags.size() == 0) { | |
| 480 trun->sample_flags.push_back(first_sample_flags); | |
| 481 } else { | |
| 482 trun->sample_flags[0] = first_sample_flags; | |
| 483 } | |
| 484 } | |
| 485 return true; | |
| 486 } | |
| 487 | |
| 488 TrackFragment::TrackFragment() {} | |
| 489 TrackFragment::~TrackFragment() {} | |
| 490 | |
| 491 bool Parse(BoxReader* r, TrackFragment* traf) { | |
| 492 return r->ScanChildren() && | |
| 493 r->ReadChild(&traf->header) && | |
| 494 // Media Source specific: 'tfdt' required | |
| 495 r->ReadChild(&traf->decode_time) && | |
| 496 r->MaybeReadChildren(&traf->runs) && | |
| 497 r->MaybeReadChild(&traf->auxiliary_offset) && | |
| 498 r->MaybeReadChild(&traf->auxiliary_size); | |
| 499 } | |
| 500 | |
| 501 MovieFragment::MovieFragment() {} | |
| 502 MovieFragment::~MovieFragment() {} | |
| 503 | |
| 504 bool Parse(BoxReader* r, MovieFragment* moof) { | |
| 505 RCHECK(r->ScanChildren() && | |
| 506 r->ReadChild(&moof->header) && | |
| 507 r->ReadChildren(&moof->tracks) && | |
| 508 r->MaybeReadChildren(&moof->pssh)); | |
| 509 return true; | |
| 510 } | |
| 511 | |
| 512 bool Parse(BoxReader* r, SegmentIndex* sidx) { | |
| 513 RCHECK(r->ReadFullBoxHeader() && | |
| 514 r->Read(&sidx->reference_id) && | |
| 515 r->Read(&sidx->timescale)); | |
| 516 | |
| 517 if (r->version() == 0) { | |
| 518 RCHECK(r->Read4(&sidx->earliest_presentation_time) && | |
| 519 r->Read4(&sidx->first_offset)); | |
| 520 } else { | |
| 521 RCHECK(r->Read(&sidx->earliest_presentation_time) && | |
| 522 r->Read(&sidx->first_offset)); | |
| 523 } | |
| 524 | |
| 525 uint32 reference_count; | |
| 526 RCHECK(r->Skip(2) && // reserved | |
| 527 r->Read(&reference_count) && | |
| 528 r->HasBytes(12 * reference_count)); | |
| 529 | |
| 530 for (uint32 i = 0; i < reference_count; ++i) { | |
| 531 uint32 flags; | |
| 532 RCHECK(r->Read(&sidx->sizes[i]) && | |
| 533 r->Read(&sidx->durations[i]) && | |
| 534 r->Read(&flags)); | |
| 535 | |
| 536 uint32 type = flags / 0x10000000 % 8; | |
| 537 | |
| 538 RCHECK(!(sidx->sizes[i] & 0x8000000) != 0 || | |
|
acolwell GONE FROM CHROMIUM
2012/06/06 17:32:39
What?!? A comment indicating what this is checking
| |
| 539 (flags & 0x80000000) != 0x80000000 || | |
| 540 (type != 0 && type != 1) || | |
| 541 (flags % 0x10000000 != 0)); | |
| 542 } | |
| 543 return true; | |
| 544 } | |
| 545 | |
| 546 } // namespace mp4 | |
| 547 } // namespace media | |
| OLD | NEW |