Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2475cf40 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "MPEG4Writer:64bit offset + fallocate"

parents 2b15f76d 28d4d67a
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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);
        }
+305 −173

File changed.

Preview size limit exceeded, changes collapsed.

+38 −3
Original line number Diff line number Diff line
@@ -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) {
@@ -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.
@@ -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;
@@ -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
+31 −4
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <utils/threads.h>
#include <media/stagefright/foundation/AHandlerReflector.h>
#include <media/stagefright/foundation/ALooper.h>
#include <mutex>

namespace android {

@@ -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);
@@ -80,6 +85,8 @@ private:

    enum {
        kWhatSwitch                          = 'swch',
        kWhatHandleIOError                   = 'ioer',
        kWhatHandleFallocateError            = 'faer'
    };

    int  mFd;
@@ -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;
@@ -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;

@@ -200,6 +215,7 @@ private:
    } ItemProperty;

    bool mHasFileLevelMeta;
    uint64_t mFileLevelMetaDataSize;
    bool mHasMoovBox;
    uint32_t mPrimaryItemId;
    uint32_t mAssociationEntryCount;
@@ -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);
@@ -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;
@@ -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);
+5 −2
Original line number Diff line number Diff line
@@ -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