• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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