Error handling in ACodec and Nuplayer.

Codec errors (and codec not found errors) now trigger a controlled shutdown
of playback and signal errors to the MediaPlayer client.

Change-Id: I2ee23ff2a1422d05a1a21e50ecb87d7c7ab958cc
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index b06f20d..7fb141a 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -340,6 +340,11 @@
                 }
 
                 finishFlushIfPossible();
+            } else if (what == ACodec::kWhatError) {
+                LOGE("Received error from %s decoder, aborting playback.",
+                     audio ? "audio" : "video");
+
+                mRenderer->queueEOS(audio, UNKNOWN_ERROR);
             } else {
                 CHECK_EQ((int)what, (int)ACodec::kWhatDrainThisBuffer);
 
@@ -358,13 +363,24 @@
                 int32_t audio;
                 CHECK(msg->findInt32("audio", &audio));
 
+                int32_t finalResult;
+                CHECK(msg->findInt32("finalResult", &finalResult));
+
                 if (audio) {
                     mAudioEOS = true;
                 } else {
                     mVideoEOS = true;
                 }
 
-                LOGV("reached %s EOS", audio ? "audio" : "video");
+                if (finalResult == ERROR_END_OF_STREAM) {
+                    LOGV("reached %s EOS", audio ? "audio" : "video");
+                } else {
+                    LOGE("%s track encountered an error (0x%08x)",
+                         audio ? "audio" : "video", finalResult);
+
+                    notifyListener(
+                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, finalResult);
+                }
 
                 if ((mAudioEOS || mAudioDecoder == NULL)
                         && (mVideoEOS || mVideoDecoder == NULL)) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 828e008..35ed43f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -200,6 +200,22 @@
 void NuPlayer::Renderer::onDrainAudioQueue() {
 
     for (;;) {
+        if (mAudioQueue.empty()) {
+            break;
+        }
+
+        QueueEntry *entry = &*mAudioQueue.begin();
+
+        if (entry->mBuffer == NULL) {
+            // EOS
+
+            notifyEOS(true /* audio */, entry->mFinalResult);
+
+            mAudioQueue.erase(mAudioQueue.begin());
+            entry = NULL;
+            return;
+        }
+
         uint32_t numFramesPlayed;
         CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
 
@@ -213,22 +229,6 @@
             break;
         }
 
-        if (mAudioQueue.empty()) {
-            break;
-        }
-
-        QueueEntry *entry = &*mAudioQueue.begin();
-
-        if (entry->mBuffer == NULL) {
-            // EOS
-
-            notifyEOS(true /* audio */);
-
-            mAudioQueue.erase(mAudioQueue.begin());
-            entry = NULL;
-            return;
-        }
-
         if (entry->mOffset == 0) {
             int64_t mediaTimeUs;
             CHECK(entry->mBuffer->meta()->findInt64("timeUs", &mediaTimeUs));
@@ -330,7 +330,7 @@
     if (entry->mBuffer == NULL) {
         // EOS
 
-        notifyEOS(false /* audio */);
+        notifyEOS(false /* audio */, entry->mFinalResult);
 
         mVideoQueue.erase(mVideoQueue.begin());
         entry = NULL;
@@ -352,10 +352,11 @@
     notifyPosition();
 }
 
-void NuPlayer::Renderer::notifyEOS(bool audio) {
+void NuPlayer::Renderer::notifyEOS(bool audio, status_t finalResult) {
     sp<AMessage> notify = mNotify->dup();
     notify->setInt32("what", kWhatEOS);
     notify->setInt32("audio", static_cast<int32_t>(audio));
+    notify->setInt32("finalResult", finalResult);
     notify->post();
 }
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 703e971..2713031 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -111,7 +111,7 @@
     void onPause();
     void onResume();
 
-    void notifyEOS(bool audio);
+    void notifyEOS(bool audio, status_t finalResult);
     void notifyFlushComplete(bool audio);
     void notifyPosition();