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