am 805b3ae3: Merge "Now back to 30fps, suspend updates if surface flinger didn\'t send us" into jb-mr1-dev

* commit '805b3ae300ea414ce5973e60a9b544169da0ac44':
  Now back to 30fps, suspend updates if surface flinger didn't send us
diff --git a/media/libstagefright/wifi-display/source/Converter.cpp b/media/libstagefright/wifi-display/source/Converter.cpp
index a5fb6b8..b9539e9 100644
--- a/media/libstagefright/wifi-display/source/Converter.cpp
+++ b/media/libstagefright/wifi-display/source/Converter.cpp
@@ -132,7 +132,7 @@
         mOutputFormat->setInt32("bitrate", audioBitrate);
     } else {
         mOutputFormat->setInt32("bitrate", videoBitrate);
-        mOutputFormat->setInt32("frame-rate", 60);
+        mOutputFormat->setInt32("frame-rate", 30);
         mOutputFormat->setInt32("i-frame-interval", 1);  // Iframes every 1 secs
         mOutputFormat->setInt32("prepend-sps-pps-to-idr-frames", 1);
     }
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.cpp b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
index 4ae9895..c91b4c8 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.cpp
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.cpp
@@ -64,6 +64,8 @@
           const sp<MediaPuller> &mediaPuller,
           const sp<Converter> &converter);
 
+    void setRepeaterSource(const sp<RepeaterSource> &source);
+
     sp<AMessage> getFormat();
     bool isAudio() const;
 
@@ -78,6 +80,8 @@
     void queueAccessUnit(const sp<ABuffer> &accessUnit);
     sp<ABuffer> dequeueAccessUnit();
 
+    void requestIDRFrame();
+
 protected:
     virtual void onMessageReceived(const sp<AMessage> &msg);
     virtual ~Track();
@@ -96,6 +100,7 @@
     ssize_t mPacketizerTrackIndex;
     bool mIsAudio;
     List<sp<ABuffer> > mQueuedAccessUnits;
+    sp<RepeaterSource> mRepeaterSource;
 
     static bool IsAudioFormat(const sp<AMessage> &format);
 
@@ -178,6 +183,11 @@
     sp<AMessage> msg = new AMessage(kWhatMediaPullerStopped, id());
 
     if (mStarted && mMediaPuller != NULL) {
+        if (mRepeaterSource != NULL) {
+            // Let's unblock MediaPuller's MediaSource::read().
+            mRepeaterSource->wakeUp();
+        }
+
         mMediaPuller->stopAsync(msg);
     } else {
         msg->post();
@@ -224,6 +234,23 @@
     return accessUnit;
 }
 
+void WifiDisplaySource::PlaybackSession::Track::setRepeaterSource(
+        const sp<RepeaterSource> &source) {
+    mRepeaterSource = source;
+}
+
+void WifiDisplaySource::PlaybackSession::Track::requestIDRFrame() {
+    if (mIsAudio) {
+        return;
+    }
+
+    if (mRepeaterSource != NULL) {
+        mRepeaterSource->wakeUp();
+    }
+
+    mConverter->requestIDRFrame();
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 
 WifiDisplaySource::PlaybackSession::PlaybackSession(
@@ -809,7 +836,8 @@
 }
 
 status_t WifiDisplaySource::PlaybackSession::addSource(
-        bool isVideo, const sp<MediaSource> &source, size_t *numInputBuffers) {
+        bool isVideo, const sp<MediaSource> &source, bool isRepeaterSource,
+        size_t *numInputBuffers) {
     sp<ALooper> pullLooper = new ALooper;
     pullLooper->setName("pull_looper");
 
@@ -871,6 +899,10 @@
     sp<Track> track = new Track(
             notify, pullLooper, codecLooper, puller, converter);
 
+    if (isRepeaterSource) {
+        track->setRepeaterSource(static_cast<RepeaterSource *>(source.get()));
+    }
+
     looper()->registerHandler(track);
 
     mTracks.add(trackIndex, track);
@@ -887,8 +919,13 @@
 
     source->setUseAbsoluteTimestamps();
 
+    sp<RepeaterSource> videoSource =
+        new RepeaterSource(source, 30.0 /* rateHz */);
+
     size_t numInputBuffers;
-    status_t err = addSource(true /* isVideo */, source, &numInputBuffers);
+    status_t err = addSource(
+            true /* isVideo */, videoSource, true /* isRepeaterSource */,
+            &numInputBuffers);
 
     if (err != OK) {
         return err;
@@ -910,7 +947,8 @@
 
     if (audioSource->initCheck() == OK) {
         return addSource(
-                false /* isVideo */, audioSource, NULL /* numInputBuffers */);
+                false /* isVideo */, audioSource, false /* isRepeaterSource */,
+                NULL /* numInputBuffers */);
     }
 
     ALOGW("Unable to instantiate audio source");
@@ -1300,7 +1338,7 @@
     for (size_t i = 0; i < mTracks.size(); ++i) {
         const sp<Track> &track = mTracks.valueAt(i);
 
-        track->converter()->requestIDRFrame();
+        track->requestIDRFrame();
     }
 }
 
diff --git a/media/libstagefright/wifi-display/source/PlaybackSession.h b/media/libstagefright/wifi-display/source/PlaybackSession.h
index 3bdb223..5d4bde8 100644
--- a/media/libstagefright/wifi-display/source/PlaybackSession.h
+++ b/media/libstagefright/wifi-display/source/PlaybackSession.h
@@ -185,6 +185,7 @@
     status_t addSource(
             bool isVideo,
             const sp<MediaSource> &source,
+            bool isRepeaterSource,
             size_t *numInputBuffers);
 
     status_t addVideoSource();
diff --git a/media/libstagefright/wifi-display/source/RepeaterSource.cpp b/media/libstagefright/wifi-display/source/RepeaterSource.cpp
index dc216e8..641e63f 100644
--- a/media/libstagefright/wifi-display/source/RepeaterSource.cpp
+++ b/media/libstagefright/wifi-display/source/RepeaterSource.cpp
@@ -18,6 +18,7 @@
       mRateHz(rateHz),
       mBuffer(NULL),
       mResult(OK),
+      mLastBufferUpdateUs(-1ll),
       mStartTimeUs(-1ll),
       mFrameCount(0) {
 }
@@ -91,39 +92,60 @@
     ReadOptions::SeekMode seekMode;
     CHECK(options == NULL || !options->getSeekTo(&seekTimeUs, &seekMode));
 
-    int64_t bufferTimeUs = -1ll;
+    for (;;) {
+        int64_t bufferTimeUs = -1ll;
 
-    if (mStartTimeUs < 0ll) {
-        Mutex::Autolock autoLock(mLock);
-        while (mBuffer == NULL && mResult == OK) {
-            mCondition.wait(mLock);
+        if (mStartTimeUs < 0ll) {
+            Mutex::Autolock autoLock(mLock);
+            while ((mLastBufferUpdateUs < 0ll || mBuffer == NULL)
+                    && mResult == OK) {
+                mCondition.wait(mLock);
+            }
+
+            ALOGV("now resuming.");
+            mStartTimeUs = ALooper::GetNowUs();
+            bufferTimeUs = mStartTimeUs;
+        } else {
+            bufferTimeUs = mStartTimeUs + (mFrameCount * 1000000ll) / mRateHz;
+
+            int64_t nowUs = ALooper::GetNowUs();
+            int64_t delayUs = bufferTimeUs - nowUs;
+
+            if (delayUs > 0ll) {
+                usleep(delayUs);
+            }
         }
 
-        mStartTimeUs = ALooper::GetNowUs();
-        bufferTimeUs = mStartTimeUs;
-    } else {
-        bufferTimeUs = mStartTimeUs + (mFrameCount * 1000000ll) / mRateHz;
+        bool stale = false;
 
-        int64_t nowUs = ALooper::GetNowUs();
-        int64_t delayUs = bufferTimeUs - nowUs;
+        {
+            Mutex::Autolock autoLock(mLock);
+            if (mResult != OK) {
+                CHECK(mBuffer == NULL);
+                return mResult;
+            }
 
-        if (delayUs > 0ll) {
-            usleep(delayUs);
+            int64_t nowUs = ALooper::GetNowUs();
+            if (nowUs - mLastBufferUpdateUs > 1000000ll) {
+                mLastBufferUpdateUs = -1ll;
+                stale = true;
+            } else {
+                mBuffer->add_ref();
+                *buffer = mBuffer;
+                (*buffer)->meta_data()->setInt64(kKeyTime, bufferTimeUs);
+                ++mFrameCount;
+            }
         }
+
+        if (!stale) {
+            break;
+        }
+
+        mStartTimeUs = -1ll;
+        mFrameCount = 0;
+        ALOGV("now dormant");
     }
 
-    Mutex::Autolock autoLock(mLock);
-    if (mResult != OK) {
-        CHECK(mBuffer == NULL);
-        return mResult;
-    }
-
-    mBuffer->add_ref();
-    *buffer = mBuffer;
-    (*buffer)->meta_data()->setInt64(kKeyTime, bufferTimeUs);
-
-    ++mFrameCount;
-
     return OK;
 }
 
@@ -147,6 +169,7 @@
             }
             mBuffer = buffer;
             mResult = err;
+            mLastBufferUpdateUs = ALooper::GetNowUs();
 
             mCondition.broadcast();
 
@@ -161,4 +184,13 @@
     }
 }
 
+void RepeaterSource::wakeUp() {
+    ALOGV("wakeUp");
+    Mutex::Autolock autoLock(mLock);
+    if (mLastBufferUpdateUs < 0ll && mBuffer != NULL) {
+        mLastBufferUpdateUs = ALooper::GetNowUs();
+        mCondition.broadcast();
+    }
+}
+
 }  // namespace android
diff --git a/media/libstagefright/wifi-display/source/RepeaterSource.h b/media/libstagefright/wifi-display/source/RepeaterSource.h
index 3049362..e4aa2b6 100644
--- a/media/libstagefright/wifi-display/source/RepeaterSource.h
+++ b/media/libstagefright/wifi-display/source/RepeaterSource.h
@@ -22,6 +22,10 @@
 
     void onMessageReceived(const sp<AMessage> &msg);
 
+    // If RepeaterSource is currently dormant, because SurfaceFlinger didn't
+    // send updates in a while, this is its wakeup call.
+    void wakeUp();
+
 protected:
     virtual ~RepeaterSource();
 
@@ -43,6 +47,7 @@
 
     MediaBuffer *mBuffer;
     status_t mResult;
+    int64_t mLastBufferUpdateUs;
 
     int64_t mStartTimeUs;
     int32_t mFrameCount;
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 1083a80..b0aaf3b 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -539,7 +539,7 @@
     //   use "78 00 02 02 00008000 00000000 00000000 00 0000 0000 00 none none\r\n"
     AString body = StringPrintf(
         "wfd_video_formats: "
-        "30 00 02 02 00000040 00000000 00000000 00 0000 0000 00 none none\r\n"
+        "28 00 02 02 00000020 00000000 00000000 00 0000 0000 00 none none\r\n"
         "wfd_audio_codecs: AAC 00000001 00\r\n"  // 2 ch AAC 48kHz
         "wfd_presentation_URL: rtsp://%s/wfd1.0/streamid=0 none\r\n"
         "wfd_client_rtp_ports: RTP/AVP/%s;unicast 19000 0 mode=play\r\n",