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