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