Fall back to s/w decoding when audio offloading fails.

Change-Id: Icde3d65c964b2a13fb1c6636adcce52ae048a3fb
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 8592ec2..3640038 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -223,6 +223,12 @@
             break;
         }
 
+        case kWhatAudioOffloadTearDown:
+        {
+            onAudioOffloadTearDown();
+            break;
+        }
+
         default:
             TRESPASS();
             break;
@@ -294,7 +300,7 @@
 
         case MediaPlayerBase::AudioSink::CB_EVENT_TEAR_DOWN:
         {
-            // TODO: send this to player.
+            me->notifyAudioOffloadTearDown();
             break;
         }
     }
@@ -582,6 +588,10 @@
     notify->post();
 }
 
+void NuPlayer::Renderer::notifyAudioOffloadTearDown() {
+    (new AMessage(kWhatAudioOffloadTearDown, id()))->post();
+}
+
 void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
     int32_t audio;
     CHECK(msg->findInt32("audio", &audio));
@@ -814,6 +824,7 @@
 void NuPlayer::Renderer::onDisableOffloadAudio() {
     Mutex::Autolock autoLock(mLock);
     mFlags &= ~FLAG_OFFLOAD_AUDIO;
+    ++mAudioQueueGeneration;
 }
 
 void NuPlayer::Renderer::notifyPosition() {
@@ -880,5 +891,21 @@
     }
 }
 
+void NuPlayer::Renderer::onAudioOffloadTearDown() {
+    uint32_t numFramesPlayed;
+    CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
+
+    int64_t currentPositionUs = mFirstAudioTimeUs
+            + (numFramesPlayed * mAudioSink->msecsPerFrame()) * 1000ll;
+
+    mAudioSink->stop();
+    mAudioSink->flush();
+
+    sp<AMessage> notify = mNotify->dup();
+    notify->setInt32("what", kWhatAudioOffloadTearDown);
+    notify->setInt64("positionUs", currentPositionUs);
+    notify->post();
+}
+
 }  // namespace android