MPEG4Writer.h revision 2cf9c5073ca3342ee52673ad68763fadd2c2be79
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 27namespace android { 28 29class MediaBuffer; 30class MediaSource; 31class MetaData; 32 33class MPEG4Writer : public MediaWriter { 34public: 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 62protected: 63 virtual ~MPEG4Writer(); 64 65private: 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; 75 off64_t mOffset; 76 off_t mMdatOffset; 77 uint8_t *mMoovBoxBuffer; 78 off64_t mMoovBoxBufferOffset; 79 bool mWriteMoovBoxToMemory; 80 off64_t mFreeBoxOffset; 81 bool mStreamableFile; 82 off64_t mEstimatedMoovBoxSize; 83 uint32_t mInterleaveDurationUs; 84 int32_t mTimeScale; 85 int64_t mStartTimestampUs; 86 int mLatitudex10000; 87 int mLongitudex10000; 88 bool mAreGeoTagsAvailable; 89 int32_t mStartTimeOffsetMs; 90 91 Mutex mLock; 92 93 List<Track *> mTracks; 94 95 List<off64_t> mBoxes; 96 97 void setStartTimestampUs(int64_t timeUs); 98 int64_t getStartTimestampUs(); // Not const 99 status_t startTracks(MetaData *params); 100 size_t numTracks(); 101 int64_t estimateMoovBoxSize(int32_t bitRate); 102 103 struct Chunk { 104 Track *mTrack; // Owner 105 int64_t mTimeStampUs; // Timestamp of the 1st sample 106 List<MediaBuffer *> mSamples; // Sample data 107 108 // Convenient constructor 109 Chunk(): mTrack(NULL), mTimeStampUs(0) {} 110 111 Chunk(Track *track, int64_t timeUs, List<MediaBuffer *> samples) 112 : mTrack(track), mTimeStampUs(timeUs), mSamples(samples) { 113 } 114 115 }; 116 struct ChunkInfo { 117 Track *mTrack; // Owner 118 List<Chunk> mChunks; // Remaining chunks to be written 119 120 // Previous chunk timestamp that has been written 121 int64_t mPrevChunkTimestampUs; 122 123 // Max time interval between neighboring chunks 124 int64_t mMaxInterChunkDurUs; 125 126 }; 127 128 bool mIsFirstChunk; 129 volatile bool mDone; // Writer thread is done? 130 pthread_t mThread; // Thread id for the writer 131 List<ChunkInfo> mChunkInfos; // Chunk infos 132 Condition mChunkReadyCondition; // Signal that chunks are available 133 134 // Writer thread handling 135 status_t startWriterThread(); 136 void stopWriterThread(); 137 static void *ThreadWrapper(void *me); 138 void threadFunc(); 139 140 // Buffer a single chunk to be written out later. 141 void bufferChunk(const Chunk& chunk); 142 143 // Write all buffered chunks from all tracks 144 void writeAllChunks(); 145 146 // Retrieve the proper chunk to write if there is one 147 // Return true if a chunk is found; otherwise, return false. 148 bool findChunkToWrite(Chunk *chunk); 149 150 // Actually write the given chunk to the file. 151 void writeChunkToFile(Chunk* chunk); 152 153 // Adjust other track media clock (presumably wall clock) 154 // based on audio track media clock with the drift time. 155 int64_t mDriftTimeUs; 156 void setDriftTimeUs(int64_t driftTimeUs); 157 int64_t getDriftTimeUs(); 158 159 // Return whether the nal length is 4 bytes or 2 bytes 160 // Only makes sense for H.264/AVC 161 bool useNalLengthFour(); 162 163 void lock(); 164 void unlock(); 165 166 // Acquire lock before calling these methods 167 off64_t addSample_l(MediaBuffer *buffer); 168 off64_t addLengthPrefixedSample_l(MediaBuffer *buffer); 169 170 inline size_t write(const void *ptr, size_t size, size_t nmemb); 171 bool exceedsFileSizeLimit(); 172 bool use32BitFileOffset() const; 173 bool exceedsFileDurationLimit(); 174 bool isFileStreamable() const; 175 void trackProgressStatus(size_t trackId, int64_t timeUs, status_t err = OK); 176 void writeCompositionMatrix(int32_t degrees); 177 void writeMvhdBox(int64_t durationUs); 178 void writeMoovBox(int64_t durationUs); 179 void writeFtypBox(MetaData *param); 180 void writeUdtaBox(); 181 void writeGeoDataBox(); 182 void writeLatitude(int degreex10000); 183 void writeLongitude(int degreex10000); 184 void sendSessionSummary(); 185 186 MPEG4Writer(const MPEG4Writer &); 187 MPEG4Writer &operator=(const MPEG4Writer &); 188}; 189 190} // namespace android 191 192#endif // MPEG4_WRITER_H_ 193