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