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

Commit 575a5361 authored by Andreas Huber's avatar Andreas Huber
Browse files

Better power savings with wifi display code.

No more polling the encoder for work to do, the encoder instead notifies
if there's activity.

Change-Id: Ia707211b4f5c5a6e6b70d750233d204a2d6bb778
related-to-bug: 7248248
parent 8d16bbc5
Loading
Loading
Loading
Loading
+26 −16
Original line number Diff line number Diff line
@@ -108,6 +108,11 @@ struct MediaCodec : public AHandler {

    status_t requestIDRFrame();

    // Notification will be posted once there "is something to do", i.e.
    // an input/output buffer has become available, a format change is
    // pending, an error is pending.
    void requestActivityNotification(const sp<AMessage> &notify);

protected:
    virtual ~MediaCodec();
    virtual void onMessageReceived(const sp<AMessage> &msg);
@@ -148,6 +153,7 @@ private:
        kWhatDequeueOutputTimedOut          = 'dOTO',
        kWhatCodecNotify                    = 'codc',
        kWhatRequestIDRFrame                = 'ridr',
        kWhatRequestActivityNotification    = 'racN',
    };

    enum {
@@ -191,6 +197,8 @@ private:

    List<sp<ABuffer> > mCSD;

    sp<AMessage> mActivityNotify;

    MediaCodec(const sp<ALooper> &looper);

    static status_t PostAndAwaitResponse(
@@ -216,6 +224,8 @@ private:
    status_t setNativeWindow(
            const sp<SurfaceTextureClient> &surfaceTextureClient);

    void postActivityNotificationIfPossible();

    DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
};

+43 −0
Original line number Diff line number Diff line
@@ -333,6 +333,12 @@ status_t MediaCodec::requestIDRFrame() {
    return OK;
}

void MediaCodec::requestActivityNotification(const sp<AMessage> &notify) {
    sp<AMessage> msg = new AMessage(kWhatRequestActivityNotification, id());
    msg->setMessage("notify", notify);
    msg->post();
}

////////////////////////////////////////////////////////////////////////////////

void MediaCodec::cancelPendingDequeueOperations() {
@@ -498,6 +504,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                            sendErrorReponse = false;

                            mFlags |= kFlagStickyError;
                            postActivityNotificationIfPossible();

                            cancelPendingDequeueOperations();
                            break;
@@ -508,6 +515,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                            sendErrorReponse = false;

                            mFlags |= kFlagStickyError;
                            postActivityNotificationIfPossible();
                            break;
                        }
                    }
@@ -600,6 +608,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                            (new AMessage)->postReply(mReplyID);
                        } else {
                            mFlags |= kFlagOutputBuffersChanged;
                            postActivityNotificationIfPossible();
                        }
                    }
                    break;
@@ -638,6 +647,7 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {

                    mOutputFormat = msg;
                    mFlags |= kFlagOutputFormatChanged;
                    postActivityNotificationIfPossible();
                    break;
                }

@@ -669,6 +679,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                                  err);

                            mFlags |= kFlagStickyError;
                            postActivityNotificationIfPossible();

                            cancelPendingDequeueOperations();
                        }
                        break;
@@ -680,6 +692,8 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                        ++mDequeueInputTimeoutGeneration;
                        mFlags &= ~kFlagDequeueInputPending;
                        mDequeueInputReplyID = 0;
                    } else {
                        postActivityNotificationIfPossible();
                    }
                    break;
                }
@@ -709,7 +723,10 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
                        ++mDequeueOutputTimeoutGeneration;
                        mFlags &= ~kFlagDequeueOutputPending;
                        mDequeueOutputReplyID = 0;
                    } else {
                        postActivityNotificationIfPossible();
                    }

                    break;
                }

@@ -1145,6 +1162,15 @@ void MediaCodec::onMessageReceived(const sp<AMessage> &msg) {
            break;
        }

        case kWhatRequestActivityNotification:
        {
            CHECK(mActivityNotify == NULL);
            CHECK(msg->findMessage("notify", &mActivityNotify));

            postActivityNotificationIfPossible();
            break;
        }

        default:
            TRESPASS();
    }
@@ -1210,6 +1236,8 @@ void MediaCodec::setState(State newState) {
        mFlags &= ~kFlagOutputFormatChanged;
        mFlags &= ~kFlagOutputBuffersChanged;
        mFlags &= ~kFlagStickyError;

        mActivityNotify.clear();
    }

    mState = newState;
@@ -1477,4 +1505,19 @@ status_t MediaCodec::setNativeWindow(
    return OK;
}

void MediaCodec::postActivityNotificationIfPossible() {
    if (mActivityNotify == NULL) {
        return;
    }

    if ((mFlags & (kFlagStickyError
                    | kFlagOutputBuffersChanged
                    | kFlagOutputFormatChanged))
            || !mAvailPortBuffers[kPortIndexInput].empty()
            || !mAvailPortBuffers[kPortIndexOutput].empty()) {
        mActivityNotify->post();
        mActivityNotify.clear();
    }
}

}  // namespace android
+33 −6
Original line number Diff line number Diff line
@@ -274,8 +274,17 @@ void Converter::onMessageReceived(const sp<AMessage> &msg) {
            break;
        }

        case kWhatDoMoreWork:
        case kWhatEncoderActivity:
        {
#if 0
            int64_t whenUs;
            if (msg->findInt64("whenUs", &whenUs)) {
                int64_t nowUs = ALooper::GetNowUs();
                ALOGI("[%s] kWhatEncoderActivity after %lld us",
                      mIsVideo ? "video" : "audio", nowUs - whenUs);
            }
#endif

            mDoMoreWorkPending = false;

            if (mEncoder == NULL) {
@@ -328,7 +337,17 @@ void Converter::scheduleDoMoreWork() {
    }

    mDoMoreWorkPending = true;
    (new AMessage(kWhatDoMoreWork, id()))->post(1000ll);

#if 1
    if (mEncoderActivityNotify == NULL) {
        mEncoderActivityNotify = new AMessage(kWhatEncoderActivity, id());
    }
    mEncoder->requestActivityNotification(mEncoderActivityNotify->dup());
#else
    sp<AMessage> notify = new AMessage(kWhatEncoderActivity, id());
    notify->setInt64("whenUs", ALooper::GetNowUs());
    mEncoder->requestActivityNotification(notify);
#endif
}

status_t Converter::feedEncoderInputBuffers() {
@@ -375,15 +394,23 @@ status_t Converter::feedEncoderInputBuffers() {
}

status_t Converter::doMoreWork() {
    status_t err;

    for (;;) {
        size_t bufferIndex;
    status_t err = mEncoder->dequeueInputBuffer(&bufferIndex);
        err = mEncoder->dequeueInputBuffer(&bufferIndex);

        if (err != OK) {
            break;
        }

    if (err == OK) {
        mAvailEncoderInputIndices.push_back(bufferIndex);
        feedEncoderInputBuffers();
    }

    feedEncoderInputBuffers();

    for (;;) {
        size_t bufferIndex;
        size_t offset;
        size_t size;
        int64_t timeUs;
+2 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ struct Converter : public AHandler {
        kWhatRequestIDRFrame,
        kWhatShutdown,
        kWhatMediaPullerNotify,
        kWhatEncoderActivity,
    };

    void shutdownAsync();
@@ -75,6 +76,7 @@ private:
    sp<AMessage> mOutputFormat;

    sp<MediaCodec> mEncoder;
    sp<AMessage> mEncoderActivityNotify;

    Vector<sp<ABuffer> > mEncoderInputBuffers;
    Vector<sp<ABuffer> > mEncoderOutputBuffers;