blob: 4b5674e4a279b7be85087573b298041e88493271 [file] [log] [blame]
Andreas Hubere46b7be2009-07-14 16:56:47 -07001/*
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
Andreas Huber996dddf2010-01-25 15:30:31 -080023#include <media/stagefright/MediaWriter.h>
Andreas Hubere46b7be2009-07-14 16:56:47 -070024#include <utils/List.h>
Andreas Hubere46b7be2009-07-14 16:56:47 -070025#include <utils/threads.h>
26
27namespace android {
28
29class MediaBuffer;
30class MediaSource;
31class MetaData;
32
Andreas Huber996dddf2010-01-25 15:30:31 -080033class MPEG4Writer : public MediaWriter {
Andreas Hubere46b7be2009-07-14 16:56:47 -070034public:
35 MPEG4Writer(const char *filename);
Andreas Huberea6a38c2009-11-16 15:43:38 -080036 MPEG4Writer(int fd);
Andreas Hubere46b7be2009-07-14 16:56:47 -070037
Andreas Huber996dddf2010-01-25 15:30:31 -080038 virtual status_t addSource(const sp<MediaSource> &source);
James Dong6feaa462010-06-20 08:20:54 -070039 virtual status_t start(MetaData *param = NULL);
James Dongd0366622010-08-18 19:10:39 -070040 virtual status_t stop();
41 virtual status_t pause();
Andreas Huber996dddf2010-01-25 15:30:31 -080042 virtual bool reachedEOS();
James Dong3f51fa72010-08-18 03:32:26 -070043 virtual status_t dump(int fd, const Vector<String16>& args);
Andreas Hubere46b7be2009-07-14 16:56:47 -070044
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();
James Dong3300e962010-04-21 16:14:15 -070054 uint32_t interleaveDuration() const { return mInterleaveDurationUs; }
55 status_t setInterleaveDuration(uint32_t duration);
James Dong52d13f02010-07-02 11:39:06 -070056 int32_t getTimeScale() const { return mTimeScale; }
Andreas Hubere46b7be2009-07-14 16:56:47 -070057
Andreas Huberbe06d262009-08-14 14:37:10 -070058protected:
59 virtual ~MPEG4Writer();
60
Andreas Hubere46b7be2009-07-14 16:56:47 -070061private:
62 class Track;
63
James Dongb1262a82010-11-16 14:04:54 -080064 int mFd;
James Dong2747e0e2010-11-18 20:59:13 -080065 status_t mInitCheck;
James Dong7755cdd2010-09-02 10:49:55 -070066 bool mUse4ByteNalLength;
James Dong39a0b212010-06-23 00:18:40 -070067 bool mUse32BitOffset;
James Dong6a9e39a2010-10-04 16:41:53 -070068 bool mIsFileSizeLimitExplicitlyRequested;
James Dong08c74732010-06-10 12:28:15 -070069 bool mPaused;
70 bool mStarted;
James Dongb1262a82010-11-16 14:04:54 -080071 off64_t mOffset;
Andreas Hubere46b7be2009-07-14 16:56:47 -070072 off_t mMdatOffset;
James Dongb5e74232010-05-07 10:26:24 -070073 uint8_t *mMoovBoxBuffer;
James Dongb1262a82010-11-16 14:04:54 -080074 off64_t mMoovBoxBufferOffset;
James Dongb5e74232010-05-07 10:26:24 -070075 bool mWriteMoovBoxToMemory;
James Dongb1262a82010-11-16 14:04:54 -080076 off64_t mFreeBoxOffset;
James Dongb5e74232010-05-07 10:26:24 -070077 bool mStreamableFile;
James Dongb1262a82010-11-16 14:04:54 -080078 off64_t mEstimatedMoovBoxSize;
James Dong3300e962010-04-21 16:14:15 -070079 uint32_t mInterleaveDurationUs;
James Dong52d13f02010-07-02 11:39:06 -070080 int32_t mTimeScale;
James Dong9db798d2010-05-13 11:47:36 -070081 int64_t mStartTimestampUs;
James Dongda8073c2010-07-30 17:41:22 -070082
Andreas Hubere46b7be2009-07-14 16:56:47 -070083 Mutex mLock;
84
85 List<Track *> mTracks;
86
James Dongb1262a82010-11-16 14:04:54 -080087 List<off64_t> mBoxes;
Andreas Hubere46b7be2009-07-14 16:56:47 -070088
James Dong36e573b2010-06-19 09:04:18 -070089 void setStartTimestampUs(int64_t timeUs);
90 int64_t getStartTimestampUs(); // Not const
James Dong09936ed2010-06-24 19:04:27 -070091 status_t startTracks(MetaData *params);
James Dongb54a91782010-06-22 11:27:37 -070092 size_t numTracks();
James Dong6feaa462010-06-20 08:20:54 -070093 int64_t estimateMoovBoxSize(int32_t bitRate);
James Dong9db798d2010-05-13 11:47:36 -070094
James Dongda8073c2010-07-30 17:41:22 -070095 struct Chunk {
96 Track *mTrack; // Owner
97 int64_t mTimeStampUs; // Timestamp of the 1st sample
98 List<MediaBuffer *> mSamples; // Sample data
99
100 // Convenient constructor
James Dongf6a2bff2011-02-09 14:00:55 -0800101 Chunk(): mTrack(NULL), mTimeStampUs(0) {}
102
James Dongda8073c2010-07-30 17:41:22 -0700103 Chunk(Track *track, int64_t timeUs, List<MediaBuffer *> samples)
104 : mTrack(track), mTimeStampUs(timeUs), mSamples(samples) {
105 }
106
107 };
108 struct ChunkInfo {
109 Track *mTrack; // Owner
110 List<Chunk> mChunks; // Remaining chunks to be written
James Dong3aea0372011-05-06 12:19:04 -0700111
112 // Previous chunk timestamp that has been written
113 int64_t mPrevChunkTimestampUs;
114
115 // Max time interval between neighboring chunks
116 int64_t mMaxInterChunkDurUs;
117
James Dongda8073c2010-07-30 17:41:22 -0700118 };
119
120 bool mIsFirstChunk;
121 volatile bool mDone; // Writer thread is done?
122 pthread_t mThread; // Thread id for the writer
123 List<ChunkInfo> mChunkInfos; // Chunk infos
124 Condition mChunkReadyCondition; // Signal that chunks are available
125
126 // Writer thread handling
127 status_t startWriterThread();
128 void stopWriterThread();
129 static void *ThreadWrapper(void *me);
130 void threadFunc();
131
132 // Buffer a single chunk to be written out later.
133 void bufferChunk(const Chunk& chunk);
134
135 // Write all buffered chunks from all tracks
James Dongf6a2bff2011-02-09 14:00:55 -0800136 void writeAllChunks();
James Dongda8073c2010-07-30 17:41:22 -0700137
James Dongf6a2bff2011-02-09 14:00:55 -0800138 // Retrieve the proper chunk to write if there is one
139 // Return true if a chunk is found; otherwise, return false.
140 bool findChunkToWrite(Chunk *chunk);
James Dongda8073c2010-07-30 17:41:22 -0700141
James Dongf6a2bff2011-02-09 14:00:55 -0800142 // Actually write the given chunk to the file.
143 void writeChunkToFile(Chunk* chunk);
James Dongda8073c2010-07-30 17:41:22 -0700144
James Dongb7208192010-08-02 19:13:40 -0700145 // Adjust other track media clock (presumably wall clock)
146 // based on audio track media clock with the drift time.
147 int64_t mDriftTimeUs;
James Dong4c238152010-09-01 18:48:35 -0700148 void setDriftTimeUs(int64_t driftTimeUs);
James Dongb7208192010-08-02 19:13:40 -0700149 int64_t getDriftTimeUs();
150
James Dong7755cdd2010-09-02 10:49:55 -0700151 // Return whether the nal length is 4 bytes or 2 bytes
152 // Only makes sense for H.264/AVC
153 bool useNalLengthFour();
154
James Dong3300e962010-04-21 16:14:15 -0700155 void lock();
156 void unlock();
157
158 // Acquire lock before calling these methods
James Dongb1262a82010-11-16 14:04:54 -0800159 off64_t addSample_l(MediaBuffer *buffer);
160 off64_t addLengthPrefixedSample_l(MediaBuffer *buffer);
Andreas Hubere46b7be2009-07-14 16:56:47 -0700161
James Dong2747e0e2010-11-18 20:59:13 -0800162 inline size_t write(const void *ptr, size_t size, size_t nmemb);
James Dong18244862010-05-11 14:57:02 -0700163 bool exceedsFileSizeLimit();
James Dongcb7e65c2010-09-02 11:19:11 -0700164 bool use32BitFileOffset() const;
James Dong18244862010-05-11 14:57:02 -0700165 bool exceedsFileDurationLimit();
James Dong22b37fa2010-10-19 21:28:47 -0700166 bool isFileStreamable() const;
James Dong7fc8b4f2011-03-18 11:25:41 -0700167 void trackProgressStatus(size_t trackId, int64_t timeUs, status_t err = OK);
James Dongb9d7e012010-11-09 11:15:47 -0800168 void writeCompositionMatrix(int32_t degrees);
James Dong7a6cea42011-05-06 16:55:39 -0700169 void writeMvhdBox(int64_t durationUs);
170 void writeMoovBox(int64_t durationUs);
James Dong78fed1712011-05-09 11:36:53 -0700171 void writeFtypBox(const MetaData *param);
James Dong3aea0372011-05-06 12:19:04 -0700172 void sendSessionSummary();
James Dongb5e74232010-05-07 10:26:24 -0700173
Andreas Hubere46b7be2009-07-14 16:56:47 -0700174 MPEG4Writer(const MPEG4Writer &);
175 MPEG4Writer &operator=(const MPEG4Writer &);
176};
177
178} // namespace android
179
180#endif // MPEG4_WRITER_H_