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