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