1 /*
2 * Copyright (C) 2009 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 "MPEG4Extractor"
19
20 #include <ctype.h>
21 #include <inttypes.h>
22 #include <algorithm>
23 #include <map>
24 #include <memory>
25 #include <stdint.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include <utils/Log.h>
30
31 #include "AC4Parser.h"
32 #include "MPEG4Extractor.h"
33 #include "SampleTable.h"
34 #include "ItemTable.h"
35
36 #include <com_android_media_extractor_flags.h>
37 #include <media/esds/ESDS.h>
38 #include <ID3.h>
39 #include <media/stagefright/DataSourceBase.h>
40 #include <media/ExtractorUtils.h>
41 #include <media/stagefright/foundation/ABitReader.h>
42 #include <media/stagefright/foundation/ABuffer.h>
43 #include <media/stagefright/foundation/ADebug.h>
44 #include <media/stagefright/foundation/AMessage.h>
45 #include <media/stagefright/foundation/AudioPresentationInfo.h>
46 #include <media/stagefright/foundation/AUtils.h>
47 #include <media/stagefright/foundation/ByteUtils.h>
48 #include <media/stagefright/foundation/ColorUtils.h>
49 #include <media/stagefright/foundation/avc_utils.h>
50 #include <media/stagefright/foundation/hexdump.h>
51 #include <media/stagefright/foundation/OpusHeader.h>
52 #include <media/stagefright/MediaBufferGroup.h>
53 #include <media/stagefright/MediaDefs.h>
54 #include <media/stagefright/MetaDataBase.h>
55 #include <media/stagefright/MetaDataUtils.h>
56 #include <utils/String8.h>
57
58 #include <byteswap.h>
59
60 #ifndef UINT32_MAX
61 #define UINT32_MAX (4294967295U)
62 #endif
63
64 #define ALAC_SPECIFIC_INFO_SIZE (36)
65
66 // TODO : Remove the defines once mainline media is built against NDK >= 31.
67 // The mp4 extractor is part of mainline and builds against NDK 29 as of
68 // writing. These keys are available only from NDK 31:
69 #define AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION \
70 "mpegh-profile-level-indication"
71 #define AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT \
72 "mpegh-reference-channel-layout"
73 #define AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS \
74 "mpegh-compatible-sets"
75
76 namespace android {
77
78 enum {
79 // max track header chunk to return
80 kMaxTrackHeaderSize = 32,
81
82 // maximum size of an atom. Some atoms can be bigger according to the spec,
83 // but we only allow up to this size.
84 kMaxAtomSize = 64 * 1024 * 1024,
85 };
86
87 class MPEG4Source : public MediaTrackHelper {
88 static const size_t kMaxPcmFrameSize = 8192;
89 public:
90 // Caller retains ownership of both "dataSource" and "sampleTable".
91 MPEG4Source(AMediaFormat *format,
92 DataSourceHelper *dataSource,
93 int32_t timeScale,
94 const sp<SampleTable> &sampleTable,
95 Vector<SidxEntry> &sidx,
96 const Trex *trex,
97 off64_t firstMoofOffset,
98 const sp<ItemTable> &itemTable,
99 uint64_t elstShiftStartTicks,
100 uint64_t elstInitialEmptyEditTicks);
101 virtual status_t init();
102
103 virtual media_status_t start();
104 virtual media_status_t stop();
105
106 virtual media_status_t getFormat(AMediaFormat *);
107
108 virtual media_status_t read(MediaBufferHelper **buffer, const ReadOptions *options = NULL);
supportsNonBlockingRead()109 bool supportsNonBlockingRead() override { return true; }
110 virtual media_status_t fragmentedRead(
111 MediaBufferHelper **buffer, const ReadOptions *options = NULL);
112
113 virtual ~MPEG4Source();
114
115 private:
116 Mutex mLock;
117
118 AMediaFormat *mFormat;
119 DataSourceHelper *mDataSource;
120 int32_t mTimescale;
121 sp<SampleTable> mSampleTable;
122 uint32_t mCurrentSampleIndex;
123 uint32_t mCurrentFragmentIndex;
124 Vector<SidxEntry> &mSegments;
125 const Trex *mTrex;
126 off64_t mFirstMoofOffset;
127 off64_t mCurrentMoofOffset;
128 off64_t mCurrentMoofSize;
129 off64_t mNextMoofOffset;
130 uint32_t mCurrentTime; // in media timescale ticks
131 int32_t mLastParsedTrackId;
132 int32_t mTrackId;
133
134 int32_t mCryptoMode; // passed in from extractor
135 int32_t mDefaultIVSize; // passed in from extractor
136 uint8_t mCryptoKey[16]; // passed in from extractor
137 int32_t mDefaultEncryptedByteBlock;
138 int32_t mDefaultSkipByteBlock;
139 uint32_t mCurrentAuxInfoType;
140 uint32_t mCurrentAuxInfoTypeParameter;
141 int32_t mCurrentDefaultSampleInfoSize;
142 uint32_t mCurrentSampleInfoCount;
143 uint32_t mCurrentSampleInfoAllocSize;
144 uint8_t* mCurrentSampleInfoSizes;
145 uint32_t mCurrentSampleInfoOffsetCount;
146 uint32_t mCurrentSampleInfoOffsetsAllocSize;
147 uint64_t* mCurrentSampleInfoOffsets;
148
149 bool mIsAVC;
150 bool mIsHEVC;
151 bool mIsAPV;
152 bool mIsDolbyVision;
153 bool mIsAC4;
154 bool mIsMpegH = false;
155 bool mIsPcm;
156 size_t mNALLengthSize;
157
158 bool mStarted;
159
160 MediaBufferHelper *mBuffer;
161
162 size_t mSrcBufferSize;
163 uint8_t *mSrcBuffer;
164
165 bool mIsHeif;
166 bool mIsAvif;
167 bool mIsAudio;
168 bool mIsUsac = false;
169 sp<ItemTable> mItemTable;
170
171 /* Shift start offset (move to earlier time) when media_time > 0,
172 * in media time scale.
173 */
174 uint64_t mElstShiftStartTicks;
175 /* Initial start offset (move to later time), empty edit list entry
176 * in media time scale.
177 */
178 uint64_t mElstInitialEmptyEditTicks;
179
180 size_t parseNALSize(const uint8_t *data) const;
181 status_t parseChunk(off64_t *offset);
182 status_t parseTrackFragmentHeader(off64_t offset, off64_t size);
183 status_t parseTrackFragmentRun(off64_t offset, off64_t size);
184 status_t parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size);
185 status_t parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size);
186 status_t parseClearEncryptedSizes(off64_t offset, bool isSampleEncryption,
187 uint32_t flags, off64_t size);
188 status_t parseSampleEncryption(off64_t offset, off64_t size);
189 // returns -1 for invalid layer ID
190 int32_t parseHEVCLayerId(const uint8_t *data, size_t size);
191 size_t getNALLengthSizeFromAvcCsd(const uint8_t *data, const size_t size) const;
192 size_t getNALLengthSizeFromHevcCsd(const uint8_t *data, const size_t size) const;
193
194 struct TrackFragmentHeaderInfo {
195 enum Flags {
196 kBaseDataOffsetPresent = 0x01,
197 kSampleDescriptionIndexPresent = 0x02,
198 kDefaultSampleDurationPresent = 0x08,
199 kDefaultSampleSizePresent = 0x10,
200 kDefaultSampleFlagsPresent = 0x20,
201 kDurationIsEmpty = 0x10000,
202 };
203
204 uint32_t mTrackID;
205 uint32_t mFlags;
206 uint64_t mBaseDataOffset;
207 uint32_t mSampleDescriptionIndex;
208 uint32_t mDefaultSampleDuration;
209 uint32_t mDefaultSampleSize;
210 uint32_t mDefaultSampleFlags;
211
212 uint64_t mDataOffset;
213 };
214 TrackFragmentHeaderInfo mTrackFragmentHeaderInfo;
215
216 struct Sample {
217 off64_t offset;
218 size_t size;
219 uint32_t duration;
220 int32_t compositionOffset;
221 uint8_t iv[16];
222 Vector<uint32_t> clearsizes;
223 Vector<uint32_t> encryptedsizes;
224 };
225 Vector<Sample> mCurrentSamples;
226 std::map<off64_t, uint32_t> mDrmOffsets;
227
228 MPEG4Source(const MPEG4Source &);
229 MPEG4Source &operator=(const MPEG4Source &);
230 };
231
232 // This custom data source wraps an existing one and satisfies requests
233 // falling entirely within a cached range from the cache while forwarding
234 // all remaining requests to the wrapped datasource.
235 // This is used to cache the full sampletable metadata for a single track,
236 // possibly wrapping multiple times to cover all tracks, i.e.
237 // Each CachedRangedDataSource caches the sampletable metadata for a single track.
238
239 class CachedRangedDataSource : public DataSourceHelper {
240 public:
241 explicit CachedRangedDataSource(DataSourceHelper *source);
242 virtual ~CachedRangedDataSource();
243
244 ssize_t readAt(off64_t offset, void *data, size_t size) override;
245 status_t getSize(off64_t *size) override;
246 uint32_t flags() override;
247
248 status_t setCachedRange(off64_t offset, size_t size, bool assumeSourceOwnershipOnSuccess);
249
250
251 private:
252 Mutex mLock;
253
254 DataSourceHelper *mSource;
255 bool mOwnsDataSource;
256 off64_t mCachedOffset;
257 size_t mCachedSize;
258 uint8_t *mCache;
259
260 void clearCache();
261
262 CachedRangedDataSource(const CachedRangedDataSource &);
263 CachedRangedDataSource &operator=(const CachedRangedDataSource &);
264 };
265
CachedRangedDataSource(DataSourceHelper * source)266 CachedRangedDataSource::CachedRangedDataSource(DataSourceHelper *source)
267 : DataSourceHelper(source),
268 mSource(source),
269 mOwnsDataSource(false),
270 mCachedOffset(0),
271 mCachedSize(0),
272 mCache(NULL) {
273 }
274
~CachedRangedDataSource()275 CachedRangedDataSource::~CachedRangedDataSource() {
276 clearCache();
277 if (mOwnsDataSource) {
278 delete mSource;
279 }
280 }
281
clearCache()282 void CachedRangedDataSource::clearCache() {
283 if (mCache) {
284 free(mCache);
285 mCache = NULL;
286 }
287
288 mCachedOffset = 0;
289 mCachedSize = 0;
290 }
291
readAt(off64_t offset,void * data,size_t size)292 ssize_t CachedRangedDataSource::readAt(off64_t offset, void *data, size_t size) {
293 Mutex::Autolock autoLock(mLock);
294
295 if (isInRange(mCachedOffset, mCachedSize, offset, size)) {
296 memcpy(data, &mCache[offset - mCachedOffset], size);
297 return size;
298 }
299
300 return mSource->readAt(offset, data, size);
301 }
302
getSize(off64_t * size)303 status_t CachedRangedDataSource::getSize(off64_t *size) {
304 return mSource->getSize(size);
305 }
306
flags()307 uint32_t CachedRangedDataSource::flags() {
308 return mSource->flags();
309 }
310
setCachedRange(off64_t offset,size_t size,bool assumeSourceOwnershipOnSuccess)311 status_t CachedRangedDataSource::setCachedRange(off64_t offset,
312 size_t size,
313 bool assumeSourceOwnershipOnSuccess) {
314 Mutex::Autolock autoLock(mLock);
315
316 clearCache();
317
318 mCache = (uint8_t *)malloc(size);
319
320 if (mCache == NULL) {
321 return -ENOMEM;
322 }
323
324 mCachedOffset = offset;
325 mCachedSize = size;
326
327 ssize_t err = mSource->readAt(mCachedOffset, mCache, mCachedSize);
328
329 if (err < (ssize_t)size) {
330 clearCache();
331
332 return ERROR_IO;
333 }
334 mOwnsDataSource = assumeSourceOwnershipOnSuccess;
335 return OK;
336 }
337
338 ////////////////////////////////////////////////////////////////////////////////
339
340 static const bool kUseHexDump = false;
341
FourCC2MIME(uint32_t fourcc)342 static const char *FourCC2MIME(uint32_t fourcc) {
343 switch (fourcc) {
344 case FOURCC("mp4a"):
345 return MEDIA_MIMETYPE_AUDIO_AAC;
346
347 case FOURCC("samr"):
348 return MEDIA_MIMETYPE_AUDIO_AMR_NB;
349
350 case FOURCC("sawb"):
351 return MEDIA_MIMETYPE_AUDIO_AMR_WB;
352
353 case FOURCC("ec-3"):
354 return MEDIA_MIMETYPE_AUDIO_EAC3;
355
356 case FOURCC("mp4v"):
357 return MEDIA_MIMETYPE_VIDEO_MPEG4;
358
359 case FOURCC("s263"):
360 case FOURCC("h263"):
361 case FOURCC("H263"):
362 return MEDIA_MIMETYPE_VIDEO_H263;
363
364 case FOURCC("avc1"):
365 return MEDIA_MIMETYPE_VIDEO_AVC;
366
367 case FOURCC("hvc1"):
368 case FOURCC("hev1"):
369 return MEDIA_MIMETYPE_VIDEO_HEVC;
370
371 case FOURCC("apv1"):
372 if (!com::android::media::extractor::flags::extractor_mp4_enable_apv()) {
373 ALOGV("APV support not enabled");
374 return "application/octet-stream";
375 }
376 return MEDIA_MIMETYPE_VIDEO_APV;
377
378 case FOURCC("dvav"):
379 case FOURCC("dva1"):
380 case FOURCC("dvhe"):
381 case FOURCC("dvh1"):
382 case FOURCC("dav1"):
383 return MEDIA_MIMETYPE_VIDEO_DOLBY_VISION;
384
385 case FOURCC("ac-4"):
386 return MEDIA_MIMETYPE_AUDIO_AC4;
387 case FOURCC("Opus"):
388 return MEDIA_MIMETYPE_AUDIO_OPUS;
389
390 case FOURCC("twos"):
391 case FOURCC("sowt"):
392 return MEDIA_MIMETYPE_AUDIO_RAW;
393 case FOURCC("alac"):
394 return MEDIA_MIMETYPE_AUDIO_ALAC;
395 case FOURCC("fLaC"):
396 return MEDIA_MIMETYPE_AUDIO_FLAC;
397 case FOURCC("av01"):
398 return MEDIA_MIMETYPE_VIDEO_AV1;
399 case FOURCC("vp09"):
400 return MEDIA_MIMETYPE_VIDEO_VP9;
401 case FOURCC(".mp3"):
402 case 0x6D730055: // "ms U" mp3 audio
403 return MEDIA_MIMETYPE_AUDIO_MPEG;
404 case FOURCC("mha1"):
405 return MEDIA_MIMETYPE_AUDIO_MPEGH_MHA1;
406 case FOURCC("mhm1"):
407 return MEDIA_MIMETYPE_AUDIO_MPEGH_MHM1;
408 case FOURCC("dtsc"):
409 return MEDIA_MIMETYPE_AUDIO_DTS;
410 case FOURCC("dtse"):
411 case FOURCC("dtsh"):
412 return MEDIA_MIMETYPE_AUDIO_DTS_HD;
413 case FOURCC("dtsl"):
414 return MEDIA_MIMETYPE_AUDIO_DTS_HD_MA;
415 case FOURCC("dtsx"):
416 return MEDIA_MIMETYPE_AUDIO_DTS_UHD_P2;
417 default:
418 ALOGW("Unknown fourcc: %c%c%c%c",
419 (fourcc >> 24) & 0xff,
420 (fourcc >> 16) & 0xff,
421 (fourcc >> 8) & 0xff,
422 fourcc & 0xff
423 );
424 return "application/octet-stream";
425 }
426 }
427
AdjustChannelsAndRate(uint32_t fourcc,uint32_t * channels,uint32_t * rate)428 static bool AdjustChannelsAndRate(uint32_t fourcc, uint32_t *channels, uint32_t *rate) {
429 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, FourCC2MIME(fourcc))) {
430 // AMR NB audio is always mono, 8kHz
431 *channels = 1;
432 *rate = 8000;
433 return true;
434 } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, FourCC2MIME(fourcc))) {
435 // AMR WB audio is always mono, 16kHz
436 *channels = 1;
437 *rate = 16000;
438 return true;
439 }
440 return false;
441 }
442
MPEG4Extractor(DataSourceHelper * source,const char * mime)443 MPEG4Extractor::MPEG4Extractor(DataSourceHelper *source, const char *mime)
444 : mMoofOffset(0),
445 mMoofFound(false),
446 mMdatFound(false),
447 mDataSource(source),
448 mInitCheck(NO_INIT),
449 mHeaderTimescale(0),
450 mIsQT(false),
451 mIsHeif(false),
452 mHasMoovBox(false),
453 mPreferHeif(mime != NULL && !strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_HEIF)),
454 mIsAvif(false),
455 mFirstTrack(NULL),
456 mLastTrack(NULL) {
457 ALOGV("mime=%s, mPreferHeif=%d", mime, mPreferHeif);
458 mFileMetaData = AMediaFormat_new();
459 }
460
~MPEG4Extractor()461 MPEG4Extractor::~MPEG4Extractor() {
462 Track *track = mFirstTrack;
463 while (track) {
464 Track *next = track->next;
465
466 delete track;
467 track = next;
468 }
469 mFirstTrack = mLastTrack = NULL;
470
471 for (size_t i = 0; i < mPssh.size(); i++) {
472 delete [] mPssh[i].data;
473 }
474 mPssh.clear();
475
476 delete mDataSource;
477 AMediaFormat_delete(mFileMetaData);
478 }
479
flags() const480 uint32_t MPEG4Extractor::flags() const {
481 return CAN_PAUSE |
482 ((mMoofOffset == 0 || mSidxEntries.size() != 0) ?
483 (CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK) : 0);
484 }
485
getMetaData(AMediaFormat * meta)486 media_status_t MPEG4Extractor::getMetaData(AMediaFormat *meta) {
487 status_t err;
488 if ((err = readMetaData()) != OK) {
489 return AMEDIA_ERROR_UNKNOWN;
490 }
491 AMediaFormat_copy(meta, mFileMetaData);
492 return AMEDIA_OK;
493 }
494
countTracks()495 size_t MPEG4Extractor::countTracks() {
496 status_t err;
497 if ((err = readMetaData()) != OK) {
498 ALOGV("MPEG4Extractor::countTracks: no tracks");
499 return 0;
500 }
501
502 size_t n = 0;
503 Track *track = mFirstTrack;
504 while (track) {
505 ++n;
506 track = track->next;
507 }
508
509 ALOGV("MPEG4Extractor::countTracks: %zu tracks", n);
510 return n;
511 }
512
getTrackMetaData(AMediaFormat * meta,size_t index,uint32_t flags)513 media_status_t MPEG4Extractor::getTrackMetaData(
514 AMediaFormat *meta,
515 size_t index, uint32_t flags) {
516 status_t err;
517 if ((err = readMetaData()) != OK) {
518 return AMEDIA_ERROR_UNKNOWN;
519 }
520
521 Track *track = mFirstTrack;
522 while (index > 0) {
523 if (track == NULL) {
524 return AMEDIA_ERROR_UNKNOWN;
525 }
526
527 track = track->next;
528 --index;
529 }
530
531 if (track == NULL) {
532 return AMEDIA_ERROR_UNKNOWN;
533 }
534
535 [this, &track] {
536 int64_t duration = track->mMdhdDurationUs;
537 int32_t samplerate;
538 // Only for audio track.
539 if (track->elst_needs_processing && mHeaderTimescale != 0 && duration != 0 &&
540 AMediaFormat_getInt32(track->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, &samplerate)) {
541 // Elst has to be processed only the first time this function is called.
542 track->elst_needs_processing = false;
543
544 if (track->elst_segment_duration > INT64_MAX) {
545 return;
546 }
547 int64_t segment_duration = track->elst_segment_duration;
548 int64_t media_time = track->elst_media_time;
549 int64_t halfscale = track->timescale / 2;
550
551 ALOGV("segment_duration = %" PRId64 ", media_time = %" PRId64
552 ", halfscale = %" PRId64 ", mdhd_timescale = %d, track_timescale = %u",
553 segment_duration, media_time,
554 halfscale, mHeaderTimescale, track->timescale);
555
556 if ((uint32_t)samplerate != track->timescale){
557 ALOGV("samplerate:%" PRId32 ", track->timescale and samplerate are different!",
558 samplerate);
559 }
560 // Both delay and paddingsamples have to be set inorder for either to be
561 // effective in the lower layers.
562 int64_t delay = 0;
563 if (media_time > 0) { // Gapless playback
564 // delay = ((media_time * samplerate) + halfscale) / track->timescale;
565 if (__builtin_mul_overflow(media_time, samplerate, &delay) ||
566 __builtin_add_overflow(delay, halfscale, &delay) ||
567 (delay /= track->timescale, false) ||
568 delay > INT32_MAX ||
569 delay < INT32_MIN) {
570 ALOGW("ignoring edit list with bogus values");
571 return;
572 }
573 }
574 ALOGV("delay = %" PRId64, delay);
575 AMediaFormat_setInt32(track->meta, AMEDIAFORMAT_KEY_ENCODER_DELAY, delay);
576
577 int64_t paddingsamples = 0;
578 if (segment_duration > 0) {
579 int64_t scaled_duration;
580 // scaled_duration = duration * mHeaderTimescale;
581 if (__builtin_mul_overflow(duration, mHeaderTimescale, &scaled_duration)) {
582 return;
583 }
584 ALOGV("scaled_duration = %" PRId64, scaled_duration);
585
586 int64_t segment_end;
587 int64_t padding;
588 int64_t segment_duration_e6;
589 int64_t media_time_scaled_e6;
590 int64_t media_time_scaled;
591 // padding = scaled_duration - ((segment_duration * 1000000) +
592 // ((media_time * mHeaderTimescale * 1000000)/track->timescale) )
593 // segment_duration is based on timescale in movie header box(mdhd)
594 // media_time is based on timescale track header/media timescale
595 if (__builtin_mul_overflow(segment_duration, 1000000, &segment_duration_e6) ||
596 __builtin_mul_overflow(media_time, mHeaderTimescale, &media_time_scaled) ||
597 __builtin_mul_overflow(media_time_scaled, 1000000, &media_time_scaled_e6)) {
598 return;
599 }
600 media_time_scaled_e6 /= track->timescale;
601 if (__builtin_add_overflow(segment_duration_e6, media_time_scaled_e6, &segment_end)
602 || __builtin_sub_overflow(scaled_duration, segment_end, &padding)) {
603 return;
604 }
605 ALOGV("segment_end = %" PRId64 ", padding = %" PRId64, segment_end, padding);
606 // track duration from media header (which is what AMEDIAFORMAT_KEY_DURATION is)
607 // might be slightly shorter than the segment duration, which would make the
608 // padding negative. Clamp to zero.
609 if (padding > 0) {
610 int64_t halfscale_mht = mHeaderTimescale / 2;
611 int64_t halfscale_e6;
612 int64_t timescale_e6;
613 // paddingsamples = ((padding * samplerate) + (halfscale_mht * 1000000))
614 // / (mHeaderTimescale * 1000000);
615 if (__builtin_mul_overflow(padding, samplerate, &paddingsamples) ||
616 __builtin_mul_overflow(halfscale_mht, 1000000, &halfscale_e6) ||
617 __builtin_mul_overflow(mHeaderTimescale, 1000000, ×cale_e6) ||
618 __builtin_add_overflow(paddingsamples, halfscale_e6, &paddingsamples) ||
619 (paddingsamples /= timescale_e6, false) ||
620 paddingsamples > INT32_MAX) {
621 return;
622 }
623 }
624 }
625 ALOGV("paddingsamples = %" PRId64, paddingsamples);
626 AMediaFormat_setInt32(track->meta, AMEDIAFORMAT_KEY_ENCODER_PADDING, paddingsamples);
627 }
628 }();
629
630 if ((flags & kIncludeExtensiveMetaData)
631 && !track->includes_expensive_metadata) {
632 track->includes_expensive_metadata = true;
633
634 const char *mime;
635 CHECK(AMediaFormat_getString(track->meta, AMEDIAFORMAT_KEY_MIME, &mime));
636 if (!strncasecmp("video/", mime, 6)) {
637 // MPEG2 tracks do not provide CSD, so read the stream header
638 if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)) {
639 off64_t offset;
640 size_t size;
641 if (track->sampleTable->getMetaDataForSample(
642 0 /* sampleIndex */, &offset, &size, NULL /* sampleTime */) == OK) {
643 if (size > kMaxTrackHeaderSize) {
644 size = kMaxTrackHeaderSize;
645 }
646 uint8_t header[kMaxTrackHeaderSize];
647 if (mDataSource->readAt(offset, &header, size) == (ssize_t)size) {
648 AMediaFormat_setBuffer(track->meta,
649 AMEDIAFORMAT_KEY_MPEG2_STREAM_HEADER, header, size);
650 }
651 }
652 }
653
654 if (mMoofOffset > 0) {
655 int64_t duration;
656 if (AMediaFormat_getInt64(track->meta,
657 AMEDIAFORMAT_KEY_DURATION, &duration)) {
658 // nothing fancy, just pick a frame near 1/4th of the duration
659 AMediaFormat_setInt64(track->meta,
660 AMEDIAFORMAT_KEY_THUMBNAIL_TIME, duration / 4);
661 }
662 } else {
663 uint32_t sampleIndex;
664 uint64_t sampleTime;
665 if (track->timescale != 0 &&
666 track->sampleTable->findThumbnailSample(&sampleIndex) == OK
667 && track->sampleTable->getMetaDataForSample(
668 sampleIndex, NULL /* offset */, NULL /* size */,
669 &sampleTime) == OK) {
670 AMediaFormat_setInt64(track->meta,
671 AMEDIAFORMAT_KEY_THUMBNAIL_TIME,
672 ((int64_t)sampleTime * 1000000) / track->timescale);
673 }
674 }
675 }
676 }
677
678 return AMediaFormat_copy(meta, track->meta);
679 }
680
readMetaData()681 status_t MPEG4Extractor::readMetaData() {
682 if (mInitCheck != NO_INIT) {
683 return mInitCheck;
684 }
685
686 off64_t offset = 0;
687 status_t err;
688 bool sawMoovOrSidx = false;
689
690 while (!((mHasMoovBox && sawMoovOrSidx && (mMdatFound || mMoofFound)) ||
691 (mIsHeif && (mPreferHeif || !mHasMoovBox) &&
692 (mItemTable != NULL) && mItemTable->isValid()))) {
693 off64_t orig_offset = offset;
694 err = parseChunk(&offset, 0);
695
696 if (err != OK && err != UNKNOWN_ERROR) {
697 break;
698 } else if (offset <= orig_offset) {
699 // only continue parsing if the offset was advanced,
700 // otherwise we might end up in an infinite loop
701 ALOGE("did not advance: %lld->%lld", (long long)orig_offset, (long long)offset);
702 err = ERROR_MALFORMED;
703 break;
704 } else if (err == UNKNOWN_ERROR) {
705 sawMoovOrSidx = true;
706 }
707 }
708
709 if ((mIsAvif || mIsHeif) && (mItemTable != NULL) && (mItemTable->countImages() > 0)) {
710 off64_t exifOffset;
711 size_t exifSize;
712 if (mItemTable->getExifOffsetAndSize(&exifOffset, &exifSize) == OK) {
713 AMediaFormat_setInt64(mFileMetaData,
714 AMEDIAFORMAT_KEY_EXIF_OFFSET, (int64_t)exifOffset);
715 AMediaFormat_setInt64(mFileMetaData,
716 AMEDIAFORMAT_KEY_EXIF_SIZE, (int64_t)exifSize);
717 }
718 off64_t xmpOffset;
719 size_t xmpSize;
720 if (mItemTable->getXmpOffsetAndSize(&xmpOffset, &xmpSize) == OK) {
721 // TODO(chz): b/175717339
722 // Use a hard-coded string here instead of named keys. The keys are available
723 // only on API 31+. The mp4 extractor is part of mainline and has min_sdk_version
724 // of 29. This hard-coded string can be replaced with the named constant once
725 // the mp4 extractor is built against API 31+.
726 AMediaFormat_setInt64(mFileMetaData,
727 "xmp-offset" /*AMEDIAFORMAT_KEY_XMP_OFFSET*/, (int64_t)xmpOffset);
728 AMediaFormat_setInt64(mFileMetaData,
729 "xmp-size" /*AMEDIAFORMAT_KEY_XMP_SIZE*/, (int64_t)xmpSize);
730 }
731 for (uint32_t imageIndex = 0;
732 imageIndex < mItemTable->countImages(); imageIndex++) {
733 AMediaFormat *meta = mItemTable->getImageMeta(imageIndex);
734 if (meta == NULL) {
735 ALOGE("heif image %u has no meta!", imageIndex);
736 continue;
737 }
738 // Some heif files advertise image sequence brands (eg. 'hevc') in
739 // ftyp box, but don't have any valid tracks in them. Instead of
740 // reporting the entire file as malformed, we override the error
741 // to allow still images to be extracted.
742 if (err != OK) {
743 ALOGW("Extracting still images only");
744 err = OK;
745 }
746 mInitCheck = OK;
747
748 ALOGV("adding %s image track %u", mIsHeif ? "HEIF" : "AVIF", imageIndex);
749 Track *track = new Track;
750 if (mLastTrack != NULL) {
751 mLastTrack->next = track;
752 } else {
753 mFirstTrack = track;
754 }
755 mLastTrack = track;
756
757 track->meta = meta;
758 AMediaFormat_setInt32(track->meta, AMEDIAFORMAT_KEY_TRACK_ID, imageIndex);
759 track->timescale = 1000000;
760 }
761 }
762
763 if (mInitCheck == OK) {
764 if (findTrackByMimePrefix("video/") != NULL) {
765 AMediaFormat_setString(mFileMetaData,
766 AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_MPEG4);
767 } else if (findTrackByMimePrefix("audio/") != NULL) {
768 AMediaFormat_setString(mFileMetaData,
769 AMEDIAFORMAT_KEY_MIME, "audio/mp4");
770 } else if (findTrackByMimePrefix(
771 MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC) != NULL) {
772 AMediaFormat_setString(mFileMetaData,
773 AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_HEIF);
774 } else if (findTrackByMimePrefix(
775 MEDIA_MIMETYPE_IMAGE_AVIF) != NULL) {
776 AMediaFormat_setString(mFileMetaData,
777 AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_IMAGE_AVIF);
778 } else {
779 AMediaFormat_setString(mFileMetaData,
780 AMEDIAFORMAT_KEY_MIME, "application/octet-stream");
781 }
782 } else {
783 mInitCheck = err;
784 }
785
786 CHECK_NE(err, (status_t)NO_INIT);
787
788 // copy pssh data into file metadata
789 uint64_t psshsize = 0;
790 for (size_t i = 0; i < mPssh.size(); i++) {
791 psshsize += 20 + mPssh[i].datalen;
792 }
793 if (psshsize > 0 && psshsize <= UINT32_MAX) {
794 char *buf = (char*)malloc(psshsize);
795 if (!buf) {
796 ALOGE("b/28471206");
797 return NO_MEMORY;
798 }
799 char *ptr = buf;
800 for (size_t i = 0; i < mPssh.size(); i++) {
801 memcpy(ptr, mPssh[i].uuid, 20); // uuid + length
802 memcpy(ptr + 20, mPssh[i].data, mPssh[i].datalen);
803 ptr += (20 + mPssh[i].datalen);
804 }
805 AMediaFormat_setBuffer(mFileMetaData, AMEDIAFORMAT_KEY_PSSH, buf, psshsize);
806 free(buf);
807 }
808
809 return mInitCheck;
810 }
811
812 struct PathAdder {
PathAdderandroid::PathAdder813 PathAdder(Vector<uint32_t> *path, uint32_t chunkType)
814 : mPath(path) {
815 mPath->push(chunkType);
816 }
817
~PathAdderandroid::PathAdder818 ~PathAdder() {
819 mPath->pop();
820 }
821
822 private:
823 Vector<uint32_t> *mPath;
824
825 PathAdder(const PathAdder &);
826 PathAdder &operator=(const PathAdder &);
827 };
828
underMetaDataPath(const Vector<uint32_t> & path)829 static bool underMetaDataPath(const Vector<uint32_t> &path) {
830 return path.size() >= 5
831 && path[0] == FOURCC("moov")
832 && path[1] == FOURCC("udta")
833 && path[2] == FOURCC("meta")
834 && path[3] == FOURCC("ilst");
835 }
836
underQTMetaPath(const Vector<uint32_t> & path,int32_t depth)837 static bool underQTMetaPath(const Vector<uint32_t> &path, int32_t depth) {
838 return path.size() >= 2
839 && path[0] == FOURCC("moov")
840 && path[1] == FOURCC("meta")
841 && (depth == 2
842 || (depth == 3
843 && (path[2] == FOURCC("hdlr")
844 || path[2] == FOURCC("ilst")
845 || path[2] == FOURCC("keys"))));
846 }
847
848 // Given a time in seconds since Jan 1 1904, produce a human-readable string.
convertTimeToDate(int64_t time_1904,String8 * s)849 static bool convertTimeToDate(int64_t time_1904, String8 *s) {
850 // delta between mpeg4 time and unix epoch time
851 static const int64_t delta = (((66 * 365 + 17) * 24) * 3600);
852 if (time_1904 < INT64_MIN + delta) {
853 return false;
854 }
855 time_t time_1970 = time_1904 - delta;
856
857 char tmp[32];
858 struct tm* tm = gmtime(&time_1970);
859 if (tm != NULL &&
860 strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", tm) > 0) {
861 *s = tmp;
862 return true;
863 }
864 return false;
865 }
866
parseChunk(off64_t * offset,int depth)867 status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
868 ALOGV("entering parseChunk %lld/%d", (long long)*offset, depth);
869
870 if (*offset < 0) {
871 ALOGE("b/23540914");
872 return ERROR_MALFORMED;
873 }
874 if (depth > 100) {
875 ALOGE("b/27456299");
876 return ERROR_MALFORMED;
877 }
878 uint32_t hdr[2];
879 if (mDataSource->readAt(*offset, hdr, 8) < 8) {
880 return ERROR_IO;
881 }
882 uint64_t chunk_size = ntohl(hdr[0]);
883 int32_t chunk_type = ntohl(hdr[1]);
884 off64_t data_offset = *offset + 8;
885
886 if (chunk_size == 1) {
887 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
888 return ERROR_IO;
889 }
890 chunk_size = ntoh64(chunk_size);
891 data_offset += 8;
892
893 if (chunk_size < 16) {
894 // The smallest valid chunk is 16 bytes long in this case.
895 return ERROR_MALFORMED;
896 }
897 } else if (chunk_size == 0) {
898 if (depth == 0) {
899 // atom extends to end of file
900 off64_t sourceSize;
901 if (mDataSource->getSize(&sourceSize) == OK) {
902 chunk_size = (sourceSize - *offset);
903 } else {
904 // XXX could we just pick a "sufficiently large" value here?
905 ALOGE("atom size is 0, and data source has no size");
906 return ERROR_MALFORMED;
907 }
908 } else {
909 // not allowed for non-toplevel atoms, skip it
910 *offset += 4;
911 return OK;
912 }
913 } else if (chunk_size < 8) {
914 // The smallest valid chunk is 8 bytes long.
915 ALOGE("invalid chunk size: %" PRIu64, chunk_size);
916 return ERROR_MALFORMED;
917 }
918
919 char chunk[5];
920 MakeFourCCString(chunk_type, chunk);
921 ALOGV("chunk: %s @ %lld, %d", chunk, (long long)*offset, depth);
922
923 if (kUseHexDump) {
924 static const char kWhitespace[] = " ";
925 const char *indent = &kWhitespace[sizeof(kWhitespace) - 1 - 2 * depth];
926 printf("%sfound chunk '%s' of size %" PRIu64 "\n", indent, chunk, chunk_size);
927
928 char buffer[256];
929 size_t n = chunk_size;
930 if (n > sizeof(buffer)) {
931 n = sizeof(buffer);
932 }
933 if (mDataSource->readAt(*offset, buffer, n)
934 < (ssize_t)n) {
935 return ERROR_IO;
936 }
937
938 hexdump(buffer, n);
939 }
940
941 PathAdder autoAdder(&mPath, chunk_type);
942
943 // (data_offset - *offset) is either 8 or 16
944 off64_t chunk_data_size = chunk_size - (data_offset - *offset);
945 if (chunk_data_size < 0) {
946 ALOGE("b/23540914");
947 return ERROR_MALFORMED;
948 }
949 if (chunk_type != FOURCC("mdat") && chunk_data_size > kMaxAtomSize) {
950 char errMsg[100];
951 sprintf(errMsg, "%s atom has size %" PRId64, chunk, chunk_data_size);
952 ALOGE("%s (b/28615448)", errMsg);
953 android_errorWriteWithInfoLog(0x534e4554, "28615448", -1, errMsg, strlen(errMsg));
954 return ERROR_MALFORMED;
955 }
956
957 if (chunk_type != FOURCC("cprt")
958 && chunk_type != FOURCC("covr")
959 && mPath.size() == 5 && underMetaDataPath(mPath)) {
960 off64_t stop_offset = *offset + chunk_size;
961 *offset = data_offset;
962 while (*offset < stop_offset) {
963 status_t err = parseChunk(offset, depth + 1);
964 if (err != OK) {
965 return err;
966 }
967 }
968
969 if (*offset != stop_offset) {
970 return ERROR_MALFORMED;
971 }
972
973 return OK;
974 }
975
976 switch(chunk_type) {
977 case FOURCC("moov"):
978 case FOURCC("trak"):
979 case FOURCC("mdia"):
980 case FOURCC("minf"):
981 case FOURCC("dinf"):
982 case FOURCC("stbl"):
983 case FOURCC("mvex"):
984 case FOURCC("moof"):
985 case FOURCC("traf"):
986 case FOURCC("mfra"):
987 case FOURCC("udta"):
988 case FOURCC("ilst"):
989 case FOURCC("sinf"):
990 case FOURCC("schi"):
991 case FOURCC("edts"):
992 case FOURCC("wave"):
993 {
994 if (chunk_type == FOURCC("moov") && depth != 0) {
995 ALOGE("moov: depth %d", depth);
996 return ERROR_MALFORMED;
997 }
998
999 if (chunk_type == FOURCC("moov") && mInitCheck == OK) {
1000 ALOGE("duplicate moov");
1001 return ERROR_MALFORMED;
1002 }
1003
1004 if (chunk_type == FOURCC("moof") && !mMoofFound) {
1005 // store the offset of the first segment
1006 mMoofFound = true;
1007 mMoofOffset = *offset;
1008 }
1009
1010 if (chunk_type == FOURCC("stbl")) {
1011 ALOGV("sampleTable chunk is %" PRIu64 " bytes long.", chunk_size);
1012
1013 if (mDataSource->flags()
1014 & (DataSourceBase::kWantsPrefetching
1015 | DataSourceBase::kIsCachingDataSource)) {
1016 CachedRangedDataSource *cachedSource =
1017 new CachedRangedDataSource(mDataSource);
1018
1019 if (cachedSource->setCachedRange(
1020 *offset, chunk_size,
1021 true /* assume ownership on success */) == OK) {
1022 mDataSource = cachedSource;
1023 } else {
1024 delete cachedSource;
1025 }
1026 }
1027
1028 if (mLastTrack == NULL) {
1029 return ERROR_MALFORMED;
1030 }
1031
1032 mLastTrack->sampleTable = new SampleTable(mDataSource);
1033 }
1034
1035 bool isTrack = false;
1036 if (chunk_type == FOURCC("trak")) {
1037 if (depth != 1) {
1038 ALOGE("trak: depth %d", depth);
1039 return ERROR_MALFORMED;
1040 }
1041 isTrack = true;
1042
1043 ALOGV("adding new track");
1044 Track *track = new Track;
1045 if (mLastTrack) {
1046 mLastTrack->next = track;
1047 } else {
1048 mFirstTrack = track;
1049 }
1050 mLastTrack = track;
1051
1052 track->meta = AMediaFormat_new();
1053 AMediaFormat_setString(track->meta,
1054 AMEDIAFORMAT_KEY_MIME, "application/octet-stream");
1055 }
1056
1057 off64_t stop_offset = *offset + chunk_size;
1058 *offset = data_offset;
1059 while (*offset < stop_offset) {
1060
1061 // pass udata terminate
1062 if (mIsQT && stop_offset - *offset == 4 && chunk_type == FOURCC("udta")) {
1063 // handle the case that udta terminates with terminate code x00000000
1064 // note that 0 terminator is optional and we just handle this case.
1065 uint32_t terminate_code = 1;
1066 mDataSource->readAt(*offset, &terminate_code, 4);
1067 if (0 == terminate_code) {
1068 *offset += 4;
1069 ALOGD("Terminal code for udta");
1070 continue;
1071 } else {
1072 ALOGW("invalid udta Terminal code");
1073 }
1074 }
1075
1076 status_t err = parseChunk(offset, depth + 1);
1077 if (err != OK) {
1078 if (isTrack) {
1079 mLastTrack->skipTrack = true;
1080 break;
1081 }
1082 return err;
1083 }
1084 }
1085
1086 if (*offset != stop_offset) {
1087 return ERROR_MALFORMED;
1088 }
1089
1090 if (isTrack) {
1091 int32_t trackId;
1092 // There must be exactly one track header per track.
1093
1094 if (!AMediaFormat_getInt32(mLastTrack->meta,
1095 AMEDIAFORMAT_KEY_TRACK_ID, &trackId)) {
1096 mLastTrack->skipTrack = true;
1097 }
1098
1099 status_t err = verifyTrack(mLastTrack);
1100 if (err != OK) {
1101 mLastTrack->skipTrack = true;
1102 }
1103
1104
1105 if (mLastTrack->skipTrack) {
1106 ALOGV("skipping this track...");
1107 Track *cur = mFirstTrack;
1108
1109 if (cur == mLastTrack) {
1110 delete cur;
1111 mFirstTrack = mLastTrack = NULL;
1112 } else {
1113 while (cur && cur->next != mLastTrack) {
1114 cur = cur->next;
1115 }
1116 if (cur) {
1117 cur->next = NULL;
1118 }
1119 delete mLastTrack;
1120 mLastTrack = cur;
1121 }
1122
1123 return OK;
1124 }
1125
1126 // place things we built elsewhere into their final locations
1127
1128 // put aggregated tx3g data into the metadata
1129 if (mLastTrack->mTx3gFilled > 0) {
1130 ALOGV("Putting %zu bytes of tx3g data into meta data",
1131 mLastTrack->mTx3gFilled);
1132 AMediaFormat_setBuffer(mLastTrack->meta,
1133 AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA,
1134 mLastTrack->mTx3gBuffer, mLastTrack->mTx3gFilled);
1135 // drop it now to reduce our footprint
1136 free(mLastTrack->mTx3gBuffer);
1137 mLastTrack->mTx3gBuffer = NULL;
1138 mLastTrack->mTx3gFilled = 0;
1139 mLastTrack->mTx3gSize = 0;
1140 }
1141
1142 const char *mime;
1143 AMediaFormat_getString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, &mime);
1144
1145 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
1146 void *data;
1147 size_t size;
1148
1149 if (AMediaFormat_getBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_2,
1150 &data, &size)
1151 && size >= 5) {
1152 const uint8_t *ptr = (const uint8_t *)data;
1153 const uint8_t profile = ptr[2] >> 1;
1154 const uint8_t blCompatibilityId = (ptr[4]) >> 4;
1155 bool create_two_tracks = false;
1156
1157 if (blCompatibilityId && blCompatibilityId != 15) {
1158 create_two_tracks = true;
1159 }
1160
1161 if (4 == profile || 7 == profile ||
1162 (profile >= 8 && profile < 11 && create_two_tracks)) {
1163 // we need a backward compatible track
1164 ALOGV("Adding new backward compatible track");
1165 Track *track_b = new Track;
1166
1167 track_b->timescale = mLastTrack->timescale;
1168 track_b->sampleTable = mLastTrack->sampleTable;
1169 track_b->includes_expensive_metadata =
1170 mLastTrack->includes_expensive_metadata;
1171 track_b->skipTrack = mLastTrack->skipTrack;
1172 track_b->elst_needs_processing = mLastTrack->elst_needs_processing;
1173 track_b->elst_media_time = mLastTrack->elst_media_time;
1174 track_b->elst_segment_duration = mLastTrack->elst_segment_duration;
1175 track_b->elst_shift_start_ticks = mLastTrack->elst_shift_start_ticks;
1176 track_b->elst_initial_empty_edit_ticks =
1177 mLastTrack->elst_initial_empty_edit_ticks;
1178 track_b->subsample_encryption = mLastTrack->subsample_encryption;
1179
1180 track_b->mTx3gBuffer = mLastTrack->mTx3gBuffer;
1181 track_b->mTx3gSize = mLastTrack->mTx3gSize;
1182 track_b->mTx3gFilled = mLastTrack->mTx3gFilled;
1183
1184 track_b->meta = AMediaFormat_new();
1185 AMediaFormat_copy(track_b->meta, mLastTrack->meta);
1186
1187 mLastTrack->next = track_b;
1188 track_b->next = NULL;
1189
1190 // we want to remove the csd-2 key from the metadata, but
1191 // don't have an AMediaFormat_* function to do so. Settle
1192 // for replacing this csd-2 with an empty csd-2.
1193 uint8_t emptybuffer[8] = {};
1194 AMediaFormat_setBuffer(track_b->meta, AMEDIAFORMAT_KEY_CSD_2,
1195 emptybuffer, 0);
1196
1197 if (4 == profile || 7 == profile || 8 == profile ) {
1198 AMediaFormat_setString(track_b->meta,
1199 AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_HEVC);
1200 } else if (9 == profile) {
1201 AMediaFormat_setString(track_b->meta,
1202 AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AVC);
1203 } else if (10 == profile) {
1204 AMediaFormat_setString(track_b->meta,
1205 AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_AV1);
1206 } // Should never get to else part
1207
1208 mLastTrack = track_b;
1209 }
1210 }
1211 }
1212 } else if (chunk_type == FOURCC("moov")) {
1213 mInitCheck = OK;
1214
1215 return UNKNOWN_ERROR; // Return a generic error.
1216 }
1217 break;
1218 }
1219
1220 case FOURCC("schm"):
1221 {
1222
1223 *offset += chunk_size;
1224 if (!mLastTrack) {
1225 return ERROR_MALFORMED;
1226 }
1227
1228 uint32_t scheme_type;
1229 if (mDataSource->readAt(data_offset + 4, &scheme_type, 4) < 4) {
1230 return ERROR_IO;
1231 }
1232 scheme_type = ntohl(scheme_type);
1233 int32_t mode = kCryptoModeUnencrypted;
1234 switch(scheme_type) {
1235 case FOURCC("cbc1"):
1236 {
1237 mode = kCryptoModeAesCbc;
1238 break;
1239 }
1240 case FOURCC("cbcs"):
1241 {
1242 mode = kCryptoModeAesCbc;
1243 mLastTrack->subsample_encryption = true;
1244 break;
1245 }
1246 case FOURCC("cenc"):
1247 {
1248 mode = kCryptoModeAesCtr;
1249 break;
1250 }
1251 case FOURCC("cens"):
1252 {
1253 mode = kCryptoModeAesCtr;
1254 mLastTrack->subsample_encryption = true;
1255 break;
1256 }
1257 }
1258 if (mode != kCryptoModeUnencrypted) {
1259 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CRYPTO_MODE, mode);
1260 }
1261 break;
1262 }
1263
1264
1265 case FOURCC("elst"):
1266 {
1267 *offset += chunk_size;
1268
1269 if (!mLastTrack) {
1270 return ERROR_MALFORMED;
1271 }
1272
1273 // See 14496-12 8.6.6
1274 uint8_t version;
1275 if (mDataSource->readAt(data_offset, &version, 1) < 1) {
1276 return ERROR_IO;
1277 }
1278
1279 uint32_t entry_count;
1280 if (!mDataSource->getUInt32(data_offset + 4, &entry_count)) {
1281 return ERROR_IO;
1282 }
1283
1284 if (entry_count > 2) {
1285 /* We support a single entry for gapless playback or negating offset for
1286 * reordering B frames, two entries (empty edit) for start offset at the moment.
1287 */
1288 ALOGW("ignoring edit list with %d entries", entry_count);
1289 } else {
1290 off64_t entriesoffset = data_offset + 8;
1291 uint64_t segment_duration;
1292 int64_t media_time;
1293 bool empty_edit_present = false;
1294 for (int i = 0; i < entry_count; ++i) {
1295 switch (version) {
1296 case 0: {
1297 uint32_t sd;
1298 int32_t mt;
1299 if (!mDataSource->getUInt32(entriesoffset, &sd) ||
1300 !mDataSource->getUInt32(entriesoffset + 4, (uint32_t*)&mt)) {
1301 return ERROR_IO;
1302 }
1303 segment_duration = sd;
1304 media_time = mt;
1305 // 4(segment duration) + 4(media time) + 4(media rate)
1306 entriesoffset += 12;
1307 break;
1308 }
1309 case 1: {
1310 if (!mDataSource->getUInt64(entriesoffset, &segment_duration) ||
1311 !mDataSource->getUInt64(entriesoffset + 8, (uint64_t*)&media_time)) {
1312 return ERROR_IO;
1313 }
1314 // 8(segment duration) + 8(media time) + 4(media rate)
1315 entriesoffset += 20;
1316 break;
1317 }
1318 default:
1319 return ERROR_IO;
1320 break;
1321 }
1322 // Empty edit entry would have to be first entry.
1323 if (media_time == -1 && i == 0) {
1324 empty_edit_present = true;
1325 ALOGV("initial empty edit ticks: %" PRIu64, segment_duration);
1326 /* In movie header timescale, and needs to be converted to media timescale
1327 * after we get that from a track's 'mdhd' atom,
1328 * which at times come after 'elst'.
1329 */
1330 mLastTrack->elst_initial_empty_edit_ticks = segment_duration;
1331 } else if (media_time >= 0 && i == 0) {
1332 ALOGV("first edit list entry - from gapless playback files");
1333 mLastTrack->elst_media_time = media_time;
1334 mLastTrack->elst_segment_duration = segment_duration;
1335 ALOGV("segment_duration: %" PRIu64 " media_time: %" PRId64,
1336 segment_duration, media_time);
1337 // media_time is in media timescale as are STTS/CTTS entries.
1338 mLastTrack->elst_shift_start_ticks = media_time;
1339 } else if (empty_edit_present && i == 1) {
1340 // Process second entry only when the first entry was an empty edit entry.
1341 ALOGV("second edit list entry");
1342 mLastTrack->elst_shift_start_ticks = media_time;
1343 } else {
1344 ALOGW("for now, unsupported entry in edit list %" PRIu32, entry_count);
1345 }
1346 }
1347 // save these for later, because the elst atom might precede
1348 // the atoms that actually gives us the duration and sample rate
1349 // needed to calculate the padding and delay values
1350 mLastTrack->elst_needs_processing = true;
1351 }
1352 break;
1353 }
1354
1355 case FOURCC("frma"):
1356 {
1357 *offset += chunk_size;
1358
1359 uint32_t original_fourcc;
1360 if (mDataSource->readAt(data_offset, &original_fourcc, 4) < 4) {
1361 return ERROR_IO;
1362 }
1363 original_fourcc = ntohl(original_fourcc);
1364 ALOGV("read original format: %d", original_fourcc);
1365
1366 if (mLastTrack == NULL) {
1367 return ERROR_MALFORMED;
1368 }
1369
1370 AMediaFormat_setString(mLastTrack->meta,
1371 AMEDIAFORMAT_KEY_MIME, FourCC2MIME(original_fourcc));
1372 uint32_t num_channels = 0;
1373 uint32_t sample_rate = 0;
1374 if (AdjustChannelsAndRate(original_fourcc, &num_channels, &sample_rate)) {
1375 AMediaFormat_setInt32(mLastTrack->meta,
1376 AMEDIAFORMAT_KEY_CHANNEL_COUNT, num_channels);
1377 AMediaFormat_setInt32(mLastTrack->meta,
1378 AMEDIAFORMAT_KEY_SAMPLE_RATE, sample_rate);
1379 }
1380
1381 if (!mIsQT && original_fourcc == FOURCC("alac")) {
1382 off64_t tmpOffset = *offset;
1383 status_t err = parseALACSampleEntry(&tmpOffset);
1384 if (err != OK) {
1385 ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
1386 return err;
1387 }
1388 *offset = tmpOffset + 8;
1389 }
1390
1391 break;
1392 }
1393
1394 case FOURCC("tenc"):
1395 {
1396 *offset += chunk_size;
1397
1398 if (chunk_size < 32) {
1399 return ERROR_MALFORMED;
1400 }
1401
1402 // tenc box contains 1 byte version, 3 byte flags, 3 byte default algorithm id, one byte
1403 // default IV size, 16 bytes default KeyID
1404 // (ISO 23001-7)
1405
1406 uint8_t version;
1407 if (mDataSource->readAt(data_offset, &version, sizeof(version))
1408 < (ssize_t)sizeof(version)) {
1409 return ERROR_IO;
1410 }
1411
1412 uint8_t buf[4];
1413 memset(buf, 0, 4);
1414 if (mDataSource->readAt(data_offset + 4, buf + 1, 3) < 3) {
1415 return ERROR_IO;
1416 }
1417
1418 if (mLastTrack == NULL) {
1419 return ERROR_MALFORMED;
1420 }
1421
1422 uint8_t defaultEncryptedByteBlock = 0;
1423 uint8_t defaultSkipByteBlock = 0;
1424 uint32_t defaultAlgorithmId = ntohl(*((int32_t*)buf));
1425 if (version == 1) {
1426 uint32_t pattern = buf[2];
1427 defaultEncryptedByteBlock = pattern >> 4;
1428 defaultSkipByteBlock = pattern & 0xf;
1429 if (defaultEncryptedByteBlock == 0 && defaultSkipByteBlock == 0) {
1430 // use (1,0) to mean "encrypt everything"
1431 defaultEncryptedByteBlock = 1;
1432 }
1433 } else if (mLastTrack->subsample_encryption) {
1434 ALOGW("subsample_encryption should be version 1");
1435 } else if (defaultAlgorithmId > 1) {
1436 // only 0 (clear) and 1 (AES-128) are valid
1437 ALOGW("defaultAlgorithmId: %u is a reserved value", defaultAlgorithmId);
1438 defaultAlgorithmId = 1;
1439 }
1440
1441 memset(buf, 0, 4);
1442 if (mDataSource->readAt(data_offset + 7, buf + 3, 1) < 1) {
1443 return ERROR_IO;
1444 }
1445 uint32_t defaultIVSize = ntohl(*((int32_t*)buf));
1446
1447 if (defaultAlgorithmId == 0 && defaultIVSize != 0) {
1448 // only unencrypted data must have 0 IV size
1449 return ERROR_MALFORMED;
1450 } else if (defaultIVSize != 0 &&
1451 defaultIVSize != 8 &&
1452 defaultIVSize != 16) {
1453 return ERROR_MALFORMED;
1454 }
1455
1456 uint8_t defaultKeyId[16];
1457
1458 if (mDataSource->readAt(data_offset + 8, &defaultKeyId, 16) < 16) {
1459 return ERROR_IO;
1460 }
1461
1462 sp<ABuffer> defaultConstantIv;
1463 if (defaultAlgorithmId != 0 && defaultIVSize == 0) {
1464
1465 uint8_t ivlength;
1466 if (mDataSource->readAt(data_offset + 24, &ivlength, sizeof(ivlength))
1467 < (ssize_t)sizeof(ivlength)) {
1468 return ERROR_IO;
1469 }
1470
1471 if (ivlength != 8 && ivlength != 16) {
1472 ALOGW("unsupported IV length: %u", ivlength);
1473 return ERROR_MALFORMED;
1474 }
1475
1476 defaultConstantIv = new ABuffer(ivlength);
1477 if (mDataSource->readAt(data_offset + 25, defaultConstantIv->data(), ivlength)
1478 < (ssize_t)ivlength) {
1479 return ERROR_IO;
1480 }
1481
1482 defaultConstantIv->setRange(0, ivlength);
1483 }
1484
1485 int32_t tmpAlgorithmId;
1486 if (!AMediaFormat_getInt32(mLastTrack->meta,
1487 AMEDIAFORMAT_KEY_CRYPTO_MODE, &tmpAlgorithmId)) {
1488 AMediaFormat_setInt32(mLastTrack->meta,
1489 AMEDIAFORMAT_KEY_CRYPTO_MODE, defaultAlgorithmId);
1490 }
1491
1492 AMediaFormat_setInt32(mLastTrack->meta,
1493 AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, defaultIVSize);
1494 AMediaFormat_setBuffer(mLastTrack->meta,
1495 AMEDIAFORMAT_KEY_CRYPTO_KEY, defaultKeyId, 16);
1496 AMediaFormat_setInt32(mLastTrack->meta,
1497 AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK, defaultEncryptedByteBlock);
1498 AMediaFormat_setInt32(mLastTrack->meta,
1499 AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK, defaultSkipByteBlock);
1500 if (defaultConstantIv != NULL) {
1501 AMediaFormat_setBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CRYPTO_IV,
1502 defaultConstantIv->data(), defaultConstantIv->size());
1503 }
1504 break;
1505 }
1506
1507 case FOURCC("tkhd"):
1508 {
1509 *offset += chunk_size;
1510
1511 status_t err;
1512 if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) {
1513 return err;
1514 }
1515
1516 break;
1517 }
1518
1519 case FOURCC("tref"):
1520 {
1521 off64_t stop_offset = *offset + chunk_size;
1522 *offset = data_offset;
1523 while (*offset < stop_offset) {
1524 status_t err = parseChunk(offset, depth + 1);
1525 if (err != OK) {
1526 return err;
1527 }
1528 }
1529 if (*offset != stop_offset) {
1530 return ERROR_MALFORMED;
1531 }
1532 break;
1533 }
1534
1535 case FOURCC("thmb"):
1536 {
1537 *offset += chunk_size;
1538
1539 if (mLastTrack != NULL) {
1540 // Skip thumbnail track for now since we don't have an
1541 // API to retrieve it yet.
1542 // The thumbnail track can't be accessed by negative index or time,
1543 // because each timed sample has its own corresponding thumbnail
1544 // in the thumbnail track. We'll need a dedicated API to retrieve
1545 // thumbnail at time instead.
1546 mLastTrack->skipTrack = true;
1547 }
1548
1549 break;
1550 }
1551
1552 case FOURCC("pssh"):
1553 {
1554 *offset += chunk_size;
1555
1556 PsshInfo pssh;
1557
1558 if (mDataSource->readAt(data_offset + 4, &pssh.uuid, 16) < 16) {
1559 return ERROR_IO;
1560 }
1561
1562 uint32_t psshdatalen = 0;
1563 if (mDataSource->readAt(data_offset + 20, &psshdatalen, 4) < 4) {
1564 return ERROR_IO;
1565 }
1566 pssh.datalen = ntohl(psshdatalen);
1567 ALOGV("pssh data size: %d", pssh.datalen);
1568 if (chunk_size < 20 || pssh.datalen > chunk_size - 20) {
1569 // pssh data length exceeds size of containing box
1570 return ERROR_MALFORMED;
1571 }
1572
1573 pssh.data = new (std::nothrow) uint8_t[pssh.datalen];
1574 if (pssh.data == NULL) {
1575 return ERROR_MALFORMED;
1576 }
1577 ALOGV("allocated pssh @ %p", pssh.data);
1578 ssize_t requested = (ssize_t) pssh.datalen;
1579 if (mDataSource->readAt(data_offset + 24, pssh.data, requested) < requested) {
1580 delete[] pssh.data;
1581 return ERROR_IO;
1582 }
1583 mPssh.push_back(pssh);
1584
1585 break;
1586 }
1587
1588 case FOURCC("mdhd"):
1589 {
1590 *offset += chunk_size;
1591
1592 if (chunk_data_size < 4 || mLastTrack == NULL) {
1593 return ERROR_MALFORMED;
1594 }
1595
1596 uint8_t version;
1597 if (mDataSource->readAt(
1598 data_offset, &version, sizeof(version))
1599 < (ssize_t)sizeof(version)) {
1600 return ERROR_IO;
1601 }
1602
1603 off64_t timescale_offset;
1604
1605 if (version == 1) {
1606 timescale_offset = data_offset + 4 + 16;
1607 } else if (version == 0) {
1608 timescale_offset = data_offset + 4 + 8;
1609 } else {
1610 return ERROR_IO;
1611 }
1612
1613 uint32_t timescale;
1614 if (mDataSource->readAt(
1615 timescale_offset, ×cale, sizeof(timescale))
1616 < (ssize_t)sizeof(timescale)) {
1617 return ERROR_IO;
1618 }
1619
1620 if (!timescale) {
1621 ALOGE("timescale should not be ZERO.");
1622 return ERROR_MALFORMED;
1623 }
1624
1625 mLastTrack->timescale = ntohl(timescale);
1626
1627 // 14496-12 says all ones means indeterminate, but some files seem to use
1628 // 0 instead. We treat both the same.
1629 int64_t duration = 0;
1630 if (version == 1) {
1631 if (mDataSource->readAt(
1632 timescale_offset + 4, &duration, sizeof(duration))
1633 < (ssize_t)sizeof(duration)) {
1634 return ERROR_IO;
1635 }
1636 if (duration != -1) {
1637 duration = ntoh64(duration);
1638 }
1639 } else {
1640 uint32_t duration32;
1641 if (mDataSource->readAt(
1642 timescale_offset + 4, &duration32, sizeof(duration32))
1643 < (ssize_t)sizeof(duration32)) {
1644 return ERROR_IO;
1645 }
1646 if (duration32 != 0xffffffff) {
1647 duration = ntohl(duration32);
1648 }
1649 }
1650 if (duration != 0 && mLastTrack->timescale != 0) {
1651 long double durationUs = ((long double)duration * 1000000) / mLastTrack->timescale;
1652 if (durationUs < 0 || durationUs > INT64_MAX) {
1653 ALOGE("cannot represent %lld * 1000000 / %lld in 64 bits",
1654 (long long) duration, (long long) mLastTrack->timescale);
1655 return ERROR_MALFORMED;
1656 }
1657 // Store this track's mdhd duration to calculate the padding.
1658 mLastTrack->mMdhdDurationUs = (int64_t)durationUs;
1659 } else {
1660 mLastTrack->mMdhdDurationUs = 0;
1661 }
1662
1663 uint8_t lang[2];
1664 off64_t lang_offset;
1665 if (version == 1) {
1666 lang_offset = timescale_offset + 4 + 8;
1667 } else if (version == 0) {
1668 lang_offset = timescale_offset + 4 + 4;
1669 } else {
1670 return ERROR_IO;
1671 }
1672
1673 if (mDataSource->readAt(lang_offset, &lang, sizeof(lang))
1674 < (ssize_t)sizeof(lang)) {
1675 return ERROR_IO;
1676 }
1677
1678 // To get the ISO-639-2/T three character language code
1679 // 1 bit pad followed by 3 5-bits characters. Each character
1680 // is packed as the difference between its ASCII value and 0x60.
1681 char lang_code[4];
1682 lang_code[0] = ((lang[0] >> 2) & 0x1f) + 0x60;
1683 lang_code[1] = ((lang[0] & 0x3) << 3 | (lang[1] >> 5)) + 0x60;
1684 lang_code[2] = (lang[1] & 0x1f) + 0x60;
1685 lang_code[3] = '\0';
1686
1687 AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_LANGUAGE, lang_code);
1688
1689 break;
1690 }
1691
1692 case FOURCC("stsd"):
1693 {
1694 uint8_t buffer[8];
1695 if (chunk_data_size < (off64_t)sizeof(buffer)) {
1696 return ERROR_MALFORMED;
1697 }
1698
1699 if (mDataSource->readAt(
1700 data_offset, buffer, 8) < 8) {
1701 return ERROR_IO;
1702 }
1703
1704 if (U32_AT(buffer) != 0) {
1705 // Should be version 0, flags 0.
1706 return ERROR_MALFORMED;
1707 }
1708
1709 uint32_t entry_count = U32_AT(&buffer[4]);
1710
1711 if (entry_count > 1) {
1712 // For 3GPP timed text, there could be multiple tx3g boxes contain
1713 // multiple text display formats. These formats will be used to
1714 // display the timed text.
1715 // For encrypted files, there may also be more than one entry.
1716 const char *mime;
1717
1718 if (mLastTrack == NULL)
1719 return ERROR_MALFORMED;
1720
1721 CHECK(AMediaFormat_getString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, &mime));
1722 if (strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) &&
1723 strcasecmp(mime, "application/octet-stream")) {
1724 // For now we only support a single type of media per track.
1725 mLastTrack->skipTrack = true;
1726 *offset += chunk_size;
1727 break;
1728 }
1729 }
1730 off64_t stop_offset = *offset + chunk_size;
1731 *offset = data_offset + 8;
1732 for (uint32_t i = 0; i < entry_count; ++i) {
1733 status_t err = parseChunk(offset, depth + 1);
1734 if (err != OK) {
1735 return err;
1736 }
1737 }
1738
1739 if (*offset != stop_offset) {
1740 return ERROR_MALFORMED;
1741 }
1742 break;
1743 }
1744 case FOURCC("mett"):
1745 {
1746 *offset += chunk_size;
1747
1748 // the absolute minimum size of a compliant mett box is 11 bytes:
1749 // 6 byte reserved, 2 byte index, null byte, one char mime_format, null byte
1750 // The resulting mime_format would be invalid at that size though.
1751 if (mLastTrack == NULL || chunk_data_size < 11) {
1752 return ERROR_MALFORMED;
1753 }
1754
1755 auto buffer = heapbuffer<uint8_t>(chunk_data_size);
1756 if (buffer.get() == NULL) {
1757 return NO_MEMORY;
1758 }
1759
1760 if (mDataSource->readAt(
1761 data_offset, buffer.get(), chunk_data_size) < chunk_data_size) {
1762 return ERROR_IO;
1763 }
1764
1765 // ISO-14496-12:
1766 // int8 reserved[6]; // should be all zeroes
1767 // int16_t data_reference_index;
1768 // char content_encoding[]; // null terminated, optional (= just the null byte)
1769 // char mime_format[]; // null terminated, mandatory
1770 // optional other boxes
1771 //
1772 // API < 29:
1773 // char mime_format[]; // null terminated
1774 //
1775 // API >= 29
1776 // char mime_format[]; // null terminated
1777 // char mime_format[]; // null terminated
1778
1779 // Prior to API 29, the metadata track was not compliant with ISO/IEC
1780 // 14496-12-2015. This led to some ISO-compliant parsers failing to read the
1781 // metatrack. As of API 29 and onwards, a change was made to metadata track to
1782 // make it somewhat compatible with the standard. The workaround is to write the
1783 // null-terminated mime_format string twice. This allows compliant parsers to
1784 // read the missing reserved, data_reference_index, and content_encoding fields
1785 // from the first mime_type string. The actual mime_format field would then be
1786 // read correctly from the second string. The non-compliant Android frameworks
1787 // from API 28 and earlier would still be able to read the mime_format correctly
1788 // as it would only read the first null-terminated mime_format string. To enable
1789 // reading metadata tracks generated from both the non-compliant and compliant
1790 // formats, a check needs to be done to see which format is used.
1791 const char *str = (const char*) buffer.get();
1792 size_t string_length = strnlen(str, chunk_data_size);
1793
1794 if (string_length == chunk_data_size - 1) {
1795 // This is likely a pre API 29 file, since it's a single null terminated
1796 // string filling the entire box.
1797 AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, str);
1798 } else {
1799 // This might be a fully compliant metadata track, a "double mime" compatibility
1800 // track, or anything else, including a single non-terminated string, so we need
1801 // to determine the length of each string we want to parse out of the box.
1802 size_t encoding_length = strnlen(str + 8, chunk_data_size - 8);
1803 if (encoding_length + 8 >= chunk_data_size - 2) {
1804 // the encoding extends to the end of the box, so there's no mime_format
1805 return ERROR_MALFORMED;
1806 }
1807 String8 contentEncoding(str + 8, encoding_length);
1808 String8 mimeFormat(str + 8 + encoding_length + 1,
1809 chunk_data_size - 8 - encoding_length - 1);
1810 AMediaFormat_setString(mLastTrack->meta,
1811 AMEDIAFORMAT_KEY_MIME, mimeFormat.c_str());
1812 }
1813 break;
1814 }
1815
1816 case FOURCC("mp4a"):
1817 case FOURCC("enca"):
1818 case FOURCC("samr"):
1819 case FOURCC("sawb"):
1820 case FOURCC("Opus"):
1821 case FOURCC("twos"):
1822 case FOURCC("sowt"):
1823 case FOURCC("alac"):
1824 case FOURCC("fLaC"):
1825 case FOURCC(".mp3"):
1826 case 0x6D730055: // "ms U" mp3 audio
1827 case FOURCC("mha1"):
1828 case FOURCC("mhm1"):
1829 case FOURCC("dtsc"):
1830 case FOURCC("dtse"):
1831 case FOURCC("dtsh"):
1832 case FOURCC("dtsl"):
1833 case FOURCC("dtsx"):
1834 {
1835 if (mIsQT && depth >= 1 && mPath[depth - 1] == FOURCC("wave")) {
1836
1837 if (chunk_type == FOURCC("alac")) {
1838 off64_t offsetTmp = *offset;
1839 status_t err = parseALACSampleEntry(&offsetTmp);
1840 if (err != OK) {
1841 ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
1842 return err;
1843 }
1844 }
1845
1846 // Ignore all atoms embedded in QT wave atom
1847 ALOGV("Ignore all atoms embedded in QT wave atom");
1848 *offset += chunk_size;
1849 break;
1850 }
1851
1852 uint8_t buffer[8 + 20];
1853 if (chunk_data_size < (ssize_t)sizeof(buffer)) {
1854 // Basic AudioSampleEntry size.
1855 return ERROR_MALFORMED;
1856 }
1857
1858 if (mDataSource->readAt(
1859 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
1860 return ERROR_IO;
1861 }
1862
1863 // we can get data_ref_index value from U16_AT(&buffer[6])
1864 uint16_t version = U16_AT(&buffer[8]);
1865 uint32_t num_channels = U16_AT(&buffer[16]);
1866
1867 uint16_t sample_size = U16_AT(&buffer[18]);
1868 uint32_t sample_rate = U32_AT(&buffer[24]) >> 16;
1869
1870 if (mLastTrack == NULL)
1871 return ERROR_MALFORMED;
1872
1873 off64_t stop_offset = *offset + chunk_size;
1874 *offset = data_offset + sizeof(buffer);
1875
1876 if (mIsQT) {
1877 if (version == 1) {
1878 if (mDataSource->readAt(*offset, buffer, 16) < 16) {
1879 return ERROR_IO;
1880 }
1881
1882 #if 0
1883 U32_AT(buffer); // samples per packet
1884 U32_AT(&buffer[4]); // bytes per packet
1885 U32_AT(&buffer[8]); // bytes per frame
1886 U32_AT(&buffer[12]); // bytes per sample
1887 #endif
1888 *offset += 16;
1889 } else if (version == 2) {
1890 uint8_t v2buffer[36];
1891 if (mDataSource->readAt(*offset, v2buffer, 36) < 36) {
1892 return ERROR_IO;
1893 }
1894
1895 #if 0
1896 U32_AT(v2buffer); // size of struct only
1897 sample_rate = (uint32_t)U64_AT(&v2buffer[4]); // audio sample rate
1898 num_channels = U32_AT(&v2buffer[12]); // num audio channels
1899 U32_AT(&v2buffer[16]); // always 0x7f000000
1900 sample_size = (uint16_t)U32_AT(&v2buffer[20]); // const bits per channel
1901 U32_AT(&v2buffer[24]); // format specifc flags
1902 U32_AT(&v2buffer[28]); // const bytes per audio packet
1903 U32_AT(&v2buffer[32]); // const LPCM frames per audio packet
1904 #endif
1905 *offset += 36;
1906 }
1907 }
1908
1909 if (chunk_type != FOURCC("enca")) {
1910 // if the chunk type is enca, we'll get the type from the frma box later
1911 AMediaFormat_setString(mLastTrack->meta,
1912 AMEDIAFORMAT_KEY_MIME, FourCC2MIME(chunk_type));
1913 AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);
1914
1915 if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, FourCC2MIME(chunk_type))) {
1916 AMediaFormat_setInt32(mLastTrack->meta,
1917 AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, sample_size);
1918 if (chunk_type == FOURCC("twos")) {
1919 AMediaFormat_setInt32(mLastTrack->meta,
1920 AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN, 1);
1921 }
1922 }
1923 }
1924 ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
1925 chunk, num_channels, sample_size, sample_rate);
1926 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, num_channels);
1927 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sample_rate);
1928
1929 if (chunk_type == FOURCC("Opus")) {
1930 uint8_t opusInfo[AOPUS_OPUSHEAD_MAXSIZE];
1931 data_offset += sizeof(buffer);
1932 size_t opusInfoSize = chunk_data_size - sizeof(buffer);
1933
1934 if (opusInfoSize < AOPUS_OPUSHEAD_MINSIZE ||
1935 opusInfoSize > AOPUS_OPUSHEAD_MAXSIZE) {
1936 return ERROR_MALFORMED;
1937 }
1938 // Read Opus Header
1939 if (mDataSource->readAt(
1940 data_offset, opusInfo, opusInfoSize) < opusInfoSize) {
1941 return ERROR_IO;
1942 }
1943
1944 // OpusHeader must start with this magic sequence, overwrite first 8 bytes
1945 // http://wiki.xiph.org/OggOpus#ID_Header
1946 strncpy((char *)opusInfo, "OpusHead", 8);
1947
1948 // Version shall be 0 as per mp4 Opus Specific Box
1949 // (https://opus-codec.org/docs/opus_in_isobmff.html#4.3.2)
1950 if (opusInfo[8]) {
1951 return ERROR_MALFORMED;
1952 }
1953 // Force version to 1 as per OpusHead definition
1954 // (http://wiki.xiph.org/OggOpus#ID_Header)
1955 opusInfo[8] = 1;
1956
1957 // Read Opus Specific Box values
1958 size_t opusOffset = 10;
1959 uint16_t pre_skip = U16_AT(&opusInfo[opusOffset]);
1960 uint32_t sample_rate = U32_AT(&opusInfo[opusOffset + 2]);
1961 uint16_t out_gain = U16_AT(&opusInfo[opusOffset + 6]);
1962
1963 // Convert Opus Specific Box values. ParseOpusHeader expects
1964 // the values in LE, however MP4 stores these values as BE
1965 // https://opus-codec.org/docs/opus_in_isobmff.html#4.3.2
1966 memcpy(&opusInfo[opusOffset], &pre_skip, sizeof(pre_skip));
1967 memcpy(&opusInfo[opusOffset + 2], &sample_rate, sizeof(sample_rate));
1968 memcpy(&opusInfo[opusOffset + 6], &out_gain, sizeof(out_gain));
1969
1970 static const int64_t kSeekPreRollNs = 80000000; // Fixed 80 msec
1971 static const int32_t kOpusSampleRate = 48000;
1972 int64_t codecDelay = pre_skip * 1000000000ll / kOpusSampleRate;
1973
1974 AMediaFormat_setBuffer(mLastTrack->meta,
1975 AMEDIAFORMAT_KEY_CSD_0, opusInfo, opusInfoSize);
1976 AMediaFormat_setBuffer(mLastTrack->meta,
1977 AMEDIAFORMAT_KEY_CSD_1, &codecDelay, sizeof(codecDelay));
1978 AMediaFormat_setBuffer(mLastTrack->meta,
1979 AMEDIAFORMAT_KEY_CSD_2, &kSeekPreRollNs, sizeof(kSeekPreRollNs));
1980
1981 data_offset += opusInfoSize;
1982 *offset = data_offset;
1983 CHECK_EQ(*offset, stop_offset);
1984 }
1985
1986 if (!mIsQT && chunk_type == FOURCC("alac")) {
1987 data_offset += sizeof(buffer);
1988
1989 status_t err = parseALACSampleEntry(&data_offset);
1990 if (err != OK) {
1991 ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
1992 return err;
1993 }
1994 *offset = data_offset;
1995 CHECK_EQ(*offset, stop_offset);
1996 }
1997
1998 if (chunk_type == FOURCC("fLaC")) {
1999 data_offset += sizeof(buffer);
2000 *offset = data_offset;
2001 }
2002
2003 while (*offset < stop_offset) {
2004 status_t err = parseChunk(offset, depth + 1);
2005 if (err != OK) {
2006 return err;
2007 }
2008 }
2009
2010 if (*offset != stop_offset) {
2011 return ERROR_MALFORMED;
2012 }
2013 break;
2014 }
2015 case FOURCC("mhaC"):
2016 {
2017 // See ISO_IEC_23008-3;2019 MHADecoderConfigurationRecord
2018 constexpr uint32_t mhac_header_size = 4 /* size */ + 4 /* boxtype 'mhaC' */
2019 + 1 /* configurationVersion */ + 1 /* mpegh3daProfileLevelIndication */
2020 + 1 /* referenceChannelLayout */ + 2 /* mpegh3daConfigLength */;
2021 uint8_t mhac_header[mhac_header_size];
2022 off64_t data_offset = *offset;
2023
2024 if (mLastTrack == NULL || chunk_size < sizeof(mhac_header)) {
2025 return ERROR_MALFORMED;
2026 }
2027
2028 if (mDataSource->readAt(data_offset, mhac_header, sizeof(mhac_header))
2029 < (ssize_t)sizeof(mhac_header)) {
2030 return ERROR_IO;
2031 }
2032
2033 //get mpegh3daProfileLevelIndication
2034 const uint32_t mpegh3daProfileLevelIndication = mhac_header[9];
2035 AMediaFormat_setInt32(mLastTrack->meta,
2036 AMEDIAFORMAT_KEY_MPEGH_PROFILE_LEVEL_INDICATION,
2037 mpegh3daProfileLevelIndication);
2038
2039 //get referenceChannelLayout
2040 const uint32_t referenceChannelLayout = mhac_header[10];
2041 AMediaFormat_setInt32(mLastTrack->meta,
2042 AMEDIAFORMAT_KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT,
2043 referenceChannelLayout);
2044
2045 // get mpegh3daConfigLength
2046 const uint32_t mhac_config_size = U16_AT(&mhac_header[11]);
2047 if (chunk_size != sizeof(mhac_header) + mhac_config_size) {
2048 return ERROR_MALFORMED;
2049 }
2050
2051 data_offset += sizeof(mhac_header);
2052 uint8_t mhac_config[mhac_config_size];
2053 if (mDataSource->readAt(data_offset, mhac_config, sizeof(mhac_config))
2054 < (ssize_t)sizeof(mhac_config)) {
2055 return ERROR_IO;
2056 }
2057
2058 AMediaFormat_setBuffer(mLastTrack->meta,
2059 AMEDIAFORMAT_KEY_CSD_0, mhac_config, sizeof(mhac_config));
2060 data_offset += sizeof(mhac_config);
2061 *offset = data_offset;
2062 break;
2063 }
2064 case FOURCC("mhaP"):
2065 {
2066 // FDAmd_2 of ISO_IEC_23008-3;2019 MHAProfileAndLevelCompatibilitySetBox
2067 constexpr uint32_t mhap_header_size = 4 /* size */ + 4 /* boxtype 'mhaP' */
2068 + 1 /* numCompatibleSets */;
2069
2070 uint8_t mhap_header[mhap_header_size];
2071 off64_t data_offset = *offset;
2072
2073 if (chunk_size < (ssize_t)mhap_header_size) {
2074 return ERROR_MALFORMED;
2075 }
2076
2077 if (mDataSource->readAt(data_offset, mhap_header, sizeof(mhap_header))
2078 < (ssize_t)sizeof(mhap_header)) {
2079 return ERROR_IO;
2080 }
2081
2082 // mhap_compatible_sets_size = numCompatibleSets * sizeof(uint8_t)
2083 const uint32_t mhap_compatible_sets_size = mhap_header[8];
2084 if (chunk_size != sizeof(mhap_header) + mhap_compatible_sets_size) {
2085 return ERROR_MALFORMED;
2086 }
2087
2088 data_offset += sizeof(mhap_header);
2089 uint8_t mhap_compatible_sets[mhap_compatible_sets_size];
2090 if (mDataSource->readAt(
2091 data_offset, mhap_compatible_sets, sizeof(mhap_compatible_sets))
2092 < (ssize_t)sizeof(mhap_compatible_sets)) {
2093 return ERROR_IO;
2094 }
2095
2096 AMediaFormat_setBuffer(mLastTrack->meta,
2097 AMEDIAFORMAT_KEY_MPEGH_COMPATIBLE_SETS,
2098 mhap_compatible_sets, sizeof(mhap_compatible_sets));
2099 data_offset += sizeof(mhap_compatible_sets);
2100 *offset = data_offset;
2101 break;
2102 }
2103 case FOURCC("mp4v"):
2104 case FOURCC("encv"):
2105 case FOURCC("s263"):
2106 case FOURCC("H263"):
2107 case FOURCC("h263"):
2108 case FOURCC("avc1"):
2109 case FOURCC("hvc1"):
2110 case FOURCC("hev1"):
2111 case FOURCC("dvav"):
2112 case FOURCC("dva1"):
2113 case FOURCC("dvhe"):
2114 case FOURCC("dvh1"):
2115 case FOURCC("dav1"):
2116 case FOURCC("av01"):
2117 case FOURCC("vp09"):
2118 case FOURCC("apv1"):
2119 {
2120 uint8_t buffer[78];
2121 if (chunk_data_size < (ssize_t)sizeof(buffer)) {
2122 // Basic VideoSampleEntry size.
2123 return ERROR_MALFORMED;
2124 }
2125
2126 if (mDataSource->readAt(
2127 data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
2128 return ERROR_IO;
2129 }
2130
2131 // we can get data_ref_index value from U16_AT(&buffer[6])
2132 uint16_t width = U16_AT(&buffer[6 + 18]);
2133 uint16_t height = U16_AT(&buffer[6 + 20]);
2134
2135 // The video sample is not standard-compliant if it has invalid dimension.
2136 // Use some default width and height value, and
2137 // let the decoder figure out the actual width and height (and thus
2138 // be prepared for INFO_FOMRAT_CHANGED event).
2139 if (width == 0) width = 352;
2140 if (height == 0) height = 288;
2141
2142 // printf("*** coding='%s' width=%d height=%d\n",
2143 // chunk, width, height);
2144
2145 if (mLastTrack == NULL)
2146 return ERROR_MALFORMED;
2147
2148 if (chunk_type != FOURCC("encv")) {
2149 // if the chunk type is encv, we'll get the type from the frma box later
2150 AMediaFormat_setString(mLastTrack->meta,
2151 AMEDIAFORMAT_KEY_MIME, FourCC2MIME(chunk_type));
2152 }
2153 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_WIDTH, width);
2154 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_HEIGHT, height);
2155
2156 off64_t stop_offset = *offset + chunk_size;
2157 *offset = data_offset + sizeof(buffer);
2158 while (*offset < stop_offset) {
2159 status_t err = parseChunk(offset, depth + 1);
2160 if (err != OK) {
2161 return err;
2162 }
2163 }
2164
2165 if (*offset != stop_offset) {
2166 return ERROR_MALFORMED;
2167 }
2168 break;
2169 }
2170
2171 case FOURCC("stco"):
2172 case FOURCC("co64"):
2173 {
2174 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) {
2175 return ERROR_MALFORMED;
2176 }
2177
2178 status_t err =
2179 mLastTrack->sampleTable->setChunkOffsetParams(
2180 chunk_type, data_offset, chunk_data_size);
2181
2182 *offset += chunk_size;
2183
2184 if (err != OK) {
2185 return err;
2186 }
2187
2188 break;
2189 }
2190
2191 case FOURCC("stsc"):
2192 {
2193 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
2194 return ERROR_MALFORMED;
2195
2196 status_t err =
2197 mLastTrack->sampleTable->setSampleToChunkParams(
2198 data_offset, chunk_data_size);
2199
2200 *offset += chunk_size;
2201
2202 if (err != OK) {
2203 return err;
2204 }
2205
2206 break;
2207 }
2208
2209 case FOURCC("stsz"):
2210 case FOURCC("stz2"):
2211 {
2212 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL)) {
2213 return ERROR_MALFORMED;
2214 }
2215
2216 status_t err =
2217 mLastTrack->sampleTable->setSampleSizeParams(
2218 chunk_type, data_offset, chunk_data_size);
2219
2220 *offset += chunk_size;
2221
2222 if (err != OK) {
2223 return err;
2224 }
2225
2226 adjustRawDefaultFrameSize();
2227
2228 size_t max_size;
2229 err = mLastTrack->sampleTable->getMaxSampleSize(&max_size);
2230
2231 if (err != OK) {
2232 return err;
2233 }
2234
2235 if (max_size != 0) {
2236 // Assume that a given buffer only contains at most 10 chunks,
2237 // each chunk originally prefixed with a 2 byte length will
2238 // have a 4 byte header (0x00 0x00 0x00 0x01) after conversion,
2239 // and thus will grow by 2 bytes per chunk.
2240 if (max_size > SIZE_MAX - 10 * 2) {
2241 ALOGE("max sample size too big: %zu", max_size);
2242 return ERROR_MALFORMED;
2243 }
2244 AMediaFormat_setInt32(mLastTrack->meta,
2245 AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, max_size + 10 * 2);
2246 } else {
2247 // No size was specified. Pick a conservatively large size.
2248 uint32_t width, height;
2249 if (!AMediaFormat_getInt32(mLastTrack->meta,
2250 AMEDIAFORMAT_KEY_WIDTH, (int32_t*)&width) ||
2251 !AMediaFormat_getInt32(mLastTrack->meta,
2252 AMEDIAFORMAT_KEY_HEIGHT,(int32_t*) &height)) {
2253 ALOGE("No width or height, assuming worst case 1080p");
2254 width = 1920;
2255 height = 1080;
2256 } else {
2257 // A resolution was specified, check that it's not too big. The values below
2258 // were chosen so that the calculations below don't cause overflows, they're
2259 // not indicating that resolutions up to 32kx32k are actually supported.
2260 if (width > 32768 || height > 32768) {
2261 ALOGE("can't support %u x %u video", width, height);
2262 return ERROR_MALFORMED;
2263 }
2264 }
2265
2266 const char *mime;
2267 CHECK(AMediaFormat_getString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, &mime));
2268 if (!strncmp(mime, "audio/", 6)) {
2269 // for audio, use 128KB
2270 max_size = 1024 * 128;
2271 } else if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
2272 || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)
2273 || !strcmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
2274 // AVC & HEVC requires compression ratio of at least 2, and uses
2275 // macroblocks
2276 max_size = ((width + 15) / 16) * ((height + 15) / 16) * 192;
2277 } else {
2278 // For all other formats there is no minimum compression
2279 // ratio. Use compression ratio of 1.
2280 max_size = width * height * 3 / 2;
2281 }
2282 // HACK: allow 10% overhead
2283 // TODO: read sample size from traf atom for fragmented MPEG4.
2284 max_size += max_size / 10;
2285 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, max_size);
2286 }
2287
2288 // NOTE: setting another piece of metadata invalidates any pointers (such as the
2289 // mimetype) previously obtained, so don't cache them.
2290 const char *mime;
2291 CHECK(AMediaFormat_getString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, &mime));
2292 // Calculate average frame rate.
2293 if (!strncasecmp("video/", mime, 6)) {
2294 size_t nSamples = mLastTrack->sampleTable->countSamples();
2295 if (nSamples == 0) {
2296 int32_t trackId;
2297 if (AMediaFormat_getInt32(mLastTrack->meta,
2298 AMEDIAFORMAT_KEY_TRACK_ID, &trackId)) {
2299 for (size_t i = 0; i < mTrex.size(); i++) {
2300 Trex *t = &mTrex.editItemAt(i);
2301 if (t->track_ID == (uint32_t) trackId) {
2302 if (t->default_sample_duration > 0) {
2303 int32_t frameRate =
2304 mLastTrack->timescale / t->default_sample_duration;
2305 AMediaFormat_setInt32(mLastTrack->meta,
2306 AMEDIAFORMAT_KEY_FRAME_RATE, frameRate);
2307 }
2308 break;
2309 }
2310 }
2311 }
2312 } else {
2313 int64_t durationUs;
2314 if (AMediaFormat_getInt64(mLastTrack->meta,
2315 AMEDIAFORMAT_KEY_DURATION, &durationUs)) {
2316 if (durationUs > 0) {
2317 int32_t frameRate = (nSamples * 1000000LL +
2318 (durationUs >> 1)) / durationUs;
2319 AMediaFormat_setInt32(mLastTrack->meta,
2320 AMEDIAFORMAT_KEY_FRAME_RATE, frameRate);
2321 }
2322 }
2323 ALOGV("setting frame count %zu", nSamples);
2324 AMediaFormat_setInt32(mLastTrack->meta,
2325 AMEDIAFORMAT_KEY_FRAME_COUNT, nSamples);
2326 }
2327 }
2328
2329 break;
2330 }
2331
2332 case FOURCC("stts"):
2333 {
2334 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
2335 return ERROR_MALFORMED;
2336
2337 *offset += chunk_size;
2338
2339 if (depth >= 1 && mPath[depth - 1] != FOURCC("stbl")) {
2340 char chunk[5];
2341 MakeFourCCString(mPath[depth - 1], chunk);
2342 ALOGW("stts's parent box (%s) is not stbl, skip it.", chunk);
2343 break;
2344 }
2345
2346 status_t err =
2347 mLastTrack->sampleTable->setTimeToSampleParams(
2348 data_offset, chunk_data_size);
2349
2350 if (err != OK) {
2351 return err;
2352 }
2353
2354 break;
2355 }
2356
2357 case FOURCC("ctts"):
2358 {
2359 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
2360 return ERROR_MALFORMED;
2361
2362 *offset += chunk_size;
2363
2364 status_t err =
2365 mLastTrack->sampleTable->setCompositionTimeToSampleParams(
2366 data_offset, chunk_data_size);
2367
2368 if (err != OK) {
2369 return err;
2370 }
2371
2372 break;
2373 }
2374
2375 case FOURCC("stss"):
2376 {
2377 if ((mLastTrack == NULL) || (mLastTrack->sampleTable == NULL))
2378 return ERROR_MALFORMED;
2379
2380 *offset += chunk_size;
2381
2382 status_t err =
2383 mLastTrack->sampleTable->setSyncSampleParams(
2384 data_offset, chunk_data_size);
2385
2386 if (err != OK) {
2387 return err;
2388 }
2389
2390 break;
2391 }
2392
2393 // \xA9xyz
2394 case FOURCC("\251xyz"):
2395 {
2396 *offset += chunk_size;
2397
2398 // Best case the total data length inside "\xA9xyz" box would
2399 // be 9, for instance "\xA9xyz" + "\x00\x05\x15\xc7" + "+0+0/",
2400 // where "\x00\x05" is the text string length with value = 5,
2401 // "\0x15\xc7" is the language code = en, and "+0+0/" is a
2402 // location (string) value with longitude = 0 and latitude = 0.
2403 // Since some devices encountered in the wild omit the trailing
2404 // slash, we'll allow that.
2405 if (chunk_data_size < 8) { // 8 instead of 9 to allow for missing /
2406 return ERROR_MALFORMED;
2407 }
2408
2409 uint16_t len;
2410 if (!mDataSource->getUInt16(data_offset, &len)) {
2411 return ERROR_IO;
2412 }
2413
2414 // allow "+0+0" without trailing slash
2415 if (len < 4 || len > chunk_data_size - 4) {
2416 return ERROR_MALFORMED;
2417 }
2418 // The location string following the language code is formatted
2419 // according to ISO 6709:2008 (https://en.wikipedia.org/wiki/ISO_6709).
2420 // Allocate 2 extra bytes, in case we need to add a trailing slash,
2421 // and to add a terminating 0.
2422 std::unique_ptr<char[]> buffer(new (std::nothrow) char[len+2]());
2423 if (!buffer) {
2424 return NO_MEMORY;
2425 }
2426
2427 if (mDataSource->readAt(
2428 data_offset + 4, &buffer[0], len) < len) {
2429 return ERROR_IO;
2430 }
2431
2432 len = strlen(&buffer[0]);
2433 if (len < 4) {
2434 return ERROR_MALFORMED;
2435 }
2436 // Add a trailing slash if there wasn't one.
2437 if (buffer[len - 1] != '/') {
2438 buffer[len] = '/';
2439 }
2440 AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_LOCATION, &buffer[0]);
2441 break;
2442 }
2443
2444 case FOURCC("esds"):
2445 {
2446 *offset += chunk_size;
2447
2448 if (chunk_data_size < 4) {
2449 return ERROR_MALFORMED;
2450 }
2451
2452 auto tmp = heapbuffer<uint8_t>(chunk_data_size);
2453 uint8_t *buffer = tmp.get();
2454 if (buffer == NULL) {
2455 return -ENOMEM;
2456 }
2457
2458 if (mDataSource->readAt(
2459 data_offset, buffer, chunk_data_size) < chunk_data_size) {
2460 return ERROR_IO;
2461 }
2462
2463 if (U32_AT(buffer) != 0) {
2464 // Should be version 0, flags 0.
2465 return ERROR_MALFORMED;
2466 }
2467
2468 if (mLastTrack == NULL)
2469 return ERROR_MALFORMED;
2470
2471 AMediaFormat_setBuffer(mLastTrack->meta,
2472 AMEDIAFORMAT_KEY_ESDS, &buffer[4], chunk_data_size - 4);
2473
2474 if (mPath.size() >= 2
2475 && mPath[mPath.size() - 2] == FOURCC("mp4a")) {
2476 // Information from the ESDS must be relied on for proper
2477 // setup of sample rate and channel count for MPEG4 Audio.
2478 // The generic header appears to only contain generic
2479 // information...
2480
2481 status_t err = updateAudioTrackInfoFromESDS_MPEG4Audio(
2482 &buffer[4], chunk_data_size - 4);
2483
2484 if (err != OK) {
2485 return err;
2486 }
2487 }
2488 if (mPath.size() >= 2
2489 && mPath[mPath.size() - 2] == FOURCC("mp4v")) {
2490 // Check if the video is MPEG2
2491 ESDS esds(&buffer[4], chunk_data_size - 4);
2492
2493 uint8_t objectTypeIndication;
2494 if (esds.getObjectTypeIndication(&objectTypeIndication) == OK) {
2495 if (objectTypeIndication >= 0x60 && objectTypeIndication <= 0x65) {
2496 AMediaFormat_setString(mLastTrack->meta,
2497 AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_VIDEO_MPEG2);
2498 }
2499 }
2500 }
2501 break;
2502 }
2503
2504 case FOURCC("btrt"):
2505 {
2506 *offset += chunk_size;
2507 if (mLastTrack == NULL) {
2508 return ERROR_MALFORMED;
2509 }
2510
2511 uint8_t buffer[12];
2512 if (chunk_data_size != sizeof(buffer)) {
2513 return ERROR_MALFORMED;
2514 }
2515
2516 if (mDataSource->readAt(
2517 data_offset, buffer, chunk_data_size) < chunk_data_size) {
2518 return ERROR_IO;
2519 }
2520
2521 uint32_t maxBitrate = U32_AT(&buffer[4]);
2522 uint32_t avgBitrate = U32_AT(&buffer[8]);
2523 if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
2524 AMediaFormat_setInt32(mLastTrack->meta,
2525 AMEDIAFORMAT_KEY_MAX_BIT_RATE, (int32_t)maxBitrate);
2526 }
2527 if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
2528 AMediaFormat_setInt32(mLastTrack->meta,
2529 AMEDIAFORMAT_KEY_BIT_RATE, (int32_t)avgBitrate);
2530 }
2531 break;
2532 }
2533
2534 case FOURCC("dfLa"):
2535 {
2536 *offset += chunk_size;
2537
2538 // From https://github.com/xiph/flac/blob/master/doc/isoflac.txt
2539 // 4 for mediaType, 4 for blockType and BlockLen, 34 for metadata
2540 uint8_t flacInfo[4 + 4 + 34];
2541
2542 if (chunk_data_size != sizeof(flacInfo)) {
2543 return ERROR_MALFORMED;
2544 }
2545
2546 data_offset += 4;
2547 size_t flacOffset = 4;
2548 // Add flaC header mediaType to CSD
2549 strncpy((char *)flacInfo, "fLaC", 4);
2550
2551 ssize_t bytesToRead = sizeof(flacInfo) - flacOffset;
2552 if (mDataSource->readAt(
2553 data_offset, flacInfo + flacOffset, bytesToRead) < bytesToRead) {
2554 return ERROR_IO;
2555 }
2556
2557 data_offset += bytesToRead;
2558 AMediaFormat_setBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_0, flacInfo,
2559 sizeof(flacInfo));
2560 break;
2561 }
2562
2563 case FOURCC("avcC"):
2564 {
2565 *offset += chunk_size;
2566
2567 auto buffer = heapbuffer<uint8_t>(chunk_data_size);
2568
2569 if (buffer.get() == NULL) {
2570 ALOGE("b/28471206");
2571 return NO_MEMORY;
2572 }
2573
2574 if (mDataSource->readAt(
2575 data_offset, buffer.get(), chunk_data_size) < chunk_data_size) {
2576 return ERROR_IO;
2577 }
2578
2579 if (mLastTrack == NULL)
2580 return ERROR_MALFORMED;
2581
2582 AMediaFormat_setBuffer(mLastTrack->meta,
2583 AMEDIAFORMAT_KEY_CSD_AVC, buffer.get(), chunk_data_size);
2584
2585 break;
2586 }
2587 case FOURCC("hvcC"):
2588 {
2589 auto buffer = heapbuffer<uint8_t>(chunk_data_size);
2590
2591 if (buffer.get() == NULL) {
2592 ALOGE("b/28471206");
2593 return NO_MEMORY;
2594 }
2595
2596 if (mDataSource->readAt(
2597 data_offset, buffer.get(), chunk_data_size) < chunk_data_size) {
2598 return ERROR_IO;
2599 }
2600
2601 if (mLastTrack == NULL)
2602 return ERROR_MALFORMED;
2603
2604 AMediaFormat_setBuffer(mLastTrack->meta,
2605 AMEDIAFORMAT_KEY_CSD_HEVC, buffer.get(), chunk_data_size);
2606
2607 *offset += chunk_size;
2608 break;
2609 }
2610 case FOURCC("vpcC"):
2611 {
2612 if (mLastTrack == NULL) {
2613 return ERROR_MALFORMED;
2614 }
2615
2616 auto buffer = heapbuffer<uint8_t>(chunk_data_size);
2617
2618 if (buffer.get() == NULL) {
2619 ALOGE("b/28471206");
2620 return NO_MEMORY;
2621 }
2622
2623 if (mDataSource->readAt(data_offset, buffer.get(), chunk_data_size) < chunk_data_size) {
2624 return ERROR_IO;
2625 }
2626
2627 if (!MakeVP9CodecPrivateFromVpcC(mLastTrack->meta, buffer.get(), chunk_data_size)) {
2628 ALOGE("Failed to create VP9 CodecPrivate from vpcC.");
2629 return ERROR_MALFORMED;
2630 }
2631
2632 *offset += chunk_size;
2633 break;
2634 }
2635
2636 case FOURCC("apvC"):
2637 case FOURCC("av1C"):
2638 {
2639 if (!com::android::media::extractor::flags::extractor_mp4_enable_apv() &&
2640 chunk_type == FOURCC("apvC")) {
2641 ALOGV("APV support not enabled");
2642 *offset += chunk_size;
2643 break;
2644 }
2645
2646 auto buffer = heapbuffer<uint8_t>(chunk_data_size);
2647
2648 if (buffer.get() == NULL) {
2649 ALOGE("b/28471206");
2650 return NO_MEMORY;
2651 }
2652
2653 if (mDataSource->readAt(
2654 data_offset, buffer.get(), chunk_data_size) < chunk_data_size) {
2655 return ERROR_IO;
2656 }
2657
2658 if (mLastTrack == NULL)
2659 return ERROR_MALFORMED;
2660
2661 AMediaFormat_setBuffer(mLastTrack->meta,
2662 AMEDIAFORMAT_KEY_CSD_0, buffer.get(), chunk_data_size);
2663
2664 *offset += chunk_size;
2665 break;
2666 }
2667
2668 case FOURCC("dvcC"):
2669 case FOURCC("dvvC"):
2670 case FOURCC("dvwC"):
2671 {
2672 if (chunk_data_size != 24) {
2673 return ERROR_MALFORMED;
2674 }
2675
2676 auto buffer = heapbuffer<uint8_t>(chunk_data_size);
2677
2678 if (buffer.get() == NULL) {
2679 ALOGE("b/28471206");
2680 return NO_MEMORY;
2681 }
2682
2683 if (mDataSource->readAt(data_offset, buffer.get(), chunk_data_size) < chunk_data_size) {
2684 return ERROR_IO;
2685 }
2686
2687 if (mLastTrack == NULL)
2688 return ERROR_MALFORMED;
2689
2690 AMediaFormat_setBuffer(mLastTrack->meta, AMEDIAFORMAT_KEY_CSD_2,
2691 buffer.get(), chunk_data_size);
2692 AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME,
2693 MEDIA_MIMETYPE_VIDEO_DOLBY_VISION);
2694
2695 *offset += chunk_size;
2696 break;
2697 }
2698
2699 case FOURCC("d263"):
2700 {
2701 *offset += chunk_size;
2702 /*
2703 * d263 contains a fixed 7 bytes part:
2704 * vendor - 4 bytes
2705 * version - 1 byte
2706 * level - 1 byte
2707 * profile - 1 byte
2708 * optionally, "d263" box itself may contain a 16-byte
2709 * bit rate box (bitr)
2710 * average bit rate - 4 bytes
2711 * max bit rate - 4 bytes
2712 */
2713 char buffer[23];
2714 if (chunk_data_size != 7 &&
2715 chunk_data_size != 23) {
2716 ALOGE("Incorrect D263 box size %lld", (long long)chunk_data_size);
2717 return ERROR_MALFORMED;
2718 }
2719
2720 if (mDataSource->readAt(
2721 data_offset, buffer, chunk_data_size) < chunk_data_size) {
2722 return ERROR_IO;
2723 }
2724
2725 if (mLastTrack == NULL)
2726 return ERROR_MALFORMED;
2727
2728 AMediaFormat_setBuffer(mLastTrack->meta,
2729 AMEDIAFORMAT_KEY_D263, buffer, chunk_data_size);
2730
2731 break;
2732 }
2733
2734 case FOURCC("meta"):
2735 {
2736 off64_t stop_offset = *offset + chunk_size;
2737 *offset = data_offset;
2738 bool isParsingMetaKeys = underQTMetaPath(mPath, 2);
2739 if (!isParsingMetaKeys) {
2740 uint8_t buffer[4];
2741 if (chunk_data_size < (off64_t)sizeof(buffer)) {
2742 *offset = stop_offset;
2743 return ERROR_MALFORMED;
2744 }
2745
2746 if (mDataSource->readAt(
2747 data_offset, buffer, 4) < 4) {
2748 *offset = stop_offset;
2749 return ERROR_IO;
2750 }
2751
2752 if (U32_AT(buffer) != 0) {
2753 // Should be version 0, flags 0.
2754
2755 // If it's not, let's assume this is one of those
2756 // apparently malformed chunks that don't have flags
2757 // and completely different semantics than what's
2758 // in the MPEG4 specs and skip it.
2759 *offset = stop_offset;
2760 return OK;
2761 }
2762 *offset += sizeof(buffer);
2763 }
2764
2765 while (*offset < stop_offset) {
2766 status_t err = parseChunk(offset, depth + 1);
2767 if (err != OK) {
2768 return err;
2769 }
2770 }
2771
2772 if (*offset != stop_offset) {
2773 return ERROR_MALFORMED;
2774 }
2775 break;
2776 }
2777
2778 case FOURCC("iloc"):
2779 case FOURCC("iinf"):
2780 case FOURCC("iprp"):
2781 case FOURCC("pitm"):
2782 case FOURCC("idat"):
2783 case FOURCC("iref"):
2784 case FOURCC("ipro"):
2785 {
2786 if (mIsHeif || mIsAvif) {
2787 if (mItemTable == NULL) {
2788 mItemTable = new ItemTable(mDataSource, mIsHeif);
2789 }
2790 status_t err = mItemTable->parse(
2791 chunk_type, data_offset, chunk_data_size);
2792 if (err != OK) {
2793 return err;
2794 }
2795 }
2796 *offset += chunk_size;
2797 break;
2798 }
2799
2800 case FOURCC("mean"):
2801 case FOURCC("name"):
2802 case FOURCC("data"):
2803 {
2804 *offset += chunk_size;
2805
2806 if (mPath.size() == 6 && underMetaDataPath(mPath)) {
2807 status_t err = parseITunesMetaData(data_offset, chunk_data_size);
2808
2809 if (err != OK) {
2810 return err;
2811 }
2812 }
2813
2814 break;
2815 }
2816
2817 case FOURCC("mvhd"):
2818 {
2819 *offset += chunk_size;
2820
2821 if (depth != 1) {
2822 ALOGE("mvhd: depth %d", depth);
2823 return ERROR_MALFORMED;
2824 }
2825 if (chunk_data_size < 32) {
2826 return ERROR_MALFORMED;
2827 }
2828
2829 uint8_t header[32];
2830 if (mDataSource->readAt(
2831 data_offset, header, sizeof(header))
2832 < (ssize_t)sizeof(header)) {
2833 return ERROR_IO;
2834 }
2835
2836 uint64_t creationTime;
2837 uint64_t duration = 0;
2838 if (header[0] == 1) {
2839 creationTime = U64_AT(&header[4]);
2840 mHeaderTimescale = U32_AT(&header[20]);
2841 duration = U64_AT(&header[24]);
2842 if (duration == 0xffffffffffffffff) {
2843 duration = 0;
2844 }
2845 } else if (header[0] != 0) {
2846 return ERROR_MALFORMED;
2847 } else {
2848 creationTime = U32_AT(&header[4]);
2849 mHeaderTimescale = U32_AT(&header[12]);
2850 uint32_t d32 = U32_AT(&header[16]);
2851 if (d32 == 0xffffffff) {
2852 d32 = 0;
2853 }
2854 duration = d32;
2855 }
2856 if (duration != 0 && mHeaderTimescale != 0 && duration < UINT64_MAX / 1000000) {
2857 AMediaFormat_setInt64(mFileMetaData,
2858 AMEDIAFORMAT_KEY_DURATION, duration * 1000000 / mHeaderTimescale);
2859 }
2860
2861 String8 s;
2862 if (convertTimeToDate(creationTime, &s)) {
2863 AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_DATE, s.c_str());
2864 }
2865
2866 break;
2867 }
2868
2869 case FOURCC("mehd"):
2870 {
2871 *offset += chunk_size;
2872
2873 if (chunk_data_size < 8) {
2874 return ERROR_MALFORMED;
2875 }
2876
2877 uint8_t flags[4];
2878 if (mDataSource->readAt(
2879 data_offset, flags, sizeof(flags))
2880 < (ssize_t)sizeof(flags)) {
2881 return ERROR_IO;
2882 }
2883
2884 uint64_t duration = 0;
2885 if (flags[0] == 1) {
2886 // 64 bit
2887 if (chunk_data_size < 12) {
2888 return ERROR_MALFORMED;
2889 }
2890 mDataSource->getUInt64(data_offset + 4, &duration);
2891 if (duration == 0xffffffffffffffff) {
2892 duration = 0;
2893 }
2894 } else if (flags[0] == 0) {
2895 // 32 bit
2896 uint32_t d32;
2897 mDataSource->getUInt32(data_offset + 4, &d32);
2898 if (d32 == 0xffffffff) {
2899 d32 = 0;
2900 }
2901 duration = d32;
2902 } else {
2903 return ERROR_MALFORMED;
2904 }
2905
2906 if (duration != 0 && mHeaderTimescale != 0) {
2907 AMediaFormat_setInt64(mFileMetaData,
2908 AMEDIAFORMAT_KEY_DURATION, duration * 1000000 / mHeaderTimescale);
2909 }
2910
2911 break;
2912 }
2913
2914 case FOURCC("mdat"):
2915 {
2916 mMdatFound = true;
2917
2918 *offset += chunk_size;
2919 break;
2920 }
2921
2922 case FOURCC("hdlr"):
2923 {
2924 *offset += chunk_size;
2925
2926 if (underQTMetaPath(mPath, 3)) {
2927 break;
2928 }
2929
2930 uint32_t buffer;
2931 if (mDataSource->readAt(
2932 data_offset + 8, &buffer, 4) < 4) {
2933 return ERROR_IO;
2934 }
2935
2936 uint32_t type = ntohl(buffer);
2937 // For the 3GPP file format, the handler-type within the 'hdlr' box
2938 // shall be 'text'. We also want to support 'sbtl' handler type
2939 // for a practical reason as various MPEG4 containers use it.
2940 if (type == FOURCC("text") || type == FOURCC("sbtl")) {
2941 if (mLastTrack != NULL) {
2942 AMediaFormat_setString(mLastTrack->meta,
2943 AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_TEXT_3GPP);
2944 }
2945 }
2946
2947 break;
2948 }
2949
2950 case FOURCC("keys"):
2951 {
2952 *offset += chunk_size;
2953
2954 if (underQTMetaPath(mPath, 3)) {
2955 status_t err = parseQTMetaKey(data_offset, chunk_data_size);
2956 if (err != OK) {
2957 return err;
2958 }
2959 }
2960 break;
2961 }
2962
2963 case FOURCC("trex"):
2964 {
2965 *offset += chunk_size;
2966
2967 if (chunk_data_size < 24) {
2968 return ERROR_IO;
2969 }
2970 Trex trex;
2971 if (!mDataSource->getUInt32(data_offset + 4, &trex.track_ID) ||
2972 !mDataSource->getUInt32(data_offset + 8, &trex.default_sample_description_index) ||
2973 !mDataSource->getUInt32(data_offset + 12, &trex.default_sample_duration) ||
2974 !mDataSource->getUInt32(data_offset + 16, &trex.default_sample_size) ||
2975 !mDataSource->getUInt32(data_offset + 20, &trex.default_sample_flags)) {
2976 return ERROR_IO;
2977 }
2978 mTrex.add(trex);
2979 break;
2980 }
2981
2982 case FOURCC("tx3g"):
2983 {
2984 if (mLastTrack == NULL)
2985 return ERROR_MALFORMED;
2986
2987 // complain about ridiculous chunks
2988 if (chunk_size > kMaxAtomSize) {
2989 return ERROR_MALFORMED;
2990 }
2991
2992 // complain about empty atoms
2993 if (chunk_data_size <= 0) {
2994 ALOGE("b/124330204");
2995 android_errorWriteLog(0x534e4554, "124330204");
2996 return ERROR_MALFORMED;
2997 }
2998
2999 // should fill buffer based on "data_offset" and "chunk_data_size"
3000 // instead of *offset and chunk_size;
3001 // but we've been feeding the extra data to consumers for multiple releases and
3002 // if those apps are compensating for it, we'd break them with such a change
3003 //
3004
3005 if (mLastTrack->mTx3gBuffer == NULL) {
3006 mLastTrack->mTx3gSize = 0;
3007 mLastTrack->mTx3gFilled = 0;
3008 }
3009 if (mLastTrack->mTx3gSize - mLastTrack->mTx3gFilled < chunk_size) {
3010 size_t growth = kTx3gGrowth;
3011 if (growth < chunk_size) {
3012 growth = chunk_size;
3013 }
3014 // although this disallows 2 tx3g atoms of nearly kMaxAtomSize...
3015 if ((uint64_t) mLastTrack->mTx3gSize + growth > kMaxAtomSize) {
3016 ALOGE("b/124330204 - too much space");
3017 android_errorWriteLog(0x534e4554, "124330204");
3018 return ERROR_MALFORMED;
3019 }
3020 uint8_t *updated = (uint8_t *)realloc(mLastTrack->mTx3gBuffer,
3021 mLastTrack->mTx3gSize + growth);
3022 if (updated == NULL) {
3023 return ERROR_MALFORMED;
3024 }
3025 mLastTrack->mTx3gBuffer = updated;
3026 mLastTrack->mTx3gSize += growth;
3027 }
3028
3029 if ((size_t)(mDataSource->readAt(*offset,
3030 mLastTrack->mTx3gBuffer + mLastTrack->mTx3gFilled,
3031 chunk_size))
3032 < chunk_size) {
3033
3034 // advance read pointer so we don't end up reading this again
3035 *offset += chunk_size;
3036 return ERROR_IO;
3037 }
3038
3039 mLastTrack->mTx3gFilled += chunk_size;
3040 *offset += chunk_size;
3041 break;
3042 }
3043
3044 case FOURCC("covr"):
3045 {
3046 *offset += chunk_size;
3047
3048 ALOGV("chunk_data_size = %" PRId64 " and data_offset = %" PRId64,
3049 chunk_data_size, data_offset);
3050
3051 if (chunk_data_size < 0 || static_cast<uint64_t>(chunk_data_size) >= SIZE_MAX - 1) {
3052 return ERROR_MALFORMED;
3053 }
3054 auto buffer = heapbuffer<uint8_t>(chunk_data_size);
3055 if (buffer.get() == NULL) {
3056 ALOGE("b/28471206");
3057 return NO_MEMORY;
3058 }
3059 if (mDataSource->readAt(
3060 data_offset, buffer.get(), chunk_data_size) != (ssize_t)chunk_data_size) {
3061 return ERROR_IO;
3062 }
3063 const int kSkipBytesOfDataBox = 16;
3064 if (chunk_data_size <= kSkipBytesOfDataBox) {
3065 return ERROR_MALFORMED;
3066 }
3067
3068 AMediaFormat_setBuffer(mFileMetaData,
3069 AMEDIAFORMAT_KEY_ALBUMART,
3070 buffer.get() + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
3071
3072 break;
3073 }
3074
3075 case FOURCC("colr"):
3076 {
3077 *offset += chunk_size;
3078 // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd')
3079 // ignore otherwise
3080 if (depth >= 2 && mPath[depth - 2] == FOURCC("stsd")) {
3081 status_t err = parseColorInfo(data_offset, chunk_data_size);
3082 if (err != OK) {
3083 return err;
3084 }
3085 }
3086
3087 break;
3088 }
3089
3090 case FOURCC("pasp"):
3091 {
3092 *offset += chunk_size;
3093 // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd')
3094 // ignore otherwise
3095 if (depth >= 2 && mPath[depth - 2] == FOURCC("stsd")) {
3096 status_t err = parsePaspBox(data_offset, chunk_data_size);
3097 if (err != OK) {
3098 return err;
3099 }
3100 }
3101
3102 break;
3103 }
3104
3105 case FOURCC("titl"):
3106 case FOURCC("perf"):
3107 case FOURCC("auth"):
3108 case FOURCC("gnre"):
3109 case FOURCC("albm"):
3110 case FOURCC("yrrc"):
3111 {
3112 *offset += chunk_size;
3113
3114 status_t err = parse3GPPMetaData(data_offset, chunk_data_size, depth);
3115
3116 if (err != OK) {
3117 return err;
3118 }
3119
3120 break;
3121 }
3122
3123 case FOURCC("ID32"):
3124 {
3125 *offset += chunk_size;
3126
3127 if (chunk_data_size < 6) {
3128 return ERROR_MALFORMED;
3129 }
3130
3131 parseID3v2MetaData(data_offset + 6, chunk_data_size - 6);
3132
3133 break;
3134 }
3135
3136 case FOURCC("----"):
3137 {
3138 mLastCommentMean.clear();
3139 mLastCommentName.clear();
3140 mLastCommentData.clear();
3141 *offset += chunk_size;
3142 break;
3143 }
3144
3145 case FOURCC("sidx"):
3146 {
3147 status_t err = parseSegmentIndex(data_offset, chunk_data_size);
3148 if (err != OK) {
3149 return err;
3150 }
3151 *offset += chunk_size;
3152 return UNKNOWN_ERROR; // stop parsing after sidx
3153 }
3154
3155 case FOURCC("ac-3"):
3156 {
3157 *offset += chunk_size;
3158 // bypass ac-3 if parse fail
3159 if (parseAC3SpecificBox(data_offset) != OK) {
3160 if (mLastTrack != NULL) {
3161 ALOGW("Fail to parse ac-3");
3162 mLastTrack->skipTrack = true;
3163 }
3164 }
3165 return OK;
3166 }
3167
3168 case FOURCC("ec-3"):
3169 {
3170 *offset += chunk_size;
3171 // bypass ec-3 if parse fail
3172 if (parseEAC3SpecificBox(data_offset) != OK) {
3173 if (mLastTrack != NULL) {
3174 ALOGW("Fail to parse ec-3");
3175 mLastTrack->skipTrack = true;
3176 }
3177 }
3178 return OK;
3179 }
3180
3181 case FOURCC("ac-4"):
3182 {
3183 *offset += chunk_size;
3184 // bypass ac-4 if parse fail
3185 if (parseAC4SpecificBox(data_offset) != OK) {
3186 if (mLastTrack != NULL) {
3187 ALOGW("Fail to parse ac-4");
3188 mLastTrack->skipTrack = true;
3189 }
3190 }
3191 return OK;
3192 }
3193
3194 case FOURCC("ftyp"):
3195 {
3196 if (chunk_data_size < 8 || depth != 0) {
3197 return ERROR_MALFORMED;
3198 }
3199
3200 off64_t stop_offset = *offset + chunk_size;
3201 uint32_t numCompatibleBrands = (chunk_data_size - 8) / 4;
3202 std::set<uint32_t> brandSet;
3203 for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
3204 if (i == 1) {
3205 // Skip this index, it refers to the minorVersion,
3206 // not a brand.
3207 continue;
3208 }
3209
3210 uint32_t brand;
3211 if (mDataSource->readAt(data_offset + 4 * i, &brand, 4) < 4) {
3212 return ERROR_MALFORMED;
3213 }
3214
3215 brand = ntohl(brand);
3216 brandSet.insert(brand);
3217 }
3218
3219 if (brandSet.count(FOURCC("qt ")) > 0) {
3220 mIsQT = true;
3221 } else {
3222 if (brandSet.count(FOURCC("mif1")) > 0
3223 && brandSet.count(FOURCC("heic")) > 0) {
3224 ALOGV("identified HEIF image");
3225
3226 mIsHeif = true;
3227 brandSet.erase(FOURCC("mif1"));
3228 brandSet.erase(FOURCC("heic"));
3229 } else if (brandSet.count(FOURCC("avif")) > 0 ||
3230 brandSet.count(FOURCC("avis")) > 0) {
3231 ALOGV("identified AVIF image");
3232 mIsAvif = true;
3233 brandSet.erase(FOURCC("avif"));
3234 brandSet.erase(FOURCC("avis"));
3235 }
3236
3237 if (!brandSet.empty()) {
3238 // This means that the file should have moov box.
3239 // It could be any iso files (mp4, heifs, etc.)
3240 mHasMoovBox = true;
3241 if (mIsHeif || mIsAvif) {
3242 ALOGV("identified %s image with other tracks", mIsHeif ? "HEIF" : "AVIF");
3243 }
3244 }
3245 }
3246
3247 *offset = stop_offset;
3248
3249 break;
3250 }
3251
3252 default:
3253 {
3254 // check if we're parsing 'ilst' for meta keys
3255 // if so, treat type as a number (key-id).
3256 if (underQTMetaPath(mPath, 3)) {
3257 status_t err = parseQTMetaVal(chunk_type, data_offset, chunk_data_size);
3258 if (err != OK) {
3259 return err;
3260 }
3261 }
3262
3263 *offset += chunk_size;
3264 break;
3265 }
3266 }
3267
3268 return OK;
3269 }
3270
parseChannelCountSampleRate(off64_t * offset,uint16_t * channelCount,uint16_t * sampleRate)3271 status_t MPEG4Extractor::parseChannelCountSampleRate(
3272 off64_t *offset, uint16_t *channelCount, uint16_t *sampleRate) {
3273 // skip 16 bytes:
3274 // + 6-byte reserved,
3275 // + 2-byte data reference index,
3276 // + 8-byte reserved
3277 *offset += 16;
3278 if (!mDataSource->getUInt16(*offset, channelCount)) {
3279 ALOGE("MPEG4Extractor: error while reading sample entry box: cannot read channel count");
3280 return ERROR_MALFORMED;
3281 }
3282 // skip 8 bytes:
3283 // + 2-byte channelCount,
3284 // + 2-byte sample size,
3285 // + 4-byte reserved
3286 *offset += 8;
3287 if (!mDataSource->getUInt16(*offset, sampleRate)) {
3288 ALOGE("MPEG4Extractor: error while reading sample entry box: cannot read sample rate");
3289 return ERROR_MALFORMED;
3290 }
3291 // skip 4 bytes:
3292 // + 2-byte sampleRate,
3293 // + 2-byte reserved
3294 *offset += 4;
3295 return OK;
3296 }
3297
parseAC4SpecificBox(off64_t offset)3298 status_t MPEG4Extractor::parseAC4SpecificBox(off64_t offset) {
3299 if (mLastTrack == NULL) {
3300 return ERROR_MALFORMED;
3301 }
3302
3303 uint16_t sampleRate, channelCount;
3304 status_t status;
3305 if ((status = parseChannelCountSampleRate(&offset, &channelCount, &sampleRate)) != OK) {
3306 return status;
3307 }
3308 uint32_t size;
3309 // + 4-byte size
3310 // + 4-byte type
3311 // + 3-byte payload
3312 const uint32_t kAC4MinimumBoxSize = 4 + 4 + 3;
3313 if (!mDataSource->getUInt32(offset, &size) || size < kAC4MinimumBoxSize) {
3314 ALOGE("MPEG4Extractor: error while reading ac-4 block: cannot read specific box size");
3315 return ERROR_MALFORMED;
3316 }
3317
3318 // + 4-byte size
3319 offset += 4;
3320 uint32_t type;
3321 if (!mDataSource->getUInt32(offset, &type) || type != FOURCC("dac4")) {
3322 ALOGE("MPEG4Extractor: error while reading ac-4 specific block: header not dac4");
3323 return ERROR_MALFORMED;
3324 }
3325
3326 // + 4-byte type
3327 offset += 4;
3328 const uint32_t kAC4SpecificBoxPayloadSize = 1176;
3329 uint8_t chunk[kAC4SpecificBoxPayloadSize];
3330 ssize_t dsiSize = size - 8; // size of box - size and type fields
3331 if (dsiSize >= (ssize_t)kAC4SpecificBoxPayloadSize ||
3332 mDataSource->readAt(offset, chunk, dsiSize) != dsiSize) {
3333 ALOGE("MPEG4Extractor: error while reading ac-4 specific block: bitstream fields");
3334 return ERROR_MALFORMED;
3335 }
3336 // + size-byte payload
3337 offset += dsiSize;
3338 ABitReader br(chunk, dsiSize);
3339 AC4DSIParser parser(br);
3340 if (!parser.parse()){
3341 ALOGE("MPEG4Extractor: error while parsing ac-4 specific block");
3342 return ERROR_MALFORMED;
3343 }
3344
3345 AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AC4);
3346 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channelCount);
3347 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
3348
3349 AudioPresentationCollection presentations;
3350 // translate the AC4 presentation information to audio presentations for this track
3351 AC4DSIParser::AC4Presentations ac4Presentations = parser.getPresentations();
3352 if (!ac4Presentations.empty()) {
3353 for (const auto& ac4Presentation : ac4Presentations) {
3354 auto& presentation = ac4Presentation.second;
3355 if (!presentation.mEnabled) {
3356 continue;
3357 }
3358 AudioPresentationV1 ap;
3359 ap.mPresentationId = presentation.mGroupIndex;
3360 ap.mProgramId = presentation.mProgramID;
3361 ap.mLanguage = presentation.mLanguage;
3362 if (presentation.mPreVirtualized) {
3363 ap.mMasteringIndication = MASTERED_FOR_HEADPHONE;
3364 } else {
3365 switch (presentation.mChannelMode) {
3366 case AC4Parser::AC4Presentation::kChannelMode_Mono:
3367 case AC4Parser::AC4Presentation::kChannelMode_Stereo:
3368 ap.mMasteringIndication = MASTERED_FOR_STEREO;
3369 break;
3370 case AC4Parser::AC4Presentation::kChannelMode_3_0:
3371 case AC4Parser::AC4Presentation::kChannelMode_5_0:
3372 case AC4Parser::AC4Presentation::kChannelMode_5_1:
3373 case AC4Parser::AC4Presentation::kChannelMode_7_0_34:
3374 case AC4Parser::AC4Presentation::kChannelMode_7_1_34:
3375 case AC4Parser::AC4Presentation::kChannelMode_7_0_52:
3376 case AC4Parser::AC4Presentation::kChannelMode_7_1_52:
3377 ap.mMasteringIndication = MASTERED_FOR_SURROUND;
3378 break;
3379 case AC4Parser::AC4Presentation::kChannelMode_7_0_322:
3380 case AC4Parser::AC4Presentation::kChannelMode_7_1_322:
3381 case AC4Parser::AC4Presentation::kChannelMode_7_0_4:
3382 case AC4Parser::AC4Presentation::kChannelMode_7_1_4:
3383 case AC4Parser::AC4Presentation::kChannelMode_9_0_4:
3384 case AC4Parser::AC4Presentation::kChannelMode_9_1_4:
3385 case AC4Parser::AC4Presentation::kChannelMode_22_2:
3386 ap.mMasteringIndication = MASTERED_FOR_3D;
3387 break;
3388 default:
3389 ALOGE("Invalid channel mode in AC4 presentation");
3390 return ERROR_MALFORMED;
3391 }
3392 }
3393
3394 ap.mAudioDescriptionAvailable = (presentation.mContentClassifier ==
3395 AC4Parser::AC4Presentation::kVisuallyImpaired);
3396 ap.mSpokenSubtitlesAvailable = (presentation.mContentClassifier ==
3397 AC4Parser::AC4Presentation::kVoiceOver);
3398 ap.mDialogueEnhancementAvailable = presentation.mHasDialogEnhancements;
3399 if (!ap.mLanguage.empty()) {
3400 ap.mLabels.emplace(ap.mLanguage, presentation.mDescription);
3401 }
3402 presentations.push_back(std::move(ap));
3403 }
3404 }
3405
3406 if (presentations.empty()) {
3407 // Clear audio presentation info in metadata.
3408 AMediaFormat_setBuffer(
3409 mLastTrack->meta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO, nullptr, 0);
3410 } else {
3411 std::ostringstream outStream(std::ios::out);
3412 serializeAudioPresentations(presentations, &outStream);
3413 AMediaFormat_setBuffer(
3414 mLastTrack->meta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO,
3415 outStream.str().data(), outStream.str().size());
3416 }
3417 return OK;
3418 }
3419
parseEAC3SpecificBox(off64_t offset)3420 status_t MPEG4Extractor::parseEAC3SpecificBox(off64_t offset) {
3421 if (mLastTrack == NULL) {
3422 return ERROR_MALFORMED;
3423 }
3424
3425 uint16_t sampleRate, channels;
3426 status_t status;
3427 if ((status = parseChannelCountSampleRate(&offset, &channels, &sampleRate)) != OK) {
3428 return status;
3429 }
3430 uint32_t size;
3431 // + 4-byte size
3432 // + 4-byte type
3433 // + 3-byte payload
3434 const uint32_t kEAC3SpecificBoxMinSize = 11;
3435 // 13 + 3 + (8 * (2 + 5 + 5 + 3 + 1 + 3 + 4 + (14 * 9 + 1))) bits == 152 bytes theoretical max
3436 // calculated from the required bits read below as well as the maximum number of independent
3437 // and dependant sub streams you can have
3438 const uint32_t kEAC3SpecificBoxMaxSize = 152;
3439 if (!mDataSource->getUInt32(offset, &size) ||
3440 size < kEAC3SpecificBoxMinSize ||
3441 size > kEAC3SpecificBoxMaxSize) {
3442 ALOGE("MPEG4Extractor: error while reading eac-3 block: cannot read specific box size");
3443 return ERROR_MALFORMED;
3444 }
3445
3446 offset += 4;
3447 uint32_t type;
3448 if (!mDataSource->getUInt32(offset, &type) || type != FOURCC("dec3")) {
3449 ALOGE("MPEG4Extractor: error while reading eac-3 specific block: header not dec3");
3450 return ERROR_MALFORMED;
3451 }
3452
3453 offset += 4;
3454 uint8_t* chunk = new (std::nothrow) uint8_t[size];
3455 if (chunk == NULL) {
3456 return ERROR_MALFORMED;
3457 }
3458
3459 if (mDataSource->readAt(offset, chunk, size) != (ssize_t)size) {
3460 ALOGE("MPEG4Extractor: error while reading eac-3 specific block: bitstream fields");
3461 delete[] chunk;
3462 return ERROR_MALFORMED;
3463 }
3464
3465 ABitReader br(chunk, size);
3466 static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
3467 static const unsigned sampleRateTable[] = {48000, 44100, 32000};
3468
3469 if (br.numBitsLeft() < 16) {
3470 delete[] chunk;
3471 return ERROR_MALFORMED;
3472 }
3473 unsigned data_rate = br.getBits(13);
3474 ALOGV("EAC3 data rate = %d", data_rate);
3475
3476 unsigned num_ind_sub = br.getBits(3) + 1;
3477 ALOGV("EAC3 independant substreams = %d", num_ind_sub);
3478 if (br.numBitsLeft() < (num_ind_sub * 23)) {
3479 delete[] chunk;
3480 return ERROR_MALFORMED;
3481 }
3482
3483 unsigned channelCount = 0;
3484 for (unsigned i = 0; i < num_ind_sub; i++) {
3485 unsigned fscod = br.getBits(2);
3486 if (fscod == 3) {
3487 ALOGE("Incorrect fscod (3) in EAC3 header");
3488 delete[] chunk;
3489 return ERROR_MALFORMED;
3490 }
3491 unsigned boxSampleRate = sampleRateTable[fscod];
3492 if (boxSampleRate != sampleRate) {
3493 ALOGE("sample rate mismatch: boxSampleRate = %d, sampleRate = %d",
3494 boxSampleRate, sampleRate);
3495 delete[] chunk;
3496 return ERROR_MALFORMED;
3497 }
3498
3499 unsigned bsid = br.getBits(5);
3500 if (bsid == 9 || bsid == 10) {
3501 ALOGW("EAC3 stream (bsid=%d) may be silenced by the decoder", bsid);
3502 } else if (bsid > 16) {
3503 ALOGE("EAC3 stream (bsid=%d) is not compatible with ETSI TS 102 366 v1.4.1", bsid);
3504 delete[] chunk;
3505 return ERROR_MALFORMED;
3506 }
3507
3508 // skip
3509 br.skipBits(2);
3510 unsigned bsmod = br.getBits(3);
3511 unsigned acmod = br.getBits(3);
3512 unsigned lfeon = br.getBits(1);
3513 // we currently only support the first stream
3514 if (i == 0)
3515 channelCount = channelCountTable[acmod] + lfeon;
3516 ALOGV("bsmod = %d, acmod = %d, lfeon = %d", bsmod, acmod, lfeon);
3517
3518 br.skipBits(3);
3519 unsigned num_dep_sub = br.getBits(4);
3520 ALOGV("EAC3 dependant substreams = %d", num_dep_sub);
3521 if (num_dep_sub != 0) {
3522 if (br.numBitsLeft() < 9) {
3523 delete[] chunk;
3524 return ERROR_MALFORMED;
3525 }
3526 static const char* chan_loc_tbl[] = { "Lc/Rc","Lrs/Rrs","Cs","Ts","Lsd/Rsd",
3527 "Lw/Rw","Lvh/Rvh","Cvh","Lfe2" };
3528 unsigned chan_loc = br.getBits(9);
3529 unsigned mask = 1;
3530 for (unsigned j = 0; j < 9; j++, mask <<= 1) {
3531 if ((chan_loc & mask) != 0) {
3532 // we currently only support the first stream
3533 if (i == 0) {
3534 channelCount++;
3535 // these are 2 channels in the mask
3536 if (j == 0 || j == 1 || j == 4 || j == 5 || j == 6) {
3537 channelCount++;
3538 }
3539 }
3540 ALOGV(" %s", chan_loc_tbl[j]);
3541 }
3542 }
3543 } else {
3544 if (br.numBitsLeft() == 0) {
3545 delete[] chunk;
3546 return ERROR_MALFORMED;
3547 }
3548 br.skipBits(1);
3549 }
3550 }
3551
3552 if (br.numBitsLeft() != 0) {
3553 if (br.numBitsLeft() < 8) {
3554 delete[] chunk;
3555 return ERROR_MALFORMED;
3556 }
3557 unsigned mask = br.getBits(8);
3558 for (unsigned i = 0; i < 8; i++) {
3559 if (((0x1 << i) & mask) == 0)
3560 continue;
3561
3562 if (br.numBitsLeft() < 8) {
3563 delete[] chunk;
3564 return ERROR_MALFORMED;
3565 }
3566 switch (i) {
3567 case 0: {
3568 unsigned complexity = br.getBits(8);
3569 ALOGV("Found a JOC stream with complexity = %d", complexity);
3570 }break;
3571 default: {
3572 br.skipBits(8);
3573 }break;
3574 }
3575 }
3576 }
3577 AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_EAC3);
3578 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channelCount);
3579 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
3580
3581 delete[] chunk;
3582 return OK;
3583 }
3584
parseAC3SpecificBox(off64_t offset)3585 status_t MPEG4Extractor::parseAC3SpecificBox(off64_t offset) {
3586 if (mLastTrack == NULL) {
3587 return ERROR_MALFORMED;
3588 }
3589
3590 uint16_t sampleRate, channels;
3591 status_t status;
3592 if ((status = parseChannelCountSampleRate(&offset, &channels, &sampleRate)) != OK) {
3593 return status;
3594 }
3595 uint32_t size;
3596 // + 4-byte size
3597 // + 4-byte type
3598 // + 3-byte payload
3599 const uint32_t kAC3SpecificBoxSize = 11;
3600 if (!mDataSource->getUInt32(offset, &size) || size < kAC3SpecificBoxSize) {
3601 ALOGE("MPEG4Extractor: error while reading ac-3 block: cannot read specific box size");
3602 return ERROR_MALFORMED;
3603 }
3604
3605 offset += 4;
3606 uint32_t type;
3607 if (!mDataSource->getUInt32(offset, &type) || type != FOURCC("dac3")) {
3608 ALOGE("MPEG4Extractor: error while reading ac-3 specific block: header not dac3");
3609 return ERROR_MALFORMED;
3610 }
3611
3612 offset += 4;
3613 const uint32_t kAC3SpecificBoxPayloadSize = 3;
3614 uint8_t chunk[kAC3SpecificBoxPayloadSize];
3615 if (mDataSource->readAt(offset, chunk, sizeof(chunk)) != sizeof(chunk)) {
3616 ALOGE("MPEG4Extractor: error while reading ac-3 specific block: bitstream fields");
3617 return ERROR_MALFORMED;
3618 }
3619
3620 ABitReader br(chunk, sizeof(chunk));
3621 static const unsigned channelCountTable[] = {2, 1, 2, 3, 3, 4, 4, 5};
3622 static const unsigned sampleRateTable[] = {48000, 44100, 32000};
3623
3624 unsigned fscod = br.getBits(2);
3625 if (fscod == 3) {
3626 ALOGE("Incorrect fscod (3) in AC3 header");
3627 return ERROR_MALFORMED;
3628 }
3629 unsigned boxSampleRate = sampleRateTable[fscod];
3630 if (boxSampleRate != sampleRate) {
3631 ALOGE("sample rate mismatch: boxSampleRate = %d, sampleRate = %d",
3632 boxSampleRate, sampleRate);
3633 return ERROR_MALFORMED;
3634 }
3635
3636 unsigned bsid = br.getBits(5);
3637 if (bsid > 8) {
3638 ALOGW("Incorrect bsid in AC3 header. Possibly E-AC-3?");
3639 return ERROR_MALFORMED;
3640 }
3641
3642 // skip
3643 br.skipBits(3); // bsmod
3644
3645 unsigned acmod = br.getBits(3);
3646 unsigned lfeon = br.getBits(1);
3647 unsigned channelCount = channelCountTable[acmod] + lfeon;
3648
3649 AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AC3);
3650 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, channelCount);
3651 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
3652 return OK;
3653 }
3654
parseALACSampleEntry(off64_t * offset)3655 status_t MPEG4Extractor::parseALACSampleEntry(off64_t *offset) {
3656 // See 'external/alac/ALACMagicCookieDescription.txt for the detail'.
3657 // Store ALAC magic cookie (decoder needs it).
3658 uint8_t alacInfo[12];
3659 off64_t data_offset = *offset;
3660
3661 if (mDataSource->readAt(
3662 data_offset, alacInfo, sizeof(alacInfo)) < (ssize_t)sizeof(alacInfo)) {
3663 return ERROR_IO;
3664 }
3665 uint32_t size = U32_AT(&alacInfo[0]);
3666 if ((size != ALAC_SPECIFIC_INFO_SIZE) ||
3667 (U32_AT(&alacInfo[4]) != FOURCC("alac")) ||
3668 (U32_AT(&alacInfo[8]) != 0)) {
3669 ALOGV("Size:%u, U32_AT(&alacInfo[4]):%u, U32_AT(&alacInfo[8]):%u",
3670 size, U32_AT(&alacInfo[4]), U32_AT(&alacInfo[8]));
3671 return ERROR_MALFORMED;
3672 }
3673 data_offset += sizeof(alacInfo);
3674 uint8_t cookie[size - sizeof(alacInfo)];
3675 if (mDataSource->readAt(
3676 data_offset, cookie, sizeof(cookie)) < (ssize_t)sizeof(cookie)) {
3677 return ERROR_IO;
3678 }
3679
3680 uint8_t bitsPerSample = cookie[5];
3681 AMediaFormat_setInt32(mLastTrack->meta,
3682 AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, bitsPerSample);
3683 AMediaFormat_setInt32(mLastTrack->meta,
3684 AMEDIAFORMAT_KEY_CHANNEL_COUNT, cookie[9]);
3685 AMediaFormat_setInt32(mLastTrack->meta,
3686 AMEDIAFORMAT_KEY_SAMPLE_RATE, U32_AT(&cookie[20]));
3687 AMediaFormat_setBuffer(mLastTrack->meta,
3688 AMEDIAFORMAT_KEY_CSD_0, cookie, sizeof(cookie));
3689 data_offset += sizeof(cookie);
3690 *offset = data_offset;
3691 return OK;
3692 }
3693
parseSegmentIndex(off64_t offset,size_t size)3694 status_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) {
3695 ALOGV("MPEG4Extractor::parseSegmentIndex");
3696
3697 if (size < 12) {
3698 return -EINVAL;
3699 }
3700
3701 uint32_t flags;
3702 if (!mDataSource->getUInt32(offset, &flags)) {
3703 return ERROR_MALFORMED;
3704 }
3705
3706 uint32_t version = flags >> 24;
3707 flags &= 0xffffff;
3708
3709 ALOGV("sidx version %d", version);
3710
3711 uint32_t referenceId;
3712 if (!mDataSource->getUInt32(offset + 4, &referenceId)) {
3713 return ERROR_MALFORMED;
3714 }
3715
3716 uint32_t timeScale;
3717 if (!mDataSource->getUInt32(offset + 8, &timeScale)) {
3718 return ERROR_MALFORMED;
3719 }
3720 ALOGV("sidx refid/timescale: %d/%d", referenceId, timeScale);
3721 if (timeScale == 0)
3722 return ERROR_MALFORMED;
3723
3724 uint64_t earliestPresentationTime;
3725 uint64_t firstOffset;
3726
3727 offset += 12;
3728 size -= 12;
3729
3730 if (version == 0) {
3731 if (size < 8) {
3732 return -EINVAL;
3733 }
3734 uint32_t tmp;
3735 if (!mDataSource->getUInt32(offset, &tmp)) {
3736 return ERROR_MALFORMED;
3737 }
3738 earliestPresentationTime = tmp;
3739 if (!mDataSource->getUInt32(offset + 4, &tmp)) {
3740 return ERROR_MALFORMED;
3741 }
3742 firstOffset = tmp;
3743 offset += 8;
3744 size -= 8;
3745 } else {
3746 if (size < 16) {
3747 return -EINVAL;
3748 }
3749 if (!mDataSource->getUInt64(offset, &earliestPresentationTime)) {
3750 return ERROR_MALFORMED;
3751 }
3752 if (!mDataSource->getUInt64(offset + 8, &firstOffset)) {
3753 return ERROR_MALFORMED;
3754 }
3755 offset += 16;
3756 size -= 16;
3757 }
3758 ALOGV("sidx pres/off: %" PRIu64 "/%" PRIu64, earliestPresentationTime, firstOffset);
3759
3760 if (size < 4) {
3761 return -EINVAL;
3762 }
3763
3764 uint16_t referenceCount;
3765 if (!mDataSource->getUInt16(offset + 2, &referenceCount)) {
3766 return ERROR_MALFORMED;
3767 }
3768 offset += 4;
3769 size -= 4;
3770 ALOGV("refcount: %d", referenceCount);
3771
3772 if (size < referenceCount * 12) {
3773 return -EINVAL;
3774 }
3775
3776 uint64_t total_duration = 0;
3777 for (unsigned int i = 0; i < referenceCount; i++) {
3778 uint32_t d1, d2, d3;
3779
3780 if (!mDataSource->getUInt32(offset, &d1) || // size
3781 !mDataSource->getUInt32(offset + 4, &d2) || // duration
3782 !mDataSource->getUInt32(offset + 8, &d3)) { // flags
3783 return ERROR_MALFORMED;
3784 }
3785
3786 if (d1 & 0x80000000) {
3787 ALOGW("sub-sidx boxes not supported yet");
3788 }
3789 bool sap = d3 & 0x80000000;
3790 uint32_t saptype = (d3 >> 28) & 7;
3791 if (!sap || (saptype != 1 && saptype != 2)) {
3792 // type 1 and 2 are sync samples
3793 ALOGW("not a stream access point, or unsupported type: %08x", d3);
3794 }
3795 total_duration += d2;
3796 offset += 12;
3797 ALOGV(" item %d, %08x %08x %08x", i, d1, d2, d3);
3798 SidxEntry se;
3799 se.mSize = d1 & 0x7fffffff;
3800 se.mDurationUs = 1000000LL * d2 / timeScale;
3801 mSidxEntries.add(se);
3802 }
3803
3804 uint64_t sidxDuration = total_duration * 1000000 / timeScale;
3805
3806 if (mLastTrack == NULL)
3807 return ERROR_MALFORMED;
3808
3809 int64_t metaDuration;
3810 if (!AMediaFormat_getInt64(mLastTrack->meta,
3811 AMEDIAFORMAT_KEY_DURATION, &metaDuration) || metaDuration == 0) {
3812 AMediaFormat_setInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION, sidxDuration);
3813 }
3814 return OK;
3815 }
3816
parseQTMetaKey(off64_t offset,size_t size)3817 status_t MPEG4Extractor::parseQTMetaKey(off64_t offset, size_t size) {
3818 if (size < 8) {
3819 return ERROR_MALFORMED;
3820 }
3821
3822 uint32_t count;
3823 if (!mDataSource->getUInt32(offset + 4, &count)) {
3824 return ERROR_MALFORMED;
3825 }
3826
3827 if (mMetaKeyMap.size() > 0) {
3828 ALOGW("'keys' atom seen again, discarding existing entries");
3829 mMetaKeyMap.clear();
3830 }
3831
3832 off64_t keyOffset = offset + 8;
3833 off64_t stopOffset = offset + size;
3834 for (size_t i = 1; i <= count; i++) {
3835 if (keyOffset + 8 > stopOffset) {
3836 return ERROR_MALFORMED;
3837 }
3838
3839 uint32_t keySize;
3840 if (!mDataSource->getUInt32(keyOffset, &keySize)
3841 || keySize < 8
3842 || keyOffset + keySize > stopOffset) {
3843 return ERROR_MALFORMED;
3844 }
3845
3846 uint32_t type;
3847 if (!mDataSource->getUInt32(keyOffset + 4, &type)
3848 || type != FOURCC("mdta")) {
3849 return ERROR_MALFORMED;
3850 }
3851
3852 keySize -= 8;
3853 keyOffset += 8;
3854
3855 auto keyData = heapbuffer<uint8_t>(keySize);
3856 if (keyData.get() == NULL) {
3857 return ERROR_MALFORMED;
3858 }
3859 if (mDataSource->readAt(
3860 keyOffset, keyData.get(), keySize) < (ssize_t) keySize) {
3861 return ERROR_MALFORMED;
3862 }
3863
3864 AString key((const char *)keyData.get(), keySize);
3865 mMetaKeyMap.add(i, key);
3866
3867 keyOffset += keySize;
3868 }
3869 return OK;
3870 }
3871
parseQTMetaVal(int32_t keyId,off64_t offset,size_t size)3872 status_t MPEG4Extractor::parseQTMetaVal(
3873 int32_t keyId, off64_t offset, size_t size) {
3874 ssize_t index = mMetaKeyMap.indexOfKey(keyId);
3875 if (index < 0) {
3876 // corresponding key is not present, ignore
3877 return ERROR_MALFORMED;
3878 }
3879
3880 if (size <= 16) {
3881 return ERROR_MALFORMED;
3882 }
3883 uint32_t dataSize;
3884 if (!mDataSource->getUInt32(offset, &dataSize)
3885 || dataSize > size || dataSize <= 16) {
3886 return ERROR_MALFORMED;
3887 }
3888 uint32_t atomFourCC;
3889 if (!mDataSource->getUInt32(offset + 4, &atomFourCC)
3890 || atomFourCC != FOURCC("data")) {
3891 return ERROR_MALFORMED;
3892 }
3893 uint32_t dataType;
3894 if (!mDataSource->getUInt32(offset + 8, &dataType)
3895 || ((dataType & 0xff000000) != 0)) {
3896 // not well-known type
3897 return ERROR_MALFORMED;
3898 }
3899
3900 dataSize -= 16;
3901 offset += 16;
3902
3903 if (dataType == 23 && dataSize >= 4) {
3904 // BE Float32
3905 uint32_t val;
3906 if (!mDataSource->getUInt32(offset, &val)) {
3907 return ERROR_MALFORMED;
3908 }
3909 if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.capture.fps")) {
3910 AMediaFormat_setFloat(mFileMetaData, AMEDIAFORMAT_KEY_CAPTURE_RATE, *(float *)&val);
3911 }
3912 } else if (dataType == 67 && dataSize >= 4) {
3913 // BE signed int32
3914 uint32_t val;
3915 if (!mDataSource->getUInt32(offset, &val)) {
3916 return ERROR_MALFORMED;
3917 }
3918 if (!strcasecmp(mMetaKeyMap[index].c_str(), "com.android.video.temporal_layers_count")) {
3919 AMediaFormat_setInt32(mFileMetaData,
3920 AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT, val);
3921 }
3922 } else {
3923 // add more keys if needed
3924 ALOGV("ignoring key: type %d, size %d", dataType, dataSize);
3925 }
3926
3927 return OK;
3928 }
3929
parseTrackHeader(off64_t data_offset,off64_t data_size)3930 status_t MPEG4Extractor::parseTrackHeader(
3931 off64_t data_offset, off64_t data_size) {
3932 if (data_size < 4) {
3933 return ERROR_MALFORMED;
3934 }
3935
3936 uint8_t version;
3937 if (mDataSource->readAt(data_offset, &version, 1) < 1) {
3938 return ERROR_IO;
3939 }
3940
3941 size_t dynSize = (version == 1) ? 36 : 24;
3942
3943 uint8_t buffer[36 + 60];
3944
3945 if (data_size != (off64_t)dynSize + 60) {
3946 return ERROR_MALFORMED;
3947 }
3948
3949 if (mDataSource->readAt(
3950 data_offset, buffer, data_size) < (ssize_t)data_size) {
3951 return ERROR_IO;
3952 }
3953
3954 int32_t id;
3955 int64_t duration;
3956
3957 if (version == 1) {
3958 // we can get ctime value from U64_AT(&buffer[4])
3959 // we can get mtime value from U64_AT(&buffer[12])
3960 id = U32_AT(&buffer[20]);
3961 duration = U64_AT(&buffer[28]);
3962 } else if (version == 0) {
3963 // we can get ctime value from U32_AT(&buffer[4])
3964 // we can get mtime value from U32_AT(&buffer[8])
3965 id = U32_AT(&buffer[12]);
3966 duration = U32_AT(&buffer[20]);
3967 } else {
3968 return ERROR_UNSUPPORTED;
3969 }
3970
3971 if (mLastTrack == NULL)
3972 return ERROR_MALFORMED;
3973
3974 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_TRACK_ID, id);
3975 if (duration != 0 && mHeaderTimescale != 0) {
3976 long double durationUs = ((long double)duration * 1000000) / mHeaderTimescale;
3977 if (durationUs < 0 || durationUs > INT64_MAX) {
3978 ALOGE("cannot represent %lld * 1000000 / %lld in 64 bits",
3979 (long long) duration, (long long) mHeaderTimescale);
3980 return ERROR_MALFORMED;
3981 }
3982 AMediaFormat_setInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION, durationUs);
3983 }
3984
3985 size_t matrixOffset = dynSize + 16;
3986 int32_t a00 = U32_AT(&buffer[matrixOffset]);
3987 int32_t a01 = U32_AT(&buffer[matrixOffset + 4]);
3988 int32_t a10 = U32_AT(&buffer[matrixOffset + 12]);
3989 int32_t a11 = U32_AT(&buffer[matrixOffset + 16]);
3990
3991 #if 0
3992 int32_t dx = U32_AT(&buffer[matrixOffset + 8]);
3993 int32_t dy = U32_AT(&buffer[matrixOffset + 20]);
3994
3995 ALOGI("x' = %.2f * x + %.2f * y + %.2f",
3996 a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f);
3997 ALOGI("y' = %.2f * x + %.2f * y + %.2f",
3998 a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f);
3999 #endif
4000
4001 uint32_t rotationDegrees;
4002
4003 static const int32_t kFixedOne = 0x10000;
4004 if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) {
4005 // Identity, no rotation
4006 rotationDegrees = 0;
4007 } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) {
4008 rotationDegrees = 90;
4009 } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) {
4010 rotationDegrees = 270;
4011 } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) {
4012 rotationDegrees = 180;
4013 } else {
4014 ALOGW("We only support 0,90,180,270 degree rotation matrices");
4015 rotationDegrees = 0;
4016 }
4017
4018 if (rotationDegrees != 0) {
4019 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_ROTATION, rotationDegrees);
4020 }
4021
4022 // Handle presentation display size, which could be different
4023 // from the image size indicated by AMEDIAFORMAT_KEY_WIDTH and AMEDIAFORMAT_KEY_HEIGHT.
4024 uint32_t width = U32_AT(&buffer[dynSize + 52]);
4025 uint32_t height = U32_AT(&buffer[dynSize + 56]);
4026 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_DISPLAY_WIDTH, width >> 16);
4027 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_DISPLAY_HEIGHT, height >> 16);
4028
4029 return OK;
4030 }
4031
parseITunesMetaData(off64_t offset,size_t size)4032 status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
4033 if (size == 0) {
4034 return OK;
4035 }
4036
4037 if (size < 4 || size == SIZE_MAX) {
4038 return ERROR_MALFORMED;
4039 }
4040
4041 uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
4042 if (buffer == NULL) {
4043 return ERROR_MALFORMED;
4044 }
4045 if (mDataSource->readAt(
4046 offset, buffer, size) != (ssize_t)size) {
4047 delete[] buffer;
4048 buffer = NULL;
4049
4050 return ERROR_IO;
4051 }
4052
4053 uint32_t flags = U32_AT(buffer);
4054
4055 const char *metadataKey = nullptr;
4056 char chunk[5];
4057 MakeFourCCString(mPath[4], chunk);
4058 ALOGV("meta: %s @ %lld", chunk, (long long)offset);
4059 switch ((int32_t)mPath[4]) {
4060 case FOURCC("\251alb"):
4061 {
4062 metadataKey = AMEDIAFORMAT_KEY_ALBUM;
4063 break;
4064 }
4065 case FOURCC("\251ART"):
4066 {
4067 metadataKey = AMEDIAFORMAT_KEY_ARTIST;
4068 break;
4069 }
4070 case FOURCC("aART"):
4071 {
4072 metadataKey = AMEDIAFORMAT_KEY_ALBUMARTIST;
4073 break;
4074 }
4075 case FOURCC("\251day"):
4076 {
4077 metadataKey = AMEDIAFORMAT_KEY_YEAR;
4078 break;
4079 }
4080 case FOURCC("\251nam"):
4081 {
4082 metadataKey = AMEDIAFORMAT_KEY_TITLE;
4083 break;
4084 }
4085 case FOURCC("\251wrt"):
4086 {
4087 // various open source taggers agree that the "©wrt" tag is for composer, not writer
4088 metadataKey = AMEDIAFORMAT_KEY_COMPOSER;
4089 break;
4090 }
4091 case FOURCC("covr"):
4092 {
4093 metadataKey = AMEDIAFORMAT_KEY_ALBUMART;
4094 break;
4095 }
4096 case FOURCC("gnre"):
4097 case FOURCC("\251gen"):
4098 {
4099 metadataKey = AMEDIAFORMAT_KEY_GENRE;
4100 break;
4101 }
4102 case FOURCC("cpil"):
4103 {
4104 if (size == 9 && flags == 21) {
4105 char tmp[16];
4106 sprintf(tmp, "%d",
4107 (int)buffer[size - 1]);
4108
4109 AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_COMPILATION, tmp);
4110 }
4111 break;
4112 }
4113 case FOURCC("trkn"):
4114 {
4115 if (size == 16 && flags == 0) {
4116 char tmp[16];
4117 uint16_t* pTrack = (uint16_t*)&buffer[10];
4118 uint16_t* pTotalTracks = (uint16_t*)&buffer[12];
4119 sprintf(tmp, "%d/%d", ntohs(*pTrack), ntohs(*pTotalTracks));
4120
4121 AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_CDTRACKNUMBER, tmp);
4122 }
4123 break;
4124 }
4125 case FOURCC("disk"):
4126 {
4127 if ((size == 14 || size == 16) && flags == 0) {
4128 char tmp[16];
4129 uint16_t* pDisc = (uint16_t*)&buffer[10];
4130 uint16_t* pTotalDiscs = (uint16_t*)&buffer[12];
4131 sprintf(tmp, "%d/%d", ntohs(*pDisc), ntohs(*pTotalDiscs));
4132
4133 AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_DISCNUMBER, tmp);
4134 }
4135 break;
4136 }
4137 case FOURCC("----"):
4138 {
4139 buffer[size] = '\0';
4140 switch (mPath[5]) {
4141 case FOURCC("mean"):
4142 mLastCommentMean = ((const char *)buffer + 4);
4143 break;
4144 case FOURCC("name"):
4145 mLastCommentName = ((const char *)buffer + 4);
4146 break;
4147 case FOURCC("data"):
4148 if (size < 8) {
4149 delete[] buffer;
4150 buffer = NULL;
4151 ALOGE("b/24346430");
4152 return ERROR_MALFORMED;
4153 }
4154 mLastCommentData = ((const char *)buffer + 8);
4155 break;
4156 }
4157
4158 // Once we have a set of mean/name/data info, go ahead and process
4159 // it to see if its something we are interested in. Whether or not
4160 // were are interested in the specific tag, make sure to clear out
4161 // the set so we can be ready to process another tuple should one
4162 // show up later in the file.
4163 if ((mLastCommentMean.length() != 0) &&
4164 (mLastCommentName.length() != 0) &&
4165 (mLastCommentData.length() != 0)) {
4166
4167 if (mLastCommentMean == "com.apple.iTunes"
4168 && mLastCommentName == "iTunSMPB") {
4169 int32_t delay, padding;
4170 if (sscanf(mLastCommentData,
4171 " %*x %x %x %*x", &delay, &padding) == 2) {
4172 if (mLastTrack == NULL) {
4173 delete[] buffer;
4174 return ERROR_MALFORMED;
4175 }
4176
4177 AMediaFormat_setInt32(mLastTrack->meta,
4178 AMEDIAFORMAT_KEY_ENCODER_DELAY, delay);
4179 AMediaFormat_setInt32(mLastTrack->meta,
4180 AMEDIAFORMAT_KEY_ENCODER_PADDING, padding);
4181 }
4182 }
4183
4184 mLastCommentMean.clear();
4185 mLastCommentName.clear();
4186 mLastCommentData.clear();
4187 }
4188 break;
4189 }
4190
4191 default:
4192 break;
4193 }
4194
4195 void *tmpData;
4196 size_t tmpDataSize;
4197 const char *s;
4198 if (size >= 8 && metadataKey &&
4199 !AMediaFormat_getBuffer(mFileMetaData, metadataKey, &tmpData, &tmpDataSize) &&
4200 !AMediaFormat_getString(mFileMetaData, metadataKey, &s)) {
4201 if (!strcmp(metadataKey, "albumart")) {
4202 AMediaFormat_setBuffer(mFileMetaData, metadataKey,
4203 buffer + 8, size - 8);
4204 } else if (!strcmp(metadataKey, AMEDIAFORMAT_KEY_GENRE)) {
4205 if (flags == 0) {
4206 // uint8_t genre code, iTunes genre codes are
4207 // the standard id3 codes, except they start
4208 // at 1 instead of 0 (e.g. Pop is 14, not 13)
4209 // We use standard id3 numbering, so subtract 1.
4210 int genrecode = (int)buffer[size - 1];
4211 genrecode--;
4212 if (genrecode < 0) {
4213 genrecode = 255; // reserved for 'unknown genre'
4214 }
4215 char genre[10];
4216 sprintf(genre, "%d", genrecode);
4217
4218 AMediaFormat_setString(mFileMetaData, metadataKey, genre);
4219 } else if (flags == 1) {
4220 // custom genre string
4221 buffer[size] = '\0';
4222
4223 AMediaFormat_setString(mFileMetaData,
4224 metadataKey, (const char *)buffer + 8);
4225 }
4226 } else {
4227 buffer[size] = '\0';
4228
4229 AMediaFormat_setString(mFileMetaData,
4230 metadataKey, (const char *)buffer + 8);
4231 }
4232 }
4233
4234 delete[] buffer;
4235 buffer = NULL;
4236
4237 return OK;
4238 }
4239
parseColorInfo(off64_t offset,size_t size)4240 status_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) {
4241 if (size < 4 || size == SIZE_MAX || mLastTrack == NULL) {
4242 return ERROR_MALFORMED;
4243 }
4244
4245 uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
4246 if (buffer == NULL) {
4247 return ERROR_MALFORMED;
4248 }
4249 if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) {
4250 delete[] buffer;
4251 buffer = NULL;
4252
4253 return ERROR_IO;
4254 }
4255
4256 int32_t type = U32_AT(&buffer[0]);
4257 if ((type == FOURCC("nclx") && size >= 11)
4258 || (type == FOURCC("nclc") && size >= 10)) {
4259 // only store the first color specification
4260 int32_t existingColor;
4261 if (!AMediaFormat_getInt32(mLastTrack->meta,
4262 AMEDIAFORMAT_KEY_COLOR_RANGE, &existingColor)) {
4263 int32_t primaries = U16_AT(&buffer[4]);
4264 int32_t isotransfer = U16_AT(&buffer[6]);
4265 int32_t coeffs = U16_AT(&buffer[8]);
4266 bool fullRange = (type == FOURCC("nclx")) && (buffer[10] & 128);
4267
4268 int32_t range = 0;
4269 int32_t standard = 0;
4270 int32_t transfer = 0;
4271 ColorUtils::convertIsoColorAspectsToPlatformAspects(
4272 primaries, isotransfer, coeffs, fullRange,
4273 &range, &standard, &transfer);
4274
4275 if (range != 0) {
4276 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_COLOR_RANGE, range);
4277 }
4278 if (standard != 0) {
4279 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_COLOR_STANDARD, standard);
4280 }
4281 if (transfer != 0) {
4282 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_COLOR_TRANSFER, transfer);
4283 }
4284 }
4285 }
4286
4287 delete[] buffer;
4288 buffer = NULL;
4289
4290 return OK;
4291 }
4292
parsePaspBox(off64_t offset,size_t size)4293 status_t MPEG4Extractor::parsePaspBox(off64_t offset, size_t size) {
4294 if (size < 8 || size == SIZE_MAX || mLastTrack == NULL) {
4295 return ERROR_MALFORMED;
4296 }
4297
4298 uint32_t data[2]; // hSpacing, vSpacing
4299 if (mDataSource->readAt(offset, data, 8) < 8) {
4300 return ERROR_IO;
4301 }
4302 uint32_t hSpacing = ntohl(data[0]);
4303 uint32_t vSpacing = ntohl(data[1]);
4304
4305 if (hSpacing != 0 && vSpacing != 0) {
4306 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAR_WIDTH, hSpacing);
4307 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAR_HEIGHT, vSpacing);
4308 }
4309
4310 return OK;
4311 }
4312
parse3GPPMetaData(off64_t offset,size_t size,int depth)4313 status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) {
4314 if (size < 4 || size == SIZE_MAX) {
4315 return ERROR_MALFORMED;
4316 }
4317
4318 uint8_t *buffer = new (std::nothrow) uint8_t[size + 1];
4319 if (buffer == NULL) {
4320 return ERROR_MALFORMED;
4321 }
4322 if (mDataSource->readAt(
4323 offset, buffer, size) != (ssize_t)size) {
4324 delete[] buffer;
4325 buffer = NULL;
4326
4327 return ERROR_IO;
4328 }
4329
4330 const char *metadataKey = nullptr;
4331 switch (mPath[depth]) {
4332 case FOURCC("titl"):
4333 {
4334 metadataKey = "title";
4335 break;
4336 }
4337 case FOURCC("perf"):
4338 {
4339 metadataKey = "artist";
4340 break;
4341 }
4342 case FOURCC("auth"):
4343 {
4344 metadataKey = "writer";
4345 break;
4346 }
4347 case FOURCC("gnre"):
4348 {
4349 metadataKey = "genre";
4350 break;
4351 }
4352 case FOURCC("albm"):
4353 {
4354 if (buffer[size - 1] != '\0') {
4355 char tmp[4];
4356 sprintf(tmp, "%u", buffer[size - 1]);
4357
4358 AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_CDTRACKNUMBER, tmp);
4359 }
4360
4361 metadataKey = "album";
4362 break;
4363 }
4364 case FOURCC("yrrc"):
4365 {
4366 if (size < 6) {
4367 delete[] buffer;
4368 buffer = NULL;
4369 ALOGE("b/62133227");
4370 android_errorWriteLog(0x534e4554, "62133227");
4371 return ERROR_MALFORMED;
4372 }
4373 char tmp[5];
4374 uint16_t year = U16_AT(&buffer[4]);
4375
4376 if (year < 10000) {
4377 sprintf(tmp, "%u", year);
4378
4379 AMediaFormat_setString(mFileMetaData, AMEDIAFORMAT_KEY_YEAR, tmp);
4380 }
4381 break;
4382 }
4383
4384 default:
4385 break;
4386 }
4387
4388 if (metadataKey) {
4389 bool isUTF8 = true; // Common case
4390 char16_t *framedata = NULL;
4391 int len16 = 0; // Number of UTF-16 characters
4392
4393 // smallest possible valid UTF-16 string w BOM: 0xfe 0xff 0x00 0x00
4394 if (size < 6) {
4395 delete[] buffer;
4396 buffer = NULL;
4397 return ERROR_MALFORMED;
4398 }
4399
4400 if (size - 6 >= 4) {
4401 len16 = ((size - 6) / 2) - 1; // don't include 0x0000 terminator
4402 framedata = (char16_t *)(buffer + 6);
4403 if (0xfffe == *framedata) {
4404 // endianness marker (BOM) doesn't match host endianness
4405 for (int i = 0; i < len16; i++) {
4406 framedata[i] = bswap_16(framedata[i]);
4407 }
4408 // BOM is now swapped to 0xfeff, we will execute next block too
4409 }
4410
4411 if (0xfeff == *framedata) {
4412 // Remove the BOM
4413 framedata++;
4414 len16--;
4415 isUTF8 = false;
4416 }
4417 // else normal non-zero-length UTF-8 string
4418 // we can't handle UTF-16 without BOM as there is no other
4419 // indication of encoding.
4420 }
4421
4422 if (isUTF8) {
4423 buffer[size] = 0;
4424 AMediaFormat_setString(mFileMetaData, metadataKey, (const char *)buffer + 6);
4425 } else {
4426 // Convert from UTF-16 string to UTF-8 string.
4427 String8 tmpUTF8str(framedata, len16);
4428 AMediaFormat_setString(mFileMetaData, metadataKey, tmpUTF8str.c_str());
4429 }
4430 }
4431
4432 delete[] buffer;
4433 buffer = NULL;
4434
4435 return OK;
4436 }
4437
parseID3v2MetaData(off64_t offset,uint64_t size)4438 void MPEG4Extractor::parseID3v2MetaData(off64_t offset, uint64_t size) {
4439 uint8_t *buffer = new (std::nothrow) uint8_t[size];
4440 if (buffer == NULL) {
4441 return;
4442 }
4443 if (mDataSource->readAt(offset, buffer, size) != (ssize_t)size) {
4444 delete[] buffer;
4445 buffer = NULL;
4446 return;
4447 }
4448
4449 ID3 id3(buffer, size, true /* ignorev1 */);
4450 delete[] buffer;
4451
4452 if (id3.isValid()) {
4453 struct Map {
4454 const char *key;
4455 const char *tag1;
4456 const char *tag2;
4457 };
4458 static const Map kMap[] = {
4459 { AMEDIAFORMAT_KEY_ALBUM, "TALB", "TAL" },
4460 { AMEDIAFORMAT_KEY_ARTIST, "TPE1", "TP1" },
4461 { AMEDIAFORMAT_KEY_ALBUMARTIST, "TPE2", "TP2" },
4462 { AMEDIAFORMAT_KEY_COMPOSER, "TCOM", "TCM" },
4463 { AMEDIAFORMAT_KEY_GENRE, "TCON", "TCO" },
4464 { AMEDIAFORMAT_KEY_TITLE, "TIT2", "TT2" },
4465 { AMEDIAFORMAT_KEY_YEAR, "TYE", "TYER" },
4466 { AMEDIAFORMAT_KEY_AUTHOR, "TXT", "TEXT" },
4467 { AMEDIAFORMAT_KEY_CDTRACKNUMBER, "TRK", "TRCK" },
4468 { AMEDIAFORMAT_KEY_DISCNUMBER, "TPA", "TPOS" },
4469 { AMEDIAFORMAT_KEY_COMPILATION, "TCP", "TCMP" },
4470 };
4471 static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
4472
4473 for (size_t i = 0; i < kNumMapEntries; ++i) {
4474 const char *ss;
4475 if (!AMediaFormat_getString(mFileMetaData, kMap[i].key, &ss)) {
4476 ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
4477 if (it->done()) {
4478 delete it;
4479 it = new ID3::Iterator(id3, kMap[i].tag2);
4480 }
4481
4482 if (it->done()) {
4483 delete it;
4484 continue;
4485 }
4486
4487 String8 s;
4488 it->getString(&s);
4489 delete it;
4490
4491 AMediaFormat_setString(mFileMetaData, kMap[i].key, s);
4492 }
4493 }
4494
4495 size_t dataSize;
4496 String8 mime;
4497 const void *data = id3.getAlbumArt(&dataSize, &mime);
4498
4499 if (data) {
4500 AMediaFormat_setBuffer(mFileMetaData, AMEDIAFORMAT_KEY_ALBUMART, data, dataSize);
4501 }
4502 }
4503 }
4504
getTrack(size_t index)4505 MediaTrackHelper *MPEG4Extractor::getTrack(size_t index) {
4506 status_t err;
4507 if ((err = readMetaData()) != OK) {
4508 return NULL;
4509 }
4510
4511 Track *track = mFirstTrack;
4512 while (index > 0) {
4513 if (track == NULL) {
4514 return NULL;
4515 }
4516
4517 track = track->next;
4518 --index;
4519 }
4520
4521 if (track == NULL) {
4522 return NULL;
4523 }
4524
4525
4526 Trex *trex = NULL;
4527 int32_t trackId;
4528 if (AMediaFormat_getInt32(track->meta, AMEDIAFORMAT_KEY_TRACK_ID, &trackId)) {
4529 for (size_t i = 0; i < mTrex.size(); i++) {
4530 Trex *t = &mTrex.editItemAt(i);
4531 if (t->track_ID == (uint32_t) trackId) {
4532 trex = t;
4533 break;
4534 }
4535 }
4536 } else {
4537 ALOGE("b/21657957");
4538 return NULL;
4539 }
4540
4541 ALOGV("getTrack called, pssh: %zu", mPssh.size());
4542
4543 const char *mime;
4544 if (!AMediaFormat_getString(track->meta, AMEDIAFORMAT_KEY_MIME, &mime)) {
4545 return NULL;
4546 }
4547 sp<ItemTable> itemTable;
4548 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
4549 void *data;
4550 size_t size;
4551 if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size)) {
4552 return NULL;
4553 }
4554
4555 const uint8_t *ptr = (const uint8_t *)data;
4556
4557 if (size < 7 || ptr[0] != 1) { // configurationVersion == 1
4558 return NULL;
4559 }
4560 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)
4561 || !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)) {
4562 void *data;
4563 size_t size;
4564 if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_HEVC, &data, &size)) {
4565 return NULL;
4566 }
4567
4568 const uint8_t *ptr = (const uint8_t *)data;
4569
4570 if (size < 22 || ptr[0] != 1) { // configurationVersion == 1
4571 return NULL;
4572 }
4573 if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC)) {
4574 itemTable = mItemTable;
4575 }
4576 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
4577 void *data;
4578 size_t size;
4579 if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_2, &data, &size)
4580 || size != 24) {
4581 return NULL;
4582 }
4583
4584 const uint8_t *ptr = (const uint8_t *)data;
4585 // dv_major.dv_minor Should be 1.0 or 2.1
4586 if ((ptr[0] != 1 || ptr[1] != 0) && (ptr[0] != 2 || ptr[1] != 1)) {
4587 return NULL;
4588 }
4589 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AV1)
4590 || !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_AVIF)) {
4591 void *data;
4592 size_t size;
4593 if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)) {
4594 return NULL;
4595 }
4596
4597 const uint8_t *ptr = (const uint8_t *)data;
4598
4599 if (size < 4 || ptr[0] != 0x81) { // configurationVersion == 1
4600 return NULL;
4601 }
4602 if (!strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_AVIF)) {
4603 itemTable = mItemTable;
4604 }
4605 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_VP9)) {
4606 void *data;
4607 size_t size;
4608 if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)) {
4609 return NULL;
4610 }
4611
4612 const uint8_t *ptr = (const uint8_t *)data;
4613
4614 if (size < 5 || ptr[0] != 0x01) { // configurationVersion == 1
4615 return NULL;
4616 }
4617 }
4618
4619 ALOGV("track->elst_shift_start_ticks :%" PRIu64, track->elst_shift_start_ticks);
4620
4621 uint64_t elst_initial_empty_edit_ticks = 0;
4622 if (mHeaderTimescale != 0) {
4623 // Convert empty_edit_ticks from movie timescale to media timescale.
4624 uint64_t elst_initial_empty_edit_ticks_mul = 0, elst_initial_empty_edit_ticks_add = 0;
4625 if (__builtin_mul_overflow(track->elst_initial_empty_edit_ticks, track->timescale,
4626 &elst_initial_empty_edit_ticks_mul) ||
4627 __builtin_add_overflow(elst_initial_empty_edit_ticks_mul, (mHeaderTimescale / 2),
4628 &elst_initial_empty_edit_ticks_add)) {
4629 ALOGE("track->elst_initial_empty_edit_ticks overflow");
4630 return nullptr;
4631 }
4632 elst_initial_empty_edit_ticks = elst_initial_empty_edit_ticks_add / mHeaderTimescale;
4633 }
4634 ALOGV("elst_initial_empty_edit_ticks in MediaTimeScale :%" PRIu64,
4635 elst_initial_empty_edit_ticks);
4636
4637 MPEG4Source* source =
4638 new MPEG4Source(track->meta, mDataSource, track->timescale, track->sampleTable,
4639 mSidxEntries, trex, mMoofOffset, itemTable,
4640 track->elst_shift_start_ticks, elst_initial_empty_edit_ticks);
4641 if (source->init() != OK) {
4642 delete source;
4643 return NULL;
4644 }
4645 return source;
4646 }
4647
4648 // static
verifyTrack(Track * track)4649 status_t MPEG4Extractor::verifyTrack(Track *track) {
4650 const char *mime;
4651 CHECK(AMediaFormat_getString(track->meta, AMEDIAFORMAT_KEY_MIME, &mime));
4652
4653 void *data;
4654 size_t size;
4655 if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
4656 if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size)) {
4657 return ERROR_MALFORMED;
4658 }
4659 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
4660 if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_HEVC, &data, &size)) {
4661 return ERROR_MALFORMED;
4662 }
4663 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION)) {
4664 if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_2, &data, &size)) {
4665 return ERROR_MALFORMED;
4666 }
4667 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AV1)) {
4668 if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)) {
4669 return ERROR_MALFORMED;
4670 }
4671 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_VP9)) {
4672 if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_CSD_0, &data, &size)) {
4673 return ERROR_MALFORMED;
4674 }
4675 } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
4676 || !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG2)
4677 || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
4678 if (!AMediaFormat_getBuffer(track->meta, AMEDIAFORMAT_KEY_ESDS, &data, &size)) {
4679 return ERROR_MALFORMED;
4680 }
4681 }
4682
4683 if (track->sampleTable == NULL || !track->sampleTable->isValid()) {
4684 // Make sure we have all the metadata we need.
4685 ALOGE("stbl atom missing/invalid.");
4686 return ERROR_MALFORMED;
4687 }
4688
4689 if (track->timescale == 0) {
4690 ALOGE("timescale invalid.");
4691 return ERROR_MALFORMED;
4692 }
4693
4694 return OK;
4695 }
4696
4697 typedef enum {
4698 //AOT_NONE = -1,
4699 //AOT_NULL_OBJECT = 0,
4700 //AOT_AAC_MAIN = 1, /**< Main profile */
4701 AOT_AAC_LC = 2, /**< Low Complexity object */
4702 //AOT_AAC_SSR = 3,
4703 //AOT_AAC_LTP = 4,
4704 AOT_SBR = 5,
4705 //AOT_AAC_SCAL = 6,
4706 //AOT_TWIN_VQ = 7,
4707 //AOT_CELP = 8,
4708 //AOT_HVXC = 9,
4709 //AOT_RSVD_10 = 10, /**< (reserved) */
4710 //AOT_RSVD_11 = 11, /**< (reserved) */
4711 //AOT_TTSI = 12, /**< TTSI Object */
4712 //AOT_MAIN_SYNTH = 13, /**< Main Synthetic object */
4713 //AOT_WAV_TAB_SYNTH = 14, /**< Wavetable Synthesis object */
4714 //AOT_GEN_MIDI = 15, /**< General MIDI object */
4715 //AOT_ALG_SYNTH_AUD_FX = 16, /**< Algorithmic Synthesis and Audio FX object */
4716 AOT_ER_AAC_LC = 17, /**< Error Resilient(ER) AAC Low Complexity */
4717 //AOT_RSVD_18 = 18, /**< (reserved) */
4718 //AOT_ER_AAC_LTP = 19, /**< Error Resilient(ER) AAC LTP object */
4719 AOT_ER_AAC_SCAL = 20, /**< Error Resilient(ER) AAC Scalable object */
4720 //AOT_ER_TWIN_VQ = 21, /**< Error Resilient(ER) TwinVQ object */
4721 AOT_ER_BSAC = 22, /**< Error Resilient(ER) BSAC object */
4722 AOT_ER_AAC_LD = 23, /**< Error Resilient(ER) AAC LowDelay object */
4723 //AOT_ER_CELP = 24, /**< Error Resilient(ER) CELP object */
4724 //AOT_ER_HVXC = 25, /**< Error Resilient(ER) HVXC object */
4725 //AOT_ER_HILN = 26, /**< Error Resilient(ER) HILN object */
4726 //AOT_ER_PARA = 27, /**< Error Resilient(ER) Parametric object */
4727 //AOT_RSVD_28 = 28, /**< might become SSC */
4728 AOT_PS = 29, /**< PS, Parametric Stereo (includes SBR) */
4729 //AOT_MPEGS = 30, /**< MPEG Surround */
4730
4731 AOT_ESCAPE = 31, /**< Signal AOT uses more than 5 bits */
4732
4733 //AOT_MP3ONMP4_L1 = 32, /**< MPEG-Layer1 in mp4 */
4734 //AOT_MP3ONMP4_L2 = 33, /**< MPEG-Layer2 in mp4 */
4735 //AOT_MP3ONMP4_L3 = 34, /**< MPEG-Layer3 in mp4 */
4736 //AOT_RSVD_35 = 35, /**< might become DST */
4737 //AOT_RSVD_36 = 36, /**< might become ALS */
4738 //AOT_AAC_SLS = 37, /**< AAC + SLS */
4739 //AOT_SLS = 38, /**< SLS */
4740 //AOT_ER_AAC_ELD = 39, /**< AAC Enhanced Low Delay */
4741
4742 AOT_USAC = 42, /**< USAC */
4743 //AOT_SAOC = 43, /**< SAOC */
4744 //AOT_LD_MPEGS = 44, /**< Low Delay MPEG Surround */
4745
4746 //AOT_RSVD50 = 50, /**< Interim AOT for Rsvd50 */
4747 } AUDIO_OBJECT_TYPE;
4748
updateAudioTrackInfoFromESDS_MPEG4Audio(const void * esds_data,size_t esds_size)4749 status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
4750 const void *esds_data, size_t esds_size) {
4751 ESDS esds(esds_data, esds_size);
4752
4753 uint8_t objectTypeIndication;
4754 if (esds.getObjectTypeIndication(&objectTypeIndication) != OK) {
4755 return ERROR_MALFORMED;
4756 }
4757
4758 if (objectTypeIndication == 0xe1) {
4759 // This isn't MPEG4 audio at all, it's QCELP 14k...
4760 if (mLastTrack == NULL)
4761 return ERROR_MALFORMED;
4762
4763 AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_QCELP);
4764 return OK;
4765 }
4766
4767 if (objectTypeIndication == 0x6B || objectTypeIndication == 0x69) {
4768 // mp3 audio
4769 if (mLastTrack == NULL)
4770 return ERROR_MALFORMED;
4771
4772 AMediaFormat_setString(mLastTrack->meta,AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MPEG);
4773 return OK;
4774 }
4775
4776 if (mLastTrack != NULL) {
4777 uint32_t maxBitrate = 0;
4778 uint32_t avgBitrate = 0;
4779 esds.getBitRate(&maxBitrate, &avgBitrate);
4780 if (maxBitrate > 0 && maxBitrate < INT32_MAX) {
4781 AMediaFormat_setInt32(mLastTrack->meta,
4782 AMEDIAFORMAT_KEY_MAX_BIT_RATE, (int32_t)maxBitrate);
4783 }
4784 if (avgBitrate > 0 && avgBitrate < INT32_MAX) {
4785 AMediaFormat_setInt32(mLastTrack->meta,
4786 AMEDIAFORMAT_KEY_BIT_RATE, (int32_t)avgBitrate);
4787 }
4788 }
4789
4790 const uint8_t *csd;
4791 size_t csd_size;
4792 if (esds.getCodecSpecificInfo(
4793 (const void **)&csd, &csd_size) != OK) {
4794 return ERROR_MALFORMED;
4795 }
4796
4797 if (kUseHexDump) {
4798 printf("ESD of size %zu\n", csd_size);
4799 hexdump(csd, csd_size);
4800 }
4801
4802 if (csd_size == 0) {
4803 // There's no further information, i.e. no codec specific data
4804 // Let's assume that the information provided in the mpeg4 headers
4805 // is accurate and hope for the best.
4806
4807 return OK;
4808 }
4809
4810 if (csd_size < 2) {
4811 return ERROR_MALFORMED;
4812 }
4813
4814 if (objectTypeIndication == 0xdd) {
4815 // vorbis audio
4816 if (csd[0] != 0x02) {
4817 return ERROR_MALFORMED;
4818 }
4819
4820 // codecInfo starts with two lengths, len1 and len2, that are
4821 // "Xiph-style-lacing encoded"..
4822
4823 size_t offset = 1;
4824 size_t len1 = 0;
4825 while (offset < csd_size && csd[offset] == 0xff) {
4826 if (__builtin_add_overflow(len1, 0xff, &len1)) {
4827 return ERROR_MALFORMED;
4828 }
4829 ++offset;
4830 }
4831 if (offset >= csd_size) {
4832 return ERROR_MALFORMED;
4833 }
4834 if (__builtin_add_overflow(len1, csd[offset], &len1)) {
4835 return ERROR_MALFORMED;
4836 }
4837 ++offset;
4838 if (len1 == 0) {
4839 return ERROR_MALFORMED;
4840 }
4841
4842 size_t len2 = 0;
4843 while (offset < csd_size && csd[offset] == 0xff) {
4844 if (__builtin_add_overflow(len2, 0xff, &len2)) {
4845 return ERROR_MALFORMED;
4846 }
4847 ++offset;
4848 }
4849 if (offset >= csd_size) {
4850 return ERROR_MALFORMED;
4851 }
4852 if (__builtin_add_overflow(len2, csd[offset], &len2)) {
4853 return ERROR_MALFORMED;
4854 }
4855 ++offset;
4856 if (len2 == 0) {
4857 return ERROR_MALFORMED;
4858 }
4859 if (offset + len1 > csd_size || csd[offset] != 0x01) {
4860 return ERROR_MALFORMED;
4861 }
4862
4863 if (mLastTrack == NULL) {
4864 return ERROR_MALFORMED;
4865 }
4866 // formerly kKeyVorbisInfo
4867 AMediaFormat_setBuffer(mLastTrack->meta,
4868 AMEDIAFORMAT_KEY_CSD_0, &csd[offset], len1);
4869
4870 if (__builtin_add_overflow(offset, len1, &offset) ||
4871 offset >= csd_size || csd[offset] != 0x03) {
4872 return ERROR_MALFORMED;
4873 }
4874
4875 if (__builtin_add_overflow(offset, len2, &offset) ||
4876 offset >= csd_size || csd[offset] != 0x05) {
4877 return ERROR_MALFORMED;
4878 }
4879
4880 // formerly kKeyVorbisBooks
4881 AMediaFormat_setBuffer(mLastTrack->meta,
4882 AMEDIAFORMAT_KEY_CSD_1, &csd[offset], csd_size - offset);
4883 AMediaFormat_setString(mLastTrack->meta,
4884 AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_VORBIS);
4885
4886 return OK;
4887 }
4888
4889 static uint32_t kSamplingRate[] = {
4890 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
4891 16000, 12000, 11025, 8000, 7350
4892 };
4893
4894 ABitReader br(csd, csd_size);
4895 uint32_t objectType = br.getBits(5);
4896
4897 if (objectType == AOT_ESCAPE) { // AAC-ELD => additional 6 bits
4898 objectType = 32 + br.getBits(6);
4899 }
4900
4901 if (mLastTrack == NULL)
4902 return ERROR_MALFORMED;
4903
4904 //keep AOT type
4905 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_AAC_PROFILE, objectType);
4906
4907 uint32_t freqIndex = br.getBits(4);
4908
4909 int32_t sampleRate = 0;
4910 int32_t numChannels = 0;
4911 if (freqIndex == 15) {
4912 if (br.numBitsLeft() < 28) return ERROR_MALFORMED;
4913 sampleRate = br.getBits(24);
4914 numChannels = br.getBits(4);
4915 } else {
4916 if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
4917 numChannels = br.getBits(4);
4918
4919 if (freqIndex == 13 || freqIndex == 14) {
4920 return ERROR_MALFORMED;
4921 }
4922
4923 sampleRate = kSamplingRate[freqIndex];
4924 }
4925
4926 if (objectType == AOT_SBR || objectType == AOT_PS) {//SBR specific config per 14496-3 tbl 1.13
4927 if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
4928 uint32_t extFreqIndex = br.getBits(4);
4929 if (extFreqIndex == 15) {
4930 if (csd_size < 8) {
4931 return ERROR_MALFORMED;
4932 }
4933 if (br.numBitsLeft() < 24) return ERROR_MALFORMED;
4934 br.skipBits(24); // extSampleRate
4935 } else {
4936 if (extFreqIndex == 13 || extFreqIndex == 14) {
4937 return ERROR_MALFORMED;
4938 }
4939 //extSampleRate = kSamplingRate[extFreqIndex];
4940 }
4941 //TODO: save the extension sampling rate value in meta data =>
4942 // AMediaFormat_setInt32(mLastTrack->meta, kKeyExtSampleRate, extSampleRate);
4943 }
4944
4945 switch (numChannels) {
4946 // values defined in 14496-3_2009 amendment-4 Table 1.19 - Channel Configuration
4947 case 0:
4948 case 1:// FC
4949 case 2:// FL FR
4950 case 3:// FC, FL FR
4951 case 4:// FC, FL FR, RC
4952 case 5:// FC, FL FR, SL SR
4953 case 6:// FC, FL FR, SL SR, LFE
4954 //numChannels already contains the right value
4955 break;
4956 case 11:// FC, FL FR, SL SR, RC, LFE
4957 numChannels = 7;
4958 break;
4959 case 7: // FC, FCL FCR, FL FR, SL SR, LFE
4960 case 12:// FC, FL FR, SL SR, RL RR, LFE
4961 case 14:// FC, FL FR, SL SR, LFE, FHL FHR
4962 numChannels = 8;
4963 break;
4964 default:
4965 return ERROR_UNSUPPORTED;
4966 }
4967
4968 {
4969 if (objectType == AOT_SBR || objectType == AOT_PS) {
4970 if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
4971 objectType = br.getBits(5);
4972
4973 if (objectType == AOT_ESCAPE) {
4974 if (br.numBitsLeft() < 6) return ERROR_MALFORMED;
4975 objectType = 32 + br.getBits(6);
4976 }
4977 }
4978 if (objectType == AOT_AAC_LC || objectType == AOT_ER_AAC_LC ||
4979 objectType == AOT_ER_AAC_LD || objectType == AOT_ER_AAC_SCAL ||
4980 objectType == AOT_ER_BSAC) {
4981 if (br.numBitsLeft() < 2) return ERROR_MALFORMED;
4982 br.skipBits(1); // frameLengthFlag
4983
4984 const int32_t dependsOnCoreCoder = br.getBits(1);
4985
4986 if (dependsOnCoreCoder ) {
4987 if (br.numBitsLeft() < 14) return ERROR_MALFORMED;
4988 br.skipBits(14); // coreCoderDelay
4989 }
4990
4991 int32_t extensionFlag = -1;
4992 if (br.numBitsLeft() > 0) {
4993 extensionFlag = br.getBits(1);
4994 } else {
4995 switch (objectType) {
4996 // 14496-3 4.5.1.1 extensionFlag
4997 case AOT_AAC_LC:
4998 extensionFlag = 0;
4999 break;
5000 case AOT_ER_AAC_LC:
5001 case AOT_ER_AAC_SCAL:
5002 case AOT_ER_BSAC:
5003 case AOT_ER_AAC_LD:
5004 extensionFlag = 1;
5005 break;
5006 default:
5007 return ERROR_MALFORMED;
5008 break;
5009 }
5010 ALOGW("csd missing extension flag; assuming %d for object type %u.",
5011 extensionFlag, objectType);
5012 }
5013
5014 if (numChannels == 0) {
5015 int32_t channelsEffectiveNum = 0;
5016 int32_t channelsNum = 0;
5017 if (br.numBitsLeft() < 32) {
5018 return ERROR_MALFORMED;
5019 }
5020 br.skipBits(4); // ElementInstanceTag
5021 br.skipBits(2); // Profile
5022 br.skipBits(4); // SamplingFrequencyIndex
5023 const int32_t NumFrontChannelElements = br.getBits(4);
5024 const int32_t NumSideChannelElements = br.getBits(4);
5025 const int32_t NumBackChannelElements = br.getBits(4);
5026 const int32_t NumLfeChannelElements = br.getBits(2);
5027 br.skipBits(3); // NumAssocDataElements
5028 br.skipBits(4); // NumValidCcElements
5029
5030 const int32_t MonoMixdownPresent = br.getBits(1);
5031
5032 if (MonoMixdownPresent != 0) {
5033 if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
5034 br.skipBits(4); // MonoMixdownElementNumber
5035 }
5036
5037 if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
5038 const int32_t StereoMixdownPresent = br.getBits(1);
5039 if (StereoMixdownPresent != 0) {
5040 if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
5041 br.skipBits(4); // StereoMixdownElementNumber
5042 }
5043
5044 if (br.numBitsLeft() < 1) return ERROR_MALFORMED;
5045 const int32_t MatrixMixdownIndexPresent = br.getBits(1);
5046 if (MatrixMixdownIndexPresent != 0) {
5047 if (br.numBitsLeft() < 3) return ERROR_MALFORMED;
5048 br.skipBits(2); // MatrixMixdownIndex
5049 br.skipBits(1); // PseudoSurroundEnable
5050 }
5051
5052 int i;
5053 for (i=0; i < NumFrontChannelElements; i++) {
5054 if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
5055 const int32_t FrontElementIsCpe = br.getBits(1);
5056 br.skipBits(4); // FrontElementTagSelect
5057 channelsNum += FrontElementIsCpe ? 2 : 1;
5058 }
5059
5060 for (i=0; i < NumSideChannelElements; i++) {
5061 if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
5062 const int32_t SideElementIsCpe = br.getBits(1);
5063 br.skipBits(4); // SideElementTagSelect
5064 channelsNum += SideElementIsCpe ? 2 : 1;
5065 }
5066
5067 for (i=0; i < NumBackChannelElements; i++) {
5068 if (br.numBitsLeft() < 5) return ERROR_MALFORMED;
5069 const int32_t BackElementIsCpe = br.getBits(1);
5070 br.skipBits(4); // BackElementTagSelect
5071 channelsNum += BackElementIsCpe ? 2 : 1;
5072 }
5073 channelsEffectiveNum = channelsNum;
5074
5075 for (i=0; i < NumLfeChannelElements; i++) {
5076 if (br.numBitsLeft() < 4) return ERROR_MALFORMED;
5077 br.skipBits(4); // LfeElementTagSelect
5078 channelsNum += 1;
5079 }
5080 ALOGV("mpeg4 audio channelsNum = %d", channelsNum);
5081 ALOGV("mpeg4 audio channelsEffectiveNum = %d", channelsEffectiveNum);
5082 numChannels = channelsNum;
5083 }
5084 }
5085 }
5086
5087 if (numChannels == 0) {
5088 return ERROR_UNSUPPORTED;
5089 }
5090
5091 if (mLastTrack == NULL)
5092 return ERROR_MALFORMED;
5093
5094 int32_t prevSampleRate;
5095 CHECK(AMediaFormat_getInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, &prevSampleRate));
5096
5097 if (prevSampleRate != sampleRate) {
5098 ALOGV("mpeg4 audio sample rate different from previous setting. "
5099 "was: %d, now: %d", prevSampleRate, sampleRate);
5100 }
5101
5102 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAMPLE_RATE, sampleRate);
5103
5104 int32_t prevChannelCount;
5105 CHECK(AMediaFormat_getInt32(mLastTrack->meta,
5106 AMEDIAFORMAT_KEY_CHANNEL_COUNT, &prevChannelCount));
5107
5108 if (prevChannelCount != numChannels) {
5109 ALOGV("mpeg4 audio channel count different from previous setting. "
5110 "was: %d, now: %d", prevChannelCount, numChannels);
5111 }
5112
5113 AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, numChannels);
5114
5115 return OK;
5116 }
5117
adjustRawDefaultFrameSize()5118 void MPEG4Extractor::adjustRawDefaultFrameSize() {
5119 int32_t chanCount = 0;
5120 int32_t bitWidth = 0;
5121 const char *mimeStr = NULL;
5122
5123 if(AMediaFormat_getString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, &mimeStr) &&
5124 !strcasecmp(mimeStr, MEDIA_MIMETYPE_AUDIO_RAW) &&
5125 AMediaFormat_getInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &chanCount) &&
5126 AMediaFormat_getInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, &bitWidth)) {
5127 // samplesize in stsz may not right , so updade default samplesize
5128 mLastTrack->sampleTable->setPredictSampleSize(chanCount * bitWidth / 8);
5129 }
5130 }
5131
5132 ////////////////////////////////////////////////////////////////////////////////
5133
MPEG4Source(AMediaFormat * format,DataSourceHelper * dataSource,int32_t timeScale,const sp<SampleTable> & sampleTable,Vector<SidxEntry> & sidx,const Trex * trex,off64_t firstMoofOffset,const sp<ItemTable> & itemTable,uint64_t elstShiftStartTicks,uint64_t elstInitialEmptyEditTicks)5134 MPEG4Source::MPEG4Source(
5135 AMediaFormat *format,
5136 DataSourceHelper *dataSource,
5137 int32_t timeScale,
5138 const sp<SampleTable> &sampleTable,
5139 Vector<SidxEntry> &sidx,
5140 const Trex *trex,
5141 off64_t firstMoofOffset,
5142 const sp<ItemTable> &itemTable,
5143 uint64_t elstShiftStartTicks,
5144 uint64_t elstInitialEmptyEditTicks)
5145 : mFormat(format),
5146 mDataSource(dataSource),
5147 mTimescale(timeScale),
5148 mSampleTable(sampleTable),
5149 mCurrentSampleIndex(0),
5150 mCurrentFragmentIndex(0),
5151 mSegments(sidx),
5152 mTrex(trex),
5153 mFirstMoofOffset(firstMoofOffset),
5154 mCurrentMoofOffset(firstMoofOffset),
5155 mCurrentMoofSize(0),
5156 mNextMoofOffset(-1),
5157 mCurrentTime(0),
5158 mDefaultEncryptedByteBlock(0),
5159 mDefaultSkipByteBlock(0),
5160 mCurrentSampleInfoAllocSize(0),
5161 mCurrentSampleInfoSizes(NULL),
5162 mCurrentSampleInfoOffsetsAllocSize(0),
5163 mCurrentSampleInfoOffsets(NULL),
5164 mIsAVC(false),
5165 mIsHEVC(false),
5166 mIsAPV(false),
5167 mIsDolbyVision(false),
5168 mIsAC4(false),
5169 mIsPcm(false),
5170 mNALLengthSize(0),
5171 mStarted(false),
5172 mBuffer(NULL),
5173 mSrcBufferSize(0),
5174 mSrcBuffer(NULL),
5175 mItemTable(itemTable),
5176 mElstShiftStartTicks(elstShiftStartTicks),
5177 mElstInitialEmptyEditTicks(elstInitialEmptyEditTicks) {
5178
5179 memset(&mTrackFragmentHeaderInfo, 0, sizeof(mTrackFragmentHeaderInfo));
5180
5181 AMediaFormat_getInt32(mFormat,
5182 AMEDIAFORMAT_KEY_CRYPTO_MODE, &mCryptoMode);
5183 mDefaultIVSize = 0;
5184 AMediaFormat_getInt32(mFormat,
5185 AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, &mDefaultIVSize);
5186 void *key;
5187 size_t keysize;
5188 if (AMediaFormat_getBuffer(mFormat,
5189 AMEDIAFORMAT_KEY_CRYPTO_KEY, &key, &keysize)) {
5190 CHECK(keysize <= 16);
5191 memset(mCryptoKey, 0, 16);
5192 memcpy(mCryptoKey, key, keysize);
5193 }
5194
5195 AMediaFormat_getInt32(mFormat,
5196 AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK, &mDefaultEncryptedByteBlock);
5197 AMediaFormat_getInt32(mFormat,
5198 AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK, &mDefaultSkipByteBlock);
5199
5200 const char *mime;
5201 bool success = AMediaFormat_getString(mFormat, AMEDIAFORMAT_KEY_MIME, &mime);
5202 CHECK(success);
5203
5204 mIsMpegH = !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEGH_MHA1) ||
5205 !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_MPEGH_MHM1);
5206 mIsAVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
5207 mIsHEVC = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC) ||
5208 !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC);
5209 mIsAPV = com::android::media::extractor::flags::extractor_mp4_enable_apv() &&
5210 !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_APV);
5211 mIsAC4 = !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC4);
5212 mIsDolbyVision = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_DOLBY_VISION);
5213 mIsHeif = !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_ANDROID_HEIC) && mItemTable != NULL;
5214 mIsAvif = !strcasecmp(mime, MEDIA_MIMETYPE_IMAGE_AVIF) && mItemTable != NULL;
5215
5216 if (mIsAVC) {
5217 void *data;
5218 size_t size;
5219 CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size));
5220
5221 mNALLengthSize = getNALLengthSizeFromAvcCsd((const uint8_t *)data, size);
5222 } else if (mIsHEVC) {
5223 void *data;
5224 size_t size;
5225 CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_HEVC, &data, &size));
5226
5227 mNALLengthSize = getNALLengthSizeFromHevcCsd((const uint8_t *)data, size);
5228 } else if (mIsDolbyVision) {
5229 ALOGV("%s DolbyVision stream detected", __FUNCTION__);
5230 void *data;
5231 size_t size;
5232 CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_2, &data, &size));
5233
5234 const uint8_t *ptr = (const uint8_t *)data;
5235
5236 CHECK(size == 24);
5237
5238 // dv_major.dv_minor Should be 1.0 or 2.1
5239 CHECK(!((ptr[0] != 1 || ptr[1] != 0) && (ptr[0] != 2 || ptr[1] != 1)));
5240
5241 const uint8_t profile = ptr[2] >> 1;
5242 // profile == (4,5,6,7,8) --> HEVC; profile == (9) --> AVC; profile == (10) --> AV1
5243 if (profile > 3 && profile < 9) {
5244 CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_HEVC, &data, &size));
5245
5246 mNALLengthSize = getNALLengthSizeFromHevcCsd((const uint8_t *)data, size);
5247 } else if (9 == profile) {
5248 CHECK(AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size));
5249
5250 mNALLengthSize = getNALLengthSizeFromAvcCsd((const uint8_t *)data, size);
5251 } else if (10 == profile) {
5252 /* AV1 profile nothing to do */
5253 } else {
5254 if (AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_HEVC, &data, &size)) {
5255 mNALLengthSize = getNALLengthSizeFromHevcCsd((const uint8_t *)data, size);
5256 } else if (AMediaFormat_getBuffer(format, AMEDIAFORMAT_KEY_CSD_AVC, &data, &size)) {
5257 mNALLengthSize = getNALLengthSizeFromAvcCsd((const uint8_t *)data, size);
5258 } else {
5259 LOG_ALWAYS_FATAL("Invalid Dolby Vision profile = %d", profile);
5260 }
5261 }
5262 }
5263
5264 mIsPcm = !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW);
5265 mIsAudio = !strncasecmp(mime, "audio/", 6);
5266
5267 int32_t aacObjectType = -1;
5268
5269 if (AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_AAC_PROFILE, &aacObjectType)) {
5270 mIsUsac = (aacObjectType == AOT_USAC);
5271 }
5272
5273 if (mIsPcm) {
5274 int32_t numChannels = 0;
5275 int32_t bitsPerSample = 0;
5276 CHECK(AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, &bitsPerSample));
5277 CHECK(AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &numChannels));
5278
5279 int32_t bytesPerSample = bitsPerSample >> 3;
5280 int32_t pcmSampleSize = bytesPerSample * numChannels;
5281
5282 size_t maxSampleSize;
5283 status_t err = mSampleTable->getMaxSampleSize(&maxSampleSize);
5284 if (err != OK || maxSampleSize != static_cast<size_t>(pcmSampleSize)
5285 || bitsPerSample != 16) {
5286 // Not supported
5287 mIsPcm = false;
5288 } else {
5289 AMediaFormat_setInt32(mFormat,
5290 AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, pcmSampleSize * kMaxPcmFrameSize);
5291 }
5292 }
5293
5294 CHECK(AMediaFormat_getInt32(format, AMEDIAFORMAT_KEY_TRACK_ID, &mTrackId));
5295 }
5296
init()5297 status_t MPEG4Source::init() {
5298 if (mFirstMoofOffset != 0) {
5299 off64_t offset = mFirstMoofOffset;
5300 return parseChunk(&offset);
5301 }
5302 return OK;
5303 }
5304
~MPEG4Source()5305 MPEG4Source::~MPEG4Source() {
5306 if (mStarted) {
5307 stop();
5308 }
5309 free(mCurrentSampleInfoSizes);
5310 free(mCurrentSampleInfoOffsets);
5311 }
5312
start()5313 media_status_t MPEG4Source::start() {
5314 Mutex::Autolock autoLock(mLock);
5315
5316 CHECK(!mStarted);
5317
5318 int32_t tmp;
5319 CHECK(AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, &tmp));
5320 size_t max_size = tmp;
5321
5322 // A somewhat arbitrary limit that should be sufficient for 8k video frames
5323 // If you see the message below for a valid input stream: increase the limit
5324 const size_t kMaxBufferSize = 64 * 1024 * 1024;
5325 if (max_size > kMaxBufferSize) {
5326 ALOGE("bogus max input size: %zu > %zu", max_size, kMaxBufferSize);
5327 return AMEDIA_ERROR_MALFORMED;
5328 }
5329 if (max_size == 0) {
5330 ALOGE("zero max input size");
5331 return AMEDIA_ERROR_MALFORMED;
5332 }
5333
5334 // Allow up to kMaxBuffers, but not if the total exceeds kMaxBufferSize.
5335 const size_t kInitialBuffers = 2;
5336 const size_t kMaxBuffers = 8;
5337 const size_t realMaxBuffers = min(kMaxBufferSize / max_size, kMaxBuffers);
5338 mBufferGroup->init(kInitialBuffers, max_size, realMaxBuffers);
5339 mSrcBuffer = new (std::nothrow) uint8_t[max_size];
5340 if (mSrcBuffer == NULL) {
5341 // file probably specified a bad max size
5342 return AMEDIA_ERROR_MALFORMED;
5343 }
5344 mSrcBufferSize = max_size;
5345
5346 mStarted = true;
5347
5348 return AMEDIA_OK;
5349 }
5350
stop()5351 media_status_t MPEG4Source::stop() {
5352 Mutex::Autolock autoLock(mLock);
5353
5354 CHECK(mStarted);
5355
5356 if (mBuffer != NULL) {
5357 mBuffer->release();
5358 mBuffer = NULL;
5359 }
5360
5361 mSrcBufferSize = 0;
5362 delete[] mSrcBuffer;
5363 mSrcBuffer = NULL;
5364
5365 mStarted = false;
5366 mCurrentSampleIndex = 0;
5367
5368 return AMEDIA_OK;
5369 }
5370
parseChunk(off64_t * offset)5371 status_t MPEG4Source::parseChunk(off64_t *offset) {
5372 uint32_t hdr[2];
5373 if (mDataSource->readAt(*offset, hdr, 8) < 8) {
5374 return ERROR_IO;
5375 }
5376 uint64_t chunk_size = ntohl(hdr[0]);
5377 uint32_t chunk_type = ntohl(hdr[1]);
5378 off64_t data_offset = *offset + 8;
5379
5380 if (chunk_size == 1) {
5381 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
5382 return ERROR_IO;
5383 }
5384 chunk_size = ntoh64(chunk_size);
5385 data_offset += 8;
5386
5387 if (chunk_size < 16) {
5388 // The smallest valid chunk is 16 bytes long in this case.
5389 return ERROR_MALFORMED;
5390 }
5391 } else if (chunk_size < 8) {
5392 // The smallest valid chunk is 8 bytes long.
5393 return ERROR_MALFORMED;
5394 }
5395
5396 char chunk[5];
5397 MakeFourCCString(chunk_type, chunk);
5398 ALOGV("MPEG4Source chunk %s @ %#llx", chunk, (long long)*offset);
5399
5400 off64_t chunk_data_size = *offset + chunk_size - data_offset;
5401
5402 switch(chunk_type) {
5403
5404 case FOURCC("traf"):
5405 case FOURCC("moof"): {
5406 off64_t stop_offset = *offset + chunk_size;
5407 *offset = data_offset;
5408 if (chunk_type == FOURCC("moof")) {
5409 mCurrentMoofSize = chunk_data_size;
5410 }
5411 while (*offset < stop_offset) {
5412 status_t err = parseChunk(offset);
5413 if (err != OK) {
5414 return err;
5415 }
5416 }
5417 if (chunk_type == FOURCC("moof")) {
5418 // *offset points to the box following this moof. Find the next moof from there.
5419
5420 while (true) {
5421 if (mDataSource->readAt(*offset, hdr, 8) < 8) {
5422 // no more box to the end of file.
5423 break;
5424 }
5425 chunk_size = ntohl(hdr[0]);
5426 chunk_type = ntohl(hdr[1]);
5427 if (chunk_size == 1) {
5428 // ISO/IEC 14496-12:2012, 8.8.4 Movie Fragment Box, moof is a Box
5429 // which is defined in 4.2 Object Structure.
5430 // When chunk_size==1, 8 bytes follows as "largesize".
5431 if (mDataSource->readAt(*offset + 8, &chunk_size, 8) < 8) {
5432 return ERROR_IO;
5433 }
5434 chunk_size = ntoh64(chunk_size);
5435 if (chunk_size < 16) {
5436 // The smallest valid chunk is 16 bytes long in this case.
5437 return ERROR_MALFORMED;
5438 }
5439 } else if (chunk_size == 0) {
5440 // next box extends to end of file.
5441 } else if (chunk_size < 8) {
5442 // The smallest valid chunk is 8 bytes long in this case.
5443 return ERROR_MALFORMED;
5444 }
5445
5446 if (chunk_type == FOURCC("moof")) {
5447 mNextMoofOffset = *offset;
5448 break;
5449 } else if (chunk_type == FOURCC("mdat")) {
5450 parseChunk(offset);
5451 continue;
5452 } else if (chunk_size == 0) {
5453 break;
5454 }
5455 *offset += chunk_size;
5456 }
5457 }
5458 break;
5459 }
5460
5461 case FOURCC("tfhd"): {
5462 status_t err;
5463 if ((err = parseTrackFragmentHeader(data_offset, chunk_data_size)) != OK) {
5464 return err;
5465 }
5466 *offset += chunk_size;
5467 break;
5468 }
5469
5470 case FOURCC("trun"): {
5471 status_t err;
5472 if (mLastParsedTrackId == mTrackId) {
5473 if ((err = parseTrackFragmentRun(data_offset, chunk_data_size)) != OK) {
5474 return err;
5475 }
5476 }
5477
5478 *offset += chunk_size;
5479 break;
5480 }
5481
5482 case FOURCC("saiz"): {
5483 status_t err;
5484 if ((err = parseSampleAuxiliaryInformationSizes(data_offset, chunk_data_size)) != OK) {
5485 return err;
5486 }
5487 *offset += chunk_size;
5488 break;
5489 }
5490 case FOURCC("saio"): {
5491 status_t err;
5492 if ((err = parseSampleAuxiliaryInformationOffsets(data_offset, chunk_data_size))
5493 != OK) {
5494 return err;
5495 }
5496 *offset += chunk_size;
5497 break;
5498 }
5499
5500 case FOURCC("senc"): {
5501 status_t err;
5502 if ((err = parseSampleEncryption(data_offset, chunk_data_size)) != OK) {
5503 return err;
5504 }
5505 *offset += chunk_size;
5506 break;
5507 }
5508
5509 case FOURCC("mdat"): {
5510 // parse DRM info if present
5511 ALOGV("MPEG4Source::parseChunk mdat");
5512 // if saiz/saoi was previously observed, do something with the sampleinfos
5513 status_t err = OK;
5514 auto kv = mDrmOffsets.lower_bound(*offset);
5515 if (kv != mDrmOffsets.end()) {
5516 auto drmoffset = kv->first;
5517 auto flags = kv->second;
5518 mDrmOffsets.erase(kv);
5519 ALOGV("mdat chunk_size %" PRIu64 " drmoffset %" PRId64 " offset %" PRId64,
5520 chunk_size, drmoffset, *offset);
5521 if (chunk_size >= drmoffset - *offset) {
5522 err = parseClearEncryptedSizes(drmoffset, false, flags,
5523 chunk_size - (drmoffset - *offset));
5524 }
5525 }
5526 if (err != OK) {
5527 return err;
5528 }
5529 *offset += chunk_size;
5530 break;
5531 }
5532
5533 default: {
5534 *offset += chunk_size;
5535 break;
5536 }
5537 }
5538 return OK;
5539 }
5540
parseSampleAuxiliaryInformationSizes(off64_t offset,off64_t size)5541 status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(
5542 off64_t offset, off64_t size) {
5543 ALOGV("parseSampleAuxiliaryInformationSizes");
5544 if (size < 9) {
5545 return -EINVAL;
5546 }
5547 // 14496-12 8.7.12
5548 uint8_t version;
5549 if (mDataSource->readAt(
5550 offset, &version, sizeof(version))
5551 < (ssize_t)sizeof(version)) {
5552 return ERROR_IO;
5553 }
5554
5555 if (version != 0) {
5556 return ERROR_UNSUPPORTED;
5557 }
5558 offset++;
5559 size--;
5560
5561 uint32_t flags;
5562 if (!mDataSource->getUInt24(offset, &flags)) {
5563 return ERROR_IO;
5564 }
5565 offset += 3;
5566 size -= 3;
5567
5568 if (flags & 1) {
5569 if (size < 13) {
5570 return -EINVAL;
5571 }
5572 uint32_t tmp;
5573 if (!mDataSource->getUInt32(offset, &tmp)) {
5574 return ERROR_MALFORMED;
5575 }
5576 mCurrentAuxInfoType = tmp;
5577 offset += 4;
5578 size -= 4;
5579 if (!mDataSource->getUInt32(offset, &tmp)) {
5580 return ERROR_MALFORMED;
5581 }
5582 mCurrentAuxInfoTypeParameter = tmp;
5583 offset += 4;
5584 size -= 4;
5585 }
5586
5587 uint8_t defsize;
5588 if (mDataSource->readAt(offset, &defsize, 1) != 1) {
5589 return ERROR_MALFORMED;
5590 }
5591 mCurrentDefaultSampleInfoSize = defsize;
5592 offset++;
5593 size--;
5594
5595 uint32_t smplcnt;
5596 if (!mDataSource->getUInt32(offset, &smplcnt)) {
5597 return ERROR_MALFORMED;
5598 }
5599 mCurrentSampleInfoCount = smplcnt;
5600 offset += 4;
5601 size -= 4;
5602 if (mCurrentDefaultSampleInfoSize != 0) {
5603 ALOGV("@@@@ using default sample info size of %d", mCurrentDefaultSampleInfoSize);
5604 return OK;
5605 }
5606 if(smplcnt > size) {
5607 ALOGW("b/124525515 - smplcnt(%u) > size(%ld)", (unsigned int)smplcnt, (unsigned long)size);
5608 android_errorWriteLog(0x534e4554, "124525515");
5609 return -EINVAL;
5610 }
5611 if (smplcnt > mCurrentSampleInfoAllocSize) {
5612 uint8_t * newPtr = (uint8_t*) realloc(mCurrentSampleInfoSizes, smplcnt);
5613 if (newPtr == NULL) {
5614 ALOGE("failed to realloc %u -> %u", mCurrentSampleInfoAllocSize, smplcnt);
5615 return NO_MEMORY;
5616 }
5617 mCurrentSampleInfoSizes = newPtr;
5618 mCurrentSampleInfoAllocSize = smplcnt;
5619 }
5620
5621 mDataSource->readAt(offset, mCurrentSampleInfoSizes, smplcnt);
5622 return OK;
5623 }
5624
parseSampleAuxiliaryInformationOffsets(off64_t offset,off64_t size)5625 status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(
5626 off64_t offset, off64_t size) {
5627 ALOGV("parseSampleAuxiliaryInformationOffsets");
5628 if (size < 8) {
5629 return -EINVAL;
5630 }
5631 // 14496-12 8.7.13
5632 uint8_t version;
5633 if (mDataSource->readAt(offset, &version, sizeof(version)) != 1) {
5634 return ERROR_IO;
5635 }
5636 offset++;
5637 size--;
5638
5639 uint32_t flags;
5640 if (!mDataSource->getUInt24(offset, &flags)) {
5641 return ERROR_IO;
5642 }
5643 offset += 3;
5644 size -= 3;
5645
5646 uint32_t entrycount;
5647 if (!mDataSource->getUInt32(offset, &entrycount)) {
5648 return ERROR_IO;
5649 }
5650 offset += 4;
5651 size -= 4;
5652 if (entrycount == 0) {
5653 return OK;
5654 }
5655 if (entrycount > UINT32_MAX / 8) {
5656 return ERROR_MALFORMED;
5657 }
5658
5659 if (entrycount > mCurrentSampleInfoOffsetsAllocSize) {
5660 uint64_t *newPtr = (uint64_t *)realloc(mCurrentSampleInfoOffsets, entrycount * 8);
5661 if (newPtr == NULL) {
5662 ALOGE("failed to realloc %u -> %u",
5663 mCurrentSampleInfoOffsetsAllocSize, entrycount * 8);
5664 return NO_MEMORY;
5665 }
5666 mCurrentSampleInfoOffsets = newPtr;
5667 mCurrentSampleInfoOffsetsAllocSize = entrycount;
5668 }
5669 mCurrentSampleInfoOffsetCount = entrycount;
5670
5671 if (mCurrentSampleInfoOffsets == NULL) {
5672 return OK;
5673 }
5674
5675 for (size_t i = 0; i < entrycount; i++) {
5676 if (version == 0) {
5677 if (size < 4) {
5678 ALOGW("b/124526959");
5679 android_errorWriteLog(0x534e4554, "124526959");
5680 return -EINVAL;
5681 }
5682 uint32_t tmp;
5683 if (!mDataSource->getUInt32(offset, &tmp)) {
5684 return ERROR_IO;
5685 }
5686 mCurrentSampleInfoOffsets[i] = tmp;
5687 offset += 4;
5688 size -= 4;
5689 } else {
5690 if (size < 8) {
5691 ALOGW("b/124526959");
5692 android_errorWriteLog(0x534e4554, "124526959");
5693 return -EINVAL;
5694 }
5695 uint64_t tmp;
5696 if (!mDataSource->getUInt64(offset, &tmp)) {
5697 return ERROR_IO;
5698 }
5699 mCurrentSampleInfoOffsets[i] = tmp;
5700 offset += 8;
5701 size -= 8;
5702 }
5703 }
5704
5705 // parse clear/encrypted data
5706
5707 off64_t drmoffset = mCurrentSampleInfoOffsets[0]; // from moof
5708
5709 drmoffset += mCurrentMoofOffset;
5710 mDrmOffsets[drmoffset] = flags;
5711 ALOGV("saio drmoffset %" PRId64 " flags %u", drmoffset, flags);
5712
5713 return OK;
5714 }
5715
parseClearEncryptedSizes(off64_t offset,bool isSampleEncryption,uint32_t flags,off64_t size)5716 status_t MPEG4Source::parseClearEncryptedSizes(
5717 off64_t offset, bool isSampleEncryption, uint32_t flags, off64_t size) {
5718
5719 int32_t ivlength;
5720 if (!AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, &ivlength)) {
5721 return ERROR_MALFORMED;
5722 }
5723
5724 // only 0, 8 and 16 byte initialization vectors are supported
5725 if (ivlength != 0 && ivlength != 8 && ivlength != 16) {
5726 ALOGW("unsupported IV length: %d", ivlength);
5727 return ERROR_MALFORMED;
5728 }
5729
5730 uint32_t sampleCount = mCurrentSampleInfoCount;
5731 if (isSampleEncryption) {
5732 if (size < 4) {
5733 return ERROR_MALFORMED;
5734 }
5735 if (!mDataSource->getUInt32(offset, &sampleCount)) {
5736 return ERROR_IO;
5737 }
5738 offset += 4;
5739 size -= 4;
5740 }
5741
5742 // read CencSampleAuxiliaryDataFormats
5743 for (size_t i = 0; i < sampleCount; i++) {
5744 if (i >= mCurrentSamples.size()) {
5745 ALOGW("too few samples");
5746 break;
5747 }
5748 Sample *smpl = &mCurrentSamples.editItemAt(i);
5749 if (!smpl->clearsizes.isEmpty()) {
5750 continue;
5751 }
5752
5753 memset(smpl->iv, 0, 16);
5754 if (size < ivlength) {
5755 return ERROR_MALFORMED;
5756 }
5757 if (mDataSource->readAt(offset, smpl->iv, ivlength) != ivlength) {
5758 return ERROR_IO;
5759 }
5760
5761 offset += ivlength;
5762 size -= ivlength;
5763
5764 bool readSubsamples;
5765 if (isSampleEncryption) {
5766 readSubsamples = flags & 2;
5767 } else {
5768 int32_t smplinfosize = mCurrentDefaultSampleInfoSize;
5769 if (smplinfosize == 0) {
5770 smplinfosize = mCurrentSampleInfoSizes[i];
5771 }
5772 readSubsamples = smplinfosize > ivlength;
5773 }
5774
5775 if (readSubsamples) {
5776 uint16_t numsubsamples;
5777 if (size < 2) {
5778 return ERROR_MALFORMED;
5779 }
5780 if (!mDataSource->getUInt16(offset, &numsubsamples)) {
5781 return ERROR_IO;
5782 }
5783 offset += 2;
5784 size -= 2;
5785 for (size_t j = 0; j < numsubsamples; j++) {
5786 uint16_t numclear;
5787 uint32_t numencrypted;
5788 if (size < 6) {
5789 return ERROR_MALFORMED;
5790 }
5791 if (!mDataSource->getUInt16(offset, &numclear)) {
5792 return ERROR_IO;
5793 }
5794 offset += 2;
5795 if (!mDataSource->getUInt32(offset, &numencrypted)) {
5796 return ERROR_IO;
5797 }
5798 offset += 4;
5799 size -= 6;
5800 smpl->clearsizes.add(numclear);
5801 smpl->encryptedsizes.add(numencrypted);
5802 }
5803 } else {
5804 smpl->clearsizes.add(0);
5805 smpl->encryptedsizes.add(smpl->size);
5806 }
5807 }
5808
5809 return OK;
5810 }
5811
parseSampleEncryption(off64_t offset,off64_t chunk_data_size)5812 status_t MPEG4Source::parseSampleEncryption(off64_t offset, off64_t chunk_data_size) {
5813 uint32_t flags;
5814 if (chunk_data_size < 4) {
5815 return ERROR_MALFORMED;
5816 }
5817 if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags
5818 return ERROR_MALFORMED;
5819 }
5820 return parseClearEncryptedSizes(offset + 4, true, flags, chunk_data_size - 4);
5821 }
5822
parseTrackFragmentHeader(off64_t offset,off64_t size)5823 status_t MPEG4Source::parseTrackFragmentHeader(off64_t offset, off64_t size) {
5824
5825 if (size < 8) {
5826 return -EINVAL;
5827 }
5828
5829 uint32_t flags;
5830 if (!mDataSource->getUInt32(offset, &flags)) { // actually version + flags
5831 return ERROR_MALFORMED;
5832 }
5833
5834 if (flags & 0xff000000) {
5835 return -EINVAL;
5836 }
5837
5838 if (!mDataSource->getUInt32(offset + 4, (uint32_t*)&mLastParsedTrackId)) {
5839 return ERROR_MALFORMED;
5840 }
5841
5842 if (mLastParsedTrackId != mTrackId) {
5843 // this is not the right track, skip it
5844 return OK;
5845 }
5846
5847 mTrackFragmentHeaderInfo.mFlags = flags;
5848 mTrackFragmentHeaderInfo.mTrackID = mLastParsedTrackId;
5849 offset += 8;
5850 size -= 8;
5851
5852 ALOGV("fragment header: %08x %08x", flags, mTrackFragmentHeaderInfo.mTrackID);
5853
5854 if (flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent) {
5855 if (size < 8) {
5856 return -EINVAL;
5857 }
5858
5859 if (!mDataSource->getUInt64(offset, &mTrackFragmentHeaderInfo.mBaseDataOffset)) {
5860 return ERROR_MALFORMED;
5861 }
5862 offset += 8;
5863 size -= 8;
5864 }
5865
5866 if (flags & TrackFragmentHeaderInfo::kSampleDescriptionIndexPresent) {
5867 if (size < 4) {
5868 return -EINVAL;
5869 }
5870
5871 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mSampleDescriptionIndex)) {
5872 return ERROR_MALFORMED;
5873 }
5874 offset += 4;
5875 size -= 4;
5876 }
5877
5878 if (flags & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
5879 if (size < 4) {
5880 return -EINVAL;
5881 }
5882
5883 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleDuration)) {
5884 return ERROR_MALFORMED;
5885 }
5886 offset += 4;
5887 size -= 4;
5888 }
5889
5890 if (flags & TrackFragmentHeaderInfo::kDefaultSampleSizePresent) {
5891 if (size < 4) {
5892 return -EINVAL;
5893 }
5894
5895 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleSize)) {
5896 return ERROR_MALFORMED;
5897 }
5898 offset += 4;
5899 size -= 4;
5900 }
5901
5902 if (flags & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent) {
5903 if (size < 4) {
5904 return -EINVAL;
5905 }
5906
5907 if (!mDataSource->getUInt32(offset, &mTrackFragmentHeaderInfo.mDefaultSampleFlags)) {
5908 return ERROR_MALFORMED;
5909 }
5910 offset += 4;
5911 size -= 4;
5912 }
5913
5914 if (!(flags & TrackFragmentHeaderInfo::kBaseDataOffsetPresent)) {
5915 mTrackFragmentHeaderInfo.mBaseDataOffset = mCurrentMoofOffset;
5916 }
5917
5918 mTrackFragmentHeaderInfo.mDataOffset = 0;
5919 return OK;
5920 }
5921
parseTrackFragmentRun(off64_t offset,off64_t size)5922 status_t MPEG4Source::parseTrackFragmentRun(off64_t offset, off64_t size) {
5923
5924 ALOGV("MPEG4Source::parseTrackFragmentRun");
5925 if (size < 8) {
5926 return -EINVAL;
5927 }
5928
5929 enum {
5930 kDataOffsetPresent = 0x01,
5931 kFirstSampleFlagsPresent = 0x04,
5932 kSampleDurationPresent = 0x100,
5933 kSampleSizePresent = 0x200,
5934 kSampleFlagsPresent = 0x400,
5935 kSampleCompositionTimeOffsetPresent = 0x800,
5936 };
5937
5938 uint32_t flags;
5939 if (!mDataSource->getUInt32(offset, &flags)) {
5940 return ERROR_MALFORMED;
5941 }
5942 // |version| only affects SampleCompositionTimeOffset field.
5943 // If version == 0, SampleCompositionTimeOffset is uint32_t;
5944 // Otherwise, SampleCompositionTimeOffset is int32_t.
5945 // Sample.compositionOffset is defined as int32_t.
5946 uint8_t version = flags >> 24;
5947 flags &= 0xffffff;
5948 ALOGV("fragment run version: 0x%02x, flags: 0x%06x", version, flags);
5949
5950 if ((flags & kFirstSampleFlagsPresent) && (flags & kSampleFlagsPresent)) {
5951 // These two shall not be used together.
5952 return -EINVAL;
5953 }
5954
5955 uint32_t sampleCount;
5956 if (!mDataSource->getUInt32(offset + 4, &sampleCount)) {
5957 return ERROR_MALFORMED;
5958 }
5959 offset += 8;
5960 size -= 8;
5961
5962 uint64_t dataOffset = mTrackFragmentHeaderInfo.mDataOffset;
5963
5964 uint32_t firstSampleFlags = 0;
5965
5966 if (flags & kDataOffsetPresent) {
5967 if (size < 4) {
5968 return -EINVAL;
5969 }
5970
5971 uint32_t dataOffsetDelta;
5972 if (!mDataSource->getUInt32(offset, &dataOffsetDelta)) {
5973 return ERROR_MALFORMED;
5974 }
5975
5976 if (__builtin_add_overflow(
5977 mTrackFragmentHeaderInfo.mBaseDataOffset, dataOffsetDelta, &dataOffset)) {
5978 ALOGW("b/232242894 mBaseDataOffset(%" PRIu64 ") + dataOffsetDelta(%u) overflows uint64",
5979 mTrackFragmentHeaderInfo.mBaseDataOffset, dataOffsetDelta);
5980 android_errorWriteLog(0x534e4554, "232242894");
5981 return ERROR_MALFORMED;
5982 }
5983
5984 offset += 4;
5985 size -= 4;
5986 }
5987
5988 if (flags & kFirstSampleFlagsPresent) {
5989 if (size < 4) {
5990 return -EINVAL;
5991 }
5992
5993 if (!mDataSource->getUInt32(offset, &firstSampleFlags)) {
5994 return ERROR_MALFORMED;
5995 }
5996 offset += 4;
5997 size -= 4;
5998 }
5999
6000 uint32_t sampleDuration = 0, sampleSize = 0, sampleFlags = 0,
6001 sampleCtsOffset = 0;
6002
6003 size_t bytesPerSample = 0;
6004 if (flags & kSampleDurationPresent) {
6005 bytesPerSample += 4;
6006 } else if (mTrackFragmentHeaderInfo.mFlags
6007 & TrackFragmentHeaderInfo::kDefaultSampleDurationPresent) {
6008 sampleDuration = mTrackFragmentHeaderInfo.mDefaultSampleDuration;
6009 } else if (mTrex) {
6010 sampleDuration = mTrex->default_sample_duration;
6011 }
6012
6013 if (flags & kSampleSizePresent) {
6014 bytesPerSample += 4;
6015 } else {
6016 sampleSize = mTrackFragmentHeaderInfo.mDefaultSampleSize;
6017 #ifdef VERY_VERY_VERBOSE_LOGGING
6018 // We don't expect this, but also want to avoid spamming the log if
6019 // we hit this case.
6020 if (!(mTrackFragmentHeaderInfo.mFlags
6021 & TrackFragmentHeaderInfo::kDefaultSampleSizePresent)) {
6022 ALOGW("No sample size specified");
6023 }
6024 #endif
6025 }
6026
6027 if (flags & kSampleFlagsPresent) {
6028 bytesPerSample += 4;
6029 } else {
6030 sampleFlags = mTrackFragmentHeaderInfo.mDefaultSampleFlags;
6031 #ifdef VERY_VERY_VERBOSE_LOGGING
6032 // We don't expect this, but also want to avoid spamming the log if
6033 // we hit this case.
6034 if (!(mTrackFragmentHeaderInfo.mFlags
6035 & TrackFragmentHeaderInfo::kDefaultSampleFlagsPresent)) {
6036 ALOGW("No sample flags specified");
6037 }
6038 #endif
6039 }
6040
6041 if (flags & kSampleCompositionTimeOffsetPresent) {
6042 bytesPerSample += 4;
6043 } else {
6044 sampleCtsOffset = 0;
6045 }
6046
6047 if (bytesPerSample != 0) {
6048 if (size < (off64_t)sampleCount * bytesPerSample) {
6049 return -EINVAL;
6050 }
6051 } else {
6052 if (sampleDuration == 0) {
6053 ALOGW("b/123389881 sampleDuration == 0");
6054 android_errorWriteLog(0x534e4554, "124389881 zero");
6055 return -EINVAL;
6056 }
6057
6058 // apply some quick (vs strict legality) checks
6059 //
6060 static constexpr uint32_t kMaxTrunSampleCount = 10000;
6061 if (sampleCount > kMaxTrunSampleCount) {
6062 ALOGW("b/123389881 sampleCount(%u) > kMaxTrunSampleCount(%u)",
6063 sampleCount, kMaxTrunSampleCount);
6064 android_errorWriteLog(0x534e4554, "124389881 count");
6065 return -EINVAL;
6066 }
6067 }
6068
6069 Sample tmp;
6070 for (uint32_t i = 0; i < sampleCount; ++i) {
6071 if (flags & kSampleDurationPresent) {
6072 if (!mDataSource->getUInt32(offset, &sampleDuration)) {
6073 return ERROR_MALFORMED;
6074 }
6075 offset += 4;
6076 }
6077
6078 if (flags & kSampleSizePresent) {
6079 if (!mDataSource->getUInt32(offset, &sampleSize)) {
6080 return ERROR_MALFORMED;
6081 }
6082 offset += 4;
6083 }
6084
6085 if (flags & kSampleFlagsPresent) {
6086 if (!mDataSource->getUInt32(offset, &sampleFlags)) {
6087 return ERROR_MALFORMED;
6088 }
6089 offset += 4;
6090 }
6091
6092 if (flags & kSampleCompositionTimeOffsetPresent) {
6093 if (!mDataSource->getUInt32(offset, &sampleCtsOffset)) {
6094 return ERROR_MALFORMED;
6095 }
6096 offset += 4;
6097 }
6098
6099 ALOGV("adding sample %d at offset 0x%08" PRIx64 ", size %u, duration %u, "
6100 " flags 0x%08x ctsOffset %" PRIu32, i + 1,
6101 dataOffset, sampleSize, sampleDuration,
6102 (flags & kFirstSampleFlagsPresent) && i == 0
6103 ? firstSampleFlags : sampleFlags, sampleCtsOffset);
6104 tmp.offset = dataOffset;
6105 tmp.size = sampleSize;
6106 tmp.duration = sampleDuration;
6107 tmp.compositionOffset = sampleCtsOffset;
6108 memset(tmp.iv, 0, sizeof(tmp.iv));
6109 if (mCurrentSamples.add(tmp) < 0) {
6110 ALOGW("b/123389881 failed saving sample(n=%zu)", mCurrentSamples.size());
6111 android_errorWriteLog(0x534e4554, "124389881 allocation");
6112 mCurrentSamples.clear();
6113 return NO_MEMORY;
6114 }
6115
6116 if (__builtin_add_overflow(dataOffset, sampleSize, &dataOffset)) {
6117 ALOGW("b/232242894 dataOffset(%" PRIu64 ") + sampleSize(%u) overflows uint64",
6118 dataOffset, sampleSize);
6119 android_errorWriteLog(0x534e4554, "232242894");
6120 return ERROR_MALFORMED;
6121 }
6122 }
6123
6124 mTrackFragmentHeaderInfo.mDataOffset = dataOffset;
6125
6126 return OK;
6127 }
6128
getFormat(AMediaFormat * meta)6129 media_status_t MPEG4Source::getFormat(AMediaFormat *meta) {
6130 Mutex::Autolock autoLock(mLock);
6131 AMediaFormat_copy(meta, mFormat);
6132 return AMEDIA_OK;
6133 }
6134
parseNALSize(const uint8_t * data) const6135 size_t MPEG4Source::parseNALSize(const uint8_t *data) const {
6136 switch (mNALLengthSize) {
6137 case 1:
6138 return *data;
6139 case 2:
6140 return U16_AT(data);
6141 case 3:
6142 return ((size_t)data[0] << 16) | U16_AT(&data[1]);
6143 case 4:
6144 return U32_AT(data);
6145 }
6146
6147 // This cannot happen, mNALLengthSize springs to life by adding 1 to
6148 // a 2-bit integer.
6149 CHECK(!"Should not be here.");
6150
6151 return 0;
6152 }
6153
parseHEVCLayerId(const uint8_t * data,size_t size)6154 int32_t MPEG4Source::parseHEVCLayerId(const uint8_t *data, size_t size) {
6155 if (data == nullptr || size < mNALLengthSize + 2) {
6156 return -1;
6157 }
6158
6159 // HEVC NAL-header (16-bit)
6160 // 1 6 6 3
6161 // |-|uuuuuu|------|iii|
6162 // ^ ^
6163 // NAL_type layer_id + 1
6164 //
6165 // Layer-id is non-zero only for Temporal Sub-layer Access pictures (TSA)
6166 enum {
6167 TSA_N = 2,
6168 TSA_R = 3,
6169 STSA_N = 4,
6170 STSA_R = 5,
6171 };
6172
6173 data += mNALLengthSize;
6174 uint16_t nalHeader = data[0] << 8 | data[1];
6175
6176 uint16_t nalType = (nalHeader >> 9) & 0x3Fu;
6177 if (nalType == TSA_N || nalType == TSA_R || nalType == STSA_N || nalType == STSA_R) {
6178 int32_t layerIdPlusOne = nalHeader & 0x7u;
6179 ALOGD_IF(layerIdPlusOne == 0, "got layerId 0 for TSA picture");
6180 return layerIdPlusOne - 1;
6181 }
6182 return 0;
6183 }
6184
getNALLengthSizeFromAvcCsd(const uint8_t * data,const size_t size) const6185 size_t MPEG4Source::getNALLengthSizeFromAvcCsd(const uint8_t *data, const size_t size) const {
6186 CHECK(data != nullptr);
6187 CHECK(size >= 7);
6188 CHECK_EQ((unsigned)data[0], 1u); // configurationVersion == 1
6189
6190 // The number of bytes used to encode the length of a NAL unit.
6191 return 1 + (data[4] & 3);
6192 }
6193
getNALLengthSizeFromHevcCsd(const uint8_t * data,const size_t size) const6194 size_t MPEG4Source::getNALLengthSizeFromHevcCsd(const uint8_t *data, const size_t size) const {
6195 CHECK(data != nullptr);
6196 CHECK(size >= 22);
6197 CHECK_EQ((unsigned)data[0], 1u); // configurationVersion == 1
6198
6199 // The number of bytes used to encode the length of a NAL unit.
6200 return 1 + (data[14 + 7] & 3);
6201 }
6202
read(MediaBufferHelper ** out,const ReadOptions * options)6203 media_status_t MPEG4Source::read(
6204 MediaBufferHelper **out, const ReadOptions *options) {
6205 Mutex::Autolock autoLock(mLock);
6206
6207 CHECK(mStarted);
6208
6209 if (options != nullptr && options->getNonBlocking() && !mBufferGroup->has_buffers()) {
6210 *out = nullptr;
6211 return AMEDIA_ERROR_WOULD_BLOCK;
6212 }
6213
6214 if (mFirstMoofOffset > 0) {
6215 return fragmentedRead(out, options);
6216 }
6217
6218 *out = NULL;
6219
6220 int64_t targetSampleTimeUs = -1;
6221
6222 int64_t seekTimeUs;
6223 ReadOptions::SeekMode mode;
6224
6225 if (options && options->getSeekTo(&seekTimeUs, &mode)) {
6226 ALOGV("seekTimeUs:%" PRId64, seekTimeUs);
6227 if (mIsHeif || mIsAvif) {
6228 CHECK(mSampleTable == NULL);
6229 CHECK(mItemTable != NULL);
6230 int32_t imageIndex;
6231 if (!AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_TRACK_ID, &imageIndex)) {
6232 return AMEDIA_ERROR_MALFORMED;
6233 }
6234
6235 status_t err;
6236 if (seekTimeUs >= 0) {
6237 err = mItemTable->findImageItem(imageIndex, &mCurrentSampleIndex);
6238 } else {
6239 err = mItemTable->findThumbnailItem(imageIndex, &mCurrentSampleIndex);
6240 }
6241 if (err != OK) {
6242 return AMEDIA_ERROR_UNKNOWN;
6243 }
6244 } else {
6245 uint32_t findFlags = 0;
6246 switch (mode) {
6247 case ReadOptions::SEEK_PREVIOUS_SYNC:
6248 findFlags = SampleTable::kFlagBefore;
6249 break;
6250 case ReadOptions::SEEK_NEXT_SYNC:
6251 findFlags = SampleTable::kFlagAfter;
6252 break;
6253 case ReadOptions::SEEK_CLOSEST_SYNC:
6254 case ReadOptions::SEEK_CLOSEST:
6255 findFlags = SampleTable::kFlagClosest;
6256 break;
6257 case ReadOptions::SEEK_FRAME_INDEX:
6258 findFlags = SampleTable::kFlagFrameIndex;
6259 break;
6260 default:
6261 CHECK(!"Should not be here.");
6262 break;
6263 }
6264 if( mode != ReadOptions::SEEK_FRAME_INDEX) {
6265 int64_t elstInitialEmptyEditUs = 0, elstShiftStartUs = 0;
6266 if (mElstInitialEmptyEditTicks > 0) {
6267 elstInitialEmptyEditUs = ((long double)mElstInitialEmptyEditTicks * 1000000) /
6268 mTimescale;
6269 /* Sample's composition time from ctts/stts entries are non-negative(>=0).
6270 * Hence, lower bound on seekTimeUs is 0.
6271 */
6272 seekTimeUs = std::max(seekTimeUs - elstInitialEmptyEditUs, (int64_t)0);
6273 }
6274 if (mElstShiftStartTicks > 0) {
6275 elstShiftStartUs = ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
6276 seekTimeUs += elstShiftStartUs;
6277 }
6278 ALOGV("shifted seekTimeUs:%" PRId64 ", elstInitialEmptyEditUs:%" PRIu64
6279 ", elstShiftStartUs:%" PRIu64, seekTimeUs, elstInitialEmptyEditUs,
6280 elstShiftStartUs);
6281 }
6282
6283 uint32_t sampleIndex;
6284 status_t err = mSampleTable->findSampleAtTime(
6285 seekTimeUs, 1000000, mTimescale,
6286 &sampleIndex, findFlags);
6287
6288 if (mode == ReadOptions::SEEK_CLOSEST
6289 || mode == ReadOptions::SEEK_FRAME_INDEX) {
6290 // We found the closest sample already, now we want the sync
6291 // sample preceding it (or the sample itself of course), even
6292 // if the subsequent sync sample is closer.
6293 findFlags = SampleTable::kFlagBefore;
6294 }
6295
6296 uint32_t syncSampleIndex = sampleIndex;
6297 // assume every non-USAC/non-MPEGH audio sample is a sync sample.
6298 // This works around
6299 // seek issues with files that were incorrectly written with an
6300 // empty or single-sample stss block for the audio track
6301 if (err == OK && (!mIsAudio || mIsUsac || mIsMpegH)) {
6302 err = mSampleTable->findSyncSampleNear(
6303 sampleIndex, &syncSampleIndex, findFlags);
6304 }
6305
6306 uint64_t sampleTime;
6307 if (err == OK) {
6308 err = mSampleTable->getMetaDataForSample(
6309 sampleIndex, NULL, NULL, &sampleTime);
6310 }
6311
6312 if (err != OK) {
6313 if (err == ERROR_OUT_OF_RANGE) {
6314 // An attempt to seek past the end of the stream would
6315 // normally cause this ERROR_OUT_OF_RANGE error. Propagating
6316 // this all the way to the MediaPlayer would cause abnormal
6317 // termination. Legacy behaviour appears to be to behave as if
6318 // we had seeked to the end of stream, ending normally.
6319 return AMEDIA_ERROR_END_OF_STREAM;
6320 }
6321 ALOGV("end of stream");
6322 return AMEDIA_ERROR_UNKNOWN;
6323 }
6324
6325 if (mode == ReadOptions::SEEK_CLOSEST
6326 || mode == ReadOptions::SEEK_FRAME_INDEX) {
6327 if (mElstInitialEmptyEditTicks > 0) {
6328 sampleTime += mElstInitialEmptyEditTicks;
6329 }
6330 if (mElstShiftStartTicks > 0){
6331 if (sampleTime > mElstShiftStartTicks) {
6332 sampleTime -= mElstShiftStartTicks;
6333 } else {
6334 sampleTime = 0;
6335 }
6336 }
6337 targetSampleTimeUs = (sampleTime * 1000000ll) / mTimescale;
6338 }
6339
6340 #if 0
6341 uint32_t syncSampleTime;
6342 CHECK_EQ(OK, mSampleTable->getMetaDataForSample(
6343 syncSampleIndex, NULL, NULL, &syncSampleTime));
6344
6345 ALOGI("seek to time %lld us => sample at time %lld us, "
6346 "sync sample at time %lld us",
6347 seekTimeUs,
6348 sampleTime * 1000000ll / mTimescale,
6349 syncSampleTime * 1000000ll / mTimescale);
6350 #endif
6351
6352 mCurrentSampleIndex = syncSampleIndex;
6353 }
6354
6355 if (mBuffer != NULL) {
6356 mBuffer->release();
6357 mBuffer = NULL;
6358 }
6359
6360 // fall through
6361 }
6362
6363 off64_t offset = 0;
6364 size_t size = 0;
6365 int64_t cts;
6366 uint64_t stts;
6367 bool isSyncSample;
6368 bool newBuffer = false;
6369 if (mBuffer == NULL) {
6370 newBuffer = true;
6371
6372 status_t err;
6373 if (!mIsHeif && !mIsAvif) {
6374 err = mSampleTable->getMetaDataForSample(mCurrentSampleIndex, &offset, &size,
6375 (uint64_t*)&cts, &isSyncSample, &stts);
6376 if(err == OK) {
6377 if (mElstInitialEmptyEditTicks > 0) {
6378 cts += mElstInitialEmptyEditTicks;
6379 }
6380 if (mElstShiftStartTicks > 0) {
6381 // cts can be negative. for example, initial audio samples for gapless playback.
6382 cts -= (int64_t)mElstShiftStartTicks;
6383 }
6384 }
6385 } else {
6386 err = mItemTable->getImageOffsetAndSize(
6387 options && options->getSeekTo(&seekTimeUs, &mode) ?
6388 &mCurrentSampleIndex : NULL, &offset, &size);
6389
6390 cts = stts = 0;
6391 isSyncSample = 0;
6392 ALOGV("image offset %lld, size %zu", (long long)offset, size);
6393 }
6394
6395 if (err != OK) {
6396 if (err == ERROR_END_OF_STREAM) {
6397 return AMEDIA_ERROR_END_OF_STREAM;
6398 }
6399 return AMEDIA_ERROR_UNKNOWN;
6400 }
6401
6402 err = mBufferGroup->acquire_buffer(&mBuffer);
6403
6404 if (err != OK || mBuffer == nullptr) {
6405 CHECK(mBuffer == NULL);
6406 return AMEDIA_ERROR_UNKNOWN;
6407 }
6408 if (size > mBuffer->size()) {
6409 ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
6410 mBuffer->release();
6411 mBuffer = NULL;
6412 return AMEDIA_ERROR_UNKNOWN; // ERROR_BUFFER_TOO_SMALL
6413 }
6414 }
6415
6416 if (!mIsAVC && !mIsHEVC && !(mIsDolbyVision && mNALLengthSize) && !mIsAC4) {
6417 if (newBuffer) {
6418 if (mIsPcm) {
6419 // The twos' PCM block reader assumes that all samples has the same size.
6420 uint32_t lastSampleIndexInChunk = mSampleTable->getLastSampleIndexInChunk();
6421 if (lastSampleIndexInChunk < mCurrentSampleIndex) {
6422 mBuffer->release();
6423 mBuffer = nullptr;
6424 return AMEDIA_ERROR_UNKNOWN;
6425 }
6426 uint32_t samplesToRead = lastSampleIndexInChunk - mCurrentSampleIndex + 1;
6427 if (samplesToRead > kMaxPcmFrameSize) {
6428 samplesToRead = kMaxPcmFrameSize;
6429 }
6430
6431 ALOGV("Reading %d PCM frames of size %zu at index %d to stop of chunk at %d",
6432 samplesToRead, size, mCurrentSampleIndex,
6433 mSampleTable->getLastSampleIndexInChunk());
6434
6435 size_t totalSize = samplesToRead * size;
6436 if (mBuffer->size() < totalSize) {
6437 mBuffer->release();
6438 mBuffer = nullptr;
6439 return AMEDIA_ERROR_UNKNOWN;
6440 }
6441 uint8_t* buf = (uint8_t *)mBuffer->data();
6442 ssize_t bytesRead = mDataSource->readAt(offset, buf, totalSize);
6443 if (bytesRead < (ssize_t)totalSize) {
6444 mBuffer->release();
6445 mBuffer = NULL;
6446 return AMEDIA_ERROR_IO;
6447 }
6448
6449 AMediaFormat *meta = mBuffer->meta_data();
6450 AMediaFormat_clear(meta);
6451 AMediaFormat_setInt64(
6452 meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
6453 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
6454
6455 int32_t byteOrder = 0;
6456 bool isGetBigEndian = AMediaFormat_getInt32(mFormat,
6457 AMEDIAFORMAT_KEY_PCM_BIG_ENDIAN, &byteOrder);
6458
6459 if (isGetBigEndian && byteOrder == 1) {
6460 // Big-endian -> little-endian
6461 uint16_t *dstData = (uint16_t *)buf;
6462 uint16_t *srcData = (uint16_t *)buf;
6463
6464 for (size_t j = 0; j < bytesRead / sizeof(uint16_t); j++) {
6465 dstData[j] = ntohs(srcData[j]);
6466 }
6467 }
6468
6469 mCurrentSampleIndex += samplesToRead;
6470 mBuffer->set_range(0, totalSize);
6471 } else {
6472 ssize_t num_bytes_read =
6473 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
6474
6475 if (num_bytes_read < (ssize_t)size) {
6476 mBuffer->release();
6477 mBuffer = NULL;
6478
6479 return AMEDIA_ERROR_IO;
6480 }
6481
6482 CHECK(mBuffer != NULL);
6483 mBuffer->set_range(0, size);
6484 AMediaFormat *meta = mBuffer->meta_data();
6485 AMediaFormat_clear(meta);
6486 AMediaFormat_setInt64(
6487 meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
6488 AMediaFormat_setInt64(
6489 meta, AMEDIAFORMAT_KEY_DURATION, ((long double)stts * 1000000) / mTimescale);
6490
6491 if (targetSampleTimeUs >= 0) {
6492 AMediaFormat_setInt64(
6493 meta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
6494 }
6495
6496 if (isSyncSample) {
6497 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
6498 }
6499
6500 AMediaFormat_setInt64(
6501 meta, "sample-file-offset" /*AMEDIAFORMAT_KEY_SAMPLE_FILE_OFFSET*/,
6502 offset);
6503
6504 if (mSampleTable != nullptr &&
6505 mCurrentSampleIndex == mSampleTable->getLastSampleIndexInChunk()) {
6506 AMediaFormat_setInt64(
6507 meta,
6508 "last-sample-index-in-chunk" /*AMEDIAFORMAT_KEY_LAST_SAMPLE_INDEX_IN_CHUNK*/,
6509 mSampleTable->getLastSampleIndexInChunk());
6510 }
6511
6512 ++mCurrentSampleIndex;
6513 }
6514 }
6515
6516 *out = mBuffer;
6517 mBuffer = NULL;
6518
6519 return AMEDIA_OK;
6520
6521 } else if (mIsAC4) {
6522 CHECK(mBuffer != NULL);
6523 // Make sure there is enough space to write the sync header and the raw frame
6524 if (mBuffer->range_length() < (7 + size)) {
6525 mBuffer->release();
6526 mBuffer = NULL;
6527
6528 return AMEDIA_ERROR_IO;
6529 }
6530
6531 uint8_t *dstData = (uint8_t *)mBuffer->data();
6532 size_t dstOffset = 0;
6533 // Add AC-4 sync header to MPEG4 encapsulated AC-4 raw frame
6534 // AC40 sync word, meaning no CRC at the end of the frame
6535 dstData[dstOffset++] = 0xAC;
6536 dstData[dstOffset++] = 0x40;
6537 dstData[dstOffset++] = 0xFF;
6538 dstData[dstOffset++] = 0xFF;
6539 dstData[dstOffset++] = (uint8_t)((size >> 16) & 0xFF);
6540 dstData[dstOffset++] = (uint8_t)((size >> 8) & 0xFF);
6541 dstData[dstOffset++] = (uint8_t)((size >> 0) & 0xFF);
6542
6543 ssize_t numBytesRead = mDataSource->readAt(offset, dstData + dstOffset, size);
6544 if (numBytesRead != (ssize_t)size) {
6545 mBuffer->release();
6546 mBuffer = NULL;
6547
6548 return AMEDIA_ERROR_IO;
6549 }
6550
6551 mBuffer->set_range(0, dstOffset + size);
6552 AMediaFormat *meta = mBuffer->meta_data();
6553 AMediaFormat_clear(meta);
6554 AMediaFormat_setInt64(
6555 meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
6556 AMediaFormat_setInt64(
6557 meta, AMEDIAFORMAT_KEY_DURATION, ((long double)stts * 1000000) / mTimescale);
6558
6559 if (targetSampleTimeUs >= 0) {
6560 AMediaFormat_setInt64(
6561 meta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
6562 }
6563
6564 if (isSyncSample) {
6565 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
6566 }
6567
6568 void *presentationsData;
6569 size_t presentationsSize;
6570 if (AMediaFormat_getBuffer(
6571 mFormat, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO,
6572 &presentationsData, &presentationsSize)) {
6573 AMediaFormat_setBuffer(
6574 meta, AMEDIAFORMAT_KEY_AUDIO_PRESENTATION_INFO,
6575 presentationsData, presentationsSize);
6576 }
6577
6578 ++mCurrentSampleIndex;
6579
6580 *out = mBuffer;
6581 mBuffer = NULL;
6582
6583 return AMEDIA_OK;
6584 } else {
6585 // Whole NAL units are returned but each fragment is prefixed by
6586 // the start code (0x00 00 00 01).
6587 ssize_t num_bytes_read = 0;
6588 bool mSrcBufferFitsDataToRead = size <= mSrcBufferSize;
6589 if (mSrcBufferFitsDataToRead) {
6590 num_bytes_read = mDataSource->readAt(offset, mSrcBuffer, size);
6591 } else {
6592 // We are trying to read a sample larger than the expected max sample size.
6593 // Fall through and let the failure be handled by the following if.
6594 android_errorWriteLog(0x534e4554, "188893559");
6595 }
6596
6597 if (num_bytes_read < (ssize_t)size) {
6598 mBuffer->release();
6599 mBuffer = NULL;
6600 return mSrcBufferFitsDataToRead ? AMEDIA_ERROR_IO : AMEDIA_ERROR_MALFORMED;
6601 }
6602
6603 uint8_t *dstData = (uint8_t *)mBuffer->data();
6604 size_t srcOffset = 0;
6605 size_t dstOffset = 0;
6606
6607 while (srcOffset < size) {
6608 bool isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
6609 size_t nalLength = 0;
6610 if (!isMalFormed) {
6611 nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
6612 srcOffset += mNALLengthSize;
6613 isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength);
6614 }
6615
6616 if (isMalFormed) {
6617 //if nallength abnormal,ignore it.
6618 ALOGW("abnormal nallength, ignore this NAL");
6619 srcOffset = size;
6620 break;
6621 }
6622
6623 if (nalLength == 0) {
6624 continue;
6625 }
6626
6627 if (dstOffset > SIZE_MAX - 4 ||
6628 dstOffset + 4 > SIZE_MAX - nalLength ||
6629 dstOffset + 4 + nalLength > mBuffer->size()) {
6630 ALOGE("b/27208621 : %zu %zu", dstOffset, mBuffer->size());
6631 android_errorWriteLog(0x534e4554, "27208621");
6632 mBuffer->release();
6633 mBuffer = NULL;
6634 return AMEDIA_ERROR_MALFORMED;
6635 }
6636
6637 dstData[dstOffset++] = 0;
6638 dstData[dstOffset++] = 0;
6639 dstData[dstOffset++] = 0;
6640 dstData[dstOffset++] = 1;
6641 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
6642 srcOffset += nalLength;
6643 dstOffset += nalLength;
6644 }
6645 CHECK_EQ(srcOffset, size);
6646 CHECK(mBuffer != NULL);
6647 mBuffer->set_range(0, dstOffset);
6648
6649 AMediaFormat *meta = mBuffer->meta_data();
6650 AMediaFormat_clear(meta);
6651 AMediaFormat_setInt64(
6652 meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
6653 AMediaFormat_setInt64(
6654 meta, AMEDIAFORMAT_KEY_DURATION, ((long double)stts * 1000000) / mTimescale);
6655
6656 if (targetSampleTimeUs >= 0) {
6657 AMediaFormat_setInt64(
6658 meta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
6659 }
6660
6661 if (mIsAVC) {
6662 uint32_t layerId = FindAVCLayerId(
6663 (const uint8_t *)mBuffer->data(), mBuffer->range_length());
6664 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
6665 } else if (mIsHEVC) {
6666 int32_t layerId = parseHEVCLayerId(
6667 (const uint8_t *)mBuffer->data(), mBuffer->range_length());
6668 if (layerId >= 0) {
6669 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
6670 }
6671 }
6672
6673 if (isSyncSample) {
6674 AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
6675 }
6676
6677 AMediaFormat_setInt64(
6678 meta, "sample-file-offset" /*AMEDIAFORMAT_KEY_SAMPLE_FILE_OFFSET*/, offset);
6679
6680 if (mSampleTable != nullptr &&
6681 mCurrentSampleIndex == mSampleTable->getLastSampleIndexInChunk()) {
6682 AMediaFormat_setInt64(
6683 meta,
6684 "last-sample-index-in-chunk" /*AMEDIAFORMAT_KEY_LAST_SAMPLE_INDEX_IN_CHUNK*/,
6685 mSampleTable->getLastSampleIndexInChunk());
6686 }
6687
6688 ++mCurrentSampleIndex;
6689
6690 *out = mBuffer;
6691 mBuffer = NULL;
6692
6693 return AMEDIA_OK;
6694 }
6695 }
6696
fragmentedRead(MediaBufferHelper ** out,const ReadOptions * options)6697 media_status_t MPEG4Source::fragmentedRead(
6698 MediaBufferHelper **out, const ReadOptions *options) {
6699
6700 ALOGV("MPEG4Source::fragmentedRead");
6701
6702 CHECK(mStarted);
6703
6704 *out = NULL;
6705
6706 int64_t targetSampleTimeUs = -1;
6707
6708 int64_t seekTimeUs;
6709 ReadOptions::SeekMode mode;
6710 if (options && options->getSeekTo(&seekTimeUs, &mode)) {
6711 ALOGV("seekTimeUs:%" PRId64, seekTimeUs);
6712 int64_t elstInitialEmptyEditUs = 0, elstShiftStartUs = 0;
6713 if (mElstInitialEmptyEditTicks > 0) {
6714 elstInitialEmptyEditUs = ((long double)mElstInitialEmptyEditTicks * 1000000) /
6715 mTimescale;
6716 /* Sample's composition time from ctts/stts entries are non-negative(>=0).
6717 * Hence, lower bound on seekTimeUs is 0.
6718 */
6719 seekTimeUs = std::max(seekTimeUs - elstInitialEmptyEditUs, (int64_t)0);
6720 }
6721 if (mElstShiftStartTicks > 0){
6722 elstShiftStartUs = ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
6723 seekTimeUs += elstShiftStartUs;
6724 }
6725 ALOGV("shifted seekTimeUs:%" PRId64 ", elstInitialEmptyEditUs:%" PRIu64
6726 ", elstShiftStartUs:%" PRIu64, seekTimeUs, elstInitialEmptyEditUs,
6727 elstShiftStartUs);
6728
6729 int numSidxEntries = mSegments.size();
6730 if (numSidxEntries != 0) {
6731 int64_t totalTime = 0;
6732 off64_t totalOffset = mFirstMoofOffset;
6733 for (int i = 0; i < numSidxEntries; i++) {
6734 const SidxEntry *se = &mSegments[i];
6735 if (totalTime + se->mDurationUs > seekTimeUs) {
6736 // The requested time is somewhere in this segment
6737 if ((mode == ReadOptions::SEEK_NEXT_SYNC && seekTimeUs > totalTime) ||
6738 (mode == ReadOptions::SEEK_CLOSEST_SYNC &&
6739 (seekTimeUs - totalTime) > (totalTime + se->mDurationUs - seekTimeUs))) {
6740 // requested next sync, or closest sync and it was closer to the end of
6741 // this segment
6742 totalTime += se->mDurationUs;
6743 totalOffset += se->mSize;
6744 }
6745 break;
6746 }
6747 totalTime += se->mDurationUs;
6748 totalOffset += se->mSize;
6749 }
6750 mCurrentMoofOffset = totalOffset;
6751 mNextMoofOffset = -1;
6752 mCurrentSamples.clear();
6753 mCurrentSampleIndex = 0;
6754 status_t err = parseChunk(&totalOffset);
6755 if (err != OK) {
6756 return AMEDIA_ERROR_UNKNOWN;
6757 }
6758 mCurrentTime = totalTime * mTimescale / 1000000ll;
6759 } else {
6760 // without sidx boxes, we can only seek to 0
6761 mCurrentMoofOffset = mFirstMoofOffset;
6762 mNextMoofOffset = -1;
6763 mCurrentSamples.clear();
6764 mCurrentSampleIndex = 0;
6765 off64_t tmp = mCurrentMoofOffset;
6766 status_t err = parseChunk(&tmp);
6767 if (err != OK) {
6768 return AMEDIA_ERROR_UNKNOWN;
6769 }
6770 mCurrentTime = 0;
6771 }
6772
6773 if (mBuffer != NULL) {
6774 mBuffer->release();
6775 mBuffer = NULL;
6776 }
6777
6778 // fall through
6779 }
6780
6781 off64_t offset = 0;
6782 size_t size = 0;
6783 int64_t cts = 0;
6784 bool isSyncSample = false;
6785 bool newBuffer = false;
6786 if (mBuffer == NULL || mCurrentSampleIndex >= mCurrentSamples.size()) {
6787 newBuffer = true;
6788
6789 if (mBuffer != NULL) {
6790 mBuffer->release();
6791 mBuffer = NULL;
6792 }
6793 if (mCurrentSampleIndex >= mCurrentSamples.size()) {
6794 // move to next fragment if there is one
6795 if (mNextMoofOffset <= mCurrentMoofOffset) {
6796 return AMEDIA_ERROR_END_OF_STREAM;
6797 }
6798 off64_t nextMoof = mNextMoofOffset;
6799 mCurrentMoofOffset = nextMoof;
6800 mCurrentSamples.clear();
6801 mCurrentSampleIndex = 0;
6802 status_t err = parseChunk(&nextMoof);
6803 if (err != OK) {
6804 return AMEDIA_ERROR_UNKNOWN;
6805 }
6806 if (mCurrentSampleIndex >= mCurrentSamples.size()) {
6807 return AMEDIA_ERROR_END_OF_STREAM;
6808 }
6809 }
6810
6811 const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
6812 offset = smpl->offset;
6813 size = smpl->size;
6814 cts = (int64_t)mCurrentTime + (int64_t)smpl->compositionOffset;
6815
6816 if (mElstInitialEmptyEditTicks > 0) {
6817 cts += mElstInitialEmptyEditTicks;
6818 }
6819 if (mElstShiftStartTicks > 0) {
6820 // cts can be negative. for example, initial audio samples for gapless playback.
6821 cts -= (int64_t)mElstShiftStartTicks;
6822 }
6823
6824 mCurrentTime += smpl->duration;
6825 isSyncSample = (mCurrentSampleIndex == 0);
6826
6827 status_t err = mBufferGroup->acquire_buffer(&mBuffer);
6828
6829 if (err != OK) {
6830 CHECK(mBuffer == NULL);
6831 ALOGV("acquire_buffer returned %d", err);
6832 return AMEDIA_ERROR_UNKNOWN;
6833 }
6834 if (size > mBuffer->size()) {
6835 ALOGE("buffer too small: %zu > %zu", size, mBuffer->size());
6836 mBuffer->release();
6837 mBuffer = NULL;
6838 return AMEDIA_ERROR_UNKNOWN;
6839 }
6840 }
6841
6842 const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
6843 AMediaFormat *bufmeta = mBuffer->meta_data();
6844 AMediaFormat_clear(bufmeta);
6845 if (smpl->encryptedsizes.size()) {
6846 // store clear/encrypted lengths in metadata
6847 AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
6848 smpl->clearsizes.array(), smpl->clearsizes.size() * sizeof(uint32_t));
6849 AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
6850 smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * sizeof(uint32_t));
6851 AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, mDefaultIVSize);
6852 AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_MODE, mCryptoMode);
6853 AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_KEY, mCryptoKey, 16);
6854 AMediaFormat_setInt32(bufmeta,
6855 AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK, mDefaultEncryptedByteBlock);
6856 AMediaFormat_setInt32(bufmeta,
6857 AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK, mDefaultSkipByteBlock);
6858
6859 void *iv = NULL;
6860 size_t ivlength = 0;
6861 if (!AMediaFormat_getBuffer(mFormat,
6862 "crypto-iv", &iv, &ivlength)) {
6863 iv = (void *) smpl->iv;
6864 ivlength = 16; // use 16 or the actual size?
6865 }
6866 AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_IV, iv, ivlength);
6867 }
6868
6869 if (!mIsAVC && !mIsHEVC && !(mIsDolbyVision && mNALLengthSize)) {
6870 if (newBuffer) {
6871 if (!isInRange((size_t)0u, mBuffer->size(), size)) {
6872 mBuffer->release();
6873 mBuffer = NULL;
6874
6875 ALOGE("fragmentedRead ERROR_MALFORMED size %zu", size);
6876 return AMEDIA_ERROR_MALFORMED;
6877 }
6878
6879 ssize_t num_bytes_read =
6880 mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);
6881
6882 if (num_bytes_read < (ssize_t)size) {
6883 mBuffer->release();
6884 mBuffer = NULL;
6885
6886 ALOGE("i/o error");
6887 return AMEDIA_ERROR_IO;
6888 }
6889
6890 CHECK(mBuffer != NULL);
6891 mBuffer->set_range(0, size);
6892 AMediaFormat_setInt64(bufmeta,
6893 AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
6894 AMediaFormat_setInt64(bufmeta,
6895 AMEDIAFORMAT_KEY_DURATION, ((long double)smpl->duration * 1000000) / mTimescale);
6896
6897 if (targetSampleTimeUs >= 0) {
6898 AMediaFormat_setInt64(bufmeta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
6899 }
6900
6901 if (mIsAVC) {
6902 uint32_t layerId = FindAVCLayerId(
6903 (const uint8_t *)mBuffer->data(), mBuffer->range_length());
6904 AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
6905 } else if (mIsHEVC) {
6906 int32_t layerId = parseHEVCLayerId(
6907 (const uint8_t *)mBuffer->data(), mBuffer->range_length());
6908 if (layerId >= 0) {
6909 AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
6910 }
6911 }
6912
6913 if (isSyncSample) {
6914 AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
6915 }
6916
6917 ++mCurrentSampleIndex;
6918 }
6919
6920 *out = mBuffer;
6921 mBuffer = NULL;
6922
6923 return AMEDIA_OK;
6924
6925 } else {
6926 ALOGV("whole NAL");
6927 // Whole NAL units are returned but each fragment is prefixed by
6928 // the start code (0x00 00 00 01).
6929 ssize_t num_bytes_read = 0;
6930 void *data = NULL;
6931 bool isMalFormed = false;
6932 int32_t max_size;
6933 if (!AMediaFormat_getInt32(mFormat, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, &max_size)
6934 || !isInRange((size_t)0u, (size_t)max_size, size)) {
6935 isMalFormed = true;
6936 } else {
6937 data = mSrcBuffer;
6938 }
6939
6940 if (isMalFormed || data == NULL) {
6941 ALOGE("isMalFormed size %zu", size);
6942 if (mBuffer != NULL) {
6943 mBuffer->release();
6944 mBuffer = NULL;
6945 }
6946 return AMEDIA_ERROR_MALFORMED;
6947 }
6948 num_bytes_read = mDataSource->readAt(offset, data, size);
6949
6950 if (num_bytes_read < (ssize_t)size) {
6951 mBuffer->release();
6952 mBuffer = NULL;
6953
6954 ALOGE("i/o error");
6955 return AMEDIA_ERROR_IO;
6956 }
6957
6958 uint8_t *dstData = (uint8_t *)mBuffer->data();
6959 size_t srcOffset = 0;
6960 size_t dstOffset = 0;
6961
6962 while (srcOffset < size) {
6963 isMalFormed = !isInRange((size_t)0u, size, srcOffset, mNALLengthSize);
6964 size_t nalLength = 0;
6965 if (!isMalFormed) {
6966 nalLength = parseNALSize(&mSrcBuffer[srcOffset]);
6967 srcOffset += mNALLengthSize;
6968 isMalFormed = !isInRange((size_t)0u, size, srcOffset, nalLength)
6969 || !isInRange((size_t)0u, mBuffer->size(), dstOffset, (size_t)4u)
6970 || !isInRange((size_t)0u, mBuffer->size(), dstOffset + 4, nalLength);
6971 }
6972
6973 if (isMalFormed) {
6974 ALOGE("Video is malformed; nalLength %zu", nalLength);
6975 mBuffer->release();
6976 mBuffer = NULL;
6977 return AMEDIA_ERROR_MALFORMED;
6978 }
6979
6980 if (nalLength == 0) {
6981 continue;
6982 }
6983
6984 if (dstOffset > SIZE_MAX - 4 ||
6985 dstOffset + 4 > SIZE_MAX - nalLength ||
6986 dstOffset + 4 + nalLength > mBuffer->size()) {
6987 ALOGE("b/26365349 : %zu %zu", dstOffset, mBuffer->size());
6988 android_errorWriteLog(0x534e4554, "26365349");
6989 mBuffer->release();
6990 mBuffer = NULL;
6991 return AMEDIA_ERROR_MALFORMED;
6992 }
6993
6994 dstData[dstOffset++] = 0;
6995 dstData[dstOffset++] = 0;
6996 dstData[dstOffset++] = 0;
6997 dstData[dstOffset++] = 1;
6998 memcpy(&dstData[dstOffset], &mSrcBuffer[srcOffset], nalLength);
6999 srcOffset += nalLength;
7000 dstOffset += nalLength;
7001 }
7002 CHECK_EQ(srcOffset, size);
7003 CHECK(mBuffer != NULL);
7004 mBuffer->set_range(0, dstOffset);
7005
7006 AMediaFormat *bufmeta = mBuffer->meta_data();
7007 AMediaFormat_setInt64(bufmeta,
7008 AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
7009 AMediaFormat_setInt64(bufmeta,
7010 AMEDIAFORMAT_KEY_DURATION, ((long double)smpl->duration * 1000000) / mTimescale);
7011
7012 if (targetSampleTimeUs >= 0) {
7013 AMediaFormat_setInt64(bufmeta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
7014 }
7015
7016 if (isSyncSample) {
7017 AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
7018 }
7019
7020 ++mCurrentSampleIndex;
7021
7022 *out = mBuffer;
7023 mBuffer = NULL;
7024
7025 return AMEDIA_OK;
7026 }
7027
7028 return AMEDIA_OK;
7029 }
7030
findTrackByMimePrefix(const char * mimePrefix)7031 MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
7032 const char *mimePrefix) {
7033 for (Track *track = mFirstTrack; track != NULL; track = track->next) {
7034 const char *mime;
7035 if (AMediaFormat_getString(track->meta, AMEDIAFORMAT_KEY_MIME, &mime)
7036 && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) {
7037 return track;
7038 }
7039 }
7040
7041 return NULL;
7042 }
7043
LegacySniffMPEG4(DataSourceHelper * source,float * confidence)7044 static bool LegacySniffMPEG4(DataSourceHelper *source, float *confidence) {
7045 uint8_t header[8];
7046
7047 ssize_t n = source->readAt(4, header, sizeof(header));
7048 if (n < (ssize_t)sizeof(header)) {
7049 return false;
7050 }
7051
7052 if (!memcmp(header, "ftyp3gp", 7) || !memcmp(header, "ftypmp42", 8)
7053 || !memcmp(header, "ftyp3gr6", 8) || !memcmp(header, "ftyp3gs6", 8)
7054 || !memcmp(header, "ftyp3ge6", 8) || !memcmp(header, "ftyp3gg6", 8)
7055 || !memcmp(header, "ftypisom", 8) || !memcmp(header, "ftypM4V ", 8)
7056 || !memcmp(header, "ftypM4A ", 8) || !memcmp(header, "ftypf4v ", 8)
7057 || !memcmp(header, "ftypkddi", 8) || !memcmp(header, "ftypM4VP", 8)
7058 || !memcmp(header, "ftypmif1", 8) || !memcmp(header, "ftypheic", 8)
7059 || !memcmp(header, "ftypmsf1", 8) || !memcmp(header, "ftyphevc", 8)
7060 || !memcmp(header, "ftypavif", 8) || !memcmp(header, "ftypavis", 8)) {
7061 *confidence = 0.4;
7062
7063 return true;
7064 }
7065
7066 return false;
7067 }
7068
isCompatibleBrand(uint32_t fourcc)7069 static bool isCompatibleBrand(uint32_t fourcc) {
7070 static const uint32_t kCompatibleBrands[] = {
7071 FOURCC("isom"),
7072 FOURCC("iso2"),
7073 FOURCC("avc1"),
7074 FOURCC("hvc1"),
7075 FOURCC("hev1"),
7076 FOURCC("av01"),
7077 FOURCC("vp09"),
7078 FOURCC("3gp4"),
7079 FOURCC("mp41"),
7080 FOURCC("mp42"),
7081 FOURCC("dash"),
7082 FOURCC("nvr1"),
7083
7084 // Won't promise that the following file types can be played.
7085 // Just give these file types a chance.
7086 FOURCC("qt "), // Apple's QuickTime
7087 FOURCC("MSNV"), // Sony's PSP
7088 FOURCC("wmf "),
7089
7090 FOURCC("3g2a"), // 3GPP2
7091 FOURCC("3g2b"),
7092 FOURCC("mif1"), // HEIF image
7093 FOURCC("heic"), // HEIF image
7094 FOURCC("msf1"), // HEIF image sequence
7095 FOURCC("hevc"), // HEIF image sequence
7096 FOURCC("avif"), // AVIF image
7097 FOURCC("avis"), // AVIF image sequence
7098 };
7099
7100 for (size_t i = 0;
7101 i < sizeof(kCompatibleBrands) / sizeof(kCompatibleBrands[0]);
7102 ++i) {
7103 if (kCompatibleBrands[i] == fourcc) {
7104 return true;
7105 }
7106 }
7107
7108 return false;
7109 }
7110
7111 // Attempt to actually parse the 'ftyp' atom and determine if a suitable
7112 // compatible brand is present.
7113 // Also try to identify where this file's metadata ends
7114 // (end of the 'moov' atom) and report it to the caller as part of
7115 // the metadata.
BetterSniffMPEG4(DataSourceHelper * source,float * confidence)7116 static bool BetterSniffMPEG4(DataSourceHelper *source, float *confidence) {
7117 // We scan up to 128 bytes to identify this file as an MP4.
7118 static const off64_t kMaxScanOffset = 128ll;
7119
7120 off64_t offset = 0ll;
7121 bool foundGoodFileType = false;
7122 off64_t moovAtomEndOffset = -1ll;
7123 bool done = false;
7124
7125 while (!done && offset < kMaxScanOffset) {
7126 uint32_t hdr[2];
7127 if (source->readAt(offset, hdr, 8) < 8) {
7128 return false;
7129 }
7130
7131 uint64_t chunkSize = ntohl(hdr[0]);
7132 uint32_t chunkType = ntohl(hdr[1]);
7133 off64_t chunkDataOffset = offset + 8;
7134
7135 if (chunkSize == 1) {
7136 if (source->readAt(offset + 8, &chunkSize, 8) < 8) {
7137 return false;
7138 }
7139
7140 chunkSize = ntoh64(chunkSize);
7141 chunkDataOffset += 8;
7142
7143 if (chunkSize < 16) {
7144 // The smallest valid chunk is 16 bytes long in this case.
7145 return false;
7146 }
7147 if (chunkSize > INT64_MAX) {
7148 // reject overly large chunk sizes that could
7149 // be interpreted as negative
7150 ALOGE("chunk size too large");
7151 return false;
7152 }
7153
7154 } else if (chunkSize < 8) {
7155 // The smallest valid chunk is 8 bytes long.
7156 return false;
7157 }
7158
7159 // (data_offset - offset) is either 8 or 16
7160 off64_t chunkDataSize = chunkSize - (chunkDataOffset - offset);
7161 if (chunkDataSize < 0) {
7162 ALOGE("b/23540914");
7163 return false;
7164 }
7165
7166 char chunkstring[5];
7167 MakeFourCCString(chunkType, chunkstring);
7168 ALOGV("saw chunk type %s, size %" PRIu64 " @ %lld",
7169 chunkstring, chunkSize, (long long)offset);
7170 switch (chunkType) {
7171 case FOURCC("ftyp"):
7172 {
7173 if (chunkDataSize < 8) {
7174 return false;
7175 }
7176
7177 uint32_t numCompatibleBrands = (chunkDataSize - 8) / 4;
7178 for (size_t i = 0; i < numCompatibleBrands + 2; ++i) {
7179 if (i == 1) {
7180 // Skip this index, it refers to the minorVersion,
7181 // not a brand.
7182 continue;
7183 }
7184
7185 uint32_t brand;
7186 if (source->readAt(
7187 chunkDataOffset + 4 * i, &brand, 4) < 4) {
7188 return false;
7189 }
7190
7191 brand = ntohl(brand);
7192
7193 if (isCompatibleBrand(brand)) {
7194 foundGoodFileType = true;
7195 break;
7196 }
7197 }
7198
7199 if (!foundGoodFileType) {
7200 return false;
7201 }
7202
7203 break;
7204 }
7205
7206 case FOURCC("moov"):
7207 {
7208 if (__builtin_add_overflow(offset, chunkSize, &moovAtomEndOffset)) {
7209 ALOGE("chunk size + offset would overflow");
7210 return false;
7211 }
7212
7213 done = true;
7214 break;
7215 }
7216
7217 default:
7218 break;
7219 }
7220
7221 if (__builtin_add_overflow(offset, chunkSize, &offset)) {
7222 ALOGE("chunk size + offset would overflow");
7223 return false;
7224 }
7225 }
7226
7227 if (!foundGoodFileType) {
7228 return false;
7229 }
7230
7231 *confidence = 0.4f;
7232
7233 return true;
7234 }
7235
CreateExtractor(CDataSource * source,void *)7236 static CMediaExtractor* CreateExtractor(CDataSource *source, void *) {
7237 return wrap(new MPEG4Extractor(new DataSourceHelper(source)));
7238 }
7239
Sniff(CDataSource * source,float * confidence,void **,FreeMetaFunc *)7240 static CreatorFunc Sniff(
7241 CDataSource *source, float *confidence, void **,
7242 FreeMetaFunc *) {
7243 DataSourceHelper helper(source);
7244 if (BetterSniffMPEG4(&helper, confidence)) {
7245 return CreateExtractor;
7246 }
7247
7248 if (LegacySniffMPEG4(&helper, confidence)) {
7249 ALOGW("Identified supported mpeg4 through LegacySniffMPEG4.");
7250 return CreateExtractor;
7251 }
7252
7253 return NULL;
7254 }
7255
7256 static const char *extensions[] = {
7257 "3g2",
7258 "3ga",
7259 "3gp",
7260 "3gpp",
7261 "3gpp2",
7262 "m4a",
7263 "m4r",
7264 "m4v",
7265 "mov",
7266 "mp4",
7267 "qt",
7268 NULL
7269 };
7270
7271 extern "C" {
7272 // This is the only symbol that needs to be exported
7273 __attribute__ ((visibility ("default")))
GETEXTRACTORDEF()7274 ExtractorDef GETEXTRACTORDEF() {
7275 return {
7276 EXTRACTORDEF_VERSION,
7277 UUID("27575c67-4417-4c54-8d3d-8e626985a164"),
7278 2, // version
7279 "MP4 Extractor",
7280 { .v3 = {Sniff, extensions} },
7281 };
7282 }
7283
7284 } // extern "C"
7285
7286 } // namespace android
7287