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