OSDN Git Service

Better power savings with wifi display code.
authorAndreas Huber <andih@google.com>
Wed, 3 Oct 2012 17:16:58 +0000 (10:16 -0700)
committerAndreas Huber <andih@google.com>
Wed, 3 Oct 2012 17:16:58 +0000 (10:16 -0700)
No more polling the encoder for work to do, the encoder instead notifies
if there's activity.

Change-Id: Ia707211b4f5c5a6e6b70d750233d204a2d6bb778
related-to-bug: 7248248

include/media/stagefright/MediaCodec.h
media/libstagefright/MediaCodec.cpp
media/libstagefright/wifi-display/source/Converter.cpp
media/libstagefright/wifi-display/source/Converter.h

index 8c612d4..cacfa54 100644 (file)
@@ -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);
 };
 
index 7f97430..56e6df0 100644 (file)
@@ -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
index f044666..a9b4c23 100644 (file)
@@ -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;
index 93ff72f..8d45395 100644 (file)
@@ -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;