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