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

Commit 577048bc authored by Wonsik Kim's avatar Wonsik Kim Committed by Gerrit Code Review
Browse files

Merge "CCodec: fix input surface throttling" into main

parents 661b2bff 1951d936
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -43,6 +43,16 @@ flag {
  bug: "325520135"
}

flag {
  name: "input_surface_throttle"
  namespace: "codec_fwk"
  description: "Bugfix flag for input surface throttle"
  bug: "342269852"
  metadata {
    purpose: PURPOSE_BUGFIX
  }
}

flag {
  name: "large_audio_frame_finish"
  namespace: "codec_fwk"
+4 −0
Original line number Diff line number Diff line
@@ -105,6 +105,10 @@ void C2AidlNode::onInputBufferDone(c2_cntr64_t index) {
    return mImpl->onInputBufferDone(index);
}

void C2AidlNode::onInputBufferEmptied() {
    return mImpl->onInputBufferEmptied();
}

android_dataspace C2AidlNode::getDataspace() {
    return mImpl->getDataspace();
}
+7 −1
Original line number Diff line number Diff line
@@ -68,12 +68,18 @@ public:
    void setFrameSize(uint32_t width, uint32_t height);

    /**
     * Clean up work item reference.
     * Notify that the input buffer reference is no longer needed by the component.
     * Clean up if necessary.
     *
     * \param index input work index
     */
    void onInputBufferDone(c2_cntr64_t index);

    /**
     * Notify input buffer is emptied.
     */
    void onInputBufferEmptied();

    /**
     * Returns dataspace information from GraphicBufferSource.
     */
+61 −12
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include <C2Debug.h>
#include <C2PlatformSupport.h>

#include <android_media_codec.h>
#include <android/fdsan.h>
#include <media/stagefright/foundation/ColorUtils.h>
#include <ui/Fence.h>
@@ -373,7 +374,10 @@ status_t C2NodeImpl::submitBuffer(
    }
    work->worklets.clear();
    work->worklets.emplace_back(new C2Worklet);
    mBufferIdsInUse.lock()->emplace(work->input.ordinal.frameIndex.peeku(), buffer);
    {
        Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker);
        buffers->mIdsInUse.emplace(work->input.ordinal.frameIndex.peeku(), buffer);
    }
    mQueueThread->queue(comp, fenceFd, std::move(work), std::move(fd0), std::move(fd1));

    return OK;
@@ -405,29 +409,74 @@ void C2NodeImpl::setFrameSize(uint32_t width, uint32_t height) {
}

void C2NodeImpl::onInputBufferDone(c2_cntr64_t index) {
    if (mAidlHal) {
        if (!mAidlBufferSource) {
            ALOGD("Buffer source not set (index=%llu)", index.peekull());
    if (android::media::codec::provider_->input_surface_throttle()) {
        Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker);
        auto it = buffers->mIdsInUse.find(index.peeku());
        if (it == buffers->mIdsInUse.end()) {
            ALOGV("Untracked input index %llu (maybe already removed)", index.peekull());
            return;
        }
        int32_t bufferId = it->second;
        (void)buffers->mIdsInUse.erase(it);
        buffers->mAvailableIds.push_back(bufferId);
    } else {
        if (!mBufferSource) {
            ALOGD("Buffer source not set (index=%llu)", index.peekull());
        if (!hasBufferSource()) {
            return;
        }
    }

        int32_t bufferId = 0;
        {
        decltype(mBufferIdsInUse)::Locked bufferIds(mBufferIdsInUse);
        auto it = bufferIds->find(index.peeku());
        if (it == bufferIds->end()) {
            Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker);
            auto it = buffers->mIdsInUse.find(index.peeku());
            if (it == buffers->mIdsInUse.end()) {
                ALOGV("Untracked input index %llu (maybe already removed)", index.peekull());
                return;
            }
            bufferId = it->second;
        (void)bufferIds->erase(it);
            (void)buffers->mIdsInUse.erase(it);
        }
        notifyInputBufferEmptied(bufferId);
    }
}

void C2NodeImpl::onInputBufferEmptied() {
    if (!android::media::codec::provider_->input_surface_throttle()) {
        ALOGE("onInputBufferEmptied should not be called "
              "when input_surface_throttle is false");
        return;
    }
    if (!hasBufferSource()) {
        return;
    }
    int32_t bufferId = 0;
    {
        Mutexed<BuffersTracker>::Locked buffers(mBuffersTracker);
        if (buffers->mAvailableIds.empty()) {
            ALOGV("The codec is ready to take more input buffers "
                    "but no input buffers are ready yet.");
            return;
        }
        bufferId = buffers->mAvailableIds.front();
        buffers->mAvailableIds.pop_front();
    }
    notifyInputBufferEmptied(bufferId);
}

bool C2NodeImpl::hasBufferSource() {
    if (mAidlHal) {
        if (!mAidlBufferSource) {
            ALOGD("Buffer source not set");
            return false;
        }
    } else {
        if (!mBufferSource) {
            ALOGD("Buffer source not set");
            return false;
        }
    }
    return true;
}

void C2NodeImpl::notifyInputBufferEmptied(int32_t bufferId) {
    if (mAidlHal) {
        ::ndk::ScopedFileDescriptor nullFence;
        (void)mAidlBufferSource->onInputBufferEmptied(bufferId, nullFence);
+20 −2
Original line number Diff line number Diff line
@@ -73,12 +73,18 @@ struct C2NodeImpl {
    void setFrameSize(uint32_t width, uint32_t height);

    /**
     * Clean up work item reference.
     * Notify that the input buffer reference is no longer needed by the component.
     * Clean up if necessary.
     *
     * \param index input work index
     */
    void onInputBufferDone(c2_cntr64_t index);

    /**
     * Notify input buffer is emptied.
     */
    void onInputBufferEmptied();

    /**
     * Returns dataspace information from GraphicBufferSource.
     */
@@ -118,12 +124,24 @@ private:
    c2_cntr64_t mPrevInputTimestamp; // input timestamp for previous frame
    c2_cntr64_t mPrevCodecTimestamp; // adjusted (codec) timestamp for previous frame

    Mutexed<std::map<uint64_t, uint32_t>> mBufferIdsInUse;
    // Tracks the status of buffers
    struct BuffersTracker {
        BuffersTracker() = default;

        // Keeps track of buffers that are used by the component. Maps timestamp -> ID
        std::map<uint64_t, uint32_t> mIdsInUse;
        // Keeps track of the buffer IDs that are available after being released from the component.
        std::list<uint32_t> mAvailableIds;
    };
    Mutexed<BuffersTracker> mBuffersTracker;

    class QueueThread;
    sp<QueueThread> mQueueThread;

    bool mAidlHal;

    bool hasBufferSource();
    void notifyInputBufferEmptied(int32_t bufferId);
};

}  // namespace android
Loading