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