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 
     20 #include <arpa/inet.h>
     21 #include <fcntl.h>
     22 #include <inttypes.h>
     23 #include <pthread.h>
     24 #include <sys/prctl.h>
     25 #include <sys/stat.h>
     26 #include <sys/types.h>
     27 #include <unistd.h>
     28 
     29 #include <utils/Log.h>
     30 
     31 #include <media/stagefright/foundation/ADebug.h>
     32 #include <media/stagefright/MPEG4Writer.h>
     33 #include <media/stagefright/MediaBuffer.h>
     34 #include <media/stagefright/MetaData.h>
     35 #include <media/stagefright/MediaDefs.h>
     36 #include <media/stagefright/MediaErrors.h>
     37 #include <media/stagefright/MediaSource.h>
     38 #include <media/stagefright/Utils.h>
     39 #include <media/mediarecorder.h>
     40 #include <cutils/properties.h>
     41 
     42 #include "include/ESDS.h"
     43 
     44 
     45 #ifndef __predict_false
     46 #define __predict_false(exp) __builtin_expect((exp) != 0, 0)
     47 #endif
     48 
     49 #define WARN_UNLESS(condition, message, ...) \
     50 ( (__predict_false(condition)) ? false : ({ \
     51     ALOGW("Condition %s failed "  message, #condition, ##__VA_ARGS__); \
     52     true; \
     53 }))
     54 
     55 namespace android {
     56 
     57 static const int64_t kMinStreamableFileSizeInBytes = 5 * 1024 * 1024;
     58 static const int64_t kMax32BitFileSize = 0x00ffffffffLL; // 2^32-1 : max FAT32
     59                                                          // filesystem file size
     60                                                          // used by most SD cards
     61 static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
     62 static const uint8_t kNalUnitTypePicParamSet = 0x08;
     63 static const int64_t kInitialDelayTimeUs     = 700000LL;
     64 
     65 class MPEG4Writer::Track {
     66 public:
     67     Track(MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId);
     68 
     69     ~Track();
     70 
     71     status_t start(MetaData *params);
     72     status_t stop();
     73     status_t pause();
     74     bool reachedEOS();
     75 
     76     int64_t getDurationUs() const;
     77     int64_t getEstimatedTrackSizeBytes() const;
     78     void writeTrackHeader(bool use32BitOffset = true);
     79     void bufferChunk(int64_t timestampUs);
     80     bool isAvc() const { return mIsAvc; }
     81     bool isAudio() const { return mIsAudio; }
     82     bool isMPEG4() const { return mIsMPEG4; }
     83     void addChunkOffset(off64_t offset);
     84     int32_t getTrackId() const { return mTrackId; }
     85     status_t dump(int fd, const Vector<String16>& args) const;
     86 
     87 private:
     88     enum {
     89         kMaxCttsOffsetTimeUs = 1000000LL,  // 1 second
     90         kSampleArraySize = 1000,
     91     };
     92 
     93     // A helper class to handle faster write box with table entries
     94     template<class TYPE>
     95     struct ListTableEntries {
     96         ListTableEntries(uint32_t elementCapacity, uint32_t entryCapacity)
     97             : mElementCapacity(elementCapacity),
     98             mEntryCapacity(entryCapacity),
     99             mTotalNumTableEntries(0),
    100             mNumValuesInCurrEntry(0),
    101             mCurrTableEntriesElement(NULL) {
    102             CHECK_GT(mElementCapacity, 0);
    103             CHECK_GT(mEntryCapacity, 0);
    104         }
    105 
    106         // Free the allocated memory.
    107         ~ListTableEntries() {
    108             while (!mTableEntryList.empty()) {
    109                 typename List<TYPE *>::iterator it = mTableEntryList.begin();
    110                 delete[] (*it);
    111                 mTableEntryList.erase(it);
    112             }
    113         }
    114 
    115         // Replace the value at the given position by the given value.
    116         // There must be an existing value at the given position.
    117         // @arg value must be in network byte order
    118         // @arg pos location the value must be in.
    119         void set(const TYPE& value, uint32_t pos) {
    120             CHECK_LT(pos, mTotalNumTableEntries * mEntryCapacity);
    121 
    122             typename List<TYPE *>::iterator it = mTableEntryList.begin();
    123             uint32_t iterations = (pos / (mElementCapacity * mEntryCapacity));
    124             while (it != mTableEntryList.end() && iterations > 0) {
    125                 ++it;
    126                 --iterations;
    127             }
    128             CHECK(it != mTableEntryList.end());
    129             CHECK_EQ(iterations, 0);
    130 
    131             (*it)[(pos % (mElementCapacity * mEntryCapacity))] = value;
    132         }
    133 
    134         // Get the value at the given position by the given value.
    135         // @arg value the retrieved value at the position in network byte order.
    136         // @arg pos location the value must be in.
    137         // @return true if a value is found.
    138         bool get(TYPE& value, uint32_t pos) const {
    139             if (pos >= mTotalNumTableEntries * mEntryCapacity) {
    140                 return false;
    141             }
    142 
    143             typename List<TYPE *>::iterator it = mTableEntryList.begin();
    144             uint32_t iterations = (pos / (mElementCapacity * mEntryCapacity));
    145             while (it != mTableEntryList.end() && iterations > 0) {
    146                 ++it;
    147                 --iterations;
    148             }
    149             CHECK(it != mTableEntryList.end());
    150             CHECK_EQ(iterations, 0);
    151 
    152             value = (*it)[(pos % (mElementCapacity * mEntryCapacity))];
    153             return true;
    154         }
    155 
    156         // Store a single value.
    157         // @arg value must be in network byte order.
    158         void add(const TYPE& value) {
    159             CHECK_LT(mNumValuesInCurrEntry, mElementCapacity);
    160             uint32_t nEntries = mTotalNumTableEntries % mElementCapacity;
    161             uint32_t nValues  = mNumValuesInCurrEntry % mEntryCapacity;
    162             if (nEntries == 0 && nValues == 0) {
    163                 mCurrTableEntriesElement = new TYPE[mEntryCapacity * mElementCapacity];
    164                 CHECK(mCurrTableEntriesElement != NULL);
    165                 mTableEntryList.push_back(mCurrTableEntriesElement);
    166             }
    167 
    168             uint32_t pos = nEntries * mEntryCapacity + nValues;
    169             mCurrTableEntriesElement[pos] = value;
    170 
    171             ++mNumValuesInCurrEntry;
    172             if ((mNumValuesInCurrEntry % mEntryCapacity) == 0) {
    173                 ++mTotalNumTableEntries;
    174                 mNumValuesInCurrEntry = 0;
    175             }
    176         }
    177 
    178         // Write out the table entries:
    179         // 1. the number of entries goes first
    180         // 2. followed by the values in the table enties in order
    181         // @arg writer the writer to actual write to the storage
    182         void write(MPEG4Writer *writer) const {
    183             CHECK_EQ(mNumValuesInCurrEntry % mEntryCapacity, 0);
    184             uint32_t nEntries = mTotalNumTableEntries;
    185             writer->writeInt32(nEntries);
    186             for (typename List<TYPE *>::iterator it = mTableEntryList.begin();
    187                 it != mTableEntryList.end(); ++it) {
    188                 CHECK_GT(nEntries, 0);
    189                 if (nEntries >= mElementCapacity) {
    190                     writer->write(*it, sizeof(TYPE) * mEntryCapacity, mElementCapacity);
    191                     nEntries -= mElementCapacity;
    192                 } else {
    193                     writer->write(*it, sizeof(TYPE) * mEntryCapacity, nEntries);
    194                     break;
    195                 }
    196             }
    197         }
    198 
    199         // Return the number of entries in the table.
    200         uint32_t count() const { return mTotalNumTableEntries; }
    201 
    202     private:
    203         uint32_t         mElementCapacity;  // # entries in an element
    204         uint32_t         mEntryCapacity;    // # of values in each entry
    205         uint32_t         mTotalNumTableEntries;
    206         uint32_t         mNumValuesInCurrEntry;  // up to mEntryCapacity
    207         TYPE             *mCurrTableEntriesElement;
    208         mutable List<TYPE *>     mTableEntryList;
    209 
    210         DISALLOW_EVIL_CONSTRUCTORS(ListTableEntries);
    211     };
    212 
    213 
    214 
    215     MPEG4Writer *mOwner;
    216     sp<MetaData> mMeta;
    217     sp<MediaSource> mSource;
    218     volatile bool mDone;
    219     volatile bool mPaused;
    220     volatile bool mResumed;
    221     volatile bool mStarted;
    222     bool mIsAvc;
    223     bool mIsAudio;
    224     bool mIsMPEG4;
    225     int32_t mTrackId;
    226     int64_t mTrackDurationUs;
    227     int64_t mMaxChunkDurationUs;
    228 
    229     int64_t mEstimatedTrackSizeBytes;
    230     int64_t mMdatSizeBytes;
    231     int32_t mTimeScale;
    232 
    233     pthread_t mThread;
    234 
    235 
    236     List<MediaBuffer *> mChunkSamples;
    237 
    238     bool                mSamplesHaveSameSize;
    239     ListTableEntries<uint32_t> *mStszTableEntries;
    240 
    241     ListTableEntries<uint32_t> *mStcoTableEntries;
    242     ListTableEntries<off64_t> *mCo64TableEntries;
    243     ListTableEntries<uint32_t> *mStscTableEntries;
    244     ListTableEntries<uint32_t> *mStssTableEntries;
    245     ListTableEntries<uint32_t> *mSttsTableEntries;
    246     ListTableEntries<uint32_t> *mCttsTableEntries;
    247 
    248     int64_t mMinCttsOffsetTimeUs;
    249     int64_t mMaxCttsOffsetTimeUs;
    250 
    251     // Sequence parameter set or picture parameter set
    252     struct AVCParamSet {
    253         AVCParamSet(uint16_t length, const uint8_t *data)
    254             : mLength(length), mData(data) {}
    255 
    256         uint16_t mLength;
    257         const uint8_t *mData;
    258     };
    259     List<AVCParamSet> mSeqParamSets;
    260     List<AVCParamSet> mPicParamSets;
    261     uint8_t mProfileIdc;
    262     uint8_t mProfileCompatible;
    263     uint8_t mLevelIdc;
    264 
    265     void *mCodecSpecificData;
    266     size_t mCodecSpecificDataSize;
    267     bool mGotAllCodecSpecificData;
    268     bool mTrackingProgressStatus;
    269 
    270     bool mReachedEOS;
    271     int64_t mStartTimestampUs;
    272     int64_t mStartTimeRealUs;
    273     int64_t mFirstSampleTimeRealUs;
    274     int64_t mPreviousTrackTimeUs;
    275     int64_t mTrackEveryTimeDurationUs;
    276 
    277     // Update the audio track's drift information.
    278     void updateDriftTime(const sp<MetaData>& meta);
    279 
    280     int32_t getStartTimeOffsetScaledTime() const;
    281 
    282     static void *ThreadWrapper(void *me);
    283     status_t threadEntry();
    284 
    285     const uint8_t *parseParamSet(
    286         const uint8_t *data, size_t length, int type, size_t *paramSetLen);
    287 
    288     status_t makeAVCCodecSpecificData(const uint8_t *data, size_t size);
    289     status_t copyAVCCodecSpecificData(const uint8_t *data, size_t size);
    290     status_t parseAVCCodecSpecificData(const uint8_t *data, size_t size);
    291 
    292     // Track authoring progress status
    293     void trackProgressStatus(int64_t timeUs, status_t err = OK);
    294     void initTrackingProgressStatus(MetaData *params);
    295 
    296     void getCodecSpecificDataFromInputFormatIfPossible();
    297 
    298     // Determine the track time scale
    299     // If it is an audio track, try to use the sampling rate as
    300     // the time scale; however, if user chooses the overwrite
    301     // value, the user-supplied time scale will be used.
    302     void setTimeScale();
    303 
    304     // Simple validation on the codec specific data
    305     status_t checkCodecSpecificData() const;
    306     int32_t mRotation;
    307 
    308     void updateTrackSizeEstimate();
    309     void addOneStscTableEntry(size_t chunkId, size_t sampleId);
    310     void addOneStssTableEntry(size_t sampleId);
    311 
    312     // Duration is time scale based
    313     void addOneSttsTableEntry(size_t sampleCount, int32_t timescaledDur);
    314     void addOneCttsTableEntry(size_t sampleCount, int32_t timescaledDur);
    315 
    316     bool isTrackMalFormed() const;
    317     void sendTrackSummary(bool hasMultipleTracks);
    318 
    319     // Write the boxes
    320     void writeStcoBox(bool use32BitOffset);
    321     void writeStscBox();
    322     void writeStszBox();
    323     void writeStssBox();
    324     void writeSttsBox();
    325     void writeCttsBox();
    326     void writeD263Box();
    327     void writePaspBox();
    328     void writeAvccBox();
    329     void writeUrlBox();
    330     void writeDrefBox();
    331     void writeDinfBox();
    332     void writeDamrBox();
    333     void writeMdhdBox(uint32_t now);
    334     void writeSmhdBox();
    335     void writeVmhdBox();
    336     void writeHdlrBox();
    337     void writeTkhdBox(uint32_t now);
    338     void writeMp4aEsdsBox();
    339     void writeMp4vEsdsBox();
    340     void writeAudioFourCCBox();
    341     void writeVideoFourCCBox();
    342     void writeStblBox(bool use32BitOffset);
    343 
    344     Track(const Track &);
    345     Track &operator=(const Track &);
    346 };
    347 
    348 MPEG4Writer::MPEG4Writer(const char *filename)
    349     : mFd(-1),
    350       mInitCheck(NO_INIT),
    351       mIsRealTimeRecording(true),
    352       mUse4ByteNalLength(true),
    353       mUse32BitOffset(true),
    354       mIsFileSizeLimitExplicitlyRequested(false),
    355       mPaused(false),
    356       mStarted(false),
    357       mWriterThreadStarted(false),
    358       mOffset(0),
    359       mMdatOffset(0),
    360       mEstimatedMoovBoxSize(0),
    361       mInterleaveDurationUs(1000000),
    362       mLatitudex10000(0),
    363       mLongitudex10000(0),
    364       mAreGeoTagsAvailable(false),
    365       mStartTimeOffsetMs(-1) {
    366 
    367     mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
    368     if (mFd >= 0) {
    369         mInitCheck = OK;
    370     }
    371 }
    372 
    373 MPEG4Writer::MPEG4Writer(int fd)
    374     : mFd(dup(fd)),
    375       mInitCheck(mFd < 0? NO_INIT: OK),
    376       mIsRealTimeRecording(true),
    377       mUse4ByteNalLength(true),
    378       mUse32BitOffset(true),
    379       mIsFileSizeLimitExplicitlyRequested(false),
    380       mPaused(false),
    381       mStarted(false),
    382       mWriterThreadStarted(false),
    383       mOffset(0),
    384       mMdatOffset(0),
    385       mEstimatedMoovBoxSize(0),
    386       mInterleaveDurationUs(1000000),
    387       mLatitudex10000(0),
    388       mLongitudex10000(0),
    389       mAreGeoTagsAvailable(false),
    390       mStartTimeOffsetMs(-1) {
    391 }
    392 
    393 MPEG4Writer::~MPEG4Writer() {
    394     reset();
    395 
    396     while (!mTracks.empty()) {
    397         List<Track *>::iterator it = mTracks.begin();
    398         delete *it;
    399         (*it) = NULL;
    400         mTracks.erase(it);
    401     }
    402     mTracks.clear();
    403 }
    404 
    405 status_t MPEG4Writer::dump(
    406         int fd, const Vector<String16>& args) {
    407     const size_t SIZE = 256;
    408     char buffer[SIZE];
    409     String8 result;
    410     snprintf(buffer, SIZE, "   MPEG4Writer %p\n", this);
    411     result.append(buffer);
    412     snprintf(buffer, SIZE, "     mStarted: %s\n", mStarted? "true": "false");
    413     result.append(buffer);
    414     ::write(fd, result.string(), result.size());
    415     for (List<Track *>::iterator it = mTracks.begin();
    416          it != mTracks.end(); ++it) {
    417         (*it)->dump(fd, args);
    418     }
    419     return OK;
    420 }
    421 
    422 status_t MPEG4Writer::Track::dump(
    423         int fd, const Vector<String16>& /* args */) const {
    424     const size_t SIZE = 256;
    425     char buffer[SIZE];
    426     String8 result;
    427     snprintf(buffer, SIZE, "     %s track\n", mIsAudio? "Audio": "Video");
    428     result.append(buffer);
    429     snprintf(buffer, SIZE, "       reached EOS: %s\n",
    430             mReachedEOS? "true": "false");
    431     result.append(buffer);
    432     snprintf(buffer, SIZE, "       frames encoded : %d\n", mStszTableEntries->count());
    433     result.append(buffer);
    434     snprintf(buffer, SIZE, "       duration encoded : %" PRId64 " us\n", mTrackDurationUs);
    435     result.append(buffer);
    436     ::write(fd, result.string(), result.size());
    437     return OK;
    438 }
    439 
    440 status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
    441     Mutex::Autolock l(mLock);
    442     if (mStarted) {
    443         ALOGE("Attempt to add source AFTER recording is started");
    444         return UNKNOWN_ERROR;
    445     }
    446 
    447     // At most 2 tracks can be supported.
    448     if (mTracks.size() >= 2) {
    449         ALOGE("Too many tracks (%zu) to add", mTracks.size());
    450         return ERROR_UNSUPPORTED;
    451     }
    452 
    453     CHECK(source.get() != NULL);
    454 
    455     // A track of type other than video or audio is not supported.
    456     const char *mime;
    457     source->getFormat()->findCString(kKeyMIMEType, &mime);
    458     bool isAudio = !strncasecmp(mime, "audio/", 6);
    459     bool isVideo = !strncasecmp(mime, "video/", 6);
    460     if (!isAudio && !isVideo) {
    461         ALOGE("Track (%s) other than video or audio is not supported",
    462             mime);
    463         return ERROR_UNSUPPORTED;
    464     }
    465 
    466     // At this point, we know the track to be added is either
    467     // video or audio. Thus, we only need to check whether it
    468     // is an audio track or not (if it is not, then it must be
    469     // a video track).
    470 
    471     // No more than one video or one audio track is supported.
    472     for (List<Track*>::iterator it = mTracks.begin();
    473          it != mTracks.end(); ++it) {
    474         if ((*it)->isAudio() == isAudio) {
    475             ALOGE("%s track already exists", isAudio? "Audio": "Video");
    476             return ERROR_UNSUPPORTED;
    477         }
    478     }
    479 
    480     // This is the first track of either audio or video.
    481     // Go ahead to add the track.
    482     Track *track = new Track(this, source, 1 + mTracks.size());
    483     mTracks.push_back(track);
    484 
    485     return OK;
    486 }
    487 
    488 status_t MPEG4Writer::startTracks(MetaData *params) {
    489     if (mTracks.empty()) {
    490         ALOGE("No source added");
    491         return INVALID_OPERATION;
    492     }
    493 
    494     for (List<Track *>::iterator it = mTracks.begin();
    495          it != mTracks.end(); ++it) {
    496         status_t err = (*it)->start(params);
    497 
    498         if (err != OK) {
    499             for (List<Track *>::iterator it2 = mTracks.begin();
    500                  it2 != it; ++it2) {
    501                 (*it2)->stop();
    502             }
    503 
    504             return err;
    505         }
    506     }
    507     return OK;
    508 }
    509 
    510 int64_t MPEG4Writer::estimateMoovBoxSize(int32_t bitRate) {
    511     // This implementation is highly experimental/heurisitic.
    512     //
    513     // Statistical analysis shows that metadata usually accounts
    514     // for a small portion of the total file size, usually < 0.6%.
    515 
    516     // The default MIN_MOOV_BOX_SIZE is set to 0.6% x 1MB / 2,
    517     // where 1MB is the common file size limit for MMS application.
    518     // The default MAX _MOOV_BOX_SIZE value is based on about 3
    519     // minute video recording with a bit rate about 3 Mbps, because
    520     // statistics also show that most of the video captured are going
    521     // to be less than 3 minutes.
    522 
    523     // If the estimation is wrong, we will pay the price of wasting
    524     // some reserved space. This should not happen so often statistically.
    525     static const int32_t factor = mUse32BitOffset? 1: 2;
    526     static const int64_t MIN_MOOV_BOX_SIZE = 3 * 1024;  // 3 KB
    527     static const int64_t MAX_MOOV_BOX_SIZE = (180 * 3000000 * 6LL / 8000);
    528     int64_t size = MIN_MOOV_BOX_SIZE;
    529 
    530     // Max file size limit is set
    531     if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
    532         size = mMaxFileSizeLimitBytes * 6 / 1000;
    533     }
    534 
    535     // Max file duration limit is set
    536     if (mMaxFileDurationLimitUs != 0) {
    537         if (bitRate > 0) {
    538             int64_t size2 =
    539                 ((mMaxFileDurationLimitUs * bitRate * 6) / 1000 / 8000000);
    540             if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
    541                 // When both file size and duration limits are set,
    542                 // we use the smaller limit of the two.
    543                 if (size > size2) {
    544                     size = size2;
    545                 }
    546             } else {
    547                 // Only max file duration limit is set
    548                 size = size2;
    549             }
    550         }
    551     }
    552 
    553     if (size < MIN_MOOV_BOX_SIZE) {
    554         size = MIN_MOOV_BOX_SIZE;
    555     }
    556 
    557     // Any long duration recording will be probably end up with
    558     // non-streamable mp4 file.
    559     if (size > MAX_MOOV_BOX_SIZE) {
    560         size = MAX_MOOV_BOX_SIZE;
    561     }
    562 
    563     ALOGI("limits: %" PRId64 "/%" PRId64 " bytes/us, bit rate: %d bps and the"
    564          " estimated moov size %" PRId64 " bytes",
    565          mMaxFileSizeLimitBytes, mMaxFileDurationLimitUs, bitRate, size);
    566     return factor * size;
    567 }
    568 
    569 status_t MPEG4Writer::start(MetaData *param) {
    570     if (mInitCheck != OK) {
    571         return UNKNOWN_ERROR;
    572     }
    573 
    574     /*
    575      * Check mMaxFileSizeLimitBytes at the beginning
    576      * since mMaxFileSizeLimitBytes may be implicitly
    577      * changed later for 32-bit file offset even if
    578      * user does not ask to set it explicitly.
    579      */
    580     if (mMaxFileSizeLimitBytes != 0) {
    581         mIsFileSizeLimitExplicitlyRequested = true;
    582     }
    583 
    584     int32_t use64BitOffset;
    585     if (param &&
    586         param->findInt32(kKey64BitFileOffset, &use64BitOffset) &&
    587         use64BitOffset) {
    588         mUse32BitOffset = false;
    589     }
    590 
    591     if (mUse32BitOffset) {
    592         // Implicit 32 bit file size limit
    593         if (mMaxFileSizeLimitBytes == 0) {
    594             mMaxFileSizeLimitBytes = kMax32BitFileSize;
    595         }
    596 
    597         // If file size is set to be larger than the 32 bit file
    598         // size limit, treat it as an error.
    599         if (mMaxFileSizeLimitBytes > kMax32BitFileSize) {
    600             ALOGW("32-bit file size limit (%" PRId64 " bytes) too big. "
    601                  "It is changed to %" PRId64 " bytes",
    602                 mMaxFileSizeLimitBytes, kMax32BitFileSize);
    603             mMaxFileSizeLimitBytes = kMax32BitFileSize;
    604         }
    605     }
    606 
    607     int32_t use2ByteNalLength;
    608     if (param &&
    609         param->findInt32(kKey2ByteNalLength, &use2ByteNalLength) &&
    610         use2ByteNalLength) {
    611         mUse4ByteNalLength = false;
    612     }
    613 
    614     int32_t isRealTimeRecording;
    615     if (param && param->findInt32(kKeyRealTimeRecording, &isRealTimeRecording)) {
    616         mIsRealTimeRecording = isRealTimeRecording;
    617     }
    618 
    619     mStartTimestampUs = -1;
    620 
    621     if (mStarted) {
    622         if (mPaused) {
    623             mPaused = false;
    624             return startTracks(param);
    625         }
    626         return OK;
    627     }
    628 
    629     if (!param ||
    630         !param->findInt32(kKeyTimeScale, &mTimeScale)) {
    631         mTimeScale = 1000;
    632     }
    633     CHECK_GT(mTimeScale, 0);
    634     ALOGV("movie time scale: %d", mTimeScale);
    635 
    636     /*
    637      * When the requested file size limit is small, the priority
    638      * is to meet the file size limit requirement, rather than
    639      * to make the file streamable. mStreamableFile does not tell
    640      * whether the actual recorded file is streamable or not.
    641      */
    642     mStreamableFile =
    643         (mMaxFileSizeLimitBytes != 0 &&
    644          mMaxFileSizeLimitBytes >= kMinStreamableFileSizeInBytes);
    645 
    646     /*
    647      * mWriteMoovBoxToMemory is true if the amount of data in moov box is
    648      * smaller than the reserved free space at the beginning of a file, AND
    649      * when the content of moov box is constructed. Note that video/audio
    650      * frame data is always written to the file but not in the memory.
    651      *
    652      * Before stop()/reset() is called, mWriteMoovBoxToMemory is always
    653      * false. When reset() is called at the end of a recording session,
    654      * Moov box needs to be constructed.
    655      *
    656      * 1) Right before a moov box is constructed, mWriteMoovBoxToMemory
    657      * to set to mStreamableFile so that if
    658      * the file is intended to be streamable, it is set to true;
    659      * otherwise, it is set to false. When the value is set to false,
    660      * all the content of the moov box is written immediately to
    661      * the end of the file. When the value is set to true, all the
    662      * content of the moov box is written to an in-memory cache,
    663      * mMoovBoxBuffer, util the following condition happens. Note
    664      * that the size of the in-memory cache is the same as the
    665      * reserved free space at the beginning of the file.
    666      *
    667      * 2) While the data of the moov box is written to an in-memory
    668      * cache, the data size is checked against the reserved space.
    669      * If the data size surpasses the reserved space, subsequent moov
    670      * data could no longer be hold in the in-memory cache. This also
    671      * indicates that the reserved space was too small. At this point,
    672      * _all_ moov data must be written to the end of the file.
    673      * mWriteMoovBoxToMemory must be set to false to direct the write
    674      * to the file.
    675      *
    676      * 3) If the data size in moov box is smaller than the reserved
    677      * space after moov box is completely constructed, the in-memory
    678      * cache copy of the moov box is written to the reserved free
    679      * space. Thus, immediately after the moov is completedly
    680      * constructed, mWriteMoovBoxToMemory is always set to false.
    681      */
    682     mWriteMoovBoxToMemory = false;
    683     mMoovBoxBuffer = NULL;
    684     mMoovBoxBufferOffset = 0;
    685 
    686     writeFtypBox(param);
    687 
    688     mFreeBoxOffset = mOffset;
    689 
    690     if (mEstimatedMoovBoxSize == 0) {
    691         int32_t bitRate = -1;
    692         if (param) {
    693             param->findInt32(kKeyBitRate, &bitRate);
    694         }
    695         mEstimatedMoovBoxSize = estimateMoovBoxSize(bitRate);
    696     }
    697     CHECK_GE(mEstimatedMoovBoxSize, 8);
    698     if (mStreamableFile) {
    699         // Reserve a 'free' box only for streamable file
    700         lseek64(mFd, mFreeBoxOffset, SEEK_SET);
    701         writeInt32(mEstimatedMoovBoxSize);
    702         write("free", 4);
    703         mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize;
    704     } else {
    705         mMdatOffset = mOffset;
    706     }
    707 
    708     mOffset = mMdatOffset;
    709     lseek64(mFd, mMdatOffset, SEEK_SET);
    710     if (mUse32BitOffset) {
    711         write("????mdat", 8);
    712     } else {
    713         write("\x00\x00\x00\x01mdat????????", 16);
    714     }
    715 
    716     status_t err = startWriterThread();
    717     if (err != OK) {
    718         return err;
    719     }
    720 
    721     err = startTracks(param);
    722     if (err != OK) {
    723         return err;
    724     }
    725 
    726     mStarted = true;
    727     return OK;
    728 }
    729 
    730 bool MPEG4Writer::use32BitFileOffset() const {
    731     return mUse32BitOffset;
    732 }
    733 
    734 status_t MPEG4Writer::pause() {
    735     if (mInitCheck != OK) {
    736         return OK;
    737     }
    738     mPaused = true;
    739     status_t err = OK;
    740     for (List<Track *>::iterator it = mTracks.begin();
    741          it != mTracks.end(); ++it) {
    742         status_t status = (*it)->pause();
    743         if (status != OK) {
    744             err = status;
    745         }
    746     }
    747     return err;
    748 }
    749 
    750 void MPEG4Writer::stopWriterThread() {
    751     ALOGD("Stopping writer thread");
    752     if (!mWriterThreadStarted) {
    753         return;
    754     }
    755 
    756     {
    757         Mutex::Autolock autolock(mLock);
    758 
    759         mDone = true;
    760         mChunkReadyCondition.signal();
    761     }
    762 
    763     void *dummy;
    764     pthread_join(mThread, &dummy);
    765     mWriterThreadStarted = false;
    766     ALOGD("Writer thread stopped");
    767 }
    768 
    769 /*
    770  * MP4 file standard defines a composition matrix:
    771  * | a  b  u |
    772  * | c  d  v |
    773  * | x  y  w |
    774  *
    775  * the element in the matrix is stored in the following
    776  * order: {a, b, u, c, d, v, x, y, w},
    777  * where a, b, c, d, x, and y is in 16.16 format, while
    778  * u, v and w is in 2.30 format.
    779  */
    780 void MPEG4Writer::writeCompositionMatrix(int degrees) {
    781     ALOGV("writeCompositionMatrix");
    782     uint32_t a = 0x00010000;
    783     uint32_t b = 0;
    784     uint32_t c = 0;
    785     uint32_t d = 0x00010000;
    786     switch (degrees) {
    787         case 0:
    788             break;
    789         case 90:
    790             a = 0;
    791             b = 0x00010000;
    792             c = 0xFFFF0000;
    793             d = 0;
    794             break;
    795         case 180:
    796             a = 0xFFFF0000;
    797             d = 0xFFFF0000;
    798             break;
    799         case 270:
    800             a = 0;
    801             b = 0xFFFF0000;
    802             c = 0x00010000;
    803             d = 0;
    804             break;
    805         default:
    806             CHECK(!"Should never reach this unknown rotation");
    807             break;
    808     }
    809 
    810     writeInt32(a);           // a
    811     writeInt32(b);           // b
    812     writeInt32(0);           // u
    813     writeInt32(c);           // c
    814     writeInt32(d);           // d
    815     writeInt32(0);           // v
    816     writeInt32(0);           // x
    817     writeInt32(0);           // y
    818     writeInt32(0x40000000);  // w
    819 }
    820 
    821 void MPEG4Writer::release() {
    822     close(mFd);
    823     mFd = -1;
    824     mInitCheck = NO_INIT;
    825     mStarted = false;
    826 }
    827 
    828 status_t MPEG4Writer::reset() {
    829     if (mInitCheck != OK) {
    830         return OK;
    831     } else {
    832         if (!mWriterThreadStarted ||
    833             !mStarted) {
    834             if (mWriterThreadStarted) {
    835                 stopWriterThread();
    836             }
    837             release();
    838             return OK;
    839         }
    840     }
    841 
    842     status_t err = OK;
    843     int64_t maxDurationUs = 0;
    844     int64_t minDurationUs = 0x7fffffffffffffffLL;
    845     for (List<Track *>::iterator it = mTracks.begin();
    846          it != mTracks.end(); ++it) {
    847         status_t status = (*it)->stop();
    848         if (err == OK && status != OK) {
    849             err = status;
    850         }
    851 
    852         int64_t durationUs = (*it)->getDurationUs();
    853         if (durationUs > maxDurationUs) {
    854             maxDurationUs = durationUs;
    855         }
    856         if (durationUs < minDurationUs) {
    857             minDurationUs = durationUs;
    858         }
    859     }
    860 
    861     if (mTracks.size() > 1) {
    862         ALOGD("Duration from tracks range is [%" PRId64 ", %" PRId64 "] us",
    863             minDurationUs, maxDurationUs);
    864     }
    865 
    866     stopWriterThread();
    867 
    868     // Do not write out movie header on error.
    869     if (err != OK) {
    870         release();
    871         return err;
    872     }
    873 
    874     // Fix up the size of the 'mdat' chunk.
    875     if (mUse32BitOffset) {
    876         lseek64(mFd, mMdatOffset, SEEK_SET);
    877         uint32_t size = htonl(static_cast<uint32_t>(mOffset - mMdatOffset));
    878         ::write(mFd, &size, 4);
    879     } else {
    880         lseek64(mFd, mMdatOffset + 8, SEEK_SET);
    881         uint64_t size = mOffset - mMdatOffset;
    882         size = hton64(size);
    883         ::write(mFd, &size, 8);
    884     }
    885     lseek64(mFd, mOffset, SEEK_SET);
    886 
    887     // Construct moov box now
    888     mMoovBoxBufferOffset = 0;
    889     mWriteMoovBoxToMemory = mStreamableFile;
    890     if (mWriteMoovBoxToMemory) {
    891         // There is no need to allocate in-memory cache
    892         // for moov box if the file is not streamable.
    893 
    894         mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize);
    895         CHECK(mMoovBoxBuffer != NULL);
    896     }
    897     writeMoovBox(maxDurationUs);
    898 
    899     // mWriteMoovBoxToMemory could be set to false in
    900     // MPEG4Writer::write() method
    901     if (mWriteMoovBoxToMemory) {
    902         mWriteMoovBoxToMemory = false;
    903         // Content of the moov box is saved in the cache, and the in-memory
    904         // moov box needs to be written to the file in a single shot.
    905 
    906         CHECK_LE(mMoovBoxBufferOffset + 8, mEstimatedMoovBoxSize);
    907 
    908         // Moov box
    909         lseek64(mFd, mFreeBoxOffset, SEEK_SET);
    910         mOffset = mFreeBoxOffset;
    911         write(mMoovBoxBuffer, 1, mMoovBoxBufferOffset);
    912 
    913         // Free box
    914         lseek64(mFd, mOffset, SEEK_SET);
    915         writeInt32(mEstimatedMoovBoxSize - mMoovBoxBufferOffset);
    916         write("free", 4);
    917     } else {
    918         ALOGI("The mp4 file will not be streamable.");
    919     }
    920 
    921     // Free in-memory cache for moov box
    922     if (mMoovBoxBuffer != NULL) {
    923         free(mMoovBoxBuffer);
    924         mMoovBoxBuffer = NULL;
    925         mMoovBoxBufferOffset = 0;
    926     }
    927 
    928     CHECK(mBoxes.empty());
    929 
    930     release();
    931     return err;
    932 }
    933 
    934 uint32_t MPEG4Writer::getMpeg4Time() {
    935     time_t now = time(NULL);
    936     // MP4 file uses time counting seconds since midnight, Jan. 1, 1904
    937     // while time function returns Unix epoch values which starts
    938     // at 1970-01-01. Lets add the number of seconds between them
    939     uint32_t mpeg4Time = now + (66 * 365 + 17) * (24 * 60 * 60);
    940     return mpeg4Time;
    941 }
    942 
    943 void MPEG4Writer::writeMvhdBox(int64_t durationUs) {
    944     uint32_t now = getMpeg4Time();
    945     beginBox("mvhd");
    946     writeInt32(0);             // version=0, flags=0
    947     writeInt32(now);           // creation time
    948     writeInt32(now);           // modification time
    949     writeInt32(mTimeScale);    // mvhd timescale
    950     int32_t duration = (durationUs * mTimeScale + 5E5) / 1E6;
    951     writeInt32(duration);
    952     writeInt32(0x10000);       // rate: 1.0
    953     writeInt16(0x100);         // volume
    954     writeInt16(0);             // reserved
    955     writeInt32(0);             // reserved
    956     writeInt32(0);             // reserved
    957     writeCompositionMatrix(0); // matrix
    958     writeInt32(0);             // predefined
    959     writeInt32(0);             // predefined
    960     writeInt32(0);             // predefined
    961     writeInt32(0);             // predefined
    962     writeInt32(0);             // predefined
    963     writeInt32(0);             // predefined
    964     writeInt32(mTracks.size() + 1);  // nextTrackID
    965     endBox();  // mvhd
    966 }
    967 
    968 void MPEG4Writer::writeMoovBox(int64_t durationUs) {
    969     beginBox("moov");
    970     writeMvhdBox(durationUs);
    971     if (mAreGeoTagsAvailable) {
    972         writeUdtaBox();
    973     }
    974     int32_t id = 1;
    975     for (List<Track *>::iterator it = mTracks.begin();
    976         it != mTracks.end(); ++it, ++id) {
    977         (*it)->writeTrackHeader(mUse32BitOffset);
    978     }
    979     endBox();  // moov
    980 }
    981 
    982 void MPEG4Writer::writeFtypBox(MetaData *param) {
    983     beginBox("ftyp");
    984 
    985     int32_t fileType;
    986     if (param && param->findInt32(kKeyFileType, &fileType) &&
    987         fileType != OUTPUT_FORMAT_MPEG_4) {
    988         writeFourcc("3gp4");
    989         writeInt32(0);
    990         writeFourcc("isom");
    991         writeFourcc("3gp4");
    992     } else {
    993         writeFourcc("mp42");
    994         writeInt32(0);
    995         writeFourcc("isom");
    996         writeFourcc("mp42");
    997     }
    998 
    999     endBox();
   1000 }
   1001 
   1002 static bool isTestModeEnabled() {
   1003 #if (PROPERTY_VALUE_MAX < 5)
   1004 #error "PROPERTY_VALUE_MAX must be at least 5"
   1005 #endif
   1006 
   1007     // Test mode is enabled only if rw.media.record.test system
   1008     // property is enabled.
   1009     char value[PROPERTY_VALUE_MAX];
   1010     if (property_get("rw.media.record.test", value, NULL) &&
   1011         (!strcasecmp(value, "true") || !strcasecmp(value, "1"))) {
   1012         return true;
   1013     }
   1014     return false;
   1015 }
   1016 
   1017 void MPEG4Writer::sendSessionSummary() {
   1018     // Send session summary only if test mode is enabled
   1019     if (!isTestModeEnabled()) {
   1020         return;
   1021     }
   1022 
   1023     for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
   1024          it != mChunkInfos.end(); ++it) {
   1025         int trackNum = it->mTrack->getTrackId() << 28;
   1026         notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   1027                 trackNum | MEDIA_RECORDER_TRACK_INTER_CHUNK_TIME_MS,
   1028                 it->mMaxInterChunkDurUs);
   1029     }
   1030 }
   1031 
   1032 status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
   1033     mInterleaveDurationUs = durationUs;
   1034     return OK;
   1035 }
   1036 
   1037 void MPEG4Writer::lock() {
   1038     mLock.lock();
   1039 }
   1040 
   1041 void MPEG4Writer::unlock() {
   1042     mLock.unlock();
   1043 }
   1044 
   1045 off64_t MPEG4Writer::addSample_l(MediaBuffer *buffer) {
   1046     off64_t old_offset = mOffset;
   1047 
   1048     ::write(mFd,
   1049           (const uint8_t *)buffer->data() + buffer->range_offset(),
   1050           buffer->range_length());
   1051 
   1052     mOffset += buffer->range_length();
   1053 
   1054     return old_offset;
   1055 }
   1056 
   1057 static void StripStartcode(MediaBuffer *buffer) {
   1058     if (buffer->range_length() < 4) {
   1059         return;
   1060     }
   1061 
   1062     const uint8_t *ptr =
   1063         (const uint8_t *)buffer->data() + buffer->range_offset();
   1064 
   1065     if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) {
   1066         buffer->set_range(
   1067                 buffer->range_offset() + 4, buffer->range_length() - 4);
   1068     }
   1069 }
   1070 
   1071 off64_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) {
   1072     off64_t old_offset = mOffset;
   1073 
   1074     size_t length = buffer->range_length();
   1075 
   1076     if (mUse4ByteNalLength) {
   1077         uint8_t x = length >> 24;
   1078         ::write(mFd, &x, 1);
   1079         x = (length >> 16) & 0xff;
   1080         ::write(mFd, &x, 1);
   1081         x = (length >> 8) & 0xff;
   1082         ::write(mFd, &x, 1);
   1083         x = length & 0xff;
   1084         ::write(mFd, &x, 1);
   1085 
   1086         ::write(mFd,
   1087               (const uint8_t *)buffer->data() + buffer->range_offset(),
   1088               length);
   1089 
   1090         mOffset += length + 4;
   1091     } else {
   1092         CHECK_LT(length, 65536);
   1093 
   1094         uint8_t x = length >> 8;
   1095         ::write(mFd, &x, 1);
   1096         x = length & 0xff;
   1097         ::write(mFd, &x, 1);
   1098         ::write(mFd, (const uint8_t *)buffer->data() + buffer->range_offset(), length);
   1099         mOffset += length + 2;
   1100     }
   1101 
   1102     return old_offset;
   1103 }
   1104 
   1105 size_t MPEG4Writer::write(
   1106         const void *ptr, size_t size, size_t nmemb) {
   1107 
   1108     const size_t bytes = size * nmemb;
   1109     if (mWriteMoovBoxToMemory) {
   1110 
   1111         off64_t moovBoxSize = 8 + mMoovBoxBufferOffset + bytes;
   1112         if (moovBoxSize > mEstimatedMoovBoxSize) {
   1113             // The reserved moov box at the beginning of the file
   1114             // is not big enough. Moov box should be written to
   1115             // the end of the file from now on, but not to the
   1116             // in-memory cache.
   1117 
   1118             // We write partial moov box that is in the memory to
   1119             // the file first.
   1120             for (List<off64_t>::iterator it = mBoxes.begin();
   1121                  it != mBoxes.end(); ++it) {
   1122                 (*it) += mOffset;
   1123             }
   1124             lseek64(mFd, mOffset, SEEK_SET);
   1125             ::write(mFd, mMoovBoxBuffer, mMoovBoxBufferOffset);
   1126             ::write(mFd, ptr, bytes);
   1127             mOffset += (bytes + mMoovBoxBufferOffset);
   1128 
   1129             // All subsequent moov box content will be written
   1130             // to the end of the file.
   1131             mWriteMoovBoxToMemory = false;
   1132         } else {
   1133             memcpy(mMoovBoxBuffer + mMoovBoxBufferOffset, ptr, bytes);
   1134             mMoovBoxBufferOffset += bytes;
   1135         }
   1136     } else {
   1137         ::write(mFd, ptr, size * nmemb);
   1138         mOffset += bytes;
   1139     }
   1140     return bytes;
   1141 }
   1142 
   1143 void MPEG4Writer::beginBox(const char *fourcc) {
   1144     CHECK_EQ(strlen(fourcc), 4);
   1145 
   1146     mBoxes.push_back(mWriteMoovBoxToMemory?
   1147             mMoovBoxBufferOffset: mOffset);
   1148 
   1149     writeInt32(0);
   1150     writeFourcc(fourcc);
   1151 }
   1152 
   1153 void MPEG4Writer::endBox() {
   1154     CHECK(!mBoxes.empty());
   1155 
   1156     off64_t offset = *--mBoxes.end();
   1157     mBoxes.erase(--mBoxes.end());
   1158 
   1159     if (mWriteMoovBoxToMemory) {
   1160        int32_t x = htonl(mMoovBoxBufferOffset - offset);
   1161        memcpy(mMoovBoxBuffer + offset, &x, 4);
   1162     } else {
   1163         lseek64(mFd, offset, SEEK_SET);
   1164         writeInt32(mOffset - offset);
   1165         mOffset -= 4;
   1166         lseek64(mFd, mOffset, SEEK_SET);
   1167     }
   1168 }
   1169 
   1170 void MPEG4Writer::writeInt8(int8_t x) {
   1171     write(&x, 1, 1);
   1172 }
   1173 
   1174 void MPEG4Writer::writeInt16(int16_t x) {
   1175     x = htons(x);
   1176     write(&x, 1, 2);
   1177 }
   1178 
   1179 void MPEG4Writer::writeInt32(int32_t x) {
   1180     x = htonl(x);
   1181     write(&x, 1, 4);
   1182 }
   1183 
   1184 void MPEG4Writer::writeInt64(int64_t x) {
   1185     x = hton64(x);
   1186     write(&x, 1, 8);
   1187 }
   1188 
   1189 void MPEG4Writer::writeCString(const char *s) {
   1190     size_t n = strlen(s);
   1191     write(s, 1, n + 1);
   1192 }
   1193 
   1194 void MPEG4Writer::writeFourcc(const char *s) {
   1195     CHECK_EQ(strlen(s), 4);
   1196     write(s, 1, 4);
   1197 }
   1198 
   1199 
   1200 // Written in +/-DD.DDDD format
   1201 void MPEG4Writer::writeLatitude(int degreex10000) {
   1202     bool isNegative = (degreex10000 < 0);
   1203     char sign = isNegative? '-': '+';
   1204 
   1205     // Handle the whole part
   1206     char str[9];
   1207     int wholePart = degreex10000 / 10000;
   1208     if (wholePart == 0) {
   1209         snprintf(str, 5, "%c%.2d.", sign, wholePart);
   1210     } else {
   1211         snprintf(str, 5, "%+.2d.", wholePart);
   1212     }
   1213 
   1214     // Handle the fractional part
   1215     int fractionalPart = degreex10000 - (wholePart * 10000);
   1216     if (fractionalPart < 0) {
   1217         fractionalPart = -fractionalPart;
   1218     }
   1219     snprintf(&str[4], 5, "%.4d", fractionalPart);
   1220 
   1221     // Do not write the null terminator
   1222     write(str, 1, 8);
   1223 }
   1224 
   1225 // Written in +/- DDD.DDDD format
   1226 void MPEG4Writer::writeLongitude(int degreex10000) {
   1227     bool isNegative = (degreex10000 < 0);
   1228     char sign = isNegative? '-': '+';
   1229 
   1230     // Handle the whole part
   1231     char str[10];
   1232     int wholePart = degreex10000 / 10000;
   1233     if (wholePart == 0) {
   1234         snprintf(str, 6, "%c%.3d.", sign, wholePart);
   1235     } else {
   1236         snprintf(str, 6, "%+.3d.", wholePart);
   1237     }
   1238 
   1239     // Handle the fractional part
   1240     int fractionalPart = degreex10000 - (wholePart * 10000);
   1241     if (fractionalPart < 0) {
   1242         fractionalPart = -fractionalPart;
   1243     }
   1244     snprintf(&str[5], 5, "%.4d", fractionalPart);
   1245 
   1246     // Do not write the null terminator
   1247     write(str, 1, 9);
   1248 }
   1249 
   1250 /*
   1251  * Geodata is stored according to ISO-6709 standard.
   1252  * latitudex10000 is latitude in degrees times 10000, and
   1253  * longitudex10000 is longitude in degrees times 10000.
   1254  * The range for the latitude is in [-90, +90], and
   1255  * The range for the longitude is in [-180, +180]
   1256  */
   1257 status_t MPEG4Writer::setGeoData(int latitudex10000, int longitudex10000) {
   1258     // Is latitude or longitude out of range?
   1259     if (latitudex10000 < -900000 || latitudex10000 > 900000 ||
   1260         longitudex10000 < -1800000 || longitudex10000 > 1800000) {
   1261         return BAD_VALUE;
   1262     }
   1263 
   1264     mLatitudex10000 = latitudex10000;
   1265     mLongitudex10000 = longitudex10000;
   1266     mAreGeoTagsAvailable = true;
   1267     return OK;
   1268 }
   1269 
   1270 void MPEG4Writer::write(const void *data, size_t size) {
   1271     write(data, 1, size);
   1272 }
   1273 
   1274 bool MPEG4Writer::isFileStreamable() const {
   1275     return mStreamableFile;
   1276 }
   1277 
   1278 bool MPEG4Writer::exceedsFileSizeLimit() {
   1279     // No limit
   1280     if (mMaxFileSizeLimitBytes == 0) {
   1281         return false;
   1282     }
   1283 
   1284     int64_t nTotalBytesEstimate = static_cast<int64_t>(mEstimatedMoovBoxSize);
   1285     for (List<Track *>::iterator it = mTracks.begin();
   1286          it != mTracks.end(); ++it) {
   1287         nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
   1288     }
   1289 
   1290     if (!mStreamableFile) {
   1291         // Add 1024 bytes as error tolerance
   1292         return nTotalBytesEstimate + 1024 >= mMaxFileSizeLimitBytes;
   1293     }
   1294     // Be conservative in the estimate: do not exceed 95% of
   1295     // the target file limit. For small target file size limit, though,
   1296     // this will not help.
   1297     return (nTotalBytesEstimate >= (95 * mMaxFileSizeLimitBytes) / 100);
   1298 }
   1299 
   1300 bool MPEG4Writer::exceedsFileDurationLimit() {
   1301     // No limit
   1302     if (mMaxFileDurationLimitUs == 0) {
   1303         return false;
   1304     }
   1305 
   1306     for (List<Track *>::iterator it = mTracks.begin();
   1307          it != mTracks.end(); ++it) {
   1308         if ((*it)->getDurationUs() >= mMaxFileDurationLimitUs) {
   1309             return true;
   1310         }
   1311     }
   1312     return false;
   1313 }
   1314 
   1315 bool MPEG4Writer::reachedEOS() {
   1316     bool allDone = true;
   1317     for (List<Track *>::iterator it = mTracks.begin();
   1318          it != mTracks.end(); ++it) {
   1319         if (!(*it)->reachedEOS()) {
   1320             allDone = false;
   1321             break;
   1322         }
   1323     }
   1324 
   1325     return allDone;
   1326 }
   1327 
   1328 void MPEG4Writer::setStartTimestampUs(int64_t timeUs) {
   1329     ALOGI("setStartTimestampUs: %" PRId64, timeUs);
   1330     CHECK_GE(timeUs, 0ll);
   1331     Mutex::Autolock autoLock(mLock);
   1332     if (mStartTimestampUs < 0 || mStartTimestampUs > timeUs) {
   1333         mStartTimestampUs = timeUs;
   1334         ALOGI("Earliest track starting time: %" PRId64, mStartTimestampUs);
   1335     }
   1336 }
   1337 
   1338 int64_t MPEG4Writer::getStartTimestampUs() {
   1339     Mutex::Autolock autoLock(mLock);
   1340     return mStartTimestampUs;
   1341 }
   1342 
   1343 size_t MPEG4Writer::numTracks() {
   1344     Mutex::Autolock autolock(mLock);
   1345     return mTracks.size();
   1346 }
   1347 
   1348 ////////////////////////////////////////////////////////////////////////////////
   1349 
   1350 MPEG4Writer::Track::Track(
   1351         MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId)
   1352     : mOwner(owner),
   1353       mMeta(source->getFormat()),
   1354       mSource(source),
   1355       mDone(false),
   1356       mPaused(false),
   1357       mResumed(false),
   1358       mStarted(false),
   1359       mTrackId(trackId),
   1360       mTrackDurationUs(0),
   1361       mEstimatedTrackSizeBytes(0),
   1362       mSamplesHaveSameSize(true),
   1363       mStszTableEntries(new ListTableEntries<uint32_t>(1000, 1)),
   1364       mStcoTableEntries(new ListTableEntries<uint32_t>(1000, 1)),
   1365       mCo64TableEntries(new ListTableEntries<off64_t>(1000, 1)),
   1366       mStscTableEntries(new ListTableEntries<uint32_t>(1000, 3)),
   1367       mStssTableEntries(new ListTableEntries<uint32_t>(1000, 1)),
   1368       mSttsTableEntries(new ListTableEntries<uint32_t>(1000, 2)),
   1369       mCttsTableEntries(new ListTableEntries<uint32_t>(1000, 2)),
   1370       mCodecSpecificData(NULL),
   1371       mCodecSpecificDataSize(0),
   1372       mGotAllCodecSpecificData(false),
   1373       mReachedEOS(false),
   1374       mRotation(0) {
   1375     getCodecSpecificDataFromInputFormatIfPossible();
   1376 
   1377     const char *mime;
   1378     mMeta->findCString(kKeyMIMEType, &mime);
   1379     mIsAvc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
   1380     mIsAudio = !strncasecmp(mime, "audio/", 6);
   1381     mIsMPEG4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
   1382                !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC);
   1383 
   1384     setTimeScale();
   1385 }
   1386 
   1387 void MPEG4Writer::Track::updateTrackSizeEstimate() {
   1388 
   1389     uint32_t stcoBoxCount = (mOwner->use32BitFileOffset()
   1390                             ? mStcoTableEntries->count()
   1391                             : mCo64TableEntries->count());
   1392     int64_t stcoBoxSizeBytes = stcoBoxCount * 4;
   1393     int64_t stszBoxSizeBytes = mSamplesHaveSameSize? 4: (mStszTableEntries->count() * 4);
   1394 
   1395     mEstimatedTrackSizeBytes = mMdatSizeBytes;  // media data size
   1396     if (!mOwner->isFileStreamable()) {
   1397         // Reserved free space is not large enough to hold
   1398         // all meta data and thus wasted.
   1399         mEstimatedTrackSizeBytes += mStscTableEntries->count() * 12 +  // stsc box size
   1400                                     mStssTableEntries->count() * 4 +   // stss box size
   1401                                     mSttsTableEntries->count() * 8 +   // stts box size
   1402                                     mCttsTableEntries->count() * 8 +   // ctts box size
   1403                                     stcoBoxSizeBytes +           // stco box size
   1404                                     stszBoxSizeBytes;            // stsz box size
   1405     }
   1406 }
   1407 
   1408 void MPEG4Writer::Track::addOneStscTableEntry(
   1409         size_t chunkId, size_t sampleId) {
   1410 
   1411         mStscTableEntries->add(htonl(chunkId));
   1412         mStscTableEntries->add(htonl(sampleId));
   1413         mStscTableEntries->add(htonl(1));
   1414 }
   1415 
   1416 void MPEG4Writer::Track::addOneStssTableEntry(size_t sampleId) {
   1417     mStssTableEntries->add(htonl(sampleId));
   1418 }
   1419 
   1420 void MPEG4Writer::Track::addOneSttsTableEntry(
   1421         size_t sampleCount, int32_t duration) {
   1422 
   1423     if (duration == 0) {
   1424         ALOGW("0-duration samples found: %zu", sampleCount);
   1425     }
   1426     mSttsTableEntries->add(htonl(sampleCount));
   1427     mSttsTableEntries->add(htonl(duration));
   1428 }
   1429 
   1430 void MPEG4Writer::Track::addOneCttsTableEntry(
   1431         size_t sampleCount, int32_t duration) {
   1432 
   1433     if (mIsAudio) {
   1434         return;
   1435     }
   1436     mCttsTableEntries->add(htonl(sampleCount));
   1437     mCttsTableEntries->add(htonl(duration));
   1438 }
   1439 
   1440 void MPEG4Writer::Track::addChunkOffset(off64_t offset) {
   1441     if (mOwner->use32BitFileOffset()) {
   1442         uint32_t value = offset;
   1443         mStcoTableEntries->add(htonl(value));
   1444     } else {
   1445         mCo64TableEntries->add(hton64(offset));
   1446     }
   1447 }
   1448 
   1449 void MPEG4Writer::Track::setTimeScale() {
   1450     ALOGV("setTimeScale");
   1451     // Default time scale
   1452     mTimeScale = 90000;
   1453 
   1454     if (mIsAudio) {
   1455         // Use the sampling rate as the default time scale for audio track.
   1456         int32_t sampleRate;
   1457         bool success = mMeta->findInt32(kKeySampleRate, &sampleRate);
   1458         CHECK(success);
   1459         mTimeScale = sampleRate;
   1460     }
   1461 
   1462     // If someone would like to overwrite the timescale, use user-supplied value.
   1463     int32_t timeScale;
   1464     if (mMeta->findInt32(kKeyTimeScale, &timeScale)) {
   1465         mTimeScale = timeScale;
   1466     }
   1467 
   1468     CHECK_GT(mTimeScale, 0);
   1469 }
   1470 
   1471 void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() {
   1472     const char *mime;
   1473     CHECK(mMeta->findCString(kKeyMIMEType, &mime));
   1474 
   1475     if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
   1476         uint32_t type;
   1477         const void *data;
   1478         size_t size;
   1479         if (mMeta->findData(kKeyAVCC, &type, &data, &size)) {
   1480             mCodecSpecificData = malloc(size);
   1481             mCodecSpecificDataSize = size;
   1482             memcpy(mCodecSpecificData, data, size);
   1483             mGotAllCodecSpecificData = true;
   1484         }
   1485     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
   1486             || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
   1487         uint32_t type;
   1488         const void *data;
   1489         size_t size;
   1490         if (mMeta->findData(kKeyESDS, &type, &data, &size)) {
   1491             ESDS esds(data, size);
   1492             if (esds.getCodecSpecificInfo(&data, &size) == OK) {
   1493                 mCodecSpecificData = malloc(size);
   1494                 mCodecSpecificDataSize = size;
   1495                 memcpy(mCodecSpecificData, data, size);
   1496                 mGotAllCodecSpecificData = true;
   1497             }
   1498         }
   1499     }
   1500 }
   1501 
   1502 MPEG4Writer::Track::~Track() {
   1503     stop();
   1504 
   1505     delete mStszTableEntries;
   1506     delete mStcoTableEntries;
   1507     delete mCo64TableEntries;
   1508     delete mStscTableEntries;
   1509     delete mSttsTableEntries;
   1510     delete mStssTableEntries;
   1511     delete mCttsTableEntries;
   1512 
   1513     mStszTableEntries = NULL;
   1514     mStcoTableEntries = NULL;
   1515     mCo64TableEntries = NULL;
   1516     mStscTableEntries = NULL;
   1517     mSttsTableEntries = NULL;
   1518     mStssTableEntries = NULL;
   1519     mCttsTableEntries = NULL;
   1520 
   1521     if (mCodecSpecificData != NULL) {
   1522         free(mCodecSpecificData);
   1523         mCodecSpecificData = NULL;
   1524     }
   1525 }
   1526 
   1527 void MPEG4Writer::Track::initTrackingProgressStatus(MetaData *params) {
   1528     ALOGV("initTrackingProgressStatus");
   1529     mPreviousTrackTimeUs = -1;
   1530     mTrackingProgressStatus = false;
   1531     mTrackEveryTimeDurationUs = 0;
   1532     {
   1533         int64_t timeUs;
   1534         if (params && params->findInt64(kKeyTrackTimeStatus, &timeUs)) {
   1535             ALOGV("Receive request to track progress status for every %" PRId64 " us", timeUs);
   1536             mTrackEveryTimeDurationUs = timeUs;
   1537             mTrackingProgressStatus = true;
   1538         }
   1539     }
   1540 }
   1541 
   1542 // static
   1543 void *MPEG4Writer::ThreadWrapper(void *me) {
   1544     ALOGV("ThreadWrapper: %p", me);
   1545     MPEG4Writer *writer = static_cast<MPEG4Writer *>(me);
   1546     writer->threadFunc();
   1547     return NULL;
   1548 }
   1549 
   1550 void MPEG4Writer::bufferChunk(const Chunk& chunk) {
   1551     ALOGV("bufferChunk: %p", chunk.mTrack);
   1552     Mutex::Autolock autolock(mLock);
   1553     CHECK_EQ(mDone, false);
   1554 
   1555     for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
   1556          it != mChunkInfos.end(); ++it) {
   1557 
   1558         if (chunk.mTrack == it->mTrack) {  // Found owner
   1559             it->mChunks.push_back(chunk);
   1560             mChunkReadyCondition.signal();
   1561             return;
   1562         }
   1563     }
   1564 
   1565     CHECK(!"Received a chunk for a unknown track");
   1566 }
   1567 
   1568 void MPEG4Writer::writeChunkToFile(Chunk* chunk) {
   1569     ALOGV("writeChunkToFile: %" PRId64 " from %s track",
   1570         chunk->mTimeStampUs, chunk->mTrack->isAudio()? "audio": "video");
   1571 
   1572     int32_t isFirstSample = true;
   1573     while (!chunk->mSamples.empty()) {
   1574         List<MediaBuffer *>::iterator it = chunk->mSamples.begin();
   1575 
   1576         off64_t offset = chunk->mTrack->isAvc()
   1577                                 ? addLengthPrefixedSample_l(*it)
   1578                                 : addSample_l(*it);
   1579 
   1580         if (isFirstSample) {
   1581             chunk->mTrack->addChunkOffset(offset);
   1582             isFirstSample = false;
   1583         }
   1584 
   1585         (*it)->release();
   1586         (*it) = NULL;
   1587         chunk->mSamples.erase(it);
   1588     }
   1589     chunk->mSamples.clear();
   1590 }
   1591 
   1592 void MPEG4Writer::writeAllChunks() {
   1593     ALOGV("writeAllChunks");
   1594     size_t outstandingChunks = 0;
   1595     Chunk chunk;
   1596     while (findChunkToWrite(&chunk)) {
   1597         writeChunkToFile(&chunk);
   1598         ++outstandingChunks;
   1599     }
   1600 
   1601     sendSessionSummary();
   1602 
   1603     mChunkInfos.clear();
   1604     ALOGD("%zu chunks are written in the last batch", outstandingChunks);
   1605 }
   1606 
   1607 bool MPEG4Writer::findChunkToWrite(Chunk *chunk) {
   1608     ALOGV("findChunkToWrite");
   1609 
   1610     int64_t minTimestampUs = 0x7FFFFFFFFFFFFFFFLL;
   1611     Track *track = NULL;
   1612     for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
   1613          it != mChunkInfos.end(); ++it) {
   1614         if (!it->mChunks.empty()) {
   1615             List<Chunk>::iterator chunkIt = it->mChunks.begin();
   1616             if (chunkIt->mTimeStampUs < minTimestampUs) {
   1617                 minTimestampUs = chunkIt->mTimeStampUs;
   1618                 track = it->mTrack;
   1619             }
   1620         }
   1621     }
   1622 
   1623     if (track == NULL) {
   1624         ALOGV("Nothing to be written after all");
   1625         return false;
   1626     }
   1627 
   1628     if (mIsFirstChunk) {
   1629         mIsFirstChunk = false;
   1630     }
   1631 
   1632     for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
   1633          it != mChunkInfos.end(); ++it) {
   1634         if (it->mTrack == track) {
   1635             *chunk = *(it->mChunks.begin());
   1636             it->mChunks.erase(it->mChunks.begin());
   1637             CHECK_EQ(chunk->mTrack, track);
   1638 
   1639             int64_t interChunkTimeUs =
   1640                 chunk->mTimeStampUs - it->mPrevChunkTimestampUs;
   1641             if (interChunkTimeUs > it->mPrevChunkTimestampUs) {
   1642                 it->mMaxInterChunkDurUs = interChunkTimeUs;
   1643             }
   1644 
   1645             return true;
   1646         }
   1647     }
   1648 
   1649     return false;
   1650 }
   1651 
   1652 void MPEG4Writer::threadFunc() {
   1653     ALOGV("threadFunc");
   1654 
   1655     prctl(PR_SET_NAME, (unsigned long)"MPEG4Writer", 0, 0, 0);
   1656 
   1657     Mutex::Autolock autoLock(mLock);
   1658     while (!mDone) {
   1659         Chunk chunk;
   1660         bool chunkFound = false;
   1661 
   1662         while (!mDone && !(chunkFound = findChunkToWrite(&chunk))) {
   1663             mChunkReadyCondition.wait(mLock);
   1664         }
   1665 
   1666         // In real time recording mode, write without holding the lock in order
   1667         // to reduce the blocking time for media track threads.
   1668         // Otherwise, hold the lock until the existing chunks get written to the
   1669         // file.
   1670         if (chunkFound) {
   1671             if (mIsRealTimeRecording) {
   1672                 mLock.unlock();
   1673             }
   1674             writeChunkToFile(&chunk);
   1675             if (mIsRealTimeRecording) {
   1676                 mLock.lock();
   1677             }
   1678         }
   1679     }
   1680 
   1681     writeAllChunks();
   1682 }
   1683 
   1684 status_t MPEG4Writer::startWriterThread() {
   1685     ALOGV("startWriterThread");
   1686 
   1687     mDone = false;
   1688     mIsFirstChunk = true;
   1689     mDriftTimeUs = 0;
   1690     for (List<Track *>::iterator it = mTracks.begin();
   1691          it != mTracks.end(); ++it) {
   1692         ChunkInfo info;
   1693         info.mTrack = *it;
   1694         info.mPrevChunkTimestampUs = 0;
   1695         info.mMaxInterChunkDurUs = 0;
   1696         mChunkInfos.push_back(info);
   1697     }
   1698 
   1699     pthread_attr_t attr;
   1700     pthread_attr_init(&attr);
   1701     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
   1702     pthread_create(&mThread, &attr, ThreadWrapper, this);
   1703     pthread_attr_destroy(&attr);
   1704     mWriterThreadStarted = true;
   1705     return OK;
   1706 }
   1707 
   1708 
   1709 status_t MPEG4Writer::Track::start(MetaData *params) {
   1710     if (!mDone && mPaused) {
   1711         mPaused = false;
   1712         mResumed = true;
   1713         return OK;
   1714     }
   1715 
   1716     int64_t startTimeUs;
   1717     if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
   1718         startTimeUs = 0;
   1719     }
   1720     mStartTimeRealUs = startTimeUs;
   1721 
   1722     int32_t rotationDegrees;
   1723     if (!mIsAudio && params && params->findInt32(kKeyRotation, &rotationDegrees)) {
   1724         mRotation = rotationDegrees;
   1725     }
   1726 
   1727     initTrackingProgressStatus(params);
   1728 
   1729     sp<MetaData> meta = new MetaData;
   1730     if (mOwner->isRealTimeRecording() && mOwner->numTracks() > 1) {
   1731         /*
   1732          * This extra delay of accepting incoming audio/video signals
   1733          * helps to align a/v start time at the beginning of a recording
   1734          * session, and it also helps eliminate the "recording" sound for
   1735          * camcorder applications.
   1736          *
   1737          * If client does not set the start time offset, we fall back to
   1738          * use the default initial delay value.
   1739          */
   1740         int64_t startTimeOffsetUs = mOwner->getStartTimeOffsetMs() * 1000LL;
   1741         if (startTimeOffsetUs < 0) {  // Start time offset was not set
   1742             startTimeOffsetUs = kInitialDelayTimeUs;
   1743         }
   1744         startTimeUs += startTimeOffsetUs;
   1745         ALOGI("Start time offset: %" PRId64 " us", startTimeOffsetUs);
   1746     }
   1747 
   1748     meta->setInt64(kKeyTime, startTimeUs);
   1749 
   1750     status_t err = mSource->start(meta.get());
   1751     if (err != OK) {
   1752         mDone = mReachedEOS = true;
   1753         return err;
   1754     }
   1755 
   1756     pthread_attr_t attr;
   1757     pthread_attr_init(&attr);
   1758     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
   1759 
   1760     mDone = false;
   1761     mStarted = true;
   1762     mTrackDurationUs = 0;
   1763     mReachedEOS = false;
   1764     mEstimatedTrackSizeBytes = 0;
   1765     mMdatSizeBytes = 0;
   1766     mMaxChunkDurationUs = 0;
   1767 
   1768     pthread_create(&mThread, &attr, ThreadWrapper, this);
   1769     pthread_attr_destroy(&attr);
   1770 
   1771     return OK;
   1772 }
   1773 
   1774 status_t MPEG4Writer::Track::pause() {
   1775     mPaused = true;
   1776     return OK;
   1777 }
   1778 
   1779 status_t MPEG4Writer::Track::stop() {
   1780     ALOGD("%s track stopping", mIsAudio? "Audio": "Video");
   1781     if (!mStarted) {
   1782         ALOGE("Stop() called but track is not started");
   1783         return ERROR_END_OF_STREAM;
   1784     }
   1785 
   1786     if (mDone) {
   1787         return OK;
   1788     }
   1789     mDone = true;
   1790 
   1791     ALOGD("%s track source stopping", mIsAudio? "Audio": "Video");
   1792     mSource->stop();
   1793     ALOGD("%s track source stopped", mIsAudio? "Audio": "Video");
   1794 
   1795     void *dummy;
   1796     pthread_join(mThread, &dummy);
   1797     status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
   1798 
   1799     ALOGD("%s track stopped", mIsAudio? "Audio": "Video");
   1800     return err;
   1801 }
   1802 
   1803 bool MPEG4Writer::Track::reachedEOS() {
   1804     return mReachedEOS;
   1805 }
   1806 
   1807 // static
   1808 void *MPEG4Writer::Track::ThreadWrapper(void *me) {
   1809     Track *track = static_cast<Track *>(me);
   1810 
   1811     status_t err = track->threadEntry();
   1812     return (void *)(uintptr_t)err;
   1813 }
   1814 
   1815 static void getNalUnitType(uint8_t byte, uint8_t* type) {
   1816     ALOGV("getNalUnitType: %d", byte);
   1817 
   1818     // nal_unit_type: 5-bit unsigned integer
   1819     *type = (byte & 0x1F);
   1820 }
   1821 
   1822 static const uint8_t *findNextStartCode(
   1823         const uint8_t *data, size_t length) {
   1824 
   1825     ALOGV("findNextStartCode: %p %zu", data, length);
   1826 
   1827     size_t bytesLeft = length;
   1828     while (bytesLeft > 4  &&
   1829             memcmp("\x00\x00\x00\x01", &data[length - bytesLeft], 4)) {
   1830         --bytesLeft;
   1831     }
   1832     if (bytesLeft <= 4) {
   1833         bytesLeft = 0; // Last parameter set
   1834     }
   1835     return &data[length - bytesLeft];
   1836 }
   1837 
   1838 const uint8_t *MPEG4Writer::Track::parseParamSet(
   1839         const uint8_t *data, size_t length, int type, size_t *paramSetLen) {
   1840 
   1841     ALOGV("parseParamSet");
   1842     CHECK(type == kNalUnitTypeSeqParamSet ||
   1843           type == kNalUnitTypePicParamSet);
   1844 
   1845     const uint8_t *nextStartCode = findNextStartCode(data, length);
   1846     *paramSetLen = nextStartCode - data;
   1847     if (*paramSetLen == 0) {
   1848         ALOGE("Param set is malformed, since its length is 0");
   1849         return NULL;
   1850     }
   1851 
   1852     AVCParamSet paramSet(*paramSetLen, data);
   1853     if (type == kNalUnitTypeSeqParamSet) {
   1854         if (*paramSetLen < 4) {
   1855             ALOGE("Seq parameter set malformed");
   1856             return NULL;
   1857         }
   1858         if (mSeqParamSets.empty()) {
   1859             mProfileIdc = data[1];
   1860             mProfileCompatible = data[2];
   1861             mLevelIdc = data[3];
   1862         } else {
   1863             if (mProfileIdc != data[1] ||
   1864                 mProfileCompatible != data[2] ||
   1865                 mLevelIdc != data[3]) {
   1866                 ALOGE("Inconsistent profile/level found in seq parameter sets");
   1867                 return NULL;
   1868             }
   1869         }
   1870         mSeqParamSets.push_back(paramSet);
   1871     } else {
   1872         mPicParamSets.push_back(paramSet);
   1873     }
   1874     return nextStartCode;
   1875 }
   1876 
   1877 status_t MPEG4Writer::Track::copyAVCCodecSpecificData(
   1878         const uint8_t *data, size_t size) {
   1879     ALOGV("copyAVCCodecSpecificData");
   1880 
   1881     // 2 bytes for each of the parameter set length field
   1882     // plus the 7 bytes for the header
   1883     if (size < 4 + 7) {
   1884         ALOGE("Codec specific data length too short: %zu", size);
   1885         return ERROR_MALFORMED;
   1886     }
   1887 
   1888     mCodecSpecificDataSize = size;
   1889     mCodecSpecificData = malloc(size);
   1890     memcpy(mCodecSpecificData, data, size);
   1891     return OK;
   1892 }
   1893 
   1894 status_t MPEG4Writer::Track::parseAVCCodecSpecificData(
   1895         const uint8_t *data, size_t size) {
   1896 
   1897     ALOGV("parseAVCCodecSpecificData");
   1898     // Data starts with a start code.
   1899     // SPS and PPS are separated with start codes.
   1900     // Also, SPS must come before PPS
   1901     uint8_t type = kNalUnitTypeSeqParamSet;
   1902     bool gotSps = false;
   1903     bool gotPps = false;
   1904     const uint8_t *tmp = data;
   1905     const uint8_t *nextStartCode = data;
   1906     size_t bytesLeft = size;
   1907     size_t paramSetLen = 0;
   1908     mCodecSpecificDataSize = 0;
   1909     while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) {
   1910         getNalUnitType(*(tmp + 4), &type);
   1911         if (type == kNalUnitTypeSeqParamSet) {
   1912             if (gotPps) {
   1913                 ALOGE("SPS must come before PPS");
   1914                 return ERROR_MALFORMED;
   1915             }
   1916             if (!gotSps) {
   1917                 gotSps = true;
   1918             }
   1919             nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, &paramSetLen);
   1920         } else if (type == kNalUnitTypePicParamSet) {
   1921             if (!gotSps) {
   1922                 ALOGE("SPS must come before PPS");
   1923                 return ERROR_MALFORMED;
   1924             }
   1925             if (!gotPps) {
   1926                 gotPps = true;
   1927             }
   1928             nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, &paramSetLen);
   1929         } else {
   1930             ALOGE("Only SPS and PPS Nal units are expected");
   1931             return ERROR_MALFORMED;
   1932         }
   1933 
   1934         if (nextStartCode == NULL) {
   1935             return ERROR_MALFORMED;
   1936         }
   1937 
   1938         // Move on to find the next parameter set
   1939         bytesLeft -= nextStartCode - tmp;
   1940         tmp = nextStartCode;
   1941         mCodecSpecificDataSize += (2 + paramSetLen);
   1942     }
   1943 
   1944     {
   1945         // Check on the number of seq parameter sets
   1946         size_t nSeqParamSets = mSeqParamSets.size();
   1947         if (nSeqParamSets == 0) {
   1948             ALOGE("Cound not find sequence parameter set");
   1949             return ERROR_MALFORMED;
   1950         }
   1951 
   1952         if (nSeqParamSets > 0x1F) {
   1953             ALOGE("Too many seq parameter sets (%zu) found", nSeqParamSets);
   1954             return ERROR_MALFORMED;
   1955         }
   1956     }
   1957 
   1958     {
   1959         // Check on the number of pic parameter sets
   1960         size_t nPicParamSets = mPicParamSets.size();
   1961         if (nPicParamSets == 0) {
   1962             ALOGE("Cound not find picture parameter set");
   1963             return ERROR_MALFORMED;
   1964         }
   1965         if (nPicParamSets > 0xFF) {
   1966             ALOGE("Too many pic parameter sets (%zd) found", nPicParamSets);
   1967             return ERROR_MALFORMED;
   1968         }
   1969     }
   1970 // FIXME:
   1971 // Add chromat_format_idc, bit depth values, etc for AVC/h264 high profile and above
   1972 // and remove #if 0
   1973 #if 0
   1974     {
   1975         // Check on the profiles
   1976         // These profiles requires additional parameter set extensions
   1977         if (mProfileIdc == 100 || mProfileIdc == 110 ||
   1978             mProfileIdc == 122 || mProfileIdc == 144) {
   1979             ALOGE("Sorry, no support for profile_idc: %d!", mProfileIdc);
   1980             return BAD_VALUE;
   1981         }
   1982     }
   1983 #endif
   1984     return OK;
   1985 }
   1986 
   1987 status_t MPEG4Writer::Track::makeAVCCodecSpecificData(
   1988         const uint8_t *data, size_t size) {
   1989 
   1990     if (mCodecSpecificData != NULL) {
   1991         ALOGE("Already have codec specific data");
   1992         return ERROR_MALFORMED;
   1993     }
   1994 
   1995     if (size < 4) {
   1996         ALOGE("Codec specific data length too short: %zu", size);
   1997         return ERROR_MALFORMED;
   1998     }
   1999 
   2000     // Data is in the form of AVCCodecSpecificData
   2001     if (memcmp("\x00\x00\x00\x01", data, 4)) {
   2002         return copyAVCCodecSpecificData(data, size);
   2003     }
   2004 
   2005     if (parseAVCCodecSpecificData(data, size) != OK) {
   2006         return ERROR_MALFORMED;
   2007     }
   2008 
   2009     // ISO 14496-15: AVC file format
   2010     mCodecSpecificDataSize += 7;  // 7 more bytes in the header
   2011     mCodecSpecificData = malloc(mCodecSpecificDataSize);
   2012     uint8_t *header = (uint8_t *)mCodecSpecificData;
   2013     header[0] = 1;                     // version
   2014     header[1] = mProfileIdc;           // profile indication
   2015     header[2] = mProfileCompatible;    // profile compatibility
   2016     header[3] = mLevelIdc;
   2017 
   2018     // 6-bit '111111' followed by 2-bit to lengthSizeMinuusOne
   2019     if (mOwner->useNalLengthFour()) {
   2020         header[4] = 0xfc | 3;  // length size == 4 bytes
   2021     } else {
   2022         header[4] = 0xfc | 1;  // length size == 2 bytes
   2023     }
   2024 
   2025     // 3-bit '111' followed by 5-bit numSequenceParameterSets
   2026     int nSequenceParamSets = mSeqParamSets.size();
   2027     header[5] = 0xe0 | nSequenceParamSets;
   2028     header += 6;
   2029     for (List<AVCParamSet>::iterator it = mSeqParamSets.begin();
   2030          it != mSeqParamSets.end(); ++it) {
   2031         // 16-bit sequence parameter set length
   2032         uint16_t seqParamSetLength = it->mLength;
   2033         header[0] = seqParamSetLength >> 8;
   2034         header[1] = seqParamSetLength & 0xff;
   2035 
   2036         // SPS NAL unit (sequence parameter length bytes)
   2037         memcpy(&header[2], it->mData, seqParamSetLength);
   2038         header += (2 + seqParamSetLength);
   2039     }
   2040 
   2041     // 8-bit nPictureParameterSets
   2042     int nPictureParamSets = mPicParamSets.size();
   2043     header[0] = nPictureParamSets;
   2044     header += 1;
   2045     for (List<AVCParamSet>::iterator it = mPicParamSets.begin();
   2046          it != mPicParamSets.end(); ++it) {
   2047         // 16-bit picture parameter set length
   2048         uint16_t picParamSetLength = it->mLength;
   2049         header[0] = picParamSetLength >> 8;
   2050         header[1] = picParamSetLength & 0xff;
   2051 
   2052         // PPS Nal unit (picture parameter set length bytes)
   2053         memcpy(&header[2], it->mData, picParamSetLength);
   2054         header += (2 + picParamSetLength);
   2055     }
   2056 
   2057     return OK;
   2058 }
   2059 
   2060 /*
   2061  * Updates the drift time from the audio track so that
   2062  * the video track can get the updated drift time information
   2063  * from the file writer. The fluctuation of the drift time of the audio
   2064  * encoding path is smoothed out with a simple filter by giving a larger
   2065  * weight to more recently drift time. The filter coefficients, 0.5 and 0.5,
   2066  * are heuristically determined.
   2067  */
   2068 void MPEG4Writer::Track::updateDriftTime(const sp<MetaData>& meta) {
   2069     int64_t driftTimeUs = 0;
   2070     if (meta->findInt64(kKeyDriftTime, &driftTimeUs)) {
   2071         int64_t prevDriftTimeUs = mOwner->getDriftTimeUs();
   2072         int64_t timeUs = (driftTimeUs + prevDriftTimeUs) >> 1;
   2073         mOwner->setDriftTimeUs(timeUs);
   2074     }
   2075 }
   2076 
   2077 status_t MPEG4Writer::Track::threadEntry() {
   2078     int32_t count = 0;
   2079     const int64_t interleaveDurationUs = mOwner->interleaveDuration();
   2080     const bool hasMultipleTracks = (mOwner->numTracks() > 1);
   2081     int64_t chunkTimestampUs = 0;
   2082     int32_t nChunks = 0;
   2083     int32_t nZeroLengthFrames = 0;
   2084     int64_t lastTimestampUs = 0;      // Previous sample time stamp
   2085     int64_t lastDurationUs = 0;       // Between the previous two samples
   2086     int64_t currDurationTicks = 0;    // Timescale based ticks
   2087     int64_t lastDurationTicks = 0;    // Timescale based ticks
   2088     int32_t sampleCount = 1;          // Sample count in the current stts table entry
   2089     uint32_t previousSampleSize = 0;  // Size of the previous sample
   2090     int64_t previousPausedDurationUs = 0;
   2091     int64_t timestampUs = 0;
   2092     int64_t cttsOffsetTimeUs = 0;
   2093     int64_t currCttsOffsetTimeTicks = 0;   // Timescale based ticks
   2094     int64_t lastCttsOffsetTimeTicks = -1;  // Timescale based ticks
   2095     int32_t cttsSampleCount = 0;           // Sample count in the current ctts table entry
   2096     uint32_t lastSamplesPerChunk = 0;
   2097 
   2098     if (mIsAudio) {
   2099         prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0);
   2100     } else {
   2101         prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0);
   2102     }
   2103 
   2104     if (mOwner->isRealTimeRecording()) {
   2105         androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
   2106     }
   2107 
   2108     sp<MetaData> meta_data;
   2109 
   2110     status_t err = OK;
   2111     MediaBuffer *buffer;
   2112     const char *trackName = mIsAudio ? "Audio" : "Video";
   2113     while (!mDone && (err = mSource->read(&buffer)) == OK) {
   2114         if (buffer->range_length() == 0) {
   2115             buffer->release();
   2116             buffer = NULL;
   2117             ++nZeroLengthFrames;
   2118             continue;
   2119         }
   2120 
   2121         // If the codec specific data has not been received yet, delay pause.
   2122         // After the codec specific data is received, discard what we received
   2123         // when the track is to be paused.
   2124         if (mPaused && !mResumed) {
   2125             buffer->release();
   2126             buffer = NULL;
   2127             continue;
   2128         }
   2129 
   2130         ++count;
   2131 
   2132         int32_t isCodecConfig;
   2133         if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig)
   2134                 && isCodecConfig) {
   2135             CHECK(!mGotAllCodecSpecificData);
   2136 
   2137             if (mIsAvc) {
   2138                 status_t err = makeAVCCodecSpecificData(
   2139                         (const uint8_t *)buffer->data()
   2140                             + buffer->range_offset(),
   2141                         buffer->range_length());
   2142                 CHECK_EQ((status_t)OK, err);
   2143             } else if (mIsMPEG4) {
   2144                 mCodecSpecificDataSize = buffer->range_length();
   2145                 mCodecSpecificData = malloc(mCodecSpecificDataSize);
   2146                 memcpy(mCodecSpecificData,
   2147                         (const uint8_t *)buffer->data()
   2148                             + buffer->range_offset(),
   2149                        buffer->range_length());
   2150             }
   2151 
   2152             buffer->release();
   2153             buffer = NULL;
   2154 
   2155             mGotAllCodecSpecificData = true;
   2156             continue;
   2157         }
   2158 
   2159         // Make a deep copy of the MediaBuffer and Metadata and release
   2160         // the original as soon as we can
   2161         MediaBuffer *copy = new MediaBuffer(buffer->range_length());
   2162         memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(),
   2163                 buffer->range_length());
   2164         copy->set_range(0, buffer->range_length());
   2165         meta_data = new MetaData(*buffer->meta_data().get());
   2166         buffer->release();
   2167         buffer = NULL;
   2168 
   2169         if (mIsAvc) StripStartcode(copy);
   2170 
   2171         size_t sampleSize = copy->range_length();
   2172         if (mIsAvc) {
   2173             if (mOwner->useNalLengthFour()) {
   2174                 sampleSize += 4;
   2175             } else {
   2176                 sampleSize += 2;
   2177             }
   2178         }
   2179 
   2180         // Max file size or duration handling
   2181         mMdatSizeBytes += sampleSize;
   2182         updateTrackSizeEstimate();
   2183 
   2184         if (mOwner->exceedsFileSizeLimit()) {
   2185             mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
   2186             break;
   2187         }
   2188         if (mOwner->exceedsFileDurationLimit()) {
   2189             mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0);
   2190             break;
   2191         }
   2192 
   2193 
   2194         int32_t isSync = false;
   2195         meta_data->findInt32(kKeyIsSyncFrame, &isSync);
   2196         CHECK(meta_data->findInt64(kKeyTime, &timestampUs));
   2197 
   2198 ////////////////////////////////////////////////////////////////////////////////
   2199         if (mStszTableEntries->count() == 0) {
   2200             mFirstSampleTimeRealUs = systemTime() / 1000;
   2201             mStartTimestampUs = timestampUs;
   2202             mOwner->setStartTimestampUs(mStartTimestampUs);
   2203             previousPausedDurationUs = mStartTimestampUs;
   2204         }
   2205 
   2206         if (mResumed) {
   2207             int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
   2208             if (WARN_UNLESS(durExcludingEarlierPausesUs >= 0ll, "for %s track", trackName)) {
   2209                 copy->release();
   2210                 return ERROR_MALFORMED;
   2211             }
   2212 
   2213             int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs;
   2214             if (WARN_UNLESS(pausedDurationUs >= lastDurationUs, "for %s track", trackName)) {
   2215                 copy->release();
   2216                 return ERROR_MALFORMED;
   2217             }
   2218 
   2219             previousPausedDurationUs += pausedDurationUs - lastDurationUs;
   2220             mResumed = false;
   2221         }
   2222 
   2223         timestampUs -= previousPausedDurationUs;
   2224         if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
   2225             copy->release();
   2226             return ERROR_MALFORMED;
   2227         }
   2228 
   2229         if (!mIsAudio) {
   2230             /*
   2231              * Composition time: timestampUs
   2232              * Decoding time: decodingTimeUs
   2233              * Composition time offset = composition time - decoding time
   2234              */
   2235             int64_t decodingTimeUs;
   2236             CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs));
   2237             decodingTimeUs -= previousPausedDurationUs;
   2238             cttsOffsetTimeUs =
   2239                     timestampUs + kMaxCttsOffsetTimeUs - decodingTimeUs;
   2240             if (WARN_UNLESS(cttsOffsetTimeUs >= 0ll, "for %s track", trackName)) {
   2241                 copy->release();
   2242                 return ERROR_MALFORMED;
   2243             }
   2244 
   2245             timestampUs = decodingTimeUs;
   2246             ALOGV("decoding time: %" PRId64 " and ctts offset time: %" PRId64,
   2247                 timestampUs, cttsOffsetTimeUs);
   2248 
   2249             // Update ctts box table if necessary
   2250             currCttsOffsetTimeTicks =
   2251                     (cttsOffsetTimeUs * mTimeScale + 500000LL) / 1000000LL;
   2252             if (WARN_UNLESS(currCttsOffsetTimeTicks <= 0x0FFFFFFFFLL, "for %s track", trackName)) {
   2253                 copy->release();
   2254                 return ERROR_MALFORMED;
   2255             }
   2256 
   2257             if (mStszTableEntries->count() == 0) {
   2258                 // Force the first ctts table entry to have one single entry
   2259                 // so that we can do adjustment for the initial track start
   2260                 // time offset easily in writeCttsBox().
   2261                 lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
   2262                 addOneCttsTableEntry(1, currCttsOffsetTimeTicks);
   2263                 cttsSampleCount = 0;      // No sample in ctts box is pending
   2264             } else {
   2265                 if (currCttsOffsetTimeTicks != lastCttsOffsetTimeTicks) {
   2266                     addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
   2267                     lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
   2268                     cttsSampleCount = 1;  // One sample in ctts box is pending
   2269                 } else {
   2270                     ++cttsSampleCount;
   2271                 }
   2272             }
   2273 
   2274             // Update ctts time offset range
   2275             if (mStszTableEntries->count() == 0) {
   2276                 mMinCttsOffsetTimeUs = currCttsOffsetTimeTicks;
   2277                 mMaxCttsOffsetTimeUs = currCttsOffsetTimeTicks;
   2278             } else {
   2279                 if (currCttsOffsetTimeTicks > mMaxCttsOffsetTimeUs) {
   2280                     mMaxCttsOffsetTimeUs = currCttsOffsetTimeTicks;
   2281                 } else if (currCttsOffsetTimeTicks < mMinCttsOffsetTimeUs) {
   2282                     mMinCttsOffsetTimeUs = currCttsOffsetTimeTicks;
   2283                 }
   2284             }
   2285 
   2286         }
   2287 
   2288         if (mOwner->isRealTimeRecording()) {
   2289             if (mIsAudio) {
   2290                 updateDriftTime(meta_data);
   2291             }
   2292         }
   2293 
   2294         if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
   2295             copy->release();
   2296             return ERROR_MALFORMED;
   2297         }
   2298 
   2299         ALOGV("%s media time stamp: %" PRId64 " and previous paused duration %" PRId64,
   2300                 trackName, timestampUs, previousPausedDurationUs);
   2301         if (timestampUs > mTrackDurationUs) {
   2302             mTrackDurationUs = timestampUs;
   2303         }
   2304 
   2305         // We need to use the time scale based ticks, rather than the
   2306         // timestamp itself to determine whether we have to use a new
   2307         // stts entry, since we may have rounding errors.
   2308         // The calculation is intended to reduce the accumulated
   2309         // rounding errors.
   2310         currDurationTicks =
   2311             ((timestampUs * mTimeScale + 500000LL) / 1000000LL -
   2312                 (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
   2313         if (currDurationTicks < 0ll) {
   2314             ALOGE("timestampUs %" PRId64 " < lastTimestampUs %" PRId64 " for %s track",
   2315                 timestampUs, lastTimestampUs, trackName);
   2316             copy->release();
   2317             return UNKNOWN_ERROR;
   2318         }
   2319 
   2320         // if the duration is different for this sample, see if it is close enough to the previous
   2321         // duration that we can fudge it and use the same value, to avoid filling the stts table
   2322         // with lots of near-identical entries.
   2323         // "close enough" here means that the current duration needs to be adjusted by less
   2324         // than 0.1 milliseconds
   2325         if (lastDurationTicks && (currDurationTicks != lastDurationTicks)) {
   2326             int64_t deltaUs = ((lastDurationTicks - currDurationTicks) * 1000000LL
   2327                     + (mTimeScale / 2)) / mTimeScale;
   2328             if (deltaUs > -100 && deltaUs < 100) {
   2329                 // use previous ticks, and adjust timestamp as if it was actually that number
   2330                 // of ticks
   2331                 currDurationTicks = lastDurationTicks;
   2332                 timestampUs += deltaUs;
   2333             }
   2334         }
   2335 
   2336         mStszTableEntries->add(htonl(sampleSize));
   2337         if (mStszTableEntries->count() > 2) {
   2338 
   2339             // Force the first sample to have its own stts entry so that
   2340             // we can adjust its value later to maintain the A/V sync.
   2341             if (mStszTableEntries->count() == 3 || currDurationTicks != lastDurationTicks) {
   2342                 addOneSttsTableEntry(sampleCount, lastDurationTicks);
   2343                 sampleCount = 1;
   2344             } else {
   2345                 ++sampleCount;
   2346             }
   2347 
   2348         }
   2349         if (mSamplesHaveSameSize) {
   2350             if (mStszTableEntries->count() >= 2 && previousSampleSize != sampleSize) {
   2351                 mSamplesHaveSameSize = false;
   2352             }
   2353             previousSampleSize = sampleSize;
   2354         }
   2355         ALOGV("%s timestampUs/lastTimestampUs: %" PRId64 "/%" PRId64,
   2356                 trackName, timestampUs, lastTimestampUs);
   2357         lastDurationUs = timestampUs - lastTimestampUs;
   2358         lastDurationTicks = currDurationTicks;
   2359         lastTimestampUs = timestampUs;
   2360 
   2361         if (isSync != 0) {
   2362             addOneStssTableEntry(mStszTableEntries->count());
   2363         }
   2364 
   2365         if (mTrackingProgressStatus) {
   2366             if (mPreviousTrackTimeUs <= 0) {
   2367                 mPreviousTrackTimeUs = mStartTimestampUs;
   2368             }
   2369             trackProgressStatus(timestampUs);
   2370         }
   2371         if (!hasMultipleTracks) {
   2372             off64_t offset = mIsAvc? mOwner->addLengthPrefixedSample_l(copy)
   2373                                  : mOwner->addSample_l(copy);
   2374 
   2375             uint32_t count = (mOwner->use32BitFileOffset()
   2376                         ? mStcoTableEntries->count()
   2377                         : mCo64TableEntries->count());
   2378 
   2379             if (count == 0) {
   2380                 addChunkOffset(offset);
   2381             }
   2382             copy->release();
   2383             copy = NULL;
   2384             continue;
   2385         }
   2386 
   2387         mChunkSamples.push_back(copy);
   2388         if (interleaveDurationUs == 0) {
   2389             addOneStscTableEntry(++nChunks, 1);
   2390             bufferChunk(timestampUs);
   2391         } else {
   2392             if (chunkTimestampUs == 0) {
   2393                 chunkTimestampUs = timestampUs;
   2394             } else {
   2395                 int64_t chunkDurationUs = timestampUs - chunkTimestampUs;
   2396                 if (chunkDurationUs > interleaveDurationUs) {
   2397                     if (chunkDurationUs > mMaxChunkDurationUs) {
   2398                         mMaxChunkDurationUs = chunkDurationUs;
   2399                     }
   2400                     ++nChunks;
   2401                     if (nChunks == 1 ||  // First chunk
   2402                         lastSamplesPerChunk != mChunkSamples.size()) {
   2403                         lastSamplesPerChunk = mChunkSamples.size();
   2404                         addOneStscTableEntry(nChunks, lastSamplesPerChunk);
   2405                     }
   2406                     bufferChunk(timestampUs);
   2407                     chunkTimestampUs = timestampUs;
   2408                 }
   2409             }
   2410         }
   2411 
   2412     }
   2413 
   2414     if (isTrackMalFormed()) {
   2415         err = ERROR_MALFORMED;
   2416     }
   2417 
   2418     mOwner->trackProgressStatus(mTrackId, -1, err);
   2419 
   2420     // Last chunk
   2421     if (!hasMultipleTracks) {
   2422         addOneStscTableEntry(1, mStszTableEntries->count());
   2423     } else if (!mChunkSamples.empty()) {
   2424         addOneStscTableEntry(++nChunks, mChunkSamples.size());
   2425         bufferChunk(timestampUs);
   2426     }
   2427 
   2428     // We don't really know how long the last frame lasts, since
   2429     // there is no frame time after it, just repeat the previous
   2430     // frame's duration.
   2431     if (mStszTableEntries->count() == 1) {
   2432         lastDurationUs = 0;  // A single sample's duration
   2433         lastDurationTicks = 0;
   2434     } else {
   2435         ++sampleCount;  // Count for the last sample
   2436     }
   2437 
   2438     if (mStszTableEntries->count() <= 2) {
   2439         addOneSttsTableEntry(1, lastDurationTicks);
   2440         if (sampleCount - 1 > 0) {
   2441             addOneSttsTableEntry(sampleCount - 1, lastDurationTicks);
   2442         }
   2443     } else {
   2444         addOneSttsTableEntry(sampleCount, lastDurationTicks);
   2445     }
   2446 
   2447     // The last ctts box may not have been written yet, and this
   2448     // is to make sure that we write out the last ctts box.
   2449     if (currCttsOffsetTimeTicks == lastCttsOffsetTimeTicks) {
   2450         if (cttsSampleCount > 0) {
   2451             addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
   2452         }
   2453     }
   2454 
   2455     mTrackDurationUs += lastDurationUs;
   2456     mReachedEOS = true;
   2457 
   2458     sendTrackSummary(hasMultipleTracks);
   2459 
   2460     ALOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s",
   2461             count, nZeroLengthFrames, mStszTableEntries->count(), trackName);
   2462     if (mIsAudio) {
   2463         ALOGI("Audio track drift time: %" PRId64 " us", mOwner->getDriftTimeUs());
   2464     }
   2465 
   2466     if (err == ERROR_END_OF_STREAM) {
   2467         return OK;
   2468     }
   2469     return err;
   2470 }
   2471 
   2472 bool MPEG4Writer::Track::isTrackMalFormed() const {
   2473     if (mStszTableEntries->count() == 0) {                      // no samples written
   2474         ALOGE("The number of recorded samples is 0");
   2475         return true;
   2476     }
   2477 
   2478     if (!mIsAudio && mStssTableEntries->count() == 0) {  // no sync frames for video
   2479         ALOGE("There are no sync frames for video track");
   2480         return true;
   2481     }
   2482 
   2483     if (OK != checkCodecSpecificData()) {         // no codec specific data
   2484         return true;
   2485     }
   2486 
   2487     return false;
   2488 }
   2489 
   2490 void MPEG4Writer::Track::sendTrackSummary(bool hasMultipleTracks) {
   2491 
   2492     // Send track summary only if test mode is enabled.
   2493     if (!isTestModeEnabled()) {
   2494         return;
   2495     }
   2496 
   2497     int trackNum = (mTrackId << 28);
   2498 
   2499     mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   2500                     trackNum | MEDIA_RECORDER_TRACK_INFO_TYPE,
   2501                     mIsAudio? 0: 1);
   2502 
   2503     mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   2504                     trackNum | MEDIA_RECORDER_TRACK_INFO_DURATION_MS,
   2505                     mTrackDurationUs / 1000);
   2506 
   2507     mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   2508                     trackNum | MEDIA_RECORDER_TRACK_INFO_ENCODED_FRAMES,
   2509                     mStszTableEntries->count());
   2510 
   2511     {
   2512         // The system delay time excluding the requested initial delay that
   2513         // is used to eliminate the recording sound.
   2514         int64_t startTimeOffsetUs = mOwner->getStartTimeOffsetMs() * 1000LL;
   2515         if (startTimeOffsetUs < 0) {  // Start time offset was not set
   2516             startTimeOffsetUs = kInitialDelayTimeUs;
   2517         }
   2518         int64_t initialDelayUs =
   2519             mFirstSampleTimeRealUs - mStartTimeRealUs - startTimeOffsetUs;
   2520 
   2521         mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   2522                     trackNum | MEDIA_RECORDER_TRACK_INFO_INITIAL_DELAY_MS,
   2523                     (initialDelayUs) / 1000);
   2524     }
   2525 
   2526     mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   2527                     trackNum | MEDIA_RECORDER_TRACK_INFO_DATA_KBYTES,
   2528                     mMdatSizeBytes / 1024);
   2529 
   2530     if (hasMultipleTracks) {
   2531         mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   2532                     trackNum | MEDIA_RECORDER_TRACK_INFO_MAX_CHUNK_DUR_MS,
   2533                     mMaxChunkDurationUs / 1000);
   2534 
   2535         int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
   2536         if (mStartTimestampUs != moovStartTimeUs) {
   2537             int64_t startTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
   2538             mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   2539                     trackNum | MEDIA_RECORDER_TRACK_INFO_START_OFFSET_MS,
   2540                     startTimeOffsetUs / 1000);
   2541         }
   2542     }
   2543 }
   2544 
   2545 void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) {
   2546     ALOGV("trackProgressStatus: %" PRId64 " us", timeUs);
   2547 
   2548     if (mTrackEveryTimeDurationUs > 0 &&
   2549         timeUs - mPreviousTrackTimeUs >= mTrackEveryTimeDurationUs) {
   2550         ALOGV("Fire time tracking progress status at %" PRId64 " us", timeUs);
   2551         mOwner->trackProgressStatus(mTrackId, timeUs - mPreviousTrackTimeUs, err);
   2552         mPreviousTrackTimeUs = timeUs;
   2553     }
   2554 }
   2555 
   2556 void MPEG4Writer::trackProgressStatus(
   2557         size_t trackId, int64_t timeUs, status_t err) {
   2558     Mutex::Autolock lock(mLock);
   2559     int32_t trackNum = (trackId << 28);
   2560 
   2561     // Error notification
   2562     // Do not consider ERROR_END_OF_STREAM an error
   2563     if (err != OK && err != ERROR_END_OF_STREAM) {
   2564         notify(MEDIA_RECORDER_TRACK_EVENT_ERROR,
   2565                trackNum | MEDIA_RECORDER_TRACK_ERROR_GENERAL,
   2566                err);
   2567         return;
   2568     }
   2569 
   2570     if (timeUs == -1) {
   2571         // Send completion notification
   2572         notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   2573                trackNum | MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS,
   2574                err);
   2575     } else {
   2576         // Send progress status
   2577         notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   2578                trackNum | MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME,
   2579                timeUs / 1000);
   2580     }
   2581 }
   2582 
   2583 void MPEG4Writer::setDriftTimeUs(int64_t driftTimeUs) {
   2584     ALOGV("setDriftTimeUs: %" PRId64 " us", driftTimeUs);
   2585     Mutex::Autolock autolock(mLock);
   2586     mDriftTimeUs = driftTimeUs;
   2587 }
   2588 
   2589 int64_t MPEG4Writer::getDriftTimeUs() {
   2590     ALOGV("getDriftTimeUs: %" PRId64 " us", mDriftTimeUs);
   2591     Mutex::Autolock autolock(mLock);
   2592     return mDriftTimeUs;
   2593 }
   2594 
   2595 bool MPEG4Writer::isRealTimeRecording() const {
   2596     return mIsRealTimeRecording;
   2597 }
   2598 
   2599 bool MPEG4Writer::useNalLengthFour() {
   2600     return mUse4ByteNalLength;
   2601 }
   2602 
   2603 void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) {
   2604     ALOGV("bufferChunk");
   2605 
   2606     Chunk chunk(this, timestampUs, mChunkSamples);
   2607     mOwner->bufferChunk(chunk);
   2608     mChunkSamples.clear();
   2609 }
   2610 
   2611 int64_t MPEG4Writer::Track::getDurationUs() const {
   2612     return mTrackDurationUs;
   2613 }
   2614 
   2615 int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const {
   2616     return mEstimatedTrackSizeBytes;
   2617 }
   2618 
   2619 status_t MPEG4Writer::Track::checkCodecSpecificData() const {
   2620     const char *mime;
   2621     CHECK(mMeta->findCString(kKeyMIMEType, &mime));
   2622     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime) ||
   2623         !strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime) ||
   2624         !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
   2625         if (!mCodecSpecificData ||
   2626             mCodecSpecificDataSize <= 0) {
   2627             ALOGE("Missing codec specific data");
   2628             return ERROR_MALFORMED;
   2629         }
   2630     } else {
   2631         if (mCodecSpecificData ||
   2632             mCodecSpecificDataSize > 0) {
   2633             ALOGE("Unexepected codec specific data found");
   2634             return ERROR_MALFORMED;
   2635         }
   2636     }
   2637     return OK;
   2638 }
   2639 
   2640 void MPEG4Writer::Track::writeTrackHeader(bool use32BitOffset) {
   2641 
   2642     ALOGV("%s track time scale: %d",
   2643         mIsAudio? "Audio": "Video", mTimeScale);
   2644 
   2645     uint32_t now = getMpeg4Time();
   2646     mOwner->beginBox("trak");
   2647         writeTkhdBox(now);
   2648         mOwner->beginBox("mdia");
   2649             writeMdhdBox(now);
   2650             writeHdlrBox();
   2651             mOwner->beginBox("minf");
   2652                 if (mIsAudio) {
   2653                     writeSmhdBox();
   2654                 } else {
   2655                     writeVmhdBox();
   2656                 }
   2657                 writeDinfBox();
   2658                 writeStblBox(use32BitOffset);
   2659             mOwner->endBox();  // minf
   2660         mOwner->endBox();  // mdia
   2661     mOwner->endBox();  // trak
   2662 }
   2663 
   2664 void MPEG4Writer::Track::writeStblBox(bool use32BitOffset) {
   2665     mOwner->beginBox("stbl");
   2666     mOwner->beginBox("stsd");
   2667     mOwner->writeInt32(0);               // version=0, flags=0
   2668     mOwner->writeInt32(1);               // entry count
   2669     if (mIsAudio) {
   2670         writeAudioFourCCBox();
   2671     } else {
   2672         writeVideoFourCCBox();
   2673     }
   2674     mOwner->endBox();  // stsd
   2675     writeSttsBox();
   2676     writeCttsBox();
   2677     if (!mIsAudio) {
   2678         writeStssBox();
   2679     }
   2680     writeStszBox();
   2681     writeStscBox();
   2682     writeStcoBox(use32BitOffset);
   2683     mOwner->endBox();  // stbl
   2684 }
   2685 
   2686 void MPEG4Writer::Track::writeVideoFourCCBox() {
   2687     const char *mime;
   2688     bool success = mMeta->findCString(kKeyMIMEType, &mime);
   2689     CHECK(success);
   2690     if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
   2691         mOwner->beginBox("mp4v");
   2692     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
   2693         mOwner->beginBox("s263");
   2694     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
   2695         mOwner->beginBox("avc1");
   2696     } else {
   2697         ALOGE("Unknown mime type '%s'.", mime);
   2698         CHECK(!"should not be here, unknown mime type.");
   2699     }
   2700 
   2701     mOwner->writeInt32(0);           // reserved
   2702     mOwner->writeInt16(0);           // reserved
   2703     mOwner->writeInt16(1);           // data ref index
   2704     mOwner->writeInt16(0);           // predefined
   2705     mOwner->writeInt16(0);           // reserved
   2706     mOwner->writeInt32(0);           // predefined
   2707     mOwner->writeInt32(0);           // predefined
   2708     mOwner->writeInt32(0);           // predefined
   2709 
   2710     int32_t width, height;
   2711     success = mMeta->findInt32(kKeyWidth, &width);
   2712     success = success && mMeta->findInt32(kKeyHeight, &height);
   2713     CHECK(success);
   2714 
   2715     mOwner->writeInt16(width);
   2716     mOwner->writeInt16(height);
   2717     mOwner->writeInt32(0x480000);    // horiz resolution
   2718     mOwner->writeInt32(0x480000);    // vert resolution
   2719     mOwner->writeInt32(0);           // reserved
   2720     mOwner->writeInt16(1);           // frame count
   2721     mOwner->writeInt8(0);            // compressor string length
   2722     mOwner->write("                               ", 31);
   2723     mOwner->writeInt16(0x18);        // depth
   2724     mOwner->writeInt16(-1);          // predefined
   2725 
   2726     CHECK_LT(23 + mCodecSpecificDataSize, 128);
   2727 
   2728     if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
   2729         writeMp4vEsdsBox();
   2730     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
   2731         writeD263Box();
   2732     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
   2733         writeAvccBox();
   2734     }
   2735 
   2736     writePaspBox();
   2737     mOwner->endBox();  // mp4v, s263 or avc1
   2738 }
   2739 
   2740 void MPEG4Writer::Track::writeAudioFourCCBox() {
   2741     const char *mime;
   2742     bool success = mMeta->findCString(kKeyMIMEType, &mime);
   2743     CHECK(success);
   2744     const char *fourcc = NULL;
   2745     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
   2746         fourcc = "samr";
   2747     } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
   2748         fourcc = "sawb";
   2749     } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
   2750         fourcc = "mp4a";
   2751     } else {
   2752         ALOGE("Unknown mime type '%s'.", mime);
   2753         CHECK(!"should not be here, unknown mime type.");
   2754     }
   2755 
   2756     mOwner->beginBox(fourcc);        // audio format
   2757     mOwner->writeInt32(0);           // reserved
   2758     mOwner->writeInt16(0);           // reserved
   2759     mOwner->writeInt16(0x1);         // data ref index
   2760     mOwner->writeInt32(0);           // reserved
   2761     mOwner->writeInt32(0);           // reserved
   2762     int32_t nChannels;
   2763     CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels));
   2764     mOwner->writeInt16(nChannels);   // channel count
   2765     mOwner->writeInt16(16);          // sample size
   2766     mOwner->writeInt16(0);           // predefined
   2767     mOwner->writeInt16(0);           // reserved
   2768 
   2769     int32_t samplerate;
   2770     success = mMeta->findInt32(kKeySampleRate, &samplerate);
   2771     CHECK(success);
   2772     mOwner->writeInt32(samplerate << 16);
   2773     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
   2774         writeMp4aEsdsBox();
   2775     } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime) ||
   2776                !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
   2777         writeDamrBox();
   2778     }
   2779     mOwner->endBox();
   2780 }
   2781 
   2782 void MPEG4Writer::Track::writeMp4aEsdsBox() {
   2783     mOwner->beginBox("esds");
   2784     CHECK(mCodecSpecificData);
   2785     CHECK_GT(mCodecSpecificDataSize, 0);
   2786 
   2787     // Make sure all sizes encode to a single byte.
   2788     CHECK_LT(mCodecSpecificDataSize + 23, 128);
   2789 
   2790     mOwner->writeInt32(0);     // version=0, flags=0
   2791     mOwner->writeInt8(0x03);   // ES_DescrTag
   2792     mOwner->writeInt8(23 + mCodecSpecificDataSize);
   2793     mOwner->writeInt16(0x0000);// ES_ID
   2794     mOwner->writeInt8(0x00);
   2795 
   2796     mOwner->writeInt8(0x04);   // DecoderConfigDescrTag
   2797     mOwner->writeInt8(15 + mCodecSpecificDataSize);
   2798     mOwner->writeInt8(0x40);   // objectTypeIndication ISO/IEC 14492-2
   2799     mOwner->writeInt8(0x15);   // streamType AudioStream
   2800 
   2801     mOwner->writeInt16(0x03);  // XXX
   2802     mOwner->writeInt8(0x00);   // buffer size 24-bit
   2803     mOwner->writeInt32(96000); // max bit rate
   2804     mOwner->writeInt32(96000); // avg bit rate
   2805 
   2806     mOwner->writeInt8(0x05);   // DecoderSpecificInfoTag
   2807     mOwner->writeInt8(mCodecSpecificDataSize);
   2808     mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
   2809 
   2810     static const uint8_t kData2[] = {
   2811         0x06,  // SLConfigDescriptorTag
   2812         0x01,
   2813         0x02
   2814     };
   2815     mOwner->write(kData2, sizeof(kData2));
   2816 
   2817     mOwner->endBox();  // esds
   2818 }
   2819 
   2820 void MPEG4Writer::Track::writeMp4vEsdsBox() {
   2821     CHECK(mCodecSpecificData);
   2822     CHECK_GT(mCodecSpecificDataSize, 0);
   2823     mOwner->beginBox("esds");
   2824 
   2825     mOwner->writeInt32(0);    // version=0, flags=0
   2826 
   2827     mOwner->writeInt8(0x03);  // ES_DescrTag
   2828     mOwner->writeInt8(23 + mCodecSpecificDataSize);
   2829     mOwner->writeInt16(0x0000);  // ES_ID
   2830     mOwner->writeInt8(0x1f);
   2831 
   2832     mOwner->writeInt8(0x04);  // DecoderConfigDescrTag
   2833     mOwner->writeInt8(15 + mCodecSpecificDataSize);
   2834     mOwner->writeInt8(0x20);  // objectTypeIndication ISO/IEC 14492-2
   2835     mOwner->writeInt8(0x11);  // streamType VisualStream
   2836 
   2837     static const uint8_t kData[] = {
   2838         0x01, 0x77, 0x00,
   2839         0x00, 0x03, 0xe8, 0x00,
   2840         0x00, 0x03, 0xe8, 0x00
   2841     };
   2842     mOwner->write(kData, sizeof(kData));
   2843 
   2844     mOwner->writeInt8(0x05);  // DecoderSpecificInfoTag
   2845 
   2846     mOwner->writeInt8(mCodecSpecificDataSize);
   2847     mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
   2848 
   2849     static const uint8_t kData2[] = {
   2850         0x06,  // SLConfigDescriptorTag
   2851         0x01,
   2852         0x02
   2853     };
   2854     mOwner->write(kData2, sizeof(kData2));
   2855 
   2856     mOwner->endBox();  // esds
   2857 }
   2858 
   2859 void MPEG4Writer::Track::writeTkhdBox(uint32_t now) {
   2860     mOwner->beginBox("tkhd");
   2861     // Flags = 7 to indicate that the track is enabled, and
   2862     // part of the presentation
   2863     mOwner->writeInt32(0x07);          // version=0, flags=7
   2864     mOwner->writeInt32(now);           // creation time
   2865     mOwner->writeInt32(now);           // modification time
   2866     mOwner->writeInt32(mTrackId);      // track id starts with 1
   2867     mOwner->writeInt32(0);             // reserved
   2868     int64_t trakDurationUs = getDurationUs();
   2869     int32_t mvhdTimeScale = mOwner->getTimeScale();
   2870     int32_t tkhdDuration =
   2871         (trakDurationUs * mvhdTimeScale + 5E5) / 1E6;
   2872     mOwner->writeInt32(tkhdDuration);  // in mvhd timescale
   2873     mOwner->writeInt32(0);             // reserved
   2874     mOwner->writeInt32(0);             // reserved
   2875     mOwner->writeInt16(0);             // layer
   2876     mOwner->writeInt16(0);             // alternate group
   2877     mOwner->writeInt16(mIsAudio ? 0x100 : 0);  // volume
   2878     mOwner->writeInt16(0);             // reserved
   2879 
   2880     mOwner->writeCompositionMatrix(mRotation);       // matrix
   2881 
   2882     if (mIsAudio) {
   2883         mOwner->writeInt32(0);
   2884         mOwner->writeInt32(0);
   2885     } else {
   2886         int32_t width, height;
   2887         bool success = mMeta->findInt32(kKeyWidth, &width);
   2888         success = success && mMeta->findInt32(kKeyHeight, &height);
   2889         CHECK(success);
   2890 
   2891         mOwner->writeInt32(width << 16);   // 32-bit fixed-point value
   2892         mOwner->writeInt32(height << 16);  // 32-bit fixed-point value
   2893     }
   2894     mOwner->endBox();  // tkhd
   2895 }
   2896 
   2897 void MPEG4Writer::Track::writeVmhdBox() {
   2898     mOwner->beginBox("vmhd");
   2899     mOwner->writeInt32(0x01);        // version=0, flags=1
   2900     mOwner->writeInt16(0);           // graphics mode
   2901     mOwner->writeInt16(0);           // opcolor
   2902     mOwner->writeInt16(0);
   2903     mOwner->writeInt16(0);
   2904     mOwner->endBox();
   2905 }
   2906 
   2907 void MPEG4Writer::Track::writeSmhdBox() {
   2908     mOwner->beginBox("smhd");
   2909     mOwner->writeInt32(0);           // version=0, flags=0
   2910     mOwner->writeInt16(0);           // balance
   2911     mOwner->writeInt16(0);           // reserved
   2912     mOwner->endBox();
   2913 }
   2914 
   2915 void MPEG4Writer::Track::writeHdlrBox() {
   2916     mOwner->beginBox("hdlr");
   2917     mOwner->writeInt32(0);             // version=0, flags=0
   2918     mOwner->writeInt32(0);             // component type: should be mhlr
   2919     mOwner->writeFourcc(mIsAudio ? "soun" : "vide");  // component subtype
   2920     mOwner->writeInt32(0);             // reserved
   2921     mOwner->writeInt32(0);             // reserved
   2922     mOwner->writeInt32(0);             // reserved
   2923     // Removing "r" for the name string just makes the string 4 byte aligned
   2924     mOwner->writeCString(mIsAudio ? "SoundHandle": "VideoHandle");  // name
   2925     mOwner->endBox();
   2926 }
   2927 
   2928 void MPEG4Writer::Track::writeMdhdBox(uint32_t now) {
   2929     int64_t trakDurationUs = getDurationUs();
   2930     mOwner->beginBox("mdhd");
   2931     mOwner->writeInt32(0);             // version=0, flags=0
   2932     mOwner->writeInt32(now);           // creation time
   2933     mOwner->writeInt32(now);           // modification time
   2934     mOwner->writeInt32(mTimeScale);    // media timescale
   2935     int32_t mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6;
   2936     mOwner->writeInt32(mdhdDuration);  // use media timescale
   2937     // Language follows the three letter standard ISO-639-2/T
   2938     // 'e', 'n', 'g' for "English", for instance.
   2939     // Each character is packed as the difference between its ASCII value and 0x60.
   2940     // For "English", these are 00101, 01110, 00111.
   2941     // XXX: Where is the padding bit located: 0x15C7?
   2942     mOwner->writeInt16(0);             // language code
   2943     mOwner->writeInt16(0);             // predefined
   2944     mOwner->endBox();
   2945 }
   2946 
   2947 void MPEG4Writer::Track::writeDamrBox() {
   2948     // 3gpp2 Spec AMRSampleEntry fields
   2949     mOwner->beginBox("damr");
   2950     mOwner->writeCString("   ");  // vendor: 4 bytes
   2951     mOwner->writeInt8(0);         // decoder version
   2952     mOwner->writeInt16(0x83FF);   // mode set: all enabled
   2953     mOwner->writeInt8(0);         // mode change period
   2954     mOwner->writeInt8(1);         // frames per sample
   2955     mOwner->endBox();
   2956 }
   2957 
   2958 void MPEG4Writer::Track::writeUrlBox() {
   2959     // The table index here refers to the sample description index
   2960     // in the sample table entries.
   2961     mOwner->beginBox("url ");
   2962     mOwner->writeInt32(1);  // version=0, flags=1 (self-contained)
   2963     mOwner->endBox();  // url
   2964 }
   2965 
   2966 void MPEG4Writer::Track::writeDrefBox() {
   2967     mOwner->beginBox("dref");
   2968     mOwner->writeInt32(0);  // version=0, flags=0
   2969     mOwner->writeInt32(1);  // entry count (either url or urn)
   2970     writeUrlBox();
   2971     mOwner->endBox();  // dref
   2972 }
   2973 
   2974 void MPEG4Writer::Track::writeDinfBox() {
   2975     mOwner->beginBox("dinf");
   2976     writeDrefBox();
   2977     mOwner->endBox();  // dinf
   2978 }
   2979 
   2980 void MPEG4Writer::Track::writeAvccBox() {
   2981     CHECK(mCodecSpecificData);
   2982     CHECK_GE(mCodecSpecificDataSize, 5);
   2983 
   2984     // Patch avcc's lengthSize field to match the number
   2985     // of bytes we use to indicate the size of a nal unit.
   2986     uint8_t *ptr = (uint8_t *)mCodecSpecificData;
   2987     ptr[4] = (ptr[4] & 0xfc) | (mOwner->useNalLengthFour() ? 3 : 1);
   2988     mOwner->beginBox("avcC");
   2989     mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
   2990     mOwner->endBox();  // avcC
   2991 }
   2992 
   2993 void MPEG4Writer::Track::writeD263Box() {
   2994     mOwner->beginBox("d263");
   2995     mOwner->writeInt32(0);  // vendor
   2996     mOwner->writeInt8(0);   // decoder version
   2997     mOwner->writeInt8(10);  // level: 10
   2998     mOwner->writeInt8(0);   // profile: 0
   2999     mOwner->endBox();  // d263
   3000 }
   3001 
   3002 // This is useful if the pixel is not square
   3003 void MPEG4Writer::Track::writePaspBox() {
   3004     mOwner->beginBox("pasp");
   3005     mOwner->writeInt32(1 << 16);  // hspacing
   3006     mOwner->writeInt32(1 << 16);  // vspacing
   3007     mOwner->endBox();  // pasp
   3008 }
   3009 
   3010 int32_t MPEG4Writer::Track::getStartTimeOffsetScaledTime() const {
   3011     int64_t trackStartTimeOffsetUs = 0;
   3012     int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
   3013     if (mStartTimestampUs != moovStartTimeUs) {
   3014         CHECK_GT(mStartTimestampUs, moovStartTimeUs);
   3015         trackStartTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
   3016     }
   3017     return (trackStartTimeOffsetUs *  mTimeScale + 500000LL) / 1000000LL;
   3018 }
   3019 
   3020 void MPEG4Writer::Track::writeSttsBox() {
   3021     mOwner->beginBox("stts");
   3022     mOwner->writeInt32(0);  // version=0, flags=0
   3023     uint32_t duration;
   3024     CHECK(mSttsTableEntries->get(duration, 1));
   3025     duration = htonl(duration);  // Back to host byte order
   3026     mSttsTableEntries->set(htonl(duration + getStartTimeOffsetScaledTime()), 1);
   3027     mSttsTableEntries->write(mOwner);
   3028     mOwner->endBox();  // stts
   3029 }
   3030 
   3031 void MPEG4Writer::Track::writeCttsBox() {
   3032     if (mIsAudio) {  // ctts is not for audio
   3033         return;
   3034     }
   3035 
   3036     // There is no B frame at all
   3037     if (mMinCttsOffsetTimeUs == mMaxCttsOffsetTimeUs) {
   3038         return;
   3039     }
   3040 
   3041     // Do not write ctts box when there is no need to have it.
   3042     if (mCttsTableEntries->count() == 0) {
   3043         return;
   3044     }
   3045 
   3046     ALOGV("ctts box has %d entries with range [%" PRId64 ", %" PRId64 "]",
   3047             mCttsTableEntries->count(), mMinCttsOffsetTimeUs, mMaxCttsOffsetTimeUs);
   3048 
   3049     mOwner->beginBox("ctts");
   3050     mOwner->writeInt32(0);  // version=0, flags=0
   3051     uint32_t duration;
   3052     CHECK(mCttsTableEntries->get(duration, 1));
   3053     duration = htonl(duration);  // Back host byte order
   3054     mCttsTableEntries->set(htonl(duration + getStartTimeOffsetScaledTime() - mMinCttsOffsetTimeUs), 1);
   3055     mCttsTableEntries->write(mOwner);
   3056     mOwner->endBox();  // ctts
   3057 }
   3058 
   3059 void MPEG4Writer::Track::writeStssBox() {
   3060     mOwner->beginBox("stss");
   3061     mOwner->writeInt32(0);  // version=0, flags=0
   3062     mStssTableEntries->write(mOwner);
   3063     mOwner->endBox();  // stss
   3064 }
   3065 
   3066 void MPEG4Writer::Track::writeStszBox() {
   3067     mOwner->beginBox("stsz");
   3068     mOwner->writeInt32(0);  // version=0, flags=0
   3069     mOwner->writeInt32(0);
   3070     mStszTableEntries->write(mOwner);
   3071     mOwner->endBox();  // stsz
   3072 }
   3073 
   3074 void MPEG4Writer::Track::writeStscBox() {
   3075     mOwner->beginBox("stsc");
   3076     mOwner->writeInt32(0);  // version=0, flags=0
   3077     mStscTableEntries->write(mOwner);
   3078     mOwner->endBox();  // stsc
   3079 }
   3080 
   3081 void MPEG4Writer::Track::writeStcoBox(bool use32BitOffset) {
   3082     mOwner->beginBox(use32BitOffset? "stco": "co64");
   3083     mOwner->writeInt32(0);  // version=0, flags=0
   3084     if (use32BitOffset) {
   3085         mStcoTableEntries->write(mOwner);
   3086     } else {
   3087         mCo64TableEntries->write(mOwner);
   3088     }
   3089     mOwner->endBox();  // stco or co64
   3090 }
   3091 
   3092 void MPEG4Writer::writeUdtaBox() {
   3093     beginBox("udta");
   3094     writeGeoDataBox();
   3095     endBox();
   3096 }
   3097 
   3098 /*
   3099  * Geodata is stored according to ISO-6709 standard.
   3100  */
   3101 void MPEG4Writer::writeGeoDataBox() {
   3102     beginBox("\xA9xyz");
   3103     /*
   3104      * For historical reasons, any user data start
   3105      * with "\0xA9", must be followed by its assoicated
   3106      * language code.
   3107      * 0x0012: text string length
   3108      * 0x15c7: lang (locale) code: en
   3109      */
   3110     writeInt32(0x001215c7);
   3111     writeLatitude(mLatitudex10000);
   3112     writeLongitude(mLongitudex10000);
   3113     writeInt8(0x2F);
   3114     endBox();
   3115 }
   3116 
   3117 }  // namespace android
   3118