blob: 7938fa4c993c61bafb2f54a8b9781983195721e9 [file] [log] [blame]
Andreas Huber84066782011-08-16 09:34:26 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "Parser"
19#include <utils/Log.h>
20
21#include "Parser.h"
22#include "TrackFragment.h"
23
24#include "ESDS.h"
25
26#include <media/stagefright/foundation/ABuffer.h>
27#include <media/stagefright/foundation/ADebug.h>
28#include <media/stagefright/foundation/AMessage.h>
29#include <media/stagefright/foundation/hexdump.h>
30#include <media/stagefright/MediaDefs.h>
31#include <media/stagefright/MediaErrors.h>
32#include <media/stagefright/Utils.h>
33
34#include "../NuPlayerStreamListener.h"
35
36namespace android {
37
38static const char *Fourcc2String(uint32_t fourcc) {
39 static char buffer[5];
40 buffer[4] = '\0';
41 buffer[0] = fourcc >> 24;
42 buffer[1] = (fourcc >> 16) & 0xff;
43 buffer[2] = (fourcc >> 8) & 0xff;
44 buffer[3] = fourcc & 0xff;
45
46 return buffer;
47}
48
49static const char *IndentString(size_t n) {
50 static const char kSpace[] = " ";
51 return kSpace + sizeof(kSpace) - 2 * n - 1;
52}
53
54// static
55const Parser::DispatchEntry Parser::kDispatchTable[] = {
56 { FOURCC('m', 'o', 'o', 'v'), 0, NULL },
57 { FOURCC('t', 'r', 'a', 'k'), FOURCC('m', 'o', 'o', 'v'), NULL },
58 { FOURCC('u', 'd', 't', 'a'), FOURCC('t', 'r', 'a', 'k'), NULL },
59 { FOURCC('u', 'd', 't', 'a'), FOURCC('m', 'o', 'o', 'v'), NULL },
60 { FOURCC('m', 'e', 't', 'a'), FOURCC('u', 'd', 't', 'a'), NULL },
61 { FOURCC('i', 'l', 's', 't'), FOURCC('m', 'e', 't', 'a'), NULL },
62
63 { FOURCC('t', 'k', 'h', 'd'), FOURCC('t', 'r', 'a', 'k'),
64 &Parser::parseTrackHeader
65 },
66
67 { FOURCC('m', 'v', 'e', 'x'), FOURCC('m', 'o', 'o', 'v'), NULL },
68
69 { FOURCC('t', 'r', 'e', 'x'), FOURCC('m', 'v', 'e', 'x'),
70 &Parser::parseTrackExtends
71 },
72
73 { FOURCC('e', 'd', 't', 's'), FOURCC('t', 'r', 'a', 'k'), NULL },
74 { FOURCC('m', 'd', 'i', 'a'), FOURCC('t', 'r', 'a', 'k'), NULL },
75
76 { FOURCC('m', 'd', 'h', 'd'), FOURCC('m', 'd', 'i', 'a'),
77 &Parser::parseMediaHeader
78 },
79
80 { FOURCC('h', 'd', 'l', 'r'), FOURCC('m', 'd', 'i', 'a'),
81 &Parser::parseMediaHandler
82 },
83
84 { FOURCC('m', 'i', 'n', 'f'), FOURCC('m', 'd', 'i', 'a'), NULL },
85 { FOURCC('d', 'i', 'n', 'f'), FOURCC('m', 'i', 'n', 'f'), NULL },
86 { FOURCC('s', 't', 'b', 'l'), FOURCC('m', 'i', 'n', 'f'), NULL },
87 { FOURCC('s', 't', 's', 'd'), FOURCC('s', 't', 'b', 'l'), NULL },
88
89 { FOURCC('s', 't', 's', 'z'), FOURCC('s', 't', 'b', 'l'),
90 &Parser::parseSampleSizes },
91
92 { FOURCC('s', 't', 'z', '2'), FOURCC('s', 't', 'b', 'l'),
93 &Parser::parseCompactSampleSizes },
94
95 { FOURCC('s', 't', 's', 'c'), FOURCC('s', 't', 'b', 'l'),
96 &Parser::parseSampleToChunk },
97
98 { FOURCC('s', 't', 'c', 'o'), FOURCC('s', 't', 'b', 'l'),
99 &Parser::parseChunkOffsets },
100
101 { FOURCC('c', 'o', '6', '4'), FOURCC('s', 't', 'b', 'l'),
102 &Parser::parseChunkOffsets64 },
103
104 { FOURCC('a', 'v', 'c', 'C'), FOURCC('a', 'v', 'c', '1'),
105 &Parser::parseAVCCodecSpecificData },
106
107 { FOURCC('e', 's', 'd', 's'), FOURCC('m', 'p', '4', 'a'),
108 &Parser::parseESDSCodecSpecificData },
109
110 { FOURCC('e', 's', 'd', 's'), FOURCC('m', 'p', '4', 'v'),
111 &Parser::parseESDSCodecSpecificData },
112
113 { FOURCC('m', 'd', 'a', 't'), 0, &Parser::parseMediaData },
114
115 { FOURCC('m', 'o', 'o', 'f'), 0, NULL },
116 { FOURCC('t', 'r', 'a', 'f'), FOURCC('m', 'o', 'o', 'f'), NULL },
117
118 { FOURCC('t', 'f', 'h', 'd'), FOURCC('t', 'r', 'a', 'f'),
119 &Parser::parseTrackFragmentHeader
120 },
121 { FOURCC('t', 'r', 'u', 'n'), FOURCC('t', 'r', 'a', 'f'),
122 &Parser::parseTrackFragmentRun
123 },
124
125 { FOURCC('m', 'f', 'r', 'a'), 0, NULL },
126};
127
128struct FileSource : public Parser::Source {
129 FileSource(const char *filename)
130 : mFile(fopen(filename, "rb")) {
131 CHECK(mFile != NULL);
132 }
133
134 virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
135 fseek(mFile, offset, SEEK_SET);
136 return fread(data, 1, size, mFile);
137 }
138
139 private:
140 FILE *mFile;
141
142 DISALLOW_EVIL_CONSTRUCTORS(FileSource);
143};
144
145Parser::Parser()
146 : mBufferPos(0),
147 mSuspended(false) {
148}
149
150Parser::~Parser() {
151}
152
153void Parser::start(const char *filename) {
154 sp<AMessage> msg = new AMessage(kWhatStart, id());
155 msg->setObject("source", new FileSource(filename));
156 msg->post();
157}
158
159void Parser::start(const sp<Source> &source) {
160 sp<AMessage> msg = new AMessage(kWhatStart, id());
161 msg->setObject("source", source);
162 msg->post();
163}
164
165sp<AMessage> Parser::getFormat(bool audio) {
166 sp<AMessage> msg = new AMessage(kWhatGetFormat, id());
167 msg->setInt32("audio", audio);
168
169 sp<AMessage> response;
170 status_t err = msg->postAndAwaitResponse(&response);
171
172 if (err != OK) {
173 return NULL;
174 }
175
176 if (response->findInt32("err", &err) && err != OK) {
177 return NULL;
178 }
179
180 sp<AMessage> format;
181 CHECK(response->findMessage("format", &format));
182
183 ALOGV("returning format %s", format->debugString().c_str());
184 return format;
185}
186
187status_t Parser::dequeueAccessUnit(bool audio, sp<ABuffer> *accessUnit) {
188 sp<AMessage> msg = new AMessage(kWhatDequeueAccessUnit, id());
189 msg->setInt32("audio", audio);
190
191 sp<AMessage> response;
192 status_t err = msg->postAndAwaitResponse(&response);
193
194 if (err != OK) {
195 return err;
196 }
197
198 if (response->findInt32("err", &err) && err != OK) {
199 return err;
200 }
201
202 CHECK(response->findBuffer("accessUnit", accessUnit));
203
204 return OK;
205}
206
207ssize_t Parser::findTrack(bool wantAudio) const {
208 for (size_t i = 0; i < mTracks.size(); ++i) {
209 const TrackInfo *info = &mTracks.valueAt(i);
210
211 bool isAudio =
212 info->mMediaHandlerType == FOURCC('s', 'o', 'u', 'n');
213
214 bool isVideo =
215 info->mMediaHandlerType == FOURCC('v', 'i', 'd', 'e');
216
217 if ((wantAudio && isAudio) || (!wantAudio && !isAudio)) {
218 if (info->mSampleDescs.empty()) {
219 break;
220 }
221
222 return i;
223 }
224 }
225
226 return -EWOULDBLOCK;
227}
228
229void Parser::onMessageReceived(const sp<AMessage> &msg) {
230 switch (msg->what()) {
231 case kWhatStart:
232 {
233 sp<RefBase> obj;
234 CHECK(msg->findObject("source", &obj));
235
236 mSource = static_cast<Source *>(obj.get());
237
238 mBuffer = new ABuffer(512 * 1024);
239 mBuffer->setRange(0, 0);
240
241 enter(0, 0);
242
243 (new AMessage(kWhatProceed, id()))->post();
244 break;
245 }
246
247 case kWhatProceed:
248 {
249 CHECK(!mSuspended);
250
251 status_t err = onProceed();
252
253 if (err == OK) {
254 if (!mSuspended) {
255 msg->post();
256 }
257 } else if (err != -EAGAIN) {
258 ALOGE("onProceed returned error %d", err);
259 }
260
261 break;
262 }
263
264 case kWhatReadMore:
265 {
266 size_t needed;
267 CHECK(msg->findSize("needed", &needed));
268
269 memmove(mBuffer->base(), mBuffer->data(), mBuffer->size());
270 mBufferPos += mBuffer->offset();
271 mBuffer->setRange(0, mBuffer->size());
272
273 size_t maxBytesToRead = mBuffer->capacity() - mBuffer->size();
Andreas Huberb9787142012-08-09 09:15:48 -0700274
275 if (maxBytesToRead < needed) {
276 ALOGI("resizing buffer.");
277
278 sp<ABuffer> newBuffer =
279 new ABuffer((mBuffer->size() + needed + 1023) & ~1023);
280 memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
281 newBuffer->setRange(0, mBuffer->size());
282
283 mBuffer = newBuffer;
284 maxBytesToRead = mBuffer->capacity() - mBuffer->size();
285 }
286
Andreas Huber84066782011-08-16 09:34:26 -0700287 CHECK_GE(maxBytesToRead, needed);
288
289 ssize_t n = mSource->readAt(
290 mBufferPos + mBuffer->size(),
291 mBuffer->data() + mBuffer->size(), needed);
292
293 if (n < (ssize_t)needed) {
294 ALOGI("%s", "Reached EOF");
295 } else {
296 mBuffer->setRange(0, mBuffer->size() + n);
297 (new AMessage(kWhatProceed, id()))->post();
298 }
299
300 break;
301 }
302
303 case kWhatGetFormat:
304 {
305 int32_t wantAudio;
306 CHECK(msg->findInt32("audio", &wantAudio));
307
308 status_t err = -EWOULDBLOCK;
309 sp<AMessage> response = new AMessage;
310
311 ssize_t trackIndex = findTrack(wantAudio);
312
313 if (trackIndex < 0) {
314 err = trackIndex;
315 } else {
316 TrackInfo *info = &mTracks.editValueAt(trackIndex);
317
318 response->setMessage(
319 "format", info->mSampleDescs.itemAt(0).mFormat);
320
321 err = OK;
322 }
323
324 response->setInt32("err", err);
325
326 uint32_t replyID;
327 CHECK(msg->senderAwaitsResponse(&replyID));
328
329 response->postReply(replyID);
330 break;
331 }
332
333 case kWhatDequeueAccessUnit:
334 {
335 int32_t wantAudio;
336 CHECK(msg->findInt32("audio", &wantAudio));
337
338 status_t err = -EWOULDBLOCK;
339 sp<AMessage> response = new AMessage;
340
341 ssize_t trackIndex = findTrack(wantAudio);
342
343 if (trackIndex < 0) {
344 err = trackIndex;
345 } else {
346 sp<ABuffer> accessUnit;
347 err = onDequeueAccessUnit(trackIndex, &accessUnit);
348
349 if (err == OK) {
350 response->setBuffer("accessUnit", accessUnit);
351 }
352 }
353
354 response->setInt32("err", err);
355
356 uint32_t replyID;
357 CHECK(msg->senderAwaitsResponse(&replyID));
358
359 response->postReply(replyID);
360 break;
361 }
362
363 default:
364 TRESPASS();
365 }
366}
367
368status_t Parser::onProceed() {
369 status_t err;
370
371 if ((err = need(8)) != OK) {
372 return err;
373 }
374
375 uint64_t size = readU32(0);
376 uint32_t type = readU32(4);
377
378 size_t offset = 8;
379
380 if (size == 1) {
381 if ((err = need(16)) != OK) {
382 return err;
383 }
384
385 size = readU64(offset);
386 offset += 8;
387 }
388
389 uint8_t userType[16];
390
391 if (type == FOURCC('u', 'u', 'i', 'd')) {
392 if ((err = need(offset + 16)) != OK) {
393 return err;
394 }
395
396 memcpy(userType, mBuffer->data() + offset, 16);
397 offset += 16;
398 }
399
400 CHECK(!mStack.isEmpty());
401 uint32_t ptype = mStack.itemAt(mStack.size() - 1).mType;
402
403 static const size_t kNumDispatchers =
404 sizeof(kDispatchTable) / sizeof(kDispatchTable[0]);
405
406 size_t i;
407 for (i = 0; i < kNumDispatchers; ++i) {
408 if (kDispatchTable[i].mType == type
409 && kDispatchTable[i].mParentType == ptype) {
410 break;
411 }
412 }
413
414 // SampleEntry boxes are container boxes that start with a variable
415 // amount of data depending on the media handler type.
416 // We don't look inside 'hint' type SampleEntry boxes.
417
418 bool isSampleEntryBox =
419 (ptype == FOURCC('s', 't', 's', 'd'))
420 && editTrack(mCurrentTrackID)->mMediaHandlerType
421 != FOURCC('h', 'i', 'n', 't');
422
423 if ((i < kNumDispatchers && kDispatchTable[i].mHandler == 0)
424 || isSampleEntryBox || ptype == FOURCC('i', 'l', 's', 't')) {
425 // This is a container box.
426 if (type == FOURCC('m', 'e', 't', 'a')) {
427 if ((err = need(offset + 4)) < OK) {
428 return err;
429 }
430
431 if (readU32(offset) != 0) {
432 return -EINVAL;
433 }
434
435 offset += 4;
436 } else if (type == FOURCC('s', 't', 's', 'd')) {
437 if ((err = need(offset + 8)) < OK) {
438 return err;
439 }
440
441 if (readU32(offset) != 0) {
442 return -EINVAL;
443 }
444
445 if (readU32(offset + 4) == 0) {
446 // We need at least some entries.
447 return -EINVAL;
448 }
449
450 offset += 8;
451 } else if (isSampleEntryBox) {
452 size_t headerSize;
453
454 switch (editTrack(mCurrentTrackID)->mMediaHandlerType) {
455 case FOURCC('v', 'i', 'd', 'e'):
456 {
457 // 8 bytes SampleEntry + 70 bytes VisualSampleEntry
458 headerSize = 78;
459 break;
460 }
461
462 case FOURCC('s', 'o', 'u', 'n'):
463 {
464 // 8 bytes SampleEntry + 20 bytes AudioSampleEntry
465 headerSize = 28;
466 break;
467 }
468
469 case FOURCC('m', 'e', 't', 'a'):
470 {
471 headerSize = 8; // 8 bytes SampleEntry
472 break;
473 }
474
475 default:
476 TRESPASS();
477 }
478
479 if (offset + headerSize > size) {
480 return -EINVAL;
481 }
482
483 if ((err = need(offset + headerSize)) != OK) {
484 return err;
485 }
486
487 switch (editTrack(mCurrentTrackID)->mMediaHandlerType) {
488 case FOURCC('v', 'i', 'd', 'e'):
489 {
490 err = parseVisualSampleEntry(
491 type, offset, offset + headerSize);
492 break;
493 }
494
495 case FOURCC('s', 'o', 'u', 'n'):
496 {
497 err = parseAudioSampleEntry(
498 type, offset, offset + headerSize);
499 break;
500 }
501
502 case FOURCC('m', 'e', 't', 'a'):
503 {
504 err = OK;
505 break;
506 }
507
508 default:
509 TRESPASS();
510 }
511
512 if (err != OK) {
513 return err;
514 }
515
516 offset += headerSize;
517 }
518
519 skip(offset);
520
521 ALOGV("%sentering box of type '%s'",
522 IndentString(mStack.size()), Fourcc2String(type));
523
524 enter(type, size - offset);
525 } else {
526 if (!fitsContainer(size)) {
527 return -EINVAL;
528 }
529
530 if (i < kNumDispatchers && kDispatchTable[i].mHandler != 0) {
531 // We have a handler for this box type.
532
533 if ((err = need(size)) != OK) {
534 return err;
535 }
536
537 ALOGV("%sparsing box of type '%s'",
538 IndentString(mStack.size()), Fourcc2String(type));
539
540 if ((err = (this->*kDispatchTable[i].mHandler)(
541 type, offset, size)) != OK) {
542 return err;
543 }
544 } else {
545 // Unknown box type
546
547 ALOGV("%sskipping box of type '%s', size %llu",
548 IndentString(mStack.size()),
549 Fourcc2String(type), size);
550
551 }
552
553 skip(size);
554 }
555
556 return OK;
557}
558
559// static
560int Parser::CompareSampleLocation(
561 const SampleInfo &sample, const MediaDataInfo &mdatInfo) {
562 if (sample.mOffset + sample.mSize < mdatInfo.mOffset) {
563 return -1;
564 }
565
566 if (sample.mOffset >= mdatInfo.mOffset + mdatInfo.mBuffer->size()) {
567 return 1;
568 }
569
570 // Otherwise make sure the sample is completely contained within this
571 // media data block.
572
573 CHECK_GE(sample.mOffset, mdatInfo.mOffset);
574
575 CHECK_LE(sample.mOffset + sample.mSize,
576 mdatInfo.mOffset + mdatInfo.mBuffer->size());
577
578 return 0;
579}
580
581void Parser::resumeIfNecessary() {
582 if (!mSuspended) {
583 return;
584 }
585
586 ALOGI("resuming.");
587
588 mSuspended = false;
589 (new AMessage(kWhatProceed, id()))->post();
590}
591
592status_t Parser::getSample(
593 TrackInfo *info, sp<TrackFragment> *fragment, SampleInfo *sampleInfo) {
594 for (;;) {
595 if (info->mFragments.empty()) {
596 resumeIfNecessary();
597 return -EWOULDBLOCK;
598 }
599
600 *fragment = *info->mFragments.begin();
601
602 status_t err = (*fragment)->getSample(sampleInfo);
603
604 if (err == OK) {
605 return OK;
606 } else if (err != ERROR_END_OF_STREAM) {
607 return err;
608 }
609
610 // Really, end of this fragment...
611
612 info->mFragments.erase(info->mFragments.begin());
613 }
614}
615
616status_t Parser::onDequeueAccessUnit(
617 size_t trackIndex, sp<ABuffer> *accessUnit) {
618 TrackInfo *info = &mTracks.editValueAt(trackIndex);
619
620 sp<TrackFragment> fragment;
621 SampleInfo sampleInfo;
622 status_t err = getSample(info, &fragment, &sampleInfo);
623
624 if (err == -EWOULDBLOCK) {
625 resumeIfNecessary();
626 return err;
627 } else if (err != OK) {
628 return err;
629 }
630
631 err = -EWOULDBLOCK;
632
633 bool checkDroppable = false;
634
635 for (size_t i = 0; i < mMediaData.size(); ++i) {
636 const MediaDataInfo &mdatInfo = mMediaData.itemAt(i);
637
638 int cmp = CompareSampleLocation(sampleInfo, mdatInfo);
639
640 if (cmp < 0) {
641 return -EPIPE;
642 } else if (cmp == 0) {
643 if (i > 0) {
644 checkDroppable = true;
645 }
646
647 err = makeAccessUnit(info, sampleInfo, mdatInfo, accessUnit);
648 break;
649 }
650 }
651
652 if (err != OK) {
653 return err;
654 }
655
656 fragment->advance();
657
658 if (!mMediaData.empty() && checkDroppable) {
659 size_t numDroppable = 0;
660 bool done = false;
661
662 for (size_t i = 0; !done && i < mMediaData.size(); ++i) {
663 const MediaDataInfo &mdatInfo = mMediaData.itemAt(i);
664
665 for (size_t j = 0; j < mTracks.size(); ++j) {
666 TrackInfo *info = &mTracks.editValueAt(j);
667
668 sp<TrackFragment> fragment;
669 SampleInfo sampleInfo;
670 err = getSample(info, &fragment, &sampleInfo);
671
672 if (err != OK) {
673 done = true;
674 break;
675 }
676
677 int cmp = CompareSampleLocation(sampleInfo, mdatInfo);
678
679 if (cmp <= 0) {
680 done = true;
681 break;
682 }
683 }
684
685 if (!done) {
686 ++numDroppable;
687 }
688 }
689
690 if (numDroppable > 0) {
691 mMediaData.removeItemsAt(0, numDroppable);
692
693 if (mMediaData.size() < 5) {
694 resumeIfNecessary();
695 }
696 }
697 }
698
699 return err;
700}
701
702static size_t parseNALSize(size_t nalLengthSize, const uint8_t *data) {
703 switch (nalLengthSize) {
704 case 1:
705 return *data;
706 case 2:
707 return U16_AT(data);
708 case 3:
709 return ((size_t)data[0] << 16) | U16_AT(&data[1]);
710 case 4:
711 return U32_AT(data);
712 }
713
714 // This cannot happen, mNALLengthSize springs to life by adding 1 to
715 // a 2-bit integer.
716 TRESPASS();
717
718 return 0;
719}
720
721status_t Parser::makeAccessUnit(
722 TrackInfo *info,
723 const SampleInfo &sample,
724 const MediaDataInfo &mdatInfo,
725 sp<ABuffer> *accessUnit) {
726 if (sample.mSampleDescIndex < 1
727 || sample.mSampleDescIndex > info->mSampleDescs.size()) {
728 return ERROR_MALFORMED;
729 }
730
731 int64_t presentationTimeUs =
732 1000000ll * sample.mPresentationTime / info->mMediaTimeScale;
733
734 const SampleDescription &sampleDesc =
735 info->mSampleDescs.itemAt(sample.mSampleDescIndex - 1);
736
737 size_t nalLengthSize;
738 if (!sampleDesc.mFormat->findSize("nal-length-size", &nalLengthSize)) {
739 *accessUnit = new ABuffer(sample.mSize);
740
741 memcpy((*accessUnit)->data(),
742 mdatInfo.mBuffer->data() + (sample.mOffset - mdatInfo.mOffset),
743 sample.mSize);
744
745 (*accessUnit)->meta()->setInt64("timeUs", presentationTimeUs);
746 return OK;
747 }
748
749 const uint8_t *srcPtr =
750 mdatInfo.mBuffer->data() + (sample.mOffset - mdatInfo.mOffset);
751
752 for (int i = 0; i < 2 ; ++i) {
753 size_t srcOffset = 0;
754 size_t dstOffset = 0;
755
756 while (srcOffset < sample.mSize) {
757 if (srcOffset + nalLengthSize > sample.mSize) {
758 return ERROR_MALFORMED;
759 }
760
761 size_t nalSize = parseNALSize(nalLengthSize, &srcPtr[srcOffset]);
762 srcOffset += nalLengthSize;
763
764 if (srcOffset + nalSize > sample.mSize) {
765 return ERROR_MALFORMED;
766 }
767
768 if (i == 1) {
769 memcpy((*accessUnit)->data() + dstOffset,
770 "\x00\x00\x00\x01",
771 4);
772
773 memcpy((*accessUnit)->data() + dstOffset + 4,
774 srcPtr + srcOffset,
775 nalSize);
776 }
777
778 srcOffset += nalSize;
779 dstOffset += nalSize + 4;
780 }
781
782 if (i == 0) {
783 (*accessUnit) = new ABuffer(dstOffset);
784 (*accessUnit)->meta()->setInt64(
785 "timeUs", presentationTimeUs);
786 }
787 }
788
789 return OK;
790}
791
792status_t Parser::need(size_t size) {
793 if (!fitsContainer(size)) {
794 return -EINVAL;
795 }
796
797 if (size <= mBuffer->size()) {
798 return OK;
799 }
800
801 sp<AMessage> msg = new AMessage(kWhatReadMore, id());
802 msg->setSize("needed", size - mBuffer->size());
803 msg->post();
804
805 // ALOGV("need(%d) returning -EAGAIN, only have %d", size, mBuffer->size());
806
807 return -EAGAIN;
808}
809
810void Parser::enter(uint32_t type, uint64_t size) {
811 Container container;
812 container.mType = type;
813 container.mExtendsToEOF = (size == 0);
814 container.mBytesRemaining = size;
815
816 mStack.push(container);
817}
818
819bool Parser::fitsContainer(uint64_t size) const {
820 CHECK(!mStack.isEmpty());
821 const Container &container = mStack.itemAt(mStack.size() - 1);
822
823 return container.mExtendsToEOF || size <= container.mBytesRemaining;
824}
825
826uint16_t Parser::readU16(size_t offset) {
827 CHECK_LE(offset + 2, mBuffer->size());
828
829 const uint8_t *ptr = mBuffer->data() + offset;
830 return (ptr[0] << 8) | ptr[1];
831}
832
833uint32_t Parser::readU32(size_t offset) {
834 CHECK_LE(offset + 4, mBuffer->size());
835
836 const uint8_t *ptr = mBuffer->data() + offset;
837 return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
838}
839
840uint64_t Parser::readU64(size_t offset) {
841 return (((uint64_t)readU32(offset)) << 32) | readU32(offset + 4);
842}
843
844void Parser::skip(off_t distance) {
845 CHECK(!mStack.isEmpty());
846 for (size_t i = mStack.size(); i-- > 0;) {
847 Container *container = &mStack.editItemAt(i);
848 if (!container->mExtendsToEOF) {
849 CHECK_LE(distance, (off_t)container->mBytesRemaining);
850
851 container->mBytesRemaining -= distance;
852
853 if (container->mBytesRemaining == 0) {
854 ALOGV("%sleaving box of type '%s'",
855 IndentString(mStack.size() - 1),
856 Fourcc2String(container->mType));
857
858#if 0
859 if (container->mType == FOURCC('s', 't', 's', 'd')) {
860 TrackInfo *trackInfo = editTrack(mCurrentTrackID);
861 for (size_t i = 0;
862 i < trackInfo->mSampleDescs.size(); ++i) {
863 ALOGI("format #%d: %s",
864 i,
865 trackInfo->mSampleDescs.itemAt(i)
866 .mFormat->debugString().c_str());
867 }
868 }
869#endif
870
871 if (container->mType == FOURCC('s', 't', 'b', 'l')) {
872 TrackInfo *trackInfo = editTrack(mCurrentTrackID);
873
874 trackInfo->mStaticFragment->signalCompletion();
875
876 CHECK(trackInfo->mFragments.empty());
877 trackInfo->mFragments.push_back(trackInfo->mStaticFragment);
878 trackInfo->mStaticFragment.clear();
879 } else if (container->mType == FOURCC('t', 'r', 'a', 'f')) {
880 TrackInfo *trackInfo =
881 editTrack(mTrackFragmentHeaderInfo.mTrackID);
882
883 const sp<TrackFragment> &fragment =
884 *--trackInfo->mFragments.end();
885
886 static_cast<DynamicTrackFragment *>(
887 fragment.get())->signalCompletion();
888 }
889
890 container = NULL;
891 mStack.removeItemsAt(i);
892 }
893 }
894 }
895
896 if (distance < (off_t)mBuffer->size()) {
897 mBuffer->setRange(mBuffer->offset() + distance, mBuffer->size() - distance);
898 mBufferPos += distance;
899 return;
900 }
901
902 mBuffer->setRange(0, 0);
903 mBufferPos += distance;
904}
905
906status_t Parser::parseTrackHeader(
907 uint32_t type, size_t offset, uint64_t size) {
908 if (offset + 4 > size) {
909 return -EINVAL;
910 }
911
912 uint32_t flags = readU32(offset);
913
914 uint32_t version = flags >> 24;
915 flags &= 0xffffff;
916
917 uint32_t trackID;
918 uint64_t duration;
919
920 if (version == 1) {
921 if (offset + 36 > size) {
922 return -EINVAL;
923 }
924
925 trackID = readU32(offset + 20);
926 duration = readU64(offset + 28);
927
928 offset += 36;
929 } else if (version == 0) {
930 if (offset + 24 > size) {
931 return -EINVAL;
932 }
933
934 trackID = readU32(offset + 12);
935 duration = readU32(offset + 20);
936
937 offset += 24;
938 } else {
939 return -EINVAL;
940 }
941
942 TrackInfo *info = editTrack(trackID, true /* createIfNecessary */);
943 info->mFlags = flags;
944 info->mDuration = duration;
945
946 info->mStaticFragment = new StaticTrackFragment;
947
948 mCurrentTrackID = trackID;
949
950 return OK;
951}
952
953status_t Parser::parseMediaHeader(
954 uint32_t type, size_t offset, uint64_t size) {
955 if (offset + 4 > size) {
956 return -EINVAL;
957 }
958
959 uint32_t versionAndFlags = readU32(offset);
960
961 if (versionAndFlags & 0xffffff) {
962 return ERROR_MALFORMED;
963 }
964
965 uint32_t version = versionAndFlags >> 24;
966
967 TrackInfo *info = editTrack(mCurrentTrackID);
968
969 if (version == 1) {
970 if (offset + 4 + 32 > size) {
971 return -EINVAL;
972 }
973 info->mMediaTimeScale = U32_AT(mBuffer->data() + offset + 20);
974 } else if (version == 0) {
975 if (offset + 4 + 20 > size) {
976 return -EINVAL;
977 }
978 info->mMediaTimeScale = U32_AT(mBuffer->data() + offset + 12);
979 } else {
980 return ERROR_MALFORMED;
981 }
982
983 return OK;
984}
985
986status_t Parser::parseMediaHandler(
987 uint32_t type, size_t offset, uint64_t size) {
988 if (offset + 12 > size) {
989 return -EINVAL;
990 }
991
992 if (readU32(offset) != 0) {
993 return -EINVAL;
994 }
995
996 uint32_t handlerType = readU32(offset + 8);
997
998 switch (handlerType) {
999 case FOURCC('v', 'i', 'd', 'e'):
1000 case FOURCC('s', 'o', 'u', 'n'):
1001 case FOURCC('h', 'i', 'n', 't'):
1002 case FOURCC('m', 'e', 't', 'a'):
1003 break;
1004
1005 default:
1006 return -EINVAL;
1007 }
1008
1009 editTrack(mCurrentTrackID)->mMediaHandlerType = handlerType;
1010
1011 return OK;
1012}
1013
1014status_t Parser::parseVisualSampleEntry(
1015 uint32_t type, size_t offset, uint64_t size) {
1016 if (offset + 78 > size) {
1017 return -EINVAL;
1018 }
1019
1020 TrackInfo *trackInfo = editTrack(mCurrentTrackID);
1021
1022 trackInfo->mSampleDescs.push();
1023 SampleDescription *sampleDesc =
1024 &trackInfo->mSampleDescs.editItemAt(
1025 trackInfo->mSampleDescs.size() - 1);
1026
1027 sampleDesc->mType = type;
1028 sampleDesc->mDataRefIndex = readU16(offset + 6);
1029
1030 sp<AMessage> format = new AMessage;
1031
1032 switch (type) {
1033 case FOURCC('a', 'v', 'c', '1'):
1034 format->setString("mime", MEDIA_MIMETYPE_VIDEO_AVC);
1035 break;
1036 case FOURCC('m', 'p', '4', 'v'):
1037 format->setString("mime", MEDIA_MIMETYPE_VIDEO_MPEG4);
1038 break;
Andreas Huberb9787142012-08-09 09:15:48 -07001039 case FOURCC('s', '2', '6', '3'):
1040 case FOURCC('h', '2', '6', '3'):
1041 case FOURCC('H', '2', '6', '3'):
1042 format->setString("mime", MEDIA_MIMETYPE_VIDEO_H263);
1043 break;
Andreas Huber84066782011-08-16 09:34:26 -07001044 default:
1045 format->setString("mime", "application/octet-stream");
1046 break;
1047 }
1048
1049 format->setInt32("width", readU16(offset + 8 + 16));
1050 format->setInt32("height", readU16(offset + 8 + 18));
1051
1052 sampleDesc->mFormat = format;
1053
1054 return OK;
1055}
1056
1057status_t Parser::parseAudioSampleEntry(
1058 uint32_t type, size_t offset, uint64_t size) {
1059 if (offset + 28 > size) {
1060 return -EINVAL;
1061 }
1062
1063 TrackInfo *trackInfo = editTrack(mCurrentTrackID);
1064
1065 trackInfo->mSampleDescs.push();
1066 SampleDescription *sampleDesc =
1067 &trackInfo->mSampleDescs.editItemAt(
1068 trackInfo->mSampleDescs.size() - 1);
1069
1070 sampleDesc->mType = type;
1071 sampleDesc->mDataRefIndex = readU16(offset + 6);
1072
1073 sp<AMessage> format = new AMessage;
1074
1075 format->setInt32("channel-count", readU16(offset + 8 + 8));
1076 format->setInt32("sample-size", readU16(offset + 8 + 10));
1077 format->setInt32("sample-rate", readU32(offset + 8 + 16) / 65536.0f);
1078
1079 switch (type) {
1080 case FOURCC('m', 'p', '4', 'a'):
1081 format->setString("mime", MEDIA_MIMETYPE_AUDIO_AAC);
1082 break;
Andreas Huberb9787142012-08-09 09:15:48 -07001083
Andreas Huber84066782011-08-16 09:34:26 -07001084 case FOURCC('s', 'a', 'm', 'r'):
1085 format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_NB);
1086 format->setInt32("channel-count", 1);
1087 format->setInt32("sample-rate", 8000);
1088 break;
Andreas Huberb9787142012-08-09 09:15:48 -07001089
Andreas Huber84066782011-08-16 09:34:26 -07001090 case FOURCC('s', 'a', 'w', 'b'):
1091 format->setString("mime", MEDIA_MIMETYPE_AUDIO_AMR_WB);
1092 format->setInt32("channel-count", 1);
1093 format->setInt32("sample-rate", 16000);
1094 break;
1095 default:
1096 format->setString("mime", "application/octet-stream");
1097 break;
1098 }
1099
1100 sampleDesc->mFormat = format;
1101
1102 return OK;
1103}
1104
1105static void addCodecSpecificData(
1106 const sp<AMessage> &format, int32_t index,
1107 const void *data, size_t size,
1108 bool insertStartCode = false) {
1109 sp<ABuffer> csd = new ABuffer(insertStartCode ? size + 4 : size);
1110
1111 memcpy(csd->data() + (insertStartCode ? 4 : 0), data, size);
1112
1113 if (insertStartCode) {
1114 memcpy(csd->data(), "\x00\x00\x00\x01", 4);
1115 }
1116
1117 csd->meta()->setInt32("csd", true);
1118 csd->meta()->setInt64("timeUs", 0ll);
1119
1120 format->setBuffer(StringPrintf("csd-%d", index).c_str(), csd);
1121}
1122
1123status_t Parser::parseSampleSizes(
1124 uint32_t type, size_t offset, uint64_t size) {
1125 return editTrack(mCurrentTrackID)->mStaticFragment->parseSampleSizes(
1126 this, type, offset, size);
1127}
1128
1129status_t Parser::parseCompactSampleSizes(
1130 uint32_t type, size_t offset, uint64_t size) {
1131 return editTrack(mCurrentTrackID)->mStaticFragment->parseCompactSampleSizes(
1132 this, type, offset, size);
1133}
1134
1135status_t Parser::parseSampleToChunk(
1136 uint32_t type, size_t offset, uint64_t size) {
1137 return editTrack(mCurrentTrackID)->mStaticFragment->parseSampleToChunk(
1138 this, type, offset, size);
1139}
1140
1141status_t Parser::parseChunkOffsets(
1142 uint32_t type, size_t offset, uint64_t size) {
1143 return editTrack(mCurrentTrackID)->mStaticFragment->parseChunkOffsets(
1144 this, type, offset, size);
1145}
1146
1147status_t Parser::parseChunkOffsets64(
1148 uint32_t type, size_t offset, uint64_t size) {
1149 return editTrack(mCurrentTrackID)->mStaticFragment->parseChunkOffsets64(
1150 this, type, offset, size);
1151}
1152
1153status_t Parser::parseAVCCodecSpecificData(
1154 uint32_t type, size_t offset, uint64_t size) {
1155 TrackInfo *trackInfo = editTrack(mCurrentTrackID);
1156
1157 SampleDescription *sampleDesc =
1158 &trackInfo->mSampleDescs.editItemAt(
1159 trackInfo->mSampleDescs.size() - 1);
1160
1161 if (sampleDesc->mType != FOURCC('a', 'v', 'c', '1')) {
1162 return -EINVAL;
1163 }
1164
1165 const uint8_t *ptr = mBuffer->data() + offset;
1166
1167 size -= offset;
1168 offset = 0;
1169
1170 if (size < 7 || ptr[0] != 0x01) {
1171 return ERROR_MALFORMED;
1172 }
1173
1174 sampleDesc->mFormat->setSize("nal-length-size", 1 + (ptr[4] & 3));
1175
1176 size_t numSPS = ptr[5] & 31;
1177
1178 ptr += 6;
1179 size -= 6;
1180
1181 for (size_t i = 0; i < numSPS; ++i) {
1182 if (size < 2) {
1183 return ERROR_MALFORMED;
1184 }
1185
1186 size_t length = U16_AT(ptr);
1187
1188 ptr += 2;
1189 size -= 2;
1190
1191 if (size < length) {
1192 return ERROR_MALFORMED;
1193 }
1194
1195 addCodecSpecificData(
1196 sampleDesc->mFormat, i, ptr, length,
1197 true /* insertStartCode */);
1198
1199 ptr += length;
1200 size -= length;
1201 }
1202
1203 if (size < 1) {
1204 return ERROR_MALFORMED;
1205 }
1206
1207 size_t numPPS = *ptr;
1208 ++ptr;
1209 --size;
1210
1211 for (size_t i = 0; i < numPPS; ++i) {
1212 if (size < 2) {
1213 return ERROR_MALFORMED;
1214 }
1215
1216 size_t length = U16_AT(ptr);
1217
1218 ptr += 2;
1219 size -= 2;
1220
1221 if (size < length) {
1222 return ERROR_MALFORMED;
1223 }
1224
1225 addCodecSpecificData(
1226 sampleDesc->mFormat, numSPS + i, ptr, length,
1227 true /* insertStartCode */);
1228
1229 ptr += length;
1230 size -= length;
1231 }
1232
1233 return OK;
1234}
1235
1236status_t Parser::parseESDSCodecSpecificData(
1237 uint32_t type, size_t offset, uint64_t size) {
1238 TrackInfo *trackInfo = editTrack(mCurrentTrackID);
1239
1240 SampleDescription *sampleDesc =
1241 &trackInfo->mSampleDescs.editItemAt(
1242 trackInfo->mSampleDescs.size() - 1);
1243
1244 if (sampleDesc->mType != FOURCC('m', 'p', '4', 'a')
1245 && sampleDesc->mType != FOURCC('m', 'p', '4', 'v')) {
1246 return -EINVAL;
1247 }
1248
1249 const uint8_t *ptr = mBuffer->data() + offset;
1250
1251 size -= offset;
1252 offset = 0;
1253
1254 if (size < 4) {
1255 return -EINVAL;
1256 }
1257
1258 if (U32_AT(ptr) != 0) {
1259 return -EINVAL;
1260 }
1261
1262 ptr += 4;
1263 size -=4;
1264
1265 ESDS esds(ptr, size);
1266
1267 uint8_t objectTypeIndication;
1268 if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
1269 return ERROR_MALFORMED;
1270 }
1271
1272 const uint8_t *csd;
1273 size_t csd_size;
1274 if (esds.getCodecSpecificInfo(
1275 (const void **)&csd, &csd_size) != OK) {
1276 return ERROR_MALFORMED;
1277 }
1278
1279 addCodecSpecificData(sampleDesc->mFormat, 0, csd, csd_size);
1280
1281 if (sampleDesc->mType != FOURCC('m', 'p', '4', 'a')) {
1282 return OK;
1283 }
1284
1285 if (csd_size == 0) {
1286 // There's no further information, i.e. no codec specific data
1287 // Let's assume that the information provided in the mpeg4 headers
1288 // is accurate and hope for the best.
1289
1290 return OK;
1291 }
1292
1293 if (csd_size < 2) {
1294 return ERROR_MALFORMED;
1295 }
1296
1297 uint32_t objectType = csd[0] >> 3;
1298
1299 if (objectType == 31) {
1300 return ERROR_UNSUPPORTED;
1301 }
1302
1303 uint32_t freqIndex = (csd[0] & 7) << 1 | (csd[1] >> 7);
1304 int32_t sampleRate = 0;
1305 int32_t numChannels = 0;
1306 if (freqIndex == 15) {
1307 if (csd_size < 5) {
1308 return ERROR_MALFORMED;
1309 }
1310
1311 sampleRate = (csd[1] & 0x7f) << 17
1312 | csd[2] << 9
1313 | csd[3] << 1
1314 | (csd[4] >> 7);
1315
1316 numChannels = (csd[4] >> 3) & 15;
1317 } else {
1318 static uint32_t kSamplingRate[] = {
1319 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
1320 16000, 12000, 11025, 8000, 7350
1321 };
1322
1323 if (freqIndex == 13 || freqIndex == 14) {
1324 return ERROR_MALFORMED;
1325 }
1326
1327 sampleRate = kSamplingRate[freqIndex];
1328 numChannels = (csd[1] >> 3) & 15;
1329 }
1330
1331 if (numChannels == 0) {
1332 return ERROR_UNSUPPORTED;
1333 }
1334
1335 sampleDesc->mFormat->setInt32("sample-rate", sampleRate);
1336 sampleDesc->mFormat->setInt32("channel-count", numChannels);
1337
1338 return OK;
1339}
1340
1341status_t Parser::parseMediaData(
1342 uint32_t type, size_t offset, uint64_t size) {
1343 ALOGV("skipping 'mdat' chunk at offsets 0x%08lx-0x%08llx.",
1344 mBufferPos + offset, mBufferPos + size);
1345
1346 sp<ABuffer> buffer = new ABuffer(size - offset);
1347 memcpy(buffer->data(), mBuffer->data() + offset, size - offset);
1348
1349 mMediaData.push();
1350 MediaDataInfo *info = &mMediaData.editItemAt(mMediaData.size() - 1);
1351 info->mBuffer = buffer;
1352 info->mOffset = mBufferPos + offset;
1353
1354 if (mMediaData.size() > 10) {
1355 ALOGI("suspending for now.");
1356 mSuspended = true;
1357 }
1358
1359 return OK;
1360}
1361
1362status_t Parser::parseTrackExtends(
1363 uint32_t type, size_t offset, uint64_t size) {
1364 if (offset + 24 > size) {
1365 return -EINVAL;
1366 }
1367
1368 if (readU32(offset) != 0) {
1369 return -EINVAL;
1370 }
1371
1372 uint32_t trackID = readU32(offset + 4);
1373
1374 TrackInfo *info = editTrack(trackID, true /* createIfNecessary */);
1375 info->mDefaultSampleDescriptionIndex = readU32(offset + 8);
1376 info->mDefaultSampleDuration = readU32(offset + 12);
1377 info->mDefaultSampleSize = readU32(offset + 16);
1378 info->mDefaultSampleFlags = readU32(offset + 20);
1379
1380 return OK;
1381}
1382
1383Parser::TrackInfo *Parser::editTrack(
1384 uint32_t trackID, bool createIfNecessary) {
1385 ssize_t i = mTracks.indexOfKey(trackID);
1386
1387 if (i >= 0) {
1388 return &mTracks.editValueAt(i);
1389 }
1390
1391 if (!createIfNecessary) {
1392 return NULL;
1393 }
1394
1395 TrackInfo info;
1396 info.mTrackID = trackID;
1397 info.mFlags = 0;
1398 info.mDuration = 0xffffffff;
1399 info.mMediaTimeScale = 0;
1400 info.mMediaHandlerType = 0;
1401 info.mDefaultSampleDescriptionIndex = 0;
1402 info.mDefaultSampleDuration = 0;
1403 info.mDefaultSampleSize = 0;
1404 info.mDefaultSampleFlags = 0;
1405
1406 info.mDecodingTime = 0;
1407
1408 mTracks.add(trackID, info);
1409 return &mTracks.editValueAt(mTracks.indexOfKey(trackID));
1410}
1411
1412status_t Parser::parseTrackFragmentHeader(
1413 uint32_t type, size_t offset, uint64_t size) {
1414 if (offset + 8 > size) {
1415 return -EINVAL;
1416 }
1417
1418 uint32_t flags = readU32(offset);
1419
1420 if (flags & 0xff000000) {
1421 return -EINVAL;
1422 }
1423
1424 mTrackFragmentHeaderInfo.mFlags = flags;
1425
1426 mTrackFragmentHeaderInfo.mTrackID = readU32(offset + 4);
1427 offset += 8;
1428
1429 if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) {
1430 if (offset + 8 > size) {
1431 return -EINVAL;
1432 }
1433
1434 mTrackFragmentHeaderInfo.mBaseDataOffset = readU64(offset);
1435 offset += 8;
1436 }
1437
1438 if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) {
1439 if (offset + 4 > size) {
1440 return -EINVAL;
1441 }
1442
1443 mTrackFragmentHeaderInfo.mSampleDescriptionIndex = readU32(offset);
1444 offset += 4;
1445 }
1446
1447 if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
1448 if (offset + 4 > size) {
1449 return -EINVAL;
1450 }
1451
1452 mTrackFragmentHeaderInfo.mDefaultSampleDuration = readU32(offset);
1453 offset += 4;
1454 }
1455
1456 if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
1457 if (offset + 4 > size) {
1458 return -EINVAL;
1459 }
1460
1461 mTrackFragmentHeaderInfo.mDefaultSampleSize = readU32(offset);
1462 offset += 4;
1463 }
1464
1465 if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
1466 if (offset + 4 > size) {
1467 return -EINVAL;
1468 }
1469
1470 mTrackFragmentHeaderInfo.mDefaultSampleFlags = readU32(offset);
1471 offset += 4;
1472 }
1473
1474 if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) {
1475 CHECK(!mStack.isEmpty());
1476
1477 // This should point to the start of the data inside the 'mdat' box
1478 // following the current 'moof' box.
1479
1480 mTrackFragmentHeaderInfo.mBaseDataOffset =
1481 mBufferPos + mStack.itemAt(mStack.size() - 1).mBytesRemaining + 8;
1482 }
1483
1484 mTrackFragmentHeaderInfo.mDataOffset =
1485 mTrackFragmentHeaderInfo.mBaseDataOffset;
1486
1487 TrackInfo *trackInfo = editTrack(mTrackFragmentHeaderInfo.mTrackID);
1488
1489 if (trackInfo->mFragments.empty()
1490 || (*trackInfo->mFragments.begin())->complete()) {
1491 trackInfo->mFragments.push_back(new DynamicTrackFragment);
1492 }
1493
1494 return OK;
1495}
1496
1497status_t Parser::parseTrackFragmentRun(
1498 uint32_t type, size_t offset, uint64_t size) {
1499 if (offset + 8 > size) {
1500 return -EINVAL;
1501 }
1502
1503 enum {
1504 kDataOffsetPresent = 0x01,
1505 kFirstSampleFlagsPresent = 0x04,
1506 kSampleDurationPresent = 0x100,
1507 kSampleSizePresent = 0x200,
1508 kSampleFlagsPresent = 0x400,
1509 kSampleCompositionTimeOffsetPresent = 0x800,
1510 };
1511
1512 uint32_t flags = readU32(offset);
1513
1514 if (flags & 0xff000000) {
1515 return -EINVAL;
1516 }
1517
1518 if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) {
1519 // These two shall not be used together.
1520 return -EINVAL;
1521 }
1522
1523 uint32_t sampleCount = readU32(offset + 4);
1524 offset += 8;
1525
1526 uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset;
1527
1528 uint32_t firstSampleFlags = 0;
1529
1530 if (flags & kDataOffsetPresent) {
1531 if (offset + 4 > size) {
1532 return -EINVAL;
1533 }
1534
1535 int32_t dataOffsetDelta = (int32_t)readU32(offset);
1536
1537 dataOffset = mTrackFragmentHeaderInfo.mBaseDataOffset + dataOffsetDelta;
1538
1539 offset += 4;
1540 }
1541
1542 if (flags & kFirstSampleFlagsPresent) {
1543 if (offset + 4 > size) {
1544 return -EINVAL;
1545 }
1546
1547 firstSampleFlags = readU32(offset);
1548 offset += 4;
1549 }
1550
1551 TrackInfo *info = editTrack(mTrackFragmentHeaderInfo.mTrackID);
1552
1553 if (info == NULL) {
1554 return -EINVAL;
1555 }
1556
1557 uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0,
1558 sampleCtsOffset = 0;
1559
1560 size_t bytesPerSample = 0;
1561 if (flags & kSampleDurationPresent) {
1562 bytesPerSample += 4;
1563 } else if (mTrackFragmentHeaderInfo.mFlags
1564 & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
1565 sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration;
1566 } else {
1567 sampleDuration = info->mDefaultSampleDuration;
1568 }
1569
1570 if (flags & kSampleSizePresent) {
1571 bytesPerSample += 4;
1572 } else if (mTrackFragmentHeaderInfo.mFlags
1573 & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
1574 sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
1575 } else {
1576 sampleSize = info->mDefaultSampleSize;
1577 }
1578
1579 if (flags & kSampleFlagsPresent) {
1580 bytesPerSample += 4;
1581 } else if (mTrackFragmentHeaderInfo.mFlags
1582 & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
1583 sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
1584 } else {
1585 sampleFlags = info->mDefaultSampleFlags;
1586 }
1587
1588 if (flags & kSampleCompositionTimeOffsetPresent) {
1589 bytesPerSample += 4;
1590 } else {
1591 sampleCtsOffset = 0;
1592 }
1593
1594 if (offset + sampleCount * bytesPerSample > size) {
1595 return -EINVAL;
1596 }
1597
1598 uint32_t sampleDescIndex =
1599 (mTrackFragmentHeaderInfo.mFlags
1600 & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent)
1601 ? mTrackFragmentHeaderInfo.mSampleDescriptionIndex
1602 : info->mDefaultSampleDescriptionIndex;
1603
1604 for (uint32_t i = 0; i < sampleCount; ++i) {
1605 if (flags & kSampleDurationPresent) {
1606 sampleDuration = readU32(offset);
1607 offset += 4;
1608 }
1609
1610 if (flags & kSampleSizePresent) {
1611 sampleSize = readU32(offset);
1612 offset += 4;
1613 }
1614
1615 if (flags & kSampleFlagsPresent) {
1616 sampleFlags = readU32(offset);
1617 offset += 4;
1618 }
1619
1620 if (flags & kSampleCompositionTimeOffsetPresent) {
1621 sampleCtsOffset = readU32(offset);
1622 offset += 4;
1623 }
1624
1625 ALOGV("adding sample at offset 0x%08llx, size %u, duration %u, "
1626 "sampleDescIndex=%u, flags 0x%08x",
1627 dataOffset, sampleSize, sampleDuration,
1628 sampleDescIndex,
1629 (flags & kFirstSampleFlagsPresent) && i == 0
1630 ? firstSampleFlags : sampleFlags);
1631
1632 const sp<TrackFragment> &fragment = *--info->mFragments.end();
1633
1634 uint32_t decodingTime = info->mDecodingTime;
1635 info->mDecodingTime += sampleDuration;
1636 uint32_t presentationTime = decodingTime + sampleCtsOffset;
1637
1638 static_cast<DynamicTrackFragment *>(
1639 fragment.get())->addSample(
1640 dataOffset,
1641 sampleSize,
1642 presentationTime,
1643 sampleDescIndex,
1644 ((flags & kFirstSampleFlagsPresent) && i == 0)
1645 ? firstSampleFlags : sampleFlags);
1646
1647 dataOffset += sampleSize;
1648 }
1649
1650 mTrackFragmentHeaderInfo.mDataOffset = dataOffset;
1651
1652 return OK;
1653}
1654
1655void Parser::copyBuffer(
1656 sp<ABuffer> *dst, size_t offset, uint64_t size, size_t extra) const {
1657 sp<ABuffer> buf = new ABuffer(size + extra);
1658 memcpy(buf->data(), mBuffer->data() + offset, size);
1659
1660 *dst = buf;
1661}
1662
1663} // namespace android