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 <algorithm>
     21 
     22 #include <arpa/inet.h>
     23 #include <fcntl.h>
     24 #include <inttypes.h>
     25 #include <pthread.h>
     26 #include <sys/prctl.h>
     27 #include <sys/stat.h>
     28 #include <sys/types.h>
     29 #include <unistd.h>
     30 
     31 #include <utils/Log.h>
     32 
     33 #include <functional>
     34 
     35 #include <media/stagefright/foundation/ADebug.h>
     36 #include <media/stagefright/foundation/AMessage.h>
     37 #include <media/stagefright/foundation/AUtils.h>
     38 #include <media/stagefright/foundation/ColorUtils.h>
     39 #include <media/stagefright/MPEG4Writer.h>
     40 #include <media/stagefright/MediaBuffer.h>
     41 #include <media/stagefright/MetaData.h>
     42 #include <media/stagefright/MediaDefs.h>
     43 #include <media/stagefright/MediaErrors.h>
     44 #include <media/stagefright/MediaSource.h>
     45 #include <media/stagefright/Utils.h>
     46 #include <media/mediarecorder.h>
     47 #include <cutils/properties.h>
     48 
     49 #include "include/ESDS.h"
     50 #include "include/HevcUtils.h"
     51 #include "include/avc_utils.h"
     52 
     53 #ifndef __predict_false
     54 #define __predict_false(exp) __builtin_expect((exp) != 0, 0)
     55 #endif
     56 
     57 #define WARN_UNLESS(condition, message, ...) \
     58 ( (__predict_false(condition)) ? false : ({ \
     59     ALOGW("Condition %s failed "  message, #condition, ##__VA_ARGS__); \
     60     true; \
     61 }))
     62 
     63 namespace android {
     64 
     65 static const int64_t kMinStreamableFileSizeInBytes = 5 * 1024 * 1024;
     66 static const int64_t kMax32BitFileSize = 0x00ffffffffLL; // 2^32-1 : max FAT32
     67                                                          // filesystem file size
     68                                                          // used by most SD cards
     69 static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
     70 static const uint8_t kNalUnitTypePicParamSet = 0x08;
     71 static const int64_t kInitialDelayTimeUs     = 700000LL;
     72 static const int64_t kMaxMetadataSize = 0x4000000LL;   // 64MB max per-frame metadata size
     73 
     74 static const char kMetaKey_Version[]    = "com.android.version";
     75 static const char kMetaKey_Manufacturer[]      = "com.android.manufacturer";
     76 static const char kMetaKey_Model[]      = "com.android.model";
     77 
     78 #ifdef SHOW_BUILD
     79 static const char kMetaKey_Build[]      = "com.android.build";
     80 #endif
     81 static const char kMetaKey_CaptureFps[] = "com.android.capture.fps";
     82 static const char kMetaKey_TemporalLayerCount[] = "com.android.video.temporal_layers_count";
     83 
     84 static const int kTimestampDebugCount = 10;
     85 
     86 static const uint8_t kMandatoryHevcNalUnitTypes[3] = {
     87     kHevcNalUnitTypeVps,
     88     kHevcNalUnitTypeSps,
     89     kHevcNalUnitTypePps,
     90 };
     91 static const uint8_t kHevcNalUnitTypes[5] = {
     92     kHevcNalUnitTypeVps,
     93     kHevcNalUnitTypeSps,
     94     kHevcNalUnitTypePps,
     95     kHevcNalUnitTypePrefixSei,
     96     kHevcNalUnitTypeSuffixSei,
     97 };
     98 /* uncomment to include build in meta */
     99 //#define SHOW_MODEL_BUILD 1
    100 
    101 class MPEG4Writer::Track {
    102 public:
    103     Track(MPEG4Writer *owner, const sp<IMediaSource> &source, size_t trackId);
    104 
    105     ~Track();
    106 
    107     status_t start(MetaData *params);
    108     status_t stop(bool stopSource = true);
    109     status_t pause();
    110     bool reachedEOS();
    111 
    112     int64_t getDurationUs() const;
    113     int64_t getEstimatedTrackSizeBytes() const;
    114     void writeTrackHeader(bool use32BitOffset = true);
    115     int64_t getMinCttsOffsetTimeUs();
    116     void bufferChunk(int64_t timestampUs);
    117     bool isAvc() const { return mIsAvc; }
    118     bool isHevc() const { return mIsHevc; }
    119     bool isAudio() const { return mIsAudio; }
    120     bool isMPEG4() const { return mIsMPEG4; }
    121     void addChunkOffset(off64_t offset);
    122     int32_t getTrackId() const { return mTrackId; }
    123     status_t dump(int fd, const Vector<String16>& args) const;
    124     static const char *getFourCCForMime(const char *mime);
    125     const char *getTrackType() const;
    126     void resetInternal();
    127 
    128 private:
    129     enum {
    130         kMaxCttsOffsetTimeUs = 1000000LL,  // 1 second
    131         kSampleArraySize = 1000,
    132     };
    133 
    134     // A helper class to handle faster write box with table entries
    135     template<class TYPE, unsigned ENTRY_SIZE>
    136     // ENTRY_SIZE: # of values in each entry
    137     struct ListTableEntries {
    138         static_assert(ENTRY_SIZE > 0, "ENTRY_SIZE must be positive");
    139         ListTableEntries(uint32_t elementCapacity)
    140             : mElementCapacity(elementCapacity),
    141             mTotalNumTableEntries(0),
    142             mNumValuesInCurrEntry(0),
    143             mCurrTableEntriesElement(NULL) {
    144             CHECK_GT(mElementCapacity, 0u);
    145             // Ensure no integer overflow on allocation in add().
    146             CHECK_LT(ENTRY_SIZE, UINT32_MAX / mElementCapacity);
    147         }
    148 
    149         // Free the allocated memory.
    150         ~ListTableEntries() {
    151             while (!mTableEntryList.empty()) {
    152                 typename List<TYPE *>::iterator it = mTableEntryList.begin();
    153                 delete[] (*it);
    154                 mTableEntryList.erase(it);
    155             }
    156         }
    157 
    158         // Replace the value at the given position by the given value.
    159         // There must be an existing value at the given position.
    160         // @arg value must be in network byte order
    161         // @arg pos location the value must be in.
    162         void set(const TYPE& value, uint32_t pos) {
    163             CHECK_LT(pos, mTotalNumTableEntries * ENTRY_SIZE);
    164 
    165             typename List<TYPE *>::iterator it = mTableEntryList.begin();
    166             uint32_t iterations = (pos / (mElementCapacity * ENTRY_SIZE));
    167             while (it != mTableEntryList.end() && iterations > 0) {
    168                 ++it;
    169                 --iterations;
    170             }
    171             CHECK(it != mTableEntryList.end());
    172             CHECK_EQ(iterations, 0u);
    173 
    174             (*it)[(pos % (mElementCapacity * ENTRY_SIZE))] = value;
    175         }
    176 
    177         // Get the value at the given position by the given value.
    178         // @arg value the retrieved value at the position in network byte order.
    179         // @arg pos location the value must be in.
    180         // @return true if a value is found.
    181         bool get(TYPE& value, uint32_t pos) const {
    182             if (pos >= mTotalNumTableEntries * ENTRY_SIZE) {
    183                 return false;
    184             }
    185 
    186             typename List<TYPE *>::iterator it = mTableEntryList.begin();
    187             uint32_t iterations = (pos / (mElementCapacity * ENTRY_SIZE));
    188             while (it != mTableEntryList.end() && iterations > 0) {
    189                 ++it;
    190                 --iterations;
    191             }
    192             CHECK(it != mTableEntryList.end());
    193             CHECK_EQ(iterations, 0u);
    194 
    195             value = (*it)[(pos % (mElementCapacity * ENTRY_SIZE))];
    196             return true;
    197         }
    198 
    199         // adjusts all values by |adjust(value)|
    200         void adjustEntries(
    201                 std::function<void(size_t /* ix */, TYPE(& /* entry */)[ENTRY_SIZE])> update) {
    202             size_t nEntries = mTotalNumTableEntries + mNumValuesInCurrEntry / ENTRY_SIZE;
    203             size_t ix = 0;
    204             for (TYPE *entryArray : mTableEntryList) {
    205                 size_t num = std::min(nEntries, (size_t)mElementCapacity);
    206                 for (size_t i = 0; i < num; ++i) {
    207                     update(ix++, (TYPE(&)[ENTRY_SIZE])(*entryArray));
    208                     entryArray += ENTRY_SIZE;
    209                 }
    210                 nEntries -= num;
    211             }
    212         }
    213 
    214         // Store a single value.
    215         // @arg value must be in network byte order.
    216         void add(const TYPE& value) {
    217             CHECK_LT(mNumValuesInCurrEntry, mElementCapacity);
    218             uint32_t nEntries = mTotalNumTableEntries % mElementCapacity;
    219             uint32_t nValues  = mNumValuesInCurrEntry % ENTRY_SIZE;
    220             if (nEntries == 0 && nValues == 0) {
    221                 mCurrTableEntriesElement = new TYPE[ENTRY_SIZE * mElementCapacity];
    222                 CHECK(mCurrTableEntriesElement != NULL);
    223                 mTableEntryList.push_back(mCurrTableEntriesElement);
    224             }
    225 
    226             uint32_t pos = nEntries * ENTRY_SIZE + nValues;
    227             mCurrTableEntriesElement[pos] = value;
    228 
    229             ++mNumValuesInCurrEntry;
    230             if ((mNumValuesInCurrEntry % ENTRY_SIZE) == 0) {
    231                 ++mTotalNumTableEntries;
    232                 mNumValuesInCurrEntry = 0;
    233             }
    234         }
    235 
    236         // Write out the table entries:
    237         // 1. the number of entries goes first
    238         // 2. followed by the values in the table enties in order
    239         // @arg writer the writer to actual write to the storage
    240         void write(MPEG4Writer *writer) const {
    241             CHECK_EQ(mNumValuesInCurrEntry % ENTRY_SIZE, 0u);
    242             uint32_t nEntries = mTotalNumTableEntries;
    243             writer->writeInt32(nEntries);
    244             for (typename List<TYPE *>::iterator it = mTableEntryList.begin();
    245                 it != mTableEntryList.end(); ++it) {
    246                 CHECK_GT(nEntries, 0u);
    247                 if (nEntries >= mElementCapacity) {
    248                     writer->write(*it, sizeof(TYPE) * ENTRY_SIZE, mElementCapacity);
    249                     nEntries -= mElementCapacity;
    250                 } else {
    251                     writer->write(*it, sizeof(TYPE) * ENTRY_SIZE, nEntries);
    252                     break;
    253                 }
    254             }
    255         }
    256 
    257         // Return the number of entries in the table.
    258         uint32_t count() const { return mTotalNumTableEntries; }
    259 
    260     private:
    261         uint32_t         mElementCapacity;  // # entries in an element
    262         uint32_t         mTotalNumTableEntries;
    263         uint32_t         mNumValuesInCurrEntry;  // up to ENTRY_SIZE
    264         TYPE             *mCurrTableEntriesElement;
    265         mutable List<TYPE *>     mTableEntryList;
    266 
    267         DISALLOW_EVIL_CONSTRUCTORS(ListTableEntries);
    268     };
    269 
    270 
    271 
    272     MPEG4Writer *mOwner;
    273     sp<MetaData> mMeta;
    274     sp<IMediaSource> mSource;
    275     volatile bool mDone;
    276     volatile bool mPaused;
    277     volatile bool mResumed;
    278     volatile bool mStarted;
    279     bool mIsAvc;
    280     bool mIsHevc;
    281     bool mIsAudio;
    282     bool mIsVideo;
    283     bool mIsMPEG4;
    284     bool mGotStartKeyFrame;
    285     bool mIsMalformed;
    286     int32_t mTrackId;
    287     int64_t mTrackDurationUs;
    288     int64_t mMaxChunkDurationUs;
    289     int64_t mLastDecodingTimeUs;
    290 
    291     int64_t mEstimatedTrackSizeBytes;
    292     int64_t mMdatSizeBytes;
    293     int32_t mTimeScale;
    294 
    295     pthread_t mThread;
    296 
    297 
    298     List<MediaBuffer *> mChunkSamples;
    299 
    300     bool                mSamplesHaveSameSize;
    301     ListTableEntries<uint32_t, 1> *mStszTableEntries;
    302 
    303     ListTableEntries<uint32_t, 1> *mStcoTableEntries;
    304     ListTableEntries<off64_t, 1> *mCo64TableEntries;
    305     ListTableEntries<uint32_t, 3> *mStscTableEntries;
    306     ListTableEntries<uint32_t, 1> *mStssTableEntries;
    307     ListTableEntries<uint32_t, 2> *mSttsTableEntries;
    308     ListTableEntries<uint32_t, 2> *mCttsTableEntries;
    309 
    310     int64_t mMinCttsOffsetTimeUs;
    311     int64_t mMinCttsOffsetTicks;
    312     int64_t mMaxCttsOffsetTicks;
    313 
    314     // Save the last 10 frames' timestamp and frame type for debug.
    315     struct TimestampDebugHelperEntry {
    316         int64_t pts;
    317         int64_t dts;
    318         std::string frameType;
    319     };
    320 
    321     std::list<TimestampDebugHelperEntry> mTimestampDebugHelper;
    322 
    323     // Sequence parameter set or picture parameter set
    324     struct AVCParamSet {
    325         AVCParamSet(uint16_t length, const uint8_t *data)
    326             : mLength(length), mData(data) {}
    327 
    328         uint16_t mLength;
    329         const uint8_t *mData;
    330     };
    331     List<AVCParamSet> mSeqParamSets;
    332     List<AVCParamSet> mPicParamSets;
    333     uint8_t mProfileIdc;
    334     uint8_t mProfileCompatible;
    335     uint8_t mLevelIdc;
    336 
    337     void *mCodecSpecificData;
    338     size_t mCodecSpecificDataSize;
    339     bool mGotAllCodecSpecificData;
    340     bool mTrackingProgressStatus;
    341 
    342     bool mReachedEOS;
    343     int64_t mStartTimestampUs;
    344     int64_t mStartTimeRealUs;
    345     int64_t mFirstSampleTimeRealUs;
    346     int64_t mPreviousTrackTimeUs;
    347     int64_t mTrackEveryTimeDurationUs;
    348 
    349     // Update the audio track's drift information.
    350     void updateDriftTime(const sp<MetaData>& meta);
    351 
    352     void dumpTimeStamps();
    353 
    354     int64_t getStartTimeOffsetTimeUs() const;
    355     int32_t getStartTimeOffsetScaledTime() const;
    356 
    357     static void *ThreadWrapper(void *me);
    358     status_t threadEntry();
    359 
    360     const uint8_t *parseParamSet(
    361         const uint8_t *data, size_t length, int type, size_t *paramSetLen);
    362 
    363     status_t copyCodecSpecificData(const uint8_t *data, size_t size, size_t minLength = 0);
    364 
    365     status_t makeAVCCodecSpecificData(const uint8_t *data, size_t size);
    366     status_t copyAVCCodecSpecificData(const uint8_t *data, size_t size);
    367     status_t parseAVCCodecSpecificData(const uint8_t *data, size_t size);
    368 
    369     status_t makeHEVCCodecSpecificData(const uint8_t *data, size_t size);
    370     status_t copyHEVCCodecSpecificData(const uint8_t *data, size_t size);
    371     status_t parseHEVCCodecSpecificData(
    372             const uint8_t *data, size_t size, HevcParameterSets &paramSets);
    373 
    374     // Track authoring progress status
    375     void trackProgressStatus(int64_t timeUs, status_t err = OK);
    376     void initTrackingProgressStatus(MetaData *params);
    377 
    378     void getCodecSpecificDataFromInputFormatIfPossible();
    379 
    380     // Determine the track time scale
    381     // If it is an audio track, try to use the sampling rate as
    382     // the time scale; however, if user chooses the overwrite
    383     // value, the user-supplied time scale will be used.
    384     void setTimeScale();
    385 
    386     // Simple validation on the codec specific data
    387     status_t checkCodecSpecificData() const;
    388     int32_t mRotation;
    389 
    390     void updateTrackSizeEstimate();
    391     void addOneStscTableEntry(size_t chunkId, size_t sampleId);
    392     void addOneStssTableEntry(size_t sampleId);
    393 
    394     // Duration is time scale based
    395     void addOneSttsTableEntry(size_t sampleCount, int32_t timescaledDur);
    396     void addOneCttsTableEntry(size_t sampleCount, int32_t timescaledDur);
    397 
    398     bool isTrackMalFormed() const;
    399     void sendTrackSummary(bool hasMultipleTracks);
    400 
    401     // Write the boxes
    402     void writeStcoBox(bool use32BitOffset);
    403     void writeStscBox();
    404     void writeStszBox();
    405     void writeStssBox();
    406     void writeSttsBox();
    407     void writeCttsBox();
    408     void writeD263Box();
    409     void writePaspBox();
    410     void writeAvccBox();
    411     void writeHvccBox();
    412     void writeUrlBox();
    413     void writeDrefBox();
    414     void writeDinfBox();
    415     void writeDamrBox();
    416     void writeMdhdBox(uint32_t now);
    417     void writeSmhdBox();
    418     void writeVmhdBox();
    419     void writeNmhdBox();
    420     void writeHdlrBox();
    421     void writeTkhdBox(uint32_t now);
    422     void writeColrBox();
    423     void writeMp4aEsdsBox();
    424     void writeMp4vEsdsBox();
    425     void writeAudioFourCCBox();
    426     void writeVideoFourCCBox();
    427     void writeMetadataFourCCBox();
    428     void writeStblBox(bool use32BitOffset);
    429 
    430     Track(const Track &);
    431     Track &operator=(const Track &);
    432 };
    433 
    434 MPEG4Writer::MPEG4Writer(int fd) {
    435     initInternal(fd, true /*isFirstSession*/);
    436 }
    437 
    438 MPEG4Writer::~MPEG4Writer() {
    439     reset();
    440 
    441     while (!mTracks.empty()) {
    442         List<Track *>::iterator it = mTracks.begin();
    443         delete *it;
    444         (*it) = NULL;
    445         mTracks.erase(it);
    446     }
    447     mTracks.clear();
    448 
    449     if (mNextFd != -1) {
    450         close(mNextFd);
    451     }
    452 }
    453 
    454 void MPEG4Writer::initInternal(int fd, bool isFirstSession) {
    455     ALOGV("initInternal");
    456     mFd = dup(fd);
    457     mNextFd = -1;
    458     mInitCheck = mFd < 0? NO_INIT: OK;
    459 
    460     mInterleaveDurationUs = 1000000;
    461 
    462     mStartTimestampUs = -1ll;
    463     mStartTimeOffsetMs = -1;
    464     mPaused = false;
    465     mStarted = false;
    466     mWriterThreadStarted = false;
    467     mSendNotify = false;
    468 
    469     // Reset following variables for all the sessions and they will be
    470     // initialized in start(MetaData *param).
    471     mIsRealTimeRecording = true;
    472     mUse4ByteNalLength = true;
    473     mUse32BitOffset = true;
    474     mOffset = 0;
    475     mMdatOffset = 0;
    476     mMoovBoxBuffer = NULL;
    477     mMoovBoxBufferOffset = 0;
    478     mWriteMoovBoxToMemory = false;
    479     mFreeBoxOffset = 0;
    480     mStreamableFile = false;
    481     mEstimatedMoovBoxSize = 0;
    482     mTimeScale = -1;
    483 
    484     // Following variables only need to be set for the first recording session.
    485     // And they will stay the same for all the recording sessions.
    486     if (isFirstSession) {
    487         mMoovExtraSize = 0;
    488         mMetaKeys = new AMessage();
    489         addDeviceMeta();
    490         mLatitudex10000 = 0;
    491         mLongitudex10000 = 0;
    492         mAreGeoTagsAvailable = false;
    493         mSwitchPending = false;
    494         mIsFileSizeLimitExplicitlyRequested = false;
    495     }
    496 
    497     // Verify mFd is seekable
    498     off64_t off = lseek64(mFd, 0, SEEK_SET);
    499     if (off < 0) {
    500         ALOGE("cannot seek mFd: %s (%d) %lld", strerror(errno), errno, (long long)mFd);
    501         release();
    502     }
    503     for (List<Track *>::iterator it = mTracks.begin();
    504          it != mTracks.end(); ++it) {
    505         (*it)->resetInternal();
    506     }
    507 }
    508 
    509 status_t MPEG4Writer::dump(
    510         int fd, const Vector<String16>& args) {
    511     const size_t SIZE = 256;
    512     char buffer[SIZE];
    513     String8 result;
    514     snprintf(buffer, SIZE, "   MPEG4Writer %p\n", this);
    515     result.append(buffer);
    516     snprintf(buffer, SIZE, "     mStarted: %s\n", mStarted? "true": "false");
    517     result.append(buffer);
    518     ::write(fd, result.string(), result.size());
    519     for (List<Track *>::iterator it = mTracks.begin();
    520          it != mTracks.end(); ++it) {
    521         (*it)->dump(fd, args);
    522     }
    523     return OK;
    524 }
    525 
    526 status_t MPEG4Writer::Track::dump(
    527         int fd, const Vector<String16>& /* args */) const {
    528     const size_t SIZE = 256;
    529     char buffer[SIZE];
    530     String8 result;
    531     snprintf(buffer, SIZE, "     %s track\n", getTrackType());
    532     result.append(buffer);
    533     snprintf(buffer, SIZE, "       reached EOS: %s\n",
    534             mReachedEOS? "true": "false");
    535     result.append(buffer);
    536     snprintf(buffer, SIZE, "       frames encoded : %d\n", mStszTableEntries->count());
    537     result.append(buffer);
    538     snprintf(buffer, SIZE, "       duration encoded : %" PRId64 " us\n", mTrackDurationUs);
    539     result.append(buffer);
    540     ::write(fd, result.string(), result.size());
    541     return OK;
    542 }
    543 
    544 // static
    545 const char *MPEG4Writer::Track::getFourCCForMime(const char *mime) {
    546     if (mime == NULL) {
    547         return NULL;
    548     }
    549     if (!strncasecmp(mime, "audio/", 6)) {
    550         if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime)) {
    551             return "samr";
    552         } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
    553             return "sawb";
    554         } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
    555             return "mp4a";
    556         }
    557     } else if (!strncasecmp(mime, "video/", 6)) {
    558         if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
    559             return "mp4v";
    560         } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
    561             return "s263";
    562         } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
    563             return "avc1";
    564         } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) {
    565             return "hvc1";
    566         }
    567     } else if (!strncasecmp(mime, "application/", 12)) {
    568         return "mett";
    569     } else {
    570         ALOGE("Track (%s) other than video/audio/metadata is not supported", mime);
    571     }
    572     return NULL;
    573 }
    574 
    575 status_t MPEG4Writer::addSource(const sp<IMediaSource> &source) {
    576     Mutex::Autolock l(mLock);
    577     if (mStarted) {
    578         ALOGE("Attempt to add source AFTER recording is started");
    579         return UNKNOWN_ERROR;
    580     }
    581 
    582     CHECK(source.get() != NULL);
    583 
    584     const char *mime;
    585     source->getFormat()->findCString(kKeyMIMEType, &mime);
    586 
    587     if (Track::getFourCCForMime(mime) == NULL) {
    588         ALOGE("Unsupported mime '%s'", mime);
    589         return ERROR_UNSUPPORTED;
    590     }
    591 
    592     // This is a metadata track or the first track of either audio or video
    593     // Go ahead to add the track.
    594     Track *track = new Track(this, source, 1 + mTracks.size());
    595     mTracks.push_back(track);
    596 
    597     return OK;
    598 }
    599 
    600 status_t MPEG4Writer::startTracks(MetaData *params) {
    601     if (mTracks.empty()) {
    602         ALOGE("No source added");
    603         return INVALID_OPERATION;
    604     }
    605 
    606     for (List<Track *>::iterator it = mTracks.begin();
    607          it != mTracks.end(); ++it) {
    608         status_t err = (*it)->start(params);
    609 
    610         if (err != OK) {
    611             for (List<Track *>::iterator it2 = mTracks.begin();
    612                  it2 != it; ++it2) {
    613                 (*it2)->stop();
    614             }
    615 
    616             return err;
    617         }
    618     }
    619     return OK;
    620 }
    621 
    622 void MPEG4Writer::addDeviceMeta() {
    623     // add device info and estimate space in 'moov'
    624     char val[PROPERTY_VALUE_MAX];
    625     size_t n;
    626     // meta size is estimated by adding up the following:
    627     // - meta header structures, which occur only once (total 66 bytes)
    628     // - size for each key, which consists of a fixed header (32 bytes),
    629     //   plus key length and data length.
    630     mMoovExtraSize += 66;
    631     if (property_get("ro.build.version.release", val, NULL)
    632             && (n = strlen(val)) > 0) {
    633         mMetaKeys->setString(kMetaKey_Version, val, n + 1);
    634         mMoovExtraSize += sizeof(kMetaKey_Version) + n + 32;
    635     }
    636 
    637     if (property_get_bool("media.recorder.show_manufacturer_and_model", false)) {
    638         if (property_get("ro.product.manufacturer", val, NULL)
    639                 && (n = strlen(val)) > 0) {
    640             mMetaKeys->setString(kMetaKey_Manufacturer, val, n + 1);
    641             mMoovExtraSize += sizeof(kMetaKey_Manufacturer) + n + 32;
    642         }
    643         if (property_get("ro.product.model", val, NULL)
    644                 && (n = strlen(val)) > 0) {
    645             mMetaKeys->setString(kMetaKey_Model, val, n + 1);
    646             mMoovExtraSize += sizeof(kMetaKey_Model) + n + 32;
    647         }
    648     }
    649 #ifdef SHOW_MODEL_BUILD
    650     if (property_get("ro.build.display.id", val, NULL)
    651             && (n = strlen(val)) > 0) {
    652         mMetaKeys->setString(kMetaKey_Build, val, n + 1);
    653         mMoovExtraSize += sizeof(kMetaKey_Build) + n + 32;
    654     }
    655 #endif
    656 }
    657 
    658 int64_t MPEG4Writer::estimateMoovBoxSize(int32_t bitRate) {
    659     // This implementation is highly experimental/heurisitic.
    660     //
    661     // Statistical analysis shows that metadata usually accounts
    662     // for a small portion of the total file size, usually < 0.6%.
    663 
    664     // The default MIN_MOOV_BOX_SIZE is set to 0.6% x 1MB / 2,
    665     // where 1MB is the common file size limit for MMS application.
    666     // The default MAX _MOOV_BOX_SIZE value is based on about 3
    667     // minute video recording with a bit rate about 3 Mbps, because
    668     // statistics also show that most of the video captured are going
    669     // to be less than 3 minutes.
    670 
    671     // If the estimation is wrong, we will pay the price of wasting
    672     // some reserved space. This should not happen so often statistically.
    673     static const int32_t factor = mUse32BitOffset? 1: 2;
    674     static const int64_t MIN_MOOV_BOX_SIZE = 3 * 1024;  // 3 KB
    675     static const int64_t MAX_MOOV_BOX_SIZE = (180 * 3000000 * 6LL / 8000);
    676     int64_t size = MIN_MOOV_BOX_SIZE;
    677 
    678     // Max file size limit is set
    679     if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
    680         size = mMaxFileSizeLimitBytes * 6 / 1000;
    681     }
    682 
    683     // Max file duration limit is set
    684     if (mMaxFileDurationLimitUs != 0) {
    685         if (bitRate > 0) {
    686             int64_t size2 =
    687                 ((mMaxFileDurationLimitUs / 1000) * bitRate * 6) / 8000000;
    688             if (mMaxFileSizeLimitBytes != 0 && mIsFileSizeLimitExplicitlyRequested) {
    689                 // When both file size and duration limits are set,
    690                 // we use the smaller limit of the two.
    691                 if (size > size2) {
    692                     size = size2;
    693                 }
    694             } else {
    695                 // Only max file duration limit is set
    696                 size = size2;
    697             }
    698         }
    699     }
    700 
    701     if (size < MIN_MOOV_BOX_SIZE) {
    702         size = MIN_MOOV_BOX_SIZE;
    703     }
    704 
    705     // Any long duration recording will be probably end up with
    706     // non-streamable mp4 file.
    707     if (size > MAX_MOOV_BOX_SIZE) {
    708         size = MAX_MOOV_BOX_SIZE;
    709     }
    710 
    711     // Account for the extra stuff (Geo, meta keys, etc.)
    712     size += mMoovExtraSize;
    713 
    714     ALOGI("limits: %" PRId64 "/%" PRId64 " bytes/us, bit rate: %d bps and the"
    715          " estimated moov size %" PRId64 " bytes",
    716          mMaxFileSizeLimitBytes, mMaxFileDurationLimitUs, bitRate, size);
    717     return factor * size;
    718 }
    719 
    720 status_t MPEG4Writer::start(MetaData *param) {
    721     if (mInitCheck != OK) {
    722         return UNKNOWN_ERROR;
    723     }
    724     mStartMeta = param;
    725 
    726     /*
    727      * Check mMaxFileSizeLimitBytes at the beginning
    728      * since mMaxFileSizeLimitBytes may be implicitly
    729      * changed later for 32-bit file offset even if
    730      * user does not ask to set it explicitly.
    731      */
    732     if (mMaxFileSizeLimitBytes != 0) {
    733         mIsFileSizeLimitExplicitlyRequested = true;
    734     }
    735 
    736     int32_t use64BitOffset;
    737     if (param &&
    738         param->findInt32(kKey64BitFileOffset, &use64BitOffset) &&
    739         use64BitOffset) {
    740         mUse32BitOffset = false;
    741     }
    742 
    743     if (mUse32BitOffset) {
    744         // Implicit 32 bit file size limit
    745         if (mMaxFileSizeLimitBytes == 0) {
    746             mMaxFileSizeLimitBytes = kMax32BitFileSize;
    747         }
    748 
    749         // If file size is set to be larger than the 32 bit file
    750         // size limit, treat it as an error.
    751         if (mMaxFileSizeLimitBytes > kMax32BitFileSize) {
    752             ALOGW("32-bit file size limit (%" PRId64 " bytes) too big. "
    753                  "It is changed to %" PRId64 " bytes",
    754                 mMaxFileSizeLimitBytes, kMax32BitFileSize);
    755             mMaxFileSizeLimitBytes = kMax32BitFileSize;
    756         }
    757     }
    758 
    759     int32_t use2ByteNalLength;
    760     if (param &&
    761         param->findInt32(kKey2ByteNalLength, &use2ByteNalLength) &&
    762         use2ByteNalLength) {
    763         mUse4ByteNalLength = false;
    764     }
    765 
    766     int32_t isRealTimeRecording;
    767     if (param && param->findInt32(kKeyRealTimeRecording, &isRealTimeRecording)) {
    768         mIsRealTimeRecording = isRealTimeRecording;
    769     }
    770 
    771     mStartTimestampUs = -1;
    772 
    773     if (mStarted) {
    774         if (mPaused) {
    775             mPaused = false;
    776             return startTracks(param);
    777         }
    778         return OK;
    779     }
    780 
    781     if (!param ||
    782         !param->findInt32(kKeyTimeScale, &mTimeScale)) {
    783         mTimeScale = 1000;
    784     }
    785     CHECK_GT(mTimeScale, 0);
    786     ALOGV("movie time scale: %d", mTimeScale);
    787 
    788     /*
    789      * When the requested file size limit is small, the priority
    790      * is to meet the file size limit requirement, rather than
    791      * to make the file streamable. mStreamableFile does not tell
    792      * whether the actual recorded file is streamable or not.
    793      */
    794     mStreamableFile =
    795         (mMaxFileSizeLimitBytes != 0 &&
    796          mMaxFileSizeLimitBytes >= kMinStreamableFileSizeInBytes);
    797 
    798     /*
    799      * mWriteMoovBoxToMemory is true if the amount of data in moov box is
    800      * smaller than the reserved free space at the beginning of a file, AND
    801      * when the content of moov box is constructed. Note that video/audio
    802      * frame data is always written to the file but not in the memory.
    803      *
    804      * Before stop()/reset() is called, mWriteMoovBoxToMemory is always
    805      * false. When reset() is called at the end of a recording session,
    806      * Moov box needs to be constructed.
    807      *
    808      * 1) Right before a moov box is constructed, mWriteMoovBoxToMemory
    809      * to set to mStreamableFile so that if
    810      * the file is intended to be streamable, it is set to true;
    811      * otherwise, it is set to false. When the value is set to false,
    812      * all the content of the moov box is written immediately to
    813      * the end of the file. When the value is set to true, all the
    814      * content of the moov box is written to an in-memory cache,
    815      * mMoovBoxBuffer, util the following condition happens. Note
    816      * that the size of the in-memory cache is the same as the
    817      * reserved free space at the beginning of the file.
    818      *
    819      * 2) While the data of the moov box is written to an in-memory
    820      * cache, the data size is checked against the reserved space.
    821      * If the data size surpasses the reserved space, subsequent moov
    822      * data could no longer be hold in the in-memory cache. This also
    823      * indicates that the reserved space was too small. At this point,
    824      * _all_ moov data must be written to the end of the file.
    825      * mWriteMoovBoxToMemory must be set to false to direct the write
    826      * to the file.
    827      *
    828      * 3) If the data size in moov box is smaller than the reserved
    829      * space after moov box is completely constructed, the in-memory
    830      * cache copy of the moov box is written to the reserved free
    831      * space. Thus, immediately after the moov is completedly
    832      * constructed, mWriteMoovBoxToMemory is always set to false.
    833      */
    834     mWriteMoovBoxToMemory = false;
    835     mMoovBoxBuffer = NULL;
    836     mMoovBoxBufferOffset = 0;
    837 
    838     writeFtypBox(param);
    839 
    840     mFreeBoxOffset = mOffset;
    841 
    842     if (mEstimatedMoovBoxSize == 0) {
    843         int32_t bitRate = -1;
    844         if (param) {
    845             param->findInt32(kKeyBitRate, &bitRate);
    846         }
    847         mEstimatedMoovBoxSize = estimateMoovBoxSize(bitRate);
    848     }
    849     CHECK_GE(mEstimatedMoovBoxSize, 8);
    850     if (mStreamableFile) {
    851         // Reserve a 'free' box only for streamable file
    852         lseek64(mFd, mFreeBoxOffset, SEEK_SET);
    853         writeInt32(mEstimatedMoovBoxSize);
    854         write("free", 4);
    855         mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize;
    856     } else {
    857         mMdatOffset = mOffset;
    858     }
    859 
    860     mOffset = mMdatOffset;
    861     lseek64(mFd, mMdatOffset, SEEK_SET);
    862     if (mUse32BitOffset) {
    863         write("????mdat", 8);
    864     } else {
    865         write("\x00\x00\x00\x01mdat????????", 16);
    866     }
    867 
    868     status_t err = startWriterThread();
    869     if (err != OK) {
    870         return err;
    871     }
    872 
    873     err = startTracks(param);
    874     if (err != OK) {
    875         return err;
    876     }
    877 
    878     mStarted = true;
    879     return OK;
    880 }
    881 
    882 bool MPEG4Writer::use32BitFileOffset() const {
    883     return mUse32BitOffset;
    884 }
    885 
    886 status_t MPEG4Writer::pause() {
    887     ALOGW("MPEG4Writer: pause is not supported");
    888     return ERROR_UNSUPPORTED;
    889 }
    890 
    891 void MPEG4Writer::stopWriterThread() {
    892     ALOGD("Stopping writer thread");
    893     if (!mWriterThreadStarted) {
    894         return;
    895     }
    896 
    897     {
    898         Mutex::Autolock autolock(mLock);
    899 
    900         mDone = true;
    901         mChunkReadyCondition.signal();
    902     }
    903 
    904     void *dummy;
    905     pthread_join(mThread, &dummy);
    906     mWriterThreadStarted = false;
    907     ALOGD("Writer thread stopped");
    908 }
    909 
    910 /*
    911  * MP4 file standard defines a composition matrix:
    912  * | a  b  u |
    913  * | c  d  v |
    914  * | x  y  w |
    915  *
    916  * the element in the matrix is stored in the following
    917  * order: {a, b, u, c, d, v, x, y, w},
    918  * where a, b, c, d, x, and y is in 16.16 format, while
    919  * u, v and w is in 2.30 format.
    920  */
    921 void MPEG4Writer::writeCompositionMatrix(int degrees) {
    922     ALOGV("writeCompositionMatrix");
    923     uint32_t a = 0x00010000;
    924     uint32_t b = 0;
    925     uint32_t c = 0;
    926     uint32_t d = 0x00010000;
    927     switch (degrees) {
    928         case 0:
    929             break;
    930         case 90:
    931             a = 0;
    932             b = 0x00010000;
    933             c = 0xFFFF0000;
    934             d = 0;
    935             break;
    936         case 180:
    937             a = 0xFFFF0000;
    938             d = 0xFFFF0000;
    939             break;
    940         case 270:
    941             a = 0;
    942             b = 0xFFFF0000;
    943             c = 0x00010000;
    944             d = 0;
    945             break;
    946         default:
    947             CHECK(!"Should never reach this unknown rotation");
    948             break;
    949     }
    950 
    951     writeInt32(a);           // a
    952     writeInt32(b);           // b
    953     writeInt32(0);           // u
    954     writeInt32(c);           // c
    955     writeInt32(d);           // d
    956     writeInt32(0);           // v
    957     writeInt32(0);           // x
    958     writeInt32(0);           // y
    959     writeInt32(0x40000000);  // w
    960 }
    961 
    962 void MPEG4Writer::release() {
    963     close(mFd);
    964     mFd = -1;
    965     mInitCheck = NO_INIT;
    966     mStarted = false;
    967     free(mMoovBoxBuffer);
    968     mMoovBoxBuffer = NULL;
    969 }
    970 
    971 void MPEG4Writer::finishCurrentSession() {
    972     reset(false /* stopSource */);
    973 }
    974 
    975 status_t MPEG4Writer::switchFd() {
    976     ALOGV("switchFd");
    977     Mutex::Autolock l(mLock);
    978     if (mSwitchPending) {
    979         return OK;
    980     }
    981 
    982     if (mNextFd == -1) {
    983         ALOGW("No FileDescripter for next recording");
    984         return INVALID_OPERATION;
    985     }
    986 
    987     mSwitchPending = true;
    988     sp<AMessage> msg = new AMessage(kWhatSwitch, mReflector);
    989     status_t err = msg->post();
    990 
    991     return err;
    992 }
    993 
    994 status_t MPEG4Writer::reset(bool stopSource) {
    995     if (mInitCheck != OK) {
    996         return OK;
    997     } else {
    998         if (!mWriterThreadStarted ||
    999             !mStarted) {
   1000             if (mWriterThreadStarted) {
   1001                 stopWriterThread();
   1002             }
   1003             release();
   1004             return OK;
   1005         }
   1006     }
   1007 
   1008     status_t err = OK;
   1009     int64_t maxDurationUs = 0;
   1010     int64_t minDurationUs = 0x7fffffffffffffffLL;
   1011     for (List<Track *>::iterator it = mTracks.begin();
   1012          it != mTracks.end(); ++it) {
   1013         status_t status = (*it)->stop(stopSource);
   1014         if (err == OK && status != OK) {
   1015             err = status;
   1016         }
   1017 
   1018         int64_t durationUs = (*it)->getDurationUs();
   1019         if (durationUs > maxDurationUs) {
   1020             maxDurationUs = durationUs;
   1021         }
   1022         if (durationUs < minDurationUs) {
   1023             minDurationUs = durationUs;
   1024         }
   1025     }
   1026 
   1027     if (mTracks.size() > 1) {
   1028         ALOGD("Duration from tracks range is [%" PRId64 ", %" PRId64 "] us",
   1029             minDurationUs, maxDurationUs);
   1030     }
   1031 
   1032     stopWriterThread();
   1033 
   1034     // Do not write out movie header on error.
   1035     if (err != OK) {
   1036         release();
   1037         return err;
   1038     }
   1039 
   1040     // Fix up the size of the 'mdat' chunk.
   1041     if (mUse32BitOffset) {
   1042         lseek64(mFd, mMdatOffset, SEEK_SET);
   1043         uint32_t size = htonl(static_cast<uint32_t>(mOffset - mMdatOffset));
   1044         ::write(mFd, &size, 4);
   1045     } else {
   1046         lseek64(mFd, mMdatOffset + 8, SEEK_SET);
   1047         uint64_t size = mOffset - mMdatOffset;
   1048         size = hton64(size);
   1049         ::write(mFd, &size, 8);
   1050     }
   1051     lseek64(mFd, mOffset, SEEK_SET);
   1052 
   1053     // Construct moov box now
   1054     mMoovBoxBufferOffset = 0;
   1055     mWriteMoovBoxToMemory = mStreamableFile;
   1056     if (mWriteMoovBoxToMemory) {
   1057         // There is no need to allocate in-memory cache
   1058         // for moov box if the file is not streamable.
   1059 
   1060         mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize);
   1061         CHECK(mMoovBoxBuffer != NULL);
   1062     }
   1063     writeMoovBox(maxDurationUs);
   1064 
   1065     // mWriteMoovBoxToMemory could be set to false in
   1066     // MPEG4Writer::write() method
   1067     if (mWriteMoovBoxToMemory) {
   1068         mWriteMoovBoxToMemory = false;
   1069         // Content of the moov box is saved in the cache, and the in-memory
   1070         // moov box needs to be written to the file in a single shot.
   1071 
   1072         CHECK_LE(mMoovBoxBufferOffset + 8, mEstimatedMoovBoxSize);
   1073 
   1074         // Moov box
   1075         lseek64(mFd, mFreeBoxOffset, SEEK_SET);
   1076         mOffset = mFreeBoxOffset;
   1077         write(mMoovBoxBuffer, 1, mMoovBoxBufferOffset);
   1078 
   1079         // Free box
   1080         lseek64(mFd, mOffset, SEEK_SET);
   1081         writeInt32(mEstimatedMoovBoxSize - mMoovBoxBufferOffset);
   1082         write("free", 4);
   1083     } else {
   1084         ALOGI("The mp4 file will not be streamable.");
   1085     }
   1086 
   1087     // Free in-memory cache for moov box
   1088     if (mMoovBoxBuffer != NULL) {
   1089         free(mMoovBoxBuffer);
   1090         mMoovBoxBuffer = NULL;
   1091         mMoovBoxBufferOffset = 0;
   1092     }
   1093 
   1094     CHECK(mBoxes.empty());
   1095 
   1096     release();
   1097     return err;
   1098 }
   1099 
   1100 uint32_t MPEG4Writer::getMpeg4Time() {
   1101     time_t now = time(NULL);
   1102     // MP4 file uses time counting seconds since midnight, Jan. 1, 1904
   1103     // while time function returns Unix epoch values which starts
   1104     // at 1970-01-01. Lets add the number of seconds between them
   1105     static const uint32_t delta = (66 * 365 + 17) * (24 * 60 * 60);
   1106     if (now < 0 || uint32_t(now) > UINT32_MAX - delta) {
   1107         return 0;
   1108     }
   1109     uint32_t mpeg4Time = uint32_t(now) + delta;
   1110     return mpeg4Time;
   1111 }
   1112 
   1113 void MPEG4Writer::writeMvhdBox(int64_t durationUs) {
   1114     uint32_t now = getMpeg4Time();
   1115     beginBox("mvhd");
   1116     writeInt32(0);             // version=0, flags=0
   1117     writeInt32(now);           // creation time
   1118     writeInt32(now);           // modification time
   1119     writeInt32(mTimeScale);    // mvhd timescale
   1120     int32_t duration = (durationUs * mTimeScale + 5E5) / 1E6;
   1121     writeInt32(duration);
   1122     writeInt32(0x10000);       // rate: 1.0
   1123     writeInt16(0x100);         // volume
   1124     writeInt16(0);             // reserved
   1125     writeInt32(0);             // reserved
   1126     writeInt32(0);             // reserved
   1127     writeCompositionMatrix(0); // matrix
   1128     writeInt32(0);             // predefined
   1129     writeInt32(0);             // predefined
   1130     writeInt32(0);             // predefined
   1131     writeInt32(0);             // predefined
   1132     writeInt32(0);             // predefined
   1133     writeInt32(0);             // predefined
   1134     writeInt32(mTracks.size() + 1);  // nextTrackID
   1135     endBox();  // mvhd
   1136 }
   1137 
   1138 void MPEG4Writer::writeMoovBox(int64_t durationUs) {
   1139     beginBox("moov");
   1140     writeMvhdBox(durationUs);
   1141     if (mAreGeoTagsAvailable) {
   1142         writeUdtaBox();
   1143     }
   1144     writeMetaBox();
   1145     // Loop through all the tracks to get the global time offset if there is
   1146     // any ctts table appears in a video track.
   1147     int64_t minCttsOffsetTimeUs = kMaxCttsOffsetTimeUs;
   1148     for (List<Track *>::iterator it = mTracks.begin();
   1149         it != mTracks.end(); ++it) {
   1150         minCttsOffsetTimeUs =
   1151             std::min(minCttsOffsetTimeUs, (*it)->getMinCttsOffsetTimeUs());
   1152     }
   1153     ALOGI("Ajust the moov start time from %lld us -> %lld us",
   1154             (long long)mStartTimestampUs,
   1155             (long long)(mStartTimestampUs + minCttsOffsetTimeUs - kMaxCttsOffsetTimeUs));
   1156     // Adjust the global start time.
   1157     mStartTimestampUs += minCttsOffsetTimeUs - kMaxCttsOffsetTimeUs;
   1158 
   1159     for (List<Track *>::iterator it = mTracks.begin();
   1160         it != mTracks.end(); ++it) {
   1161         (*it)->writeTrackHeader(mUse32BitOffset);
   1162     }
   1163     endBox();  // moov
   1164 }
   1165 
   1166 void MPEG4Writer::writeFtypBox(MetaData *param) {
   1167     beginBox("ftyp");
   1168 
   1169     int32_t fileType;
   1170     if (param && param->findInt32(kKeyFileType, &fileType) &&
   1171         fileType != OUTPUT_FORMAT_MPEG_4) {
   1172         writeFourcc("3gp4");
   1173         writeInt32(0);
   1174         writeFourcc("isom");
   1175         writeFourcc("3gp4");
   1176     } else {
   1177         writeFourcc("mp42");
   1178         writeInt32(0);
   1179         writeFourcc("isom");
   1180         writeFourcc("mp42");
   1181     }
   1182 
   1183     endBox();
   1184 }
   1185 
   1186 static bool isTestModeEnabled() {
   1187 #if (PROPERTY_VALUE_MAX < 5)
   1188 #error "PROPERTY_VALUE_MAX must be at least 5"
   1189 #endif
   1190 
   1191     // Test mode is enabled only if rw.media.record.test system
   1192     // property is enabled.
   1193     if (property_get_bool("rw.media.record.test", false)) {
   1194         return true;
   1195     }
   1196     return false;
   1197 }
   1198 
   1199 void MPEG4Writer::sendSessionSummary() {
   1200     // Send session summary only if test mode is enabled
   1201     if (!isTestModeEnabled()) {
   1202         return;
   1203     }
   1204 
   1205     for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
   1206          it != mChunkInfos.end(); ++it) {
   1207         int trackNum = it->mTrack->getTrackId() << 28;
   1208         notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   1209                 trackNum | MEDIA_RECORDER_TRACK_INTER_CHUNK_TIME_MS,
   1210                 it->mMaxInterChunkDurUs);
   1211     }
   1212 }
   1213 
   1214 status_t MPEG4Writer::setInterleaveDuration(uint32_t durationUs) {
   1215     mInterleaveDurationUs = durationUs;
   1216     return OK;
   1217 }
   1218 
   1219 void MPEG4Writer::lock() {
   1220     mLock.lock();
   1221 }
   1222 
   1223 void MPEG4Writer::unlock() {
   1224     mLock.unlock();
   1225 }
   1226 
   1227 off64_t MPEG4Writer::addSample_l(MediaBuffer *buffer) {
   1228     off64_t old_offset = mOffset;
   1229 
   1230     ::write(mFd,
   1231           (const uint8_t *)buffer->data() + buffer->range_offset(),
   1232           buffer->range_length());
   1233 
   1234     mOffset += buffer->range_length();
   1235 
   1236     return old_offset;
   1237 }
   1238 
   1239 static void StripStartcode(MediaBuffer *buffer) {
   1240     if (buffer->range_length() < 4) {
   1241         return;
   1242     }
   1243 
   1244     const uint8_t *ptr =
   1245         (const uint8_t *)buffer->data() + buffer->range_offset();
   1246 
   1247     if (!memcmp(ptr, "\x00\x00\x00\x01", 4)) {
   1248         buffer->set_range(
   1249                 buffer->range_offset() + 4, buffer->range_length() - 4);
   1250     }
   1251 }
   1252 
   1253 off64_t MPEG4Writer::addMultipleLengthPrefixedSamples_l(MediaBuffer *buffer) {
   1254     off64_t old_offset = mOffset;
   1255 
   1256     const size_t kExtensionNALSearchRange = 64; // bytes to look for non-VCL NALUs
   1257 
   1258     const uint8_t *dataStart = (const uint8_t *)buffer->data() + buffer->range_offset();
   1259     const uint8_t *currentNalStart = dataStart;
   1260     const uint8_t *nextNalStart;
   1261     const uint8_t *data = dataStart;
   1262     size_t nextNalSize;
   1263     size_t searchSize = buffer->range_length() > kExtensionNALSearchRange ?
   1264                    kExtensionNALSearchRange : buffer->range_length();
   1265 
   1266     while (getNextNALUnit(&data, &searchSize, &nextNalStart,
   1267             &nextNalSize, true) == OK) {
   1268         size_t currentNalSize = nextNalStart - currentNalStart - 4 /* strip start-code */;
   1269         MediaBuffer *nalBuf = new MediaBuffer((void *)currentNalStart, currentNalSize);
   1270         addLengthPrefixedSample_l(nalBuf);
   1271         nalBuf->release();
   1272 
   1273         currentNalStart = nextNalStart;
   1274     }
   1275 
   1276     size_t currentNalOffset = currentNalStart - dataStart;
   1277     buffer->set_range(buffer->range_offset() + currentNalOffset,
   1278             buffer->range_length() - currentNalOffset);
   1279     addLengthPrefixedSample_l(buffer);
   1280 
   1281     return old_offset;
   1282 }
   1283 
   1284 off64_t MPEG4Writer::addLengthPrefixedSample_l(MediaBuffer *buffer) {
   1285     off64_t old_offset = mOffset;
   1286 
   1287     size_t length = buffer->range_length();
   1288 
   1289     if (mUse4ByteNalLength) {
   1290         uint8_t x = length >> 24;
   1291         ::write(mFd, &x, 1);
   1292         x = (length >> 16) & 0xff;
   1293         ::write(mFd, &x, 1);
   1294         x = (length >> 8) & 0xff;
   1295         ::write(mFd, &x, 1);
   1296         x = length & 0xff;
   1297         ::write(mFd, &x, 1);
   1298 
   1299         ::write(mFd,
   1300               (const uint8_t *)buffer->data() + buffer->range_offset(),
   1301               length);
   1302 
   1303         mOffset += length + 4;
   1304     } else {
   1305         CHECK_LT(length, 65536u);
   1306 
   1307         uint8_t x = length >> 8;
   1308         ::write(mFd, &x, 1);
   1309         x = length & 0xff;
   1310         ::write(mFd, &x, 1);
   1311         ::write(mFd, (const uint8_t *)buffer->data() + buffer->range_offset(), length);
   1312         mOffset += length + 2;
   1313     }
   1314 
   1315     return old_offset;
   1316 }
   1317 
   1318 size_t MPEG4Writer::write(
   1319         const void *ptr, size_t size, size_t nmemb) {
   1320 
   1321     const size_t bytes = size * nmemb;
   1322     if (mWriteMoovBoxToMemory) {
   1323 
   1324         off64_t moovBoxSize = 8 + mMoovBoxBufferOffset + bytes;
   1325         if (moovBoxSize > mEstimatedMoovBoxSize) {
   1326             // The reserved moov box at the beginning of the file
   1327             // is not big enough. Moov box should be written to
   1328             // the end of the file from now on, but not to the
   1329             // in-memory cache.
   1330 
   1331             // We write partial moov box that is in the memory to
   1332             // the file first.
   1333             for (List<off64_t>::iterator it = mBoxes.begin();
   1334                  it != mBoxes.end(); ++it) {
   1335                 (*it) += mOffset;
   1336             }
   1337             lseek64(mFd, mOffset, SEEK_SET);
   1338             ::write(mFd, mMoovBoxBuffer, mMoovBoxBufferOffset);
   1339             ::write(mFd, ptr, bytes);
   1340             mOffset += (bytes + mMoovBoxBufferOffset);
   1341 
   1342             // All subsequent moov box content will be written
   1343             // to the end of the file.
   1344             mWriteMoovBoxToMemory = false;
   1345         } else {
   1346             memcpy(mMoovBoxBuffer + mMoovBoxBufferOffset, ptr, bytes);
   1347             mMoovBoxBufferOffset += bytes;
   1348         }
   1349     } else {
   1350         ::write(mFd, ptr, size * nmemb);
   1351         mOffset += bytes;
   1352     }
   1353     return bytes;
   1354 }
   1355 
   1356 void MPEG4Writer::beginBox(uint32_t id) {
   1357     mBoxes.push_back(mWriteMoovBoxToMemory?
   1358             mMoovBoxBufferOffset: mOffset);
   1359 
   1360     writeInt32(0);
   1361     writeInt32(id);
   1362 }
   1363 
   1364 void MPEG4Writer::beginBox(const char *fourcc) {
   1365     CHECK_EQ(strlen(fourcc), 4u);
   1366 
   1367     mBoxes.push_back(mWriteMoovBoxToMemory?
   1368             mMoovBoxBufferOffset: mOffset);
   1369 
   1370     writeInt32(0);
   1371     writeFourcc(fourcc);
   1372 }
   1373 
   1374 void MPEG4Writer::endBox() {
   1375     CHECK(!mBoxes.empty());
   1376 
   1377     off64_t offset = *--mBoxes.end();
   1378     mBoxes.erase(--mBoxes.end());
   1379 
   1380     if (mWriteMoovBoxToMemory) {
   1381        int32_t x = htonl(mMoovBoxBufferOffset - offset);
   1382        memcpy(mMoovBoxBuffer + offset, &x, 4);
   1383     } else {
   1384         lseek64(mFd, offset, SEEK_SET);
   1385         writeInt32(mOffset - offset);
   1386         mOffset -= 4;
   1387         lseek64(mFd, mOffset, SEEK_SET);
   1388     }
   1389 }
   1390 
   1391 void MPEG4Writer::writeInt8(int8_t x) {
   1392     write(&x, 1, 1);
   1393 }
   1394 
   1395 void MPEG4Writer::writeInt16(int16_t x) {
   1396     x = htons(x);
   1397     write(&x, 1, 2);
   1398 }
   1399 
   1400 void MPEG4Writer::writeInt32(int32_t x) {
   1401     x = htonl(x);
   1402     write(&x, 1, 4);
   1403 }
   1404 
   1405 void MPEG4Writer::writeInt64(int64_t x) {
   1406     x = hton64(x);
   1407     write(&x, 1, 8);
   1408 }
   1409 
   1410 void MPEG4Writer::writeCString(const char *s) {
   1411     size_t n = strlen(s);
   1412     write(s, 1, n + 1);
   1413 }
   1414 
   1415 void MPEG4Writer::writeFourcc(const char *s) {
   1416     CHECK_EQ(strlen(s), 4u);
   1417     write(s, 1, 4);
   1418 }
   1419 
   1420 
   1421 // Written in +/-DD.DDDD format
   1422 void MPEG4Writer::writeLatitude(int degreex10000) {
   1423     bool isNegative = (degreex10000 < 0);
   1424     char sign = isNegative? '-': '+';
   1425 
   1426     // Handle the whole part
   1427     char str[9];
   1428     int wholePart = degreex10000 / 10000;
   1429     if (wholePart == 0) {
   1430         snprintf(str, 5, "%c%.2d.", sign, wholePart);
   1431     } else {
   1432         snprintf(str, 5, "%+.2d.", wholePart);
   1433     }
   1434 
   1435     // Handle the fractional part
   1436     int fractionalPart = degreex10000 - (wholePart * 10000);
   1437     if (fractionalPart < 0) {
   1438         fractionalPart = -fractionalPart;
   1439     }
   1440     snprintf(&str[4], 5, "%.4d", fractionalPart);
   1441 
   1442     // Do not write the null terminator
   1443     write(str, 1, 8);
   1444 }
   1445 
   1446 // Written in +/- DDD.DDDD format
   1447 void MPEG4Writer::writeLongitude(int degreex10000) {
   1448     bool isNegative = (degreex10000 < 0);
   1449     char sign = isNegative? '-': '+';
   1450 
   1451     // Handle the whole part
   1452     char str[10];
   1453     int wholePart = degreex10000 / 10000;
   1454     if (wholePart == 0) {
   1455         snprintf(str, 6, "%c%.3d.", sign, wholePart);
   1456     } else {
   1457         snprintf(str, 6, "%+.3d.", wholePart);
   1458     }
   1459 
   1460     // Handle the fractional part
   1461     int fractionalPart = degreex10000 - (wholePart * 10000);
   1462     if (fractionalPart < 0) {
   1463         fractionalPart = -fractionalPart;
   1464     }
   1465     snprintf(&str[5], 5, "%.4d", fractionalPart);
   1466 
   1467     // Do not write the null terminator
   1468     write(str, 1, 9);
   1469 }
   1470 
   1471 /*
   1472  * Geodata is stored according to ISO-6709 standard.
   1473  * latitudex10000 is latitude in degrees times 10000, and
   1474  * longitudex10000 is longitude in degrees times 10000.
   1475  * The range for the latitude is in [-90, +90], and
   1476  * The range for the longitude is in [-180, +180]
   1477  */
   1478 status_t MPEG4Writer::setGeoData(int latitudex10000, int longitudex10000) {
   1479     // Is latitude or longitude out of range?
   1480     if (latitudex10000 < -900000 || latitudex10000 > 900000 ||
   1481         longitudex10000 < -1800000 || longitudex10000 > 1800000) {
   1482         return BAD_VALUE;
   1483     }
   1484 
   1485     mLatitudex10000 = latitudex10000;
   1486     mLongitudex10000 = longitudex10000;
   1487     mAreGeoTagsAvailable = true;
   1488     mMoovExtraSize += 30;
   1489     return OK;
   1490 }
   1491 
   1492 status_t MPEG4Writer::setCaptureRate(float captureFps) {
   1493     if (captureFps <= 0.0f) {
   1494         return BAD_VALUE;
   1495     }
   1496 
   1497     mMetaKeys->setFloat(kMetaKey_CaptureFps, captureFps);
   1498     mMoovExtraSize += sizeof(kMetaKey_CaptureFps) + 4 + 32;
   1499 
   1500     return OK;
   1501 }
   1502 
   1503 status_t MPEG4Writer::setTemporalLayerCount(uint32_t layerCount) {
   1504     if (layerCount > 9) {
   1505         return BAD_VALUE;
   1506     }
   1507 
   1508     if (layerCount > 0) {
   1509         mMetaKeys->setInt32(kMetaKey_TemporalLayerCount, layerCount);
   1510         mMoovExtraSize += sizeof(kMetaKey_TemporalLayerCount) + 4 + 32;
   1511     }
   1512 
   1513     return OK;
   1514 }
   1515 
   1516 void MPEG4Writer::notifyApproachingLimit() {
   1517     Mutex::Autolock autolock(mLock);
   1518     // Only notify once.
   1519     if (mSendNotify) {
   1520         return;
   1521     }
   1522     ALOGW("Recorded file size is approaching limit %" PRId64 "bytes",
   1523         mMaxFileSizeLimitBytes);
   1524     notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING, 0);
   1525     mSendNotify = true;
   1526 }
   1527 
   1528 void MPEG4Writer::write(const void *data, size_t size) {
   1529     write(data, 1, size);
   1530 }
   1531 
   1532 bool MPEG4Writer::isFileStreamable() const {
   1533     return mStreamableFile;
   1534 }
   1535 
   1536 bool MPEG4Writer::exceedsFileSizeLimit() {
   1537     // No limit
   1538     if (mMaxFileSizeLimitBytes == 0) {
   1539         return false;
   1540     }
   1541     int64_t nTotalBytesEstimate = static_cast<int64_t>(mEstimatedMoovBoxSize);
   1542     for (List<Track *>::iterator it = mTracks.begin();
   1543          it != mTracks.end(); ++it) {
   1544         nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
   1545     }
   1546 
   1547     if (!mStreamableFile) {
   1548         // Add 1024 bytes as error tolerance
   1549         return nTotalBytesEstimate + 1024 >= mMaxFileSizeLimitBytes;
   1550     }
   1551 
   1552     // Be conservative in the estimate: do not exceed 95% of
   1553     // the target file limit. For small target file size limit, though,
   1554     // this will not help.
   1555     return (nTotalBytesEstimate >= (95 * mMaxFileSizeLimitBytes) / 100);
   1556 }
   1557 
   1558 bool MPEG4Writer::approachingFileSizeLimit() {
   1559     // No limit
   1560     if (mMaxFileSizeLimitBytes == 0) {
   1561         return false;
   1562     }
   1563 
   1564     int64_t nTotalBytesEstimate = static_cast<int64_t>(mEstimatedMoovBoxSize);
   1565     for (List<Track *>::iterator it = mTracks.begin();
   1566          it != mTracks.end(); ++it) {
   1567         nTotalBytesEstimate += (*it)->getEstimatedTrackSizeBytes();
   1568     }
   1569 
   1570     if (!mStreamableFile) {
   1571         // Add 1024 bytes as error tolerance
   1572         return nTotalBytesEstimate + 1024 >= (90 * mMaxFileSizeLimitBytes) / 100;
   1573     }
   1574 
   1575     return (nTotalBytesEstimate >= (90 * mMaxFileSizeLimitBytes) / 100);
   1576 }
   1577 
   1578 bool MPEG4Writer::exceedsFileDurationLimit() {
   1579     // No limit
   1580     if (mMaxFileDurationLimitUs == 0) {
   1581         return false;
   1582     }
   1583 
   1584     for (List<Track *>::iterator it = mTracks.begin();
   1585          it != mTracks.end(); ++it) {
   1586         if ((*it)->getDurationUs() >= mMaxFileDurationLimitUs) {
   1587             return true;
   1588         }
   1589     }
   1590     return false;
   1591 }
   1592 
   1593 bool MPEG4Writer::reachedEOS() {
   1594     bool allDone = true;
   1595     for (List<Track *>::iterator it = mTracks.begin();
   1596          it != mTracks.end(); ++it) {
   1597         if (!(*it)->reachedEOS()) {
   1598             allDone = false;
   1599             break;
   1600         }
   1601     }
   1602 
   1603     return allDone;
   1604 }
   1605 
   1606 void MPEG4Writer::setStartTimestampUs(int64_t timeUs) {
   1607     ALOGI("setStartTimestampUs: %" PRId64, timeUs);
   1608     CHECK_GE(timeUs, 0ll);
   1609     Mutex::Autolock autoLock(mLock);
   1610     if (mStartTimestampUs < 0 || mStartTimestampUs > timeUs) {
   1611         mStartTimestampUs = timeUs;
   1612         ALOGI("Earliest track starting time: %" PRId64, mStartTimestampUs);
   1613     }
   1614 }
   1615 
   1616 int64_t MPEG4Writer::getStartTimestampUs() {
   1617     Mutex::Autolock autoLock(mLock);
   1618     return mStartTimestampUs;
   1619 }
   1620 
   1621 size_t MPEG4Writer::numTracks() {
   1622     Mutex::Autolock autolock(mLock);
   1623     return mTracks.size();
   1624 }
   1625 
   1626 ////////////////////////////////////////////////////////////////////////////////
   1627 
   1628 MPEG4Writer::Track::Track(
   1629         MPEG4Writer *owner, const sp<IMediaSource> &source, size_t trackId)
   1630     : mOwner(owner),
   1631       mMeta(source->getFormat()),
   1632       mSource(source),
   1633       mDone(false),
   1634       mPaused(false),
   1635       mResumed(false),
   1636       mStarted(false),
   1637       mGotStartKeyFrame(false),
   1638       mIsMalformed(false),
   1639       mTrackId(trackId),
   1640       mTrackDurationUs(0),
   1641       mEstimatedTrackSizeBytes(0),
   1642       mSamplesHaveSameSize(true),
   1643       mStszTableEntries(new ListTableEntries<uint32_t, 1>(1000)),
   1644       mStcoTableEntries(new ListTableEntries<uint32_t, 1>(1000)),
   1645       mCo64TableEntries(new ListTableEntries<off64_t, 1>(1000)),
   1646       mStscTableEntries(new ListTableEntries<uint32_t, 3>(1000)),
   1647       mStssTableEntries(new ListTableEntries<uint32_t, 1>(1000)),
   1648       mSttsTableEntries(new ListTableEntries<uint32_t, 2>(1000)),
   1649       mCttsTableEntries(new ListTableEntries<uint32_t, 2>(1000)),
   1650       mMinCttsOffsetTimeUs(0),
   1651       mMinCttsOffsetTicks(0),
   1652       mMaxCttsOffsetTicks(0),
   1653       mCodecSpecificData(NULL),
   1654       mCodecSpecificDataSize(0),
   1655       mGotAllCodecSpecificData(false),
   1656       mReachedEOS(false),
   1657       mStartTimestampUs(-1),
   1658       mRotation(0) {
   1659     getCodecSpecificDataFromInputFormatIfPossible();
   1660 
   1661     const char *mime;
   1662     mMeta->findCString(kKeyMIMEType, &mime);
   1663     mIsAvc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
   1664     mIsHevc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC);
   1665     mIsAudio = !strncasecmp(mime, "audio/", 6);
   1666     mIsVideo = !strncasecmp(mime, "video/", 6);
   1667     mIsMPEG4 = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4) ||
   1668                !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC);
   1669 
   1670     // store temporal layer count
   1671     if (mIsVideo) {
   1672         int32_t count;
   1673         if (mMeta->findInt32(kKeyTemporalLayerCount, &count) && count > 1) {
   1674             mOwner->setTemporalLayerCount(count);
   1675         }
   1676     }
   1677 
   1678     setTimeScale();
   1679 }
   1680 
   1681 // Clear all the internal states except the CSD data.
   1682 void MPEG4Writer::Track::resetInternal() {
   1683       mDone = false;
   1684       mPaused = false;
   1685       mResumed = false;
   1686       mStarted = false;
   1687       mGotStartKeyFrame = false;
   1688       mIsMalformed = false;
   1689       mTrackDurationUs = 0;
   1690       mEstimatedTrackSizeBytes = 0;
   1691       mSamplesHaveSameSize = 0;
   1692       if (mStszTableEntries != NULL) {
   1693          delete mStszTableEntries;
   1694          mStszTableEntries = new ListTableEntries<uint32_t, 1>(1000);
   1695       }
   1696 
   1697       if (mStcoTableEntries != NULL) {
   1698          delete mStcoTableEntries;
   1699          mStcoTableEntries = new ListTableEntries<uint32_t, 1>(1000);
   1700       }
   1701       if (mCo64TableEntries != NULL) {
   1702          delete mCo64TableEntries;
   1703          mCo64TableEntries = new ListTableEntries<off64_t, 1>(1000);
   1704       }
   1705 
   1706       if (mStscTableEntries != NULL) {
   1707          delete mStscTableEntries;
   1708          mStscTableEntries = new ListTableEntries<uint32_t, 3>(1000);
   1709       }
   1710       if (mStssTableEntries != NULL) {
   1711          delete mStssTableEntries;
   1712          mStssTableEntries = new ListTableEntries<uint32_t, 1>(1000);
   1713       }
   1714       if (mSttsTableEntries != NULL) {
   1715          delete mSttsTableEntries;
   1716          mSttsTableEntries = new ListTableEntries<uint32_t, 2>(1000);
   1717       }
   1718       if (mCttsTableEntries != NULL) {
   1719          delete mCttsTableEntries;
   1720          mCttsTableEntries = new ListTableEntries<uint32_t, 2>(1000);
   1721       }
   1722       mReachedEOS = false;
   1723 }
   1724 
   1725 void MPEG4Writer::Track::updateTrackSizeEstimate() {
   1726 
   1727     uint32_t stcoBoxCount = (mOwner->use32BitFileOffset()
   1728                             ? mStcoTableEntries->count()
   1729                             : mCo64TableEntries->count());
   1730     int64_t stcoBoxSizeBytes = stcoBoxCount * 4;
   1731     int64_t stszBoxSizeBytes = mSamplesHaveSameSize? 4: (mStszTableEntries->count() * 4);
   1732 
   1733     mEstimatedTrackSizeBytes = mMdatSizeBytes;  // media data size
   1734     if (!mOwner->isFileStreamable()) {
   1735         // Reserved free space is not large enough to hold
   1736         // all meta data and thus wasted.
   1737         mEstimatedTrackSizeBytes += mStscTableEntries->count() * 12 +  // stsc box size
   1738                                     mStssTableEntries->count() * 4 +   // stss box size
   1739                                     mSttsTableEntries->count() * 8 +   // stts box size
   1740                                     mCttsTableEntries->count() * 8 +   // ctts box size
   1741                                     stcoBoxSizeBytes +           // stco box size
   1742                                     stszBoxSizeBytes;            // stsz box size
   1743     }
   1744 }
   1745 
   1746 void MPEG4Writer::Track::addOneStscTableEntry(
   1747         size_t chunkId, size_t sampleId) {
   1748 
   1749         mStscTableEntries->add(htonl(chunkId));
   1750         mStscTableEntries->add(htonl(sampleId));
   1751         mStscTableEntries->add(htonl(1));
   1752 }
   1753 
   1754 void MPEG4Writer::Track::addOneStssTableEntry(size_t sampleId) {
   1755     mStssTableEntries->add(htonl(sampleId));
   1756 }
   1757 
   1758 void MPEG4Writer::Track::addOneSttsTableEntry(
   1759         size_t sampleCount, int32_t duration) {
   1760 
   1761     if (duration == 0) {
   1762         ALOGW("0-duration samples found: %zu", sampleCount);
   1763     }
   1764     mSttsTableEntries->add(htonl(sampleCount));
   1765     mSttsTableEntries->add(htonl(duration));
   1766 }
   1767 
   1768 void MPEG4Writer::Track::addOneCttsTableEntry(
   1769         size_t sampleCount, int32_t duration) {
   1770 
   1771     if (!mIsVideo) {
   1772         return;
   1773     }
   1774     mCttsTableEntries->add(htonl(sampleCount));
   1775     mCttsTableEntries->add(htonl(duration));
   1776 }
   1777 
   1778 status_t MPEG4Writer::setNextFd(int fd) {
   1779     ALOGV("addNextFd");
   1780     Mutex::Autolock l(mLock);
   1781     if (mLooper == NULL) {
   1782         mReflector = new AHandlerReflector<MPEG4Writer>(this);
   1783         mLooper = new ALooper;
   1784         mLooper->registerHandler(mReflector);
   1785         mLooper->start();
   1786     }
   1787 
   1788     if (mNextFd != -1) {
   1789         // No need to set a new FD yet.
   1790         return INVALID_OPERATION;
   1791     }
   1792     mNextFd = fd;
   1793     return OK;
   1794 }
   1795 
   1796 void MPEG4Writer::Track::addChunkOffset(off64_t offset) {
   1797     if (mOwner->use32BitFileOffset()) {
   1798         uint32_t value = offset;
   1799         mStcoTableEntries->add(htonl(value));
   1800     } else {
   1801         mCo64TableEntries->add(hton64(offset));
   1802     }
   1803 }
   1804 
   1805 void MPEG4Writer::Track::setTimeScale() {
   1806     ALOGV("setTimeScale");
   1807     // Default time scale
   1808     mTimeScale = 90000;
   1809 
   1810     if (mIsAudio) {
   1811         // Use the sampling rate as the default time scale for audio track.
   1812         int32_t sampleRate;
   1813         bool success = mMeta->findInt32(kKeySampleRate, &sampleRate);
   1814         CHECK(success);
   1815         mTimeScale = sampleRate;
   1816     }
   1817 
   1818     // If someone would like to overwrite the timescale, use user-supplied value.
   1819     int32_t timeScale;
   1820     if (mMeta->findInt32(kKeyTimeScale, &timeScale)) {
   1821         mTimeScale = timeScale;
   1822     }
   1823 
   1824     CHECK_GT(mTimeScale, 0);
   1825 }
   1826 
   1827 void MPEG4Writer::onMessageReceived(const sp<AMessage> &msg) {
   1828     switch (msg->what()) {
   1829         case kWhatSwitch:
   1830         {
   1831             finishCurrentSession();
   1832             mLock.lock();
   1833             int fd = mNextFd;
   1834             mNextFd = -1;
   1835             mLock.unlock();
   1836             initInternal(fd, false /*isFirstSession*/);
   1837             start(mStartMeta.get());
   1838             mSwitchPending = false;
   1839             notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_NEXT_OUTPUT_FILE_STARTED, 0);
   1840             break;
   1841         }
   1842         default:
   1843         TRESPASS();
   1844     }
   1845 }
   1846 
   1847 void MPEG4Writer::Track::getCodecSpecificDataFromInputFormatIfPossible() {
   1848     const char *mime;
   1849 
   1850     CHECK(mMeta->findCString(kKeyMIMEType, &mime));
   1851 
   1852     uint32_t type;
   1853     const void *data = NULL;
   1854     size_t size = 0;
   1855     if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
   1856         mMeta->findData(kKeyAVCC, &type, &data, &size);
   1857     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
   1858         mMeta->findData(kKeyHVCC, &type, &data, &size);
   1859     } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
   1860             || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
   1861         if (mMeta->findData(kKeyESDS, &type, &data, &size)) {
   1862             ESDS esds(data, size);
   1863             if (esds.getCodecSpecificInfo(&data, &size) == OK &&
   1864                     data != NULL &&
   1865                     copyCodecSpecificData((uint8_t*)data, size) == OK) {
   1866                 mGotAllCodecSpecificData = true;
   1867             }
   1868             return;
   1869         }
   1870     }
   1871     if (data != NULL && copyCodecSpecificData((uint8_t *)data, size) == OK) {
   1872         mGotAllCodecSpecificData = true;
   1873     }
   1874 }
   1875 
   1876 MPEG4Writer::Track::~Track() {
   1877     stop();
   1878 
   1879     delete mStszTableEntries;
   1880     delete mStcoTableEntries;
   1881     delete mCo64TableEntries;
   1882     delete mStscTableEntries;
   1883     delete mSttsTableEntries;
   1884     delete mStssTableEntries;
   1885     delete mCttsTableEntries;
   1886 
   1887     mStszTableEntries = NULL;
   1888     mStcoTableEntries = NULL;
   1889     mCo64TableEntries = NULL;
   1890     mStscTableEntries = NULL;
   1891     mSttsTableEntries = NULL;
   1892     mStssTableEntries = NULL;
   1893     mCttsTableEntries = NULL;
   1894 
   1895     if (mCodecSpecificData != NULL) {
   1896         free(mCodecSpecificData);
   1897         mCodecSpecificData = NULL;
   1898     }
   1899 }
   1900 
   1901 void MPEG4Writer::Track::initTrackingProgressStatus(MetaData *params) {
   1902     ALOGV("initTrackingProgressStatus");
   1903     mPreviousTrackTimeUs = -1;
   1904     mTrackingProgressStatus = false;
   1905     mTrackEveryTimeDurationUs = 0;
   1906     {
   1907         int64_t timeUs;
   1908         if (params && params->findInt64(kKeyTrackTimeStatus, &timeUs)) {
   1909             ALOGV("Receive request to track progress status for every %" PRId64 " us", timeUs);
   1910             mTrackEveryTimeDurationUs = timeUs;
   1911             mTrackingProgressStatus = true;
   1912         }
   1913     }
   1914 }
   1915 
   1916 // static
   1917 void *MPEG4Writer::ThreadWrapper(void *me) {
   1918     ALOGV("ThreadWrapper: %p", me);
   1919     MPEG4Writer *writer = static_cast<MPEG4Writer *>(me);
   1920     writer->threadFunc();
   1921     return NULL;
   1922 }
   1923 
   1924 void MPEG4Writer::bufferChunk(const Chunk& chunk) {
   1925     ALOGV("bufferChunk: %p", chunk.mTrack);
   1926     Mutex::Autolock autolock(mLock);
   1927     CHECK_EQ(mDone, false);
   1928 
   1929     for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
   1930          it != mChunkInfos.end(); ++it) {
   1931 
   1932         if (chunk.mTrack == it->mTrack) {  // Found owner
   1933             it->mChunks.push_back(chunk);
   1934             mChunkReadyCondition.signal();
   1935             return;
   1936         }
   1937     }
   1938 
   1939     CHECK(!"Received a chunk for a unknown track");
   1940 }
   1941 
   1942 void MPEG4Writer::writeChunkToFile(Chunk* chunk) {
   1943     ALOGV("writeChunkToFile: %" PRId64 " from %s track",
   1944         chunk->mTimeStampUs, chunk->mTrack->getTrackType());
   1945 
   1946     int32_t isFirstSample = true;
   1947     while (!chunk->mSamples.empty()) {
   1948         List<MediaBuffer *>::iterator it = chunk->mSamples.begin();
   1949 
   1950         off64_t offset = (chunk->mTrack->isAvc() || chunk->mTrack->isHevc())
   1951                                 ? addMultipleLengthPrefixedSamples_l(*it)
   1952                                 : addSample_l(*it);
   1953 
   1954         if (isFirstSample) {
   1955             chunk->mTrack->addChunkOffset(offset);
   1956             isFirstSample = false;
   1957         }
   1958 
   1959         (*it)->release();
   1960         (*it) = NULL;
   1961         chunk->mSamples.erase(it);
   1962     }
   1963     chunk->mSamples.clear();
   1964 }
   1965 
   1966 void MPEG4Writer::writeAllChunks() {
   1967     ALOGV("writeAllChunks");
   1968     size_t outstandingChunks = 0;
   1969     Chunk chunk;
   1970     while (findChunkToWrite(&chunk)) {
   1971         writeChunkToFile(&chunk);
   1972         ++outstandingChunks;
   1973     }
   1974 
   1975     sendSessionSummary();
   1976 
   1977     mChunkInfos.clear();
   1978     ALOGD("%zu chunks are written in the last batch", outstandingChunks);
   1979 }
   1980 
   1981 bool MPEG4Writer::findChunkToWrite(Chunk *chunk) {
   1982     ALOGV("findChunkToWrite");
   1983 
   1984     int64_t minTimestampUs = 0x7FFFFFFFFFFFFFFFLL;
   1985     Track *track = NULL;
   1986     for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
   1987          it != mChunkInfos.end(); ++it) {
   1988         if (!it->mChunks.empty()) {
   1989             List<Chunk>::iterator chunkIt = it->mChunks.begin();
   1990             if (chunkIt->mTimeStampUs < minTimestampUs) {
   1991                 minTimestampUs = chunkIt->mTimeStampUs;
   1992                 track = it->mTrack;
   1993             }
   1994         }
   1995     }
   1996 
   1997     if (track == NULL) {
   1998         ALOGV("Nothing to be written after all");
   1999         return false;
   2000     }
   2001 
   2002     if (mIsFirstChunk) {
   2003         mIsFirstChunk = false;
   2004     }
   2005 
   2006     for (List<ChunkInfo>::iterator it = mChunkInfos.begin();
   2007          it != mChunkInfos.end(); ++it) {
   2008         if (it->mTrack == track) {
   2009             *chunk = *(it->mChunks.begin());
   2010             it->mChunks.erase(it->mChunks.begin());
   2011             CHECK_EQ(chunk->mTrack, track);
   2012 
   2013             int64_t interChunkTimeUs =
   2014                 chunk->mTimeStampUs - it->mPrevChunkTimestampUs;
   2015             if (interChunkTimeUs > it->mPrevChunkTimestampUs) {
   2016                 it->mMaxInterChunkDurUs = interChunkTimeUs;
   2017             }
   2018 
   2019             return true;
   2020         }
   2021     }
   2022 
   2023     return false;
   2024 }
   2025 
   2026 void MPEG4Writer::threadFunc() {
   2027     ALOGV("threadFunc");
   2028 
   2029     prctl(PR_SET_NAME, (unsigned long)"MPEG4Writer", 0, 0, 0);
   2030 
   2031     Mutex::Autolock autoLock(mLock);
   2032     while (!mDone) {
   2033         Chunk chunk;
   2034         bool chunkFound = false;
   2035 
   2036         while (!mDone && !(chunkFound = findChunkToWrite(&chunk))) {
   2037             mChunkReadyCondition.wait(mLock);
   2038         }
   2039 
   2040         // In real time recording mode, write without holding the lock in order
   2041         // to reduce the blocking time for media track threads.
   2042         // Otherwise, hold the lock until the existing chunks get written to the
   2043         // file.
   2044         if (chunkFound) {
   2045             if (mIsRealTimeRecording) {
   2046                 mLock.unlock();
   2047             }
   2048             writeChunkToFile(&chunk);
   2049             if (mIsRealTimeRecording) {
   2050                 mLock.lock();
   2051             }
   2052         }
   2053     }
   2054 
   2055     writeAllChunks();
   2056 }
   2057 
   2058 status_t MPEG4Writer::startWriterThread() {
   2059     ALOGV("startWriterThread");
   2060 
   2061     mDone = false;
   2062     mIsFirstChunk = true;
   2063     mDriftTimeUs = 0;
   2064     for (List<Track *>::iterator it = mTracks.begin();
   2065          it != mTracks.end(); ++it) {
   2066         ChunkInfo info;
   2067         info.mTrack = *it;
   2068         info.mPrevChunkTimestampUs = 0;
   2069         info.mMaxInterChunkDurUs = 0;
   2070         mChunkInfos.push_back(info);
   2071     }
   2072 
   2073     pthread_attr_t attr;
   2074     pthread_attr_init(&attr);
   2075     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
   2076     pthread_create(&mThread, &attr, ThreadWrapper, this);
   2077     pthread_attr_destroy(&attr);
   2078     mWriterThreadStarted = true;
   2079     return OK;
   2080 }
   2081 
   2082 
   2083 status_t MPEG4Writer::Track::start(MetaData *params) {
   2084     if (!mDone && mPaused) {
   2085         mPaused = false;
   2086         mResumed = true;
   2087         return OK;
   2088     }
   2089 
   2090     int64_t startTimeUs;
   2091     if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
   2092         startTimeUs = 0;
   2093     }
   2094     mStartTimeRealUs = startTimeUs;
   2095 
   2096     int32_t rotationDegrees;
   2097     if (mIsVideo && params && params->findInt32(kKeyRotation, &rotationDegrees)) {
   2098         mRotation = rotationDegrees;
   2099     }
   2100 
   2101     initTrackingProgressStatus(params);
   2102 
   2103     sp<MetaData> meta = new MetaData;
   2104     if (mOwner->isRealTimeRecording() && mOwner->numTracks() > 1) {
   2105         /*
   2106          * This extra delay of accepting incoming audio/video signals
   2107          * helps to align a/v start time at the beginning of a recording
   2108          * session, and it also helps eliminate the "recording" sound for
   2109          * camcorder applications.
   2110          *
   2111          * If client does not set the start time offset, we fall back to
   2112          * use the default initial delay value.
   2113          */
   2114         int64_t startTimeOffsetUs = mOwner->getStartTimeOffsetMs() * 1000LL;
   2115         if (startTimeOffsetUs < 0) {  // Start time offset was not set
   2116             startTimeOffsetUs = kInitialDelayTimeUs;
   2117         }
   2118         startTimeUs += startTimeOffsetUs;
   2119         ALOGI("Start time offset: %" PRId64 " us", startTimeOffsetUs);
   2120     }
   2121 
   2122     meta->setInt64(kKeyTime, startTimeUs);
   2123 
   2124     status_t err = mSource->start(meta.get());
   2125     if (err != OK) {
   2126         mDone = mReachedEOS = true;
   2127         return err;
   2128     }
   2129 
   2130     pthread_attr_t attr;
   2131     pthread_attr_init(&attr);
   2132     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
   2133 
   2134     mDone = false;
   2135     mStarted = true;
   2136     mTrackDurationUs = 0;
   2137     mReachedEOS = false;
   2138     mEstimatedTrackSizeBytes = 0;
   2139     mMdatSizeBytes = 0;
   2140     mMaxChunkDurationUs = 0;
   2141     mLastDecodingTimeUs = -1;
   2142 
   2143     pthread_create(&mThread, &attr, ThreadWrapper, this);
   2144     pthread_attr_destroy(&attr);
   2145 
   2146     return OK;
   2147 }
   2148 
   2149 status_t MPEG4Writer::Track::pause() {
   2150     mPaused = true;
   2151     return OK;
   2152 }
   2153 
   2154 status_t MPEG4Writer::Track::stop(bool stopSource) {
   2155     ALOGD("%s track stopping. %s source", getTrackType(), stopSource ? "Stop" : "Not Stop");
   2156     if (!mStarted) {
   2157         ALOGE("Stop() called but track is not started");
   2158         return ERROR_END_OF_STREAM;
   2159     }
   2160 
   2161     if (mDone) {
   2162         return OK;
   2163     }
   2164 
   2165     if (stopSource) {
   2166         ALOGD("%s track source stopping", getTrackType());
   2167         mSource->stop();
   2168         ALOGD("%s track source stopped", getTrackType());
   2169     }
   2170 
   2171     // Set mDone to be true after sucessfully stop mSource as mSource may be still outputting
   2172     // buffers to the writer.
   2173     mDone = true;
   2174 
   2175     void *dummy;
   2176     pthread_join(mThread, &dummy);
   2177     status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
   2178 
   2179     ALOGD("%s track stopped. %s source", getTrackType(), stopSource ? "Stop" : "Not Stop");
   2180     return err;
   2181 }
   2182 
   2183 bool MPEG4Writer::Track::reachedEOS() {
   2184     return mReachedEOS;
   2185 }
   2186 
   2187 // static
   2188 void *MPEG4Writer::Track::ThreadWrapper(void *me) {
   2189     Track *track = static_cast<Track *>(me);
   2190 
   2191     status_t err = track->threadEntry();
   2192     return (void *)(uintptr_t)err;
   2193 }
   2194 
   2195 static void getNalUnitType(uint8_t byte, uint8_t* type) {
   2196     ALOGV("getNalUnitType: %d", byte);
   2197 
   2198     // nal_unit_type: 5-bit unsigned integer
   2199     *type = (byte & 0x1F);
   2200 }
   2201 
   2202 const uint8_t *MPEG4Writer::Track::parseParamSet(
   2203         const uint8_t *data, size_t length, int type, size_t *paramSetLen) {
   2204 
   2205     ALOGV("parseParamSet");
   2206     CHECK(type == kNalUnitTypeSeqParamSet ||
   2207           type == kNalUnitTypePicParamSet);
   2208 
   2209     const uint8_t *nextStartCode = findNextNalStartCode(data, length);
   2210     *paramSetLen = nextStartCode - data;
   2211     if (*paramSetLen == 0) {
   2212         ALOGE("Param set is malformed, since its length is 0");
   2213         return NULL;
   2214     }
   2215 
   2216     AVCParamSet paramSet(*paramSetLen, data);
   2217     if (type == kNalUnitTypeSeqParamSet) {
   2218         if (*paramSetLen < 4) {
   2219             ALOGE("Seq parameter set malformed");
   2220             return NULL;
   2221         }
   2222         if (mSeqParamSets.empty()) {
   2223             mProfileIdc = data[1];
   2224             mProfileCompatible = data[2];
   2225             mLevelIdc = data[3];
   2226         } else {
   2227             if (mProfileIdc != data[1] ||
   2228                 mProfileCompatible != data[2] ||
   2229                 mLevelIdc != data[3]) {
   2230                 // COULD DO: set profile/level to the lowest required to support all SPSs
   2231                 ALOGE("Inconsistent profile/level found in seq parameter sets");
   2232                 return NULL;
   2233             }
   2234         }
   2235         mSeqParamSets.push_back(paramSet);
   2236     } else {
   2237         mPicParamSets.push_back(paramSet);
   2238     }
   2239     return nextStartCode;
   2240 }
   2241 
   2242 status_t MPEG4Writer::Track::copyAVCCodecSpecificData(
   2243         const uint8_t *data, size_t size) {
   2244     ALOGV("copyAVCCodecSpecificData");
   2245 
   2246     // 2 bytes for each of the parameter set length field
   2247     // plus the 7 bytes for the header
   2248     return copyCodecSpecificData(data, size, 4 + 7);
   2249 }
   2250 
   2251 status_t MPEG4Writer::Track::copyHEVCCodecSpecificData(
   2252         const uint8_t *data, size_t size) {
   2253     ALOGV("copyHEVCCodecSpecificData");
   2254 
   2255     // Min length of HEVC CSD is 23. (ISO/IEC 14496-15:2014 Chapter 8.3.3.1.2)
   2256     return copyCodecSpecificData(data, size, 23);
   2257 }
   2258 
   2259 status_t MPEG4Writer::Track::copyCodecSpecificData(
   2260         const uint8_t *data, size_t size, size_t minLength) {
   2261     if (size < minLength) {
   2262         ALOGE("Codec specific data length too short: %zu", size);
   2263         return ERROR_MALFORMED;
   2264     }
   2265 
   2266     mCodecSpecificData = malloc(size);
   2267     if (mCodecSpecificData == NULL) {
   2268         ALOGE("Failed allocating codec specific data");
   2269         return NO_MEMORY;
   2270     }
   2271     mCodecSpecificDataSize = size;
   2272     memcpy(mCodecSpecificData, data, size);
   2273     return OK;
   2274 }
   2275 
   2276 status_t MPEG4Writer::Track::parseAVCCodecSpecificData(
   2277         const uint8_t *data, size_t size) {
   2278 
   2279     ALOGV("parseAVCCodecSpecificData");
   2280     // Data starts with a start code.
   2281     // SPS and PPS are separated with start codes.
   2282     // Also, SPS must come before PPS
   2283     uint8_t type = kNalUnitTypeSeqParamSet;
   2284     bool gotSps = false;
   2285     bool gotPps = false;
   2286     const uint8_t *tmp = data;
   2287     const uint8_t *nextStartCode = data;
   2288     size_t bytesLeft = size;
   2289     size_t paramSetLen = 0;
   2290     mCodecSpecificDataSize = 0;
   2291     while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) {
   2292         getNalUnitType(*(tmp + 4), &type);
   2293         if (type == kNalUnitTypeSeqParamSet) {
   2294             if (gotPps) {
   2295                 ALOGE("SPS must come before PPS");
   2296                 return ERROR_MALFORMED;
   2297             }
   2298             if (!gotSps) {
   2299                 gotSps = true;
   2300             }
   2301             nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, &paramSetLen);
   2302         } else if (type == kNalUnitTypePicParamSet) {
   2303             if (!gotSps) {
   2304                 ALOGE("SPS must come before PPS");
   2305                 return ERROR_MALFORMED;
   2306             }
   2307             if (!gotPps) {
   2308                 gotPps = true;
   2309             }
   2310             nextStartCode = parseParamSet(tmp + 4, bytesLeft - 4, type, &paramSetLen);
   2311         } else {
   2312             ALOGE("Only SPS and PPS Nal units are expected");
   2313             return ERROR_MALFORMED;
   2314         }
   2315 
   2316         if (nextStartCode == NULL) {
   2317             return ERROR_MALFORMED;
   2318         }
   2319 
   2320         // Move on to find the next parameter set
   2321         bytesLeft -= nextStartCode - tmp;
   2322         tmp = nextStartCode;
   2323         mCodecSpecificDataSize += (2 + paramSetLen);
   2324     }
   2325 
   2326     {
   2327         // Check on the number of seq parameter sets
   2328         size_t nSeqParamSets = mSeqParamSets.size();
   2329         if (nSeqParamSets == 0) {
   2330             ALOGE("Cound not find sequence parameter set");
   2331             return ERROR_MALFORMED;
   2332         }
   2333 
   2334         if (nSeqParamSets > 0x1F) {
   2335             ALOGE("Too many seq parameter sets (%zu) found", nSeqParamSets);
   2336             return ERROR_MALFORMED;
   2337         }
   2338     }
   2339 
   2340     {
   2341         // Check on the number of pic parameter sets
   2342         size_t nPicParamSets = mPicParamSets.size();
   2343         if (nPicParamSets == 0) {
   2344             ALOGE("Cound not find picture parameter set");
   2345             return ERROR_MALFORMED;
   2346         }
   2347         if (nPicParamSets > 0xFF) {
   2348             ALOGE("Too many pic parameter sets (%zd) found", nPicParamSets);
   2349             return ERROR_MALFORMED;
   2350         }
   2351     }
   2352 // FIXME:
   2353 // Add chromat_format_idc, bit depth values, etc for AVC/h264 high profile and above
   2354 // and remove #if 0
   2355 #if 0
   2356     {
   2357         // Check on the profiles
   2358         // These profiles requires additional parameter set extensions
   2359         if (mProfileIdc == 100 || mProfileIdc == 110 ||
   2360             mProfileIdc == 122 || mProfileIdc == 144) {
   2361             ALOGE("Sorry, no support for profile_idc: %d!", mProfileIdc);
   2362             return BAD_VALUE;
   2363         }
   2364     }
   2365 #endif
   2366     return OK;
   2367 }
   2368 
   2369 status_t MPEG4Writer::Track::makeAVCCodecSpecificData(
   2370         const uint8_t *data, size_t size) {
   2371 
   2372     if (mCodecSpecificData != NULL) {
   2373         ALOGE("Already have codec specific data");
   2374         return ERROR_MALFORMED;
   2375     }
   2376 
   2377     if (size < 4) {
   2378         ALOGE("Codec specific data length too short: %zu", size);
   2379         return ERROR_MALFORMED;
   2380     }
   2381 
   2382     // Data is in the form of AVCCodecSpecificData
   2383     if (memcmp("\x00\x00\x00\x01", data, 4)) {
   2384         return copyAVCCodecSpecificData(data, size);
   2385     }
   2386 
   2387     if (parseAVCCodecSpecificData(data, size) != OK) {
   2388         return ERROR_MALFORMED;
   2389     }
   2390 
   2391     // ISO 14496-15: AVC file format
   2392     mCodecSpecificDataSize += 7;  // 7 more bytes in the header
   2393     mCodecSpecificData = malloc(mCodecSpecificDataSize);
   2394     if (mCodecSpecificData == NULL) {
   2395         mCodecSpecificDataSize = 0;
   2396         ALOGE("Failed allocating codec specific data");
   2397         return NO_MEMORY;
   2398     }
   2399     uint8_t *header = (uint8_t *)mCodecSpecificData;
   2400     header[0] = 1;                     // version
   2401     header[1] = mProfileIdc;           // profile indication
   2402     header[2] = mProfileCompatible;    // profile compatibility
   2403     header[3] = mLevelIdc;
   2404 
   2405     // 6-bit '111111' followed by 2-bit to lengthSizeMinuusOne
   2406     if (mOwner->useNalLengthFour()) {
   2407         header[4] = 0xfc | 3;  // length size == 4 bytes
   2408     } else {
   2409         header[4] = 0xfc | 1;  // length size == 2 bytes
   2410     }
   2411 
   2412     // 3-bit '111' followed by 5-bit numSequenceParameterSets
   2413     int nSequenceParamSets = mSeqParamSets.size();
   2414     header[5] = 0xe0 | nSequenceParamSets;
   2415     header += 6;
   2416     for (List<AVCParamSet>::iterator it = mSeqParamSets.begin();
   2417          it != mSeqParamSets.end(); ++it) {
   2418         // 16-bit sequence parameter set length
   2419         uint16_t seqParamSetLength = it->mLength;
   2420         header[0] = seqParamSetLength >> 8;
   2421         header[1] = seqParamSetLength & 0xff;
   2422 
   2423         // SPS NAL unit (sequence parameter length bytes)
   2424         memcpy(&header[2], it->mData, seqParamSetLength);
   2425         header += (2 + seqParamSetLength);
   2426     }
   2427 
   2428     // 8-bit nPictureParameterSets
   2429     int nPictureParamSets = mPicParamSets.size();
   2430     header[0] = nPictureParamSets;
   2431     header += 1;
   2432     for (List<AVCParamSet>::iterator it = mPicParamSets.begin();
   2433          it != mPicParamSets.end(); ++it) {
   2434         // 16-bit picture parameter set length
   2435         uint16_t picParamSetLength = it->mLength;
   2436         header[0] = picParamSetLength >> 8;
   2437         header[1] = picParamSetLength & 0xff;
   2438 
   2439         // PPS Nal unit (picture parameter set length bytes)
   2440         memcpy(&header[2], it->mData, picParamSetLength);
   2441         header += (2 + picParamSetLength);
   2442     }
   2443 
   2444     return OK;
   2445 }
   2446 
   2447 
   2448 status_t MPEG4Writer::Track::parseHEVCCodecSpecificData(
   2449         const uint8_t *data, size_t size, HevcParameterSets &paramSets) {
   2450 
   2451     ALOGV("parseHEVCCodecSpecificData");
   2452     const uint8_t *tmp = data;
   2453     const uint8_t *nextStartCode = data;
   2454     size_t bytesLeft = size;
   2455     while (bytesLeft > 4 && !memcmp("\x00\x00\x00\x01", tmp, 4)) {
   2456         nextStartCode = findNextNalStartCode(tmp + 4, bytesLeft - 4);
   2457         status_t err = paramSets.addNalUnit(tmp + 4, (nextStartCode - tmp) - 4);
   2458         if (err != OK) {
   2459             return ERROR_MALFORMED;
   2460         }
   2461 
   2462         // Move on to find the next parameter set
   2463         bytesLeft -= nextStartCode - tmp;
   2464         tmp = nextStartCode;
   2465     }
   2466 
   2467     size_t csdSize = 23;
   2468     const size_t numNalUnits = paramSets.getNumNalUnits();
   2469     for (size_t i = 0; i < ARRAY_SIZE(kMandatoryHevcNalUnitTypes); ++i) {
   2470         int type = kMandatoryHevcNalUnitTypes[i];
   2471         size_t numParamSets = paramSets.getNumNalUnitsOfType(type);
   2472         if (numParamSets == 0) {
   2473             ALOGE("Cound not find NAL unit of type %d", type);
   2474             return ERROR_MALFORMED;
   2475         }
   2476     }
   2477     for (size_t i = 0; i < ARRAY_SIZE(kHevcNalUnitTypes); ++i) {
   2478         int type = kHevcNalUnitTypes[i];
   2479         size_t numParamSets = paramSets.getNumNalUnitsOfType(type);
   2480         if (numParamSets > 0xffff) {
   2481             ALOGE("Too many seq parameter sets (%zu) found", numParamSets);
   2482             return ERROR_MALFORMED;
   2483         }
   2484         csdSize += 3;
   2485         for (size_t j = 0; j < numNalUnits; ++j) {
   2486             if (paramSets.getType(j) != type) {
   2487                 continue;
   2488             }
   2489             csdSize += 2 + paramSets.getSize(j);
   2490         }
   2491     }
   2492     mCodecSpecificDataSize = csdSize;
   2493     return OK;
   2494 }
   2495 
   2496 status_t MPEG4Writer::Track::makeHEVCCodecSpecificData(
   2497         const uint8_t *data, size_t size) {
   2498 
   2499     if (mCodecSpecificData != NULL) {
   2500         ALOGE("Already have codec specific data");
   2501         return ERROR_MALFORMED;
   2502     }
   2503 
   2504     if (size < 4) {
   2505         ALOGE("Codec specific data length too short: %zu", size);
   2506         return ERROR_MALFORMED;
   2507     }
   2508 
   2509     // Data is in the form of HEVCCodecSpecificData
   2510     if (memcmp("\x00\x00\x00\x01", data, 4)) {
   2511         return copyHEVCCodecSpecificData(data, size);
   2512     }
   2513 
   2514     HevcParameterSets paramSets;
   2515     if (parseHEVCCodecSpecificData(data, size, paramSets) != OK) {
   2516         ALOGE("failed parsing codec specific data");
   2517         return ERROR_MALFORMED;
   2518     }
   2519 
   2520     mCodecSpecificData = malloc(mCodecSpecificDataSize);
   2521     if (mCodecSpecificData == NULL) {
   2522         mCodecSpecificDataSize = 0;
   2523         ALOGE("Failed allocating codec specific data");
   2524         return NO_MEMORY;
   2525     }
   2526     status_t err = paramSets.makeHvcc((uint8_t *)mCodecSpecificData,
   2527             &mCodecSpecificDataSize, mOwner->useNalLengthFour() ? 4 : 2);
   2528     if (err != OK) {
   2529         ALOGE("failed constructing HVCC atom");
   2530         return err;
   2531     }
   2532 
   2533     return OK;
   2534 }
   2535 
   2536 /*
   2537  * Updates the drift time from the audio track so that
   2538  * the video track can get the updated drift time information
   2539  * from the file writer. The fluctuation of the drift time of the audio
   2540  * encoding path is smoothed out with a simple filter by giving a larger
   2541  * weight to more recently drift time. The filter coefficients, 0.5 and 0.5,
   2542  * are heuristically determined.
   2543  */
   2544 void MPEG4Writer::Track::updateDriftTime(const sp<MetaData>& meta) {
   2545     int64_t driftTimeUs = 0;
   2546     if (meta->findInt64(kKeyDriftTime, &driftTimeUs)) {
   2547         int64_t prevDriftTimeUs = mOwner->getDriftTimeUs();
   2548         int64_t timeUs = (driftTimeUs + prevDriftTimeUs) >> 1;
   2549         mOwner->setDriftTimeUs(timeUs);
   2550     }
   2551 }
   2552 
   2553 void MPEG4Writer::Track::dumpTimeStamps() {
   2554     ALOGE("Dumping %s track's last 10 frames timestamp and frame type ", getTrackType());
   2555     std::string timeStampString;
   2556     for (std::list<TimestampDebugHelperEntry>::iterator entry = mTimestampDebugHelper.begin();
   2557             entry != mTimestampDebugHelper.end(); ++entry) {
   2558         timeStampString += "(" + std::to_string(entry->pts)+
   2559                 "us, " + std::to_string(entry->dts) + "us " + entry->frameType + ") ";
   2560     }
   2561     ALOGE("%s", timeStampString.c_str());
   2562 }
   2563 
   2564 status_t MPEG4Writer::Track::threadEntry() {
   2565     int32_t count = 0;
   2566     const int64_t interleaveDurationUs = mOwner->interleaveDuration();
   2567     const bool hasMultipleTracks = (mOwner->numTracks() > 1);
   2568     int64_t chunkTimestampUs = 0;
   2569     int32_t nChunks = 0;
   2570     int32_t nActualFrames = 0;        // frames containing non-CSD data (non-0 length)
   2571     int32_t nZeroLengthFrames = 0;
   2572     int64_t lastTimestampUs = 0;      // Previous sample time stamp
   2573     int64_t lastDurationUs = 0;       // Between the previous two samples
   2574     int64_t currDurationTicks = 0;    // Timescale based ticks
   2575     int64_t lastDurationTicks = 0;    // Timescale based ticks
   2576     int32_t sampleCount = 1;          // Sample count in the current stts table entry
   2577     uint32_t previousSampleSize = 0;  // Size of the previous sample
   2578     int64_t previousPausedDurationUs = 0;
   2579     int64_t timestampUs = 0;
   2580     int64_t cttsOffsetTimeUs = 0;
   2581     int64_t currCttsOffsetTimeTicks = 0;   // Timescale based ticks
   2582     int64_t lastCttsOffsetTimeTicks = -1;  // Timescale based ticks
   2583     int32_t cttsSampleCount = 0;           // Sample count in the current ctts table entry
   2584     uint32_t lastSamplesPerChunk = 0;
   2585 
   2586     if (mIsAudio) {
   2587         prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0);
   2588     } else if (mIsVideo) {
   2589         prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0);
   2590     } else {
   2591         prctl(PR_SET_NAME, (unsigned long)"MetadataTrackEncoding", 0, 0, 0);
   2592     }
   2593 
   2594     if (mOwner->isRealTimeRecording()) {
   2595         androidSetThreadPriority(0, ANDROID_PRIORITY_AUDIO);
   2596     }
   2597 
   2598     sp<MetaData> meta_data;
   2599 
   2600     status_t err = OK;
   2601     MediaBuffer *buffer;
   2602     const char *trackName = getTrackType();
   2603     while (!mDone && (err = mSource->read(&buffer)) == OK) {
   2604         if (buffer->range_length() == 0) {
   2605             buffer->release();
   2606             buffer = NULL;
   2607             ++nZeroLengthFrames;
   2608             continue;
   2609         }
   2610 
   2611         // If the codec specific data has not been received yet, delay pause.
   2612         // After the codec specific data is received, discard what we received
   2613         // when the track is to be paused.
   2614         if (mPaused && !mResumed) {
   2615             buffer->release();
   2616             buffer = NULL;
   2617             continue;
   2618         }
   2619 
   2620         ++count;
   2621 
   2622         int32_t isCodecConfig;
   2623         if (buffer->meta_data()->findInt32(kKeyIsCodecConfig, &isCodecConfig)
   2624                 && isCodecConfig) {
   2625             // if config format (at track addition) already had CSD, keep that
   2626             // UNLESS we have not received any frames yet.
   2627             // TODO: for now the entire CSD has to come in one frame for encoders, even though
   2628             // they need to be spread out for decoders.
   2629             if (mGotAllCodecSpecificData && nActualFrames > 0) {
   2630                 ALOGI("ignoring additional CSD for video track after first frame");
   2631             } else {
   2632                 mMeta = mSource->getFormat(); // get output format after format change
   2633                 status_t err;
   2634                 if (mIsAvc) {
   2635                     err = makeAVCCodecSpecificData(
   2636                             (const uint8_t *)buffer->data()
   2637                                 + buffer->range_offset(),
   2638                             buffer->range_length());
   2639                 } else if (mIsHevc) {
   2640                     err = makeHEVCCodecSpecificData(
   2641                             (const uint8_t *)buffer->data()
   2642                                 + buffer->range_offset(),
   2643                             buffer->range_length());
   2644                 } else if (mIsMPEG4) {
   2645                     copyCodecSpecificData((const uint8_t *)buffer->data() + buffer->range_offset(),
   2646                             buffer->range_length());
   2647                 }
   2648             }
   2649 
   2650             buffer->release();
   2651             buffer = NULL;
   2652             if (OK != err) {
   2653                 mSource->stop();
   2654                 mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_ERROR,
   2655                        mTrackId | MEDIA_RECORDER_TRACK_ERROR_GENERAL, err);
   2656                 break;
   2657             }
   2658 
   2659             mGotAllCodecSpecificData = true;
   2660             continue;
   2661         }
   2662 
   2663         // Per-frame metadata sample's size must be smaller than max allowed.
   2664         if (!mIsVideo && !mIsAudio && buffer->range_length() >= kMaxMetadataSize) {
   2665             ALOGW("Buffer size is %zu. Maximum metadata buffer size is %lld for %s track",
   2666                     buffer->range_length(), (long long)kMaxMetadataSize, trackName);
   2667             buffer->release();
   2668             mSource->stop();
   2669             mIsMalformed = true;
   2670             break;
   2671         }
   2672 
   2673         ++nActualFrames;
   2674 
   2675         // Make a deep copy of the MediaBuffer and Metadata and release
   2676         // the original as soon as we can
   2677         MediaBuffer *copy = new MediaBuffer(buffer->range_length());
   2678         memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(),
   2679                 buffer->range_length());
   2680         copy->set_range(0, buffer->range_length());
   2681         meta_data = new MetaData(*buffer->meta_data().get());
   2682         buffer->release();
   2683         buffer = NULL;
   2684 
   2685         if (mIsAvc || mIsHevc) StripStartcode(copy);
   2686 
   2687         size_t sampleSize = copy->range_length();
   2688         if (mIsAvc || mIsHevc) {
   2689             if (mOwner->useNalLengthFour()) {
   2690                 sampleSize += 4;
   2691             } else {
   2692                 sampleSize += 2;
   2693             }
   2694         }
   2695 
   2696         // Max file size or duration handling
   2697         mMdatSizeBytes += sampleSize;
   2698         updateTrackSizeEstimate();
   2699 
   2700         if (mOwner->exceedsFileSizeLimit()) {
   2701             if (mOwner->switchFd() != OK) {
   2702                 ALOGW("Recorded file size exceeds limit %" PRId64 "bytes",
   2703                         mOwner->mMaxFileSizeLimitBytes);
   2704                 mSource->stop();
   2705                 mOwner->notify(
   2706                         MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED, 0);
   2707             } else {
   2708                 ALOGV("%s Current recorded file size exceeds limit %" PRId64 "bytes. Switching output",
   2709                         getTrackType(), mOwner->mMaxFileSizeLimitBytes);
   2710             }
   2711             copy->release();
   2712             break;
   2713         }
   2714 
   2715         if (mOwner->exceedsFileDurationLimit()) {
   2716             ALOGW("Recorded file duration exceeds limit %" PRId64 "microseconds",
   2717                     mOwner->mMaxFileDurationLimitUs);
   2718             mOwner->notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_MAX_DURATION_REACHED, 0);
   2719             copy->release();
   2720             mSource->stop();
   2721             break;
   2722         }
   2723 
   2724         if (mOwner->approachingFileSizeLimit()) {
   2725             mOwner->notifyApproachingLimit();
   2726         }
   2727 
   2728         int32_t isSync = false;
   2729         meta_data->findInt32(kKeyIsSyncFrame, &isSync);
   2730         CHECK(meta_data->findInt64(kKeyTime, &timestampUs));
   2731 
   2732         // For video, skip the first several non-key frames until getting the first key frame.
   2733         if (mIsVideo && !mGotStartKeyFrame && !isSync) {
   2734             ALOGD("Video skip non-key frame");
   2735             copy->release();
   2736             continue;
   2737         }
   2738         if (mIsVideo && isSync) {
   2739             mGotStartKeyFrame = true;
   2740         }
   2741 ////////////////////////////////////////////////////////////////////////////////
   2742         if (mStszTableEntries->count() == 0) {
   2743             mFirstSampleTimeRealUs = systemTime() / 1000;
   2744             mStartTimestampUs = timestampUs;
   2745             mOwner->setStartTimestampUs(mStartTimestampUs);
   2746             previousPausedDurationUs = mStartTimestampUs;
   2747         }
   2748 
   2749         if (mResumed) {
   2750             int64_t durExcludingEarlierPausesUs = timestampUs - previousPausedDurationUs;
   2751             if (WARN_UNLESS(durExcludingEarlierPausesUs >= 0ll, "for %s track", trackName)) {
   2752                 copy->release();
   2753                 mSource->stop();
   2754                 mIsMalformed = true;
   2755                 break;
   2756             }
   2757 
   2758             int64_t pausedDurationUs = durExcludingEarlierPausesUs - mTrackDurationUs;
   2759             if (WARN_UNLESS(pausedDurationUs >= lastDurationUs, "for %s track", trackName)) {
   2760                 copy->release();
   2761                 mSource->stop();
   2762                 mIsMalformed = true;
   2763                 break;
   2764             }
   2765 
   2766             previousPausedDurationUs += pausedDurationUs - lastDurationUs;
   2767             mResumed = false;
   2768         }
   2769         TimestampDebugHelperEntry timestampDebugEntry;
   2770         timestampUs -= previousPausedDurationUs;
   2771         timestampDebugEntry.pts = timestampUs;
   2772         if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
   2773             copy->release();
   2774             mSource->stop();
   2775             mIsMalformed = true;
   2776             break;
   2777         }
   2778 
   2779         if (mIsVideo) {
   2780             /*
   2781              * Composition time: timestampUs
   2782              * Decoding time: decodingTimeUs
   2783              * Composition time offset = composition time - decoding time
   2784              */
   2785             int64_t decodingTimeUs;
   2786             CHECK(meta_data->findInt64(kKeyDecodingTime, &decodingTimeUs));
   2787             decodingTimeUs -= previousPausedDurationUs;
   2788 
   2789             // ensure non-negative, monotonic decoding time
   2790             if (mLastDecodingTimeUs < 0) {
   2791                 decodingTimeUs = std::max((int64_t)0, decodingTimeUs);
   2792             } else {
   2793                 // increase decoding time by at least the larger vaule of 1 tick and
   2794                 // 0.1 milliseconds. This needs to take into account the possible
   2795                 // delta adjustment in DurationTicks in below.
   2796                 decodingTimeUs = std::max(mLastDecodingTimeUs +
   2797                         std::max(100, divUp(1000000, mTimeScale)), decodingTimeUs);
   2798             }
   2799 
   2800             mLastDecodingTimeUs = decodingTimeUs;
   2801             timestampDebugEntry.dts = decodingTimeUs;
   2802             timestampDebugEntry.frameType = isSync ? "Key frame" : "Non-Key frame";
   2803             // Insert the timestamp into the mTimestampDebugHelper
   2804             if (mTimestampDebugHelper.size() >= kTimestampDebugCount) {
   2805                 mTimestampDebugHelper.pop_front();
   2806             }
   2807             mTimestampDebugHelper.push_back(timestampDebugEntry);
   2808 
   2809             cttsOffsetTimeUs =
   2810                     timestampUs + kMaxCttsOffsetTimeUs - decodingTimeUs;
   2811             if (WARN_UNLESS(cttsOffsetTimeUs >= 0ll, "for %s track", trackName)) {
   2812                 copy->release();
   2813                 mSource->stop();
   2814                 mIsMalformed = true;
   2815                 break;
   2816             }
   2817 
   2818             timestampUs = decodingTimeUs;
   2819             ALOGV("decoding time: %" PRId64 " and ctts offset time: %" PRId64,
   2820                 timestampUs, cttsOffsetTimeUs);
   2821 
   2822             // Update ctts box table if necessary
   2823             currCttsOffsetTimeTicks =
   2824                     (cttsOffsetTimeUs * mTimeScale + 500000LL) / 1000000LL;
   2825             if (WARN_UNLESS(currCttsOffsetTimeTicks <= 0x0FFFFFFFFLL, "for %s track", trackName)) {
   2826                 copy->release();
   2827                 mSource->stop();
   2828                 mIsMalformed = true;
   2829                 break;
   2830             }
   2831 
   2832             if (mStszTableEntries->count() == 0) {
   2833                 // Force the first ctts table entry to have one single entry
   2834                 // so that we can do adjustment for the initial track start
   2835                 // time offset easily in writeCttsBox().
   2836                 lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
   2837                 addOneCttsTableEntry(1, currCttsOffsetTimeTicks);
   2838                 cttsSampleCount = 0;      // No sample in ctts box is pending
   2839             } else {
   2840                 if (currCttsOffsetTimeTicks != lastCttsOffsetTimeTicks) {
   2841                     addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
   2842                     lastCttsOffsetTimeTicks = currCttsOffsetTimeTicks;
   2843                     cttsSampleCount = 1;  // One sample in ctts box is pending
   2844                 } else {
   2845                     ++cttsSampleCount;
   2846                 }
   2847             }
   2848 
   2849             // Update ctts time offset range
   2850             if (mStszTableEntries->count() == 0) {
   2851                 mMinCttsOffsetTicks = currCttsOffsetTimeTicks;
   2852                 mMaxCttsOffsetTicks = currCttsOffsetTimeTicks;
   2853             } else {
   2854                 if (currCttsOffsetTimeTicks > mMaxCttsOffsetTicks) {
   2855                     mMaxCttsOffsetTicks = currCttsOffsetTimeTicks;
   2856                 } else if (currCttsOffsetTimeTicks < mMinCttsOffsetTicks) {
   2857                     mMinCttsOffsetTicks = currCttsOffsetTimeTicks;
   2858                     mMinCttsOffsetTimeUs = cttsOffsetTimeUs;
   2859                 }
   2860             }
   2861         }
   2862 
   2863         if (mOwner->isRealTimeRecording()) {
   2864             if (mIsAudio) {
   2865                 updateDriftTime(meta_data);
   2866             }
   2867         }
   2868 
   2869         if (WARN_UNLESS(timestampUs >= 0ll, "for %s track", trackName)) {
   2870             copy->release();
   2871             mSource->stop();
   2872             mIsMalformed = true;
   2873             break;
   2874         }
   2875 
   2876         ALOGV("%s media time stamp: %" PRId64 " and previous paused duration %" PRId64,
   2877                 trackName, timestampUs, previousPausedDurationUs);
   2878         if (timestampUs > mTrackDurationUs) {
   2879             mTrackDurationUs = timestampUs;
   2880         }
   2881 
   2882         // We need to use the time scale based ticks, rather than the
   2883         // timestamp itself to determine whether we have to use a new
   2884         // stts entry, since we may have rounding errors.
   2885         // The calculation is intended to reduce the accumulated
   2886         // rounding errors.
   2887         currDurationTicks =
   2888             ((timestampUs * mTimeScale + 500000LL) / 1000000LL -
   2889                 (lastTimestampUs * mTimeScale + 500000LL) / 1000000LL);
   2890         if (currDurationTicks < 0ll) {
   2891             ALOGE("do not support out of order frames (timestamp: %lld < last: %lld for %s track",
   2892                     (long long)timestampUs, (long long)lastTimestampUs, trackName);
   2893             copy->release();
   2894             mSource->stop();
   2895             mIsMalformed = true;
   2896             break;
   2897         }
   2898 
   2899         // if the duration is different for this sample, see if it is close enough to the previous
   2900         // duration that we can fudge it and use the same value, to avoid filling the stts table
   2901         // with lots of near-identical entries.
   2902         // "close enough" here means that the current duration needs to be adjusted by less
   2903         // than 0.1 milliseconds
   2904         if (lastDurationTicks && (currDurationTicks != lastDurationTicks)) {
   2905             int64_t deltaUs = ((lastDurationTicks - currDurationTicks) * 1000000LL
   2906                     + (mTimeScale / 2)) / mTimeScale;
   2907             if (deltaUs > -100 && deltaUs < 100) {
   2908                 // use previous ticks, and adjust timestamp as if it was actually that number
   2909                 // of ticks
   2910                 currDurationTicks = lastDurationTicks;
   2911                 timestampUs += deltaUs;
   2912             }
   2913         }
   2914         mStszTableEntries->add(htonl(sampleSize));
   2915         if (mStszTableEntries->count() > 2) {
   2916 
   2917             // Force the first sample to have its own stts entry so that
   2918             // we can adjust its value later to maintain the A/V sync.
   2919             if (mStszTableEntries->count() == 3 || currDurationTicks != lastDurationTicks) {
   2920                 addOneSttsTableEntry(sampleCount, lastDurationTicks);
   2921                 sampleCount = 1;
   2922             } else {
   2923                 ++sampleCount;
   2924             }
   2925 
   2926         }
   2927         if (mSamplesHaveSameSize) {
   2928             if (mStszTableEntries->count() >= 2 && previousSampleSize != sampleSize) {
   2929                 mSamplesHaveSameSize = false;
   2930             }
   2931             previousSampleSize = sampleSize;
   2932         }
   2933         ALOGV("%s timestampUs/lastTimestampUs: %" PRId64 "/%" PRId64,
   2934                 trackName, timestampUs, lastTimestampUs);
   2935         lastDurationUs = timestampUs - lastTimestampUs;
   2936         lastDurationTicks = currDurationTicks;
   2937         lastTimestampUs = timestampUs;
   2938 
   2939         if (isSync != 0) {
   2940             addOneStssTableEntry(mStszTableEntries->count());
   2941         }
   2942 
   2943         if (mTrackingProgressStatus) {
   2944             if (mPreviousTrackTimeUs <= 0) {
   2945                 mPreviousTrackTimeUs = mStartTimestampUs;
   2946             }
   2947             trackProgressStatus(timestampUs);
   2948         }
   2949         if (!hasMultipleTracks) {
   2950             off64_t offset = (mIsAvc || mIsHevc) ? mOwner->addMultipleLengthPrefixedSamples_l(copy)
   2951                                  : mOwner->addSample_l(copy);
   2952 
   2953             uint32_t count = (mOwner->use32BitFileOffset()
   2954                         ? mStcoTableEntries->count()
   2955                         : mCo64TableEntries->count());
   2956 
   2957             if (count == 0) {
   2958                 addChunkOffset(offset);
   2959             }
   2960             copy->release();
   2961             copy = NULL;
   2962             continue;
   2963         }
   2964 
   2965         mChunkSamples.push_back(copy);
   2966         if (interleaveDurationUs == 0) {
   2967             addOneStscTableEntry(++nChunks, 1);
   2968             bufferChunk(timestampUs);
   2969         } else {
   2970             if (chunkTimestampUs == 0) {
   2971                 chunkTimestampUs = timestampUs;
   2972             } else {
   2973                 int64_t chunkDurationUs = timestampUs - chunkTimestampUs;
   2974                 if (chunkDurationUs > interleaveDurationUs) {
   2975                     if (chunkDurationUs > mMaxChunkDurationUs) {
   2976                         mMaxChunkDurationUs = chunkDurationUs;
   2977                     }
   2978                     ++nChunks;
   2979                     if (nChunks == 1 ||  // First chunk
   2980                         lastSamplesPerChunk != mChunkSamples.size()) {
   2981                         lastSamplesPerChunk = mChunkSamples.size();
   2982                         addOneStscTableEntry(nChunks, lastSamplesPerChunk);
   2983                     }
   2984                     bufferChunk(timestampUs);
   2985                     chunkTimestampUs = timestampUs;
   2986                 }
   2987             }
   2988         }
   2989 
   2990     }
   2991 
   2992     if (isTrackMalFormed()) {
   2993         dumpTimeStamps();
   2994         err = ERROR_MALFORMED;
   2995     }
   2996 
   2997     mOwner->trackProgressStatus(mTrackId, -1, err);
   2998 
   2999     // Last chunk
   3000     if (!hasMultipleTracks) {
   3001         addOneStscTableEntry(1, mStszTableEntries->count());
   3002     } else if (!mChunkSamples.empty()) {
   3003         addOneStscTableEntry(++nChunks, mChunkSamples.size());
   3004         bufferChunk(timestampUs);
   3005     }
   3006 
   3007     // We don't really know how long the last frame lasts, since
   3008     // there is no frame time after it, just repeat the previous
   3009     // frame's duration.
   3010     if (mStszTableEntries->count() == 1) {
   3011         lastDurationUs = 0;  // A single sample's duration
   3012         lastDurationTicks = 0;
   3013     } else {
   3014         ++sampleCount;  // Count for the last sample
   3015     }
   3016 
   3017     if (mStszTableEntries->count() <= 2) {
   3018         addOneSttsTableEntry(1, lastDurationTicks);
   3019         if (sampleCount - 1 > 0) {
   3020             addOneSttsTableEntry(sampleCount - 1, lastDurationTicks);
   3021         }
   3022     } else {
   3023         addOneSttsTableEntry(sampleCount, lastDurationTicks);
   3024     }
   3025 
   3026     // The last ctts box may not have been written yet, and this
   3027     // is to make sure that we write out the last ctts box.
   3028     if (currCttsOffsetTimeTicks == lastCttsOffsetTimeTicks) {
   3029         if (cttsSampleCount > 0) {
   3030             addOneCttsTableEntry(cttsSampleCount, lastCttsOffsetTimeTicks);
   3031         }
   3032     }
   3033 
   3034     mTrackDurationUs += lastDurationUs;
   3035     mReachedEOS = true;
   3036 
   3037     sendTrackSummary(hasMultipleTracks);
   3038 
   3039     ALOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s",
   3040             count, nZeroLengthFrames, mStszTableEntries->count(), trackName);
   3041     if (mIsAudio) {
   3042         ALOGI("Audio track drift time: %" PRId64 " us", mOwner->getDriftTimeUs());
   3043     }
   3044 
   3045     if (err == ERROR_END_OF_STREAM) {
   3046         return OK;
   3047     }
   3048     return err;
   3049 }
   3050 
   3051 bool MPEG4Writer::Track::isTrackMalFormed() const {
   3052     if (mIsMalformed) {
   3053         return true;
   3054     }
   3055 
   3056     if (mStszTableEntries->count() == 0) {                      // no samples written
   3057         ALOGE("The number of recorded samples is 0");
   3058         return true;
   3059     }
   3060 
   3061     if (mIsVideo && mStssTableEntries->count() == 0) {  // no sync frames for video
   3062         ALOGE("There are no sync frames for video track");
   3063         return true;
   3064     }
   3065 
   3066     if (OK != checkCodecSpecificData()) {         // no codec specific data
   3067         return true;
   3068     }
   3069 
   3070     return false;
   3071 }
   3072 
   3073 void MPEG4Writer::Track::sendTrackSummary(bool hasMultipleTracks) {
   3074 
   3075     // Send track summary only if test mode is enabled.
   3076     if (!isTestModeEnabled()) {
   3077         return;
   3078     }
   3079 
   3080     int trackNum = (mTrackId << 28);
   3081 
   3082     mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   3083                     trackNum | MEDIA_RECORDER_TRACK_INFO_TYPE,
   3084                     mIsAudio ? 0: 1);
   3085 
   3086     mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   3087                     trackNum | MEDIA_RECORDER_TRACK_INFO_DURATION_MS,
   3088                     mTrackDurationUs / 1000);
   3089 
   3090     mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   3091                     trackNum | MEDIA_RECORDER_TRACK_INFO_ENCODED_FRAMES,
   3092                     mStszTableEntries->count());
   3093 
   3094     {
   3095         // The system delay time excluding the requested initial delay that
   3096         // is used to eliminate the recording sound.
   3097         int64_t startTimeOffsetUs = mOwner->getStartTimeOffsetMs() * 1000LL;
   3098         if (startTimeOffsetUs < 0) {  // Start time offset was not set
   3099             startTimeOffsetUs = kInitialDelayTimeUs;
   3100         }
   3101         int64_t initialDelayUs =
   3102             mFirstSampleTimeRealUs - mStartTimeRealUs - startTimeOffsetUs;
   3103 
   3104         mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   3105                     trackNum | MEDIA_RECORDER_TRACK_INFO_INITIAL_DELAY_MS,
   3106                     (initialDelayUs) / 1000);
   3107     }
   3108 
   3109     mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   3110                     trackNum | MEDIA_RECORDER_TRACK_INFO_DATA_KBYTES,
   3111                     mMdatSizeBytes / 1024);
   3112 
   3113     if (hasMultipleTracks) {
   3114         mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   3115                     trackNum | MEDIA_RECORDER_TRACK_INFO_MAX_CHUNK_DUR_MS,
   3116                     mMaxChunkDurationUs / 1000);
   3117 
   3118         int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
   3119         if (mStartTimestampUs != moovStartTimeUs) {
   3120             int64_t startTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
   3121             mOwner->notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   3122                     trackNum | MEDIA_RECORDER_TRACK_INFO_START_OFFSET_MS,
   3123                     startTimeOffsetUs / 1000);
   3124         }
   3125     }
   3126 }
   3127 
   3128 void MPEG4Writer::Track::trackProgressStatus(int64_t timeUs, status_t err) {
   3129     ALOGV("trackProgressStatus: %" PRId64 " us", timeUs);
   3130 
   3131     if (mTrackEveryTimeDurationUs > 0 &&
   3132         timeUs - mPreviousTrackTimeUs >= mTrackEveryTimeDurationUs) {
   3133         ALOGV("Fire time tracking progress status at %" PRId64 " us", timeUs);
   3134         mOwner->trackProgressStatus(mTrackId, timeUs - mPreviousTrackTimeUs, err);
   3135         mPreviousTrackTimeUs = timeUs;
   3136     }
   3137 }
   3138 
   3139 void MPEG4Writer::trackProgressStatus(
   3140         size_t trackId, int64_t timeUs, status_t err) {
   3141     Mutex::Autolock lock(mLock);
   3142     int32_t trackNum = (trackId << 28);
   3143 
   3144     // Error notification
   3145     // Do not consider ERROR_END_OF_STREAM an error
   3146     if (err != OK && err != ERROR_END_OF_STREAM) {
   3147         notify(MEDIA_RECORDER_TRACK_EVENT_ERROR,
   3148                trackNum | MEDIA_RECORDER_TRACK_ERROR_GENERAL,
   3149                err);
   3150         return;
   3151     }
   3152 
   3153     if (timeUs == -1) {
   3154         // Send completion notification
   3155         notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   3156                trackNum | MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS,
   3157                err);
   3158     } else {
   3159         // Send progress status
   3160         notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
   3161                trackNum | MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME,
   3162                timeUs / 1000);
   3163     }
   3164 }
   3165 
   3166 void MPEG4Writer::setDriftTimeUs(int64_t driftTimeUs) {
   3167     ALOGV("setDriftTimeUs: %" PRId64 " us", driftTimeUs);
   3168     Mutex::Autolock autolock(mLock);
   3169     mDriftTimeUs = driftTimeUs;
   3170 }
   3171 
   3172 int64_t MPEG4Writer::getDriftTimeUs() {
   3173     ALOGV("getDriftTimeUs: %" PRId64 " us", mDriftTimeUs);
   3174     Mutex::Autolock autolock(mLock);
   3175     return mDriftTimeUs;
   3176 }
   3177 
   3178 bool MPEG4Writer::isRealTimeRecording() const {
   3179     return mIsRealTimeRecording;
   3180 }
   3181 
   3182 bool MPEG4Writer::useNalLengthFour() {
   3183     return mUse4ByteNalLength;
   3184 }
   3185 
   3186 void MPEG4Writer::Track::bufferChunk(int64_t timestampUs) {
   3187     ALOGV("bufferChunk");
   3188 
   3189     Chunk chunk(this, timestampUs, mChunkSamples);
   3190     mOwner->bufferChunk(chunk);
   3191     mChunkSamples.clear();
   3192 }
   3193 
   3194 int64_t MPEG4Writer::Track::getDurationUs() const {
   3195     return mTrackDurationUs + getStartTimeOffsetTimeUs();
   3196 }
   3197 
   3198 int64_t MPEG4Writer::Track::getEstimatedTrackSizeBytes() const {
   3199     return mEstimatedTrackSizeBytes;
   3200 }
   3201 
   3202 status_t MPEG4Writer::Track::checkCodecSpecificData() const {
   3203     const char *mime;
   3204     CHECK(mMeta->findCString(kKeyMIMEType, &mime));
   3205     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime) ||
   3206         !strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime) ||
   3207         !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime) ||
   3208         !strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) {
   3209         if (!mCodecSpecificData ||
   3210             mCodecSpecificDataSize <= 0) {
   3211             ALOGE("Missing codec specific data");
   3212             return ERROR_MALFORMED;
   3213         }
   3214     } else {
   3215         if (mCodecSpecificData ||
   3216             mCodecSpecificDataSize > 0) {
   3217             ALOGE("Unexepected codec specific data found");
   3218             return ERROR_MALFORMED;
   3219         }
   3220     }
   3221     return OK;
   3222 }
   3223 
   3224 const char *MPEG4Writer::Track::getTrackType() const {
   3225     return mIsAudio ? "Audio" : (mIsVideo ? "Video" : "Metadata");
   3226 }
   3227 
   3228 void MPEG4Writer::Track::writeTrackHeader(bool use32BitOffset) {
   3229     uint32_t now = getMpeg4Time();
   3230     mOwner->beginBox("trak");
   3231         writeTkhdBox(now);
   3232         mOwner->beginBox("mdia");
   3233             writeMdhdBox(now);
   3234             writeHdlrBox();
   3235             mOwner->beginBox("minf");
   3236                 if (mIsAudio) {
   3237                     writeSmhdBox();
   3238                 } else if (mIsVideo) {
   3239                     writeVmhdBox();
   3240                 } else {
   3241                     writeNmhdBox();
   3242                 }
   3243                 writeDinfBox();
   3244                 writeStblBox(use32BitOffset);
   3245             mOwner->endBox();  // minf
   3246         mOwner->endBox();  // mdia
   3247     mOwner->endBox();  // trak
   3248 }
   3249 
   3250 int64_t MPEG4Writer::Track::getMinCttsOffsetTimeUs() {
   3251     // For video tracks with ctts table, this should return the minimum ctts
   3252     // offset in the table. For non-video tracks or video tracks without ctts
   3253     // table, this will return kMaxCttsOffsetTimeUs.
   3254     if (mMinCttsOffsetTicks == mMaxCttsOffsetTicks) {
   3255         return kMaxCttsOffsetTimeUs;
   3256     }
   3257     return mMinCttsOffsetTimeUs;
   3258 }
   3259 
   3260 void MPEG4Writer::Track::writeStblBox(bool use32BitOffset) {
   3261     mOwner->beginBox("stbl");
   3262     mOwner->beginBox("stsd");
   3263     mOwner->writeInt32(0);               // version=0, flags=0
   3264     mOwner->writeInt32(1);               // entry count
   3265     if (mIsAudio) {
   3266         writeAudioFourCCBox();
   3267     } else if (mIsVideo) {
   3268         writeVideoFourCCBox();
   3269     } else {
   3270         writeMetadataFourCCBox();
   3271     }
   3272     mOwner->endBox();  // stsd
   3273     writeSttsBox();
   3274     if (mIsVideo) {
   3275         writeCttsBox();
   3276         writeStssBox();
   3277     }
   3278     writeStszBox();
   3279     writeStscBox();
   3280     writeStcoBox(use32BitOffset);
   3281     mOwner->endBox();  // stbl
   3282 }
   3283 
   3284 void MPEG4Writer::Track::writeMetadataFourCCBox() {
   3285     const char *mime;
   3286     bool success = mMeta->findCString(kKeyMIMEType, &mime);
   3287     CHECK(success);
   3288     const char *fourcc = getFourCCForMime(mime);
   3289     if (fourcc == NULL) {
   3290         ALOGE("Unknown mime type '%s'.", mime);
   3291         TRESPASS();
   3292     }
   3293     mOwner->beginBox(fourcc);    // TextMetaDataSampleEntry
   3294     mOwner->writeCString(mime);  // metadata mime_format
   3295     mOwner->endBox(); // mett
   3296 }
   3297 
   3298 void MPEG4Writer::Track::writeVideoFourCCBox() {
   3299     const char *mime;
   3300     bool success = mMeta->findCString(kKeyMIMEType, &mime);
   3301     CHECK(success);
   3302     const char *fourcc = getFourCCForMime(mime);
   3303     if (fourcc == NULL) {
   3304         ALOGE("Unknown mime type '%s'.", mime);
   3305         TRESPASS();
   3306     }
   3307 
   3308     mOwner->beginBox(fourcc);        // video format
   3309     mOwner->writeInt32(0);           // reserved
   3310     mOwner->writeInt16(0);           // reserved
   3311     mOwner->writeInt16(1);           // data ref index
   3312     mOwner->writeInt16(0);           // predefined
   3313     mOwner->writeInt16(0);           // reserved
   3314     mOwner->writeInt32(0);           // predefined
   3315     mOwner->writeInt32(0);           // predefined
   3316     mOwner->writeInt32(0);           // predefined
   3317 
   3318     int32_t width, height;
   3319     success = mMeta->findInt32(kKeyWidth, &width);
   3320     success = success && mMeta->findInt32(kKeyHeight, &height);
   3321     CHECK(success);
   3322 
   3323     mOwner->writeInt16(width);
   3324     mOwner->writeInt16(height);
   3325     mOwner->writeInt32(0x480000);    // horiz resolution
   3326     mOwner->writeInt32(0x480000);    // vert resolution
   3327     mOwner->writeInt32(0);           // reserved
   3328     mOwner->writeInt16(1);           // frame count
   3329     mOwner->writeInt8(0);            // compressor string length
   3330     mOwner->write("                               ", 31);
   3331     mOwner->writeInt16(0x18);        // depth
   3332     mOwner->writeInt16(-1);          // predefined
   3333 
   3334     if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
   3335         writeMp4vEsdsBox();
   3336     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) {
   3337         writeD263Box();
   3338     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
   3339         writeAvccBox();
   3340     } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) {
   3341         writeHvccBox();
   3342     }
   3343 
   3344     writePaspBox();
   3345     writeColrBox();
   3346     mOwner->endBox();  // mp4v, s263 or avc1
   3347 }
   3348 
   3349 void MPEG4Writer::Track::writeColrBox() {
   3350     ColorAspects aspects;
   3351     memset(&aspects, 0, sizeof(aspects));
   3352     // TRICKY: using | instead of || because we want to execute all findInt32-s
   3353     if (mMeta->findInt32(kKeyColorPrimaries, (int32_t*)&aspects.mPrimaries)
   3354             | mMeta->findInt32(kKeyTransferFunction, (int32_t*)&aspects.mTransfer)
   3355             | mMeta->findInt32(kKeyColorMatrix, (int32_t*)&aspects.mMatrixCoeffs)
   3356             | mMeta->findInt32(kKeyColorRange, (int32_t*)&aspects.mRange)) {
   3357         int32_t primaries, transfer, coeffs;
   3358         bool fullRange;
   3359         ColorUtils::convertCodecColorAspectsToIsoAspects(
   3360                 aspects, &primaries, &transfer, &coeffs, &fullRange);
   3361         mOwner->beginBox("colr");
   3362         mOwner->writeFourcc("nclx");
   3363         mOwner->writeInt16(primaries);
   3364         mOwner->writeInt16(transfer);
   3365         mOwner->writeInt16(coeffs);
   3366         mOwner->writeInt8(int8_t(fullRange ? 0x80 : 0x0));
   3367         mOwner->endBox(); // colr
   3368     }
   3369 }
   3370 
   3371 void MPEG4Writer::Track::writeAudioFourCCBox() {
   3372     const char *mime;
   3373     bool success = mMeta->findCString(kKeyMIMEType, &mime);
   3374     CHECK(success);
   3375     const char *fourcc = getFourCCForMime(mime);
   3376     if (fourcc == NULL) {
   3377         ALOGE("Unknown mime type '%s'.", mime);
   3378         TRESPASS();
   3379     }
   3380 
   3381     mOwner->beginBox(fourcc);        // audio format
   3382     mOwner->writeInt32(0);           // reserved
   3383     mOwner->writeInt16(0);           // reserved
   3384     mOwner->writeInt16(0x1);         // data ref index
   3385     mOwner->writeInt32(0);           // reserved
   3386     mOwner->writeInt32(0);           // reserved
   3387     int32_t nChannels;
   3388     CHECK_EQ(true, mMeta->findInt32(kKeyChannelCount, &nChannels));
   3389     mOwner->writeInt16(nChannels);   // channel count
   3390     mOwner->writeInt16(16);          // sample size
   3391     mOwner->writeInt16(0);           // predefined
   3392     mOwner->writeInt16(0);           // reserved
   3393 
   3394     int32_t samplerate;
   3395     success = mMeta->findInt32(kKeySampleRate, &samplerate);
   3396     CHECK(success);
   3397     mOwner->writeInt32(samplerate << 16);
   3398     if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
   3399         writeMp4aEsdsBox();
   3400     } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_NB, mime) ||
   3401                !strcasecmp(MEDIA_MIMETYPE_AUDIO_AMR_WB, mime)) {
   3402         writeDamrBox();
   3403     }
   3404     mOwner->endBox();
   3405 }
   3406 
   3407 void MPEG4Writer::Track::writeMp4aEsdsBox() {
   3408     mOwner->beginBox("esds");
   3409     CHECK(mCodecSpecificData);
   3410     CHECK_GT(mCodecSpecificDataSize, 0u);
   3411 
   3412     // Make sure all sizes encode to a single byte.
   3413     CHECK_LT(mCodecSpecificDataSize + 23, 128u);
   3414 
   3415     mOwner->writeInt32(0);     // version=0, flags=0
   3416     mOwner->writeInt8(0x03);   // ES_DescrTag
   3417     mOwner->writeInt8(23 + mCodecSpecificDataSize);
   3418     mOwner->writeInt16(0x0000);// ES_ID
   3419     mOwner->writeInt8(0x00);
   3420 
   3421     mOwner->writeInt8(0x04);   // DecoderConfigDescrTag
   3422     mOwner->writeInt8(15 + mCodecSpecificDataSize);
   3423     mOwner->writeInt8(0x40);   // objectTypeIndication ISO/IEC 14492-2
   3424     mOwner->writeInt8(0x15);   // streamType AudioStream
   3425 
   3426     mOwner->writeInt16(0x03);  // XXX
   3427     mOwner->writeInt8(0x00);   // buffer size 24-bit (0x300)
   3428 
   3429     int32_t avgBitrate = 0;
   3430     (void)mMeta->findInt32(kKeyBitRate, &avgBitrate);
   3431     int32_t maxBitrate = 0;
   3432     (void)mMeta->findInt32(kKeyMaxBitRate, &maxBitrate);
   3433     mOwner->writeInt32(maxBitrate);
   3434     mOwner->writeInt32(avgBitrate);
   3435 
   3436     mOwner->writeInt8(0x05);   // DecoderSpecificInfoTag
   3437     mOwner->writeInt8(mCodecSpecificDataSize);
   3438     mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
   3439 
   3440     static const uint8_t kData2[] = {
   3441         0x06,  // SLConfigDescriptorTag
   3442         0x01,
   3443         0x02
   3444     };
   3445     mOwner->write(kData2, sizeof(kData2));
   3446 
   3447     mOwner->endBox();  // esds
   3448 }
   3449 
   3450 void MPEG4Writer::Track::writeMp4vEsdsBox() {
   3451     CHECK(mCodecSpecificData);
   3452     CHECK_GT(mCodecSpecificDataSize, 0u);
   3453 
   3454     // Make sure all sizes encode to a single byte.
   3455     CHECK_LT(23 + mCodecSpecificDataSize, 128u);
   3456 
   3457     mOwner->beginBox("esds");
   3458 
   3459     mOwner->writeInt32(0);    // version=0, flags=0
   3460 
   3461     mOwner->writeInt8(0x03);  // ES_DescrTag
   3462     mOwner->writeInt8(23 + mCodecSpecificDataSize);
   3463     mOwner->writeInt16(0x0000);  // ES_ID
   3464     mOwner->writeInt8(0x1f);
   3465 
   3466     mOwner->writeInt8(0x04);  // DecoderConfigDescrTag
   3467     mOwner->writeInt8(15 + mCodecSpecificDataSize);
   3468     mOwner->writeInt8(0x20);  // objectTypeIndication ISO/IEC 14492-2
   3469     mOwner->writeInt8(0x11);  // streamType VisualStream
   3470 
   3471     static const uint8_t kData[] = {
   3472         0x01, 0x77, 0x00, // buffer size 96000 bytes
   3473     };
   3474     mOwner->write(kData, sizeof(kData));
   3475 
   3476     int32_t avgBitrate = 0;
   3477     (void)mMeta->findInt32(kKeyBitRate, &avgBitrate);
   3478     int32_t maxBitrate = 0;
   3479     (void)mMeta->findInt32(kKeyMaxBitRate, &maxBitrate);
   3480     mOwner->writeInt32(maxBitrate);
   3481     mOwner->writeInt32(avgBitrate);
   3482 
   3483     mOwner->writeInt8(0x05);  // DecoderSpecificInfoTag
   3484 
   3485     mOwner->writeInt8(mCodecSpecificDataSize);
   3486     mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
   3487 
   3488     static const uint8_t kData2[] = {
   3489         0x06,  // SLConfigDescriptorTag
   3490         0x01,
   3491         0x02
   3492     };
   3493     mOwner->write(kData2, sizeof(kData2));
   3494 
   3495     mOwner->endBox();  // esds
   3496 }
   3497 
   3498 void MPEG4Writer::Track::writeTkhdBox(uint32_t now) {
   3499     mOwner->beginBox("tkhd");
   3500     // Flags = 7 to indicate that the track is enabled, and
   3501     // part of the presentation
   3502     mOwner->writeInt32(0x07);          // version=0, flags=7
   3503     mOwner->writeInt32(now);           // creation time
   3504     mOwner->writeInt32(now);           // modification time
   3505     mOwner->writeInt32(mTrackId);      // track id starts with 1
   3506     mOwner->writeInt32(0);             // reserved
   3507     int64_t trakDurationUs = getDurationUs();
   3508     int32_t mvhdTimeScale = mOwner->getTimeScale();
   3509     int32_t tkhdDuration =
   3510         (trakDurationUs * mvhdTimeScale + 5E5) / 1E6;
   3511     mOwner->writeInt32(tkhdDuration);  // in mvhd timescale
   3512     mOwner->writeInt32(0);             // reserved
   3513     mOwner->writeInt32(0);             // reserved
   3514     mOwner->writeInt16(0);             // layer
   3515     mOwner->writeInt16(0);             // alternate group
   3516     mOwner->writeInt16(mIsAudio ? 0x100 : 0);  // volume
   3517     mOwner->writeInt16(0);             // reserved
   3518 
   3519     mOwner->writeCompositionMatrix(mRotation);       // matrix
   3520 
   3521     if (!mIsVideo) {
   3522         mOwner->writeInt32(0);
   3523         mOwner->writeInt32(0);
   3524     } else {
   3525         int32_t width, height;
   3526         bool success = mMeta->findInt32(kKeyDisplayWidth, &width);
   3527         success = success && mMeta->findInt32(kKeyDisplayHeight, &height);
   3528 
   3529         // Use width/height if display width/height are not present.
   3530         if (!success) {
   3531             success = mMeta->findInt32(kKeyWidth, &width);
   3532             success = success && mMeta->findInt32(kKeyHeight, &height);
   3533         }
   3534         CHECK(success);
   3535 
   3536         mOwner->writeInt32(width << 16);   // 32-bit fixed-point value
   3537         mOwner->writeInt32(height << 16);  // 32-bit fixed-point value
   3538     }
   3539     mOwner->endBox();  // tkhd
   3540 }
   3541 
   3542 void MPEG4Writer::Track::writeVmhdBox() {
   3543     mOwner->beginBox("vmhd");
   3544     mOwner->writeInt32(0x01);        // version=0, flags=1
   3545     mOwner->writeInt16(0);           // graphics mode
   3546     mOwner->writeInt16(0);           // opcolor
   3547     mOwner->writeInt16(0);
   3548     mOwner->writeInt16(0);
   3549     mOwner->endBox();
   3550 }
   3551 
   3552 void MPEG4Writer::Track::writeSmhdBox() {
   3553     mOwner->beginBox("smhd");
   3554     mOwner->writeInt32(0);           // version=0, flags=0
   3555     mOwner->writeInt16(0);           // balance
   3556     mOwner->writeInt16(0);           // reserved
   3557     mOwner->endBox();
   3558 }
   3559 
   3560 void MPEG4Writer::Track::writeNmhdBox() {
   3561     mOwner->beginBox("nmhd");
   3562     mOwner->writeInt32(0);           // version=0, flags=0
   3563     mOwner->endBox();
   3564 }
   3565 
   3566 void MPEG4Writer::Track::writeHdlrBox() {
   3567     mOwner->beginBox("hdlr");
   3568     mOwner->writeInt32(0);             // version=0, flags=0
   3569     mOwner->writeInt32(0);             // component type: should be mhlr
   3570     mOwner->writeFourcc(mIsAudio ? "soun" : (mIsVideo ? "vide" : "meta"));  // component subtype
   3571     mOwner->writeInt32(0);             // reserved
   3572     mOwner->writeInt32(0);             // reserved
   3573     mOwner->writeInt32(0);             // reserved
   3574     // Removing "r" for the name string just makes the string 4 byte aligned
   3575     mOwner->writeCString(mIsAudio ? "SoundHandle": (mIsVideo ? "VideoHandle" : "MetadHandle"));
   3576     mOwner->endBox();
   3577 }
   3578 
   3579 void MPEG4Writer::Track::writeMdhdBox(uint32_t now) {
   3580     int64_t trakDurationUs = getDurationUs();
   3581     int64_t mdhdDuration = (trakDurationUs * mTimeScale + 5E5) / 1E6;
   3582     mOwner->beginBox("mdhd");
   3583 
   3584     if (mdhdDuration > UINT32_MAX) {
   3585         mOwner->writeInt32((1 << 24));            // version=1, flags=0
   3586         mOwner->writeInt64((int64_t)now);         // creation time
   3587         mOwner->writeInt64((int64_t)now);         // modification time
   3588         mOwner->writeInt32(mTimeScale);           // media timescale
   3589         mOwner->writeInt64(mdhdDuration);         // media timescale
   3590     } else {
   3591         mOwner->writeInt32(0);                      // version=0, flags=0
   3592         mOwner->writeInt32(now);                    // creation time
   3593         mOwner->writeInt32(now);                    // modification time
   3594         mOwner->writeInt32(mTimeScale);             // media timescale
   3595         mOwner->writeInt32((int32_t)mdhdDuration);  // use media timescale
   3596     }
   3597     // Language follows the three letter standard ISO-639-2/T
   3598     // 'e', 'n', 'g' for "English", for instance.
   3599     // Each character is packed as the difference between its ASCII value and 0x60.
   3600     // For "English", these are 00101, 01110, 00111.
   3601     // XXX: Where is the padding bit located: 0x15C7?
   3602     const char *lang = NULL;
   3603     int16_t langCode = 0;
   3604     if (mMeta->findCString(kKeyMediaLanguage, &lang) && lang && strnlen(lang, 3) > 2) {
   3605         langCode = ((lang[0] & 0x1f) << 10) | ((lang[1] & 0x1f) << 5) | (lang[2] & 0x1f);
   3606     }
   3607     mOwner->writeInt16(langCode);      // language code
   3608     mOwner->writeInt16(0);             // predefined
   3609     mOwner->endBox();
   3610 }
   3611 
   3612 void MPEG4Writer::Track::writeDamrBox() {
   3613     // 3gpp2 Spec AMRSampleEntry fields
   3614     mOwner->beginBox("damr");
   3615     mOwner->writeCString("   ");  // vendor: 4 bytes
   3616     mOwner->writeInt8(0);         // decoder version
   3617     mOwner->writeInt16(0x83FF);   // mode set: all enabled
   3618     mOwner->writeInt8(0);         // mode change period
   3619     mOwner->writeInt8(1);         // frames per sample
   3620     mOwner->endBox();
   3621 }
   3622 
   3623 void MPEG4Writer::Track::writeUrlBox() {
   3624     // The table index here refers to the sample description index
   3625     // in the sample table entries.
   3626     mOwner->beginBox("url ");
   3627     mOwner->writeInt32(1);  // version=0, flags=1 (self-contained)
   3628     mOwner->endBox();  // url
   3629 }
   3630 
   3631 void MPEG4Writer::Track::writeDrefBox() {
   3632     mOwner->beginBox("dref");
   3633     mOwner->writeInt32(0);  // version=0, flags=0
   3634     mOwner->writeInt32(1);  // entry count (either url or urn)
   3635     writeUrlBox();
   3636     mOwner->endBox();  // dref
   3637 }
   3638 
   3639 void MPEG4Writer::Track::writeDinfBox() {
   3640     mOwner->beginBox("dinf");
   3641     writeDrefBox();
   3642     mOwner->endBox();  // dinf
   3643 }
   3644 
   3645 void MPEG4Writer::Track::writeAvccBox() {
   3646     CHECK(mCodecSpecificData);
   3647     CHECK_GE(mCodecSpecificDataSize, 5u);
   3648 
   3649     // Patch avcc's lengthSize field to match the number
   3650     // of bytes we use to indicate the size of a nal unit.
   3651     uint8_t *ptr = (uint8_t *)mCodecSpecificData;
   3652     ptr[4] = (ptr[4] & 0xfc) | (mOwner->useNalLengthFour() ? 3 : 1);
   3653     mOwner->beginBox("avcC");
   3654     mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
   3655     mOwner->endBox();  // avcC
   3656 }
   3657 
   3658 
   3659 void MPEG4Writer::Track::writeHvccBox() {
   3660     CHECK(mCodecSpecificData);
   3661     CHECK_GE(mCodecSpecificDataSize, 5u);
   3662 
   3663     // Patch avcc's lengthSize field to match the number
   3664     // of bytes we use to indicate the size of a nal unit.
   3665     uint8_t *ptr = (uint8_t *)mCodecSpecificData;
   3666     ptr[21] = (ptr[21] & 0xfc) | (mOwner->useNalLengthFour() ? 3 : 1);
   3667     mOwner->beginBox("hvcC");
   3668     mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
   3669     mOwner->endBox();  // hvcC
   3670 }
   3671 
   3672 void MPEG4Writer::Track::writeD263Box() {
   3673     mOwner->beginBox("d263");
   3674     mOwner->writeInt32(0);  // vendor
   3675     mOwner->writeInt8(0);   // decoder version
   3676     mOwner->writeInt8(10);  // level: 10
   3677     mOwner->writeInt8(0);   // profile: 0
   3678     mOwner->endBox();  // d263
   3679 }
   3680 
   3681 // This is useful if the pixel is not square
   3682 void MPEG4Writer::Track::writePaspBox() {
   3683     mOwner->beginBox("pasp");
   3684     mOwner->writeInt32(1 << 16);  // hspacing
   3685     mOwner->writeInt32(1 << 16);  // vspacing
   3686     mOwner->endBox();  // pasp
   3687 }
   3688 
   3689 int64_t MPEG4Writer::Track::getStartTimeOffsetTimeUs() const {
   3690     int64_t trackStartTimeOffsetUs = 0;
   3691     int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
   3692     if (mStartTimestampUs != -1 && mStartTimestampUs != moovStartTimeUs) {
   3693         CHECK_GT(mStartTimestampUs, moovStartTimeUs);
   3694         trackStartTimeOffsetUs = mStartTimestampUs - moovStartTimeUs;
   3695     }
   3696     return trackStartTimeOffsetUs;
   3697 }
   3698 
   3699 int32_t MPEG4Writer::Track::getStartTimeOffsetScaledTime() const {
   3700     return (getStartTimeOffsetTimeUs() * mTimeScale + 500000LL) / 1000000LL;
   3701 }
   3702 
   3703 void MPEG4Writer::Track::writeSttsBox() {
   3704     mOwner->beginBox("stts");
   3705     mOwner->writeInt32(0);  // version=0, flags=0
   3706     if (mMinCttsOffsetTicks == mMaxCttsOffsetTicks) {
   3707         // For non-vdeio tracks or video tracks without ctts table,
   3708         // adjust duration of first sample for tracks to account for
   3709         // first sample not starting at the media start time.
   3710         // TODO: consider signaling this using some offset
   3711         // as this is not quite correct.
   3712         uint32_t duration;
   3713         CHECK(mSttsTableEntries->get(duration, 1));
   3714         duration = htonl(duration);  // Back to host byte order
   3715         mSttsTableEntries->set(htonl(duration + getStartTimeOffsetScaledTime()), 1);
   3716     }
   3717     mSttsTableEntries->write(mOwner);
   3718     mOwner->endBox();  // stts
   3719 }
   3720 
   3721 void MPEG4Writer::Track::writeCttsBox() {
   3722     // There is no B frame at all
   3723     if (mMinCttsOffsetTicks == mMaxCttsOffsetTicks) {
   3724         return;
   3725     }
   3726 
   3727     // Do not write ctts box when there is no need to have it.
   3728     if (mCttsTableEntries->count() == 0) {
   3729         return;
   3730     }
   3731 
   3732     ALOGV("ctts box has %d entries with range [%" PRId64 ", %" PRId64 "]",
   3733             mCttsTableEntries->count(), mMinCttsOffsetTicks, mMaxCttsOffsetTicks);
   3734 
   3735     mOwner->beginBox("ctts");
   3736     mOwner->writeInt32(0);  // version=0, flags=0
   3737     int64_t deltaTimeUs = kMaxCttsOffsetTimeUs - getStartTimeOffsetTimeUs();
   3738     int64_t delta = (deltaTimeUs * mTimeScale + 500000LL) / 1000000LL;
   3739     mCttsTableEntries->adjustEntries([delta](size_t /* ix */, uint32_t (&value)[2]) {
   3740         // entries are <count, ctts> pairs; adjust only ctts
   3741         uint32_t duration = htonl(value[1]); // back to host byte order
   3742         // Prevent overflow and underflow
   3743         if (delta > duration) {
   3744             duration = 0;
   3745         } else if (delta < 0 && UINT32_MAX + delta < duration) {
   3746             duration = UINT32_MAX;
   3747         } else {
   3748             duration -= delta;
   3749         }
   3750         value[1] = htonl(duration);
   3751     });
   3752     mCttsTableEntries->write(mOwner);
   3753     mOwner->endBox();  // ctts
   3754 }
   3755 
   3756 void MPEG4Writer::Track::writeStssBox() {
   3757     mOwner->beginBox("stss");
   3758     mOwner->writeInt32(0);  // version=0, flags=0
   3759     mStssTableEntries->write(mOwner);
   3760     mOwner->endBox();  // stss
   3761 }
   3762 
   3763 void MPEG4Writer::Track::writeStszBox() {
   3764     mOwner->beginBox("stsz");
   3765     mOwner->writeInt32(0);  // version=0, flags=0
   3766     mOwner->writeInt32(0);
   3767     mStszTableEntries->write(mOwner);
   3768     mOwner->endBox();  // stsz
   3769 }
   3770 
   3771 void MPEG4Writer::Track::writeStscBox() {
   3772     mOwner->beginBox("stsc");
   3773     mOwner->writeInt32(0);  // version=0, flags=0
   3774     mStscTableEntries->write(mOwner);
   3775     mOwner->endBox();  // stsc
   3776 }
   3777 
   3778 void MPEG4Writer::Track::writeStcoBox(bool use32BitOffset) {
   3779     mOwner->beginBox(use32BitOffset? "stco": "co64");
   3780     mOwner->writeInt32(0);  // version=0, flags=0
   3781     if (use32BitOffset) {
   3782         mStcoTableEntries->write(mOwner);
   3783     } else {
   3784         mCo64TableEntries->write(mOwner);
   3785     }
   3786     mOwner->endBox();  // stco or co64
   3787 }
   3788 
   3789 void MPEG4Writer::writeUdtaBox() {
   3790     beginBox("udta");
   3791     writeGeoDataBox();
   3792     endBox();
   3793 }
   3794 
   3795 void MPEG4Writer::writeHdlr() {
   3796     beginBox("hdlr");
   3797     writeInt32(0); // Version, Flags
   3798     writeInt32(0); // Predefined
   3799     writeFourcc("mdta");
   3800     writeInt32(0); // Reserved[0]
   3801     writeInt32(0); // Reserved[1]
   3802     writeInt32(0); // Reserved[2]
   3803     writeInt8(0);  // Name (empty)
   3804     endBox();
   3805 }
   3806 
   3807 void MPEG4Writer::writeKeys() {
   3808     size_t count = mMetaKeys->countEntries();
   3809 
   3810     beginBox("keys");
   3811     writeInt32(0);     // Version, Flags
   3812     writeInt32(count); // Entry_count
   3813     for (size_t i = 0; i < count; i++) {
   3814         AMessage::Type type;
   3815         const char *key = mMetaKeys->getEntryNameAt(i, &type);
   3816         size_t n = strlen(key);
   3817         writeInt32(n + 8);
   3818         writeFourcc("mdta");
   3819         write(key, n); // write without the \0
   3820     }
   3821     endBox();
   3822 }
   3823 
   3824 void MPEG4Writer::writeIlst() {
   3825     size_t count = mMetaKeys->countEntries();
   3826 
   3827     beginBox("ilst");
   3828     for (size_t i = 0; i < count; i++) {
   3829         beginBox(i + 1); // key id (1-based)
   3830         beginBox("data");
   3831         AMessage::Type type;
   3832         const char *key = mMetaKeys->getEntryNameAt(i, &type);
   3833         switch (type) {
   3834             case AMessage::kTypeString:
   3835             {
   3836                 AString val;
   3837                 CHECK(mMetaKeys->findString(key, &val));
   3838                 writeInt32(1); // type = UTF8
   3839                 writeInt32(0); // default country/language
   3840                 write(val.c_str(), strlen(val.c_str())); // write without \0
   3841                 break;
   3842             }
   3843 
   3844             case AMessage::kTypeFloat:
   3845             {
   3846                 float val;
   3847                 CHECK(mMetaKeys->findFloat(key, &val));
   3848                 writeInt32(23); // type = float32
   3849                 writeInt32(0);  // default country/language
   3850                 writeInt32(*reinterpret_cast<int32_t *>(&val));
   3851                 break;
   3852             }
   3853 
   3854             case AMessage::kTypeInt32:
   3855             {
   3856                 int32_t val;
   3857                 CHECK(mMetaKeys->findInt32(key, &val));
   3858                 writeInt32(67); // type = signed int32
   3859                 writeInt32(0);  // default country/language
   3860                 writeInt32(val);
   3861                 break;
   3862             }
   3863 
   3864             default:
   3865             {
   3866                 ALOGW("Unsupported key type, writing 0 instead");
   3867                 writeInt32(77); // type = unsigned int32
   3868                 writeInt32(0);  // default country/language
   3869                 writeInt32(0);
   3870                 break;
   3871             }
   3872         }
   3873         endBox(); // data
   3874         endBox(); // key id
   3875     }
   3876     endBox(); // ilst
   3877 }
   3878 
   3879 void MPEG4Writer::writeMetaBox() {
   3880     size_t count = mMetaKeys->countEntries();
   3881     if (count == 0) {
   3882         return;
   3883     }
   3884 
   3885     beginBox("meta");
   3886     writeHdlr();
   3887     writeKeys();
   3888     writeIlst();
   3889     endBox();
   3890 }
   3891 
   3892 /*
   3893  * Geodata is stored according to ISO-6709 standard.
   3894  */
   3895 void MPEG4Writer::writeGeoDataBox() {
   3896     beginBox("\xA9xyz");
   3897     /*
   3898      * For historical reasons, any user data start
   3899      * with "\0xA9", must be followed by its assoicated
   3900      * language code.
   3901      * 0x0012: text string length
   3902      * 0x15c7: lang (locale) code: en
   3903      */
   3904     writeInt32(0x001215c7);
   3905     writeLatitude(mLatitudex10000);
   3906     writeLongitude(mLongitudex10000);
   3907     writeInt8(0x2F);
   3908     endBox();
   3909 }
   3910 
   3911 }  // namespace android
   3912