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

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

Issue 10536014: Implement ISO BMFF support in Media Source. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: A thorough sign-ification Created 8 years, 6 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
(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(&timescale) &&
145 reader->Read8(&duration));
146 } else {
147 RCHECK(reader->Read4Into8(&creation_time) &&
148 reader->Read4Into8(&modification_time) &&
149 reader->Read4(&timescale) &&
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(&timescale) &&
389 reader->Read8(&duration));
390 } else {
391 RCHECK(reader->Read4Into8(&creation_time) &&
392 reader->Read4Into8(&modification_time) &&
393 reader->Read4(&timescale) &&
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698