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