From 575a5361fc970476cd7979638ee3ac00cc6e5024 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Wed, 3 Oct 2012 10:16:58 -0700 Subject: 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 --- media/libstagefright/MediaCodec.cpp | 43 ++++++++++++++++++++++ .../wifi-display/source/Converter.cpp | 39 +++++++++++++++++--- .../libstagefright/wifi-display/source/Converter.h | 2 + 3 files changed, 78 insertions(+), 6 deletions(-) (limited to 'media/libstagefright') diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 7f97430..56e6df0 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -333,6 +333,12 @@ status_t MediaCodec::requestIDRFrame() { return OK; } +void MediaCodec::requestActivityNotification(const sp ¬ify) { + sp msg = new AMessage(kWhatRequestActivityNotification, id()); + msg->setMessage("notify", notify); + msg->post(); +} + //////////////////////////////////////////////////////////////////////////////// void MediaCodec::cancelPendingDequeueOperations() { @@ -498,6 +504,7 @@ void MediaCodec::onMessageReceived(const sp &msg) { sendErrorReponse = false; mFlags |= kFlagStickyError; + postActivityNotificationIfPossible(); cancelPendingDequeueOperations(); break; @@ -508,6 +515,7 @@ void MediaCodec::onMessageReceived(const sp &msg) { sendErrorReponse = false; mFlags |= kFlagStickyError; + postActivityNotificationIfPossible(); break; } } @@ -600,6 +608,7 @@ void MediaCodec::onMessageReceived(const sp &msg) { (new AMessage)->postReply(mReplyID); } else { mFlags |= kFlagOutputBuffersChanged; + postActivityNotificationIfPossible(); } } break; @@ -638,6 +647,7 @@ void MediaCodec::onMessageReceived(const sp &msg) { mOutputFormat = msg; mFlags |= kFlagOutputFormatChanged; + postActivityNotificationIfPossible(); break; } @@ -669,6 +679,8 @@ void MediaCodec::onMessageReceived(const sp &msg) { err); mFlags |= kFlagStickyError; + postActivityNotificationIfPossible(); + cancelPendingDequeueOperations(); } break; @@ -680,6 +692,8 @@ void MediaCodec::onMessageReceived(const sp &msg) { ++mDequeueInputTimeoutGeneration; mFlags &= ~kFlagDequeueInputPending; mDequeueInputReplyID = 0; + } else { + postActivityNotificationIfPossible(); } break; } @@ -709,7 +723,10 @@ void MediaCodec::onMessageReceived(const sp &msg) { ++mDequeueOutputTimeoutGeneration; mFlags &= ~kFlagDequeueOutputPending; mDequeueOutputReplyID = 0; + } else { + postActivityNotificationIfPossible(); } + break; } @@ -1145,6 +1162,15 @@ void MediaCodec::onMessageReceived(const sp &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 diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp index f044666..a9b4c23 100644 --- a/media/libstagefright/wifi-display/source/Converter.cpp +++ b/media/libstagefright/wifi-display/source/Converter.cpp @@ -274,8 +274,17 @@ void Converter::onMessageReceived(const sp &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 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() { - size_t bufferIndex; - status_t err = mEncoder->dequeueInputBuffer(&bufferIndex); + status_t err; + + for (;;) { + size_t 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; diff --git a/media/libstagefright/wifi-display/source/Converter.h b/media/libstagefright/wifi-display/source/Converter.h index 93ff72f..8d45395 100644 --- a/media/libstagefright/wifi-display/source/Converter.h +++ b/media/libstagefright/wifi-display/source/Converter.h @@ -58,6 +58,7 @@ struct Converter : public AHandler { kWhatRequestIDRFrame, kWhatShutdown, kWhatMediaPullerNotify, + kWhatEncoderActivity, }; void shutdownAsync(); @@ -75,6 +76,7 @@ private: sp mOutputFormat; sp mEncoder; + sp mEncoderActivityNotify; Vector > mEncoderInputBuffers; Vector > mEncoderOutputBuffers; -- cgit v1.1