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