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