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