MPEG4Writer.cpp revision 80f78b773f92048944a850efb7b60629643370cd
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 "MPEG4Writer"
19
20#include <arpa/inet.h>
21#include <fcntl.h>
22#include <inttypes.h>
23#include <pthread.h>
24#include <sys/prctl.h>
25#include <sys/stat.h>
26#include <sys/types.h>
27#include <unistd.h>
28
29#include <utils/Log.h>
30
31#include <media/stagefright/foundation/ADebug.h>
32#include <media/stagefright/foundation/AMessage.h>
33#include <media/stagefright/foundation/ColorUtils.h>
34#include <media/stagefright/MPEG4Writer.h>
35#include <media/stagefright/MediaBuffer.h>
36#include <media/stagefright/MetaData.h>
37#include <media/stagefright/MediaDefs.h>
38#include <media/stagefright/MediaErrors.h>
39#include <media/stagefright/MediaSource.h>
40#include <media/stagefright/Utils.h>
41#include <media/mediarecorder.h>
42#include <cutils/properties.h>
43
44#include "include/ESDS.h"
45#include "include/HevcUtils.h"
46#include "include/avc_utils.h"
47
48#ifndef __predict_false
49#define __predict_false(exp) __builtin_expect((exp) != 0, 0)
50#endif
51
52#define WARN_UNLESS(condition, message, ...) \
53( (__predict_false(condition)) ? false : ({ \
54    ALOGW("Condition %s failed "  message, #condition, ##__VA_ARGS__); \
55    true; \
56}))
57
58namespace android {
59
60static const int64_t kMinStreamableFileSizeInBytes = 5 * 1024 * 1024;
61static const int64_t kMax32BitFileSize = 0x00ffffffffLL; // 2^32-1 : max FAT32
62                                                         // filesystem file size
63                                                         // used by most SD cards
64static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
65static const uint8_t kNalUnitTypePicParamSet = 0x08;
66static const int64_t kInitialDelayTimeUs     = 700000LL;
67
68static const char kMetaKey_Version[]    = "com.android.version";
69#ifdef SHOW_MODEL_BUILD
70static const char kMetaKey_Model[]      = "com.android.model";
71static const char kMetaKey_Build[]      = "com.android.build";
72#endif
73static const char kMetaKey_CaptureFps[] = "com.android.capture.fps";
74
75static const uint8_t kMandatoryHevcNalUnitTypes[3] = {
76    kHevcNalUnitTypeVps,
77    kHevcNalUnitTypeSps,
78    kHevcNalUnitTypePps,
79};
80static const uint8_t kHevcNalUnitTypes[5] = {
81    kHevcNalUnitTypeVps,
82    kHevcNalUnitTypeSps,
83    kHevcNalUnitTypePps,
84    kHevcNalUnitTypePrefixSei,
85    kHevcNalUnitTypeSuffixSei,
86};
87/* uncomment to include model and build in meta */
88//#define SHOW_MODEL_BUILD 1
89
90class MPEG4Writer::Track {
91public:
92    Track(MPEG4Writer *owner, const sp<IMediaSource> &source, size_t trackId);
93
94    ~Track();
95
96    status_t start(MetaData *params);
97    status_t stop();
98    status_t pause();
99    bool reachedEOS();
100
101    int64_t getDurationUs() const;
102    int64_t getEstimatedTrackSizeBytes() const;
103    void writeTrackHeader(bool use32BitOffset = true);
104    void bufferChunk(int64_t timestampUs);
105    bool isAvc() const { return mIsAvc; }
106    bool isHevc() const { return mIsHevc; }
107    bool isAudio() const { return mIsAudio; }
108    bool isMPEG4() const { return mIsMPEG4; }
109    void addChunkOffset(off64_t offset);
110    int32_t getTrackId() const { return mTrackId; }
111    status_t dump(int fd, const Vector<String16>& args) const;
112    static const char *getFourCCForMime(const char *mime);
113
114private:
115    enum {
116        kMaxCttsOffsetTimeUs = 1000000LL,  // 1 second
117        kSampleArraySize = 1000,
118    };
119
120    // A helper class to handle faster write box with table entries
121    template<class TYPE>
122    struct ListTableEntries {
123        ListTableEntries(uint32_t elementCapacity, uint32_t entryCapacity)
124            : mElementCapacity(elementCapacity),
125            mEntryCapacity(entryCapacity),
126            mTotalNumTableEntries(0),
127            mNumValuesInCurrEntry(0),
128            mCurrTableEntriesElement(NULL) {
129            CHECK_GT(mElementCapacity, 0);
130            CHECK_GT(mEntryCapacity, 0);
131            // Ensure no integer overflow on allocation in add().
132            CHECK_LT(mEntryCapacity, UINT32_MAX / mElementCapacity);
133        }
134
135        // Free the allocated memory.
136        ~ListTableEntries() {
137            while (!mTableEntryList.empty()) {
138                typename List<TYPE *>::iterator it = mTableEntryList.begin();
139                delete[] (*it);
140                mTableEntryList.erase(it);
141            }
142        }
143
144        // Replace the value at the given position by the given value.
145        // There must be an existing value at the given position.
146        // @arg value must be in network byte order
147        // @arg pos location the value must be in.
148        void set(const TYPE& value, uint32_t pos) {
149            CHECK_LT(pos, mTotalNumTableEntries * mEntryCapacity);
150
151            typename List<TYPE *>::iterator it = mTableEntryList.begin();
152            uint32_t iterations = (pos / (mElementCapacity * mEntryCapacity));
153            while (it != mTableEntryList.end() && iterations > 0) {
154                ++it;
155                --iterations;
156            }
157            CHECK(it != mTableEntryList.end());
158            CHECK_EQ(iterations, 0);
159
160            (*it)[(pos % (mElementCapacity * mEntryCapacity))] = value;
161        }
162
163        // Get the value at the given position by the given value.
164        // @arg value the retrieved value at the position in network byte order.
165        // @arg pos location the value must be in.
166        // @return true if a value is found.
167        bool get(TYPE& value, uint32_t pos) const {
168            if (pos >= mTotalNumTableEntries * mEntryCapacity) {
169                return false;
170            }
171
172            typename List<TYPE *>::iterator it = mTableEntryList.begin();
173            uint32_t iterations = (pos / (mElementCapacity * mEntryCapacity));
174            while (it != mTableEntryList.end() && iterations > 0) {
175                ++it;
176                --iterations;
177            }
178            CHECK(it != mTableEntryList.end());
179            CHECK_EQ(iterations, 0);
180
181            value = (*it)[(pos % (mElementCapacity * mEntryCapacity))];
182            return true;
183        }
184
185        // Store a single value.
186        // @arg value must be in network byte order.
187        void add(const TYPE& value) {
188            CHECK_LT(mNumValuesInCurrEntry, mElementCapacity);
189            uint32_t nEntries = mTotalNumTableEntries % mElementCapacity;
190            uint32_t nValues  = mNumValuesInCurrEntry % mEntryCapacity;
191            if (nEntries == 0 && nValues == 0) {
192                mCurrTableEntriesElement = new TYPE[mEntryCapacity * mElementCapacity];
193                CHECK(mCurrTableEntriesElement != NULL);
194                mTableEntryList.push_back(mCurrTableEntriesElement);
195            }
196
197            uint32_t pos = nEntries * mEntryCapacity + nValues;
198            mCurrTableEntriesElement[pos] = value;
199
200            ++mNumValuesInCurrEntry;
201            if ((mNumValuesInCurrEntry % mEntryCapacity) == 0) {
202                ++mTotalNumTableEntries;
203                mNumValuesInCurrEntry = 0;
204            }
205        }
206
207        // Write out the table entries:
208        // 1. the number of entries goes first
209        // 2. followed by the values in the table enties in order
210        // @arg writer the writer to actual write to the storage
211        void write(MPEG4Writer *writer) const {
212            CHECK_EQ(mNumValuesInCurrEntry % mEntryCapacity, 0);
213            uint32_t nEntries = mTotalNumTableEntries;
214            writer->writeInt32(nEntries);
215            for (typename List<TYPE *>::iterator it = mTableEntryList.begin();
216                it != mTableEntryList.end(); ++it) {
217                CHECK_GT(nEntries, 0);
218                if (nEntries >= mElementCapacity) {
219                    writer->write(*it, sizeof(TYPE) * mEntryCapacity, mElementCapacity);
220                    nEntries -= mElementCapacity;
221                } else {
222                    writer->write(*it, sizeof(TYPE) * mEntryCapacity, nEntries);
223                    break;
224                }
225            }
226        }
227
228        // Return the number of entries in the table.
229        uint32_t count() const { return mTotalNumTableEntries; }
230
231    private:
232        uint32_t         mElementCapacity;  // # entries in an element
233        uint32_t         mEntryCapacity;    // # of values in each entry
234        uint32_t         mTotalNumTableEntries;
235        uint32_t         mNumValuesInCurrEntry;  // up to mEntryCapacity
236        TYPE             *mCurrTableEntriesElement;
237        mutable List<TYPE *>     mTableEntryList;
238
239        DISALLOW_EVIL_CONSTRUCTORS(ListTableEntries);
240    };
241
242
243
244    MPEG4Writer *mOwner;
245    sp<MetaData> mMeta;
246    sp<IMediaSource> mSource;
247    volatile bool mDone;
248    volatile bool mPaused;
249    volatile bool mResumed;
250    volatile bool mStarted;
251    bool mIsAvc;
252    bool mIsHevc;
253    bool mIsAudio;
254    bool mIsMPEG4;
255    int32_t mTrackId;
256    int64_t mTrackDurationUs;
257    int64_t mMaxChunkDurationUs;
258
259    int64_t mEstimatedTrackSizeBytes;
260    int64_t mMdatSizeBytes;
261    int32_t mTimeScale;
262
263    pthread_t mThread;
264
265
266    List<MediaBuffer *> mChunkSamples;
267
268    bool                mSamplesHaveSameSize;
269    ListTableEntries<uint32_t> *mStszTableEntries;
270
271    ListTableEntries<uint32_t> *mStcoTableEntries;
272    ListTableEntries<off64_t> *mCo64TableEntries;
273    ListTableEntries<uint32_t> *mStscTableEntries;
274    ListTableEntries<uint32_t> *mStssTableEntries;
275    ListTableEntries<uint32_t> *mSttsTableEntries;
276    ListTableEntries<uint32_t> *mCttsTableEntries;
277
278    int64_t mMinCttsOffsetTimeUs;
279    int64_t mMaxCttsOffsetTimeUs;
280
281    // Sequence parameter set or picture parameter set
282    struct AVCParamSet {
283        AVCParamSet(uint16_t length, const uint8_t *data)
284            : mLength(length), mData(data) {}
285
286        uint16_t mLength;
287        const uint8_t *mData;
288    };
289    List<AVCParamSet> mSeqParamSets;
290    List<AVCParamSet> mPicParamSets;
291    uint8_t mProfileIdc;
292    uint8_t mProfileCompatible;
293    uint8_t mLevelIdc;
294
295    void *mCodecSpecificData;
296    size_t mCodecSpecificDataSize;
297    bool mGotAllCodecSpecificData;
298    bool mTrackingProgressStatus;
299
300    bool mReachedEOS;
301    int64_t mStartTimestampUs;
302    int64_t mStartTimeRealUs;
303    int64_t mFirstSampleTimeRealUs;
304    int64_t mPreviousTrackTimeUs;
305    int64_t mTrackEveryTimeDurationUs;
306
307    // Update the audio track's drift information.
308    void updateDriftTime(const sp<MetaData>& meta);
309
310    int32_t getStartTimeOffsetScaledTime() const;
311
312    static void *ThreadWrapper(void *me);
313    status_t threadEntry();
314
315    const uint8_t *parseParamSet(
316        const uint8_t *data, size_t length, int type, size_t *paramSetLen);
317
318    status_t copyCodecSpecificData(const uint8_t *data, size_t size, size_t minLength = 0);
319
320    status_t makeAVCCodecSpecificData(const uint8_t *data, size_t size);
321    status_t copyAVCCodecSpecificData(const uint8_t *data, size_t size);
322    status_t parseAVCCodecSpecificData(const uint8_t *data, size_t size);
323
324    status_t makeHEVCCodecSpecificData(const uint8_t *data, size_t size);
325    status_t copyHEVCCodecSpecificData(const uint8_t *data, size_t size);
326    status_t parseHEVCCodecSpecificData(
327            const uint8_t *data, size_t size, HevcParameterSets &paramSets);
328
329    // Track authoring progress status
330    void trackProgressStatus(int64_t timeUs, status_t err = OK);
331    void initTrackingProgressStatus(MetaData *params);
332
333    void getCodecSpecificDataFromInputFormatIfPossible();
334
335    // Determine the track time scale
336    // If it is an audio track, try to use the sampling rate as
337    // the time scale; however, if user chooses the overwrite
338    // value, the user-supplied time scale will be used.
339    void setTimeScale();
340
341    // Simple validation on the codec specific data
342    status_t checkCodecSpecificData() const;
343    int32_t mRotation;
344
345    void updateTrackSizeEstimate();
346    void addOneStscTableEntry(size_t chunkId, size_t sampleId);
347    void addOneStssTableEntry(size_t sampleId);
348
349    // Duration is time scale based
350    void addOneSttsTableEntry(size_t sampleCount, int32_t timescaledDur);
351    void addOneCttsTableEntry(size_t sampleCount, int32_t timescaledDur);
352
353    bool isTrackMalFormed() const;
354    void sendTrackSummary(bool hasMultipleTracks);
355
356    // Write the boxes
357    void writeStcoBox(bool use32BitOffset);
358    void writeStscBox();
359    void writeStszBox();
360    void writeStssBox();
361    void writeSttsBox();
362    void writeCttsBox();
363    void writeD263Box();
364    void writePaspBox();
365    void writeAvccBox();
366    void writeHvccBox();
367    void writeUrlBox();
368    void writeDrefBox();
369    void writeDinfBox();
370    void writeDamrBox();
371    void writeMdhdBox(uint32_t now);
372    void writeSmhdBox();
373    void writeVmhdBox();
374    void writeHdlrBox();
375    void writeTkhdBox(uint32_t now);
376    void writeColrBox();
377    void writeMp4aEsdsBox();
378    void writeMp4vEsdsBox();
379    void writeAudioFourCCBox();
380    void writeVideoFourCCBox();
381    void writeStblBox(bool use32BitOffset);
382
383    Track(const Track &);
384    Track &operator=(const Track &);
385};
386
387MPEG4Writer::MPEG4Writer(int fd)
388    : mFd(dup(fd)),
389      mInitCheck(mFd < 0? NO_INIT: OK),
390      mIsRealTimeRecording(true),
391      mUse4ByteNalLength(true),
392      mUse32BitOffset(true),
393      mIsFileSizeLimitExplicitlyRequested(false),
394      mPaused(false),
395      mStarted(false),
396      mWriterThreadStarted(false),
397      mOffset(0),
398      mMdatOffset(0),
399      mMoovBoxBuffer(NULL),
400      mMoovBoxBufferOffset(0),
401      mWriteMoovBoxToMemory(false),
402      mFreeBoxOffset(0),
403      mStreamableFile(false),
404      mEstimatedMoovBoxSize(0),
405      mMoovExtraSize(0),
406      mInterleaveDurationUs(1000000),
407      mTimeScale(-1),
408      mStartTimestampUs(-1ll),
409      mLatitudex10000(0),
410      mLongitudex10000(0),
411      mAreGeoTagsAvailable(false),
412      mStartTimeOffsetMs(-1),
413      mMetaKeys(new AMessage()) {
414    addDeviceMeta();
415
416    // Verify mFd is seekable
417    off64_t off = lseek64(mFd, 0, SEEK_SET);
418    if (off < 0) {
419        ALOGE("cannot seek mFd: %s (%d)", strerror(errno), errno);
420        release();
421    }
422}
423
424MPEG4Writer::~MPEG4Writer() {
425    reset();
426
427    while (!mTracks.empty()) {
428        List<Track *>::iterator it = mTracks.begin();
429        delete *it;
430        (*it) = NULL;
431        mTracks.erase(it);
432    }
433    mTracks.clear();
434}
435
436status_t MPEG4Writer::dump(
437        int fd, const Vector<String16>& args) {
438    const size_t SIZE = 256;
439    char buffer[SIZE];
440    String8 result;
441    snprintf(buffer, SIZE, "   MPEG4Writer %p\n", this);
442    result.append(buffer);
443    snprintf(buffer, SIZE, "     mStarted: %s\n", mStarted? "true": "false");
444    result.append(buffer);
445    ::write(fd, result.string(), result.size());
446    for (List<Track *>::iterator it = mTracks.begin();
447         it != mTracks.end(); ++it) {
448        (*it)->dump(fd, args);
449    }
450    return OK;
451}
452
453status_t MPEG4Writer::Track::dump(
454        int fd, const Vector<String16>& /* args */) const {
455    const size_t SIZE = 256;
456    char buffer[SIZE];
457    String8 result;
458    snprintf(buffer, SIZE, "     %s track\n", mIsAudio? "Audio": "Video");
459    result.append(buffer);
460    snprintf(buffer, SIZE, "       reached EOS: %s\n",
461            mReachedEOS? "true": "false");
462    result.append(buffer);
463    snprintf(buffer, SIZE, "       frames encoded : %d\n", mStszTableEntries->count());
464    result.append(buffer);
465    snprintf(buffer, SIZE, "       duration encoded : %" PRId64 " us\n", mTrackDurationUs);
466    result.append(buffer);
467    ::write(fd, result.string(), result.size());
468    return OK;
469}
470
471// static
472const char *MPEG4Writer::Track::getFourCCForMime(const char *mime) {
473    if (mime == NULL) {
474        return NULL;
475    }
476    if (!strncasecmp(mime, "audio/", 6)) {
477        if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
478            return "samr";
479        } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
480            return "sawb";
481        } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
482            return "mp4a";
483        }
484    } else if (!strncasecmp(mime, "video/", 6)) {
485        if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
486            return "mp4v";
487        } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
488            return "s263";
489        } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
490            return "avc1";
491        } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) {
492            return "hvc1";
493        }
494    } else {
495        ALOGE("Track (%s) other than video or audio is not supported", mime);
496    }
497    return NULL;
498}
499
500status_t MPEG4Writer::addSource(const sp<IMediaSource> &source) {
501    Mutex::Autolock l(mLock);
502    if (mStarted) {
503        ALOGE("Attempt to add source AFTER recording is started");
504        return UNKNOWN_ERROR;
505    }
506
507    // At most 2 tracks can be supported.
508    if (mTracks.size() >= 2) {
509        ALOGE("Too many tracks (%zu) to add", mTracks.size());
510        return ERROR_UNSUPPORTED;
511    }
512
513    CHECK(source.get() != NULL);
514
515    const char *mime;
516    source->getFormat()->findCString(kKeyMIMEType, &mime);
517    bool isAudio = !strncasecmp(mime, "audio/", 6);
518    if (Track::getFourCCForMime(mime) == NULL) {
519        ALOGE("Unsupported mime '%s'", mime);
520        return ERROR_UNSUPPORTED;
521    }
522
523    // At this point, we know the track to be added is either
524    // video or audio. Thus, we only need to check whether it
525    // is an audio track or not (if it is not, then it must be
526    // a video track).
527
528    // No more than one video or one audio track is supported.
529    for (List<Track*>::iterator it = mTracks.begin();
530         it != mTracks.end(); ++it) {
531        if ((*it)->isAudio() == isAudio) {
532            ALOGE("%s track already exists", isAudio? "Audio": "Video");
533            return ERROR_UNSUPPORTED;
534        }
535    }
536
537    // This is the first track of either audio or video.
538    // Go ahead to add the track.
539    Track *track = new Track(this, source, 1 + mTracks.size());
540    mTracks.push_back(track);
541
542    return OK;
543}
544
545status_t MPEG4Writer::startTracks(MetaData *params) {
546    if (mTracks.empty()) {
547        ALOGE("No source added");
548        return INVALID_OPERATION;
549    }
550
551    for (List<Track *>::iterator it = mTracks.begin();
552         it != mTracks.end(); ++it) {
553        status_t err = (*it)->start(params);
554
555        if (err != OK) {
556            for (List<Track *>::iterator it2 = mTracks.begin();
557                 it2 != it; ++it2) {
558                (*it2)->stop();
559            }
560
561            return err;
562        }
563    }
564    return OK;
565}
566
567void MPEG4Writer::addDeviceMeta() {
568    // add device info and estimate space in 'moov'
569    char val[PROPERTY_VALUE_MAX];
570    size_t n;
571    // meta size is estimated by adding up the following:
572    // - meta header structures, which occur only once (total 66 bytes)
573    // - size for each key, which consists of a fixed header (32 bytes),
574    //   plus key length and data length.
575    mMoovExtraSize += 66;
576    if (property_get("ro.build.version.release", val, NULL)
577            && (n = strlen(val)) > 0) {
578        mMetaKeys->setString(kMetaKey_Version, val, n + 1);
579        mMoovExtraSize += sizeof(kMetaKey_Version) + n + 32;
580    }
581#ifdef SHOW_MODEL_BUILD
582    if (property_get("ro.product.model", val, NULL)
583            && (n = strlen(val)) > 0) {
584        mMetaKeys->setString(kMetaKey_Model, val, n + 1);
585        mMoovExtraSize += sizeof(kMetaKey_Model) + n + 32;
586    }
587    if (property_get("ro.build.display.id", val, NULL)
588            && (n = strlen(val)) > 0) {
589        mMetaKeys->setString(kMetaKey_Build, val, n + 1);
590        mMoovExtraSize += sizeof(kMetaKey_Build) + n + 32;
591    }
592#endif
593}
594
595int64_t MPEG4Writer::estimateMoovBoxSize(int32_t bitRate) {
596    // This implementation is highly experimental/heurisitic.
597    //
598    // Statistical analysis shows that metadata usually accounts
599    // for a small portion of the total file size, usually < 0.6%.
600
601    // The default MIN_MOOV_BOX_SIZE is set to 0.6% x 1MB / 2,
602    // where 1MB is the common file size limit for MMS application.
603    // The default MAX _MOOV_BOX_SIZE value is based on about 3
604    // minute video recording with a bit rate about 3 Mbps, because
605    // statistics also show that most of the video captured are going
606    // to be less than 3 minutes.
607
608    // If the estimation is wrong, we will pay the price of wasting
609    // some reserved space. This should not happen so often statistically.
610    static const int32_t factor = mUse32BitOffset? 1: 2;
611    static const int64_t MIN_MOOV_BOX_SIZE = 3 * 1024;  // 3 KB
612    static const int64_t MAX_MOOV_BOX_SIZE = (180 * 3000000 * 6LL / 8000);
613    int64_t size = MIN_MOOV_BOX_SIZE;
614
615    // Max file size limit is set
616    if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
617        size = mMaxFileSizeLimitBytes * 6 / 1000;
618    }
619
620    // Max file duration limit is set
621    if (mMaxFileDurationLimitUs != 0) {
622        if (bitRate > 0) {
623            int64_t size2 =
624                ((mMaxFileDurationLimitUs * bitRate * 6) / 1000 / 8000000);
625            if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
626                // When both file size and duration limits are set,
627                // we use the smaller limit of the two.
628                if (size > size2) {
629                    size = size2;
630                }
631            } else {
632                // Only max file duration limit is set
633                size = size2;
634            }
635        }
636    }
637
638    if (size < MIN_MOOV_BOX_SIZE) {
639        size = MIN_MOOV_BOX_SIZE;
640    }
641
642    // Any long duration recording will be probably end up with
643    // non-streamable mp4 file.
644    if (size > MAX_MOOV_BOX_SIZE) {
645        size = MAX_MOOV_BOX_SIZE;
646    }
647
648    // Account for the extra stuff (Geo, meta keys, etc.)
649    size += mMoovExtraSize;
650
651    ALOGI("limits: %" PRId64 "/%" PRId64 " bytes/us, bit rate: %d bps and the"
652         " estimated moov size %" PRId64 " bytes",
653         mMaxFileSizeLimitBytes, mMaxFileDurationLimitUs, bitRate, size);
654    return factor * size;
655}
656
657status_t MPEG4Writer::start(MetaData *param) {
658    if (mInitCheck != OK) {
659        return UNKNOWN_ERROR;
660    }
661
662    /*
663     * Check mMaxFileSizeLimitBytes at the beginning
664     * since mMaxFileSizeLimitBytes may be implicitly
665     * changed later for 32-bit file offset even if
666     * user does not ask to set it explicitly.
667     */
668    if (mMaxFileSizeLimitBytes != 0) {
669        mIsFileSizeLimitExplicitlyRequested = true;
670    }
671
672    int32_t use64BitOffset;
673    if (param &&
674        param->findInt32(kKey64BitFileOffset, &use64BitOffset) &&
675        use64BitOffset) {
676        mUse32BitOffset = false;
677    }
678
679    if (mUse32BitOffset) {
680        // Implicit 32 bit file size limit
681        if (mMaxFileSizeLimitBytes == 0) {
682            mMaxFileSizeLimitBytes = kMax32BitFileSize;
683        }
684
685        // If file size is set to be larger than the 32 bit file
686        // size limit, treat it as an error.
687        if (mMaxFileSizeLimitBytes > kMax32BitFileSize) {
688            ALOGW("32-bit file size limit (%" PRId64 " bytes) too big. "
689                 "It is changed to %" PRId64 " bytes",
690                mMaxFileSizeLimitBytes, kMax32BitFileSize);
691            mMaxFileSizeLimitBytes = kMax32BitFileSize;
692        }
693    }
694
695    int32_t use2ByteNalLength;
696    if (param &&
697        param->findInt32(kKey2ByteNalLength, &use2ByteNalLength) &&
698        use2ByteNalLength) {
699        mUse4ByteNalLength = false;
700    }
701
702    int32_t isRealTimeRecording;
703    if (param && param->findInt32(kKeyRealTimeRecording, &isRealTimeRecording)) {
704        mIsRealTimeRecording = isRealTimeRecording;
705    }
706
707    mStartTimestampUs = -1;
708
709    if (mStarted) {
710        if (mPaused) {
711            mPaused = false;
712            return startTracks(param);
713        }
714        return OK;
715    }
716
717    if (!param ||
718        !param->findInt32(kKeyTimeScale, &mTimeScale)) {
719        mTimeScale = 1000;
720    }
721    CHECK_GT(mTimeScale, 0);
722    ALOGV("movie time scale: %d", mTimeScale);
723
724    /*
725     * When the requested file size limit is small, the priority
726     * is to meet the file size limit requirement, rather than
727     * to make the file streamable. mStreamableFile does not tell
728     * whether the actual recorded file is streamable or not.
729     */
730    mStreamableFile =
731        (mMaxFileSizeLimitBytes != 0 &&
732         mMaxFileSizeLimitBytes >= kMinStreamableFileSizeInBytes);
733
734    /*
735     * mWriteMoovBoxToMemory is true if the amount of data in moov box is
736     * smaller than the reserved free space at the beginning of a file, AND
737     * when the content of moov box is constructed. Note that video/audio
738     * frame data is always written to the file but not in the memory.
739     *
740     * Before stop()/reset() is called, mWriteMoovBoxToMemory is always
741     * false. When reset() is called at the end of a recording session,
742     * Moov box needs to be constructed.
743     *
744     * 1) Right before a moov box is constructed, mWriteMoovBoxToMemory
745     * to set to mStreamableFile so that if
746     * the file is intended to be streamable, it is set to true;
747     * otherwise, it is set to false. When the value is set to false,
748     * all the content of the moov box is written immediately to
749     * the end of the file. When the value is set to true, all the
750     * content of the moov box is written to an in-memory cache,
751     * mMoovBoxBuffer, util the following condition happens. Note
752     * that the size of the in-memory cache is the same as the
753     * reserved free space at the beginning of the file.
754     *
755     * 2) While the data of the moov box is written to an in-memory
756     * cache, the data size is checked against the reserved space.
757     * If the data size surpasses the reserved space, subsequent moov
758     * data could no longer be hold in the in-memory cache. This also
759     * indicates that the reserved space was too small. At this point,
760     * _all_ moov data must be written to the end of the file.
761     * mWriteMoovBoxToMemory must be set to false to direct the write
762     * to the file.
763     *
764     * 3) If the data size in moov box is smaller than the reserved
765     * space after moov box is completely constructed, the in-memory
766     * cache copy of the moov box is written to the reserved free
767     * space. Thus, immediately after the moov is completedly
768     * constructed, mWriteMoovBoxToMemory is always set to false.
769     */
770    mWriteMoovBoxToMemory = false;
771    mMoovBoxBuffer = NULL;
772    mMoovBoxBufferOffset = 0;
773
774    writeFtypBox(param);
775
776    mFreeBoxOffset = mOffset;
777
778    if (mEstimatedMoovBoxSize == 0) {
779        int32_t bitRate = -1;
780        if (param) {
781            param->findInt32(kKeyBitRate, &bitRate);
782        }
783        mEstimatedMoovBoxSize = estimateMoovBoxSize(bitRate);
784    }
785    CHECK_GE(mEstimatedMoovBoxSize, 8);
786    if (mStreamableFile) {
787        // Reserve a 'free' box only for streamable file
788        lseek64(mFd, mFreeBoxOffset, SEEK_SET);
789        writeInt32(mEstimatedMoovBoxSize);
790        write("free", 4);
791        mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize;
792    } else {
793        mMdatOffset = mOffset;
794    }
795
796    mOffset = mMdatOffset;
797    lseek64(mFd, mMdatOffset, SEEK_SET);
798    if (mUse32BitOffset) {
799        write("????mdat", 8);
800    } else {
801        write("\x00\x00\x00\x01mdat????????", 16);
802    }
803
804    status_t err = startWriterThread();
805    if (err != OK) {
806        return err;
807    }
808
809    err = startTracks(param);
810    if (err != OK) {
811        return err;
812    }
813
814    mStarted = true;
815    return OK;
816}
817
818bool MPEG4Writer::use32BitFileOffset() const {
819    return mUse32BitOffset;
820}
821
822status_t MPEG4Writer::pause() {
823    if (mInitCheck != OK) {
824        return OK;
825    }
826    mPaused = true;
827    status_t err = OK;
828    for (List<Track *>::iterator it = mTracks.begin();
829         it != mTracks.end(); ++it) {
830        status_t status = (*it)->pause();
831        if (status != OK) {
832            err = status;
833        }
834    }
835    return err;
836}
837
838void MPEG4Writer::stopWriterThread() {
839    ALOGD("Stopping writer thread");
840    if (!mWriterThreadStarted) {
841        return;
842    }
843
844    {
845        Mutex::Autolock autolock(mLock);
846
847        mDone = true;
848        mChunkReadyCondition.signal();
849    }
850
851    void *dummy;
852    pthread_join(mThread, &dummy);
853    mWriterThreadStarted = false;
854    ALOGD("Writer thread stopped");
855}
856
857/*
858 * MP4 file standard defines a composition matrix:
859 * | a  b  u |
860 * | c  d  v |
861 * | x  y  w |
862 *
863 * the element in the matrix is stored in the following
864 * order: {a, b, u, c, d, v, x, y, w},
865 * where a, b, c, d, x, and y is in 16.16 format, while
866 * u, v and w is in 2.30 format.
867 */
868void MPEG4Writer::writeCompositionMatrix(int degrees) {
869    ALOGV("writeCompositionMatrix");
870    uint32_t a = 0x00010000;
871    uint32_t b = 0;
872    uint32_t c = 0;
873    uint32_t d = 0x00010000;
874    switch (degrees) {
875        case 0:
876            break;
877        case 90:
878            a = 0;
879            b = 0x00010000;
880            c = 0xFFFF0000;
881            d = 0;
882            break;
883        case 180:
884            a = 0xFFFF0000;
885            d = 0xFFFF0000;
886            break;
887        case 270:
888            a = 0;
889            b = 0xFFFF0000;
890            c = 0x00010000;
891            d = 0;
892            break;
893        default:
894            CHECK(!"Should never reach this unknown rotation");
895            break;
896    }
897
898    writeInt32(a);           // a
899    writeInt32(b);           // b
900    writeInt32(0);           // u
901    writeInt32(c);           // c
902    writeInt32(d);           // d
903    writeInt32(0);           // v
904    writeInt32(0);           // x
905    writeInt32(0);           // y
906    writeInt32(0x40000000);  // w
907}
908
909void MPEG4Writer::release() {
910    close(mFd);
911    mFd = -1;
912    mInitCheck = NO_INIT;
913    mStarted = false;
914    free(mMoovBoxBuffer);
915    mMoovBoxBuffer = NULL;
916}
917
918status_t MPEG4Writer::reset() {
919    if (mInitCheck != OK) {
920        return OK;
921    } else {
922        if (!mWriterThreadStarted ||
923            !mStarted) {
924            if (mWriterThreadStarted) {
925                stopWriterThread();
926            }
927            release();
928            return OK;
929        }
930    }
931
932    status_t err = OK;
933    int64_t maxDurationUs = 0;
934    int64_t minDurationUs = 0x7fffffffffffffffLL;
935    for (List<Track *>::iterator it = mTracks.begin();
936         it != mTracks.end(); ++it) {
937        status_t status = (*it)->stop();
938        if (err == OK && status != OK) {
939            err = status;
940        }
941
942        int64_t durationUs = (*it)->getDurationUs();
943        if (durationUs > maxDurationUs) {
944            maxDurationUs = durationUs;
945        }
946        if (durationUs < minDurationUs) {
947            minDurationUs = durationUs;
948        }
949    }
950
951    if (mTracks.size() > 1) {
952        ALOGD("Duration from tracks range is [%" PRId64 ", %" PRId64 "] us",
953            minDurationUs, maxDurationUs);
954    }
955
956    stopWriterThread();
957
958    // Do not write out movie header on error.
959    if (err != OK) {
960        release();
961        return err;
962    }
963
964    // Fix up the size of the 'mdat' chunk.
965    if (mUse32BitOffset) {
966        lseek64(mFd, mMdatOffset, SEEK_SET);
967        uint32_t size = htonl(static_cast<uint32_t>(mOffset - mMdatOffset));
968        ::write(mFd, &size, 4);
969    } else {
970        lseek64(mFd, mMdatOffset + 8, SEEK_SET);
971        uint64_t size = mOffset - mMdatOffset;
972        size = hton64(size);
973        ::write(mFd, &size, 8);
974    }
975    lseek64(mFd, mOffset, SEEK_SET);
976
977    // Construct moov box now
978    mMoovBoxBufferOffset = 0;
979    mWriteMoovBoxToMemory = mStreamableFile;
980    if (mWriteMoovBoxToMemory) {
981        // There is no need to allocate in-memory cache
982        // for moov box if the file is not streamable.
983
984        mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize);
985        CHECK(mMoovBoxBuffer != NULL);
986    }
987    writeMoovBox(maxDurationUs);
988
989    // mWriteMoovBoxToMemory could be set to false in
990    // MPEG4Writer::write() method
991    if (mWriteMoovBoxToMemory) {
992        mWriteMoovBoxToMemory = false;
993        // Content of the moov box is saved in the cache, and the in-memory
994        // moov box needs to be written to the file in a single shot.
995
996        CHECK_LE(mMoovBoxBufferOffset + 8, mEstimatedMoovBoxSize);
997
998        // Moov box
999        lseek64(mFd, mFreeBoxOffset, SEEK_SET);
1000        mOffset = mFreeBoxOffset;
1001        write(mMoovBoxBuffer, 1, mMoovBoxBufferOffset);
1002
1003        // Free box
1004        lseek64(mFd, mOffset, SEEK_SET);
1005        writeInt32(mEstimatedMoovBoxSize - mMoovBoxBufferOffset);
1006        write("free", 4);
1007    } else {
1008        ALOGI("The mp4 file will not be streamable.");
1009    }
1010
1011    // Free in-memory cache for moov box
1012    if (mMoovBoxBuffer != NULL) {
1013        free(mMoovBoxBuffer);
1014        mMoovBoxBuffer = NULL;
1015        mMoovBoxBufferOffset = 0;
1016    }
1017
1018    CHECK(mBoxes.empty());
1019
1020    release();
1021    return err;
1022}
1023
1024uint32_t MPEG4Writer::getMpeg4Time() {
1025    time_t now = time(NULL);
1026    // MP4 file uses time counting seconds since midnight, Jan. 1, 1904
1027    // while time function returns Unix epoch values which starts
1028    // at 1970-01-01. Lets add the number of seconds between them
1029    static const uint32_t delta = (66 * 365 + 17) * (24 * 60 * 60);
1030    if (now < 0 || uint32_t(now) > UINT32_MAX - delta) {
1031        return 0;
1032    }
1033    uint32_t mpeg4Time = uint32_t(now) + delta;
1034    return mpeg4Time;
1035}
1036
1037void MPEG4Writer::writeMvhdBox(int64_t durationUs) {
1038    uint32_t now = getMpeg4Time();
1039    beginBox("mvhd");
1040    writeInt32(0);             // version=0, flags=0
1041    writeInt32(now);           // creation time
1042    writeInt32(now);           // modification time
1043    writeInt32(mTimeScale);    // mvhd timescale
1044    int32_t duration = (durationUs * mTimeScale + 5E5) / 1E6;
1045    writeInt32(duration);
1046    writeInt32(0x10000);       // rate: 1.0
1047    writeInt16(0x100);         // volume
1048    writeInt16(0);             // reserved
1049    writeInt32(0);             // reserved
1050    writeInt32(0);             // reserved
1051    writeCompositionMatrix(0); // matrix
1052    writeInt32(0);             // predefined
1053    writeInt32(0);             // predefined
1054    writeInt32(0);             // predefined
1055    writeInt32(0);             // predefined
1056    writeInt32(0);             // predefined
1057    writeInt32(0);             // predefined
1058    writeInt32(mTracks.size() + 1);  // nextTrackID
1059    endBox();  // mvhd
1060}
1061
1062void MPEG4Writer::writeMoovBox(int64_t durationUs) {
1063    beginBox("moov");
1064    writeMvhdBox(durationUs);
1065    if (mAreGeoTagsAvailable) {
1066        writeUdtaBox();
1067    }
1068    writeMetaBox();
1069    int32_t id = 1;
1070    for (List<Track *>::iterator it = mTracks.begin();
1071        it != mTracks.end(); ++it, ++id) {
1072        (*it)->writeTrackHeader(mUse32BitOffset);
1073    }
1074    endBox();  // moov
1075}
1076
1077void MPEG4Writer::writeFtypBox(MetaData *param) {
1078    beginBox("ftyp");
1079
1080    int32_t fileType;
1081    if (param && param->findInt32(kKeyFileType, &fileType) &&
1082        fileType != OUTPUT_FORMAT_MPEG_4) {
1083        writeFourcc("3gp4");
1084        writeInt32(0);
1085        writeFourcc("isom");
1086        writeFourcc("3gp4");
1087    } else {
1088        writeFourcc("mp42");
1089        writeInt32(0);
1090        writeFourcc("isom");
1091        writeFourcc("mp42");
1092    }
1093
1094    endBox();
1095}
1096
1097static bool isTestModeEnabled() {
1098#if (PROPERTY_VALUE_MAX < 5)
1099#error "PROPERTY_VALUE_MAX must be at least 5"
1100#endif
1101
1102    // Test mode is enabled only if rw.media.record.test system
1103    // property is enabled.
1104    char value[PROPERTY_VALUE_MAX];
1105    if (property_get("rw.media.record.test", value, NULL) &&
1106        (!strcasecmp(value, "true") || !strcasecmp(value, "1"))) {
1107        return true;
1108    }
1109    return false;
1110}
1111
1112void MPEG4Writer::sendSessionSummary() {
1113    // Send session summary only if test mode is enabled
1114    if (!isTestModeEnabled()) {
1115        return;
1116    }
1117
1118    for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
1119         it != mChunkInfos.end(); ++it) {
1120        int trackNum = it->mTrack->getTrackId() << 28;
1121        notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
1122                trackNum | MEDIA_RECORDER_TRACK_INTER_CHUNK_TIME_MS,
1123                it->mMaxInterChunkDurUs);
1124    }
1125}
1126
1127status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
1128    mInterleaveDurationUs = durationUs;
1129    return OK;
1130}
1131
1132void MPEG4Writer::lock() {
1133    mLock.lock();
1134}
1135
1136void MPEG4Writer::unlock() {
1137    mLock.unlock();
1138}
1139
1140off64_t MPEG4Writer::addSample_l(MediaBuffer *buffer) {
1141    off64_t old_offset = mOffset;
1142
1143    ::write(mFd,
1144          (const uint8_t *)buffer->data() + buffer->range_offset(),
1145          buffer->range_length());
1146
1147    mOffset += buffer->range_length();
1148
1149    return old_offset;
1150}
1151
1152static void StripStartcode(MediaBuffer *buffer) {
1153    if (buffer->range_length() < 4) {
1154        return;
1155    }
1156
1157    const uint8_t *ptr =
1158        (const uint8_t *)buffer->data() + buffer->range_offset();
1159
1160    if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) {
1161        buffer->set_range(
1162                buffer->range_offset() + 4, buffer->range_length() - 4);
1163    }
1164}
1165
1166off64_t MPEG4Writer::addMultipleLengthPrefixedSamples_l(MediaBuffer *buffer) {
1167    off64_t old_offset = mOffset;
1168
1169    const size_t kExtensionNALSearchRange = 64; // bytes to look for non-VCL NALUs
1170
1171    const uint8_t *dataStart = (const uint8_t *)buffer->data() + buffer->range_offset();
1172    const uint8_t *currentNalStart = dataStart;
1173    const uint8_t *nextNalStart;
1174    const uint8_t *data = dataStart;
1175    size_t nextNalSize;
1176    size_t searchSize = buffer->range_length() > kExtensionNALSearchRange ?
1177                   kExtensionNALSearchRange : buffer->range_length();
1178
1179    while (getNextNALUnit(&data, &searchSize, &nextNalStart,
1180            &nextNalSize, true) == OK) {
1181        size_t currentNalSize = nextNalStart - currentNalStart - 3 /* strip start-code */;
1182        MediaBuffer *nalBuf = new MediaBuffer((void *)currentNalStart, currentNalSize);
1183        addLengthPrefixedSample_l(nalBuf);
1184        nalBuf->release();
1185
1186        currentNalStart = nextNalStart;
1187    }
1188
1189    size_t currentNalOffset = currentNalStart - dataStart;
1190    buffer->set_range(buffer->range_offset() + currentNalOffset,
1191            buffer->range_length() - currentNalOffset);
1192    addLengthPrefixedSample_l(buffer);
1193
1194    return old_offset;
1195}
1196
1197off64_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) {
1198    off64_t old_offset = mOffset;
1199
1200    size_t length = buffer->range_length();
1201
1202    if (mUse4ByteNalLength) {
1203        uint8_t x = length >> 24;
1204        ::write(mFd, &x, 1);
1205        x = (length >> 16) & 0xff;
1206        ::write(mFd, &x, 1);
1207        x = (length >> 8) & 0xff;
1208        ::write(mFd, &x, 1);
1209        x = length & 0xff;
1210        ::write(mFd, &x, 1);
1211
1212        ::write(mFd,
1213              (const uint8_t *)buffer->data() + buffer->range_offset(),
1214              length);
1215
1216        mOffset += length + 4;
1217    } else {
1218        CHECK_LT(length, 65536);
1219
1220        uint8_t x = length >> 8;
1221        ::write(mFd, &x, 1);
1222        x = length & 0xff;
1223        ::write(mFd, &x, 1);
1224        ::write(mFd, (const uint8_t *)buffer->data() + buffer->range_offset(), length);
1225        mOffset += length + 2;
1226    }
1227
1228    return old_offset;
1229}
1230
1231size_t MPEG4Writer::write(
1232        const void *ptr, size_t size, size_t nmemb) {
1233
1234    const size_t bytes = size * nmemb;
1235    if (mWriteMoovBoxToMemory) {
1236
1237        off64_t moovBoxSize = 8 + mMoovBoxBufferOffset + bytes;
1238        if (moovBoxSize > mEstimatedMoovBoxSize) {
1239            // The reserved moov box at the beginning of the file
1240            // is not big enough. Moov box should be written to
1241            // the end of the file from now on, but not to the
1242            // in-memory cache.
1243
1244            // We write partial moov box that is in the memory to
1245            // the file first.
1246            for (List<off64_t>::iterator it = mBoxes.begin();
1247                 it != mBoxes.end(); ++it) {
1248                (*it) += mOffset;
1249            }
1250            lseek64(mFd, mOffset, SEEK_SET);
1251            ::write(mFd, mMoovBoxBuffer, mMoovBoxBufferOffset);
1252            ::write(mFd, ptr, bytes);
1253            mOffset += (bytes + mMoovBoxBufferOffset);
1254
1255            // All subsequent moov box content will be written
1256            // to the end of the file.
1257            mWriteMoovBoxToMemory = false;
1258        } else {
1259            memcpy(mMoovBoxBuffer + mMoovBoxBufferOffset, ptr, bytes);
1260            mMoovBoxBufferOffset += bytes;
1261        }
1262    } else {
1263        ::write(mFd, ptr, size * nmemb);
1264        mOffset += bytes;
1265    }
1266    return bytes;
1267}
1268
1269void MPEG4Writer::beginBox(uint32_t id) {
1270    mBoxes.push_back(mWriteMoovBoxToMemory?
1271            mMoovBoxBufferOffset: mOffset);
1272
1273    writeInt32(0);
1274    writeInt32(id);
1275}
1276
1277void MPEG4Writer::beginBox(const char *fourcc) {
1278    CHECK_EQ(strlen(fourcc), 4);
1279
1280    mBoxes.push_back(mWriteMoovBoxToMemory?
1281            mMoovBoxBufferOffset: mOffset);
1282
1283    writeInt32(0);
1284    writeFourcc(fourcc);
1285}
1286
1287void MPEG4Writer::endBox() {
1288    CHECK(!mBoxes.empty());
1289
1290    off64_t offset = *--mBoxes.end();
1291    mBoxes.erase(--mBoxes.end());
1292
1293    if (mWriteMoovBoxToMemory) {
1294       int32_t x = htonl(mMoovBoxBufferOffset - offset);
1295       memcpy(mMoovBoxBuffer + offset, &x, 4);
1296    } else {
1297        lseek64(mFd, offset, SEEK_SET);
1298        writeInt32(mOffset - offset);
1299        mOffset -= 4;
1300        lseek64(mFd, mOffset, SEEK_SET);
1301    }
1302}
1303
1304void MPEG4Writer::writeInt8(int8_t x) {
1305    write(&x, 1, 1);
1306}
1307
1308void MPEG4Writer::writeInt16(int16_t x) {
1309    x = htons(x);
1310    write(&x, 1, 2);
1311}
1312
1313void MPEG4Writer::writeInt32(int32_t x) {
1314    x = htonl(x);
1315    write(&x, 1, 4);
1316}
1317
1318void MPEG4Writer::writeInt64(int64_t x) {
1319    x = hton64(x);
1320    write(&x, 1, 8);
1321}
1322
1323void MPEG4Writer::writeCString(const char *s) {
1324    size_t n = strlen(s);
1325    write(s, 1, n + 1);
1326}
1327
1328void MPEG4Writer::writeFourcc(const char *s) {
1329    CHECK_EQ(strlen(s), 4);
1330    write(s, 1, 4);
1331}
1332
1333
1334// Written in +/-DD.DDDD format
1335void MPEG4Writer::writeLatitude(int degreex10000) {
1336    bool isNegative = (degreex10000 < 0);
1337    char sign = isNegative? '-': '+';
1338
1339    // Handle the whole part
1340    char str[9];
1341    int wholePart = degreex10000 / 10000;
1342    if (wholePart == 0) {
1343        snprintf(str, 5, "%c%.2d.", sign, wholePart);
1344    } else {
1345        snprintf(str, 5, "%+.2d.", wholePart);
1346    }
1347
1348    // Handle the fractional part
1349    int fractionalPart = degreex10000 - (wholePart * 10000);
1350    if (fractionalPart < 0) {
1351        fractionalPart = -fractionalPart;
1352    }
1353    snprintf(&str[4], 5, "%.4d", fractionalPart);
1354
1355    // Do not write the null terminator
1356    write(str, 1, 8);
1357}
1358
1359// Written in +/- DDD.DDDD format
1360void MPEG4Writer::writeLongitude(int degreex10000) {
1361    bool isNegative = (degreex10000 < 0);
1362    char sign = isNegative? '-': '+';
1363
1364    // Handle the whole part
1365    char str[10];
1366    int wholePart = degreex10000 / 10000;
1367    if (wholePart == 0) {
1368        snprintf(str, 6, "%c%.3d.", sign, wholePart);
1369    } else {
1370        snprintf(str, 6, "%+.3d.", wholePart);
1371    }
1372
1373    // Handle the fractional part
1374    int fractionalPart = degreex10000 - (wholePart * 10000);
1375    if (fractionalPart < 0) {
1376        fractionalPart = -fractionalPart;
1377    }
1378    snprintf(&str[5], 5, "%.4d", fractionalPart);
1379
1380    // Do not write the null terminator
1381    write(str, 1, 9);
1382}
1383
1384/*
1385 * Geodata is stored according to ISO-6709 standard.
1386 * latitudex10000 is latitude in degrees times 10000, and
1387 * longitudex10000 is longitude in degrees times 10000.
1388 * The range for the latitude is in [-90, +90], and
1389 * The range for the longitude is in [-180, +180]
1390 */
1391status_t MPEG4Writer::setGeoData(int latitudex10000, int longitudex10000) {
1392    // Is latitude or longitude out of range?
1393    if (latitudex10000 < -900000 || latitudex10000 > 900000 ||
1394        longitudex10000 < -1800000 || longitudex10000 > 1800000) {
1395        return BAD_VALUE;
1396    }
1397
1398    mLatitudex10000 = latitudex10000;
1399    mLongitudex10000 = longitudex10000;
1400    mAreGeoTagsAvailable = true;
1401    mMoovExtraSize += 30;
1402    return OK;
1403}
1404
1405status_t MPEG4Writer::setCaptureRate(float captureFps) {
1406    if (captureFps <= 0.0f) {
1407        return BAD_VALUE;
1408    }
1409
1410    mMetaKeys->setFloat(kMetaKey_CaptureFps, captureFps);
1411    mMoovExtraSize += sizeof(kMetaKey_CaptureFps) + 4 + 32;
1412
1413    return OK;
1414}
1415
1416void MPEG4Writer::write(const void *data, size_t size) {
1417    write(data, 1, size);
1418}
1419
1420bool MPEG4Writer::isFileStreamable() const {
1421    return mStreamableFile;
1422}
1423
1424bool MPEG4Writer::exceedsFileSizeLimit() {
1425    // No limit
1426    if (mMaxFileSizeLimitBytes == 0) {
1427        return false;
1428    }
1429
1430    int64_t nTotalBytesEstimate = static_cast<int64_t>(mEstimatedMoovBoxSize);
1431    for (List<Track *>::iterator it = mTracks.begin();
1432         it != mTracks.end(); ++it) {
1433        nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
1434    }
1435
1436    if (!mStreamableFile) {
1437        // Add 1024 bytes as error tolerance
1438        return nTotalBytesEstimate + 1024 >= mMaxFileSizeLimitBytes;
1439    }
1440    // Be conservative in the estimate: do not exceed 95% of
1441    // the target file limit. For small target file size limit, though,
1442    // this will not help.
1443    return (nTotalBytesEstimate >= (95 * mMaxFileSizeLimitBytes) / 100);
1444}
1445
1446bool MPEG4Writer::exceedsFileDurationLimit() {
1447    // No limit
1448    if (mMaxFileDurationLimitUs == 0) {
1449        return false;
1450    }
1451
1452    for (List<Track *>::iterator it = mTracks.begin();
1453         it != mTracks.end(); ++it) {
1454        if ((*it)->getDurationUs() >= mMaxFileDurationLimitUs) {
1455            return true;
1456        }
1457    }
1458    return false;
1459}
1460
1461bool MPEG4Writer::reachedEOS() {
1462    bool allDone = true;
1463    for (List<Track *>::iterator it = mTracks.begin();
1464         it != mTracks.end(); ++it) {
1465        if (!(*it)->reachedEOS()) {
1466            allDone = false;
1467            break;
1468        }
1469    }
1470
1471    return allDone;
1472}
1473
1474void MPEG4Writer::setStartTimestampUs(int64_t timeUs) {
1475    ALOGI("setStartTimestampUs: %" PRId64, timeUs);
1476    CHECK_GE(timeUs, 0ll);
1477    Mutex::Autolock autoLock(mLock);
1478    if (mStartTimestampUs < 0 || mStartTimestampUs > timeUs) {
1479        mStartTimestampUs = timeUs;
1480        ALOGI("Earliest track starting time: %" PRId64, mStartTimestampUs);
1481    }
1482}
1483
1484int64_t MPEG4Writer::getStartTimestampUs() {
1485    Mutex::Autolock autoLock(mLock);
1486    return mStartTimestampUs;
1487}
1488
1489size_t MPEG4Writer::numTracks() {
1490    Mutex::Autolock autolock(mLock);
1491    return mTracks.size();
1492}
1493
1494////////////////////////////////////////////////////////////////////////////////
1495
1496MPEG4Writer::Track::Track(
1497        MPEG4Writer *owner, const sp<IMediaSource> &source, size_t trackId)
1498    : mOwner(owner),
1499      mMeta(source->getFormat()),
1500      mSource(source),
1501      mDone(false),
1502      mPaused(false),
1503      mResumed(false),
1504      mStarted(false),
1505      mTrackId(trackId),
1506      mTrackDurationUs(0),
1507      mEstimatedTrackSizeBytes(0),
1508      mSamplesHaveSameSize(true),
1509      mStszTableEntries(new ListTableEntries<uint32_t>(1000, 1)),
1510      mStcoTableEntries(new ListTableEntries<uint32_t>(1000, 1)),
1511      mCo64TableEntries(new ListTableEntries<off64_t>(1000, 1)),
1512      mStscTableEntries(new ListTableEntries<uint32_t>(1000, 3)),
1513      mStssTableEntries(new ListTableEntries<uint32_t>(1000, 1)),
1514      mSttsTableEntries(new ListTableEntries<uint32_t>(1000, 2)),
1515      mCttsTableEntries(new ListTableEntries<uint32_t>(1000, 2)),
1516      mCodecSpecificData(NULL),
1517      mCodecSpecificDataSize(0),
1518      mGotAllCodecSpecificData(false),
1519      mReachedEOS(false),
1520      mRotation(0) {
1521    getCodecSpecificDataFromInputFormatIfPossible();
1522
1523    const char *mime;
1524    mMeta->findCString(kKeyMIMEType, &mime);
1525    mIsAvc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
1526    mIsHevc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC);
1527    mIsAudio = !strncasecmp(mime, "audio/", 6);
1528    mIsMPEG4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
1529               !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC);
1530
1531    setTimeScale();
1532}
1533
1534void MPEG4Writer::Track::updateTrackSizeEstimate() {
1535
1536    uint32_t stcoBoxCount = (mOwner->use32BitFileOffset()
1537                            ? mStcoTableEntries->count()
1538                            : mCo64TableEntries->count());
1539    int64_t stcoBoxSizeBytes = stcoBoxCount * 4;
1540    int64_t stszBoxSizeBytes = mSamplesHaveSameSize? 4: (mStszTableEntries->count() * 4);
1541
1542    mEstimatedTrackSizeBytes = mMdatSizeBytes;  // media data size
1543    if (!mOwner->isFileStreamable()) {
1544        // Reserved free space is not large enough to hold
1545        // all meta data and thus wasted.
1546        mEstimatedTrackSizeBytes += mStscTableEntries->count() * 12 +  // stsc box size
1547                                    mStssTableEntries->count() * 4 +   // stss box size
1548                                    mSttsTableEntries->count() * 8 +   // stts box size
1549                                    mCttsTableEntries->count() * 8 +   // ctts box size
1550                                    stcoBoxSizeBytes +           // stco box size
1551                                    stszBoxSizeBytes;            // stsz box size
1552    }
1553}
1554
1555void MPEG4Writer::Track::addOneStscTableEntry(
1556        size_t chunkId, size_t sampleId) {
1557
1558        mStscTableEntries->add(htonl(chunkId));
1559        mStscTableEntries->add(htonl(sampleId));
1560        mStscTableEntries->add(htonl(1));
1561}
1562
1563void MPEG4Writer::Track::addOneStssTableEntry(size_t sampleId) {
1564    mStssTableEntries->add(htonl(sampleId));
1565}
1566
1567void MPEG4Writer::Track::addOneSttsTableEntry(
1568        size_t sampleCount, int32_t duration) {
1569
1570    if (duration == 0) {
1571        ALOGW("0-duration samples found: %zu", sampleCount);
1572    }
1573    mSttsTableEntries->add(htonl(sampleCount));
1574    mSttsTableEntries->add(htonl(duration));
1575}
1576
1577void MPEG4Writer::Track::addOneCttsTableEntry(
1578        size_t sampleCount, int32_t duration) {
1579
1580    if (mIsAudio) {
1581        return;
1582    }
1583    mCttsTableEntries->add(htonl(sampleCount));
1584    mCttsTableEntries->add(htonl(duration));
1585}
1586
1587void MPEG4Writer::Track::addChunkOffset(off64_t offset) {
1588    if (mOwner->use32BitFileOffset()) {
1589        uint32_t value = offset;
1590        mStcoTableEntries->add(htonl(value));
1591    } else {
1592        mCo64TableEntries->add(hton64(offset));
1593    }
1594}
1595
1596void MPEG4Writer::Track::setTimeScale() {
1597    ALOGV("setTimeScale");
1598    // Default time scale
1599    mTimeScale = 90000;
1600
1601    if (mIsAudio) {
1602        // Use the sampling rate as the default time scale for audio track.
1603        int32_t sampleRate;
1604        bool success = mMeta->findInt32(kKeySampleRate, &sampleRate);
1605        CHECK(success);
1606        mTimeScale = sampleRate;
1607    }
1608
1609    // If someone would like to overwrite the timescale, use user-supplied value.
1610    int32_t timeScale;
1611    if (mMeta->findInt32(kKeyTimeScale, &timeScale)) {
1612        mTimeScale = timeScale;
1613    }
1614
1615    CHECK_GT(mTimeScale, 0);
1616}
1617
1618void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() {
1619    const char *mime;
1620    CHECK(mMeta->findCString(kKeyMIMEType, &mime));
1621
1622    uint32_t type;
1623    const void *data = NULL;
1624    size_t size = 0;
1625    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
1626        mMeta->findData(kKeyAVCC, &type, &data, &size);
1627    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
1628        mMeta->findData(kKeyHVCC, &type, &data, &size);
1629    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
1630            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1631        if (mMeta->findData(kKeyESDS, &type, &data, &size)) {
1632            ESDS esds(data, size);
1633            if (esds.getCodecSpecificInfo(&data, &size) != OK) {
1634                data = NULL;
1635                size = 0;
1636            }
1637        }
1638    }
1639    if (data != NULL && copyCodecSpecificData((uint8_t *)data, size) == OK) {
1640        mGotAllCodecSpecificData = true;
1641    }
1642}
1643
1644MPEG4Writer::Track::~Track() {
1645    stop();
1646
1647    delete mStszTableEntries;
1648    delete mStcoTableEntries;
1649    delete mCo64TableEntries;
1650    delete mStscTableEntries;
1651    delete mSttsTableEntries;
1652    delete mStssTableEntries;
1653    delete mCttsTableEntries;
1654
1655    mStszTableEntries = NULL;
1656    mStcoTableEntries = NULL;
1657    mCo64TableEntries = NULL;
1658    mStscTableEntries = NULL;
1659    mSttsTableEntries = NULL;
1660    mStssTableEntries = NULL;
1661    mCttsTableEntries = NULL;
1662
1663    if (mCodecSpecificData != NULL) {
1664        free(mCodecSpecificData);
1665        mCodecSpecificData = NULL;
1666    }
1667}
1668
1669void MPEG4Writer::Track::initTrackingProgressStatus(MetaData *params) {
1670    ALOGV("initTrackingProgressStatus");
1671    mPreviousTrackTimeUs = -1;
1672    mTrackingProgressStatus = false;
1673    mTrackEveryTimeDurationUs = 0;
1674    {
1675        int64_t timeUs;
1676        if (params && params->findInt64(kKeyTrackTimeStatus, &timeUs)) {
1677            ALOGV("Receive request to track progress status for every %" PRId64 " us", timeUs);
1678            mTrackEveryTimeDurationUs = timeUs;
1679            mTrackingProgressStatus = true;
1680        }
1681    }
1682}
1683
1684// static
1685void *MPEG4Writer::ThreadWrapper(void *me) {
1686    ALOGV("ThreadWrapper: %p", me);
1687    MPEG4Writer *writer = static_cast<MPEG4Writer *>(me);
1688    writer->threadFunc();
1689    return NULL;
1690}
1691
1692void MPEG4Writer::bufferChunk(const Chunk& chunk) {
1693    ALOGV("bufferChunk: %p", chunk.mTrack);
1694    Mutex::Autolock autolock(mLock);
1695    CHECK_EQ(mDone, false);
1696
1697    for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
1698         it != mChunkInfos.end(); ++it) {
1699
1700        if (chunk.mTrack == it->mTrack) {  // Found owner
1701            it->mChunks.push_back(chunk);
1702            mChunkReadyCondition.signal();
1703            return;
1704        }
1705    }
1706
1707    CHECK(!"Received a chunk for a unknown track");
1708}
1709
1710void MPEG4Writer::writeChunkToFile(Chunk* chunk) {
1711    ALOGV("writeChunkToFile: %" PRId64 " from %s track",
1712        chunk->mTimeStampUs, chunk->mTrack->isAudio()? "audio": "video");
1713
1714    int32_t isFirstSample = true;
1715    while (!chunk->mSamples.empty()) {
1716        List<MediaBuffer *>::iterator it = chunk->mSamples.begin();
1717
1718        off64_t offset = (chunk->mTrack->isAvc() || chunk->mTrack->isHevc())
1719                                ? addMultipleLengthPrefixedSamples_l(*it)
1720                                : addSample_l(*it);
1721
1722        if (isFirstSample) {
1723            chunk->mTrack->addChunkOffset(offset);
1724            isFirstSample = false;
1725        }
1726
1727        (*it)->release();
1728        (*it) = NULL;
1729        chunk->mSamples.erase(it);
1730    }
1731    chunk->mSamples.clear();
1732}
1733
1734void MPEG4Writer::writeAllChunks() {
1735    ALOGV("writeAllChunks");
1736    size_t outstandingChunks = 0;
1737    Chunk chunk;
1738    while (findChunkToWrite(&chunk)) {
1739        writeChunkToFile(&chunk);
1740        ++outstandingChunks;
1741    }
1742
1743    sendSessionSummary();
1744
1745    mChunkInfos.clear();
1746    ALOGD("%zu chunks are written in the last batch", outstandingChunks);
1747}
1748
1749bool MPEG4Writer::findChunkToWrite(Chunk *chunk) {
1750    ALOGV("findChunkToWrite");
1751
1752    int64_t minTimestampUs = 0x7FFFFFFFFFFFFFFFLL;
1753    Track *track = NULL;
1754    for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
1755         it != mChunkInfos.end(); ++it) {
1756        if (!it->mChunks.empty()) {
1757            List<Chunk>::iterator chunkIt = it->mChunks.begin();
1758            if (chunkIt->mTimeStampUs < minTimestampUs) {
1759                minTimestampUs = chunkIt->mTimeStampUs;
1760                track = it->mTrack;
1761            }
1762        }
1763    }
1764
1765    if (track == NULL) {
1766        ALOGV("Nothing to be written after all");
1767        return false;
1768    }
1769
1770    if (mIsFirstChunk) {
1771        mIsFirstChunk = false;
1772    }
1773
1774    for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
1775         it != mChunkInfos.end(); ++it) {
1776        if (it->mTrack == track) {
1777            *chunk = *(it->mChunks.begin());
1778            it->mChunks.erase(it->mChunks.begin());
1779            CHECK_EQ(chunk->mTrack, track);
1780
1781            int64_t interChunkTimeUs =
1782                chunk->mTimeStampUs - it->mPrevChunkTimestampUs;
1783            if (interChunkTimeUs > it->mPrevChunkTimestampUs) {
1784                it->mMaxInterChunkDurUs = interChunkTimeUs;
1785            }
1786
1787            return true;
1788        }
1789    }
1790
1791    return false;
1792}
1793
1794void MPEG4Writer::threadFunc() {
1795    ALOGV("threadFunc");
1796
1797    prctl(PR_SET_NAME, (unsigned long)"MPEG4Writer", 0, 0, 0);
1798
1799    Mutex::Autolock autoLock(mLock);
1800    while (!mDone) {
1801        Chunk chunk;
1802        bool chunkFound = false;
1803
1804        while (!mDone && !(chunkFound = findChunkToWrite(&chunk))) {
1805            mChunkReadyCondition.wait(mLock);
1806        }
1807
1808        // In real time recording mode, write without holding the lock in order
1809        // to reduce the blocking time for media track threads.
1810        // Otherwise, hold the lock until the existing chunks get written to the
1811        // file.
1812        if (chunkFound) {
1813            if (mIsRealTimeRecording) {
1814                mLock.unlock();
1815            }
1816            writeChunkToFile(&chunk);
1817            if (mIsRealTimeRecording) {
1818                mLock.lock();
1819            }
1820        }
1821    }
1822
1823    writeAllChunks();
1824}
1825
1826status_t MPEG4Writer::startWriterThread() {
1827    ALOGV("startWriterThread");
1828
1829    mDone = false;
1830    mIsFirstChunk = true;
1831    mDriftTimeUs = 0;
1832    for (List<Track *>::iterator it = mTracks.begin();
1833         it != mTracks.end(); ++it) {
1834        ChunkInfo info;
1835        info.mTrack = *it;
1836        info.mPrevChunkTimestampUs = 0;
1837        info.mMaxInterChunkDurUs = 0;
1838        mChunkInfos.push_back(info);
1839    }
1840
1841    pthread_attr_t attr;
1842    pthread_attr_init(&attr);
1843    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
1844    pthread_create(&mThread, &attr, ThreadWrapper, this);
1845    pthread_attr_destroy(&attr);
1846    mWriterThreadStarted = true;
1847    return OK;
1848}
1849
1850
1851status_t MPEG4Writer::Track::start(MetaData *params) {
1852    if (!mDone && mPaused) {
1853        mPaused = false;
1854        mResumed = true;
1855        return OK;
1856    }
1857
1858    int64_t startTimeUs;
1859    if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
1860        startTimeUs = 0;
1861    }
1862    mStartTimeRealUs = startTimeUs;
1863
1864    int32_t rotationDegrees;
1865    if (!mIsAudio && params && params->findInt32(kKeyRotation, &rotationDegrees)) {
1866        mRotation = rotationDegrees;
1867    }
1868
1869    initTrackingProgressStatus(params);
1870
1871    sp<MetaData> meta = new MetaData;
1872    if (mOwner->isRealTimeRecording() && mOwner->numTracks() > 1) {
1873        /*
1874         * This extra delay of accepting incoming audio/video signals
1875         * helps to align a/v start time at the beginning of a recording
1876         * session, and it also helps eliminate the "recording" sound for
1877         * camcorder applications.
1878         *
1879         * If client does not set the start time offset, we fall back to
1880         * use the default initial delay value.
1881         */
1882        int64_t startTimeOffsetUs = mOwner->getStartTimeOffsetMs() * 1000LL;
1883        if (startTimeOffsetUs < 0) {  // Start time offset was not set
1884            startTimeOffsetUs = kInitialDelayTimeUs;
1885        }
1886        startTimeUs += startTimeOffsetUs;
1887        ALOGI("Start time offset: %" PRId64 " us", startTimeOffsetUs);
1888    }
1889
1890    meta->setInt64(kKeyTime, startTimeUs);
1891
1892    status_t err = mSource->start(meta.get());
1893    if (err != OK) {
1894        mDone = mReachedEOS = true;
1895        return err;
1896    }
1897
1898    pthread_attr_t attr;
1899    pthread_attr_init(&attr);
1900    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
1901
1902    mDone = false;
1903    mStarted = true;
1904    mTrackDurationUs = 0;
1905    mReachedEOS = false;
1906    mEstimatedTrackSizeBytes = 0;
1907    mMdatSizeBytes = 0;
1908    mMaxChunkDurationUs = 0;
1909
1910    pthread_create(&mThread, &attr, ThreadWrapper, this);
1911    pthread_attr_destroy(&attr);
1912
1913    return OK;
1914}
1915
1916status_t MPEG4Writer::Track::pause() {
1917    mPaused = true;
1918    return OK;
1919}
1920
1921status_t MPEG4Writer::Track::stop() {
1922    ALOGD("%s track stopping", mIsAudio? "Audio": "Video");
1923    if (!mStarted) {
1924        ALOGE("Stop() called but track is not started");
1925        return ERROR_END_OF_STREAM;
1926    }
1927
1928    if (mDone) {
1929        return OK;
1930    }
1931    mDone = true;
1932
1933    ALOGD("%s track source stopping", mIsAudio? "Audio": "Video");
1934    mSource->stop();
1935    ALOGD("%s track source stopped", mIsAudio? "Audio": "Video");
1936
1937    void *dummy;
1938    pthread_join(mThread, &dummy);
1939    status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
1940
1941    ALOGD("%s track stopped", mIsAudio? "Audio": "Video");
1942    return err;
1943}
1944
1945bool MPEG4Writer::Track::reachedEOS() {
1946    return mReachedEOS;
1947}
1948
1949// static
1950void *MPEG4Writer::Track::ThreadWrapper(void *me) {
1951    Track *track = static_cast<Track *>(me);
1952
1953    status_t err = track->threadEntry();
1954    return (void *)(uintptr_t)err;
1955}
1956
1957static void getNalUnitType(uint8_t byte, uint8_t* type) {
1958    ALOGV("getNalUnitType: %d", byte);
1959
1960    // nal_unit_type: 5-bit unsigned integer
1961    *type = (byte & 0x1F);
1962}
1963
1964const uint8_t *MPEG4Writer::Track::parseParamSet(
1965        const uint8_t *data, size_t length, int type, size_t *paramSetLen) {
1966
1967    ALOGV("parseParamSet");
1968    CHECK(type == kNalUnitTypeSeqParamSet ||
1969          type == kNalUnitTypePicParamSet);
1970
1971    const uint8_t *nextStartCode = findNextNalStartCode(data, length);
1972    *paramSetLen = nextStartCode - data;
1973    if (*paramSetLen == 0) {
1974        ALOGE("Param set is malformed, since its length is 0");
1975        return NULL;
1976    }
1977
1978    AVCParamSet paramSet(*paramSetLen, data);
1979    if (type == kNalUnitTypeSeqParamSet) {
1980        if (*paramSetLen < 4) {
1981            ALOGE("Seq parameter set malformed");
1982            return NULL;
1983        }
1984        if (mSeqParamSets.empty()) {
1985            mProfileIdc = data[1];
1986            mProfileCompatible = data[2];
1987            mLevelIdc = data[3];
1988        } else {
1989            if (mProfileIdc != data[1] ||
1990                mProfileCompatible != data[2] ||
1991                mLevelIdc != data[3]) {
1992                // COULD DO: set profile/level to the lowest required to support all SPSs
1993                ALOGE("Inconsistent profile/level found in seq parameter sets");
1994                return NULL;
1995            }
1996        }
1997        mSeqParamSets.push_back(paramSet);
1998    } else {
1999        mPicParamSets.push_back(paramSet);
2000    }
2001    return nextStartCode;
2002}
2003
2004status_t MPEG4Writer::Track::copyAVCCodecSpecificData(
2005        const uint8_t *data, size_t size) {
2006    ALOGV("copyAVCCodecSpecificData");
2007
2008    // 2 bytes for each of the parameter set length field
2009    // plus the 7 bytes for the header
2010    return copyCodecSpecificData(data, size, 4 + 7);
2011}
2012
2013status_t MPEG4Writer::Track::copyHEVCCodecSpecificData(
2014        const uint8_t *data, size_t size) {
2015    ALOGV("copyHEVCCodecSpecificData");
2016
2017    // Min length of HEVC CSD is 23. (ISO/IEC 14496-15:2014 Chapter 8.3.3.1.2)
2018    return copyCodecSpecificData(data, size, 23);
2019}
2020
2021status_t MPEG4Writer::Track::copyCodecSpecificData(
2022        const uint8_t *data, size_t size, size_t minLength) {
2023    if (size < minLength) {
2024        ALOGE("Codec specific data length too short: %zu", size);
2025        return ERROR_MALFORMED;
2026    }
2027
2028    mCodecSpecificData = malloc(size);
2029    if (mCodecSpecificData == NULL) {
2030        ALOGE("Failed allocating codec specific data");
2031        return NO_MEMORY;
2032    }
2033    mCodecSpecificDataSize = size;
2034    memcpy(mCodecSpecificData, data, size);
2035    return OK;
2036}
2037
2038status_t MPEG4Writer::Track::parseAVCCodecSpecificData(
2039        const uint8_t *data, size_t size) {
2040
2041    ALOGV("parseAVCCodecSpecificData");
2042    // Data starts with a start code.
2043    // SPS and PPS are separated with start codes.
2044    // Also, SPS must come before PPS
2045    uint8_t type = kNalUnitTypeSeqParamSet;
2046    bool gotSps = false;
2047    bool gotPps = false;
2048    const uint8_t *tmp = data;
2049    const uint8_t *nextStartCode = data;
2050    size_t bytesLeft = size;
2051    size_t paramSetLen = 0;
2052    mCodecSpecificDataSize = 0;
2053    while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) {
2054        getNalUnitType(*(tmp + 4), &type);
2055        if (type == kNalUnitTypeSeqParamSet) {
2056            if (gotPps) {
2057                ALOGE("SPS must come before PPS");
2058                return ERROR_MALFORMED;
2059            }
2060            if (!gotSps) {
2061                gotSps = true;
2062            }
2063            nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, &paramSetLen);
2064        } else if (type == kNalUnitTypePicParamSet) {
2065            if (!gotSps) {
2066                ALOGE("SPS must come before PPS");
2067                return ERROR_MALFORMED;
2068            }
2069            if (!gotPps) {
2070                gotPps = true;
2071            }
2072            nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, &paramSetLen);
2073        } else {
2074            ALOGE("Only SPS and PPS Nal units are expected");
2075            return ERROR_MALFORMED;
2076        }
2077
2078        if (nextStartCode == NULL) {
2079            return ERROR_MALFORMED;
2080        }
2081
2082        // Move on to find the next parameter set
2083        bytesLeft -= nextStartCode - tmp;
2084        tmp = nextStartCode;
2085        mCodecSpecificDataSize += (2 + paramSetLen);
2086    }
2087
2088    {
2089        // Check on the number of seq parameter sets
2090        size_t nSeqParamSets = mSeqParamSets.size();
2091        if (nSeqParamSets == 0) {
2092            ALOGE("Cound not find sequence parameter set");
2093            return ERROR_MALFORMED;
2094        }
2095
2096        if (nSeqParamSets > 0x1F) {
2097            ALOGE("Too many seq parameter sets (%zu) found", nSeqParamSets);
2098            return ERROR_MALFORMED;
2099        }
2100    }
2101
2102    {
2103        // Check on the number of pic parameter sets
2104        size_t nPicParamSets = mPicParamSets.size();
2105        if (nPicParamSets == 0) {
2106            ALOGE("Cound not find picture parameter set");
2107            return ERROR_MALFORMED;
2108        }
2109        if (nPicParamSets > 0xFF) {
2110            ALOGE("Too many pic parameter sets (%zd) found", nPicParamSets);
2111            return ERROR_MALFORMED;
2112        }
2113    }
2114// FIXME:
2115// Add chromat_format_idc, bit depth values, etc for AVC/h264 high profile and above
2116// and remove #if 0
2117#if 0
2118    {
2119        // Check on the profiles
2120        // These profiles requires additional parameter set extensions
2121        if (mProfileIdc == 100 || mProfileIdc == 110 ||
2122            mProfileIdc == 122 || mProfileIdc == 144) {
2123            ALOGE("Sorry, no support for profile_idc: %d!", mProfileIdc);
2124            return BAD_VALUE;
2125        }
2126    }
2127#endif
2128    return OK;
2129}
2130
2131status_t MPEG4Writer::Track::makeAVCCodecSpecificData(
2132        const uint8_t *data, size_t size) {
2133
2134    if (mCodecSpecificData != NULL) {
2135        ALOGE("Already have codec specific data");
2136        return ERROR_MALFORMED;
2137    }
2138
2139    if (size < 4) {
2140        ALOGE("Codec specific data length too short: %zu", size);
2141        return ERROR_MALFORMED;
2142    }
2143
2144    // Data is in the form of AVCCodecSpecificData
2145    if (memcmp("\x00\x00\x00\x01", data, 4)) {
2146        return copyAVCCodecSpecificData(data, size);
2147    }
2148
2149    if (parseAVCCodecSpecificData(data, size) != OK) {
2150        return ERROR_MALFORMED;
2151    }
2152
2153    // ISO 14496-15: AVC file format
2154    mCodecSpecificDataSize += 7;  // 7 more bytes in the header
2155    mCodecSpecificData = malloc(mCodecSpecificDataSize);
2156    if (mCodecSpecificData == NULL) {
2157        mCodecSpecificDataSize = 0;
2158        ALOGE("Failed allocating codec specific data");
2159        return NO_MEMORY;
2160    }
2161    uint8_t *header = (uint8_t *)mCodecSpecificData;
2162    header[0] = 1;                     // version
2163    header[1] = mProfileIdc;           // profile indication
2164    header[2] = mProfileCompatible;    // profile compatibility
2165    header[3] = mLevelIdc;
2166
2167    // 6-bit '111111' followed by 2-bit to lengthSizeMinuusOne
2168    if (mOwner->useNalLengthFour()) {
2169        header[4] = 0xfc | 3;  // length size == 4 bytes
2170    } else {
2171        header[4] = 0xfc | 1;  // length size == 2 bytes
2172    }
2173
2174    // 3-bit '111' followed by 5-bit numSequenceParameterSets
2175    int nSequenceParamSets = mSeqParamSets.size();
2176    header[5] = 0xe0 | nSequenceParamSets;
2177    header += 6;
2178    for (List<AVCParamSet>::iterator it = mSeqParamSets.begin();
2179         it != mSeqParamSets.end(); ++it) {
2180        // 16-bit sequence parameter set length
2181        uint16_t seqParamSetLength = it->mLength;
2182        header[0] = seqParamSetLength >> 8;
2183        header[1] = seqParamSetLength & 0xff;
2184
2185        // SPS NAL unit (sequence parameter length bytes)
2186        memcpy(&header[2], it->mData, seqParamSetLength);
2187        header += (2 + seqParamSetLength);
2188    }
2189
2190    // 8-bit nPictureParameterSets
2191    int nPictureParamSets = mPicParamSets.size();
2192    header[0] = nPictureParamSets;
2193    header += 1;
2194    for (List<AVCParamSet>::iterator it = mPicParamSets.begin();
2195         it != mPicParamSets.end(); ++it) {
2196        // 16-bit picture parameter set length
2197        uint16_t picParamSetLength = it->mLength;
2198        header[0] = picParamSetLength >> 8;
2199        header[1] = picParamSetLength & 0xff;
2200
2201        // PPS Nal unit (picture parameter set length bytes)
2202        memcpy(&header[2], it->mData, picParamSetLength);
2203        header += (2 + picParamSetLength);
2204    }
2205
2206    return OK;
2207}
2208
2209
2210status_t MPEG4Writer::Track::parseHEVCCodecSpecificData(
2211        const uint8_t *data, size_t size, HevcParameterSets &paramSets) {
2212
2213    ALOGV("parseHEVCCodecSpecificData");
2214    const uint8_t *tmp = data;
2215    const uint8_t *nextStartCode = data;
2216    size_t bytesLeft = size;
2217    while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) {
2218        nextStartCode = findNextNalStartCode(tmp + 4, bytesLeft - 4);
2219        status_t err = paramSets.addNalUnit(tmp + 4, (nextStartCode - tmp) - 4);
2220        if (err != OK) {
2221            return ERROR_MALFORMED;
2222        }
2223
2224        // Move on to find the next parameter set
2225        bytesLeft -= nextStartCode - tmp;
2226        tmp = nextStartCode;
2227    }
2228
2229    size_t csdSize = 23;
2230    const size_t numNalUnits = paramSets.getNumNalUnits();
2231    for (size_t i = 0; i < ARRAY_SIZE(kMandatoryHevcNalUnitTypes); ++i) {
2232        int type = kMandatoryHevcNalUnitTypes[i];
2233        size_t numParamSets = paramSets.getNumNalUnitsOfType(type);
2234        if (numParamSets == 0) {
2235            ALOGE("Cound not find NAL unit of type %d", type);
2236            return ERROR_MALFORMED;
2237        }
2238    }
2239    for (size_t i = 0; i < ARRAY_SIZE(kHevcNalUnitTypes); ++i) {
2240        int type = kHevcNalUnitTypes[i];
2241        size_t numParamSets = paramSets.getNumNalUnitsOfType(type);
2242        if (numParamSets > 0xffff) {
2243            ALOGE("Too many seq parameter sets (%zu) found", numParamSets);
2244            return ERROR_MALFORMED;
2245        }
2246        csdSize += 3;
2247        for (size_t j = 0; j < numNalUnits; ++j) {
2248            if (paramSets.getType(j) != type) {
2249                continue;
2250            }
2251            csdSize += 2 + paramSets.getSize(j);
2252        }
2253    }
2254    mCodecSpecificDataSize = csdSize;
2255    return OK;
2256}
2257
2258status_t MPEG4Writer::Track::makeHEVCCodecSpecificData(
2259        const uint8_t *data, size_t size) {
2260
2261    if (mCodecSpecificData != NULL) {
2262        ALOGE("Already have codec specific data");
2263        return ERROR_MALFORMED;
2264    }
2265
2266    if (size < 4) {
2267        ALOGE("Codec specific data length too short: %zu", size);
2268        return ERROR_MALFORMED;
2269    }
2270
2271    // Data is in the form of HEVCCodecSpecificData
2272    if (memcmp("\x00\x00\x00\x01", data, 4)) {
2273        return copyHEVCCodecSpecificData(data, size);
2274    }
2275
2276    HevcParameterSets paramSets;
2277    if (parseHEVCCodecSpecificData(data, size, paramSets) != OK) {
2278        ALOGE("failed parsing codec specific data");
2279        return ERROR_MALFORMED;
2280    }
2281
2282    mCodecSpecificData = malloc(mCodecSpecificDataSize);
2283    if (mCodecSpecificData == NULL) {
2284        mCodecSpecificDataSize = 0;
2285        ALOGE("Failed allocating codec specific data");
2286        return NO_MEMORY;
2287    }
2288    status_t err = paramSets.makeHvcc((uint8_t *)mCodecSpecificData,
2289            &mCodecSpecificDataSize, mOwner->useNalLengthFour() ? 4 : 2);
2290    if (err != OK) {
2291        ALOGE("failed constructing HVCC atom");
2292        return err;
2293    }
2294
2295    return OK;
2296}
2297
2298/*
2299 * Updates the drift time from the audio track so that
2300 * the video track can get the updated drift time information
2301 * from the file writer. The fluctuation of the drift time of the audio
2302 * encoding path is smoothed out with a simple filter by giving a larger
2303 * weight to more recently drift time. The filter coefficients, 0.5 and 0.5,
2304 * are heuristically determined.
2305 */
2306void MPEG4Writer::Track::updateDriftTime(const sp<MetaData>& meta) {
2307    int64_t driftTimeUs = 0;
2308    if (meta->findInt64(kKeyDriftTime, &driftTimeUs)) {
2309        int64_t prevDriftTimeUs = mOwner->getDriftTimeUs();
2310        int64_t timeUs = (driftTimeUs + prevDriftTimeUs) >> 1;
2311        mOwner->setDriftTimeUs(timeUs);
2312    }
2313}
2314
2315status_t MPEG4Writer::Track::threadEntry() {
2316    int32_t count = 0;
2317    const int64_t interleaveDurationUs = mOwner->interleaveDuration();
2318    const bool hasMultipleTracks = (mOwner->numTracks() > 1);
2319    int64_t chunkTimestampUs = 0;
2320    int32_t nChunks = 0;
2321    int32_t nActualFrames = 0;        // frames containing non-CSD data (non-0 length)
2322    int32_t nZeroLengthFrames = 0;
2323    int64_t lastTimestampUs = 0;      // Previous sample time stamp
2324    int64_t lastDurationUs = 0;       // Between the previous two samples
2325    int64_t currDurationTicks = 0;    // Timescale based ticks
2326    int64_t lastDurationTicks = 0;    // Timescale based ticks
2327    int32_t sampleCount = 1;          // Sample count in the current stts table entry
2328    uint32_t previousSampleSize = 0;  // Size of the previous sample
2329    int64_t previousPausedDurationUs = 0;
2330    int64_t timestampUs = 0;
2331    int64_t cttsOffsetTimeUs = 0;
2332    int64_t currCttsOffsetTimeTicks = 0;   // Timescale based ticks
2333    int64_t lastCttsOffsetTimeTicks = -1;  // Timescale based ticks
2334    int32_t cttsSampleCount = 0;           // Sample count in the current ctts table entry
2335    uint32_t lastSamplesPerChunk = 0;
2336
2337    if (mIsAudio) {
2338        prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0);
2339    } else {
2340        prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0);
2341    }
2342
2343    if (mOwner->isRealTimeRecording()) {
2344        androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
2345    }
2346
2347    sp<MetaData> meta_data;
2348
2349    status_t err = OK;
2350    MediaBuffer *buffer;
2351    const char *trackName = mIsAudio ? "Audio" : "Video";
2352    while (!mDone && (err = mSource->read(&buffer)) == OK) {
2353        if (buffer->range_length() == 0) {
2354            buffer->release();
2355            buffer = NULL;
2356            ++nZeroLengthFrames;
2357            continue;
2358        }
2359
2360        // If the codec specific data has not been received yet, delay pause.
2361        // After the codec specific data is received, discard what we received
2362        // when the track is to be paused.
2363        if (mPaused && !mResumed) {
2364            buffer->release();
2365            buffer = NULL;
2366            continue;
2367        }
2368
2369        ++count;
2370
2371        int32_t isCodecConfig;
2372        if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig)
2373                && isCodecConfig) {
2374            // if config format (at track addition) already had CSD, keep that
2375            // UNLESS we have not received any frames yet.
2376            // TODO: for now the entire CSD has to come in one frame for encoders, even though
2377            // they need to be spread out for decoders.
2378            if (mGotAllCodecSpecificData && nActualFrames > 0) {
2379                ALOGI("ignoring additional CSD for video track after first frame");
2380            } else {
2381                mMeta = mSource->getFormat(); // get output format after format change
2382
2383                if (mIsAvc) {
2384                    status_t err = makeAVCCodecSpecificData(
2385                            (const uint8_t *)buffer->data()
2386                                + buffer->range_offset(),
2387                            buffer->range_length());
2388                    CHECK_EQ((status_t)OK, err);
2389                } else if (mIsHevc) {
2390                    status_t err = makeHEVCCodecSpecificData(
2391                            (const uint8_t *)buffer->data()
2392                                + buffer->range_offset(),
2393                            buffer->range_length());
2394                    CHECK_EQ((status_t)OK, err);
2395                } else if (mIsMPEG4) {
2396                    copyCodecSpecificData((const uint8_t *)buffer->data() + buffer->range_offset(),
2397                            buffer->range_length());
2398                }
2399            }
2400
2401            buffer->release();
2402            buffer = NULL;
2403
2404            mGotAllCodecSpecificData = true;
2405            continue;
2406        }
2407
2408        ++nActualFrames;
2409
2410        // Make a deep copy of the MediaBuffer and Metadata and release
2411        // the original as soon as we can
2412        MediaBuffer *copy = new MediaBuffer(buffer->range_length());
2413        memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(),
2414                buffer->range_length());
2415        copy->set_range(0, buffer->range_length());
2416        meta_data = new MetaData(*buffer->meta_data().get());
2417        buffer->release();
2418        buffer = NULL;
2419
2420        if (mIsAvc || mIsHevc) StripStartcode(copy);
2421
2422        size_t sampleSize = copy->range_length();
2423        if (mIsAvc || mIsHevc) {
2424            if (mOwner->useNalLengthFour()) {
2425                sampleSize += 4;
2426            } else {
2427                sampleSize += 2;
2428            }
2429        }
2430
2431        // Max file size or duration handling
2432        mMdatSizeBytes += sampleSize;
2433        updateTrackSizeEstimate();
2434
2435        if (mOwner->exceedsFileSizeLimit()) {
2436            ALOGW("Recorded file size exceeds limit %" PRId64 "bytes",
2437                    mOwner->mMaxFileSizeLimitBytes);
2438            mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
2439            break;
2440        }
2441        if (mOwner->exceedsFileDurationLimit()) {
2442            ALOGW("Recorded file duration exceeds limit %" PRId64 "microseconds",
2443                    mOwner->mMaxFileDurationLimitUs);
2444            mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0);
2445            break;
2446        }
2447
2448
2449        int32_t isSync = false;
2450        meta_data->findInt32(kKeyIsSyncFrame, &isSync);
2451        CHECK(meta_data->findInt64(kKeyTime, &timestampUs));
2452
2453////////////////////////////////////////////////////////////////////////////////
2454        if (mStszTableEntries->count() == 0) {
2455            mFirstSampleTimeRealUs = systemTime() / 1000;
2456            mStartTimestampUs = timestampUs;
2457            mOwner->setStartTimestampUs(mStartTimestampUs);
2458            previousPausedDurationUs = mStartTimestampUs;
2459        }
2460
2461        if (mResumed) {
2462            int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
2463            if (WARN_UNLESS(durExcludingEarlierPausesUs >= 0ll, "for %s track", trackName)) {
2464                copy->release();
2465                return ERROR_MALFORMED;
2466            }
2467
2468            int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs;
2469            if (WARN_UNLESS(pausedDurationUs >= lastDurationUs, "for %s track", trackName)) {
2470                copy->release();
2471                return ERROR_MALFORMED;
2472            }
2473
2474            previousPausedDurationUs += pausedDurationUs - lastDurationUs;
2475            mResumed = false;
2476        }
2477
2478        timestampUs -= previousPausedDurationUs;
2479        if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
2480            copy->release();
2481            return ERROR_MALFORMED;
2482        }
2483
2484        if (!mIsAudio) {
2485            /*
2486             * Composition time: timestampUs
2487             * Decoding time: decodingTimeUs
2488             * Composition time offset = composition time - decoding time
2489             */
2490            int64_t decodingTimeUs;
2491            CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs));
2492            decodingTimeUs -= previousPausedDurationUs;
2493            cttsOffsetTimeUs =
2494                    timestampUs + kMaxCttsOffsetTimeUs - decodingTimeUs;
2495            if (WARN_UNLESS(cttsOffsetTimeUs >= 0ll, "for %s track", trackName)) {
2496                copy->release();
2497                return ERROR_MALFORMED;
2498            }
2499
2500            timestampUs = decodingTimeUs;
2501            ALOGV("decoding time: %" PRId64 " and ctts offset time: %" PRId64,
2502                timestampUs, cttsOffsetTimeUs);
2503
2504            // Update ctts box table if necessary
2505            currCttsOffsetTimeTicks =
2506                    (cttsOffsetTimeUs * mTimeScale + 500000LL) / 1000000LL;
2507            if (WARN_UNLESS(currCttsOffsetTimeTicks <= 0x0FFFFFFFFLL, "for %s track", trackName)) {
2508                copy->release();
2509                return ERROR_MALFORMED;
2510            }
2511
2512            if (mStszTableEntries->count() == 0) {
2513                // Force the first ctts table entry to have one single entry
2514                // so that we can do adjustment for the initial track start
2515                // time offset easily in writeCttsBox().
2516                lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
2517                addOneCttsTableEntry(1, currCttsOffsetTimeTicks);
2518                cttsSampleCount = 0;      // No sample in ctts box is pending
2519            } else {
2520                if (currCttsOffsetTimeTicks != lastCttsOffsetTimeTicks) {
2521                    addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
2522                    lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
2523                    cttsSampleCount = 1;  // One sample in ctts box is pending
2524                } else {
2525                    ++cttsSampleCount;
2526                }
2527            }
2528
2529            // Update ctts time offset range
2530            if (mStszTableEntries->count() == 0) {
2531                mMinCttsOffsetTimeUs = currCttsOffsetTimeTicks;
2532                mMaxCttsOffsetTimeUs = currCttsOffsetTimeTicks;
2533            } else {
2534                if (currCttsOffsetTimeTicks > mMaxCttsOffsetTimeUs) {
2535                    mMaxCttsOffsetTimeUs = currCttsOffsetTimeTicks;
2536                } else if (currCttsOffsetTimeTicks < mMinCttsOffsetTimeUs) {
2537                    mMinCttsOffsetTimeUs = currCttsOffsetTimeTicks;
2538                }
2539            }
2540
2541        }
2542
2543        if (mOwner->isRealTimeRecording()) {
2544            if (mIsAudio) {
2545                updateDriftTime(meta_data);
2546            }
2547        }
2548
2549        if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
2550            copy->release();
2551            return ERROR_MALFORMED;
2552        }
2553
2554        ALOGV("%s media time stamp: %" PRId64 " and previous paused duration %" PRId64,
2555                trackName, timestampUs, previousPausedDurationUs);
2556        if (timestampUs > mTrackDurationUs) {
2557            mTrackDurationUs = timestampUs;
2558        }
2559
2560        // We need to use the time scale based ticks, rather than the
2561        // timestamp itself to determine whether we have to use a new
2562        // stts entry, since we may have rounding errors.
2563        // The calculation is intended to reduce the accumulated
2564        // rounding errors.
2565        currDurationTicks =
2566            ((timestampUs * mTimeScale + 500000LL) / 1000000LL -
2567                (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
2568        if (currDurationTicks < 0ll) {
2569            ALOGE("do not support out of order frames (timestamp: %lld < last: %lld for %s track",
2570                    (long long)timestampUs, (long long)lastTimestampUs, trackName);
2571            copy->release();
2572            mSource->stop();
2573            return UNKNOWN_ERROR;
2574        }
2575
2576        // if the duration is different for this sample, see if it is close enough to the previous
2577        // duration that we can fudge it and use the same value, to avoid filling the stts table
2578        // with lots of near-identical entries.
2579        // "close enough" here means that the current duration needs to be adjusted by less
2580        // than 0.1 milliseconds
2581        if (lastDurationTicks && (currDurationTicks != lastDurationTicks)) {
2582            int64_t deltaUs = ((lastDurationTicks - currDurationTicks) * 1000000LL
2583                    + (mTimeScale / 2)) / mTimeScale;
2584            if (deltaUs > -100 && deltaUs < 100) {
2585                // use previous ticks, and adjust timestamp as if it was actually that number
2586                // of ticks
2587                currDurationTicks = lastDurationTicks;
2588                timestampUs += deltaUs;
2589            }
2590        }
2591
2592        mStszTableEntries->add(htonl(sampleSize));
2593        if (mStszTableEntries->count() > 2) {
2594
2595            // Force the first sample to have its own stts entry so that
2596            // we can adjust its value later to maintain the A/V sync.
2597            if (mStszTableEntries->count() == 3 || currDurationTicks != lastDurationTicks) {
2598                addOneSttsTableEntry(sampleCount, lastDurationTicks);
2599                sampleCount = 1;
2600            } else {
2601                ++sampleCount;
2602            }
2603
2604        }
2605        if (mSamplesHaveSameSize) {
2606            if (mStszTableEntries->count() >= 2 && previousSampleSize != sampleSize) {
2607                mSamplesHaveSameSize = false;
2608            }
2609            previousSampleSize = sampleSize;
2610        }
2611        ALOGV("%s timestampUs/lastTimestampUs: %" PRId64 "/%" PRId64,
2612                trackName, timestampUs, lastTimestampUs);
2613        lastDurationUs = timestampUs - lastTimestampUs;
2614        lastDurationTicks = currDurationTicks;
2615        lastTimestampUs = timestampUs;
2616
2617        if (isSync != 0) {
2618            addOneStssTableEntry(mStszTableEntries->count());
2619        }
2620
2621        if (mTrackingProgressStatus) {
2622            if (mPreviousTrackTimeUs <= 0) {
2623                mPreviousTrackTimeUs = mStartTimestampUs;
2624            }
2625            trackProgressStatus(timestampUs);
2626        }
2627        if (!hasMultipleTracks) {
2628            off64_t offset = (mIsAvc || mIsHevc) ? mOwner->addMultipleLengthPrefixedSamples_l(copy)
2629                                 : mOwner->addSample_l(copy);
2630
2631            uint32_t count = (mOwner->use32BitFileOffset()
2632                        ? mStcoTableEntries->count()
2633                        : mCo64TableEntries->count());
2634
2635            if (count == 0) {
2636                addChunkOffset(offset);
2637            }
2638            copy->release();
2639            copy = NULL;
2640            continue;
2641        }
2642
2643        mChunkSamples.push_back(copy);
2644        if (interleaveDurationUs == 0) {
2645            addOneStscTableEntry(++nChunks, 1);
2646            bufferChunk(timestampUs);
2647        } else {
2648            if (chunkTimestampUs == 0) {
2649                chunkTimestampUs = timestampUs;
2650            } else {
2651                int64_t chunkDurationUs = timestampUs - chunkTimestampUs;
2652                if (chunkDurationUs > interleaveDurationUs) {
2653                    if (chunkDurationUs > mMaxChunkDurationUs) {
2654                        mMaxChunkDurationUs = chunkDurationUs;
2655                    }
2656                    ++nChunks;
2657                    if (nChunks == 1 ||  // First chunk
2658                        lastSamplesPerChunk != mChunkSamples.size()) {
2659                        lastSamplesPerChunk = mChunkSamples.size();
2660                        addOneStscTableEntry(nChunks, lastSamplesPerChunk);
2661                    }
2662                    bufferChunk(timestampUs);
2663                    chunkTimestampUs = timestampUs;
2664                }
2665            }
2666        }
2667
2668    }
2669
2670    if (isTrackMalFormed()) {
2671        err = ERROR_MALFORMED;
2672    }
2673
2674    mOwner->trackProgressStatus(mTrackId, -1, err);
2675
2676    // Last chunk
2677    if (!hasMultipleTracks) {
2678        addOneStscTableEntry(1, mStszTableEntries->count());
2679    } else if (!mChunkSamples.empty()) {
2680        addOneStscTableEntry(++nChunks, mChunkSamples.size());
2681        bufferChunk(timestampUs);
2682    }
2683
2684    // We don't really know how long the last frame lasts, since
2685    // there is no frame time after it, just repeat the previous
2686    // frame's duration.
2687    if (mStszTableEntries->count() == 1) {
2688        lastDurationUs = 0;  // A single sample's duration
2689        lastDurationTicks = 0;
2690    } else {
2691        ++sampleCount;  // Count for the last sample
2692    }
2693
2694    if (mStszTableEntries->count() <= 2) {
2695        addOneSttsTableEntry(1, lastDurationTicks);
2696        if (sampleCount - 1 > 0) {
2697            addOneSttsTableEntry(sampleCount - 1, lastDurationTicks);
2698        }
2699    } else {
2700        addOneSttsTableEntry(sampleCount, lastDurationTicks);
2701    }
2702
2703    // The last ctts box may not have been written yet, and this
2704    // is to make sure that we write out the last ctts box.
2705    if (currCttsOffsetTimeTicks == lastCttsOffsetTimeTicks) {
2706        if (cttsSampleCount > 0) {
2707            addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
2708        }
2709    }
2710
2711    mTrackDurationUs += lastDurationUs;
2712    mReachedEOS = true;
2713
2714    sendTrackSummary(hasMultipleTracks);
2715
2716    ALOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s",
2717            count, nZeroLengthFrames, mStszTableEntries->count(), trackName);
2718    if (mIsAudio) {
2719        ALOGI("Audio track drift time: %" PRId64 " us", mOwner->getDriftTimeUs());
2720    }
2721
2722    if (err == ERROR_END_OF_STREAM) {
2723        return OK;
2724    }
2725    return err;
2726}
2727
2728bool MPEG4Writer::Track::isTrackMalFormed() const {
2729    if (mStszTableEntries->count() == 0) {                      // no samples written
2730        ALOGE("The number of recorded samples is 0");
2731        return true;
2732    }
2733
2734    if (!mIsAudio && mStssTableEntries->count() == 0) {  // no sync frames for video
2735        ALOGE("There are no sync frames for video track");
2736        return true;
2737    }
2738
2739    if (OK != checkCodecSpecificData()) {         // no codec specific data
2740        return true;
2741    }
2742
2743    return false;
2744}
2745
2746void MPEG4Writer::Track::sendTrackSummary(bool hasMultipleTracks) {
2747
2748    // Send track summary only if test mode is enabled.
2749    if (!isTestModeEnabled()) {
2750        return;
2751    }
2752
2753    int trackNum = (mTrackId << 28);
2754
2755    mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
2756                    trackNum | MEDIA_RECORDER_TRACK_INFO_TYPE,
2757                    mIsAudio? 0: 1);
2758
2759    mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
2760                    trackNum | MEDIA_RECORDER_TRACK_INFO_DURATION_MS,
2761                    mTrackDurationUs / 1000);
2762
2763    mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
2764                    trackNum | MEDIA_RECORDER_TRACK_INFO_ENCODED_FRAMES,
2765                    mStszTableEntries->count());
2766
2767    {
2768        // The system delay time excluding the requested initial delay that
2769        // is used to eliminate the recording sound.
2770        int64_t startTimeOffsetUs = mOwner->getStartTimeOffsetMs() * 1000LL;
2771        if (startTimeOffsetUs < 0) {  // Start time offset was not set
2772            startTimeOffsetUs = kInitialDelayTimeUs;
2773        }
2774        int64_t initialDelayUs =
2775            mFirstSampleTimeRealUs - mStartTimeRealUs - startTimeOffsetUs;
2776
2777        mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
2778                    trackNum | MEDIA_RECORDER_TRACK_INFO_INITIAL_DELAY_MS,
2779                    (initialDelayUs) / 1000);
2780    }
2781
2782    mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
2783                    trackNum | MEDIA_RECORDER_TRACK_INFO_DATA_KBYTES,
2784                    mMdatSizeBytes / 1024);
2785
2786    if (hasMultipleTracks) {
2787        mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
2788                    trackNum | MEDIA_RECORDER_TRACK_INFO_MAX_CHUNK_DUR_MS,
2789                    mMaxChunkDurationUs / 1000);
2790
2791        int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
2792        if (mStartTimestampUs != moovStartTimeUs) {
2793            int64_t startTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
2794            mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
2795                    trackNum | MEDIA_RECORDER_TRACK_INFO_START_OFFSET_MS,
2796                    startTimeOffsetUs / 1000);
2797        }
2798    }
2799}
2800
2801void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) {
2802    ALOGV("trackProgressStatus: %" PRId64 " us", timeUs);
2803
2804    if (mTrackEveryTimeDurationUs > 0 &&
2805        timeUs - mPreviousTrackTimeUs >= mTrackEveryTimeDurationUs) {
2806        ALOGV("Fire time tracking progress status at %" PRId64 " us", timeUs);
2807        mOwner->trackProgressStatus(mTrackId, timeUs - mPreviousTrackTimeUs, err);
2808        mPreviousTrackTimeUs = timeUs;
2809    }
2810}
2811
2812void MPEG4Writer::trackProgressStatus(
2813        size_t trackId, int64_t timeUs, status_t err) {
2814    Mutex::Autolock lock(mLock);
2815    int32_t trackNum = (trackId << 28);
2816
2817    // Error notification
2818    // Do not consider ERROR_END_OF_STREAM an error
2819    if (err != OK && err != ERROR_END_OF_STREAM) {
2820        notify(MEDIA_RECORDER_TRACK_EVENT_ERROR,
2821               trackNum | MEDIA_RECORDER_TRACK_ERROR_GENERAL,
2822               err);
2823        return;
2824    }
2825
2826    if (timeUs == -1) {
2827        // Send completion notification
2828        notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
2829               trackNum | MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS,
2830               err);
2831    } else {
2832        // Send progress status
2833        notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
2834               trackNum | MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME,
2835               timeUs / 1000);
2836    }
2837}
2838
2839void MPEG4Writer::setDriftTimeUs(int64_t driftTimeUs) {
2840    ALOGV("setDriftTimeUs: %" PRId64 " us", driftTimeUs);
2841    Mutex::Autolock autolock(mLock);
2842    mDriftTimeUs = driftTimeUs;
2843}
2844
2845int64_t MPEG4Writer::getDriftTimeUs() {
2846    ALOGV("getDriftTimeUs: %" PRId64 " us", mDriftTimeUs);
2847    Mutex::Autolock autolock(mLock);
2848    return mDriftTimeUs;
2849}
2850
2851bool MPEG4Writer::isRealTimeRecording() const {
2852    return mIsRealTimeRecording;
2853}
2854
2855bool MPEG4Writer::useNalLengthFour() {
2856    return mUse4ByteNalLength;
2857}
2858
2859void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) {
2860    ALOGV("bufferChunk");
2861
2862    Chunk chunk(this, timestampUs, mChunkSamples);
2863    mOwner->bufferChunk(chunk);
2864    mChunkSamples.clear();
2865}
2866
2867int64_t MPEG4Writer::Track::getDurationUs() const {
2868    return mTrackDurationUs;
2869}
2870
2871int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const {
2872    return mEstimatedTrackSizeBytes;
2873}
2874
2875status_t MPEG4Writer::Track::checkCodecSpecificData() const {
2876    const char *mime;
2877    CHECK(mMeta->findCString(kKeyMIMEType, &mime));
2878    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime) ||
2879        !strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime) ||
2880        !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime) ||
2881        !strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) {
2882        if (!mCodecSpecificData ||
2883            mCodecSpecificDataSize <= 0) {
2884            ALOGE("Missing codec specific data");
2885            return ERROR_MALFORMED;
2886        }
2887    } else {
2888        if (mCodecSpecificData ||
2889            mCodecSpecificDataSize > 0) {
2890            ALOGE("Unexepected codec specific data found");
2891            return ERROR_MALFORMED;
2892        }
2893    }
2894    return OK;
2895}
2896
2897void MPEG4Writer::Track::writeTrackHeader(bool use32BitOffset) {
2898
2899    ALOGV("%s track time scale: %d",
2900        mIsAudio? "Audio": "Video", mTimeScale);
2901
2902    uint32_t now = getMpeg4Time();
2903    mOwner->beginBox("trak");
2904        writeTkhdBox(now);
2905        mOwner->beginBox("mdia");
2906            writeMdhdBox(now);
2907            writeHdlrBox();
2908            mOwner->beginBox("minf");
2909                if (mIsAudio) {
2910                    writeSmhdBox();
2911                } else {
2912                    writeVmhdBox();
2913                }
2914                writeDinfBox();
2915                writeStblBox(use32BitOffset);
2916            mOwner->endBox();  // minf
2917        mOwner->endBox();  // mdia
2918    mOwner->endBox();  // trak
2919}
2920
2921void MPEG4Writer::Track::writeStblBox(bool use32BitOffset) {
2922    mOwner->beginBox("stbl");
2923    mOwner->beginBox("stsd");
2924    mOwner->writeInt32(0);               // version=0, flags=0
2925    mOwner->writeInt32(1);               // entry count
2926    if (mIsAudio) {
2927        writeAudioFourCCBox();
2928    } else {
2929        writeVideoFourCCBox();
2930    }
2931    mOwner->endBox();  // stsd
2932    writeSttsBox();
2933    writeCttsBox();
2934    if (!mIsAudio) {
2935        writeStssBox();
2936    }
2937    writeStszBox();
2938    writeStscBox();
2939    writeStcoBox(use32BitOffset);
2940    mOwner->endBox();  // stbl
2941}
2942
2943void MPEG4Writer::Track::writeVideoFourCCBox() {
2944    const char *mime;
2945    bool success = mMeta->findCString(kKeyMIMEType, &mime);
2946    CHECK(success);
2947    const char *fourcc = getFourCCForMime(mime);
2948    if (fourcc == NULL) {
2949        ALOGE("Unknown mime type '%s'.", mime);
2950        CHECK(!"should not be here, unknown mime type.");
2951    }
2952
2953    mOwner->beginBox(fourcc);        // video format
2954    mOwner->writeInt32(0);           // reserved
2955    mOwner->writeInt16(0);           // reserved
2956    mOwner->writeInt16(1);           // data ref index
2957    mOwner->writeInt16(0);           // predefined
2958    mOwner->writeInt16(0);           // reserved
2959    mOwner->writeInt32(0);           // predefined
2960    mOwner->writeInt32(0);           // predefined
2961    mOwner->writeInt32(0);           // predefined
2962
2963    int32_t width, height;
2964    success = mMeta->findInt32(kKeyWidth, &width);
2965    success = success && mMeta->findInt32(kKeyHeight, &height);
2966    CHECK(success);
2967
2968    mOwner->writeInt16(width);
2969    mOwner->writeInt16(height);
2970    mOwner->writeInt32(0x480000);    // horiz resolution
2971    mOwner->writeInt32(0x480000);    // vert resolution
2972    mOwner->writeInt32(0);           // reserved
2973    mOwner->writeInt16(1);           // frame count
2974    mOwner->writeInt8(0);            // compressor string length
2975    mOwner->write("                               ", 31);
2976    mOwner->writeInt16(0x18);        // depth
2977    mOwner->writeInt16(-1);          // predefined
2978
2979    CHECK_LT(23 + mCodecSpecificDataSize, 128);
2980
2981    if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
2982        writeMp4vEsdsBox();
2983    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
2984        writeD263Box();
2985    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
2986        writeAvccBox();
2987    } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) {
2988        writeHvccBox();
2989    }
2990
2991    writePaspBox();
2992    writeColrBox();
2993    mOwner->endBox();  // mp4v, s263 or avc1
2994}
2995
2996void MPEG4Writer::Track::writeColrBox() {
2997    ColorAspects aspects;
2998    memset(&aspects, 0, sizeof(aspects));
2999    // TRICKY: using | instead of || because we want to execute all findInt32-s
3000    if (mMeta->findInt32(kKeyColorPrimaries, (int32_t*)&aspects.mPrimaries)
3001            | mMeta->findInt32(kKeyTransferFunction, (int32_t*)&aspects.mTransfer)
3002            | mMeta->findInt32(kKeyColorMatrix, (int32_t*)&aspects.mMatrixCoeffs)
3003            | mMeta->findInt32(kKeyColorRange, (int32_t*)&aspects.mRange)) {
3004        int32_t primaries, transfer, coeffs;
3005        bool fullRange;
3006        ColorUtils::convertCodecColorAspectsToIsoAspects(
3007                aspects, &primaries, &transfer, &coeffs, &fullRange);
3008        mOwner->beginBox("colr");
3009        mOwner->writeFourcc("nclx");
3010        mOwner->writeInt16(primaries);
3011        mOwner->writeInt16(transfer);
3012        mOwner->writeInt16(coeffs);
3013        mOwner->writeInt8(fullRange ? 128 : 0);
3014        mOwner->endBox(); // colr
3015    }
3016}
3017
3018void MPEG4Writer::Track::writeAudioFourCCBox() {
3019    const char *mime;
3020    bool success = mMeta->findCString(kKeyMIMEType, &mime);
3021    CHECK(success);
3022    const char *fourcc = getFourCCForMime(mime);
3023    if (fourcc == NULL) {
3024        ALOGE("Unknown mime type '%s'.", mime);
3025        CHECK(!"should not be here, unknown mime type.");
3026    }
3027
3028    mOwner->beginBox(fourcc);        // audio format
3029    mOwner->writeInt32(0);           // reserved
3030    mOwner->writeInt16(0);           // reserved
3031    mOwner->writeInt16(0x1);         // data ref index
3032    mOwner->writeInt32(0);           // reserved
3033    mOwner->writeInt32(0);           // reserved
3034    int32_t nChannels;
3035    CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels));
3036    mOwner->writeInt16(nChannels);   // channel count
3037    mOwner->writeInt16(16);          // sample size
3038    mOwner->writeInt16(0);           // predefined
3039    mOwner->writeInt16(0);           // reserved
3040
3041    int32_t samplerate;
3042    success = mMeta->findInt32(kKeySampleRate, &samplerate);
3043    CHECK(success);
3044    mOwner->writeInt32(samplerate << 16);
3045    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
3046        writeMp4aEsdsBox();
3047    } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime) ||
3048               !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
3049        writeDamrBox();
3050    }
3051    mOwner->endBox();
3052}
3053
3054void MPEG4Writer::Track::writeMp4aEsdsBox() {
3055    mOwner->beginBox("esds");
3056    CHECK(mCodecSpecificData);
3057    CHECK_GT(mCodecSpecificDataSize, 0);
3058
3059    // Make sure all sizes encode to a single byte.
3060    CHECK_LT(mCodecSpecificDataSize + 23, 128);
3061
3062    mOwner->writeInt32(0);     // version=0, flags=0
3063    mOwner->writeInt8(0x03);   // ES_DescrTag
3064    mOwner->writeInt8(23 + mCodecSpecificDataSize);
3065    mOwner->writeInt16(0x0000);// ES_ID
3066    mOwner->writeInt8(0x00);
3067
3068    mOwner->writeInt8(0x04);   // DecoderConfigDescrTag
3069    mOwner->writeInt8(15 + mCodecSpecificDataSize);
3070    mOwner->writeInt8(0x40);   // objectTypeIndication ISO/IEC 14492-2
3071    mOwner->writeInt8(0x15);   // streamType AudioStream
3072
3073    mOwner->writeInt16(0x03);  // XXX
3074    mOwner->writeInt8(0x00);   // buffer size 24-bit (0x300)
3075
3076    int32_t avgBitrate = 0;
3077    (void)mMeta->findInt32(kKeyBitRate, &avgBitrate);
3078    int32_t maxBitrate = 0;
3079    (void)mMeta->findInt32(kKeyMaxBitRate, &maxBitrate);
3080    mOwner->writeInt32(maxBitrate);
3081    mOwner->writeInt32(avgBitrate);
3082
3083    mOwner->writeInt8(0x05);   // DecoderSpecificInfoTag
3084    mOwner->writeInt8(mCodecSpecificDataSize);
3085    mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
3086
3087    static const uint8_t kData2[] = {
3088        0x06,  // SLConfigDescriptorTag
3089        0x01,
3090        0x02
3091    };
3092    mOwner->write(kData2, sizeof(kData2));
3093
3094    mOwner->endBox();  // esds
3095}
3096
3097void MPEG4Writer::Track::writeMp4vEsdsBox() {
3098    CHECK(mCodecSpecificData);
3099    CHECK_GT(mCodecSpecificDataSize, 0);
3100    mOwner->beginBox("esds");
3101
3102    mOwner->writeInt32(0);    // version=0, flags=0
3103
3104    mOwner->writeInt8(0x03);  // ES_DescrTag
3105    mOwner->writeInt8(23 + mCodecSpecificDataSize);
3106    mOwner->writeInt16(0x0000);  // ES_ID
3107    mOwner->writeInt8(0x1f);
3108
3109    mOwner->writeInt8(0x04);  // DecoderConfigDescrTag
3110    mOwner->writeInt8(15 + mCodecSpecificDataSize);
3111    mOwner->writeInt8(0x20);  // objectTypeIndication ISO/IEC 14492-2
3112    mOwner->writeInt8(0x11);  // streamType VisualStream
3113
3114    static const uint8_t kData[] = {
3115        0x01, 0x77, 0x00, // buffer size 96000 bytes
3116    };
3117    mOwner->write(kData, sizeof(kData));
3118
3119    int32_t avgBitrate = 0;
3120    (void)mMeta->findInt32(kKeyBitRate, &avgBitrate);
3121    int32_t maxBitrate = 0;
3122    (void)mMeta->findInt32(kKeyMaxBitRate, &maxBitrate);
3123    mOwner->writeInt32(maxBitrate);
3124    mOwner->writeInt32(avgBitrate);
3125
3126    mOwner->writeInt8(0x05);  // DecoderSpecificInfoTag
3127
3128    mOwner->writeInt8(mCodecSpecificDataSize);
3129    mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
3130
3131    static const uint8_t kData2[] = {
3132        0x06,  // SLConfigDescriptorTag
3133        0x01,
3134        0x02
3135    };
3136    mOwner->write(kData2, sizeof(kData2));
3137
3138    mOwner->endBox();  // esds
3139}
3140
3141void MPEG4Writer::Track::writeTkhdBox(uint32_t now) {
3142    mOwner->beginBox("tkhd");
3143    // Flags = 7 to indicate that the track is enabled, and
3144    // part of the presentation
3145    mOwner->writeInt32(0x07);          // version=0, flags=7
3146    mOwner->writeInt32(now);           // creation time
3147    mOwner->writeInt32(now);           // modification time
3148    mOwner->writeInt32(mTrackId);      // track id starts with 1
3149    mOwner->writeInt32(0);             // reserved
3150    int64_t trakDurationUs = getDurationUs();
3151    int32_t mvhdTimeScale = mOwner->getTimeScale();
3152    int32_t tkhdDuration =
3153        (trakDurationUs * mvhdTimeScale + 5E5) / 1E6;
3154    mOwner->writeInt32(tkhdDuration);  // in mvhd timescale
3155    mOwner->writeInt32(0);             // reserved
3156    mOwner->writeInt32(0);             // reserved
3157    mOwner->writeInt16(0);             // layer
3158    mOwner->writeInt16(0);             // alternate group
3159    mOwner->writeInt16(mIsAudio ? 0x100 : 0);  // volume
3160    mOwner->writeInt16(0);             // reserved
3161
3162    mOwner->writeCompositionMatrix(mRotation);       // matrix
3163
3164    if (mIsAudio) {
3165        mOwner->writeInt32(0);
3166        mOwner->writeInt32(0);
3167    } else {
3168        int32_t width, height;
3169        bool success = mMeta->findInt32(kKeyWidth, &width);
3170        success = success && mMeta->findInt32(kKeyHeight, &height);
3171        CHECK(success);
3172
3173        mOwner->writeInt32(width << 16);   // 32-bit fixed-point value
3174        mOwner->writeInt32(height << 16);  // 32-bit fixed-point value
3175    }
3176    mOwner->endBox();  // tkhd
3177}
3178
3179void MPEG4Writer::Track::writeVmhdBox() {
3180    mOwner->beginBox("vmhd");
3181    mOwner->writeInt32(0x01);        // version=0, flags=1
3182    mOwner->writeInt16(0);           // graphics mode
3183    mOwner->writeInt16(0);           // opcolor
3184    mOwner->writeInt16(0);
3185    mOwner->writeInt16(0);
3186    mOwner->endBox();
3187}
3188
3189void MPEG4Writer::Track::writeSmhdBox() {
3190    mOwner->beginBox("smhd");
3191    mOwner->writeInt32(0);           // version=0, flags=0
3192    mOwner->writeInt16(0);           // balance
3193    mOwner->writeInt16(0);           // reserved
3194    mOwner->endBox();
3195}
3196
3197void MPEG4Writer::Track::writeHdlrBox() {
3198    mOwner->beginBox("hdlr");
3199    mOwner->writeInt32(0);             // version=0, flags=0
3200    mOwner->writeInt32(0);             // component type: should be mhlr
3201    mOwner->writeFourcc(mIsAudio ? "soun" : "vide");  // component subtype
3202    mOwner->writeInt32(0);             // reserved
3203    mOwner->writeInt32(0);             // reserved
3204    mOwner->writeInt32(0);             // reserved
3205    // Removing "r" for the name string just makes the string 4 byte aligned
3206    mOwner->writeCString(mIsAudio ? "SoundHandle": "VideoHandle");  // name
3207    mOwner->endBox();
3208}
3209
3210void MPEG4Writer::Track::writeMdhdBox(uint32_t now) {
3211    int64_t trakDurationUs = getDurationUs();
3212    mOwner->beginBox("mdhd");
3213    mOwner->writeInt32(0);             // version=0, flags=0
3214    mOwner->writeInt32(now);           // creation time
3215    mOwner->writeInt32(now);           // modification time
3216    mOwner->writeInt32(mTimeScale);    // media timescale
3217    int32_t mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6;
3218    mOwner->writeInt32(mdhdDuration);  // use media timescale
3219    // Language follows the three letter standard ISO-639-2/T
3220    // 'e', 'n', 'g' for "English", for instance.
3221    // Each character is packed as the difference between its ASCII value and 0x60.
3222    // For "English", these are 00101, 01110, 00111.
3223    // XXX: Where is the padding bit located: 0x15C7?
3224    mOwner->writeInt16(0);             // language code
3225    mOwner->writeInt16(0);             // predefined
3226    mOwner->endBox();
3227}
3228
3229void MPEG4Writer::Track::writeDamrBox() {
3230    // 3gpp2 Spec AMRSampleEntry fields
3231    mOwner->beginBox("damr");
3232    mOwner->writeCString("   ");  // vendor: 4 bytes
3233    mOwner->writeInt8(0);         // decoder version
3234    mOwner->writeInt16(0x83FF);   // mode set: all enabled
3235    mOwner->writeInt8(0);         // mode change period
3236    mOwner->writeInt8(1);         // frames per sample
3237    mOwner->endBox();
3238}
3239
3240void MPEG4Writer::Track::writeUrlBox() {
3241    // The table index here refers to the sample description index
3242    // in the sample table entries.
3243    mOwner->beginBox("url ");
3244    mOwner->writeInt32(1);  // version=0, flags=1 (self-contained)
3245    mOwner->endBox();  // url
3246}
3247
3248void MPEG4Writer::Track::writeDrefBox() {
3249    mOwner->beginBox("dref");
3250    mOwner->writeInt32(0);  // version=0, flags=0
3251    mOwner->writeInt32(1);  // entry count (either url or urn)
3252    writeUrlBox();
3253    mOwner->endBox();  // dref
3254}
3255
3256void MPEG4Writer::Track::writeDinfBox() {
3257    mOwner->beginBox("dinf");
3258    writeDrefBox();
3259    mOwner->endBox();  // dinf
3260}
3261
3262void MPEG4Writer::Track::writeAvccBox() {
3263    CHECK(mCodecSpecificData);
3264    CHECK_GE(mCodecSpecificDataSize, 5);
3265
3266    // Patch avcc's lengthSize field to match the number
3267    // of bytes we use to indicate the size of a nal unit.
3268    uint8_t *ptr = (uint8_t *)mCodecSpecificData;
3269    ptr[4] = (ptr[4] & 0xfc) | (mOwner->useNalLengthFour() ? 3 : 1);
3270    mOwner->beginBox("avcC");
3271    mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
3272    mOwner->endBox();  // avcC
3273}
3274
3275
3276void MPEG4Writer::Track::writeHvccBox() {
3277    CHECK(mCodecSpecificData);
3278    CHECK_GE(mCodecSpecificDataSize, 5);
3279
3280    // Patch avcc's lengthSize field to match the number
3281    // of bytes we use to indicate the size of a nal unit.
3282    uint8_t *ptr = (uint8_t *)mCodecSpecificData;
3283    ptr[21] = (ptr[21] & 0xfc) | (mOwner->useNalLengthFour() ? 3 : 1);
3284    mOwner->beginBox("hvcC");
3285    mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
3286    mOwner->endBox();  // hvcC
3287}
3288
3289void MPEG4Writer::Track::writeD263Box() {
3290    mOwner->beginBox("d263");
3291    mOwner->writeInt32(0);  // vendor
3292    mOwner->writeInt8(0);   // decoder version
3293    mOwner->writeInt8(10);  // level: 10
3294    mOwner->writeInt8(0);   // profile: 0
3295    mOwner->endBox();  // d263
3296}
3297
3298// This is useful if the pixel is not square
3299void MPEG4Writer::Track::writePaspBox() {
3300    mOwner->beginBox("pasp");
3301    mOwner->writeInt32(1 << 16);  // hspacing
3302    mOwner->writeInt32(1 << 16);  // vspacing
3303    mOwner->endBox();  // pasp
3304}
3305
3306int32_t MPEG4Writer::Track::getStartTimeOffsetScaledTime() const {
3307    int64_t trackStartTimeOffsetUs = 0;
3308    int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
3309    if (mStartTimestampUs != moovStartTimeUs) {
3310        CHECK_GT(mStartTimestampUs, moovStartTimeUs);
3311        trackStartTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
3312    }
3313    return (trackStartTimeOffsetUs *  mTimeScale + 500000LL) / 1000000LL;
3314}
3315
3316void MPEG4Writer::Track::writeSttsBox() {
3317    mOwner->beginBox("stts");
3318    mOwner->writeInt32(0);  // version=0, flags=0
3319    uint32_t duration;
3320    CHECK(mSttsTableEntries->get(duration, 1));
3321    duration = htonl(duration);  // Back to host byte order
3322    mSttsTableEntries->set(htonl(duration + getStartTimeOffsetScaledTime()), 1);
3323    mSttsTableEntries->write(mOwner);
3324    mOwner->endBox();  // stts
3325}
3326
3327void MPEG4Writer::Track::writeCttsBox() {
3328    if (mIsAudio) {  // ctts is not for audio
3329        return;
3330    }
3331
3332    // There is no B frame at all
3333    if (mMinCttsOffsetTimeUs == mMaxCttsOffsetTimeUs) {
3334        return;
3335    }
3336
3337    // Do not write ctts box when there is no need to have it.
3338    if (mCttsTableEntries->count() == 0) {
3339        return;
3340    }
3341
3342    ALOGV("ctts box has %d entries with range [%" PRId64 ", %" PRId64 "]",
3343            mCttsTableEntries->count(), mMinCttsOffsetTimeUs, mMaxCttsOffsetTimeUs);
3344
3345    mOwner->beginBox("ctts");
3346    mOwner->writeInt32(0);  // version=0, flags=0
3347    uint32_t duration;
3348    CHECK(mCttsTableEntries->get(duration, 1));
3349    duration = htonl(duration);  // Back host byte order
3350    mCttsTableEntries->set(htonl(duration + getStartTimeOffsetScaledTime() - mMinCttsOffsetTimeUs), 1);
3351    mCttsTableEntries->write(mOwner);
3352    mOwner->endBox();  // ctts
3353}
3354
3355void MPEG4Writer::Track::writeStssBox() {
3356    mOwner->beginBox("stss");
3357    mOwner->writeInt32(0);  // version=0, flags=0
3358    mStssTableEntries->write(mOwner);
3359    mOwner->endBox();  // stss
3360}
3361
3362void MPEG4Writer::Track::writeStszBox() {
3363    mOwner->beginBox("stsz");
3364    mOwner->writeInt32(0);  // version=0, flags=0
3365    mOwner->writeInt32(0);
3366    mStszTableEntries->write(mOwner);
3367    mOwner->endBox();  // stsz
3368}
3369
3370void MPEG4Writer::Track::writeStscBox() {
3371    mOwner->beginBox("stsc");
3372    mOwner->writeInt32(0);  // version=0, flags=0
3373    mStscTableEntries->write(mOwner);
3374    mOwner->endBox();  // stsc
3375}
3376
3377void MPEG4Writer::Track::writeStcoBox(bool use32BitOffset) {
3378    mOwner->beginBox(use32BitOffset? "stco": "co64");
3379    mOwner->writeInt32(0);  // version=0, flags=0
3380    if (use32BitOffset) {
3381        mStcoTableEntries->write(mOwner);
3382    } else {
3383        mCo64TableEntries->write(mOwner);
3384    }
3385    mOwner->endBox();  // stco or co64
3386}
3387
3388void MPEG4Writer::writeUdtaBox() {
3389    beginBox("udta");
3390    writeGeoDataBox();
3391    endBox();
3392}
3393
3394void MPEG4Writer::writeHdlr() {
3395    beginBox("hdlr");
3396    writeInt32(0); // Version, Flags
3397    writeInt32(0); // Predefined
3398    writeFourcc("mdta");
3399    writeInt32(0); // Reserved[0]
3400    writeInt32(0); // Reserved[1]
3401    writeInt32(0); // Reserved[2]
3402    writeInt8(0);  // Name (empty)
3403    endBox();
3404}
3405
3406void MPEG4Writer::writeKeys() {
3407    size_t count = mMetaKeys->countEntries();
3408
3409    beginBox("keys");
3410    writeInt32(0);     // Version, Flags
3411    writeInt32(count); // Entry_count
3412    for (size_t i = 0; i < count; i++) {
3413        AMessage::Type type;
3414        const char *key = mMetaKeys->getEntryNameAt(i, &type);
3415        size_t n = strlen(key);
3416        writeInt32(n + 8);
3417        writeFourcc("mdta");
3418        write(key, n); // write without the \0
3419    }
3420    endBox();
3421}
3422
3423void MPEG4Writer::writeIlst() {
3424    size_t count = mMetaKeys->countEntries();
3425
3426    beginBox("ilst");
3427    for (size_t i = 0; i < count; i++) {
3428        beginBox(i + 1); // key id (1-based)
3429        beginBox("data");
3430        AMessage::Type type;
3431        const char *key = mMetaKeys->getEntryNameAt(i, &type);
3432        switch (type) {
3433            case AMessage::kTypeString:
3434            {
3435                AString val;
3436                CHECK(mMetaKeys->findString(key, &val));
3437                writeInt32(1); // type = UTF8
3438                writeInt32(0); // default country/language
3439                write(val.c_str(), strlen(val.c_str())); // write without \0
3440                break;
3441            }
3442
3443            case AMessage::kTypeFloat:
3444            {
3445                float val;
3446                CHECK(mMetaKeys->findFloat(key, &val));
3447                writeInt32(23); // type = float32
3448                writeInt32(0);  // default country/language
3449                writeInt32(*reinterpret_cast<int32_t *>(&val));
3450                break;
3451            }
3452
3453            case AMessage::kTypeInt32:
3454            {
3455                int32_t val;
3456                CHECK(mMetaKeys->findInt32(key, &val));
3457                writeInt32(67); // type = signed int32
3458                writeInt32(0);  // default country/language
3459                writeInt32(val);
3460                break;
3461            }
3462
3463            default:
3464            {
3465                ALOGW("Unsupported key type, writing 0 instead");
3466                writeInt32(77); // type = unsigned int32
3467                writeInt32(0);  // default country/language
3468                writeInt32(0);
3469                break;
3470            }
3471        }
3472        endBox(); // data
3473        endBox(); // key id
3474    }
3475    endBox(); // ilst
3476}
3477
3478void MPEG4Writer::writeMetaBox() {
3479    size_t count = mMetaKeys->countEntries();
3480    if (count == 0) {
3481        return;
3482    }
3483
3484    beginBox("meta");
3485    writeHdlr();
3486    writeKeys();
3487    writeIlst();
3488    endBox();
3489}
3490
3491/*
3492 * Geodata is stored according to ISO-6709 standard.
3493 */
3494void MPEG4Writer::writeGeoDataBox() {
3495    beginBox("\xA9xyz");
3496    /*
3497     * For historical reasons, any user data start
3498     * with "\0xA9", must be followed by its assoicated
3499     * language code.
3500     * 0x0012: text string length
3501     * 0x15c7: lang (locale) code: en
3502     */
3503    writeInt32(0x001215c7);
3504    writeLatitude(mLatitudex10000);
3505    writeLongitude(mLongitudex10000);
3506    writeInt8(0x2F);
3507    endBox();
3508}
3509
3510}  // namespace android
3511