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

Commit 32ebae3d authored by Sungtak Lee's avatar Sungtak Lee Committed by Automerger Merge Worker
Browse files

Merge "CCodec: push a blank buffer at the end correctly" into tm-qpr-dev am: 918a6f39

parents 1866ae2a 918a6f39
Loading
Loading
Loading
Loading
+19 −22
Original line number Diff line number Diff line
@@ -1868,18 +1868,14 @@ void CCodec::initiateStop() {
        }
        state->set(STOPPING);
    }
    {
        Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
        const std::unique_ptr<Config> &config = *configLocked;
        if (config->mPushBlankBuffersOnStop) {
            mChannel->pushBlankBufferToOutputSurface();
        }
    }
    mChannel->reset();
    (new AMessage(kWhatStop, this))->post();
    bool pushBlankBuffer = mConfig.lock().get()->mPushBlankBuffersOnStop;
    sp<AMessage> stopMessage(new AMessage(kWhatStop, this));
    stopMessage->setInt32("pushBlankBuffer", pushBlankBuffer);
    stopMessage->post();
}

void CCodec::stop() {
void CCodec::stop(bool pushBlankBuffer) {
    std::shared_ptr<Codec2Client::Component> comp;
    {
        Mutexed<State>::Locked state(mState);
@@ -1898,7 +1894,7 @@ void CCodec::stop() {
        comp = state->comp;
    }
    status_t err = comp->stop();
    mChannel->stopUseOutputSurface();
    mChannel->stopUseOutputSurface(pushBlankBuffer);
    if (err != C2_OK) {
        // TODO: convert err into status_t
        mCallback->onError(UNKNOWN_ERROR, ACTION_CODE_FATAL);
@@ -1963,21 +1959,16 @@ void CCodec::initiateRelease(bool sendCallback /* = true */) {
            config->mInputSurfaceDataspace = HAL_DATASPACE_UNKNOWN;
        }
    }
    {
        Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
        const std::unique_ptr<Config> &config = *configLocked;
        if (config->mPushBlankBuffersOnStop) {
            mChannel->pushBlankBufferToOutputSurface();
        }
    }

    mChannel->reset();
    bool pushBlankBuffer = mConfig.lock().get()->mPushBlankBuffersOnStop;
    // thiz holds strong ref to this while the thread is running.
    sp<CCodec> thiz(this);
    std::thread([thiz, sendCallback] { thiz->release(sendCallback); }).detach();
    std::thread([thiz, sendCallback, pushBlankBuffer]
                { thiz->release(sendCallback, pushBlankBuffer); }).detach();
}

void CCodec::release(bool sendCallback) {
void CCodec::release(bool sendCallback, bool pushBlankBuffer) {
    std::shared_ptr<Codec2Client::Component> comp;
    {
        Mutexed<State>::Locked state(mState);
@@ -1992,7 +1983,7 @@ void CCodec::release(bool sendCallback) {
        comp = state->comp;
    }
    comp->release();
    mChannel->stopUseOutputSurface();
    mChannel->stopUseOutputSurface(pushBlankBuffer);

    {
        Mutexed<State>::Locked state(mState);
@@ -2006,6 +1997,7 @@ void CCodec::release(bool sendCallback) {
}

status_t CCodec::setSurface(const sp<Surface> &surface) {
    bool pushBlankBuffer = false;
    {
        Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
        const std::unique_ptr<Config> &config = *configLocked;
@@ -2031,8 +2023,9 @@ status_t CCodec::setSurface(const sp<Surface> &surface) {
                return err;
            }
        }
        pushBlankBuffer = config->mPushBlankBuffersOnStop;
    }
    return mChannel->setSurface(surface);
    return mChannel->setSurface(surface, pushBlankBuffer);
}

void CCodec::signalFlush() {
@@ -2331,7 +2324,11 @@ void CCodec::onMessageReceived(const sp<AMessage> &msg) {
        case kWhatStop: {
            // C2Component::stop() should return within 500ms.
            setDeadline(now, 1500ms, "stop");
            stop();
            int32_t pushBlankBuffer;
            if (!msg->findInt32("pushBlankBuffer", &pushBlankBuffer)) {
                pushBlankBuffer = 0;
            }
            stop(static_cast<bool>(pushBlankBuffer));
            break;
        }
        case kWhatFlush: {
+27 −13
Original line number Diff line number Diff line
@@ -1578,14 +1578,22 @@ void CCodecBufferChannel::stop() {
    mFirstValidFrameIndex = mFrameIndex.load(std::memory_order_relaxed);
}

void CCodecBufferChannel::stopUseOutputSurface() {
    if (mOutputSurface.lock()->surface) {
void CCodecBufferChannel::stopUseOutputSurface(bool pushBlankBuffer) {
    sp<Surface> surface = mOutputSurface.lock()->surface;
    if (surface) {
        C2BlockPool::local_id_t outputPoolId;
        {
            Mutexed<BlockPools>::Locked pools(mBlockPools);
            outputPoolId = pools->outputPoolId;
        }
        if (mComponent) mComponent->stopUsingOutputSurface(outputPoolId);

        if (pushBlankBuffer) {
            sp<ANativeWindow> anw = static_cast<ANativeWindow *>(surface.get());
            if (anw) {
                pushBlankBuffersToNativeWindow(anw.get());
            }
        }
    }
}

@@ -2097,14 +2105,20 @@ void CCodecBufferChannel::sendOutputBuffers() {
    }
}

status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) {
status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface, bool pushBlankBuffer) {
    static std::atomic_uint32_t surfaceGeneration{0};
    uint32_t generation = (getpid() << 10) |
            ((surfaceGeneration.fetch_add(1, std::memory_order_relaxed) + 1)
                & ((1 << 10) - 1));

    sp<IGraphicBufferProducer> producer;
    int maxDequeueCount = mOutputSurface.lock()->maxDequeueBuffers;
    int maxDequeueCount;
    sp<Surface> oldSurface;
    {
        Mutexed<OutputSurface>::Locked outputSurface(mOutputSurface);
        maxDequeueCount = outputSurface->maxDequeueBuffers;
        oldSurface = outputSurface->surface;
    }
    if (newSurface) {
        newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
        newSurface->setDequeueTimeout(kDequeueTimeoutNs);
@@ -2141,6 +2155,15 @@ status_t CCodecBufferChannel::setSurface(const sp<Surface> &newSurface) {
        output->generation = generation;
    }

    if (oldSurface && pushBlankBuffer) {
        // When ReleaseSurface was set from MediaCodec,
        // pushing a blank buffer at the end might be necessary.
        sp<ANativeWindow> anw = static_cast<ANativeWindow *>(oldSurface.get());
        if (anw) {
            pushBlankBuffersToNativeWindow(anw.get());
        }
    }

    return OK;
}

@@ -2230,13 +2253,4 @@ status_t toStatusT(c2_status_t c2s, c2_operation_t c2op) {
    }
}

status_t CCodecBufferChannel::pushBlankBufferToOutputSurface() {
  Mutexed<OutputSurface>::Locked output(mOutputSurface);
  sp<ANativeWindow> nativeWindow = static_cast<ANativeWindow *>(output->surface.get());
  if (nativeWindow == nullptr) {
      return INVALID_OPERATION;
  }
  return pushBlankBuffersToNativeWindow(nativeWindow.get());
}

}  // namespace android
+4 −7
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ public:
    /**
     * Set output graphic surface for rendering.
     */
    status_t setSurface(const sp<Surface> &surface);
    status_t setSurface(const sp<Surface> &surface, bool pushBlankBuffer);

    /**
     * Set GraphicBufferSource object from which the component extracts input
@@ -151,8 +151,10 @@ public:
    /**
     * Stop using buffers of the current output surface for other Codec
     * instances to use the surface safely.
     *
     * \param pushBlankBuffer[in]       push a blank buffer at the end if true
     */
    void stopUseOutputSurface();
    void stopUseOutputSurface(bool pushBlankBuffer);

    /**
     * Stop queueing buffers to the component. This object should never queue
@@ -201,11 +203,6 @@ public:

    void setMetaMode(MetaMode mode);

    /**
     * Push a blank buffer to the configured native output surface.
     */
    status_t pushBlankBufferToOutputSurface();

private:
    class QueueGuard;

+2 −2
Original line number Diff line number Diff line
@@ -109,9 +109,9 @@ private:
    void allocate(const sp<MediaCodecInfo> &codecInfo);
    void configure(const sp<AMessage> &msg);
    void start();
    void stop();
    void stop(bool pushBlankBuffer);
    void flush();
    void release(bool sendCallback);
    void release(bool sendCallback, bool pushBlankBuffer);

    /**
     * Creates an input surface for the current device configuration compatible with CCodec.
+5 −0
Original line number Diff line number Diff line
@@ -250,6 +250,11 @@ status_t pushBlankBuffersToNativeWindow(ANativeWindow *nativeWindow /* nonnull *

    static_cast<Surface*>(nativeWindow)->getIGraphicBufferProducer()->allowAllocation(true);

    // In nonblocking mode(timetout = 0), native_window_dequeue_buffer_and_wait()
    // can fail with timeout. Changing to blocking mode will ensure that dequeue
    // does not timeout.
    static_cast<Surface*>(nativeWindow)->getIGraphicBufferProducer()->setDequeueTimeout(-1);

    err = nativeWindow->query(nativeWindow,
            NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS, &minUndequeuedBufs);
    if (err != NO_ERROR) {