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() { return reset(); }
     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     inline size_t write(const void *ptr, size_t size, size_t nmemb);
     54     void endBox();
     55     uint32_t interleaveDuration() const { return mInterleaveDurationUs; }
     56     status_t setInterleaveDuration(uint32_t duration);
     57     int32_t getTimeScale() const { return mTimeScale; }
     58 
     59     status_t setGeoData(int latitudex10000, int longitudex10000);
     60     void setStartTimeOffsetMs(int ms) { mStartTimeOffsetMs = ms; }
     61     int32_t getStartTimeOffsetMs() const { return mStartTimeOffsetMs; }
     62 
     63 protected:
     64     virtual ~MPEG4Writer();
     65 
     66 private:
     67     class Track;
     68 
     69     int  mFd;
     70     status_t mInitCheck;
     71     bool mUse4ByteNalLength;
     72     bool mUse32BitOffset;
     73     bool mIsFileSizeLimitExplicitlyRequested;
     74     bool mPaused;
     75     bool mStarted;  // Writer thread + track threads started successfully
     76     bool mWriterThreadStarted;  // Only writer thread started successfully
     77     off64_t mOffset;
     78     off_t mMdatOffset;
     79     uint8_t *mMoovBoxBuffer;
     80     off64_t mMoovBoxBufferOffset;
     81     bool  mWriteMoovBoxToMemory;
     82     off64_t mFreeBoxOffset;
     83     bool mStreamableFile;
     84     off64_t mEstimatedMoovBoxSize;
     85     uint32_t mInterleaveDurationUs;
     86     int32_t mTimeScale;
     87     int64_t mStartTimestampUs;
     88     int mLatitudex10000;
     89     int mLongitudex10000;
     90     bool mAreGeoTagsAvailable;
     91     int32_t mStartTimeOffsetMs;
     92 
     93     Mutex mLock;
     94 
     95     List<Track *> mTracks;
     96 
     97     List<off64_t> mBoxes;
     98 
     99     void setStartTimestampUs(int64_t timeUs);
    100     int64_t getStartTimestampUs();  // Not const
    101     status_t startTracks(MetaData *params);
    102     size_t numTracks();
    103     int64_t estimateMoovBoxSize(int32_t bitRate);
    104 
    105     struct Chunk {
    106         Track               *mTrack;        // Owner
    107         int64_t             mTimeStampUs;   // Timestamp of the 1st sample
    108         List<MediaBuffer *> mSamples;       // Sample data
    109 
    110         // Convenient constructor
    111         Chunk(): mTrack(NULL), mTimeStampUs(0) {}
    112 
    113         Chunk(Track *track, int64_t timeUs, List<MediaBuffer *> samples)
    114             : mTrack(track), mTimeStampUs(timeUs), mSamples(samples) {
    115         }
    116 
    117     };
    118     struct ChunkInfo {
    119         Track               *mTrack;        // Owner
    120         List<Chunk>         mChunks;        // Remaining chunks to be written
    121 
    122         // Previous chunk timestamp that has been written
    123         int64_t mPrevChunkTimestampUs;
    124 
    125         // Max time interval between neighboring chunks
    126         int64_t mMaxInterChunkDurUs;
    127 
    128     };
    129 
    130     bool            mIsFirstChunk;
    131     volatile bool   mDone;                  // Writer thread is done?
    132     pthread_t       mThread;                // Thread id for the writer
    133     List<ChunkInfo> mChunkInfos;            // Chunk infos
    134     Condition       mChunkReadyCondition;   // Signal that chunks are available
    135 
    136     // Writer thread handling
    137     status_t startWriterThread();
    138     void stopWriterThread();
    139     static void *ThreadWrapper(void *me);
    140     void threadFunc();
    141 
    142     // Buffer a single chunk to be written out later.
    143     void bufferChunk(const Chunk& chunk);
    144 
    145     // Write all buffered chunks from all tracks
    146     void writeAllChunks();
    147 
    148     // Retrieve the proper chunk to write if there is one
    149     // Return true if a chunk is found; otherwise, return false.
    150     bool findChunkToWrite(Chunk *chunk);
    151 
    152     // Actually write the given chunk to the file.
    153     void writeChunkToFile(Chunk* chunk);
    154 
    155     // Adjust other track media clock (presumably wall clock)
    156     // based on audio track media clock with the drift time.
    157     int64_t mDriftTimeUs;
    158     void setDriftTimeUs(int64_t driftTimeUs);
    159     int64_t getDriftTimeUs();
    160 
    161     // Return whether the nal length is 4 bytes or 2 bytes
    162     // Only makes sense for H.264/AVC
    163     bool useNalLengthFour();
    164 
    165     void lock();
    166     void unlock();
    167 
    168     // Acquire lock before calling these methods
    169     off64_t addSample_l(MediaBuffer *buffer);
    170     off64_t addLengthPrefixedSample_l(MediaBuffer *buffer);
    171 
    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     status_t reset();
    188 
    189     static uint32_t getMpeg4Time();
    190 
    191     MPEG4Writer(const MPEG4Writer &);
    192     MPEG4Writer &operator=(const MPEG4Writer &);
    193 };
    194 
    195 }  // namespace android
    196 
    197 #endif  // MPEG4_WRITER_H_
    198