MPEG4Writer.h revision 07b1bb529a1ae76c46a71b01338c166f9490629d
14be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi/* 24be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * Copyright (C) 2009 The Android Open Source Project 34be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * 44be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * Licensed under the Apache License, Version 2.0 (the "License"); 54be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * you may not use this file except in compliance with the License. 64be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * You may obtain a copy of the License at 74be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * 84be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * http://www.apache.org/licenses/LICENSE-2.0 94be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * 104be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * Unless required by applicable law or agreed to in writing, software 114be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * distributed under the License is distributed on an "AS IS" BASIS, 124be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * See the License for the specific language governing permissions and 144be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi * limitations under the License. 154be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi */ 164be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 174be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#ifndef MPEG4_WRITER_H_ 184be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 194be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#define MPEG4_WRITER_H_ 204be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 214be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#include <stdio.h> 224be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 234be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#include <media/stagefright/MediaWriter.h> 244be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#include <utils/List.h> 254be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#include <utils/threads.h> 264be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 274be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivinamespace android { 284be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 294be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Triviclass MediaBuffer; 304be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Triviclass MediaSource; 314be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Triviclass MetaData; 324be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 334be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Triviclass MPEG4Writer : public MediaWriter { 344be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivipublic: 354be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi MPEG4Writer(const char *filename); 364be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi MPEG4Writer(int fd); 374be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 384be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi virtual status_t addSource(const sp<MediaSource> &source); 394be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi virtual status_t start(MetaData *param = NULL); 404be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi virtual status_t stop(); 414be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi virtual status_t pause(); 424be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi virtual bool reachedEOS(); 434be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi virtual status_t dump(int fd, const Vector<String16>& args); 444be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 454be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void beginBox(const char *fourcc); 464be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeInt8(int8_t x); 474be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeInt16(int16_t x); 484be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeInt32(int32_t x); 494be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeInt64(int64_t x); 504be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeCString(const char *s); 514be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeFourcc(const char *fourcc); 524be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void write(const void *data, size_t size); 534be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void endBox(); 544be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi uint32_t interleaveDuration() const { return mInterleaveDurationUs; } 554be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi status_t setInterleaveDuration(uint32_t duration); 564be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int32_t getTimeScale() const { return mTimeScale; } 574be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 584be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi status_t setGeoData(int latitudex10000, int longitudex10000); 594be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 604be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Triviprotected: 614be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi virtual ~MPEG4Writer(); 624be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 634be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Triviprivate: 64b3b757daa7d162b6f66590d917c1f84f3ba73c70Eric Laurent class Track; 65b3b757daa7d162b6f66590d917c1f84f3ba73c70Eric Laurent 66b3b757daa7d162b6f66590d917c1f84f3ba73c70Eric Laurent int mFd; 67b3b757daa7d162b6f66590d917c1f84f3ba73c70Eric Laurent status_t mInitCheck; 68b3b757daa7d162b6f66590d917c1f84f3ba73c70Eric Laurent bool mUse4ByteNalLength; 694be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool mUse32BitOffset; 704be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool mIsFileSizeLimitExplicitlyRequested; 714be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool mPaused; 724be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool mStarted; 734be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi off64_t mOffset; 744be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi off_t mMdatOffset; 754be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi uint8_t *mMoovBoxBuffer; 764be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi off64_t mMoovBoxBufferOffset; 774be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool mWriteMoovBoxToMemory; 784be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi off64_t mFreeBoxOffset; 794be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool mStreamableFile; 804be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi off64_t mEstimatedMoovBoxSize; 814be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi uint32_t mInterleaveDurationUs; 824be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int32_t mTimeScale; 834be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int64_t mStartTimestampUs; 844be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int mLatitudex10000; 854be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int mLongitudex10000; 864be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool mAreGeoTagsAvailable; 874be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 884be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi Mutex mLock; 894be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 904be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi List<Track *> mTracks; 914be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 924be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi List<off64_t> mBoxes; 934be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 944be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void setStartTimestampUs(int64_t timeUs); 954be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int64_t getStartTimestampUs(); // Not const 964be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi status_t startTracks(MetaData *params); 974be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi size_t numTracks(); 984be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int64_t estimateMoovBoxSize(int32_t bitRate); 994be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1004be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi struct Chunk { 1014be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi Track *mTrack; // Owner 1024be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int64_t mTimeStampUs; // Timestamp of the 1st sample 1034be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi List<MediaBuffer *> mSamples; // Sample data 1044be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1054be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Convenient constructor 1064be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi Chunk(): mTrack(NULL), mTimeStampUs(0) {} 1074be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1084be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi Chunk(Track *track, int64_t timeUs, List<MediaBuffer *> samples) 1094be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi : mTrack(track), mTimeStampUs(timeUs), mSamples(samples) { 1104be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi } 1114be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1124be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi }; 1134be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi struct ChunkInfo { 1144be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi Track *mTrack; // Owner 1154be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi List<Chunk> mChunks; // Remaining chunks to be written 1164be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1174be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Previous chunk timestamp that has been written 1184be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int64_t mPrevChunkTimestampUs; 1194be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1204be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Max time interval between neighboring chunks 1214be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int64_t mMaxInterChunkDurUs; 1224be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1234be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi }; 1244be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1254be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool mIsFirstChunk; 1264be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi volatile bool mDone; // Writer thread is done? 1274be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi pthread_t mThread; // Thread id for the writer 1284be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi List<ChunkInfo> mChunkInfos; // Chunk infos 1294be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi Condition mChunkReadyCondition; // Signal that chunks are available 1304be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1314be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Writer thread handling 1324be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi status_t startWriterThread(); 1334be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void stopWriterThread(); 1344be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi static void *ThreadWrapper(void *me); 1354be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void threadFunc(); 1364be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1374be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Buffer a single chunk to be written out later. 1384be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void bufferChunk(const Chunk& chunk); 1394be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1404be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Write all buffered chunks from all tracks 1414be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeAllChunks(); 1424be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1434be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Retrieve the proper chunk to write if there is one 1444be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Return true if a chunk is found; otherwise, return false. 1454be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool findChunkToWrite(Chunk *chunk); 1464be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1474be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Actually write the given chunk to the file. 1484be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeChunkToFile(Chunk* chunk); 1494be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1504be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Adjust other track media clock (presumably wall clock) 1514be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // based on audio track media clock with the drift time. 1524be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int64_t mDriftTimeUs; 1534be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void setDriftTimeUs(int64_t driftTimeUs); 1544be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi int64_t getDriftTimeUs(); 1554be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 156b3b757daa7d162b6f66590d917c1f84f3ba73c70Eric Laurent // Return whether the nal length is 4 bytes or 2 bytes 1574be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Only makes sense for H.264/AVC 1584be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool useNalLengthFour(); 1594be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1604be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void lock(); 161b3b757daa7d162b6f66590d917c1f84f3ba73c70Eric Laurent void unlock(); 1624be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1634be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi // Acquire lock before calling these methods 1644be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi off64_t addSample_l(MediaBuffer *buffer); 1654be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi off64_t addLengthPrefixedSample_l(MediaBuffer *buffer); 1664be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1674be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi inline size_t write(const void *ptr, size_t size, size_t nmemb); 1684be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool exceedsFileSizeLimit(); 1694be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool use32BitFileOffset() const; 1704be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi bool exceedsFileDurationLimit(); 171b3b757daa7d162b6f66590d917c1f84f3ba73c70Eric Laurent bool isFileStreamable() const; 1724be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void trackProgressStatus(size_t trackId, int64_t timeUs, status_t err = OK); 1734be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeCompositionMatrix(int32_t degrees); 1744be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeMvhdBox(int64_t durationUs); 1754be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeMoovBox(int64_t durationUs); 1764be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeFtypBox(const MetaData *param); 1774be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeUdtaBox(); 1784be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeGeoDataBox(); 1794be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeLatitude(int degreex10000); 1804be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void writeLongitude(int degreex10000); 1814be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi void sendSessionSummary(); 1824be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1834be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi MPEG4Writer(const MPEG4Writer &); 1844be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi MPEG4Writer &operator=(const MPEG4Writer &); 1854be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi}; 1864be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1874be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi} // namespace android 1884be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi 1894be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi#endif // MPEG4_WRITER_H_ 1904be7fe875758b42939719a1082ae9e6dbf37a1d7Jean-Michel Trivi