Home | History | Annotate | Download | only in stagefright
      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 #ifndef MPEG4_WRITER_H_
     18 
     19 #define MPEG4_WRITER_H_
     20 
     21 #include <stdio.h>
     22 
     23 #include <media/stagefright/MediaWriter.h>
     24 #include <utils/List.h>
     25 #include <utils/threads.h>
     26 
     27 namespace android {
     28 
     29 class MediaBuffer;
     30 class MediaSource;
     31 class MetaData;
     32 
     33 class MPEG4Writer : public MediaWriter {
     34 public:
     35     MPEG4Writer(const char *filename);
     36     MPEG4Writer(int fd);
     37 
     38     virtual status_t addSource(const sp<MediaSource> &source);
     39     virtual status_t start(MetaData *param = NULL);
     40     virtual status_t stop();
     41     virtual status_t pause();
     42     virtual bool reachedEOS();
     43     virtual status_t dump(int fd, const Vector<String16>& args);
     44 
     45     void beginBox(const char *fourcc);
     46     void writeInt8(int8_t x);
     47     void writeInt16(int16_t x);
     48     void writeInt32(int32_t x);
     49     void writeInt64(int64_t x);
     50     void writeCString(const char *s);
     51     void writeFourcc(const char *fourcc);
     52     void write(const void *data, size_t size);
     53     void endBox();
     54     uint32_t interleaveDuration() const { return mInterleaveDurationUs; }
     55     status_t setInterleaveDuration(uint32_t duration);
     56     int32_t getTimeScale() const { return mTimeScale; }
     57 
     58     status_t setGeoData(int latitudex10000, int longitudex10000);
     59     void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
     60     int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
     61 
     62 protected:
     63     virtual ~MPEG4Writer();
     64 
     65 private:
     66     class Track;
     67 
     68     int  mFd;
     69     status_t mInitCheck;
     70     bool mUse4ByteNalLength;
     71     bool mUse32BitOffset;
     72     bool mIsFileSizeLimitExplicitlyRequested;
     73     bool mPaused;
     74     bool mStarted;  // Writer thread + track threads started successfully
     75     bool mWriterThreadStarted;  // Only writer thread started successfully
     76     off64_t mOffset;
     77     off_t mMdatOffset;
     78     uint8_t *mMoovBoxBuffer;
     79     off64_t mMoovBoxBufferOffset;
     80     bool  mWriteMoovBoxToMemory;
     81     off64_t mFreeBoxOffset;
     82     bool mStreamableFile;
     83     off64_t mEstimatedMoovBoxSize;
     84     uint32_t mInterleaveDurationUs;
     85     int32_t mTimeScale;
     86     int64_t mStartTimestampUs;
     87     int mLatitudex10000;
     88     int mLongitudex10000;
     89     bool mAreGeoTagsAvailable;
     90     int32_t mStartTimeOffsetMs;
     91 
     92     Mutex mLock;
     93 
     94     List<Track *> mTracks;
     95 
     96     List<off64_t> mBoxes;
     97 
     98     void setStartTimestampUs(int64_t timeUs);
     99     int64_t getStartTimestampUs();  // Not const
    100     status_t startTracks(MetaData *params);
    101     size_t numTracks();
    102     int64_t estimateMoovBoxSize(int32_t bitRate);
    103 
    104     struct Chunk {
    105         Track               *mTrack;        // Owner
    106         int64_t             mTimeStampUs;   // Timestamp of the 1st sample
    107         List<MediaBuffer *> mSamples;       // Sample data
    108 
    109         // Convenient constructor
    110         Chunk(): mTrack(NULL), mTimeStampUs(0) {}
    111 
    112         Chunk(Track *track, int64_t timeUs, List<MediaBuffer *> samples)
    113             : mTrack(track), mTimeStampUs(timeUs), mSamples(samples) {
    114         }
    115 
    116     };
    117     struct ChunkInfo {
    118         Track               *mTrack;        // Owner
    119         List<Chunk>         mChunks;        // Remaining chunks to be written
    120 
    121         // Previous chunk timestamp that has been written
    122         int64_t mPrevChunkTimestampUs;
    123 
    124         // Max time interval between neighboring chunks
    125         int64_t mMaxInterChunkDurUs;
    126 
    127     };
    128 
    129     bool            mIsFirstChunk;
    130     volatile bool   mDone;                  // Writer thread is done?
    131     pthread_t       mThread;                // Thread id for the writer
    132     List<ChunkInfo> mChunkInfos;            // Chunk infos
    133     Condition       mChunkReadyCondition;   // Signal that chunks are available
    134 
    135     // Writer thread handling
    136     status_t startWriterThread();
    137     void stopWriterThread();
    138     static void *ThreadWrapper(void *me);
    139     void threadFunc();
    140 
    141     // Buffer a single chunk to be written out later.
    142     void bufferChunk(const Chunk& chunk);
    143 
    144     // Write all buffered chunks from all tracks
    145     void writeAllChunks();
    146 
    147     // Retrieve the proper chunk to write if there is one
    148     // Return true if a chunk is found; otherwise, return false.
    149     bool findChunkToWrite(Chunk *chunk);
    150 
    151     // Actually write the given chunk to the file.
    152     void writeChunkToFile(Chunk* chunk);
    153 
    154     // Adjust other track media clock (presumably wall clock)
    155     // based on audio track media clock with the drift time.
    156     int64_t mDriftTimeUs;
    157     void setDriftTimeUs(int64_t driftTimeUs);
    158     int64_t getDriftTimeUs();
    159 
    160     // Return whether the nal length is 4 bytes or 2 bytes
    161     // Only makes sense for H.264/AVC
    162     bool useNalLengthFour();
    163 
    164     void lock();
    165     void unlock();
    166 
    167     // Acquire lock before calling these methods
    168     off64_t addSample_l(MediaBuffer *buffer);
    169     off64_t addLengthPrefixedSample_l(MediaBuffer *buffer);
    170 
    171     inline size_t write(const void *ptr, size_t size, size_t nmemb);
    172     bool exceedsFileSizeLimit();
    173     bool use32BitFileOffset() const;
    174     bool exceedsFileDurationLimit();
    175     bool isFileStreamable() const;
    176     void trackProgressStatus(size_t trackId, int64_t timeUs, status_t err = OK);
    177     void writeCompositionMatrix(int32_t degrees);
    178     void writeMvhdBox(int64_t durationUs);
    179     void writeMoovBox(int64_t durationUs);
    180     void writeFtypBox(MetaData *param);
    181     void writeUdtaBox();
    182     void writeGeoDataBox();
    183     void writeLatitude(int degreex10000);
    184     void writeLongitude(int degreex10000);
    185     void sendSessionSummary();
    186     void release();
    187 
    188     MPEG4Writer(const MPEG4Writer &);
    189     MPEG4Writer &operator=(const MPEG4Writer &);
    190 };
    191 
    192 }  // namespace android
    193 
    194 #endif  // MPEG4_WRITER_H_
    195