Merge "audioflinger: fix effect problem during underrun" into jb-dev
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 7fb395e..baabd37 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -3648,7 +3648,7 @@
 }
 
 status_t OMXCodec::stop() {
-    CODEC_LOGV("stop mState=%d", mState);
+    CODEC_LOGI("stop mState=%d", mState);
 
     Mutex::Autolock autoLock(mLock);
 
@@ -3748,9 +3748,10 @@
         mLeftOverBuffer = NULL;
     }
 
+    CODEC_LOGI("stopping in state %d", mState);
     mSource->stop();
 
-    CODEC_LOGV("stopped in state %d", mState);
+    CODEC_LOGI("stopped in state %d", mState);
 
     return OK;
 }
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 791445c..ff95f9f 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -293,12 +293,18 @@
         info->mOwnedByUs = false;
         notifyEmptyBufferDone(header);
 
-        maybeConfigureDownmix();
-        ALOGI("Initially configuring decoder: %d Hz, %d channels",
-              mStreamInfo->sampleRate,
-              mStreamInfo->numChannels);
-        notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
-        mOutputPortSettingsChange = AWAITING_DISABLED;
+        // Only send out port settings changed event if both sample rate
+        // and numChannels are valid.
+        if (mStreamInfo->sampleRate && mStreamInfo->numChannels) {
+            maybeConfigureDownmix();
+            ALOGI("Initially configuring decoder: %d Hz, %d channels",
+                mStreamInfo->sampleRate,
+                mStreamInfo->numChannels);
+
+            notify(OMX_EventPortSettingsChanged, 1, 0, NULL);
+            mOutputPortSettingsChange = AWAITING_DISABLED;
+        }
+
         return;
     }
 
@@ -416,6 +422,9 @@
                                                 outHeader->nAllocLen,
                                                 0 /* flags */);
 
+            if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
+                ALOGW("Not enough bits, bytesValid %d", bytesValid[0]);
+            }
         }
 
         /*
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 92d1223..bf07f8b 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -410,6 +410,7 @@
 status_t CameraService::Client::lock() {
     int callingPid = getCallingPid();
     LOG1("lock (pid %d)", callingPid);
+    Mutex::Autolock ilock(mICameraLock);
     Mutex::Autolock lock(mLock);
 
     // lock camera to this client if the the camera is unlocked
@@ -425,6 +426,7 @@
 status_t CameraService::Client::unlock() {
     int callingPid = getCallingPid();
     LOG1("unlock (pid %d)", callingPid);
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
 
     // allow anyone to use camera (after they lock the camera)
@@ -447,6 +449,7 @@
 status_t CameraService::Client::connect(const sp<ICameraClient>& client) {
     int callingPid = getCallingPid();
     LOG1("connect E (pid %d)", callingPid);
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
 
     if (mClientPid != 0 && checkPid() != NO_ERROR) {
@@ -482,6 +485,7 @@
 void CameraService::Client::disconnect() {
     int callingPid = getCallingPid();
     LOG1("disconnect E (pid %d)", callingPid);
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
 
     if (checkPid() != NO_ERROR) {
@@ -526,6 +530,7 @@
 
 status_t CameraService::Client::setPreviewWindow(const sp<IBinder>& binder,
         const sp<ANativeWindow>& window) {
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
     if (result != NO_ERROR) return result;
@@ -597,6 +602,7 @@
 // preview are handled.
 void CameraService::Client::setPreviewCallbackFlag(int callback_flag) {
     LOG1("setPreviewCallbackFlag(%d) (pid %d)", callback_flag, getCallingPid());
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) return;
 
@@ -623,6 +629,7 @@
 // start preview or recording
 status_t CameraService::Client::startCameraMode(camera_mode mode) {
     LOG1("startCameraMode(%d)", mode);
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
     if (result != NO_ERROR) return result;
@@ -696,6 +703,7 @@
 // stop preview mode
 void CameraService::Client::stopPreview() {
     LOG1("stopPreview (pid %d)", getCallingPid());
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) return;
 
@@ -709,6 +717,7 @@
 // stop recording mode
 void CameraService::Client::stopRecording() {
     LOG1("stopRecording (pid %d)", getCallingPid());
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) return;
 
@@ -721,6 +730,7 @@
 
 // release a recording frame
 void CameraService::Client::releaseRecordingFrame(const sp<IMemory>& mem) {
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) return;
     mHardware->releaseRecordingFrame(mem);
@@ -729,6 +739,7 @@
 status_t CameraService::Client::storeMetaDataInBuffers(bool enabled)
 {
     LOG1("storeMetaDataInBuffers: %s", enabled? "true": "false");
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) {
         return UNKNOWN_ERROR;
@@ -739,6 +750,7 @@
 bool CameraService::Client::previewEnabled() {
     LOG1("previewEnabled (pid %d)", getCallingPid());
 
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) return false;
     return mHardware->previewEnabled();
@@ -747,6 +759,7 @@
 bool CameraService::Client::recordingEnabled() {
     LOG1("recordingEnabled (pid %d)", getCallingPid());
 
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) return false;
     return mHardware->recordingEnabled();
@@ -755,6 +768,7 @@
 status_t CameraService::Client::autoFocus() {
     LOG1("autoFocus (pid %d)", getCallingPid());
 
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
     if (result != NO_ERROR) return result;
@@ -765,6 +779,7 @@
 status_t CameraService::Client::cancelAutoFocus() {
     LOG1("cancelAutoFocus (pid %d)", getCallingPid());
 
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
     if (result != NO_ERROR) return result;
@@ -776,26 +791,30 @@
 status_t CameraService::Client::takePicture(int msgType) {
     LOG1("takePicture (pid %d): 0x%x", getCallingPid(), msgType);
 
-    Mutex::Autolock lock(mLock);
-    status_t result = checkPidAndHardware();
-    if (result != NO_ERROR) return result;
+    Mutex::Autolock iLock(mICameraLock);
+    int picMsgType = 0;
+    { // scope for lock
+        Mutex::Autolock lock(mLock);
+        status_t result = checkPidAndHardware();
+        if (result != NO_ERROR) return result;
 
-    if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
-        (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
-        ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
-                " cannot be both enabled");
-        return BAD_VALUE;
+        if ((msgType & CAMERA_MSG_RAW_IMAGE) &&
+                (msgType & CAMERA_MSG_RAW_IMAGE_NOTIFY)) {
+            ALOGE("CAMERA_MSG_RAW_IMAGE and CAMERA_MSG_RAW_IMAGE_NOTIFY"
+                    " cannot be both enabled");
+            return BAD_VALUE;
+        }
+
+        // We only accept picture related message types
+        // and ignore other types of messages for takePicture().
+        picMsgType = msgType
+                & (CAMERA_MSG_SHUTTER |
+                        CAMERA_MSG_POSTVIEW_FRAME |
+                        CAMERA_MSG_RAW_IMAGE |
+                        CAMERA_MSG_RAW_IMAGE_NOTIFY |
+                        CAMERA_MSG_COMPRESSED_IMAGE);
+
     }
-
-    // We only accept picture related message types
-    // and ignore other types of messages for takePicture().
-    int picMsgType = msgType
-                        & (CAMERA_MSG_SHUTTER |
-                           CAMERA_MSG_POSTVIEW_FRAME |
-                           CAMERA_MSG_RAW_IMAGE |
-                           CAMERA_MSG_RAW_IMAGE_NOTIFY |
-                           CAMERA_MSG_COMPRESSED_IMAGE);
-
     enableMsgType(picMsgType);
 
     return mHardware->takePicture();
@@ -805,6 +824,7 @@
 status_t CameraService::Client::setParameters(const String8& params) {
     LOG1("setParameters (pid %d) (%s)", getCallingPid(), params.string());
 
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
     if (result != NO_ERROR) return result;
@@ -815,6 +835,7 @@
 
 // get preview/capture parameters - key/value pairs
 String8 CameraService::Client::getParameters() const {
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     if (checkPidAndHardware() != NO_ERROR) return String8();
 
@@ -855,6 +876,7 @@
 status_t CameraService::Client::sendCommand(int32_t cmd, int32_t arg1, int32_t arg2) {
     LOG1("sendCommand (pid %d)", getCallingPid());
     int orientation;
+    Mutex::Autolock iLock(mICameraLock);
     Mutex::Autolock lock(mLock);
     status_t result = checkPidAndHardware();
     if (result != NO_ERROR) return result;
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index 5b63399..95ac197 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -190,6 +190,11 @@
 
         // Ensures atomicity among the public methods
         mutable Mutex                   mLock;
+        // A lock to synchronize access through the ICamera binder
+        // interface. The entire binder call should be done with mICameraLock
+        // locked, to serialize ICamera access, even when mLock is disabled for
+        // calls to the HAL.
+        mutable Mutex                   mICameraLock;
         // This is a binder of Surface or SurfaceTexture.
         sp<IBinder>                     mSurface;
         sp<ANativeWindow>               mPreviewWindow;