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