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

Commit 4fa4f2bb authored by Wonsik Kim's avatar Wonsik Kim
Browse files

CCodec: skip first N longest work inside total delay

If the client pauses pushing input to the component, work items inside
total delay may sit in the pipeline indefinitely. We don't want to
error out for those work. Once the client pushes EOS, ensure all work
items finishes within reasonable time regardless of delay.

Bug: 124355114
Test: manual
Test: atest CtsSecurityTestCases:StagefrightTest
Test: atest CtsMediaTestCases -- --module-arg CtsMediaTestCases:size:small
Change-Id: I0e95b2ddb94482da855d70cbe75f6bffaaffe279
parent 0e2c6b80
Loading
Loading
Loading
Loading
+16 −9
Original line number Diff line number Diff line
@@ -1557,6 +1557,7 @@ CCodecBufferChannel::CCodecBufferChannel(
      mCCodecCallback(callback),
      mNumInputSlots(kSmoothnessFactor),
      mNumOutputSlots(kSmoothnessFactor),
      mDelay(0),
      mFrameIndex(0u),
      mFirstValidFrameIndex(0u),
      mMetaMode(MODE_NONE),
@@ -2104,11 +2105,13 @@ status_t CCodecBufferChannel::start(
        }
    }

    mNumInputSlots =
        (inputDelay ? inputDelay.value : 0) +
        (pipelineDelay ? pipelineDelay.value : 0) +
        kSmoothnessFactor;
    mNumOutputSlots = (outputDelay ? outputDelay.value : 0) + kSmoothnessFactor;
    uint32_t inputDelayValue = inputDelay ? inputDelay.value : 0;
    uint32_t pipelineDelayValue = pipelineDelay ? pipelineDelay.value : 0;
    uint32_t outputDelayValue = outputDelay ? outputDelay.value : 0;

    mNumInputSlots = inputDelayValue + pipelineDelayValue + kSmoothnessFactor;
    mNumOutputSlots = outputDelayValue + kSmoothnessFactor;
    mDelay = inputDelayValue + pipelineDelayValue + outputDelayValue;

    // TODO: get this from input format
    bool secure = mComponent->getName().find(".secure") != std::string::npos;
@@ -2397,9 +2400,9 @@ status_t CCodecBufferChannel::start(

    {
        Mutexed<PipelineWatcher>::Locked watcher(mPipelineWatcher);
        watcher->inputDelay(inputDelay ? inputDelay.value : 0)
                .pipelineDelay(pipelineDelay ? pipelineDelay.value : 0)
                .outputDelay(outputDelay ? outputDelay.value : 0)
        watcher->inputDelay(inputDelayValue)
                .pipelineDelay(pipelineDelayValue)
                .outputDelay(outputDelayValue)
                .smoothnessFactor(kSmoothnessFactor);
        watcher->flush();
    }
@@ -2816,7 +2819,11 @@ status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) {
}

PipelineWatcher::Clock::duration CCodecBufferChannel::elapsed() {
    return mPipelineWatcher.lock()->elapsed(PipelineWatcher::Clock::now());
    // When client pushed EOS, we want all the work to be done quickly.
    // Otherwise, component may have stalled work due to input starvation up to
    // the sum of the delay in the pipeline.
    size_t n = mInputMetEos ? 0 : mDelay;
    return mPipelineWatcher.lock()->elapsed(PipelineWatcher::Clock::now(), n);
}

void CCodecBufferChannel::setMetaMode(MetaMode mode) {
+1 −0
Original line number Diff line number Diff line
@@ -236,6 +236,7 @@ private:

    size_t mNumInputSlots;
    size_t mNumOutputSlots;
    size_t mDelay;

    Mutexed<std::unique_ptr<InputBuffers>> mInputBuffers;
    Mutexed<std::list<sp<ABuffer>>> mFlushedConfigs;
+15 −13
Original line number Diff line number Diff line
@@ -127,19 +127,21 @@ bool PipelineWatcher::pipelineFull() const {
}

PipelineWatcher::Clock::duration PipelineWatcher::elapsed(
        const PipelineWatcher::Clock::time_point &now) const {
    return std::accumulate(
            mFramesInPipeline.begin(),
            mFramesInPipeline.end(),
            Clock::duration::zero(),
            [&now](const Clock::duration &current,
                   const decltype(mFramesInPipeline)::value_type &value) {
        const PipelineWatcher::Clock::time_point &now, size_t n) const {
    if (mFramesInPipeline.size() <= n) {
        return Clock::duration::zero();
    }
    std::vector<Clock::duration> durations;
    for (const decltype(mFramesInPipeline)::value_type &value : mFramesInPipeline) {
        Clock::duration elapsed = now - value.second.queuedAt;
        ALOGV("elapsed: frameIndex = %llu elapsed = %lldms",
              (unsigned long long)value.first,
              std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count());
                return current > elapsed ? current : elapsed;
            });
        durations.push_back(elapsed);
    }
    nth_element(durations.begin(), durations.end(), durations.begin() + n,
                std::greater<Clock::duration>());
    return durations[n];
}

}  // namespace android
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ public:
    void flush();

    bool pipelineFull() const;
    Clock::duration elapsed(const Clock::time_point &now) const;
    Clock::duration elapsed(const Clock::time_point &now, size_t n) const;

private:
    uint32_t mInputDelay;