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