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