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