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