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

Commit b8756d12 authored by Wonsik Kim's avatar Wonsik Kim Committed by Automerger Merge Worker
Browse files

Merge "CCodecBufferChannel: throttle by # of frames in pipeline" into main am:...

Merge "CCodecBufferChannel: throttle by # of frames in pipeline" into main am: 7182832e am: 80c2e94f

Original change: https://android-review.googlesource.com/c/platform/frameworks/av/+/3205741



Change-Id: Ic34dd5729925cf235b1affa8b47f5deeef9e34b5
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents b011133a 80c2e94f
Loading
Loading
Loading
Loading
+53 −24
Original line number Diff line number Diff line
@@ -228,17 +228,23 @@ void CCodecBufferChannel::setComponent(
status_t CCodecBufferChannel::setInputSurface(
        const std::shared_ptr<InputSurfaceWrapper> &surface) {
    ALOGV("[%s] setInputSurface", mName);
    Mutexed<std::shared_ptr<InputSurfaceWrapper>>::Locked inputSurface(mInputSurface);
    *inputSurface = surface;
    return (*inputSurface)->connect(mComponent);
    if (!surface) {
        ALOGE("[%s] setInputSurface: surface must not be null", mName);
        return BAD_VALUE;
    }
    Mutexed<InputSurface>::Locked inputSurface(mInputSurface);
    inputSurface->numProcessingBuffersBalance = 0;
    inputSurface->surface = surface;
    mHasInputSurface = true;
    return inputSurface->surface->connect(mComponent);
}

status_t CCodecBufferChannel::signalEndOfInputStream() {
    Mutexed<std::shared_ptr<InputSurfaceWrapper>>::Locked inputSurface(mInputSurface);
    if ((*inputSurface) == nullptr) {
    Mutexed<InputSurface>::Locked inputSurface(mInputSurface);
    if (inputSurface->surface == nullptr) {
        return INVALID_OPERATION;
    }
    return (*inputSurface)->signalEndOfInputStream();
    return inputSurface->surface->signalEndOfInputStream();
}

status_t CCodecBufferChannel::queueInputBufferInternal(
@@ -1063,20 +1069,37 @@ void CCodecBufferChannel::feedInputBufferIfAvailableInternal() {
    if (mInputMetEos) {
        return;
    }
    {
    int64_t numOutputSlots = 0;
    bool outputFull = [this, &numOutputSlots]() {
        Mutexed<Output>::Locked output(mOutput);
        if (!output->buffers ||
                output->buffers->hasPending() ||
                (!output->bounded && output->buffers->numActiveSlots() >= output->numSlots)) {
            return;
        if (!output->buffers) {
            ALOGV("[%s] feedInputBufferIfAvailableInternal: "
                  "return because output buffers are null", mName);
            return true;
        }
        numOutputSlots = int64_t(output->numSlots);
        if (output->buffers->hasPending() ||
                (!output->bounded && output->buffers->numActiveSlots() >= output->numSlots)) {
            ALOGV("[%s] feedInputBufferIfAvailableInternal: "
                  "return because there are no room for more output buffers", mName);
            return true;
        }
        return false;
    }();
    if (android::media::codec::provider_->input_surface_throttle()) {
        Mutexed<std::shared_ptr<InputSurfaceWrapper>>::Locked inputSurface(mInputSurface);
        if ((*inputSurface) != nullptr) {
            (*inputSurface)->onInputBufferEmptied();
        Mutexed<InputSurface>::Locked inputSurface(mInputSurface);
        if (inputSurface->surface) {
            if (inputSurface->numProcessingBuffersBalance <= numOutputSlots) {
                ++inputSurface->numProcessingBuffersBalance;
                ALOGV("[%s] feedInputBufferIfAvailableInternal: numProcessingBuffersBalance = %lld",
                      mName, static_cast<long long>(inputSurface->numProcessingBuffersBalance));
                inputSurface->surface->onInputBufferEmptied();
            }
        }
    }
    if (outputFull) {
        return;
    }
    size_t numActiveSlots = 0;
    while (!mPipelineWatcher.lock()->pipelineFull()) {
        sp<MediaCodecBuffer> inBuffer;
@@ -1704,7 +1727,7 @@ status_t CCodecBufferChannel::start(
                && (hasCryptoOrDescrambler() || conforming)) {
            input->buffers.reset(new SlotInputBuffers(mName));
        } else if (graphic) {
            if (mInputSurface.lock()->get()) {
            if (mHasInputSurface) {
                input->buffers.reset(new DummyInputBuffers(mName));
            } else if (mMetaMode == MODE_ANW) {
                input->buffers.reset(new GraphicMetadataInputBuffers(mName));
@@ -1987,7 +2010,7 @@ status_t CCodecBufferChannel::start(

status_t CCodecBufferChannel::prepareInitialInputBuffers(
        std::map<size_t, sp<MediaCodecBuffer>> *clientInputBuffers, bool retry) {
    if (mInputSurface.lock()->get()) {
    if (mHasInputSurface) {
        return OK;
    }

@@ -2113,8 +2136,12 @@ void CCodecBufferChannel::stopUseOutputSurface(bool pushBlankBuffer) {

void CCodecBufferChannel::reset() {
    stop();
    mInputSurface.lock()->reset();
    mPipelineWatcher.lock()->flush();
    {
        mHasInputSurface = false;
        Mutexed<InputSurface>::Locked inputSurface(mInputSurface);
        inputSurface->surface.reset();
    }
    {
        Mutexed<Input>::Locked input(mInput);
        input->buffers.reset(new DummyInputBuffers(""));
@@ -2208,9 +2235,6 @@ void CCodecBufferChannel::onWorkDone(

void CCodecBufferChannel::onInputBufferDone(
        uint64_t frameIndex, size_t arrayIndex) {
    if (mInputSurface.lock()->get()) {
        return;
    }
    std::shared_ptr<C2Buffer> buffer =
            mPipelineWatcher.lock()->onInputBufferReleased(frameIndex, arrayIndex);
    bool newInputSlotAvailable = false;
@@ -2265,8 +2289,7 @@ bool CCodecBufferChannel::handleWork(
        notifyClient = false;
    }

    bool hasInputSurface = (mInputSurface.lock()->get() != nullptr);
    if (!hasInputSurface && (work->worklets.size() != 1u
    if (!mHasInputSurface && (work->worklets.size() != 1u
            || !work->worklets.front()
            || !(work->worklets.front()->output.flags &
                 C2FrameData::FLAG_INCOMPLETE))) {
@@ -2475,7 +2498,7 @@ bool CCodecBufferChannel::handleWork(
    c2_cntr64_t timestamp =
        worklet->output.ordinal.timestamp + work->input.ordinal.customOrdinal
                - work->input.ordinal.timestamp;
    if (hasInputSurface) {
    if (mHasInputSurface) {
        // When using input surface we need to restore the original input timestamp.
        timestamp = work->input.ordinal.customOrdinal;
    }
@@ -2633,6 +2656,12 @@ void CCodecBufferChannel::sendOutputBuffers() {
                    outBuffer->meta()->setObject("accessUnitInfo", obj);
                }
            }
            if (mHasInputSurface && android::media::codec::provider_->input_surface_throttle()) {
                Mutexed<InputSurface>::Locked inputSurface(mInputSurface);
                --inputSurface->numProcessingBuffersBalance;
                ALOGV("[%s] onOutputBufferAvailable: numProcessingBuffersBalance = %lld",
                      mName, static_cast<long long>(inputSurface->numProcessingBuffersBalance));
            }
            mCallback->onOutputBufferAvailable(index, outBuffer);
            break;
        }
@@ -2802,7 +2831,7 @@ void CCodecBufferChannel::resetBuffersPixelFormat(bool isEncoder) {
}

void CCodecBufferChannel::setInfoBuffer(const std::shared_ptr<C2InfoBuffer> &buffer) {
    if (mInputSurface.lock()->get() == nullptr) {
    if (!mHasInputSurface) {
        mInfoBuffers.push_back(buffer);
    } else {
        std::list<std::unique_ptr<C2Work>> items;
+15 −1
Original line number Diff line number Diff line
@@ -391,7 +391,21 @@ private:
    };
    Mutexed<BlockPools> mBlockPools;

    Mutexed<std::shared_ptr<InputSurfaceWrapper>> mInputSurface;
    std::atomic_bool mHasInputSurface;
    struct InputSurface {
        std::shared_ptr<InputSurfaceWrapper> surface;
        // This variable tracks the number of buffers processing
        // in the input surface and codec by counting the # of buffers to
        // be filled in and queued from the input surface and the # of
        // buffers generated from the codec.
        //
        // Note that this variable can go below 0, because it does not take
        // account the number of buffers initially in the buffer queue at
        // start. This is okay, as we only track how many more we allow
        // from the initial state.
        int64_t numProcessingBuffersBalance;
    };
    Mutexed<InputSurface> mInputSurface;

    MetaMode mMetaMode;