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