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