Merge "Revert "handle case OMX_AUDIO_CodingG711 in ACodec::getPortFormat"" into lmp-dev
diff --git a/include/private/media/VideoFrame.h b/include/private/media/VideoFrame.h
index 5dd425b..5193d00 100644
--- a/include/private/media/VideoFrame.h
+++ b/include/private/media/VideoFrame.h
@@ -63,8 +63,11 @@
     uint32_t mDisplayWidth;
     uint32_t mDisplayHeight;
     uint32_t mSize;            // Number of bytes in mData
+    int32_t  mRotationAngle;   // rotation angle, clockwise, should be multiple of 90
+    // mData should be 64 bit aligned to prevent additional padding
     uint8_t* mData;            // Actual binary data
-    int32_t  mRotationAngle;   // rotation angle, clockwise
+    // pad structure so it's the same size on 64 bit and 32 bit
+    char     mPadding[8 - sizeof(mData)];
 };
 
 }; // namespace android
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index e3beba5..8e0704f 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -2244,6 +2244,9 @@
             return true;
         }
     }
+    if (exitPending()) {
+        return false;
+    }
     nsecs_t ns = mReceiver.processAudioBuffer();
     switch (ns) {
     case 0:
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index d6bf1de..e5c64f6 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -72,6 +72,7 @@
       mHasVideo(false),
       mSyncQueues(false),
       mPaused(false),
+      mPauseStartedTimeRealUs(-1),
       mVideoSampleReceived(false),
       mVideoRenderingStarted(false),
       mVideoRenderingStartGeneration(0),
@@ -574,7 +575,9 @@
             if (!mHasAudio) {
                 mAnchorTimeMediaUs = mediaTimeUs;
                 mAnchorTimeRealUs = nowUs;
-                notifyPosition();
+                if (!mPaused || mVideoSampleReceived) {
+                    notifyPosition();
+                }
             }
             realTimeUs = nowUs;
         } else {
@@ -645,6 +648,10 @@
         }
     } else {
         mVideoLateByUs = 0ll;
+        if (!mHasAudio && !mVideoSampleReceived) {
+            mAnchorTimeMediaUs = -1;
+            mAnchorTimeRealUs = -1;
+        }
     }
 
     entry->mNotifyConsumed->setInt64("timestampNs", realTimeUs * 1000ll);
@@ -830,6 +837,9 @@
     {
          Mutex::Autolock autoLock(mLock);
          syncQueuesDone_l();
+         if (!mHasAudio) {
+             mPauseStartedTimeRealUs = -1;
+         }
     }
 
     ALOGV("flushing %s", audio ? "audio" : "video");
@@ -980,6 +990,9 @@
         ++mVideoQueueGeneration;
         prepareForMediaRenderingStart();
         mPaused = true;
+        if (!mHasAudio) {
+            mPauseStartedTimeRealUs = ALooper::GetNowUs();
+        }
     }
 
     mDrainAudioQueuePending = false;
@@ -1008,6 +1021,10 @@
 
     Mutex::Autolock autoLock(mLock);
     mPaused = false;
+    if (!mHasAudio && mPauseStartedTimeRealUs != -1) {
+        mAnchorTimeRealUs += ALooper::GetNowUs() - mPauseStartedTimeRealUs;
+        mPauseStartedTimeRealUs = -1;
+    }
 
     if (!mAudioQueue.empty()) {
         postDrainAudioQueue_l();
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index 4237902..d27c238 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -130,6 +130,7 @@
     bool mSyncQueues;
 
     bool mPaused;
+    int64_t mPauseStartedTimeRealUs;
     bool mVideoSampleReceived;
     bool mVideoRenderingStarted;
     int32_t mVideoRenderingStartGeneration;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index b568063..5f55484 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -780,7 +780,9 @@
                                 // STOPPING->UNINITIALIZED, instead of the
                                 // usual STOPPING->INITIALIZED state.
                                 setState(UNINITIALIZED);
-
+                                if (mState == RELEASING) {
+                                    mComponentName.clear();
+                                }
                                 (new AMessage)->postReply(mReplyID);
                             }
                             break;
@@ -1046,7 +1048,9 @@
                     }
 
                     if (mFlags & kFlagIsAsync) {
-                        onInputBufferAvailable();
+                        if (!mHaveInputSurface) {
+                            onInputBufferAvailable();
+                        }
                     } else if (mFlags & kFlagDequeueInputPending) {
                         CHECK(handleDequeueInputBuffer(mDequeueInputReplyID));
 
@@ -1130,6 +1134,7 @@
                     } else {
                         CHECK_EQ(mState, RELEASING);
                         setState(UNINITIALIZED);
+                        mComponentName.clear();
                     }
 
                     (new AMessage)->postReply(mReplyID);
@@ -1339,12 +1344,12 @@
                 // after stop() returned, it would be safe to call release()
                 // and it should be in this case, no harm to allow a release()
                 // if we're already uninitialized.
-                // Similarly stopping a stopped MediaCodec should be benign.
                 sp<AMessage> response = new AMessage;
-                response->setInt32(
-                        "err",
-                        mState == targetState ? OK : INVALID_OPERATION);
-
+                status_t err = mState == targetState ? OK : INVALID_OPERATION;
+                response->setInt32("err", err);
+                if (err == OK && targetState == UNINITIALIZED) {
+                    mComponentName.clear();
+                }
                 response->postReply(replyID);
                 break;
             }
@@ -1353,6 +1358,9 @@
                 // It's dead, Jim. Don't expect initiateShutdown to yield
                 // any useful results now...
                 setState(UNINITIALIZED);
+                if (targetState == UNINITIALIZED) {
+                    mComponentName.clear();
+                }
                 (new AMessage)->postReply(replyID);
                 break;
             }
@@ -1745,8 +1753,6 @@
         // return any straggling buffers, e.g. if we got here on an error
         returnBuffersToCodec();
 
-        mComponentName.clear();
-
         // The component is gone, mediaserver's probably back up already
         // but should definitely be back up should we try to instantiate
         // another component.. and the cycle continues.
diff --git a/services/audiopolicy/AudioPolicyService.cpp b/services/audiopolicy/AudioPolicyService.cpp
index 4761a13..06a7e84 100644
--- a/services/audiopolicy/AudioPolicyService.cpp
+++ b/services/audiopolicy/AudioPolicyService.cpp
@@ -61,6 +61,10 @@
     : BnAudioPolicyService(), mpAudioPolicyDev(NULL), mpAudioPolicy(NULL),
       mAudioPolicyManager(NULL), mAudioPolicyClient(NULL), mPhoneState(AUDIO_MODE_INVALID)
 {
+}
+
+void AudioPolicyService::onFirstRef()
+{
     char value[PROPERTY_VALUE_MAX];
     const struct hw_module_t *module;
     int forced_val;
diff --git a/services/audiopolicy/AudioPolicyService.h b/services/audiopolicy/AudioPolicyService.h
index 2cea40b..4e68ab1 100644
--- a/services/audiopolicy/AudioPolicyService.h
+++ b/services/audiopolicy/AudioPolicyService.h
@@ -134,6 +134,9 @@
     // IBinder::DeathRecipient
     virtual     void        binderDied(const wp<IBinder>& who);
 
+    // RefBase
+    virtual     void        onFirstRef();
+
     //
     // Helpers for the struct audio_policy_service_ops implementation.
     // This is used by the audio policy manager for certain operations that