diff options
| author | Andreas Huber <andih@google.com> | 2012-10-03 10:16:58 -0700 | 
|---|---|---|
| committer | Andreas Huber <andih@google.com> | 2012-10-03 10:16:58 -0700 | 
| commit | 575a5361fc970476cd7979638ee3ac00cc6e5024 (patch) | |
| tree | 4dfdda910405a6d40d50c52119c86d0853fd3587 | |
| parent | 8d16bbc5a354d302abfd912b8d88d9c7feb3948f (diff) | |
| download | frameworks_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.h | 42 | ||||
| -rw-r--r-- | media/libstagefright/MediaCodec.cpp | 43 | ||||
| -rw-r--r-- | media/libstagefright/wifi-display/source/Converter.cpp | 39 | ||||
| -rw-r--r-- | media/libstagefright/wifi-display/source/Converter.h | 2 | 
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> ¬ify); +  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> ¬ify) { +    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;  | 
