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