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

Commit 00f41327 authored by Andreas Huber's avatar Andreas Huber
Browse files

Throttle SurfaceMediaSource.

Change-Id: I214ce60f8d94df9c07041577e34ed1ad5e199fdb
parent bdde5f88
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -167,6 +167,8 @@ private:
    // this list in signalBufferReturned
    Vector<sp<GraphicBuffer> > mCurrentBuffers;

    size_t mNumPendingBuffers;

    // mCurrentTimestamp is the timestamp for the current texture. It
    // gets set to mLastQueuedTimestamp each time updateTexImage is called.
    int64_t mCurrentTimestamp;
@@ -202,10 +204,14 @@ private:
    // offset timestamps.
    int64_t mStartTimeNs;

    size_t mMaxAcquiredBufferCount;

    // mFrameAvailableCondition condition used to indicate whether there
    // is a frame available for dequeuing
    Condition mFrameAvailableCondition;

    Condition mMediaBuffersAvailableCondition;

    // Avoid copying and equating and default constructor
    DISALLOW_IMPLICIT_CONSTRUCTORS(SurfaceMediaSource);
};
+33 −12
Original line number Diff line number Diff line
@@ -18,8 +18,8 @@

#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/SurfaceMediaSource.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <OMX_IVCommon.h>
#include <MetadataBufferType.h>

@@ -39,12 +39,14 @@ SurfaceMediaSource::SurfaceMediaSource(uint32_t bufferWidth, uint32_t bufferHeig
    mWidth(bufferWidth),
    mHeight(bufferHeight),
    mCurrentSlot(BufferQueue::INVALID_BUFFER_SLOT),
    mNumPendingBuffers(0),
    mCurrentTimestamp(0),
    mFrameRate(30),
    mStopped(false),
    mNumFramesReceived(0),
    mNumFramesEncoded(0),
    mFirstFrameTimestamp(0)
    mFirstFrameTimestamp(0),
    mMaxAcquiredBufferCount(4)  // XXX double-check the default
{
    ALOGV("SurfaceMediaSource");

@@ -155,20 +157,32 @@ status_t SurfaceMediaSource::start(MetaData *params)
            ALOGE("bufferCount %d is too small", bufferCount);
            return BAD_VALUE;
        }

        mMaxAcquiredBufferCount = bufferCount;
    }

    if (bufferCount != 0) {
        status_t err = mBufferQueue->setMaxAcquiredBufferCount(bufferCount);
    CHECK_GT(mMaxAcquiredBufferCount, 1);

    status_t err =
        mBufferQueue->setMaxAcquiredBufferCount(mMaxAcquiredBufferCount);

    if (err != OK) {
        return err;
    }
    }

    mNumPendingBuffers = 0;

    return OK;
}

status_t SurfaceMediaSource::setMaxAcquiredBufferCount(size_t count) {
    return mBufferQueue->setMaxAcquiredBufferCount(count);
    ALOGV("setMaxAcquiredBufferCount(%d)", count);
    Mutex::Autolock lock(mMutex);

    CHECK_GT(count, 1);
    mMaxAcquiredBufferCount = count;

    return OK;
}


@@ -216,9 +230,8 @@ sp<MetaData> SurfaceMediaSource::getFormat()
// Note: Call only when you have the lock
static void passMetadataBuffer(MediaBuffer **buffer,
        buffer_handle_t bufferHandle) {
    // MediaBuffer allocates and owns this data
    MediaBuffer *tempBuffer = new MediaBuffer(4 + sizeof(buffer_handle_t));
    char *data = (char *)tempBuffer->data();
    *buffer = new MediaBuffer(4 + sizeof(buffer_handle_t));
    char *data = (char *)(*buffer)->data();
    if (data == NULL) {
        ALOGE("Cannot allocate memory for metadata buffer!");
        return;
@@ -226,7 +239,6 @@ static void passMetadataBuffer(MediaBuffer **buffer,
    OMX_U32 type = kMetadataBufferTypeGrallocSource;
    memcpy(data, &type, 4);
    memcpy(data + 4, &bufferHandle, sizeof(buffer_handle_t));
    *buffer = tempBuffer;

    ALOGV("handle = %p, , offset = %d, length = %d",
            bufferHandle, (*buffer)->range_length(), (*buffer)->range_offset());
@@ -240,6 +252,10 @@ status_t SurfaceMediaSource::read( MediaBuffer **buffer,

    *buffer = NULL;

    while (!mStopped && mNumPendingBuffers == mMaxAcquiredBufferCount) {
        mMediaBuffersAvailableCondition.wait(mMutex);
    }

    // Update the current buffer info
    // TODO: mCurrentSlot can be made a bufferstate since there
    // can be more than one "current" slots.
@@ -306,6 +322,7 @@ status_t SurfaceMediaSource::read( MediaBuffer **buffer,

    mNumFramesEncoded++;
    // Pass the data to the MediaBuffer. Pass in only the metadata

    passMetadataBuffer(buffer, mBufferSlot[mCurrentSlot]->handle);

    (*buffer)->setObserver(this);
@@ -315,6 +332,7 @@ status_t SurfaceMediaSource::read( MediaBuffer **buffer,
            mNumFramesEncoded, mCurrentTimestamp / 1000,
            mCurrentTimestamp / 1000 - prevTimeStamp / 1000);

    ++mNumPendingBuffers;

    return OK;
}
@@ -371,6 +389,9 @@ void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
    if (!foundBuffer) {
        CHECK(!"signalBufferReturned: bogus buffer");
    }

    --mNumPendingBuffers;
    mMediaBuffersAvailableCondition.broadcast();
}

// Part of the BufferQueue::ConsumerListener