Merge "NuPlayer: add pause timeout event for offload audio." into lmp-dev
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index a8c8818..73ac057 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -32,6 +32,10 @@
 
 namespace android {
 
+// Maximum time in paused state when offloading audio decompression. When elapsed, the AudioSink
+// is closed to allow the audio DSP to power down.
+static const int64_t kOffloadPauseMaxUs = 60000000ll;
+
 // static
 const int64_t NuPlayer::Renderer::kMinPositionUpdateDelayUs = 100000ll;
 
@@ -61,7 +65,9 @@
       mVideoRenderingStartGeneration(0),
       mAudioRenderingStartGeneration(0),
       mLastPositionUpdateUs(-1ll),
-      mVideoLateByUs(0ll) {
+      mVideoLateByUs(0ll),
+      mAudioOffloadPauseTimeoutGeneration(0),
+      mAudioOffloadTornDown(false) {
 }
 
 NuPlayer::Renderer::~Renderer() {
@@ -259,6 +265,17 @@
             break;
         }
 
+        case kWhatAudioOffloadPauseTimeout:
+        {
+            int32_t generation;
+            CHECK(msg->findInt32("generation", &generation));
+            if (generation != mAudioOffloadPauseTimeoutGeneration) {
+                break;
+            }
+            onAudioOffloadTearDown();
+            break;
+        }
+
         default:
             TRESPASS();
             break;
@@ -951,6 +968,7 @@
 
     if (mHasAudio) {
         mAudioSink->pause();
+        startAudioOffloadPauseTimeout();
     }
 
     ALOGV("now paused audio queue has %d entries, video has %d entries",
@@ -963,6 +981,7 @@
     }
 
     if (mHasAudio) {
+        cancelAudioOffloadPauseTimeout();
         mAudioSink->start();
     }
 
@@ -1051,6 +1070,11 @@
 }
 
 void NuPlayer::Renderer::onAudioOffloadTearDown() {
+    if (mAudioOffloadTornDown) {
+        return;
+    }
+    mAudioOffloadTornDown = true;
+
     int64_t firstAudioTimeUs;
     {
         Mutex::Autolock autoLock(mLock);
@@ -1069,5 +1093,19 @@
     notify->post();
 }
 
+void NuPlayer::Renderer::startAudioOffloadPauseTimeout() {
+    if (offloadingAudio()) {
+        sp<AMessage> msg = new AMessage(kWhatAudioOffloadPauseTimeout, id());
+        msg->setInt32("generation", mAudioOffloadPauseTimeoutGeneration);
+        msg->post(kOffloadPauseMaxUs);
+    }
+}
+
+void NuPlayer::Renderer::cancelAudioOffloadPauseTimeout() {
+    if (offloadingAudio()) {
+        ++mAudioOffloadPauseTimeoutGeneration;
+    }
+}
+
 }  // namespace android
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index e28071f..8e6112b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -66,6 +66,7 @@
         kWhatVideoRenderingStart = 'vdrd',
         kWhatMediaRenderingStart = 'mdrd',
         kWhatAudioOffloadTearDown = 'aOTD',
+        kWhatAudioOffloadPauseTimeout = 'aOPT',
     };
 
 protected:
@@ -132,6 +133,9 @@
     int64_t mLastPositionUpdateUs;
     int64_t mVideoLateByUs;
 
+    int32_t mAudioOffloadPauseTimeoutGeneration;
+    bool mAudioOffloadTornDown;
+
     size_t fillAudioBuffer(void *buffer, size_t size);
 
     bool onDrainAudioQueue();
@@ -168,6 +172,9 @@
 
     bool offloadingAudio() const { return (mFlags & FLAG_OFFLOAD_AUDIO) != 0; }
 
+    void startAudioOffloadPauseTimeout();
+    void cancelAudioOffloadPauseTimeout();
+
     DISALLOW_EVIL_CONSTRUCTORS(Renderer);
 };