Merge "Always use an address for remote submix" into lmp-mr1-dev
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index cf18a45..c412299 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -208,8 +208,15 @@
 
     void        sendEvent(int msg, int ext1=0, int ext2=0,
                           const Parcel *obj=NULL) {
-        Mutex::Autolock autoLock(mNotifyLock);
-        if (mNotify) mNotify(mCookie, msg, ext1, ext2, obj);
+        notify_callback_f notifyCB;
+        void* cookie;
+        {
+            Mutex::Autolock autoLock(mNotifyLock);
+            notifyCB = mNotify;
+            cookie = mCookie;
+        }
+
+        if (notifyCB) notifyCB(cookie, msg, ext1, ext2, obj);
     }
 
     virtual status_t dump(int fd, const Vector<String16> &args) const {
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
index c146b8d..f91e3e4 100644
--- a/media/libmedia/Visualizer.cpp
+++ b/media/libmedia/Visualizer.cpp
@@ -52,6 +52,13 @@
 
 Visualizer::~Visualizer()
 {
+    ALOGV("Visualizer::~Visualizer()");
+    if (mCaptureThread != NULL) {
+        mCaptureThread->requestExitAndWait();
+        mCaptureThread.clear();
+    }
+    mCaptureCallBack = NULL;
+    mCaptureFlags = 0;
 }
 
 status_t Visualizer::setEnabled(bool enabled)
@@ -102,20 +109,18 @@
         return INVALID_OPERATION;
     }
 
-    sp<CaptureThread> t = mCaptureThread;
-    if (t != 0) {
-        t->mLock.lock();
+    if (mCaptureThread != 0) {
+        mCaptureLock.unlock();
+        mCaptureThread->requestExitAndWait();
+        mCaptureLock.lock();
     }
+
     mCaptureThread.clear();
     mCaptureCallBack = cbk;
     mCaptureCbkUser = user;
     mCaptureFlags = flags;
     mCaptureRate = rate;
 
-    if (t != 0) {
-        t->mLock.unlock();
-    }
-
     if (cbk != NULL) {
         mCaptureThread = new CaptureThread(*this, rate, ((flags & CAPTURE_CALL_JAVA) != 0));
     }
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 8eb1269..c120898 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -2159,7 +2159,6 @@
     {
     case MEDIA_ERROR:
         ALOGE("Error %d, %d occurred", ext1, ext2);
-        p->mError = ext1;
         break;
     case MEDIA_PREPARED:
         ALOGV("prepared");
@@ -2174,6 +2173,9 @@
 
     // wake up thread
     Mutex::Autolock lock(p->mLock);
+    if (msg == MEDIA_ERROR) {
+        p->mError = ext1;
+    }
     p->mCommandComplete = true;
     p->mSignal.signal();
 }
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index a63a940..4a9d790 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1119,7 +1119,7 @@
     // Current code will just make that we select deep buffer
     // with video which should not be a problem as it should
     // not prevent from keeping A/V sync.
-    if (hasVideo &&
+    if (!hasVideo &&
             mSource->getDuration(&durationUs) == OK &&
             durationUs
                 > AUDIO_SINK_MIN_DEEP_BUFFER_DURATION_US) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 86ce385..e0c5e18 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -1374,8 +1374,9 @@
                 return offloadingAudio();
             }
             ALOGV("openAudioSink: try to open AudioSink in offload mode");
-            flags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
-            flags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+            uint32_t offloadFlags = flags;
+            offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+            offloadFlags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
             audioSinkChanged = true;
             mAudioSink->close();
             err = mAudioSink->open(
@@ -1386,7 +1387,7 @@
                     8 /* bufferCount */,
                     &NuPlayer::Renderer::AudioSinkCallback,
                     this,
-                    (audio_output_flags_t)flags,
+                    (audio_output_flags_t)offloadFlags,
                     &offloadInfo);
 
             if (err == OK) {
@@ -1410,9 +1411,9 @@
         }
     }
     if (!offloadOnly && !offloadingAudio()) {
-        flags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
         ALOGV("openAudioSink: open AudioSink in NON-offload mode");
-
+        uint32_t pcmFlags = flags;
+        pcmFlags &= ~AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
         audioSinkChanged = true;
         mAudioSink->close();
         mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
@@ -1424,7 +1425,7 @@
                     8 /* bufferCount */,
                     NULL,
                     NULL,
-                    (audio_output_flags_t)flags),
+                    (audio_output_flags_t)pcmFlags),
                  (status_t)OK);
         mAudioSink->start();
     }
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 2f2f9cf..0e9d734 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -2221,7 +2221,11 @@
 
     video_def->xFramerate = (OMX_U32)(frameRate * 65536.0f);
     video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
-    video_def->eColorFormat = colorFormat;
+    // this is redundant as it was already set up in setVideoPortFormatType
+    // FIXME for now skip this only for flexible YUV formats
+    if (colorFormat != OMX_COLOR_FormatYUV420Flexible) {
+        video_def->eColorFormat = colorFormat;
+    }
 
     err = mOMX->setParameter(
             mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
diff --git a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
index ed3dca0..bb55871 100644
--- a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
@@ -575,9 +575,13 @@
                     &editPortInfo(0)->mDef;
                 portDef->format.video.nFrameWidth = mVideoWidth;
                 portDef->format.video.nFrameHeight = mVideoHeight;
+                portDef->format.video.nStride = portDef->format.video.nFrameWidth;
+                portDef->format.video.nSliceHeight = portDef->format.video.nFrameHeight;
                 portDef->format.video.xFramerate = def->format.video.xFramerate;
                 portDef->format.video.eColorFormat =
                     (OMX_COLOR_FORMATTYPE) mVideoColorFormat;
+                portDef->nBufferSize =
+                    (portDef->format.video.nStride * portDef->format.video.nSliceHeight * 3) / 2;
                 portDef = &editPortInfo(1)->mDef;
                 portDef->format.video.nFrameWidth = mVideoWidth;
                 portDef->format.video.nFrameHeight = mVideoHeight;
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index c87d19c..400f320 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -462,9 +462,13 @@
                     &editPortInfo(0)->mDef;
                 portDef->format.video.nFrameWidth = mVideoWidth;
                 portDef->format.video.nFrameHeight = mVideoHeight;
+                portDef->format.video.nStride = portDef->format.video.nFrameWidth;
+                portDef->format.video.nSliceHeight = portDef->format.video.nFrameHeight;
                 portDef->format.video.xFramerate = def->format.video.xFramerate;
                 portDef->format.video.eColorFormat =
                     (OMX_COLOR_FORMATTYPE) mVideoColorFormat;
+                portDef->nBufferSize =
+                    (portDef->format.video.nStride * portDef->format.video.nSliceHeight * 3) / 2;
                 portDef = &editPortInfo(1)->mDef;
                 portDef->format.video.nFrameWidth = mVideoWidth;
                 portDef->format.video.nFrameHeight = mVideoHeight;
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index eb621d5..0285feb 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -805,8 +805,12 @@
         OMX_PARAM_PORTDEFINITIONTYPE *def = &editPortInfo(kInputPortIndex)->mDef;
         def->format.video.nFrameWidth = mWidth;
         def->format.video.nFrameHeight = mHeight;
+        def->format.video.nStride = def->format.video.nFrameWidth;
+        def->format.video.nSliceHeight = def->format.video.nFrameHeight;
         def->format.video.xFramerate = mFramerate;
         def->format.video.eColorFormat = mColorFormat;
+        def->nBufferSize =
+            (def->format.video.nStride * def->format.video.nSliceHeight * 3) / 2;
         def = &editPortInfo(kOutputPortIndex)->mDef;
         def->format.video.nFrameWidth = mWidth;
         def->format.video.nFrameHeight = mHeight;
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index bd22e42..5567800 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -4377,11 +4377,15 @@
     muteWaitMs = checkDeviceMuteStrategies(outputDesc, prevDevice, delayMs);
 
     // Do not change the routing if:
-    //  - the requested device is AUDIO_DEVICE_NONE
-    //  - the requested device is the same as current device and force is not specified.
+    //      the requested device is AUDIO_DEVICE_NONE
+    //      OR the requested device is the same as current device
+    //  AND force is not specified
+    //  AND the output is connected by a valid audio patch.
     // Doing this check here allows the caller to call setOutputDevice() without conditions
-    if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force) {
-        ALOGV("setOutputDevice() setting same device %04x or null device for output %d", device, output);
+    if ((device == AUDIO_DEVICE_NONE || device == prevDevice) && !force &&
+            outputDesc->mPatchHandle != 0) {
+        ALOGV("setOutputDevice() setting same device %04x or null device for output %d",
+              device, output);
         return muteWaitMs;
     }