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

Commit 4249d164 authored by Guillaume Chelfi's avatar Guillaume Chelfi
Browse files

Implement peek mode state tracking in MediaCodec

This commit adds a new PeekMode type and mPeekMode member to
MediaCodec to track the current state of the video peek flow.

Bug: 157501309
Test: Currently untested, full CTS coverage coming soon
CTS-Coverage-Bug: 157501309
Change-Id: If8bc83f93d5cf12c1138c467e3152eafc3e92015
parent a3f909a8
Loading
Loading
Loading
Loading
+90 −4
Original line number Diff line number Diff line
@@ -712,6 +712,7 @@ MediaCodec::MediaCodec(
      mTunneledInputWidth(0),
      mTunneledInputHeight(0),
      mTunneled(false),
      mTunnelPeekState(TunnelPeekState::kEnabledNoBuffer),
      mHaveInputSurface(false),
      mHavePendingInputBuffers(false),
      mCpuBoostRequested(false),
@@ -917,6 +918,47 @@ void MediaCodec::updateLowLatency(const sp<AMessage> &msg) {
    }
}

constexpr const char *MediaCodec::asString(TunnelPeekState state, const char *default_string){
    switch(state) {
        case TunnelPeekState::kEnabledNoBuffer:
            return "EnabledNoBuffer";
        case TunnelPeekState::kDisabledNoBuffer:
            return "DisabledNoBuffer";
        case TunnelPeekState::kBufferDecoded:
            return "BufferDecoded";
        case TunnelPeekState::kBufferRendered:
            return "BufferRendered";
        default:
            return default_string;
    }
}

void MediaCodec::updateTunnelPeek(const sp<AMessage> &msg) {
    int32_t tunnelPeek = 0;
    if (!msg->findInt32("tunnel-peek", &tunnelPeek)){
        return;
    }
    if(tunnelPeek == 0){
        if (mTunnelPeekState == TunnelPeekState::kEnabledNoBuffer) {
            mTunnelPeekState = TunnelPeekState::kDisabledNoBuffer;
            ALOGV("TunnelPeekState: %s -> %s",
                  asString(TunnelPeekState::kEnabledNoBuffer),
                  asString(TunnelPeekState::kDisabledNoBuffer));
            return;
        }
    } else {
        if (mTunnelPeekState == TunnelPeekState::kDisabledNoBuffer) {
            mTunnelPeekState = TunnelPeekState::kEnabledNoBuffer;
            ALOGV("TunnelPeekState: %s -> %s",
                  asString(TunnelPeekState::kDisabledNoBuffer),
                  asString(TunnelPeekState::kEnabledNoBuffer));
            return;
        }
    }

    ALOGV("Ignoring tunnel-peek=%d for %s", tunnelPeek, asString(mTunnelPeekState));
}

bool MediaCodec::Histogram::setup(int nbuckets, int64_t width, int64_t floor)
{
    if (nbuckets <= 0 || width <= 0) {
@@ -3007,9 +3049,17 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {

                case kWhatOutputFramesRendered:
                {
                    // ignore these in all states except running, and check that we have a
                    // notification set
                    if (mState == STARTED && mOnFrameRenderedNotification != NULL) {
                    // ignore these in all states except running
                    if (mState != STARTED) {
                        break;
                    }
                    TunnelPeekState previousState = mTunnelPeekState;
                    mTunnelPeekState = TunnelPeekState::kBufferRendered;
                    ALOGV("TunnelPeekState: %s -> %s",
                          asString(previousState),
                          asString(TunnelPeekState::kBufferRendered));
                    // check that we have a notification set
                    if (mOnFrameRenderedNotification != NULL) {
                        sp<AMessage> notify = mOnFrameRenderedNotification->dup();
                        notify->setMessage("data", msg);
                        notify->post();
@@ -3019,7 +3069,32 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {

                case kWhatFirstTunnelFrameReady:
                {
                    if (mState == STARTED && mOnFirstTunnelFrameReadyNotification != nullptr) {
                    if (mState != STARTED) {
                        break;
                    }
                    switch(mTunnelPeekState) {
                        case TunnelPeekState::kDisabledNoBuffer:
                            mTunnelPeekState = TunnelPeekState::kBufferDecoded;
                            ALOGV("TunnelPeekState: %s -> %s",
                                  asString(TunnelPeekState::kDisabledNoBuffer),
                                  asString(TunnelPeekState::kBufferDecoded));
                            break;
                        case TunnelPeekState::kEnabledNoBuffer:
                            mTunnelPeekState = TunnelPeekState::kBufferDecoded;
                            ALOGV("TunnelPeekState: %s -> %s",
                                  asString(TunnelPeekState::kEnabledNoBuffer),
                                  asString(TunnelPeekState::kBufferDecoded));
                            {
                                sp<AMessage> parameters = new AMessage();
                                parameters->setInt32("android._trigger-tunnel-peek", 1);
                                mCodec->signalSetParameters(parameters);
                            }
                            break;
                        default:
                            break;
                    }

                    if (mOnFirstTunnelFrameReadyNotification != nullptr) {
                        sp<AMessage> notify = mOnFirstTunnelFrameReadyNotification->dup();
                        notify->setMessage("data", msg);
                        notify->post();
@@ -3489,6 +3564,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
            }
            sp<AReplyToken> replyID;
            CHECK(msg->senderAwaitsResponse(&replyID));
            TunnelPeekState previousState = mTunnelPeekState;
            mTunnelPeekState = TunnelPeekState::kEnabledNoBuffer;
            ALOGV("TunnelPeekState: %s -> %s",
                  asString(previousState),
                  asString(TunnelPeekState::kEnabledNoBuffer));

            mReplyID = replyID;
            setState(STARTING);
@@ -3923,6 +4003,11 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {

            mCodec->signalFlush();
            returnBuffersToCodec();
            TunnelPeekState previousState = mTunnelPeekState;
            mTunnelPeekState = TunnelPeekState::kEnabledNoBuffer;
            ALOGV("TunnelPeekState: %s -> %s",
                  asString(previousState),
                  asString(TunnelPeekState::kEnabledNoBuffer));
            break;
        }

@@ -4833,6 +4918,7 @@ status_t MediaCodec::setParameters(const sp<AMessage> &params) {
status_t MediaCodec::onSetParameters(const sp<AMessage> &params) {
    updateLowLatency(params);
    mapFormat(mComponentName, params, nullptr, false);
    updateTunnelPeek(params);
    mCodec->signalSetParameters(params);

    return OK;
+19 −0
Original line number Diff line number Diff line
@@ -363,6 +363,22 @@ private:
        bool mOwnedByClient;
    };

    // This type is used to track the tunnel mode video peek state machine:
    //
    // DisabledNoBuffer -> EnabledNoBuffer  when tunnel-peek = true
    // EnabledNoBuffer  -> DisabledNoBuffer when tunnel-peek = false
    // DisabledNoBuffer -> BufferDecoded    when kWhatFirstTunnelFrameReady
    // EnabledNoBuffer  -> BufferDecoded    when kWhatFirstTunnelFrameReady
    // BufferDecoded    -> BufferRendered   when kWhatFrameRendered
    // <all states>     -> EnabledNoBuffer  when flush
    // <all states>     -> EnabledNoBuffer  when stop then configure then start
    enum struct TunnelPeekState {
        kDisabledNoBuffer,
        kEnabledNoBuffer,
        kBufferDecoded,
        kBufferRendered,
    };

    struct ResourceManagerServiceProxy;

    State mState;
@@ -389,6 +405,8 @@ private:
    void flushMediametrics();
    void updateEphemeralMediametrics(mediametrics_handle_t item);
    void updateLowLatency(const sp<AMessage> &msg);
    constexpr const char *asString(TunnelPeekState state, const char *default_string="?");
    void updateTunnelPeek(const sp<AMessage> &msg);

    sp<AMessage> mOutputFormat;
    sp<AMessage> mInputFormat;
@@ -442,6 +460,7 @@ private:
    int32_t mTunneledInputWidth;
    int32_t mTunneledInputHeight;
    bool mTunneled;
    TunnelPeekState mTunnelPeekState;

    sp<IDescrambler> mDescrambler;