summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Huber <andih@google.com>2012-10-03 10:16:58 -0700
committerAndreas Huber <andih@google.com>2012-10-03 10:16:58 -0700
commit575a5361fc970476cd7979638ee3ac00cc6e5024 (patch)
tree4dfdda910405a6d40d50c52119c86d0853fd3587
parent8d16bbc5a354d302abfd912b8d88d9c7feb3948f (diff)
downloadframeworks_av-575a5361fc970476cd7979638ee3ac00cc6e5024.zip
frameworks_av-575a5361fc970476cd7979638ee3ac00cc6e5024.tar.gz
frameworks_av-575a5361fc970476cd7979638ee3ac00cc6e5024.tar.bz2
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
-rw-r--r--include/media/stagefright/MediaCodec.h42
-rw-r--r--media/libstagefright/MediaCodec.cpp43
-rw-r--r--media/libstagefright/wifi-display/source/Converter.cpp39
-rw-r--r--media/libstagefright/wifi-display/source/Converter.h2
4 files changed, 104 insertions, 22 deletions
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 8c612d4..cacfa54 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -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);
@@ -132,22 +137,23 @@ private:
};
enum {
- kWhatInit = 'init',
- kWhatConfigure = 'conf',
- kWhatStart = 'strt',
- kWhatStop = 'stop',
- kWhatRelease = 'rele',
- kWhatDequeueInputBuffer = 'deqI',
- kWhatQueueInputBuffer = 'queI',
- kWhatDequeueOutputBuffer = 'deqO',
- kWhatReleaseOutputBuffer = 'relO',
- kWhatGetBuffers = 'getB',
- kWhatFlush = 'flus',
- kWhatGetOutputFormat = 'getO',
- kWhatDequeueInputTimedOut = 'dITO',
- kWhatDequeueOutputTimedOut = 'dOTO',
- kWhatCodecNotify = 'codc',
- kWhatRequestIDRFrame = 'ridr',
+ kWhatInit = 'init',
+ kWhatConfigure = 'conf',
+ kWhatStart = 'strt',
+ kWhatStop = 'stop',
+ kWhatRelease = 'rele',
+ kWhatDequeueInputBuffer = 'deqI',
+ kWhatQueueInputBuffer = 'queI',
+ kWhatDequeueOutputBuffer = 'deqO',
+ kWhatReleaseOutputBuffer = 'relO',
+ kWhatGetBuffers = 'getB',
+ kWhatFlush = 'flus',
+ kWhatGetOutputFormat = 'getO',
+ kWhatDequeueInputTimedOut = 'dITO',
+ 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);
};
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<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
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<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() {
- 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<AMessage> mOutputFormat;
sp<MediaCodec> mEncoder;
+ sp<AMessage> mEncoderActivityNotify;
Vector<sp<ABuffer> > mEncoderInputBuffers;
Vector<sp<ABuffer> > mEncoderOutputBuffers;