MPEG4Writer.cpp revision 13f6284305e4b27395a23db7882d670bdb1bcae1
1/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "MPEG4Writer"
19#include <utils/Log.h>
20
21#include <arpa/inet.h>
22
23#include <pthread.h>
24#include <sys/prctl.h>
25#include <sys/resource.h>
26
27#include <media/stagefright/MPEG4Writer.h>
28#include <media/stagefright/MediaBuffer.h>
29#include <media/stagefright/MetaData.h>
30#include <media/stagefright/MediaDebug.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
37#include "include/ESDS.h"
38
39namespace android {
40
41static const int64_t kMax32BitFileSize = 0x007fffffffLL;
42static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
43static const uint8_t kNalUnitTypePicParamSet = 0x08;
44
45// Using longer adjustment period to suppress fluctuations in
46// the audio encoding paths
47static const int64_t kVideoMediaTimeAdjustPeriodTimeUs = 600000000LL;  // 10 minutes
48
49class MPEG4Writer::Track {
50public:
51    Track(MPEG4Writer *owner, const sp<MediaSource> &source);
52
53    ~Track();
54
55    status_t start(MetaData *params);
56    status_t stop();
57    status_t pause();
58    bool reachedEOS();
59
60    int64_t getDurationUs() const;
61    int64_t getEstimatedTrackSizeBytes() const;
62    void writeTrackHeader(int32_t trackID, bool use32BitOffset = true);
63    void bufferChunk(int64_t timestampUs);
64    bool isAvc() const { return mIsAvc; }
65    bool isAudio() const { return mIsAudio; }
66    bool isMPEG4() const { return mIsMPEG4; }
67    void addChunkOffset(off_t offset);
68    status_t dump(int fd, const Vector<String16>& args) const;
69
70private:
71    MPEG4Writer *mOwner;
72    sp<MetaData> mMeta;
73    sp<MediaSource> mSource;
74    volatile bool mDone;
75    volatile bool mPaused;
76    volatile bool mResumed;
77    bool mIsAvc;
78    bool mIsAudio;
79    bool mIsMPEG4;
80    int64_t mTrackDurationUs;
81
82    // For realtime applications, we need to adjust the media clock
83    // for video track based on the audio media clock
84    bool mIsRealTimeRecording;
85    int64_t mMaxTimeStampUs;
86    int64_t mEstimatedTrackSizeBytes;
87    int64_t mMdatSizeBytes;
88    int32_t mTimeScale;
89
90    pthread_t mThread;
91
92    // mNumSamples is used to track how many samples in mSampleSizes List.
93    // This is to reduce the cost associated with mSampleSizes.size() call,
94    // since it is O(n). Ideally, the fix should be in List class.
95    size_t              mNumSamples;
96    List<size_t>        mSampleSizes;
97    bool                mSamplesHaveSameSize;
98
99    List<MediaBuffer *> mChunkSamples;
100
101    size_t              mNumStcoTableEntries;
102    List<off_t>         mChunkOffsets;
103
104    size_t              mNumStscTableEntries;
105    struct StscTableEntry {
106
107        StscTableEntry(uint32_t chunk, uint32_t samples, uint32_t id)
108            : firstChunk(chunk),
109              samplesPerChunk(samples),
110              sampleDescriptionId(id) {}
111
112        uint32_t firstChunk;
113        uint32_t samplesPerChunk;
114        uint32_t sampleDescriptionId;
115    };
116    List<StscTableEntry> mStscTableEntries;
117
118    size_t        mNumStssTableEntries;
119    List<int32_t> mStssTableEntries;
120
121    size_t        mNumSttsTableEntries;
122    struct SttsTableEntry {
123
124        SttsTableEntry(uint32_t count, uint32_t durationUs)
125            : sampleCount(count), sampleDurationUs(durationUs) {}
126
127        uint32_t sampleCount;
128        uint32_t sampleDurationUs;
129    };
130    List<SttsTableEntry> mSttsTableEntries;
131
132    // Sequence parameter set or picture parameter set
133    struct AVCParamSet {
134        AVCParamSet(uint16_t length, const uint8_t *data)
135            : mLength(length), mData(data) {}
136
137        uint16_t mLength;
138        const uint8_t *mData;
139    };
140    List<AVCParamSet> mSeqParamSets;
141    List<AVCParamSet> mPicParamSets;
142    uint8_t mProfileIdc;
143    uint8_t mProfileCompatible;
144    uint8_t mLevelIdc;
145
146    void *mCodecSpecificData;
147    size_t mCodecSpecificDataSize;
148    bool mGotAllCodecSpecificData;
149    bool mTrackingProgressStatus;
150
151    bool mReachedEOS;
152    int64_t mStartTimestampUs;
153    int64_t mPreviousTrackTimeUs;
154    int64_t mTrackEveryTimeDurationUs;
155
156    // Has the media time adjustment for video started?
157    bool    mIsMediaTimeAdjustmentOn;
158    // The time stamp when previous media time adjustment period starts
159    int64_t mPrevMediaTimeAdjustTimestampUs;
160    // Number of vidoe frames whose time stamp may be adjusted
161    int64_t mMediaTimeAdjustNumFrames;
162    // The sample number when previous meida time adjustmnet period starts
163    int64_t mPrevMediaTimeAdjustSample;
164    // The total accumulated drift time within a period of
165    // kVideoMediaTimeAdjustPeriodTimeUs.
166    int64_t mTotalDriftTimeToAdjustUs;
167    // The total accumalated drift time since the start of the recording
168    // excluding the current time adjustment period
169    int64_t mPrevTotalAccumDriftTimeUs;
170
171    // Update the audio track's drift information.
172    void updateDriftTime(const sp<MetaData>& meta);
173
174    // Adjust the time stamp of the video track according to
175    // the drift time information from the audio track.
176    void adjustMediaTime(int64_t *timestampUs);
177
178    static void *ThreadWrapper(void *me);
179    status_t threadEntry();
180
181    const uint8_t *parseParamSet(
182        const uint8_t *data, size_t length, int type, size_t *paramSetLen);
183
184    status_t makeAVCCodecSpecificData(
185            const uint8_t *data, size_t size);
186    status_t copyAVCCodecSpecificData(
187            const uint8_t *data, size_t size);
188    status_t parseAVCCodecSpecificData(
189            const uint8_t *data, size_t size);
190
191    // Track authoring progress status
192    void trackProgressStatus(int64_t timeUs, status_t err = OK);
193    void initTrackingProgressStatus(MetaData *params);
194
195    void getCodecSpecificDataFromInputFormatIfPossible();
196
197    // Determine the track time scale
198    // If it is an audio track, try to use the sampling rate as
199    // the time scale; however, if user chooses the overwrite
200    // value, the user-supplied time scale will be used.
201    void setTimeScale();
202
203    // Simple validation on the codec specific data
204    status_t checkCodecSpecificData() const;
205    int32_t mRotation;
206
207    void updateTrackSizeEstimate();
208    void addOneStscTableEntry(size_t chunkId, size_t sampleId);
209    void addOneStssTableEntry(size_t sampleId);
210    void addOneSttsTableEntry(size_t sampleCount, int64_t durationUs);
211
212    Track(const Track &);
213    Track &operator=(const Track &);
214};
215
216MPEG4Writer::MPEG4Writer(const char *filename)
217    : mFile(fopen(filename, "wb")),
218      mUse4ByteNalLength(true),
219      mUse32BitOffset(true),
220      mIsFileSizeLimitExplicitlyRequested(false),
221      mPaused(false),
222      mStarted(false),
223      mOffset(0),
224      mMdatOffset(0),
225      mEstimatedMoovBoxSize(0),
226      mInterleaveDurationUs(1000000) {
227    CHECK(mFile != NULL);
228}
229
230MPEG4Writer::MPEG4Writer(int fd)
231    : mFile(fdopen(fd, "wb")),
232      mUse4ByteNalLength(true),
233      mUse32BitOffset(true),
234      mIsFileSizeLimitExplicitlyRequested(false),
235      mPaused(false),
236      mStarted(false),
237      mOffset(0),
238      mMdatOffset(0),
239      mEstimatedMoovBoxSize(0),
240      mInterleaveDurationUs(1000000) {
241    CHECK(mFile != NULL);
242}
243
244MPEG4Writer::~MPEG4Writer() {
245    stop();
246
247    while (!mTracks.empty()) {
248        List<Track *>::iterator it = mTracks.begin();
249        delete *it;
250        (*it) = NULL;
251        mTracks.erase(it);
252    }
253    mTracks.clear();
254}
255
256status_t MPEG4Writer::dump(
257        int fd, const Vector<String16>& args) {
258    const size_t SIZE = 256;
259    char buffer[SIZE];
260    String8 result;
261    snprintf(buffer, SIZE, "   MPEG4Writer %p\n", this);
262    result.append(buffer);
263    snprintf(buffer, SIZE, "     mStarted: %s\n", mStarted? "true": "false");
264    result.append(buffer);
265    ::write(fd, result.string(), result.size());
266    for (List<Track *>::iterator it = mTracks.begin();
267         it != mTracks.end(); ++it) {
268        (*it)->dump(fd, args);
269    }
270    return OK;
271}
272
273status_t MPEG4Writer::Track::dump(
274        int fd, const Vector<String16>& args) const {
275    const size_t SIZE = 256;
276    char buffer[SIZE];
277    String8 result;
278    snprintf(buffer, SIZE, "     %s track\n", mIsAudio? "Audio": "Video");
279    result.append(buffer);
280    snprintf(buffer, SIZE, "       reached EOS: %s\n",
281            mReachedEOS? "true": "false");
282    result.append(buffer);
283    ::write(fd, result.string(), result.size());
284    return OK;
285}
286
287status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
288    Track *track = new Track(this, source);
289    mTracks.push_back(track);
290
291    return OK;
292}
293
294status_t MPEG4Writer::startTracks(MetaData *params) {
295    for (List<Track *>::iterator it = mTracks.begin();
296         it != mTracks.end(); ++it) {
297        status_t err = (*it)->start(params);
298
299        if (err != OK) {
300            for (List<Track *>::iterator it2 = mTracks.begin();
301                 it2 != it; ++it2) {
302                (*it2)->stop();
303            }
304
305            return err;
306        }
307    }
308    return OK;
309}
310
311int64_t MPEG4Writer::estimateMoovBoxSize(int32_t bitRate) {
312    // This implementation is highly experimental/heurisitic.
313    //
314    // Statistical analysis shows that metadata usually accounts
315    // for a small portion of the total file size, usually < 0.6%.
316
317    // The default MIN_MOOV_BOX_SIZE is set to 0.6% x 1MB / 2,
318    // where 1MB is the common file size limit for MMS application.
319    // The default MAX _MOOV_BOX_SIZE value is based on about 3
320    // minute video recording with a bit rate about 3 Mbps, because
321    // statistics also show that most of the video captured are going
322    // to be less than 3 minutes.
323
324    // If the estimation is wrong, we will pay the price of wasting
325    // some reserved space. This should not happen so often statistically.
326    static const int32_t factor = mUse32BitOffset? 1: 2;
327    static const int64_t MIN_MOOV_BOX_SIZE = 3 * 1024;  // 3 KB
328    static const int64_t MAX_MOOV_BOX_SIZE = (180 * 3000000 * 6LL / 8000);
329    int64_t size = MIN_MOOV_BOX_SIZE;
330
331    // Max file size limit is set
332    if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
333        size = mMaxFileSizeLimitBytes * 6 / 1000;
334    }
335
336    // Max file duration limit is set
337    if (mMaxFileDurationLimitUs != 0) {
338        if (bitRate > 0) {
339            int64_t size2 =
340                ((mMaxFileDurationLimitUs * bitRate * 6) / 1000 / 8000000);
341            if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
342                // When both file size and duration limits are set,
343                // we use the smaller limit of the two.
344                if (size > size2) {
345                    size = size2;
346                }
347            } else {
348                // Only max file duration limit is set
349                size = size2;
350            }
351        }
352    }
353
354    if (size < MIN_MOOV_BOX_SIZE) {
355        size = MIN_MOOV_BOX_SIZE;
356    }
357
358    // Any long duration recording will be probably end up with
359    // non-streamable mp4 file.
360    if (size > MAX_MOOV_BOX_SIZE) {
361        size = MAX_MOOV_BOX_SIZE;
362    }
363
364    LOGI("limits: %lld/%lld bytes/us, bit rate: %d bps and the estimated"
365         " moov size %lld bytes",
366         mMaxFileSizeLimitBytes, mMaxFileDurationLimitUs, bitRate, size);
367    return factor * size;
368}
369
370status_t MPEG4Writer::start(MetaData *param) {
371    if (mFile == NULL) {
372        return UNKNOWN_ERROR;
373    }
374
375    /*
376     * Check mMaxFileSizeLimitBytes at the beginning
377     * since mMaxFileSizeLimitBytes may be implicitly
378     * changed later for 32-bit file offset even if
379     * user does not ask to set it explicitly.
380     */
381    if (mMaxFileSizeLimitBytes != 0) {
382        mIsFileSizeLimitExplicitlyRequested = true;
383    }
384
385    int32_t use64BitOffset;
386    if (param &&
387        param->findInt32(kKey64BitFileOffset, &use64BitOffset) &&
388        use64BitOffset) {
389        mUse32BitOffset = false;
390    }
391
392    if (mUse32BitOffset) {
393        // Implicit 32 bit file size limit
394        if (mMaxFileSizeLimitBytes == 0) {
395            mMaxFileSizeLimitBytes = kMax32BitFileSize;
396        }
397
398        // If file size is set to be larger than the 32 bit file
399        // size limit, treat it as an error.
400        if (mMaxFileSizeLimitBytes > kMax32BitFileSize) {
401            LOGW("32-bit file size limit (%lld bytes) too big. "
402                 "It is changed to %lld bytes",
403                mMaxFileSizeLimitBytes, kMax32BitFileSize);
404            mMaxFileSizeLimitBytes = kMax32BitFileSize;
405        }
406    }
407
408    int32_t use2ByteNalLength;
409    if (param &&
410        param->findInt32(kKey2ByteNalLength, &use2ByteNalLength) &&
411        use2ByteNalLength) {
412        mUse4ByteNalLength = false;
413    }
414
415    mStartTimestampUs = -1;
416
417    if (mStarted) {
418        if (mPaused) {
419            mPaused = false;
420            return startTracks(param);
421        }
422        return OK;
423    }
424
425    if (!param ||
426        !param->findInt32(kKeyTimeScale, &mTimeScale)) {
427        mTimeScale = 1000;
428    }
429    CHECK(mTimeScale > 0);
430    LOGV("movie time scale: %d", mTimeScale);
431
432    mStreamableFile = true;
433    mWriteMoovBoxToMemory = false;
434    mMoovBoxBuffer = NULL;
435    mMoovBoxBufferOffset = 0;
436
437    beginBox("ftyp");
438      {
439        int32_t fileType;
440        if (param && param->findInt32(kKeyFileType, &fileType) &&
441            fileType != OUTPUT_FORMAT_MPEG_4) {
442            writeFourcc("3gp4");
443        } else {
444            writeFourcc("isom");
445        }
446      }
447      writeInt32(0);
448      writeFourcc("isom");
449      writeFourcc("3gp4");
450    endBox();
451
452    mFreeBoxOffset = mOffset;
453
454    if (mEstimatedMoovBoxSize == 0) {
455        int32_t bitRate = -1;
456        if (param) {
457            param->findInt32(kKeyBitRate, &bitRate);
458        }
459        mEstimatedMoovBoxSize = estimateMoovBoxSize(bitRate);
460    }
461    CHECK(mEstimatedMoovBoxSize >= 8);
462    fseeko(mFile, mFreeBoxOffset, SEEK_SET);
463    writeInt32(mEstimatedMoovBoxSize);
464    write("free", 4);
465
466    mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize;
467    mOffset = mMdatOffset;
468    fseeko(mFile, mMdatOffset, SEEK_SET);
469    if (mUse32BitOffset) {
470        write("????mdat", 8);
471    } else {
472        write("\x00\x00\x00\x01mdat????????", 16);
473    }
474
475    status_t err = startWriterThread();
476    if (err != OK) {
477        return err;
478    }
479
480    err = startTracks(param);
481    if (err != OK) {
482        return err;
483    }
484
485    mStarted = true;
486    return OK;
487}
488
489bool MPEG4Writer::use32BitFileOffset() const {
490    return mUse32BitOffset;
491}
492
493status_t MPEG4Writer::pause() {
494    if (mFile == NULL) {
495        return OK;
496    }
497    mPaused = true;
498    status_t err = OK;
499    for (List<Track *>::iterator it = mTracks.begin();
500         it != mTracks.end(); ++it) {
501        status_t status = (*it)->pause();
502        if (status != OK) {
503            err = status;
504        }
505    }
506    return err;
507}
508
509void MPEG4Writer::stopWriterThread() {
510    LOGD("Stopping writer thread");
511
512    {
513        Mutex::Autolock autolock(mLock);
514
515        mDone = true;
516        mChunkReadyCondition.signal();
517    }
518
519    void *dummy;
520    pthread_join(mThread, &dummy);
521    LOGD("Writer thread stopped");
522}
523
524/*
525 * MP4 file standard defines a composition matrix:
526 * | a  b  u |
527 * | c  d  v |
528 * | x  y  w |
529 *
530 * the element in the matrix is stored in the following
531 * order: {a, b, u, c, d, v, x, y, w},
532 * where a, b, c, d, x, and y is in 16.16 format, while
533 * u, v and w is in 2.30 format.
534 */
535void MPEG4Writer::writeCompositionMatrix(int degrees) {
536    LOGV("writeCompositionMatrix");
537    uint32_t a = 0x00010000;
538    uint32_t b = 0;
539    uint32_t c = 0;
540    uint32_t d = 0x00010000;
541    switch (degrees) {
542        case 0:
543            break;
544        case 90:
545            a = 0;
546            b = 0x00010000;
547            c = 0xFFFF0000;
548            d = 0;
549            break;
550        case 180:
551            a = 0xFFFF0000;
552            d = 0xFFFF0000;
553            break;
554        case 270:
555            a = 0;
556            b = 0xFFFF0000;
557            c = 0x00010000;
558            d = 0;
559            break;
560        default:
561            CHECK(!"Should never reach this unknown rotation");
562            break;
563    }
564
565    writeInt32(a);           // a
566    writeInt32(b);           // b
567    writeInt32(0);           // u
568    writeInt32(c);           // c
569    writeInt32(d);           // d
570    writeInt32(0);           // v
571    writeInt32(0);           // x
572    writeInt32(0);           // y
573    writeInt32(0x40000000);  // w
574}
575
576
577status_t MPEG4Writer::stop() {
578    if (mFile == NULL) {
579        return OK;
580    }
581
582    status_t err = OK;
583    int64_t maxDurationUs = 0;
584    for (List<Track *>::iterator it = mTracks.begin();
585         it != mTracks.end(); ++it) {
586        status_t status = (*it)->stop();
587        if (err == OK && status != OK) {
588            err = status;
589        }
590
591        int64_t durationUs = (*it)->getDurationUs();
592        if (durationUs > maxDurationUs) {
593            maxDurationUs = durationUs;
594        }
595    }
596
597    stopWriterThread();
598
599    // Do not write out movie header on error.
600    if (err != OK) {
601        fflush(mFile);
602        fclose(mFile);
603        mFile = NULL;
604        mStarted = false;
605        return err;
606    }
607
608    // Fix up the size of the 'mdat' chunk.
609    if (mUse32BitOffset) {
610        fseeko(mFile, mMdatOffset, SEEK_SET);
611        int32_t size = htonl(static_cast<int32_t>(mOffset - mMdatOffset));
612        fwrite(&size, 1, 4, mFile);
613    } else {
614        fseeko(mFile, mMdatOffset + 8, SEEK_SET);
615        int64_t size = mOffset - mMdatOffset;
616        size = hton64(size);
617        fwrite(&size, 1, 8, mFile);
618    }
619    fseeko(mFile, mOffset, SEEK_SET);
620
621    time_t now = time(NULL);
622    const off_t moovOffset = mOffset;
623    mWriteMoovBoxToMemory = true;
624    mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize);
625    mMoovBoxBufferOffset = 0;
626    CHECK(mMoovBoxBuffer != NULL);
627    int32_t duration = (maxDurationUs * mTimeScale + 5E5) / 1E6;
628
629    beginBox("moov");
630
631      beginBox("mvhd");
632        writeInt32(0);             // version=0, flags=0
633        writeInt32(now);           // creation time
634        writeInt32(now);           // modification time
635        writeInt32(mTimeScale);    // mvhd timescale
636        writeInt32(duration);
637        writeInt32(0x10000);       // rate: 1.0
638        writeInt16(0x100);         // volume
639        writeInt16(0);             // reserved
640        writeInt32(0);             // reserved
641        writeInt32(0);             // reserved
642        writeCompositionMatrix(0); // matrix
643        writeInt32(0);             // predefined
644        writeInt32(0);             // predefined
645        writeInt32(0);             // predefined
646        writeInt32(0);             // predefined
647        writeInt32(0);             // predefined
648        writeInt32(0);             // predefined
649        writeInt32(mTracks.size() + 1);  // nextTrackID
650      endBox();  // mvhd
651
652      int32_t id = 1;
653      for (List<Track *>::iterator it = mTracks.begin();
654           it != mTracks.end(); ++it, ++id) {
655          (*it)->writeTrackHeader(id, mUse32BitOffset);
656      }
657    endBox();  // moov
658
659    mWriteMoovBoxToMemory = false;
660    if (mStreamableFile) {
661        CHECK(mMoovBoxBufferOffset + 8 <= mEstimatedMoovBoxSize);
662
663        // Moov box
664        fseeko(mFile, mFreeBoxOffset, SEEK_SET);
665        mOffset = mFreeBoxOffset;
666        write(mMoovBoxBuffer, 1, mMoovBoxBufferOffset, mFile);
667
668        // Free box
669        fseeko(mFile, mOffset, SEEK_SET);
670        writeInt32(mEstimatedMoovBoxSize - mMoovBoxBufferOffset);
671        write("free", 4);
672
673        // Free temp memory
674        free(mMoovBoxBuffer);
675        mMoovBoxBuffer = NULL;
676        mMoovBoxBufferOffset = 0;
677    } else {
678        LOGI("The mp4 file will not be streamable.");
679    }
680
681    CHECK(mBoxes.empty());
682
683    fflush(mFile);
684    fclose(mFile);
685    mFile = NULL;
686    mStarted = false;
687    return err;
688}
689
690status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
691    mInterleaveDurationUs = durationUs;
692    return OK;
693}
694
695void MPEG4Writer::lock() {
696    mLock.lock();
697}
698
699void MPEG4Writer::unlock() {
700    mLock.unlock();
701}
702
703off_t MPEG4Writer::addSample_l(MediaBuffer *buffer) {
704    off_t old_offset = mOffset;
705
706    fwrite((const uint8_t *)buffer->data() + buffer->range_offset(),
707           1, buffer->range_length(), mFile);
708
709    mOffset += buffer->range_length();
710
711    return old_offset;
712}
713
714static void StripStartcode(MediaBuffer *buffer) {
715    if (buffer->range_length() < 4) {
716        return;
717    }
718
719    const uint8_t *ptr =
720        (const uint8_t *)buffer->data() + buffer->range_offset();
721
722    if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) {
723        buffer->set_range(
724                buffer->range_offset() + 4, buffer->range_length() - 4);
725    }
726}
727
728off_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) {
729    off_t old_offset = mOffset;
730
731    size_t length = buffer->range_length();
732
733    if (mUse4ByteNalLength) {
734        uint8_t x = length >> 24;
735        fwrite(&x, 1, 1, mFile);
736        x = (length >> 16) & 0xff;
737        fwrite(&x, 1, 1, mFile);
738        x = (length >> 8) & 0xff;
739        fwrite(&x, 1, 1, mFile);
740        x = length & 0xff;
741        fwrite(&x, 1, 1, mFile);
742
743        fwrite((const uint8_t *)buffer->data() + buffer->range_offset(),
744                1, length, mFile);
745        mOffset += length + 4;
746    } else {
747        CHECK(length < 65536);
748
749        uint8_t x = length >> 8;
750        fwrite(&x, 1, 1, mFile);
751        x = length & 0xff;
752        fwrite(&x, 1, 1, mFile);
753        fwrite((const uint8_t *)buffer->data() + buffer->range_offset(),
754                1, length, mFile);
755        mOffset += length + 2;
756    }
757
758    return old_offset;
759}
760
761size_t MPEG4Writer::write(
762        const void *ptr, size_t size, size_t nmemb, FILE *stream) {
763
764    const size_t bytes = size * nmemb;
765    if (mWriteMoovBoxToMemory) {
766        off_t moovBoxSize = 8 + mMoovBoxBufferOffset + bytes;
767        if (moovBoxSize > mEstimatedMoovBoxSize) {
768            for (List<off_t>::iterator it = mBoxes.begin();
769                 it != mBoxes.end(); ++it) {
770                (*it) += mOffset;
771            }
772            fseeko(mFile, mOffset, SEEK_SET);
773            fwrite(mMoovBoxBuffer, 1, mMoovBoxBufferOffset, stream);
774            fwrite(ptr, size, nmemb, stream);
775            mOffset += (bytes + mMoovBoxBufferOffset);
776            free(mMoovBoxBuffer);
777            mMoovBoxBuffer = NULL;
778            mMoovBoxBufferOffset = 0;
779            mWriteMoovBoxToMemory = false;
780            mStreamableFile = false;
781        } else {
782            memcpy(mMoovBoxBuffer + mMoovBoxBufferOffset, ptr, bytes);
783            mMoovBoxBufferOffset += bytes;
784        }
785    } else {
786        fwrite(ptr, size, nmemb, stream);
787        mOffset += bytes;
788    }
789    return bytes;
790}
791
792void MPEG4Writer::beginBox(const char *fourcc) {
793    CHECK_EQ(strlen(fourcc), 4);
794
795    mBoxes.push_back(mWriteMoovBoxToMemory?
796            mMoovBoxBufferOffset: mOffset);
797
798    writeInt32(0);
799    writeFourcc(fourcc);
800}
801
802void MPEG4Writer::endBox() {
803    CHECK(!mBoxes.empty());
804
805    off_t offset = *--mBoxes.end();
806    mBoxes.erase(--mBoxes.end());
807
808    if (mWriteMoovBoxToMemory) {
809       int32_t x = htonl(mMoovBoxBufferOffset - offset);
810       memcpy(mMoovBoxBuffer + offset, &x, 4);
811    } else {
812        fseeko(mFile, offset, SEEK_SET);
813        writeInt32(mOffset - offset);
814        mOffset -= 4;
815        fseeko(mFile, mOffset, SEEK_SET);
816    }
817}
818
819void MPEG4Writer::writeInt8(int8_t x) {
820    write(&x, 1, 1, mFile);
821}
822
823void MPEG4Writer::writeInt16(int16_t x) {
824    x = htons(x);
825    write(&x, 1, 2, mFile);
826}
827
828void MPEG4Writer::writeInt32(int32_t x) {
829    x = htonl(x);
830    write(&x, 1, 4, mFile);
831}
832
833void MPEG4Writer::writeInt64(int64_t x) {
834    x = hton64(x);
835    write(&x, 1, 8, mFile);
836}
837
838void MPEG4Writer::writeCString(const char *s) {
839    size_t n = strlen(s);
840    write(s, 1, n + 1, mFile);
841}
842
843void MPEG4Writer::writeFourcc(const char *s) {
844    CHECK_EQ(strlen(s), 4);
845    write(s, 1, 4, mFile);
846}
847
848void MPEG4Writer::write(const void *data, size_t size) {
849    write(data, 1, size, mFile);
850}
851
852bool MPEG4Writer::isFileStreamable() const {
853    return mStreamableFile;
854}
855
856bool MPEG4Writer::exceedsFileSizeLimit() {
857    // No limit
858    if (mMaxFileSizeLimitBytes == 0) {
859        return false;
860    }
861
862    int64_t nTotalBytesEstimate = static_cast<int64_t>(mEstimatedMoovBoxSize);
863    for (List<Track *>::iterator it = mTracks.begin();
864         it != mTracks.end(); ++it) {
865        nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
866    }
867
868    return (nTotalBytesEstimate >= mMaxFileSizeLimitBytes);
869}
870
871bool MPEG4Writer::exceedsFileDurationLimit() {
872    // No limit
873    if (mMaxFileDurationLimitUs == 0) {
874        return false;
875    }
876
877    for (List<Track *>::iterator it = mTracks.begin();
878         it != mTracks.end(); ++it) {
879        if ((*it)->getDurationUs() >= mMaxFileDurationLimitUs) {
880            return true;
881        }
882    }
883    return false;
884}
885
886bool MPEG4Writer::reachedEOS() {
887    bool allDone = true;
888    for (List<Track *>::iterator it = mTracks.begin();
889         it != mTracks.end(); ++it) {
890        if (!(*it)->reachedEOS()) {
891            allDone = false;
892            break;
893        }
894    }
895
896    return allDone;
897}
898
899void MPEG4Writer::setStartTimestampUs(int64_t timeUs) {
900    LOGI("setStartTimestampUs: %lld", timeUs);
901    CHECK(timeUs >= 0);
902    Mutex::Autolock autoLock(mLock);
903    if (mStartTimestampUs < 0 || mStartTimestampUs > timeUs) {
904        mStartTimestampUs = timeUs;
905        LOGI("Earliest track starting time: %lld", mStartTimestampUs);
906    }
907}
908
909int64_t MPEG4Writer::getStartTimestampUs() {
910    Mutex::Autolock autoLock(mLock);
911    return mStartTimestampUs;
912}
913
914size_t MPEG4Writer::numTracks() {
915    Mutex::Autolock autolock(mLock);
916    return mTracks.size();
917}
918
919////////////////////////////////////////////////////////////////////////////////
920
921MPEG4Writer::Track::Track(
922        MPEG4Writer *owner, const sp<MediaSource> &source)
923    : mOwner(owner),
924      mMeta(source->getFormat()),
925      mSource(source),
926      mDone(false),
927      mPaused(false),
928      mResumed(false),
929      mTrackDurationUs(0),
930      mEstimatedTrackSizeBytes(0),
931      mSamplesHaveSameSize(true),
932      mCodecSpecificData(NULL),
933      mCodecSpecificDataSize(0),
934      mGotAllCodecSpecificData(false),
935      mReachedEOS(false),
936      mRotation(0) {
937    getCodecSpecificDataFromInputFormatIfPossible();
938
939    const char *mime;
940    mMeta->findCString(kKeyMIMEType, &mime);
941    mIsAvc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
942    mIsAudio = !strncasecmp(mime, "audio/", 6);
943    mIsMPEG4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
944               !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC);
945
946    setTimeScale();
947}
948
949void MPEG4Writer::Track::updateTrackSizeEstimate() {
950
951    int64_t stcoBoxSizeBytes = mOwner->use32BitFileOffset()
952                                ? mNumStcoTableEntries * 4
953                                : mNumStcoTableEntries * 8;
954
955    int64_t stszBoxSizeBytes = mSamplesHaveSameSize? 4: (mNumSamples * 4);
956
957    mEstimatedTrackSizeBytes = mMdatSizeBytes;  // media data size
958    if (!mOwner->isFileStreamable()) {
959        // Reserved free space is not large enough to hold
960        // all meta data and thus wasted.
961        mEstimatedTrackSizeBytes += mNumStscTableEntries * 12 +  // stsc box size
962                                    mNumStssTableEntries * 4 +   // stss box size
963                                    mNumSttsTableEntries * 8 +   // stts box size
964                                    stcoBoxSizeBytes +           // stco box size
965                                    stszBoxSizeBytes;            // stsz box size
966    }
967}
968
969void MPEG4Writer::Track::addOneStscTableEntry(
970        size_t chunkId, size_t sampleId) {
971
972        StscTableEntry stscEntry(chunkId, sampleId, 1);
973        mStscTableEntries.push_back(stscEntry);
974        ++mNumStscTableEntries;
975}
976
977void MPEG4Writer::Track::addOneStssTableEntry(size_t sampleId) {
978    mStssTableEntries.push_back(sampleId);
979    ++mNumStssTableEntries;
980}
981
982void MPEG4Writer::Track::addOneSttsTableEntry(
983        size_t sampleCount, int64_t durationUs) {
984
985    SttsTableEntry sttsEntry(sampleCount, durationUs);
986    mSttsTableEntries.push_back(sttsEntry);
987    ++mNumSttsTableEntries;
988}
989
990void MPEG4Writer::Track::addChunkOffset(off_t offset) {
991    ++mNumStcoTableEntries;
992    mChunkOffsets.push_back(offset);
993}
994
995void MPEG4Writer::Track::setTimeScale() {
996    LOGV("setTimeScale");
997    // Default time scale
998    mTimeScale = 90000;
999
1000    if (mIsAudio) {
1001        // Use the sampling rate as the default time scale for audio track.
1002        int32_t sampleRate;
1003        bool success = mMeta->findInt32(kKeySampleRate, &sampleRate);
1004        CHECK(success);
1005        mTimeScale = sampleRate;
1006    }
1007
1008    // If someone would like to overwrite the timescale, use user-supplied value.
1009    int32_t timeScale;
1010    if (mMeta->findInt32(kKeyTimeScale, &timeScale)) {
1011        mTimeScale = timeScale;
1012    }
1013
1014    CHECK(mTimeScale > 0);
1015}
1016
1017void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() {
1018    const char *mime;
1019    CHECK(mMeta->findCString(kKeyMIMEType, &mime));
1020
1021    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
1022        uint32_t type;
1023        const void *data;
1024        size_t size;
1025        if (mMeta->findData(kKeyAVCC, &type, &data, &size)) {
1026            mCodecSpecificData = malloc(size);
1027            mCodecSpecificDataSize = size;
1028            memcpy(mCodecSpecificData, data, size);
1029            mGotAllCodecSpecificData = true;
1030        }
1031    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
1032            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
1033        uint32_t type;
1034        const void *data;
1035        size_t size;
1036        if (mMeta->findData(kKeyESDS, &type, &data, &size)) {
1037            ESDS esds(data, size);
1038            if (esds.getCodecSpecificInfo(&data, &size) == OK) {
1039                mCodecSpecificData = malloc(size);
1040                mCodecSpecificDataSize = size;
1041                memcpy(mCodecSpecificData, data, size);
1042                mGotAllCodecSpecificData = true;
1043            }
1044        }
1045    }
1046}
1047
1048MPEG4Writer::Track::~Track() {
1049    stop();
1050
1051    if (mCodecSpecificData != NULL) {
1052        free(mCodecSpecificData);
1053        mCodecSpecificData = NULL;
1054    }
1055}
1056
1057void MPEG4Writer::Track::initTrackingProgressStatus(MetaData *params) {
1058    LOGV("initTrackingProgressStatus");
1059    mPreviousTrackTimeUs = -1;
1060    mTrackingProgressStatus = false;
1061    mTrackEveryTimeDurationUs = 0;
1062    {
1063        int64_t timeUs;
1064        if (params && params->findInt64(kKeyTrackTimeStatus, &timeUs)) {
1065            LOGV("Receive request to track progress status for every %lld us", timeUs);
1066            mTrackEveryTimeDurationUs = timeUs;
1067            mTrackingProgressStatus = true;
1068        }
1069    }
1070}
1071
1072// static
1073void *MPEG4Writer::ThreadWrapper(void *me) {
1074    LOGV("ThreadWrapper: %p", me);
1075    MPEG4Writer *writer = static_cast<MPEG4Writer *>(me);
1076    writer->threadFunc();
1077    return NULL;
1078}
1079
1080void MPEG4Writer::bufferChunk(const Chunk& chunk) {
1081    LOGV("bufferChunk: %p", chunk.mTrack);
1082    Mutex::Autolock autolock(mLock);
1083    CHECK_EQ(mDone, false);
1084
1085    for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
1086         it != mChunkInfos.end(); ++it) {
1087
1088        if (chunk.mTrack == it->mTrack) {  // Found owner
1089            it->mChunks.push_back(chunk);
1090            mChunkReadyCondition.signal();
1091            return;
1092        }
1093    }
1094
1095    CHECK("Received a chunk for a unknown track" == 0);
1096}
1097
1098void MPEG4Writer::writeFirstChunk(ChunkInfo* info) {
1099    LOGV("writeFirstChunk: %p", info->mTrack);
1100
1101    List<Chunk>::iterator chunkIt = info->mChunks.begin();
1102    for (List<MediaBuffer *>::iterator it = chunkIt->mSamples.begin();
1103         it != chunkIt->mSamples.end(); ++it) {
1104
1105        off_t offset = info->mTrack->isAvc()
1106                            ? addLengthPrefixedSample_l(*it)
1107                            : addSample_l(*it);
1108        if (it == chunkIt->mSamples.begin()) {
1109            info->mTrack->addChunkOffset(offset);
1110        }
1111    }
1112
1113    // Done with the current chunk.
1114    // Release all the samples in this chunk.
1115    while (!chunkIt->mSamples.empty()) {
1116        List<MediaBuffer *>::iterator it = chunkIt->mSamples.begin();
1117        (*it)->release();
1118        (*it) = NULL;
1119        chunkIt->mSamples.erase(it);
1120    }
1121    chunkIt->mSamples.clear();
1122    info->mChunks.erase(chunkIt);
1123}
1124
1125void MPEG4Writer::writeChunks() {
1126    LOGV("writeChunks");
1127    size_t outstandingChunks = 0;
1128    while (!mChunkInfos.empty()) {
1129        List<ChunkInfo>::iterator it = mChunkInfos.begin();
1130        while (!it->mChunks.empty()) {
1131            CHECK_EQ(OK, writeOneChunk());
1132            ++outstandingChunks;
1133        }
1134        it->mTrack = NULL;
1135        mChunkInfos.erase(it);
1136    }
1137    mChunkInfos.clear();
1138    LOGD("%d chunks are written in the last batch", outstandingChunks);
1139}
1140
1141status_t MPEG4Writer::writeOneChunk() {
1142    LOGV("writeOneChunk");
1143
1144    // Find the smallest timestamp, and write that chunk out
1145    // XXX: What if some track is just too slow?
1146    int64_t minTimestampUs = 0x7FFFFFFFFFFFFFFFLL;
1147    Track *track = NULL;
1148    for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
1149         it != mChunkInfos.end(); ++it) {
1150        if (!it->mChunks.empty()) {
1151            List<Chunk>::iterator chunkIt = it->mChunks.begin();
1152            if (chunkIt->mTimeStampUs < minTimestampUs) {
1153                minTimestampUs = chunkIt->mTimeStampUs;
1154                track = it->mTrack;
1155            }
1156        }
1157    }
1158
1159    if (track == NULL) {
1160        LOGV("Nothing to be written after all");
1161        return OK;
1162    }
1163
1164    if (mIsFirstChunk) {
1165        mIsFirstChunk = false;
1166    }
1167    for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
1168         it != mChunkInfos.end(); ++it) {
1169        if (it->mTrack == track) {
1170            writeFirstChunk(&(*it));
1171        }
1172    }
1173    return OK;
1174}
1175
1176void MPEG4Writer::threadFunc() {
1177    LOGV("threadFunc");
1178
1179    prctl(PR_SET_NAME, (unsigned long)"MPEG4Writer", 0, 0, 0);
1180    while (!mDone) {
1181        {
1182            Mutex::Autolock autolock(mLock);
1183            mChunkReadyCondition.wait(mLock);
1184            CHECK_EQ(writeOneChunk(), OK);
1185        }
1186    }
1187
1188    {
1189        // Write ALL samples
1190        Mutex::Autolock autolock(mLock);
1191        writeChunks();
1192    }
1193}
1194
1195status_t MPEG4Writer::startWriterThread() {
1196    LOGV("startWriterThread");
1197
1198    mDone = false;
1199    mIsFirstChunk = true;
1200    mDriftTimeUs = 0;
1201    for (List<Track *>::iterator it = mTracks.begin();
1202         it != mTracks.end(); ++it) {
1203        ChunkInfo info;
1204        info.mTrack = *it;
1205        mChunkInfos.push_back(info);
1206    }
1207
1208    pthread_attr_t attr;
1209    pthread_attr_init(&attr);
1210    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
1211    pthread_create(&mThread, &attr, ThreadWrapper, this);
1212    pthread_attr_destroy(&attr);
1213    return OK;
1214}
1215
1216
1217status_t MPEG4Writer::Track::start(MetaData *params) {
1218    if (!mDone && mPaused) {
1219        mPaused = false;
1220        mResumed = true;
1221        return OK;
1222    }
1223
1224    int64_t startTimeUs;
1225    if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
1226        startTimeUs = 0;
1227    }
1228
1229    int32_t rotationDegrees;
1230    if (!mIsAudio && params && params->findInt32(kKeyRotation, &rotationDegrees)) {
1231        mRotation = rotationDegrees;
1232    }
1233
1234    mIsRealTimeRecording = true;
1235    {
1236        int32_t isNotRealTime;
1237        if (params && params->findInt32(kKeyNotRealTime, &isNotRealTime)) {
1238            mIsRealTimeRecording = (isNotRealTime == 0);
1239        }
1240    }
1241
1242    initTrackingProgressStatus(params);
1243
1244    sp<MetaData> meta = new MetaData;
1245    meta->setInt64(kKeyTime, startTimeUs);
1246    status_t err = mSource->start(meta.get());
1247    if (err != OK) {
1248        mDone = mReachedEOS = true;
1249        return err;
1250    }
1251
1252    pthread_attr_t attr;
1253    pthread_attr_init(&attr);
1254    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
1255
1256    mDone = false;
1257    mTrackDurationUs = 0;
1258    mReachedEOS = false;
1259    mEstimatedTrackSizeBytes = 0;
1260    mNumStcoTableEntries = 0;
1261    mNumStssTableEntries = 0;
1262    mNumStscTableEntries = 0;
1263    mNumSttsTableEntries = 0;
1264    mMdatSizeBytes = 0;
1265    mIsMediaTimeAdjustmentOn = false;
1266    mPrevMediaTimeAdjustTimestampUs = 0;
1267    mMediaTimeAdjustNumFrames = 0;
1268    mPrevMediaTimeAdjustSample = 0;
1269    mTotalDriftTimeToAdjustUs = 0;
1270    mPrevTotalAccumDriftTimeUs = 0;
1271
1272    pthread_create(&mThread, &attr, ThreadWrapper, this);
1273    pthread_attr_destroy(&attr);
1274
1275    return OK;
1276}
1277
1278status_t MPEG4Writer::Track::pause() {
1279    mPaused = true;
1280    return OK;
1281}
1282
1283status_t MPEG4Writer::Track::stop() {
1284    LOGD("Stopping %s track", mIsAudio? "Audio": "Video");
1285    if (mDone) {
1286        return OK;
1287    }
1288
1289    mDone = true;
1290
1291    void *dummy;
1292    pthread_join(mThread, &dummy);
1293
1294    status_t err = (status_t) dummy;
1295
1296    LOGD("Stopping %s track source", mIsAudio? "Audio": "Video");
1297    {
1298        status_t status = mSource->stop();
1299        if (err == OK && status != OK && status != ERROR_END_OF_STREAM) {
1300            err = status;
1301        }
1302    }
1303
1304    LOGD("%s track stopped", mIsAudio? "Audio": "Video");
1305    return err;
1306}
1307
1308bool MPEG4Writer::Track::reachedEOS() {
1309    return mReachedEOS;
1310}
1311
1312// static
1313void *MPEG4Writer::Track::ThreadWrapper(void *me) {
1314    Track *track = static_cast<Track *>(me);
1315
1316    status_t err = track->threadEntry();
1317    return (void *) err;
1318}
1319
1320static void getNalUnitType(uint8_t byte, uint8_t* type) {
1321    LOGV("getNalUnitType: %d", byte);
1322
1323    // nal_unit_type: 5-bit unsigned integer
1324    *type = (byte & 0x1F);
1325}
1326
1327static const uint8_t *findNextStartCode(
1328        const uint8_t *data, size_t length) {
1329
1330    LOGV("findNextStartCode: %p %d", data, length);
1331
1332    size_t bytesLeft = length;
1333    while (bytesLeft > 4  &&
1334            memcmp("\x00\x00\x00\x01", &data[length - bytesLeft], 4)) {
1335        --bytesLeft;
1336    }
1337    if (bytesLeft <= 4) {
1338        bytesLeft = 0; // Last parameter set
1339    }
1340    return &data[length - bytesLeft];
1341}
1342
1343const uint8_t *MPEG4Writer::Track::parseParamSet(
1344        const uint8_t *data, size_t length, int type, size_t *paramSetLen) {
1345
1346    LOGV("parseParamSet");
1347    CHECK(type == kNalUnitTypeSeqParamSet ||
1348          type == kNalUnitTypePicParamSet);
1349
1350    const uint8_t *nextStartCode = findNextStartCode(data, length);
1351    *paramSetLen = nextStartCode - data;
1352    if (*paramSetLen == 0) {
1353        LOGE("Param set is malformed, since its length is 0");
1354        return NULL;
1355    }
1356
1357    AVCParamSet paramSet(*paramSetLen, data);
1358    if (type == kNalUnitTypeSeqParamSet) {
1359        if (*paramSetLen < 4) {
1360            LOGE("Seq parameter set malformed");
1361            return NULL;
1362        }
1363        if (mSeqParamSets.empty()) {
1364            mProfileIdc = data[1];
1365            mProfileCompatible = data[2];
1366            mLevelIdc = data[3];
1367        } else {
1368            if (mProfileIdc != data[1] ||
1369                mProfileCompatible != data[2] ||
1370                mLevelIdc != data[3]) {
1371                LOGE("Inconsistent profile/level found in seq parameter sets");
1372                return NULL;
1373            }
1374        }
1375        mSeqParamSets.push_back(paramSet);
1376    } else {
1377        mPicParamSets.push_back(paramSet);
1378    }
1379    return nextStartCode;
1380}
1381
1382status_t MPEG4Writer::Track::copyAVCCodecSpecificData(
1383        const uint8_t *data, size_t size) {
1384    LOGV("copyAVCCodecSpecificData");
1385
1386    // 2 bytes for each of the parameter set length field
1387    // plus the 7 bytes for the header
1388    if (size < 4 + 7) {
1389        LOGE("Codec specific data length too short: %d", size);
1390        return ERROR_MALFORMED;
1391    }
1392
1393    mCodecSpecificDataSize = size;
1394    mCodecSpecificData = malloc(size);
1395    memcpy(mCodecSpecificData, data, size);
1396    return OK;
1397}
1398
1399status_t MPEG4Writer::Track::parseAVCCodecSpecificData(
1400        const uint8_t *data, size_t size) {
1401
1402    LOGV("parseAVCCodecSpecificData");
1403    // Data starts with a start code.
1404    // SPS and PPS are separated with start codes.
1405    // Also, SPS must come before PPS
1406    uint8_t type = kNalUnitTypeSeqParamSet;
1407    bool gotSps = false;
1408    bool gotPps = false;
1409    const uint8_t *tmp = data;
1410    const uint8_t *nextStartCode = data;
1411    size_t bytesLeft = size;
1412    size_t paramSetLen = 0;
1413    mCodecSpecificDataSize = 0;
1414    while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) {
1415        getNalUnitType(*(tmp + 4), &type);
1416        if (type == kNalUnitTypeSeqParamSet) {
1417            if (gotPps) {
1418                LOGE("SPS must come before PPS");
1419                return ERROR_MALFORMED;
1420            }
1421            if (!gotSps) {
1422                gotSps = true;
1423            }
1424            nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, &paramSetLen);
1425        } else if (type == kNalUnitTypePicParamSet) {
1426            if (!gotSps) {
1427                LOGE("SPS must come before PPS");
1428                return ERROR_MALFORMED;
1429            }
1430            if (!gotPps) {
1431                gotPps = true;
1432            }
1433            nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, &paramSetLen);
1434        } else {
1435            LOGE("Only SPS and PPS Nal units are expected");
1436            return ERROR_MALFORMED;
1437        }
1438
1439        if (nextStartCode == NULL) {
1440            return ERROR_MALFORMED;
1441        }
1442
1443        // Move on to find the next parameter set
1444        bytesLeft -= nextStartCode - tmp;
1445        tmp = nextStartCode;
1446        mCodecSpecificDataSize += (2 + paramSetLen);
1447    }
1448
1449    {
1450        // Check on the number of seq parameter sets
1451        size_t nSeqParamSets = mSeqParamSets.size();
1452        if (nSeqParamSets == 0) {
1453            LOGE("Cound not find sequence parameter set");
1454            return ERROR_MALFORMED;
1455        }
1456
1457        if (nSeqParamSets > 0x1F) {
1458            LOGE("Too many seq parameter sets (%d) found", nSeqParamSets);
1459            return ERROR_MALFORMED;
1460        }
1461    }
1462
1463    {
1464        // Check on the number of pic parameter sets
1465        size_t nPicParamSets = mPicParamSets.size();
1466        if (nPicParamSets == 0) {
1467            LOGE("Cound not find picture parameter set");
1468            return ERROR_MALFORMED;
1469        }
1470        if (nPicParamSets > 0xFF) {
1471            LOGE("Too many pic parameter sets (%d) found", nPicParamSets);
1472            return ERROR_MALFORMED;
1473        }
1474    }
1475
1476    {
1477        // Check on the profiles
1478        // These profiles requires additional parameter set extensions
1479        if (mProfileIdc == 100 || mProfileIdc == 110 ||
1480            mProfileIdc == 122 || mProfileIdc == 144) {
1481            LOGE("Sorry, no support for profile_idc: %d!", mProfileIdc);
1482            return BAD_VALUE;
1483        }
1484    }
1485
1486    return OK;
1487}
1488
1489status_t MPEG4Writer::Track::makeAVCCodecSpecificData(
1490        const uint8_t *data, size_t size) {
1491
1492    if (mCodecSpecificData != NULL) {
1493        LOGE("Already have codec specific data");
1494        return ERROR_MALFORMED;
1495    }
1496
1497    if (size < 4) {
1498        LOGE("Codec specific data length too short: %d", size);
1499        return ERROR_MALFORMED;
1500    }
1501
1502    // Data is in the form of AVCCodecSpecificData
1503    if (memcmp("\x00\x00\x00\x01", data, 4)) {
1504        return copyAVCCodecSpecificData(data, size);
1505    }
1506
1507    if (parseAVCCodecSpecificData(data, size) != OK) {
1508        return ERROR_MALFORMED;
1509    }
1510
1511    // ISO 14496-15: AVC file format
1512    mCodecSpecificDataSize += 7;  // 7 more bytes in the header
1513    mCodecSpecificData = malloc(mCodecSpecificDataSize);
1514    uint8_t *header = (uint8_t *)mCodecSpecificData;
1515    header[0] = 1;                     // version
1516    header[1] = mProfileIdc;           // profile indication
1517    header[2] = mProfileCompatible;    // profile compatibility
1518    header[3] = mLevelIdc;
1519
1520    // 6-bit '111111' followed by 2-bit to lengthSizeMinuusOne
1521    if (mOwner->useNalLengthFour()) {
1522        header[4] = 0xfc | 3;  // length size == 4 bytes
1523    } else {
1524        header[4] = 0xfc | 1;  // length size == 2 bytes
1525    }
1526
1527    // 3-bit '111' followed by 5-bit numSequenceParameterSets
1528    int nSequenceParamSets = mSeqParamSets.size();
1529    header[5] = 0xe0 | nSequenceParamSets;
1530    header += 6;
1531    for (List<AVCParamSet>::iterator it = mSeqParamSets.begin();
1532         it != mSeqParamSets.end(); ++it) {
1533        // 16-bit sequence parameter set length
1534        uint16_t seqParamSetLength = it->mLength;
1535        header[0] = seqParamSetLength >> 8;
1536        header[1] = seqParamSetLength & 0xff;
1537
1538        // SPS NAL unit (sequence parameter length bytes)
1539        memcpy(&header[2], it->mData, seqParamSetLength);
1540        header += (2 + seqParamSetLength);
1541    }
1542
1543    // 8-bit nPictureParameterSets
1544    int nPictureParamSets = mPicParamSets.size();
1545    header[0] = nPictureParamSets;
1546    header += 1;
1547    for (List<AVCParamSet>::iterator it = mPicParamSets.begin();
1548         it != mPicParamSets.end(); ++it) {
1549        // 16-bit picture parameter set length
1550        uint16_t picParamSetLength = it->mLength;
1551        header[0] = picParamSetLength >> 8;
1552        header[1] = picParamSetLength & 0xff;
1553
1554        // PPS Nal unit (picture parameter set length bytes)
1555        memcpy(&header[2], it->mData, picParamSetLength);
1556        header += (2 + picParamSetLength);
1557    }
1558
1559    return OK;
1560}
1561
1562/*
1563* The video track's media time adjustment for real-time applications
1564* is described as follows:
1565*
1566* First, the media time adjustment is done for every period of
1567* kVideoMediaTimeAdjustPeriodTimeUs. kVideoMediaTimeAdjustPeriodTimeUs
1568* is currently a fixed value chosen heuristically. The value of
1569* kVideoMediaTimeAdjustPeriodTimeUs should not be very large or very small
1570* for two considerations: on one hand, a relatively large value
1571* helps reduce large fluctuation of drift time in the audio encoding
1572* path; while on the other hand, a relatively small value helps keep
1573* restoring synchronization in audio/video more frequently. Note for the
1574* very first period of kVideoMediaTimeAdjustPeriodTimeUs, there is
1575* no media time adjustment for the video track.
1576*
1577* Second, the total accumulated audio track time drift found
1578* in a period of kVideoMediaTimeAdjustPeriodTimeUs is distributed
1579* over a stream of incoming video frames. The number of video frames
1580* affected is determined based on the number of recorded video frames
1581* within the past kVideoMediaTimeAdjustPeriodTimeUs period.
1582* We choose to distribute the drift time over only a portion
1583* (rather than all) of the total number of recorded video frames
1584* in order to make sure that the video track media time adjustment is
1585* completed for the current period before the next video track media
1586* time adjustment period starts. Currently, the portion chosen is a
1587* half (0.5).
1588*
1589* Last, various additional checks are performed to ensure that
1590* the actual audio encoding path does not have too much drift.
1591* In particular, 1) we want to limit the average incremental time
1592* adjustment for each video frame to be less than a threshold
1593* for a single period of kVideoMediaTimeAdjustPeriodTimeUs.
1594* Currently, the threshold is set to 5 ms. If the average incremental
1595* media time adjustment for a video frame is larger than the
1596* threshold, the audio encoding path has too much time drift.
1597* 2) We also want to limit the total time drift in the audio
1598* encoding path to be less than a threshold for a period of
1599* kVideoMediaTimeAdjustPeriodTimeUs. Currently, the threshold
1600* is 0.5% of kVideoMediaTimeAdjustPeriodTimeUs. If the time drift of
1601* the audio encoding path is larger than the threshold, the audio
1602* encoding path has too much time drift. We treat the large time
1603* drift of the audio encoding path as errors, since there is no
1604* way to keep audio/video in synchronization for real-time
1605* applications if the time drift is too large unless we drop some
1606* video frames, which has its own problems that we don't want
1607* to get into for the time being.
1608*/
1609void MPEG4Writer::Track::adjustMediaTime(int64_t *timestampUs) {
1610    if (*timestampUs - mPrevMediaTimeAdjustTimestampUs >=
1611        kVideoMediaTimeAdjustPeriodTimeUs) {
1612
1613        LOGV("New media time adjustment period at %lld us", *timestampUs);
1614        mIsMediaTimeAdjustmentOn = true;
1615        mMediaTimeAdjustNumFrames =
1616                (mNumSamples - mPrevMediaTimeAdjustSample) >> 1;
1617
1618        mPrevMediaTimeAdjustTimestampUs = *timestampUs;
1619        mPrevMediaTimeAdjustSample = mNumSamples;
1620        int64_t totalAccumDriftTimeUs = mOwner->getDriftTimeUs();
1621        mTotalDriftTimeToAdjustUs =
1622                totalAccumDriftTimeUs - mPrevTotalAccumDriftTimeUs;
1623
1624        mPrevTotalAccumDriftTimeUs = totalAccumDriftTimeUs;
1625
1626        // Check on incremental adjusted time per frame
1627        int64_t adjustTimePerFrameUs =
1628                mTotalDriftTimeToAdjustUs / mMediaTimeAdjustNumFrames;
1629
1630        if (adjustTimePerFrameUs < 0) {
1631            adjustTimePerFrameUs = -adjustTimePerFrameUs;
1632        }
1633        if (adjustTimePerFrameUs >= 5000) {
1634            LOGE("Adjusted time per video frame is %lld us",
1635                adjustTimePerFrameUs);
1636            CHECK(!"Video frame time adjustment is too large!");
1637        }
1638
1639        // Check on total accumulated time drift within a period of
1640        // kVideoMediaTimeAdjustPeriodTimeUs.
1641        int64_t driftPercentage = (mTotalDriftTimeToAdjustUs * 1000)
1642                / kVideoMediaTimeAdjustPeriodTimeUs;
1643
1644        if (driftPercentage < 0) {
1645            driftPercentage = -driftPercentage;
1646        }
1647        if (driftPercentage > 5) {
1648            LOGE("Audio track has time drift %lld us over %lld us",
1649                mTotalDriftTimeToAdjustUs,
1650                kVideoMediaTimeAdjustPeriodTimeUs);
1651
1652            CHECK(!"The audio track media time drifts too much!");
1653        }
1654
1655    }
1656
1657    if (mIsMediaTimeAdjustmentOn) {
1658        if (mNumSamples - mPrevMediaTimeAdjustSample <=
1659            mMediaTimeAdjustNumFrames) {
1660
1661            // Do media time incremental adjustment
1662            int64_t incrementalAdjustTimeUs =
1663                        (mTotalDriftTimeToAdjustUs *
1664                            (mNumSamples - mPrevMediaTimeAdjustSample))
1665                                / mMediaTimeAdjustNumFrames;
1666
1667            *timestampUs +=
1668                (incrementalAdjustTimeUs + mPrevTotalAccumDriftTimeUs);
1669
1670            LOGV("Incremental video frame media time adjustment: %lld us",
1671                (incrementalAdjustTimeUs + mPrevTotalAccumDriftTimeUs));
1672        } else {
1673            // Within the remaining adjustment period,
1674            // no incremental adjustment is needed.
1675            *timestampUs +=
1676                (mTotalDriftTimeToAdjustUs + mPrevTotalAccumDriftTimeUs);
1677
1678            LOGV("Fixed video frame media time adjustment: %lld us",
1679                (mTotalDriftTimeToAdjustUs + mPrevTotalAccumDriftTimeUs));
1680        }
1681    }
1682}
1683
1684/*
1685 * Updates the drift time from the audio track so that
1686 * the video track can get the updated drift time information
1687 * from the file writer. The fluctuation of the drift time of the audio
1688 * encoding path is smoothed out with a simple filter by giving a larger
1689 * weight to more recently drift time. The filter coefficients, 0.5 and 0.5,
1690 * are heuristically determined.
1691 */
1692void MPEG4Writer::Track::updateDriftTime(const sp<MetaData>& meta) {
1693    int64_t driftTimeUs = 0;
1694    if (meta->findInt64(kKeyDriftTime, &driftTimeUs)) {
1695        int64_t prevDriftTimeUs = mOwner->getDriftTimeUs();
1696        int64_t timeUs = (driftTimeUs + prevDriftTimeUs) >> 1;
1697        mOwner->setDriftTimeUs(timeUs);
1698    }
1699}
1700
1701status_t MPEG4Writer::Track::threadEntry() {
1702    int32_t count = 0;
1703    const int64_t interleaveDurationUs = mOwner->interleaveDuration();
1704    int64_t chunkTimestampUs = 0;
1705    int32_t nChunks = 0;
1706    int32_t nZeroLengthFrames = 0;
1707    int64_t lastTimestampUs = 0;  // Previous sample time stamp in ms
1708    int64_t lastDurationUs = 0;   // Between the previous two samples in ms
1709    int64_t currDurationTicks = 0;  // Timescale based ticks
1710    int64_t lastDurationTicks = 0;  // Timescale based ticks
1711    int32_t sampleCount = 1;      // Sample count in the current stts table entry
1712    uint32_t previousSampleSize = 0;  // Size of the previous sample
1713    int64_t previousPausedDurationUs = 0;
1714    int64_t timestampUs;
1715
1716    if (mIsAudio) {
1717        prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0);
1718    } else {
1719        prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0);
1720    }
1721    sp<MetaData> meta_data;
1722
1723    mNumSamples = 0;
1724    status_t err = OK;
1725    MediaBuffer *buffer;
1726    while (!mDone && (err = mSource->read(&buffer)) == OK) {
1727        if (buffer->range_length() == 0) {
1728            buffer->release();
1729            buffer = NULL;
1730            ++nZeroLengthFrames;
1731            continue;
1732        }
1733
1734        // If the codec specific data has not been received yet, delay pause.
1735        // After the codec specific data is received, discard what we received
1736        // when the track is to be paused.
1737        if (mPaused && !mResumed) {
1738            buffer->release();
1739            buffer = NULL;
1740            continue;
1741        }
1742
1743        ++count;
1744
1745        int32_t isCodecConfig;
1746        if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig)
1747                && isCodecConfig) {
1748            CHECK(!mGotAllCodecSpecificData);
1749
1750            if (mIsAvc) {
1751                status_t err = makeAVCCodecSpecificData(
1752                        (const uint8_t *)buffer->data()
1753                            + buffer->range_offset(),
1754                        buffer->range_length());
1755                CHECK_EQ(OK, err);
1756            } else if (mIsMPEG4) {
1757                mCodecSpecificDataSize = buffer->range_length();
1758                mCodecSpecificData = malloc(mCodecSpecificDataSize);
1759                memcpy(mCodecSpecificData,
1760                        (const uint8_t *)buffer->data()
1761                            + buffer->range_offset(),
1762                       buffer->range_length());
1763            }
1764
1765            buffer->release();
1766            buffer = NULL;
1767
1768            mGotAllCodecSpecificData = true;
1769            continue;
1770        }
1771
1772        // Make a deep copy of the MediaBuffer and Metadata and release
1773        // the original as soon as we can
1774        MediaBuffer *copy = new MediaBuffer(buffer->range_length());
1775        memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(),
1776                buffer->range_length());
1777        copy->set_range(0, buffer->range_length());
1778        meta_data = new MetaData(*buffer->meta_data().get());
1779        buffer->release();
1780        buffer = NULL;
1781
1782        if (mIsAvc) StripStartcode(copy);
1783
1784        size_t sampleSize = copy->range_length();
1785        if (mIsAvc) {
1786            if (mOwner->useNalLengthFour()) {
1787                sampleSize += 4;
1788            } else {
1789                sampleSize += 2;
1790            }
1791        }
1792
1793        // Max file size or duration handling
1794        mMdatSizeBytes += sampleSize;
1795        updateTrackSizeEstimate();
1796
1797        if (mOwner->exceedsFileSizeLimit()) {
1798            mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
1799            break;
1800        }
1801        if (mOwner->exceedsFileDurationLimit()) {
1802            mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0);
1803            break;
1804        }
1805
1806
1807        int32_t isSync = false;
1808        meta_data->findInt32(kKeyIsSyncFrame, &isSync);
1809
1810        /*
1811         * The original timestamp found in the data buffer will be modified as below:
1812         *
1813         * There is a playback offset into this track if the track's start time
1814         * is not the same as the movie start time, which will be recorded in edst
1815         * box of the output file. The playback offset is to make sure that the
1816         * starting time of the audio/video tracks are synchronized. Although the
1817         * track's media timestamp may be subject to various modifications
1818         * as outlined below, the track's playback offset time remains unchanged
1819         * once the first data buffer of the track is received.
1820         *
1821         * The media time stamp will be calculated by subtracting the playback offset
1822         * (and potential pause durations) from the original timestamp in the buffer.
1823         *
1824         * If this track is a video track for a real-time recording application with
1825         * both audio and video tracks, its media timestamp will subject to further
1826         * modification based on the media clock of the audio track. This modification
1827         * is needed for the purpose of maintaining good audio/video synchronization.
1828         *
1829         * If the recording session is paused and resumed multiple times, the track
1830         * media timestamp will be modified as if the  recording session had never been
1831         * paused at all during playback of the recorded output file. In other words,
1832         * the output file will have no memory of pause/resume durations.
1833         *
1834         */
1835        CHECK(meta_data->findInt64(kKeyTime, &timestampUs));
1836        LOGV("%s timestampUs: %lld", mIsAudio? "Audio": "Video", timestampUs);
1837
1838////////////////////////////////////////////////////////////////////////////////
1839        if (mSampleSizes.empty()) {
1840            mStartTimestampUs = timestampUs;
1841            mOwner->setStartTimestampUs(mStartTimestampUs);
1842            previousPausedDurationUs = mStartTimestampUs;
1843        }
1844
1845        if (mResumed) {
1846            int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
1847            CHECK(durExcludingEarlierPausesUs >= 0);
1848            int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs;
1849            CHECK(pausedDurationUs >= lastDurationUs);
1850            previousPausedDurationUs += pausedDurationUs - lastDurationUs;
1851            mResumed = false;
1852        }
1853
1854        timestampUs -= previousPausedDurationUs;
1855        CHECK(timestampUs >= 0);
1856
1857        // Media time adjustment for real-time applications
1858        if (mIsRealTimeRecording) {
1859            if (mIsAudio) {
1860                updateDriftTime(meta_data);
1861            } else {
1862                adjustMediaTime(&timestampUs);
1863            }
1864        }
1865
1866        CHECK(timestampUs >= 0);
1867        if (mNumSamples > 1) {
1868            if (timestampUs <= lastTimestampUs) {
1869                LOGW("Frame arrives too late!");
1870                // Don't drop the late frame, since dropping a frame may cause
1871                // problems later during playback
1872
1873                // The idea here is to avoid having two or more samples with the
1874                // same timestamp in the output file.
1875                if (mTimeScale >= 1000000LL) {
1876                    timestampUs = lastTimestampUs + 1;
1877                } else {
1878                    timestampUs = lastTimestampUs + (1000000LL + (mTimeScale >> 1)) / mTimeScale;
1879                }
1880            }
1881        }
1882
1883        LOGV("%s media time stamp: %lld and previous paused duration %lld",
1884                mIsAudio? "Audio": "Video", timestampUs, previousPausedDurationUs);
1885        if (timestampUs > mTrackDurationUs) {
1886            mTrackDurationUs = timestampUs;
1887        }
1888
1889        mSampleSizes.push_back(sampleSize);
1890        ++mNumSamples;
1891        if (mNumSamples > 2) {
1892            // We need to use the time scale based ticks, rather than the
1893            // timestamp itself to determine whether we have to use a new
1894            // stts entry, since we may have rounding errors.
1895            // The calculation is intended to reduce the accumulated
1896            // rounding errors.
1897            currDurationTicks =
1898                     ((timestampUs * mTimeScale + 500000LL) / 1000000LL -
1899                     (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
1900
1901            if (currDurationTicks != lastDurationTicks) {
1902                addOneSttsTableEntry(sampleCount, lastDurationUs);
1903                sampleCount = 1;
1904            } else {
1905                ++sampleCount;
1906            }
1907        }
1908        if (mSamplesHaveSameSize) {
1909            if (mNumSamples >= 2 && previousSampleSize != sampleSize) {
1910                mSamplesHaveSameSize = false;
1911            }
1912            previousSampleSize = sampleSize;
1913        }
1914        lastDurationUs = timestampUs - lastTimestampUs;
1915        lastDurationTicks = currDurationTicks;
1916        lastTimestampUs = timestampUs;
1917
1918        if (isSync != 0) {
1919            addOneStssTableEntry(mNumSamples);
1920        }
1921
1922        if (mTrackingProgressStatus) {
1923            if (mPreviousTrackTimeUs <= 0) {
1924                mPreviousTrackTimeUs = mStartTimestampUs;
1925            }
1926            trackProgressStatus(timestampUs);
1927        }
1928        if (mOwner->numTracks() == 1) {
1929            off_t offset = mIsAvc? mOwner->addLengthPrefixedSample_l(copy)
1930                                 : mOwner->addSample_l(copy);
1931            if (mChunkOffsets.empty()) {
1932                addChunkOffset(offset);
1933            }
1934            copy->release();
1935            copy = NULL;
1936            continue;
1937        }
1938
1939        mChunkSamples.push_back(copy);
1940        if (interleaveDurationUs == 0) {
1941            addOneStscTableEntry(++nChunks, 1);
1942            bufferChunk(timestampUs);
1943        } else {
1944            if (chunkTimestampUs == 0) {
1945                chunkTimestampUs = timestampUs;
1946            } else {
1947                if (timestampUs - chunkTimestampUs > interleaveDurationUs) {
1948                    ++nChunks;
1949                    if (nChunks == 1 ||  // First chunk
1950                        (--(mStscTableEntries.end()))->samplesPerChunk !=
1951                         mChunkSamples.size()) {
1952                        addOneStscTableEntry(nChunks, mChunkSamples.size());
1953                    }
1954                    bufferChunk(timestampUs);
1955                    chunkTimestampUs = timestampUs;
1956                }
1957            }
1958        }
1959
1960    }
1961
1962    if (mSampleSizes.empty() ||                      // no samples written
1963        (!mIsAudio && mNumStssTableEntries == 0) ||  // no sync frames for video
1964        (OK != checkCodecSpecificData())) {          // no codec specific data
1965        err = ERROR_MALFORMED;
1966    }
1967    mOwner->trackProgressStatus(this, -1, err);
1968
1969    // Last chunk
1970    if (mOwner->numTracks() == 1) {
1971        addOneStscTableEntry(1, mNumSamples);
1972    } else if (!mChunkSamples.empty()) {
1973        addOneStscTableEntry(++nChunks, mChunkSamples.size());
1974        bufferChunk(timestampUs);
1975    }
1976
1977    // We don't really know how long the last frame lasts, since
1978    // there is no frame time after it, just repeat the previous
1979    // frame's duration.
1980    if (mNumSamples == 1) {
1981        lastDurationUs = 0;  // A single sample's duration
1982    } else {
1983        ++sampleCount;  // Count for the last sample
1984    }
1985    addOneSttsTableEntry(sampleCount, lastDurationUs);
1986    mTrackDurationUs += lastDurationUs;
1987    mReachedEOS = true;
1988    LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s",
1989            count, nZeroLengthFrames, mNumSamples, mIsAudio? "audio": "video");
1990    if (mIsAudio) {
1991        LOGI("Audio track drift time: %lld us", mOwner->getDriftTimeUs());
1992    }
1993
1994    if (err == ERROR_END_OF_STREAM) {
1995        return OK;
1996    }
1997    return err;
1998}
1999
2000void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) {
2001    LOGV("trackProgressStatus: %lld us", timeUs);
2002    if (mTrackEveryTimeDurationUs > 0 &&
2003        timeUs - mPreviousTrackTimeUs >= mTrackEveryTimeDurationUs) {
2004        LOGV("Fire time tracking progress status at %lld us", timeUs);
2005        mOwner->trackProgressStatus(this, timeUs - mPreviousTrackTimeUs, err);
2006        mPreviousTrackTimeUs = timeUs;
2007    }
2008}
2009
2010void MPEG4Writer::trackProgressStatus(
2011        const MPEG4Writer::Track* track, int64_t timeUs, status_t err) {
2012    Mutex::Autolock lock(mLock);
2013    int32_t nTracks = mTracks.size();
2014    CHECK(nTracks >= 1);
2015    CHECK(nTracks < 64);  // Arbitrary number
2016
2017    int32_t trackNum = 0;
2018    CHECK(trackNum < nTracks);
2019    trackNum <<= 16;
2020
2021    // Error notification
2022    // Do not consider ERROR_END_OF_STREAM an error
2023    if (err != OK && err != ERROR_END_OF_STREAM) {
2024        notify(MEDIA_RECORDER_EVENT_ERROR,
2025               trackNum | MEDIA_RECORDER_ERROR_UNKNOWN,
2026               err);
2027        return;
2028    }
2029
2030    if (timeUs == -1) {
2031        // Send completion notification
2032        notify(MEDIA_RECORDER_EVENT_INFO,
2033               trackNum | MEDIA_RECORDER_INFO_COMPLETION_STATUS,
2034               err);
2035        return;
2036    } else {
2037        // Send progress status
2038        notify(MEDIA_RECORDER_EVENT_INFO,
2039               trackNum | MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS,
2040               timeUs / 1000);
2041    }
2042}
2043
2044void MPEG4Writer::setDriftTimeUs(int64_t driftTimeUs) {
2045    LOGV("setDriftTimeUs: %lld us", driftTimeUs);
2046    Mutex::Autolock autolock(mLock);
2047    mDriftTimeUs = driftTimeUs;
2048}
2049
2050int64_t MPEG4Writer::getDriftTimeUs() {
2051    LOGV("getDriftTimeUs: %lld us", mDriftTimeUs);
2052    Mutex::Autolock autolock(mLock);
2053    return mDriftTimeUs;
2054}
2055
2056bool MPEG4Writer::useNalLengthFour() {
2057    return mUse4ByteNalLength;
2058}
2059
2060void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) {
2061    LOGV("bufferChunk");
2062
2063    Chunk chunk(this, timestampUs, mChunkSamples);
2064    mOwner->bufferChunk(chunk);
2065    mChunkSamples.clear();
2066}
2067
2068int64_t MPEG4Writer::Track::getDurationUs() const {
2069    return mTrackDurationUs;
2070}
2071
2072int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const {
2073    return mEstimatedTrackSizeBytes;
2074}
2075
2076status_t MPEG4Writer::Track::checkCodecSpecificData() const {
2077    const char *mime;
2078    CHECK(mMeta->findCString(kKeyMIMEType, &mime));
2079    if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime) ||
2080        !strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime) ||
2081        !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
2082        if (!mCodecSpecificData ||
2083            mCodecSpecificDataSize <= 0) {
2084            LOGE("Missing codec specific data");
2085            return ERROR_MALFORMED;
2086        }
2087    } else {
2088        if (mCodecSpecificData ||
2089            mCodecSpecificDataSize > 0) {
2090            LOGE("Unexepected codec specific data found");
2091            return ERROR_MALFORMED;
2092        }
2093    }
2094    return OK;
2095}
2096
2097void MPEG4Writer::Track::writeTrackHeader(
2098        int32_t trackID, bool use32BitOffset) {
2099    const char *mime;
2100    bool success = mMeta->findCString(kKeyMIMEType, &mime);
2101    CHECK(success);
2102
2103    LOGV("%s track time scale: %d",
2104        mIsAudio? "Audio": "Video", mTimeScale);
2105
2106    time_t now = time(NULL);
2107    int32_t mvhdTimeScale = mOwner->getTimeScale();
2108    int64_t trakDurationUs = getDurationUs();
2109
2110    mOwner->beginBox("trak");
2111
2112      mOwner->beginBox("tkhd");
2113        // Flags = 7 to indicate that the track is enabled, and
2114        // part of the presentation
2115        mOwner->writeInt32(0x07);          // version=0, flags=7
2116        mOwner->writeInt32(now);           // creation time
2117        mOwner->writeInt32(now);           // modification time
2118        mOwner->writeInt32(trackID);
2119        mOwner->writeInt32(0);             // reserved
2120        int32_t tkhdDuration =
2121            (trakDurationUs * mvhdTimeScale + 5E5) / 1E6;
2122        mOwner->writeInt32(tkhdDuration);  // in mvhd timescale
2123        mOwner->writeInt32(0);             // reserved
2124        mOwner->writeInt32(0);             // reserved
2125        mOwner->writeInt16(0);             // layer
2126        mOwner->writeInt16(0);             // alternate group
2127        mOwner->writeInt16(mIsAudio ? 0x100 : 0);  // volume
2128        mOwner->writeInt16(0);             // reserved
2129
2130        mOwner->writeCompositionMatrix(mRotation);       // matrix
2131
2132        if (mIsAudio) {
2133            mOwner->writeInt32(0);
2134            mOwner->writeInt32(0);
2135        } else {
2136            int32_t width, height;
2137            bool success = mMeta->findInt32(kKeyWidth, &width);
2138            success = success && mMeta->findInt32(kKeyHeight, &height);
2139            CHECK(success);
2140
2141            mOwner->writeInt32(width << 16);   // 32-bit fixed-point value
2142            mOwner->writeInt32(height << 16);  // 32-bit fixed-point value
2143        }
2144      mOwner->endBox();  // tkhd
2145
2146      int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
2147      if (mStartTimestampUs != moovStartTimeUs) {
2148        mOwner->beginBox("edts");
2149          mOwner->beginBox("elst");
2150            mOwner->writeInt32(0);           // version=0, flags=0: 32-bit time
2151            mOwner->writeInt32(2);           // never ends with an empty list
2152
2153            // First elst entry: specify the starting time offset
2154            int64_t offsetUs = mStartTimestampUs - moovStartTimeUs;
2155            LOGV("OffsetUs: %lld", offsetUs);
2156            int32_t seg = (offsetUs * mvhdTimeScale + 5E5) / 1E6;
2157            mOwner->writeInt32(seg);         // in mvhd timecale
2158            mOwner->writeInt32(-1);          // starting time offset
2159            mOwner->writeInt32(1 << 16);     // rate = 1.0
2160
2161            // Second elst entry: specify the track duration
2162            seg = (trakDurationUs * mvhdTimeScale + 5E5) / 1E6;
2163            mOwner->writeInt32(seg);         // in mvhd timescale
2164            mOwner->writeInt32(0);
2165            mOwner->writeInt32(1 << 16);
2166          mOwner->endBox();
2167        mOwner->endBox();
2168      }
2169
2170      mOwner->beginBox("mdia");
2171
2172        mOwner->beginBox("mdhd");
2173          mOwner->writeInt32(0);             // version=0, flags=0
2174          mOwner->writeInt32(now);           // creation time
2175          mOwner->writeInt32(now);           // modification time
2176          mOwner->writeInt32(mTimeScale);    // media timescale
2177          int32_t mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6;
2178          mOwner->writeInt32(mdhdDuration);  // use media timescale
2179          // Language follows the three letter standard ISO-639-2/T
2180          // 'e', 'n', 'g' for "English", for instance.
2181          // Each character is packed as the difference between its ASCII value and 0x60.
2182          // For "English", these are 00101, 01110, 00111.
2183          // XXX: Where is the padding bit located: 0x15C7?
2184          mOwner->writeInt16(0);             // language code
2185          mOwner->writeInt16(0);             // predefined
2186        mOwner->endBox();
2187
2188        mOwner->beginBox("hdlr");
2189          mOwner->writeInt32(0);             // version=0, flags=0
2190          mOwner->writeInt32(0);             // component type: should be mhlr
2191          mOwner->writeFourcc(mIsAudio ? "soun" : "vide");  // component subtype
2192          mOwner->writeInt32(0);             // reserved
2193          mOwner->writeInt32(0);             // reserved
2194          mOwner->writeInt32(0);             // reserved
2195          // Removing "r" for the name string just makes the string 4 byte aligned
2196          mOwner->writeCString(mIsAudio ? "SoundHandle": "VideoHandle");  // name
2197        mOwner->endBox();
2198
2199        mOwner->beginBox("minf");
2200          if (mIsAudio) {
2201              mOwner->beginBox("smhd");
2202              mOwner->writeInt32(0);           // version=0, flags=0
2203              mOwner->writeInt16(0);           // balance
2204              mOwner->writeInt16(0);           // reserved
2205              mOwner->endBox();
2206          } else {
2207              mOwner->beginBox("vmhd");
2208              mOwner->writeInt32(0x01);        // version=0, flags=1
2209              mOwner->writeInt16(0);           // graphics mode
2210              mOwner->writeInt16(0);           // opcolor
2211              mOwner->writeInt16(0);
2212              mOwner->writeInt16(0);
2213              mOwner->endBox();
2214          }
2215
2216          mOwner->beginBox("dinf");
2217            mOwner->beginBox("dref");
2218              mOwner->writeInt32(0);  // version=0, flags=0
2219              mOwner->writeInt32(1);  // entry count (either url or urn)
2220              // The table index here refers to the sample description index
2221              // in the sample table entries.
2222              mOwner->beginBox("url ");
2223                mOwner->writeInt32(1);  // version=0, flags=1 (self-contained)
2224              mOwner->endBox();  // url
2225            mOwner->endBox();  // dref
2226          mOwner->endBox();  // dinf
2227
2228        mOwner->beginBox("stbl");
2229
2230          mOwner->beginBox("stsd");
2231            mOwner->writeInt32(0);               // version=0, flags=0
2232            mOwner->writeInt32(1);               // entry count
2233            if (mIsAudio) {
2234                const char *fourcc = NULL;
2235                if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
2236                    fourcc = "samr";
2237                } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
2238                    fourcc = "sawb";
2239                } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
2240                    fourcc = "mp4a";
2241                } else {
2242                    LOGE("Unknown mime type '%s'.", mime);
2243                    CHECK(!"should not be here, unknown mime type.");
2244                }
2245
2246                mOwner->beginBox(fourcc);          // audio format
2247                  mOwner->writeInt32(0);           // reserved
2248                  mOwner->writeInt16(0);           // reserved
2249                  mOwner->writeInt16(0x1);         // data ref index
2250                  mOwner->writeInt32(0);           // reserved
2251                  mOwner->writeInt32(0);           // reserved
2252                  int32_t nChannels;
2253                  CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels));
2254                  mOwner->writeInt16(nChannels);   // channel count
2255                  mOwner->writeInt16(16);          // sample size
2256                  mOwner->writeInt16(0);           // predefined
2257                  mOwner->writeInt16(0);           // reserved
2258
2259                  int32_t samplerate;
2260                  bool success = mMeta->findInt32(kKeySampleRate, &samplerate);
2261                  CHECK(success);
2262                  mOwner->writeInt32(samplerate << 16);
2263                  if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
2264                    mOwner->beginBox("esds");
2265                        CHECK(mCodecSpecificData);
2266                        CHECK(mCodecSpecificDataSize > 0);
2267
2268                        // Make sure all sizes encode to a single byte.
2269                        CHECK(mCodecSpecificDataSize + 23 < 128);
2270
2271                        mOwner->writeInt32(0);     // version=0, flags=0
2272                        mOwner->writeInt8(0x03);   // ES_DescrTag
2273                        mOwner->writeInt8(23 + mCodecSpecificDataSize);
2274                        mOwner->writeInt16(0x0000);// ES_ID
2275                        mOwner->writeInt8(0x00);
2276
2277                        mOwner->writeInt8(0x04);   // DecoderConfigDescrTag
2278                        mOwner->writeInt8(15 + mCodecSpecificDataSize);
2279                        mOwner->writeInt8(0x40);   // objectTypeIndication ISO/IEC 14492-2
2280                        mOwner->writeInt8(0x15);   // streamType AudioStream
2281
2282                        mOwner->writeInt16(0x03);  // XXX
2283                        mOwner->writeInt8(0x00);   // buffer size 24-bit
2284                        mOwner->writeInt32(96000); // max bit rate
2285                        mOwner->writeInt32(96000); // avg bit rate
2286
2287                        mOwner->writeInt8(0x05);   // DecoderSpecificInfoTag
2288                        mOwner->writeInt8(mCodecSpecificDataSize);
2289                        mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
2290
2291                        static const uint8_t kData2[] = {
2292                            0x06,  // SLConfigDescriptorTag
2293                            0x01,
2294                            0x02
2295                        };
2296                        mOwner->write(kData2, sizeof(kData2));
2297
2298                    mOwner->endBox();  // esds
2299                  } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime) ||
2300                             !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
2301                    // 3gpp2 Spec AMRSampleEntry fields
2302                    mOwner->beginBox("damr");
2303                      mOwner->writeCString("   ");  // vendor: 4 bytes
2304                      mOwner->writeInt8(0);         // decoder version
2305                      mOwner->writeInt16(0x83FF);   // mode set: all enabled
2306                      mOwner->writeInt8(0);         // mode change period
2307                      mOwner->writeInt8(1);         // frames per sample
2308                    mOwner->endBox();
2309                  }
2310                mOwner->endBox();
2311            } else {
2312                if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
2313                    mOwner->beginBox("mp4v");
2314                } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
2315                    mOwner->beginBox("s263");
2316                } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
2317                    mOwner->beginBox("avc1");
2318                } else {
2319                    LOGE("Unknown mime type '%s'.", mime);
2320                    CHECK(!"should not be here, unknown mime type.");
2321                }
2322
2323                  mOwner->writeInt32(0);           // reserved
2324                  mOwner->writeInt16(0);           // reserved
2325                  mOwner->writeInt16(1);           // data ref index
2326                  mOwner->writeInt16(0);           // predefined
2327                  mOwner->writeInt16(0);           // reserved
2328                  mOwner->writeInt32(0);           // predefined
2329                  mOwner->writeInt32(0);           // predefined
2330                  mOwner->writeInt32(0);           // predefined
2331
2332                  int32_t width, height;
2333                  bool success = mMeta->findInt32(kKeyWidth, &width);
2334                  success = success && mMeta->findInt32(kKeyHeight, &height);
2335                  CHECK(success);
2336
2337                  mOwner->writeInt16(width);
2338                  mOwner->writeInt16(height);
2339                  mOwner->writeInt32(0x480000);    // horiz resolution
2340                  mOwner->writeInt32(0x480000);    // vert resolution
2341                  mOwner->writeInt32(0);           // reserved
2342                  mOwner->writeInt16(1);           // frame count
2343                  mOwner->write("                                ", 32);
2344                  mOwner->writeInt16(0x18);        // depth
2345                  mOwner->writeInt16(-1);          // predefined
2346
2347                  CHECK(23 + mCodecSpecificDataSize < 128);
2348
2349                  if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
2350                      CHECK(mCodecSpecificData);
2351                      CHECK(mCodecSpecificDataSize > 0);
2352                      mOwner->beginBox("esds");
2353
2354                        mOwner->writeInt32(0);           // version=0, flags=0
2355
2356                        mOwner->writeInt8(0x03);  // ES_DescrTag
2357                        mOwner->writeInt8(23 + mCodecSpecificDataSize);
2358                        mOwner->writeInt16(0x0000);  // ES_ID
2359                        mOwner->writeInt8(0x1f);
2360
2361                        mOwner->writeInt8(0x04);  // DecoderConfigDescrTag
2362                        mOwner->writeInt8(15 + mCodecSpecificDataSize);
2363                        mOwner->writeInt8(0x20);  // objectTypeIndication ISO/IEC 14492-2
2364                        mOwner->writeInt8(0x11);  // streamType VisualStream
2365
2366                        static const uint8_t kData[] = {
2367                            0x01, 0x77, 0x00,
2368                            0x00, 0x03, 0xe8, 0x00,
2369                            0x00, 0x03, 0xe8, 0x00
2370                        };
2371                        mOwner->write(kData, sizeof(kData));
2372
2373                        mOwner->writeInt8(0x05);  // DecoderSpecificInfoTag
2374
2375                        mOwner->writeInt8(mCodecSpecificDataSize);
2376                        mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
2377
2378                        static const uint8_t kData2[] = {
2379                            0x06,  // SLConfigDescriptorTag
2380                            0x01,
2381                            0x02
2382                        };
2383                        mOwner->write(kData2, sizeof(kData2));
2384
2385                      mOwner->endBox();  // esds
2386                  } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
2387                      mOwner->beginBox("d263");
2388
2389                          mOwner->writeInt32(0);  // vendor
2390                          mOwner->writeInt8(0);   // decoder version
2391                          mOwner->writeInt8(10);  // level: 10
2392                          mOwner->writeInt8(0);   // profile: 0
2393
2394                      mOwner->endBox();  // d263
2395                  } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
2396                      CHECK(mCodecSpecificData);
2397                      CHECK(mCodecSpecificDataSize >= 5);
2398
2399                      // Patch avcc's lengthSize field to match the number
2400                      // of bytes we use to indicate the size of a nal unit.
2401                      uint8_t *ptr = (uint8_t *)mCodecSpecificData;
2402                      ptr[4] =
2403                          (ptr[4] & 0xfc)
2404                            | (mOwner->useNalLengthFour() ? 3 : 1);
2405
2406                      mOwner->beginBox("avcC");
2407                        mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
2408                      mOwner->endBox();  // avcC
2409                  }
2410
2411                  mOwner->beginBox("pasp");
2412                    // This is useful if the pixel is not square
2413                    mOwner->writeInt32(1 << 16);  // hspacing
2414                    mOwner->writeInt32(1 << 16);  // vspacing
2415                  mOwner->endBox();  // pasp
2416                mOwner->endBox();  // mp4v, s263 or avc1
2417            }
2418          mOwner->endBox();  // stsd
2419
2420          mOwner->beginBox("stts");
2421            mOwner->writeInt32(0);  // version=0, flags=0
2422            mOwner->writeInt32(mNumSttsTableEntries);
2423            int64_t prevTimestampUs = 0;
2424            for (List<SttsTableEntry>::iterator it = mSttsTableEntries.begin();
2425                 it != mSttsTableEntries.end(); ++it) {
2426                mOwner->writeInt32(it->sampleCount);
2427
2428                // Make sure that we are calculating the sample duration the exactly
2429                // same way as we made decision on how to create stts entries.
2430                int64_t currTimestampUs = prevTimestampUs + it->sampleDurationUs;
2431                int32_t dur = ((currTimestampUs * mTimeScale + 500000LL) / 1000000LL -
2432                               (prevTimestampUs * mTimeScale + 500000LL) / 1000000LL);
2433                prevTimestampUs += (it->sampleCount * it->sampleDurationUs);
2434
2435                mOwner->writeInt32(dur);
2436            }
2437          mOwner->endBox();  // stts
2438
2439          if (!mIsAudio) {
2440            mOwner->beginBox("stss");
2441              mOwner->writeInt32(0);  // version=0, flags=0
2442              mOwner->writeInt32(mNumStssTableEntries);  // number of sync frames
2443              for (List<int32_t>::iterator it = mStssTableEntries.begin();
2444                   it != mStssTableEntries.end(); ++it) {
2445                  mOwner->writeInt32(*it);
2446              }
2447            mOwner->endBox();  // stss
2448          }
2449
2450          mOwner->beginBox("stsz");
2451            mOwner->writeInt32(0);  // version=0, flags=0
2452            if (mSamplesHaveSameSize) {
2453                List<size_t>::iterator it = mSampleSizes.begin();
2454                mOwner->writeInt32(*it);  // default sample size
2455            } else {
2456                mOwner->writeInt32(0);
2457            }
2458            mOwner->writeInt32(mNumSamples);
2459            if (!mSamplesHaveSameSize) {
2460                for (List<size_t>::iterator it = mSampleSizes.begin();
2461                     it != mSampleSizes.end(); ++it) {
2462                    mOwner->writeInt32(*it);
2463                }
2464            }
2465          mOwner->endBox();  // stsz
2466
2467          mOwner->beginBox("stsc");
2468            mOwner->writeInt32(0);  // version=0, flags=0
2469            mOwner->writeInt32(mNumStscTableEntries);
2470            for (List<StscTableEntry>::iterator it = mStscTableEntries.begin();
2471                 it != mStscTableEntries.end(); ++it) {
2472                mOwner->writeInt32(it->firstChunk);
2473                mOwner->writeInt32(it->samplesPerChunk);
2474                mOwner->writeInt32(it->sampleDescriptionId);
2475            }
2476          mOwner->endBox();  // stsc
2477          mOwner->beginBox(use32BitOffset? "stco": "co64");
2478            mOwner->writeInt32(0);  // version=0, flags=0
2479            mOwner->writeInt32(mNumStcoTableEntries);
2480            for (List<off_t>::iterator it = mChunkOffsets.begin();
2481                 it != mChunkOffsets.end(); ++it) {
2482                if (use32BitOffset) {
2483                    mOwner->writeInt32(static_cast<int32_t>(*it));
2484                } else {
2485                    mOwner->writeInt64((*it));
2486                }
2487            }
2488          mOwner->endBox();  // stco or co64
2489
2490        mOwner->endBox();  // stbl
2491       mOwner->endBox();  // minf
2492      mOwner->endBox();  // mdia
2493    mOwner->endBox();  // trak
2494}
2495
2496}  // namespace android
2497