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

Commit 7ab4b9ac authored by Gopalakrishnan Nallasamy's avatar Gopalakrishnan Nallasamy
Browse files

MediaMuxer:Unblock writeSampleData,gate pushBuffer

As MediaMuxer's writeSampleData handles inputs from multiple tracks,
limited the scope of mMuxerLock to an inner block so that the
current track's buffer does not wait until the completion
of processing of previous buffer of the same or another track.
It's the responsibility of individual track - MediaAdapter object
to gate its buffers.  When interleaving is enabled and data
is written in chunks, the delay was very much noticeable.
For example, when video buffers were getting written to the file,
no new audio buffer was queued to it's thread.

This change has decreased the time required
to complete muxing data from multiple tracks by as much as 35%.

Bug: 157373376

Test: atest android.media.cts.MediaMuxerTest \
      android.mediav2.cts.MuxerTest \
      android.mediav2.cts.MuxerUnitTest
Change-Id: If02f60441292afcf29d01939b09a80bbba43e6b6
parent e5c44c76
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -114,6 +114,13 @@ status_t MediaAdapter::pushBuffer(MediaBuffer *buffer) {
        return -EINVAL;
    }

    /* As mAdapterLock is unlocked while waiting for signalBufferReturned,
     * a new buffer for the same track could be pushed from another thread
     * in the client process, mBufferGatingMutex will help to hold that
     * until the previous buffer is processed.
     */
    std::unique_lock<std::mutex> lk(mBufferGatingMutex);

    Mutex::Autolock autoLock(mAdapterLock);
    if (!mStarted) {
        ALOGE("pushBuffer called before start");
+17 −10
Original line number Diff line number Diff line
@@ -175,13 +175,19 @@ status_t MediaMuxer::stop() {

status_t MediaMuxer::writeSampleData(const sp<ABuffer> &buffer, size_t trackIndex,
                                     int64_t timeUs, uint32_t flags) {
    Mutex::Autolock autoLock(mMuxerLock);

    if (buffer.get() == NULL) {
        ALOGE("WriteSampleData() get an NULL buffer.");
        return -EINVAL;
    }

    {
        /* As MediaMuxer's writeSampleData handles inputs from multiple tracks,
         * limited the scope of mMuxerLock to this inner block so that the
         * current track's buffer does not wait until the completion
         * of processing of previous buffer of the same or another track.
         * It's the responsibility of individual track - MediaAdapter object
         * to gate its buffers.
         */
        Mutex::Autolock autoLock(mMuxerLock);
        if (mState != STARTED) {
            ALOGE("WriteSampleData() is called in invalid state %d", mState);
            return INVALID_OPERATION;
@@ -191,6 +197,7 @@ status_t MediaMuxer::writeSampleData(const sp<ABuffer> &buffer, size_t trackInde
            ALOGE("WriteSampleData() get an invalid index %zu", trackIndex);
            return -EINVAL;
        }
    }

    MediaBuffer* mediaBuffer = new MediaBuffer(buffer);

+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ public:

private:
    Mutex mAdapterLock;
    std::mutex mBufferGatingMutex;
    // Make sure the read() wait for the incoming buffer.
    Condition mBufferReadCond;
    // Make sure the pushBuffer() wait for the current buffer consumed.