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