Loading media/libmediaplayerservice/StagefrightRecorder.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -2002,7 +2002,6 @@ void StagefrightRecorder::setupMPEG4orWEBMMetaData(sp<MetaData> *meta) { (*meta)->setInt32(kKeyTimeScale, mMovieTimeScale); } if (mOutputFormat != OUTPUT_FORMAT_WEBM) { (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset); if (mTrackEveryTimeDurationUs > 0) { (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs); } Loading media/libstagefright/MPEG4Writer.cpp +305 −173 File changed.Preview size limit exceeded, changes collapsed. Show changes media/libstagefright/MediaMuxer.cpp +38 −3 Original line number Diff line number Diff line Loading @@ -48,7 +48,8 @@ static bool isMp4Format(MediaMuxer::OutputFormat format) { MediaMuxer::MediaMuxer(int fd, OutputFormat format) : mFormat(format), mState(UNINITIALIZED) { mState(UNINITIALIZED), mError(OK) { if (isMp4Format(format)) { mWriter = new MPEG4Writer(fd); } else if (format == OUTPUT_FORMAT_WEBM) { Loading @@ -58,6 +59,7 @@ MediaMuxer::MediaMuxer(int fd, OutputFormat format) } if (mWriter != NULL) { mWriter->setMuxerListener(this); mFileMeta = new MetaData; if (format == OUTPUT_FORMAT_HEIF) { // Note that the key uses recorder file types. Loading Loading @@ -156,14 +158,22 @@ status_t MediaMuxer::start() { status_t MediaMuxer::stop() { Mutex::Autolock autoLock(mMuxerLock); if (mState == STARTED) { if (mState == STARTED || mState == ERROR) { mState = STOPPED; for (size_t i = 0; i < mTrackList.size(); i++) { if (mTrackList[i]->stop() != OK) { return INVALID_OPERATION; } } return mWriter->stop(); status_t err = mWriter->stop(); if (err != OK || mError != OK) { ALOGE("stop err: %d, mError:%d", err, mError); } // Prioritize mError over err. if (mError != OK) { err = mError; } return err; } else { ALOGE("stop() is called in invalid state %d", mState); return INVALID_OPERATION; Loading Loading @@ -212,4 +222,29 @@ status_t MediaMuxer::writeSampleData(const sp<ABuffer> &buffer, size_t trackInde return currentTrack->pushBuffer(mediaBuffer); } void MediaMuxer::notify(int msg, int ext1, int ext2) { switch (msg) { case MEDIA_RECORDER_EVENT_ERROR: case MEDIA_RECORDER_TRACK_EVENT_ERROR: { Mutex::Autolock autoLock(mMuxerLock); mState = ERROR; mError = ext2; ALOGW("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); break; } case MEDIA_RECORDER_EVENT_INFO: { if (ext1 == MEDIA_RECORDER_INFO_UNKNOWN) { Mutex::Autolock autoLock(mMuxerLock); mState = ERROR; mError = ext2; ALOGW("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); } break; } default: // Ignore INFO and other notifications for now. break; } } } // namespace android media/libstagefright/include/media/stagefright/MPEG4Writer.h +31 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <utils/threads.h> #include <media/stagefright/foundation/AHandlerReflector.h> #include <media/stagefright/foundation/ALooper.h> #include <mutex> namespace android { Loading Loading @@ -58,6 +59,10 @@ public: void writeFourcc(const char *fourcc); void write(const void *data, size_t size); inline size_t write(const void *ptr, size_t size, size_t nmemb); // Write to file system by calling ::write() or post error message to looper on failure. void writeOrPostError(int fd, const void *buf, size_t count); // Seek in the file by calling ::lseek64() or post error message to looper on failure. void seekOrPostError(int fd, off64_t offset, int whence); void endBox(); uint32_t interleaveDuration() const { return mInterleaveDurationUs; } status_t setInterleaveDuration(uint32_t duration); Loading @@ -80,6 +85,8 @@ private: enum { kWhatSwitch = 'swch', kWhatHandleIOError = 'ioer', kWhatHandleFallocateError = 'faer' }; int mFd; Loading @@ -88,14 +95,15 @@ private: status_t mInitCheck; bool mIsRealTimeRecording; bool mUse4ByteNalLength; bool mUse32BitOffset; bool mIsFileSizeLimitExplicitlyRequested; bool mPaused; bool mStarted; // Writer thread + track threads started successfully bool mWriterThreadStarted; // Only writer thread started successfully bool mSendNotify; off64_t mOffset; off_t mMdatOffset; off64_t mPreAllocateFileEndOffset; //End of file offset during preallocation. off64_t mMdatOffset; off64_t mMdatEndOffset; // End offset of mdat atom. uint8_t *mInMemoryCache; off64_t mInMemoryCacheOffset; off64_t mInMemoryCacheSize; Loading @@ -112,11 +120,18 @@ private: bool mAreGeoTagsAvailable; int32_t mStartTimeOffsetMs; bool mSwitchPending; bool mWriteSeekErr; bool mFallocateErr; bool mPreAllocationEnabled; sp<ALooper> mLooper; sp<AHandlerReflector<MPEG4Writer> > mReflector; Mutex mLock; std::mutex mResetMutex; std::mutex mFallocMutex; bool mPreAllocFirstTime; // Pre-allocate space for file and track headers only once per file. uint64_t mPrevAllTracksTotalMetaDataSizeEstimate; List<Track *> mTracks; Loading Loading @@ -200,6 +215,7 @@ private: } ItemProperty; bool mHasFileLevelMeta; uint64_t mFileLevelMetaDataSize; bool mHasMoovBox; uint32_t mPrimaryItemId; uint32_t mAssociationEntryCount; Loading @@ -210,9 +226,11 @@ private: // Writer thread handling status_t startWriterThread(); void stopWriterThread(); status_t stopWriterThread(); static void *ThreadWrapper(void *me); void threadFunc(); void setupAndStartLooper(); void stopAndReleaseLooper(); // Buffer a single chunk to be written out later. void bufferChunk(const Chunk& chunk); Loading Loading @@ -263,7 +281,6 @@ private: void addRefs_l(uint16_t itemId, const ItemRefs &); bool exceedsFileSizeLimit(); bool use32BitFileOffset() const; bool exceedsFileDurationLimit(); bool approachingFileSizeLimit(); bool isFileStreamable() const; Loading @@ -284,6 +301,16 @@ private: void writeIlst(); void writeMoovLevelMetaBox(); /* * Allocate space needed for MOOV atom in advance and maintain just enough before write * of any data. Stop writing and save MOOV atom if there was any error. */ bool preAllocate(uint64_t wantSize); /* * Truncate file as per the size used for meta data and actual data in a session. */ bool truncatePreAllocation(); // HEIF writing void writeIlocBox(); void writeInfeBox(uint16_t itemId, const char *type, uint32_t flags); Loading media/libstagefright/include/media/stagefright/MediaMuxer.h +5 −2 Original line number Diff line number Diff line Loading @@ -117,21 +117,24 @@ public: status_t writeSampleData(const sp<ABuffer> &buffer, size_t trackIndex, int64_t timeUs, uint32_t flags) ; void notify(int msg, int ext1, int ext2); private: const OutputFormat mFormat; sp<MediaWriter> mWriter; Vector< sp<MediaAdapter> > mTrackList; // Each track has its MediaAdapter. sp<MetaData> mFileMeta; // Metadata for the whole file. Mutex mMuxerLock; enum State { UNINITIALIZED, INITIALIZED, STARTED, STOPPED STOPPED, ERROR }; State mState; status_t mError; DISALLOW_EVIL_CONSTRUCTORS(MediaMuxer); }; Loading Loading
media/libmediaplayerservice/StagefrightRecorder.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -2002,7 +2002,6 @@ void StagefrightRecorder::setupMPEG4orWEBMMetaData(sp<MetaData> *meta) { (*meta)->setInt32(kKeyTimeScale, mMovieTimeScale); } if (mOutputFormat != OUTPUT_FORMAT_WEBM) { (*meta)->setInt32(kKey64BitFileOffset, mUse64BitFileOffset); if (mTrackEveryTimeDurationUs > 0) { (*meta)->setInt64(kKeyTrackTimeStatus, mTrackEveryTimeDurationUs); } Loading
media/libstagefright/MPEG4Writer.cpp +305 −173 File changed.Preview size limit exceeded, changes collapsed. Show changes
media/libstagefright/MediaMuxer.cpp +38 −3 Original line number Diff line number Diff line Loading @@ -48,7 +48,8 @@ static bool isMp4Format(MediaMuxer::OutputFormat format) { MediaMuxer::MediaMuxer(int fd, OutputFormat format) : mFormat(format), mState(UNINITIALIZED) { mState(UNINITIALIZED), mError(OK) { if (isMp4Format(format)) { mWriter = new MPEG4Writer(fd); } else if (format == OUTPUT_FORMAT_WEBM) { Loading @@ -58,6 +59,7 @@ MediaMuxer::MediaMuxer(int fd, OutputFormat format) } if (mWriter != NULL) { mWriter->setMuxerListener(this); mFileMeta = new MetaData; if (format == OUTPUT_FORMAT_HEIF) { // Note that the key uses recorder file types. Loading Loading @@ -156,14 +158,22 @@ status_t MediaMuxer::start() { status_t MediaMuxer::stop() { Mutex::Autolock autoLock(mMuxerLock); if (mState == STARTED) { if (mState == STARTED || mState == ERROR) { mState = STOPPED; for (size_t i = 0; i < mTrackList.size(); i++) { if (mTrackList[i]->stop() != OK) { return INVALID_OPERATION; } } return mWriter->stop(); status_t err = mWriter->stop(); if (err != OK || mError != OK) { ALOGE("stop err: %d, mError:%d", err, mError); } // Prioritize mError over err. if (mError != OK) { err = mError; } return err; } else { ALOGE("stop() is called in invalid state %d", mState); return INVALID_OPERATION; Loading Loading @@ -212,4 +222,29 @@ status_t MediaMuxer::writeSampleData(const sp<ABuffer> &buffer, size_t trackInde return currentTrack->pushBuffer(mediaBuffer); } void MediaMuxer::notify(int msg, int ext1, int ext2) { switch (msg) { case MEDIA_RECORDER_EVENT_ERROR: case MEDIA_RECORDER_TRACK_EVENT_ERROR: { Mutex::Autolock autoLock(mMuxerLock); mState = ERROR; mError = ext2; ALOGW("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); break; } case MEDIA_RECORDER_EVENT_INFO: { if (ext1 == MEDIA_RECORDER_INFO_UNKNOWN) { Mutex::Autolock autoLock(mMuxerLock); mState = ERROR; mError = ext2; ALOGW("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2); } break; } default: // Ignore INFO and other notifications for now. break; } } } // namespace android
media/libstagefright/include/media/stagefright/MPEG4Writer.h +31 −4 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ #include <utils/threads.h> #include <media/stagefright/foundation/AHandlerReflector.h> #include <media/stagefright/foundation/ALooper.h> #include <mutex> namespace android { Loading Loading @@ -58,6 +59,10 @@ public: void writeFourcc(const char *fourcc); void write(const void *data, size_t size); inline size_t write(const void *ptr, size_t size, size_t nmemb); // Write to file system by calling ::write() or post error message to looper on failure. void writeOrPostError(int fd, const void *buf, size_t count); // Seek in the file by calling ::lseek64() or post error message to looper on failure. void seekOrPostError(int fd, off64_t offset, int whence); void endBox(); uint32_t interleaveDuration() const { return mInterleaveDurationUs; } status_t setInterleaveDuration(uint32_t duration); Loading @@ -80,6 +85,8 @@ private: enum { kWhatSwitch = 'swch', kWhatHandleIOError = 'ioer', kWhatHandleFallocateError = 'faer' }; int mFd; Loading @@ -88,14 +95,15 @@ private: status_t mInitCheck; bool mIsRealTimeRecording; bool mUse4ByteNalLength; bool mUse32BitOffset; bool mIsFileSizeLimitExplicitlyRequested; bool mPaused; bool mStarted; // Writer thread + track threads started successfully bool mWriterThreadStarted; // Only writer thread started successfully bool mSendNotify; off64_t mOffset; off_t mMdatOffset; off64_t mPreAllocateFileEndOffset; //End of file offset during preallocation. off64_t mMdatOffset; off64_t mMdatEndOffset; // End offset of mdat atom. uint8_t *mInMemoryCache; off64_t mInMemoryCacheOffset; off64_t mInMemoryCacheSize; Loading @@ -112,11 +120,18 @@ private: bool mAreGeoTagsAvailable; int32_t mStartTimeOffsetMs; bool mSwitchPending; bool mWriteSeekErr; bool mFallocateErr; bool mPreAllocationEnabled; sp<ALooper> mLooper; sp<AHandlerReflector<MPEG4Writer> > mReflector; Mutex mLock; std::mutex mResetMutex; std::mutex mFallocMutex; bool mPreAllocFirstTime; // Pre-allocate space for file and track headers only once per file. uint64_t mPrevAllTracksTotalMetaDataSizeEstimate; List<Track *> mTracks; Loading Loading @@ -200,6 +215,7 @@ private: } ItemProperty; bool mHasFileLevelMeta; uint64_t mFileLevelMetaDataSize; bool mHasMoovBox; uint32_t mPrimaryItemId; uint32_t mAssociationEntryCount; Loading @@ -210,9 +226,11 @@ private: // Writer thread handling status_t startWriterThread(); void stopWriterThread(); status_t stopWriterThread(); static void *ThreadWrapper(void *me); void threadFunc(); void setupAndStartLooper(); void stopAndReleaseLooper(); // Buffer a single chunk to be written out later. void bufferChunk(const Chunk& chunk); Loading Loading @@ -263,7 +281,6 @@ private: void addRefs_l(uint16_t itemId, const ItemRefs &); bool exceedsFileSizeLimit(); bool use32BitFileOffset() const; bool exceedsFileDurationLimit(); bool approachingFileSizeLimit(); bool isFileStreamable() const; Loading @@ -284,6 +301,16 @@ private: void writeIlst(); void writeMoovLevelMetaBox(); /* * Allocate space needed for MOOV atom in advance and maintain just enough before write * of any data. Stop writing and save MOOV atom if there was any error. */ bool preAllocate(uint64_t wantSize); /* * Truncate file as per the size used for meta data and actual data in a session. */ bool truncatePreAllocation(); // HEIF writing void writeIlocBox(); void writeInfeBox(uint16_t itemId, const char *type, uint32_t flags); Loading
media/libstagefright/include/media/stagefright/MediaMuxer.h +5 −2 Original line number Diff line number Diff line Loading @@ -117,21 +117,24 @@ public: status_t writeSampleData(const sp<ABuffer> &buffer, size_t trackIndex, int64_t timeUs, uint32_t flags) ; void notify(int msg, int ext1, int ext2); private: const OutputFormat mFormat; sp<MediaWriter> mWriter; Vector< sp<MediaAdapter> > mTrackList; // Each track has its MediaAdapter. sp<MetaData> mFileMeta; // Metadata for the whole file. Mutex mMuxerLock; enum State { UNINITIALIZED, INITIALIZED, STARTED, STOPPED STOPPED, ERROR }; State mState; status_t mError; DISALLOW_EVIL_CONSTRUCTORS(MediaMuxer); }; Loading