Merge "Fix more potential overflows in amrwbenc" into nyc-dev
diff --git a/camera/cameraserver/cameraserver.rc b/camera/cameraserver/cameraserver.rc
index 37e2688..16d9da8 100644
--- a/camera/cameraserver/cameraserver.rc
+++ b/camera/cameraserver/cameraserver.rc
@@ -3,3 +3,4 @@
     user cameraserver
     group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct
     ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
diff --git a/drm/drmserver/drmserver.rc b/drm/drmserver/drmserver.rc
index 42f5fc8..de46fb9 100644
--- a/drm/drmserver/drmserver.rc
+++ b/drm/drmserver/drmserver.rc
@@ -2,3 +2,4 @@
     class main
     user drm
     group drm system inet drmrpc readproc
+    writepid /dev/cpuset/foreground/tasks
diff --git a/drm/libmediadrm/Android.mk b/drm/libmediadrm/Android.mk
new file mode 100644
index 0000000..6a2ed31
--- /dev/null
+++ b/drm/libmediadrm/Android.mk
@@ -0,0 +1,36 @@
+LOCAL_PATH:= $(call my-dir)
+
+#
+# libmediadrm
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	Crypto.cpp \
+	Drm.cpp \
+	DrmSessionManager.cpp \
+	SharedLibrary.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libbinder \
+	libcrypto \
+	libcutils \
+	libdl \
+	liblog \
+	libmedia \
+	libstagefright \
+	libstagefright_foundation \
+	libutils
+
+LOCAL_C_INCLUDES := \
+    libcore/include
+
+LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall
+LOCAL_CLANG := true
+
+LOCAL_MODULE:= libmediadrm
+
+include $(BUILD_SHARED_LIBRARY)
+
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libmediaplayerservice/Crypto.cpp b/drm/libmediadrm/Crypto.cpp
similarity index 99%
rename from media/libmediaplayerservice/Crypto.cpp
rename to drm/libmediadrm/Crypto.cpp
index 9165b9d..79633cb 100644
--- a/media/libmediaplayerservice/Crypto.cpp
+++ b/drm/libmediadrm/Crypto.cpp
@@ -20,9 +20,8 @@
 #include <dirent.h>
 #include <dlfcn.h>
 
-#include "Crypto.h"
-
 #include <binder/IMemory.h>
+#include <media/Crypto.h>
 #include <media/hardware/CryptoAPI.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AString.h>
diff --git a/media/libmediaplayerservice/Drm.cpp b/drm/libmediadrm/Drm.cpp
similarity index 98%
rename from media/libmediaplayerservice/Drm.cpp
rename to drm/libmediadrm/Drm.cpp
index 321ccbf..7c1f5c8 100644
--- a/media/libmediaplayerservice/Drm.cpp
+++ b/drm/libmediadrm/Drm.cpp
@@ -21,10 +21,9 @@
 #include <dirent.h>
 #include <dlfcn.h>
 
-#include "Drm.h"
-
-#include "DrmSessionClientInterface.h"
-#include "DrmSessionManager.h"
+#include <media/DrmSessionClientInterface.h>
+#include <media/DrmSessionManager.h>
+#include <media/Drm.h>
 #include <media/drm/DrmAPI.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/foundation/AString.h>
diff --git a/media/libmediaplayerservice/DrmSessionManager.cpp b/drm/libmediadrm/DrmSessionManager.cpp
similarity index 98%
rename from media/libmediaplayerservice/DrmSessionManager.cpp
rename to drm/libmediadrm/DrmSessionManager.cpp
index 641f881..a87fb9d 100644
--- a/media/libmediaplayerservice/DrmSessionManager.cpp
+++ b/drm/libmediadrm/DrmSessionManager.cpp
@@ -18,12 +18,11 @@
 #define LOG_TAG "DrmSessionManager"
 #include <utils/Log.h>
 
-#include "DrmSessionManager.h"
-
-#include "DrmSessionClientInterface.h"
 #include <binder/IPCThreadState.h>
 #include <binder/IProcessInfoService.h>
 #include <binder/IServiceManager.h>
+#include <media/DrmSessionManager.h>
+#include <media/DrmSessionClientInterface.h>
 #include <media/stagefright/ProcessInfo.h>
 #include <unistd.h>
 #include <utils/String8.h>
diff --git a/media/libmediaplayerservice/SharedLibrary.cpp b/drm/libmediadrm/SharedLibrary.cpp
similarity index 97%
rename from media/libmediaplayerservice/SharedLibrary.cpp
rename to drm/libmediadrm/SharedLibrary.cpp
index 34db761..74b3a71 100644
--- a/media/libmediaplayerservice/SharedLibrary.cpp
+++ b/drm/libmediadrm/SharedLibrary.cpp
@@ -16,12 +16,11 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "Drm"
-#include <utils/Log.h>
-#include <media/stagefright/foundation/ADebug.h>
 
 #include <dlfcn.h>
-
-#include "SharedLibrary.h"
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/SharedLibrary.h>
+#include <utils/Log.h>
 
 namespace android {
 
diff --git a/include/camera/ndk/NdkCameraMetadataTags.h b/include/camera/ndk/NdkCameraMetadataTags.h
index 155f221..ec2e159 100644
--- a/include/camera/ndk/NdkCameraMetadataTags.h
+++ b/include/camera/ndk/NdkCameraMetadataTags.h
@@ -4140,7 +4140,7 @@
      * color channel listed in the CFA.</p>
      * <p>This key will be available if ACAMERA_SENSOR_OPTICAL_BLACK_REGIONS is
      * available or the camera device advertises this key via
-     * {@link android.hardware.camera2.CameraCharacteristics#getAvailableCaptureRequestKeys}.</p>
+     * {@link android.hardware.camera2.CameraCharacteristics#getAvailableCaptureResultKeys}.</p>
      *
      * @see ACAMERA_SENSOR_BLACK_LEVEL_PATTERN
      * @see ACAMERA_SENSOR_INFO_COLOR_FILTER_ARRANGEMENT
@@ -4655,16 +4655,26 @@
             ACAMERA_STATISTICS_START + 10,
     /**
      * <p>The shading map is a low-resolution floating-point map
-     * that lists the coefficients used to correct for vignetting, for each
-     * Bayer color channel of RAW image data.</p>
+     * that lists the coefficients used to correct for vignetting and color shading,
+     * for each Bayer color channel of RAW image data.</p>
      *
      * <p>This tag may appear in:</p>
      * <ul>
      *   <li>ACameraMetadata from ACameraCaptureSession_captureCallback_result callbacks</li>
      * </ul>
      *
-     * <p>The least shaded section of the image should have a gain factor
-     * of 1; all other sections should have gains above 1.</p>
+     * <p>The lens shading correction is defined as a full shading correction that
+     * corrects both color shading for the output non-RAW images. After the
+     * shading map is applied, the output non-RAW images will be flat-field images
+     * for flat scenes under uniform illumination.</p>
+     * <p>When there is no lens shading correction applied to RAW output images
+     * (ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED <code>==</code> false), this map is a full lens
+     * shading correction map; when there is some lens shading correction applied
+     * to the RAW output image (ACAMERA_SENSOR_INFO_LENS_SHADING_APPLIED <code>==</code> true),
+     * this map reports the remaining lens shading correction map that needs to be
+     * applied to get fully shading corrected images.</p>
+     * <p>For a full shading correction map, the least shaded section of the image
+     * should have a gain factor of 1; all other sections should have gains above 1.</p>
      * <p>When ACAMERA_COLOR_CORRECTION_MODE = TRANSFORM_MATRIX, the map
      * must take into account the colorCorrection settings.</p>
      * <p>The shading map is for the entire active pixel array, and is not
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index fc7217a..1107142 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -186,8 +186,21 @@
      *                     and inform of marker, position updates, etc.
      * user:               Context for use by the callback receiver.
      * notificationFrames: The callback function is called each time notificationFrames PCM
-     *                     frames have been consumed from track input buffer.
-     *                     This is expressed in units of frames at the initial source sample rate.
+     *                     frames have been consumed from track input buffer by server.
+     *                     Zero means to use a default value, which is typically:
+     *                      - fast tracks: HAL buffer size, even if track frameCount is larger
+     *                      - normal tracks: 1/2 of track frameCount
+     *                     A positive value means that many frames at initial source sample rate.
+     *                     A negative value for this parameter specifies the negative of the
+     *                     requested number of notifications (sub-buffers) in the entire buffer.
+     *                     For fast tracks, the FastMixer will process one sub-buffer at a time.
+     *                     The size of each sub-buffer is determined by the HAL.
+     *                     To get "double buffering", for example, one should pass -2.
+     *                     The minimum number of sub-buffers is 1 (expressed as -1),
+     *                     and the maximum number of sub-buffers is 8 (expressed as -8).
+     *                     Negative is only permitted for fast tracks, and if frameCount is zero.
+     *                     TODO It is ugly to overload a parameter in this way depending on
+     *                     whether it is positive, negative, or zero.  Consider splitting apart.
      * sessionId:          Specific session ID, or zero to use default.
      * transferType:       How data is transferred to AudioTrack.
      * offloadInfo:        If not NULL, provides offload parameters for
@@ -216,7 +229,7 @@
                                     audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                                     callback_t cbf       = NULL,
                                     void* user           = NULL,
-                                    uint32_t notificationFrames = 0,
+                                    int32_t notificationFrames = 0,
                                     audio_session_t sessionId  = AUDIO_SESSION_ALLOCATE,
                                     transfer_type transferType = TRANSFER_DEFAULT,
                                     const audio_offload_info_t *offloadInfo = NULL,
@@ -246,7 +259,7 @@
                                     audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                                     callback_t cbf      = NULL,
                                     void* user          = NULL,
-                                    uint32_t notificationFrames = 0,
+                                    int32_t notificationFrames = 0,
                                     audio_session_t sessionId   = AUDIO_SESSION_ALLOCATE,
                                     transfer_type transferType = TRANSFER_DEFAULT,
                                     const audio_offload_info_t *offloadInfo = NULL,
@@ -290,7 +303,7 @@
                             audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE,
                             callback_t cbf      = NULL,
                             void* user          = NULL,
-                            uint32_t notificationFrames = 0,
+                            int32_t notificationFrames = 0,
                             const sp<IMemory>& sharedBuffer = 0,
                             bool threadCanCallJava = false,
                             audio_session_t sessionId  = AUDIO_SESSION_ALLOCATE,
@@ -335,6 +348,8 @@
             uint32_t    channelCount() const { return mChannelCount; }
             size_t      frameCount() const  { return mFrameCount; }
 
+    // TODO consider notificationFrames() if needed
+
     /* Return effective size of audio buffer that an application writes to
      * or a negative error if the track is uninitialized.
      */
@@ -977,9 +992,16 @@
     void*                   mUserData;
 
     // for notification APIs
+
+    // next 2 fields are const after constructor or set()
     uint32_t                mNotificationFramesReq; // requested number of frames between each
                                                     // notification callback,
                                                     // at initial source sample rate
+    uint32_t                mNotificationsPerBufferReq;
+                                                    // requested number of notifications per buffer,
+                                                    // currently only used for fast tracks with
+                                                    // default track buffer size
+
     uint32_t                mNotificationFramesAct; // actual number of frames between each
                                                     // notification callback,
                                                     // at initial source sample rate
diff --git a/media/libmediaplayerservice/Crypto.h b/include/media/Crypto.h
similarity index 100%
rename from media/libmediaplayerservice/Crypto.h
rename to include/media/Crypto.h
diff --git a/media/libmediaplayerservice/Drm.h b/include/media/Drm.h
similarity index 100%
rename from media/libmediaplayerservice/Drm.h
rename to include/media/Drm.h
diff --git a/services/mediadrm/DrmSessionClientInterface.h b/include/media/DrmSessionClientInterface.h
similarity index 100%
rename from services/mediadrm/DrmSessionClientInterface.h
rename to include/media/DrmSessionClientInterface.h
diff --git a/media/libmediaplayerservice/DrmSessionManager.h b/include/media/DrmSessionManager.h
similarity index 100%
rename from media/libmediaplayerservice/DrmSessionManager.h
rename to include/media/DrmSessionManager.h
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index e5d3cda..8266b0b 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -31,8 +31,6 @@
 
 namespace android {
 
-struct ICrypto;
-struct IDrm;
 struct IHDCP;
 struct IMediaCodecList;
 struct IMediaHTTPService;
@@ -52,8 +50,6 @@
     virtual sp<IMediaPlayer> create(const sp<IMediaPlayerClient>& client,
             audio_session_t audioSessionId = AUDIO_SESSION_ALLOCATE) = 0;
     virtual sp<IOMX>            getOMX() = 0;
-    virtual sp<ICrypto>         makeCrypto() = 0;
-    virtual sp<IDrm>            makeDrm() = 0;
     virtual sp<IHDCP>           makeHDCP(bool createEncryptionModule) = 0;
     virtual sp<IMediaCodecList> getCodecList() const = 0;
 
diff --git a/media/libmediaplayerservice/SharedLibrary.h b/include/media/SharedLibrary.h
similarity index 100%
rename from media/libmediaplayerservice/SharedLibrary.h
rename to include/media/SharedLibrary.h
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index b22e0b4..f6d5f12 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -425,10 +425,10 @@
     // gets index or sets it to 0 on error. Returns error from codec.
     status_t initDescribeHDRStaticInfoIndex();
 
-    // sets HDR static information for the decoder based on |configFormat|, and
-    // set resulting HDRStaticInfo config into |outputFormat|. Returns error from the codec.
-    status_t setHDRStaticInfoForVideoDecoder(
-            const sp<AMessage> &configFormat, sp<AMessage> &outputFormat);
+    // sets HDR static metadata for the video encoder/decoder based on |configFormat|, and
+    // sets resulting HDRStaticInfo config into |outputFormat|. Returns error from the codec.
+    status_t setHDRStaticInfoForVideoCodec(
+            OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat);
 
     // sets |params|. Returns the codec error.
     status_t setHDRStaticInfo(const DescribeHDRStaticInfoParams &params);
@@ -436,8 +436,8 @@
     // gets |params|. Returns the codec error.
     status_t getHDRStaticInfo(DescribeHDRStaticInfoParams &params);
 
-    // gets HDR static information for the video decoder port and sets them into |format|.
-    status_t getHDRStaticInfoForVideoDecoder(sp<AMessage> &format);
+    // gets HDR static information for the video encoder/decoder port and sets them into |format|.
+    status_t getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format);
 
     typedef struct drcParams {
         int32_t drcCut;
diff --git a/media/audioserver/audioserver.rc b/media/audioserver/audioserver.rc
index 1b39c8d..2409157 100644
--- a/media/audioserver/audioserver.rc
+++ b/media/audioserver/audioserver.rc
@@ -4,3 +4,4 @@
     # media gid needed for /dev/fm (radio) and for /data/misc/media (tee)
     group audio camera drmrpc inet media mediadrm net_bt net_bt_admin net_bw_acct
     ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index b9138f2..472f6c0 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -90,16 +90,24 @@
 // TODO: Move to a common library
 static size_t calculateMinFrameCount(
         uint32_t afLatencyMs, uint32_t afFrameCount, uint32_t afSampleRate,
-        uint32_t sampleRate, float speed)
+        uint32_t sampleRate, float speed /*, uint32_t notificationsPerBufferReq*/)
 {
     // Ensure that buffer depth covers at least audio hardware latency
     uint32_t minBufCount = afLatencyMs / ((1000 * afFrameCount) / afSampleRate);
     if (minBufCount < 2) {
         minBufCount = 2;
     }
+#if 0
+    // The notificationsPerBufferReq parameter is not yet used for non-fast tracks,
+    // but keeping the code here to make it easier to add later.
+    if (minBufCount < notificationsPerBufferReq) {
+        minBufCount = notificationsPerBufferReq;
+    }
+#endif
     ALOGV("calculateMinFrameCount afLatency %u  afFrameCount %u  afSampleRate %u  "
-            "sampleRate %u  speed %f  minBufCount: %u",
-            afLatencyMs, afFrameCount, afSampleRate, sampleRate, speed, minBufCount);
+            "sampleRate %u  speed %f  minBufCount: %u" /*"  notificationsPerBufferReq %u"*/,
+            afLatencyMs, afFrameCount, afSampleRate, sampleRate, speed, minBufCount
+            /*, notificationsPerBufferReq*/);
     return minBufCount * sourceFramesNeededWithTimestretch(
             sampleRate, afFrameCount, afSampleRate, speed);
 }
@@ -144,7 +152,8 @@
 
     // When called from createTrack, speed is 1.0f (normal speed).
     // This is rechecked again on setting playback rate (TODO: on setting sample rate, too).
-    *frameCount = calculateMinFrameCount(afLatency, afFrameCount, afSampleRate, sampleRate, 1.0f);
+    *frameCount = calculateMinFrameCount(afLatency, afFrameCount, afSampleRate, sampleRate, 1.0f
+            /*, 0 notificationsPerBufferReq*/);
 
     // The formula above should always produce a non-zero value under normal circumstances:
     // AudioTrack.SAMPLE_RATE_HZ_MIN <= sampleRate <= AudioTrack.SAMPLE_RATE_HZ_MAX.
@@ -184,7 +193,7 @@
         audio_output_flags_t flags,
         callback_t cbf,
         void* user,
-        uint32_t notificationFrames,
+        int32_t notificationFrames,
         audio_session_t sessionId,
         transfer_type transferType,
         const audio_offload_info_t *offloadInfo,
@@ -215,7 +224,7 @@
         audio_output_flags_t flags,
         callback_t cbf,
         void* user,
-        uint32_t notificationFrames,
+        int32_t notificationFrames,
         audio_session_t sessionId,
         transfer_type transferType,
         const audio_offload_info_t *offloadInfo,
@@ -274,7 +283,7 @@
         audio_output_flags_t flags,
         callback_t cbf,
         void* user,
-        uint32_t notificationFrames,
+        int32_t notificationFrames,
         const sp<IMemory>& sharedBuffer,
         bool threadCanCallJava,
         audio_session_t sessionId,
@@ -287,7 +296,7 @@
         float maxRequiredSpeed)
 {
     ALOGV("set(): streamType %d, sampleRate %u, format %#x, channelMask %#x, frameCount %zu, "
-          "flags #%x, notificationFrames %u, sessionId %d, transferType %d, uid %d, pid %d",
+          "flags #%x, notificationFrames %d, sessionId %d, transferType %d, uid %d, pid %d",
           streamType, sampleRate, format, channelMask, frameCount, flags, notificationFrames,
           sessionId, transferType, uid, pid);
 
@@ -443,7 +452,29 @@
     mSendLevel = 0.0f;
     // mFrameCount is initialized in createTrack_l
     mReqFrameCount = frameCount;
-    mNotificationFramesReq = notificationFrames;
+    if (notificationFrames >= 0) {
+        mNotificationFramesReq = notificationFrames;
+        mNotificationsPerBufferReq = 0;
+    } else {
+        if (!(flags & AUDIO_OUTPUT_FLAG_FAST)) {
+            ALOGE("notificationFrames=%d not permitted for non-fast track",
+                    notificationFrames);
+            return BAD_VALUE;
+        }
+        if (frameCount > 0) {
+            ALOGE("notificationFrames=%d not permitted with non-zero frameCount=%zu",
+                    notificationFrames, frameCount);
+            return BAD_VALUE;
+        }
+        mNotificationFramesReq = 0;
+        const uint32_t minNotificationsPerBuffer = 1;
+        const uint32_t maxNotificationsPerBuffer = 8;
+        mNotificationsPerBufferReq = min(maxNotificationsPerBuffer,
+                max((uint32_t) -notificationFrames, minNotificationsPerBuffer));
+        ALOGW_IF(mNotificationsPerBufferReq != (uint32_t) -notificationFrames,
+                "notificationFrames=%d clamped to the range -%u to -%u",
+                notificationFrames, minNotificationsPerBuffer, maxNotificationsPerBuffer);
+    }
     mNotificationFramesAct = 0;
     if (sessionId == AUDIO_SESSION_ALLOCATE) {
         mSessionId = (audio_session_t) AudioSystem::newAudioUniqueId(AUDIO_UNIQUE_ID_USE_SESSION);
@@ -1231,6 +1262,15 @@
         goto release;
     }
 
+    // TODO consider making this a member variable if there are other uses for it later
+    size_t afFrameCountHAL;
+    status = AudioSystem::getFrameCountHAL(output, &afFrameCountHAL);
+    if (status != NO_ERROR) {
+        ALOGE("getFrameCountHAL(output=%d) status %d", output, status);
+        goto release;
+    }
+    ALOG_ASSERT(afFrameCountHAL > 0);
+
     status = AudioSystem::getSamplingRate(output, &mAfSampleRate);
     if (status != NO_ERROR) {
         ALOGE("getSamplingRate(output=%d) status %d", output, status);
@@ -1303,18 +1343,30 @@
         // there _is_ a frameCount parameter.  We silently ignore it.
         frameCount = mSharedBuffer->size() / mFrameSize;
     } else {
-        // For fast tracks the frame count calculations and checks are done by server
-
-        if ((mFlags & AUDIO_OUTPUT_FLAG_FAST) == 0) {
+        size_t minFrameCount = 0;
+        // For fast tracks the frame count calculations and checks are mostly done by server,
+        // but we try to respect the application's request for notifications per buffer.
+        if (mFlags & AUDIO_OUTPUT_FLAG_FAST) {
+            if (mNotificationsPerBufferReq > 0) {
+                // Avoid possible arithmetic overflow during multiplication.
+                // mNotificationsPerBuffer is clamped to a small integer earlier, so it is unlikely.
+                if (mNotificationsPerBufferReq > SIZE_MAX / afFrameCountHAL) {
+                    ALOGE("Requested notificationPerBuffer=%u ignored for HAL frameCount=%zu",
+                            mNotificationsPerBufferReq, afFrameCountHAL);
+                } else {
+                    minFrameCount = afFrameCountHAL * mNotificationsPerBufferReq;
+                }
+            }
+        } else {
             // for normal tracks precompute the frame count based on speed.
             const float speed = !isPurePcmData_l() || isOffloadedOrDirect_l() ? 1.0f :
                             max(mMaxRequiredSpeed, mPlaybackRate.mSpeed);
-            const size_t minFrameCount = calculateMinFrameCount(
+            minFrameCount = calculateMinFrameCount(
                     mAfLatency, mAfFrameCount, mAfSampleRate, mSampleRate,
-                    speed);
-            if (frameCount < minFrameCount) {
-                frameCount = minFrameCount;
-            }
+                    speed /*, 0 mNotificationsPerBufferReq*/);
+        }
+        if (frameCount < minFrameCount) {
+            frameCount = minFrameCount;
         }
     }
 
@@ -1408,22 +1460,26 @@
     }
 
     // Make sure that application is notified with sufficient margin before underrun.
-    // The client's AudioTrack buffer is divided into n parts for purpose of wakeup by server, where
-    //  n = 1   fast track with single buffering; nBuffering is ignored
-    //  n = 2   fast track with double buffering
-    //  n = 2   normal track, (including those with sample rate conversion)
-    //  n >= 3  very high latency or very small notification interval (unused).
-    // FIXME Move the computation from client side to server side,
-    //       and allow nBuffering to be larger than 1 for OpenSL ES, like it can be for Java.
+    // The client can divide the AudioTrack buffer into sub-buffers,
+    // and expresses its desire to server as the notification frame count.
     if (mSharedBuffer == 0 && audio_is_linear_pcm(mFormat)) {
-        size_t maxNotificationFrames = frameCount;
-        if (!(trackFlags & IAudioFlinger::TRACK_FAST)) {
-            const uint32_t nBuffering = 2;
-            maxNotificationFrames /= nBuffering;
+        size_t maxNotificationFrames;
+        if (trackFlags & IAudioFlinger::TRACK_FAST) {
+            // notify every HAL buffer, regardless of the size of the track buffer
+            maxNotificationFrames = afFrameCountHAL;
+        } else {
+            // For normal tracks, use double-buffering
+            const int nBuffering = 2;
+            maxNotificationFrames = frameCount / nBuffering;
         }
         if (mNotificationFramesAct == 0 || mNotificationFramesAct > maxNotificationFrames) {
-            ALOGW("Client adjusted notificationFrames from %u to %zu for frameCount %zu",
+            if (mNotificationFramesAct == 0) {
+                ALOGD("Client defaulted notificationFrames to %zu for frameCount %zu",
+                    maxNotificationFrames, frameCount);
+            } else {
+                ALOGW("Client adjusted notificationFrames from %u to %zu for frameCount %zu",
                     mNotificationFramesAct, maxNotificationFrames, frameCount);
+            }
             mNotificationFramesAct = (uint32_t) maxNotificationFrames;
         }
     }
@@ -2043,6 +2099,7 @@
                 const nsecs_t datans = mRemainingFrames <= avail ? 0 :
                         framesToNanoseconds(mRemainingFrames - avail, sampleRate, speed);
                 // audio flinger thread buffer size (TODO: adjust for fast tracks)
+                // FIXME: use mAfFrameCountHAL instead of mAfFrameCount below for fast tracks.
                 const nsecs_t afns = framesToNanoseconds(mAfFrameCount, mAfSampleRate, speed);
                 // add a half the AudioFlinger buffer time to avoid soaking CPU if datans is 0.
                 myns = datans + (afns / 2);
@@ -2203,7 +2260,8 @@
         return true; // static tracks do not have issues with buffer sizing.
     }
     const size_t minFrameCount =
-            calculateMinFrameCount(mAfLatency, mAfFrameCount, mAfSampleRate, sampleRate, speed);
+            calculateMinFrameCount(mAfLatency, mAfFrameCount, mAfSampleRate, sampleRate, speed
+                /*, 0 mNotificationsPerBufferReq*/);
     ALOGV("isSampleRateSpeedAllowed_l mFrameCount %zu  minFrameCount %zu",
             mFrameCount, minFrameCount);
     return mFrameCount >= minFrameCount;
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index 27b9edd..7590c1b 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -20,8 +20,6 @@
 
 #include <binder/Parcel.h>
 #include <binder/IMemory.h>
-#include <media/ICrypto.h>
-#include <media/IDrm.h>
 #include <media/IHDCP.h>
 #include <media/IMediaCodecList.h>
 #include <media/IMediaHTTPService.h>
@@ -42,8 +40,6 @@
     CREATE_MEDIA_RECORDER,
     CREATE_METADATA_RETRIEVER,
     GET_OMX,
-    MAKE_CRYPTO,
-    MAKE_DRM,
     MAKE_HDCP,
     ADD_BATTERY_DATA,
     PULL_BATTERY_DATA,
@@ -94,20 +90,6 @@
         return interface_cast<IOMX>(reply.readStrongBinder());
     }
 
-    virtual sp<ICrypto> makeCrypto() {
-        Parcel data, reply;
-        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
-        remote()->transact(MAKE_CRYPTO, data, &reply);
-        return interface_cast<ICrypto>(reply.readStrongBinder());
-    }
-
-    virtual sp<IDrm> makeDrm() {
-        Parcel data, reply;
-        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
-        remote()->transact(MAKE_DRM, data, &reply);
-        return interface_cast<IDrm>(reply.readStrongBinder());
-    }
-
     virtual sp<IHDCP> makeHDCP(bool createEncryptionModule) {
         Parcel data, reply;
         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
@@ -185,18 +167,6 @@
             reply->writeStrongBinder(IInterface::asBinder(omx));
             return NO_ERROR;
         } break;
-        case MAKE_CRYPTO: {
-            CHECK_INTERFACE(IMediaPlayerService, data, reply);
-            sp<ICrypto> crypto = makeCrypto();
-            reply->writeStrongBinder(IInterface::asBinder(crypto));
-            return NO_ERROR;
-        } break;
-        case MAKE_DRM: {
-            CHECK_INTERFACE(IMediaPlayerService, data, reply);
-            sp<IDrm> drm = makeDrm();
-            reply->writeStrongBinder(IInterface::asBinder(drm));
-            return NO_ERROR;
-        } break;
         case MAKE_HDCP: {
             CHECK_INTERFACE(IMediaPlayerService, data, reply);
             bool createEncryptionModule = data.readInt32();
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index edad4be..68860d2 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -8,16 +8,12 @@
 
 LOCAL_SRC_FILES:=               \
     ActivityManager.cpp         \
-    Crypto.cpp                  \
-    Drm.cpp                     \
-    DrmSessionManager.cpp       \
     HDCP.cpp                    \
     MediaPlayerFactory.cpp      \
     MediaPlayerService.cpp      \
     MediaRecorderClient.cpp     \
     MetadataRetrieverClient.cpp \
     RemoteDisplay.cpp           \
-    SharedLibrary.cpp           \
     StagefrightRecorder.cpp     \
     TestPlayerStub.cpp          \
 
@@ -52,6 +48,7 @@
     $(TOP)/frameworks/av/media/libstagefright/rtsp                  \
     $(TOP)/frameworks/av/media/libstagefright/wifi-display          \
     $(TOP)/frameworks/av/media/libstagefright/webm                  \
+    $(TOP)/frameworks/av/include/media                              \
     $(TOP)/frameworks/av/include/camera                             \
     $(TOP)/frameworks/native/include/media/openmax                  \
     $(TOP)/external/tremolo/Tremolo                                 \
diff --git a/media/libmediaplayerservice/DrmSessionClientInterface.h b/media/libmediaplayerservice/DrmSessionClientInterface.h
deleted file mode 100644
index 17faf08..0000000
--- a/media/libmediaplayerservice/DrmSessionClientInterface.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef DRM_PROXY_INTERFACE_H_
-#define DRM_PROXY_INTERFACE_H_
-
-#include <utils/RefBase.h>
-#include <utils/Vector.h>
-
-namespace android {
-
-struct DrmSessionClientInterface : public RefBase {
-    virtual bool reclaimSession(const Vector<uint8_t>& sessionId) = 0;
-
-protected:
-    virtual ~DrmSessionClientInterface() {}
-};
-
-}  // namespace android
-
-#endif  // DRM_PROXY_INTERFACE_H_
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 9b081e9..7d3c671 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -78,8 +78,6 @@
 
 #include <OMX.h>
 
-#include "Crypto.h"
-#include "Drm.h"
 #include "HDCP.h"
 #include "HTTPBase.h"
 #include "RemoteDisplay.h"
@@ -359,14 +357,6 @@
     return mOMX;
 }
 
-sp<ICrypto> MediaPlayerService::makeCrypto() {
-    return new Crypto;
-}
-
-sp<IDrm> MediaPlayerService::makeDrm() {
-    return new Drm;
-}
-
 sp<IHDCP> MediaPlayerService::makeHDCP(bool createEncryptionModule) {
     return new HDCP(createEncryptionModule);
 }
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 80593b2..1cf648e 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -219,8 +219,6 @@
 
     virtual sp<IMediaCodecList> getCodecList() const;
     virtual sp<IOMX>            getOMX();
-    virtual sp<ICrypto>         makeCrypto();
-    virtual sp<IDrm>            makeDrm();
     virtual sp<IHDCP>           makeHDCP(bool createEncryptionModule);
 
     virtual sp<IRemoteDisplay> listenForRemoteDisplay(const String16 &opPackageName,
@@ -410,7 +408,6 @@
                 SortedVector< wp<MediaRecorderClient> > mMediaRecorderClients;
                 int32_t                     mNextConnId;
                 sp<IOMX>                    mOMX;
-                sp<ICrypto>                 mCrypto;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 81aafbe..9e33cb5 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -1620,14 +1620,13 @@
 }
 
 void NuPlayer::GenericSource::BufferingMonitor::startBufferingIfNecessary_l() {
-    ALOGD("startBufferingIfNecessary_l: mPrepareBuffering=%d, mBuffering=%d",
-            mPrepareBuffering, mBuffering);
-
     if (mPrepareBuffering) {
         return;
     }
 
     if (!mBuffering) {
+        ALOGD("startBufferingIfNecessary_l");
+
         mBuffering = true;
 
         ensureCacheIsFetching_l();
@@ -1640,10 +1639,9 @@
 }
 
 void NuPlayer::GenericSource::BufferingMonitor::stopBufferingIfNecessary_l() {
-    ALOGD("stopBufferingIfNecessary_l: mPrepareBuffering=%d, mBuffering=%d",
-            mPrepareBuffering, mBuffering);
-
     if (mPrepareBuffering) {
+        ALOGD("stopBufferingIfNecessary_l, mBuffering=%d", mBuffering);
+
         mPrepareBuffering = false;
 
         sp<AMessage> notify = mNotify->dup();
@@ -1655,6 +1653,7 @@
     }
 
     if (mBuffering) {
+        ALOGD("stopBufferingIfNecessary_l");
         mBuffering = false;
 
         sendCacheStats_l();
diff --git a/media/libmediaplayerservice/tests/Android.mk b/media/libmediaplayerservice/tests/Android.mk
index 8cbf782..ea75a97 100644
--- a/media/libmediaplayerservice/tests/Android.mk
+++ b/media/libmediaplayerservice/tests/Android.mk
@@ -12,6 +12,7 @@
 LOCAL_SHARED_LIBRARIES := \
 	liblog \
 	libmediaplayerservice \
+	libmediadrm \
 	libutils \
 
 LOCAL_C_INCLUDES := \
diff --git a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
index ef4c833..c5212fc 100644
--- a/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
+++ b/media/libmediaplayerservice/tests/DrmSessionManager_test.cpp
@@ -20,9 +20,9 @@
 
 #include <gtest/gtest.h>
 
-#include "Drm.h"
-#include "DrmSessionClientInterface.h"
-#include "DrmSessionManager.h"
+#include <media/Drm.h>
+#include <media/DrmSessionClientInterface.h>
+#include <media/DrmSessionManager.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/ProcessInfoInterface.h>
 
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 7c903ea..f159882 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -3192,7 +3192,7 @@
         return err;
     }
 
-    err = setHDRStaticInfoForVideoDecoder(msg, outputFormat);
+    err = setHDRStaticInfoForVideoCodec(kPortIndexOutput, msg, outputFormat);
     if (err == ERROR_UNSUPPORTED) { // support is optional
         err = OK;
     }
@@ -3392,6 +3392,25 @@
     return OK;
 }
 
+status_t ACodec::setHDRStaticInfoForVideoCodec(
+        OMX_U32 portIndex, const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
+    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
+
+    DescribeHDRStaticInfoParams params;
+    InitOMXParams(&params);
+    params.nPortIndex = portIndex;
+
+    HDRStaticInfo *info = &params.sInfo;
+    if (getHDRStaticInfoFromFormat(configFormat, info)) {
+        setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
+    }
+
+    (void)initDescribeHDRStaticInfoIndex();
+
+    // communicate HDR static Info to codec
+    return setHDRStaticInfo(params);
+}
+
 // subsequent initial video encoder setup for surface mode
 status_t ACodec::setInitialColorAspectsForVideoEncoderSurfaceAndGetDataSpace(
         android_dataspace *dataSpace /* nonnull */) {
@@ -3444,10 +3463,11 @@
     return err;
 }
 
-status_t ACodec::getHDRStaticInfoForVideoDecoder(sp<AMessage> &format) {
+status_t ACodec::getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format) {
+    CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
     DescribeHDRStaticInfoParams params;
     InitOMXParams(&params);
-    params.nPortIndex = kPortIndexOutput;
+    params.nPortIndex = portIndex;
 
     status_t err = getHDRStaticInfo(params);
     if (err == OK) {
@@ -3466,23 +3486,6 @@
     return err;
 }
 
-status_t ACodec::setHDRStaticInfoForVideoDecoder(
-        const sp<AMessage> &configFormat, sp<AMessage> &outputFormat) {
-    DescribeHDRStaticInfoParams params;
-    InitOMXParams(&params);
-    params.nPortIndex = kPortIndexOutput;
-
-    HDRStaticInfo *info = &params.sInfo;
-    if (getHDRStaticInfoFromFormat(configFormat, info)) {
-        setHDRStaticInfoIntoFormat(params.sInfo, outputFormat);
-    }
-
-    (void)initDescribeHDRStaticInfoIndex();
-
-    // communicate HDR static Info to codec
-    return setHDRStaticInfo(params);
-}
-
 status_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams &params) {
     status_t err = ERROR_UNSUPPORTED;
     if (mDescribeHDRStaticInfoIndex) {
@@ -3697,6 +3700,16 @@
         err = OK;
     }
 
+    if (err != OK) {
+        return err;
+    }
+
+    err = setHDRStaticInfoForVideoCodec(kPortIndexInput, msg, outputFormat);
+    if (err == ERROR_UNSUPPORTED) { // support is optional
+        ALOGI("[%s] cannot encode HDR static metadata. Ignoring.", mComponentName.c_str());
+        err = OK;
+    }
+
     if (err == OK) {
         ALOGI("setupVideoEncoder succeeded");
     }
@@ -4729,9 +4742,12 @@
                         if (mUsingNativeWindow) {
                             notify->setInt32("android._dataspace", dataSpace);
                         }
-                        (void)getHDRStaticInfoForVideoDecoder(notify);
+                        (void)getHDRStaticInfoForVideoCodec(kPortIndexOutput, notify);
                     } else {
                         (void)getInputColorAspectsForVideoEncoder(notify);
+                        if (mConfigFormat->contains("hdr-static-info")) {
+                            (void)getHDRStaticInfoForVideoCodec(kPortIndexInput, notify);
+                        }
                     }
 
                     break;
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_cequivalent.h b/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_cequivalent.h
index 7fd680d..3c7590c 100644
--- a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_cequivalent.h
+++ b/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder_basic_op_cequivalent.h
@@ -206,16 +206,18 @@
     {
         int32 L_var_out;
 
-        L_var_out = L_var1 + L_var2;
-
-        if (((L_var1 ^ L_var2) & MIN_32) == 0)  /* same sign ? */
-        {
-            if ((L_var_out ^ L_var1) & MIN_32)  /* addition matches sign ? */
-            {
-                L_var_out = (L_var1 >> 31) ^ MAX_32;
+        //L_var_out = L_var1 + L_var2;
+        if (L_var2 < 0) {
+            if (L_var1 < MIN_32 - L_var2) {
+                return MIN_32;
+            }
+        } else {
+            if (L_var1 > MAX_32 - L_var2) {
+                return MAX_32;
             }
         }
-        return (L_var_out);
+
+        return L_var1 + L_var2;
     }
 
 
@@ -248,142 +250,24 @@
 
     __inline  int32 sub_int32(int32 L_var1, int32 L_var2)
     {
-        int32 L_var_out;
-
-        L_var_out = L_var1 - L_var2;
-
-        if (((L_var1 ^ L_var2) & MIN_32) != 0)  /* different sign ? */
-        {
-            if ((L_var_out ^ L_var1) & MIN_32)  /* difference matches sign ? */
-            {
-                L_var_out = (L_var1 >> 31) ^ MAX_32;
+        //L_var_out = L_var1 - L_var2;
+        if (L_var2 < 0) {
+            if (L_var1 > MAX_32 + L_var2) {
+                return  MAX_32;
             }
-        }
-        return (L_var_out);
-    }
-
-
-
-    /*----------------------------------------------------------------------------
-
-         Function Name : mac_16by16_to_int32
-
-         Multiply var1 by var2 and shift the result left by 1. Add the 32 bit
-         result to L_var3 with saturation, return a 32 bit result:
-              L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)).
-
-         Inputs :
-
-          L_var3   32 bit long signed integer (int32) whose value falls in the
-                   range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
-
-          var1
-                   16 bit short signed integer (int16) whose value falls in the
-                   range : 0xffff 8000 <= var1 <= 0x0000 7fff.
-
-          var2
-                   16 bit short signed integer (int16) whose value falls in the
-                   range : 0xffff 8000 <= var1 <= 0x0000 7fff.
-
-
-         Return Value :
-                   32 bit long signed integer (int32) whose value falls in the
-                   range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
-
-     ----------------------------------------------------------------------------*/
-
-
-    __inline  int32 mac_16by16_to_int32(int32 L_var3, int16 var1, int16 var2)
-    {
-        int32 L_var_out;
-        int32 L_mul;
-
-        L_mul  = ((int32) var1 * (int32) var2);
-
-        if (L_mul != 0x40000000)
-        {
-            L_mul <<= 1;
-        }
-        else
-        {
-            L_mul = MAX_32;     /* saturation */
-        }
-
-        L_var_out = L_var3 + L_mul;
-
-        if (((L_mul ^ L_var3) & MIN_32) == 0)  /* same sign ? */
-        {
-            if ((L_var_out ^ L_var3) & MIN_32)  /* addition matches sign ? */
-            {
-                L_var_out = (L_var3 >> 31) ^ MAX_32;
+        } else {
+            if (L_var1 < MIN_32 + L_var2) {
+                return MIN_32;
             }
         }
 
-        return (L_var_out);
+        return L_var1 - L_var2;
     }
 
 
 
     /*----------------------------------------------------------------------------
 
-         Function Name : msu_16by16_from_int32
-
-         Multiply var1 by var2 and shift the result left by 1. Subtract the 32 bit
-         result to L_var3 with saturation, return a 32 bit result:
-              L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)).
-
-         Inputs :
-
-          L_var3   32 bit long signed integer (int32) whose value falls in the
-                   range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
-
-          var1
-                   16 bit short signed integer (int16) whose value falls in the
-                   range : 0xffff 8000 <= var1 <= 0x0000 7fff.
-
-          var2
-                   16 bit short signed integer (int16) whose value falls in the
-                   range : 0xffff 8000 <= var1 <= 0x0000 7fff.
-
-
-         Return Value :
-                   32 bit long signed integer (int32) whose value falls in the
-                   range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
-
-     ----------------------------------------------------------------------------*/
-
-    __inline  int32 msu_16by16_from_int32(int32 L_var3, int16 var1, int16 var2)
-    {
-        int32 L_var_out;
-        int32 L_mul;
-
-        L_mul  = ((int32) var1 * (int32) var2);
-
-        if (L_mul != 0x40000000)
-        {
-            L_mul <<= 1;
-        }
-        else
-        {
-            L_mul = MAX_32;     /* saturation */
-        }
-
-        L_var_out = L_var3 - L_mul;
-
-        if (((L_mul ^ L_var3) & MIN_32) != 0)  /* different sign ? */
-        {
-            if ((L_var_out ^ L_var3) & MIN_32)  /* difference matches sign ? */
-            {
-                L_var_out = (L_var3 >> 31) ^ MAX_32;
-            }
-        }
-
-        return (L_var_out);
-    }
-
-
-    /*----------------------------------------------------------------------------
-
          Function Name : mul_16by16_to_int32
 
          mul_16by16_to_int32 is the 32 bit result of the multiplication of var1
@@ -428,6 +312,75 @@
 
     /*----------------------------------------------------------------------------
 
+         Function Name : mac_16by16_to_int32
+
+         Multiply var1 by var2 and shift the result left by 1. Add the 32 bit
+         result to L_var3 with saturation, return a 32 bit result:
+              L_mac(L_var3,var1,var2) = L_add(L_var3,L_mult(var1,var2)).
+
+         Inputs :
+
+          L_var3   32 bit long signed integer (int32) whose value falls in the
+                   range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
+
+          var1
+                   16 bit short signed integer (int16) whose value falls in the
+                   range : 0xffff 8000 <= var1 <= 0x0000 7fff.
+
+          var2
+                   16 bit short signed integer (int16) whose value falls in the
+                   range : 0xffff 8000 <= var1 <= 0x0000 7fff.
+
+
+         Return Value :
+                   32 bit long signed integer (int32) whose value falls in the
+                   range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
+
+     ----------------------------------------------------------------------------*/
+
+
+    __inline  int32 mac_16by16_to_int32(int32 L_var3, int16 var1, int16 var2)
+    {
+        return add_int32(L_var3, mul_16by16_to_int32(var1, var2));
+    }
+
+
+    /*----------------------------------------------------------------------------
+
+         Function Name : msu_16by16_from_int32
+
+         Multiply var1 by var2 and shift the result left by 1. Subtract the 32 bit
+         result to L_var3 with saturation, return a 32 bit result:
+              L_msu(L_var3,var1,var2) = L_sub(L_var3,L_mult(var1,var2)).
+
+         Inputs :
+
+          L_var3   32 bit long signed integer (int32) whose value falls in the
+                   range : 0x8000 0000 <= L_var3 <= 0x7fff ffff.
+
+          var1
+                   16 bit short signed integer (int16) whose value falls in the
+                   range : 0xffff 8000 <= var1 <= 0x0000 7fff.
+
+          var2
+                   16 bit short signed integer (int16) whose value falls in the
+                   range : 0xffff 8000 <= var1 <= 0x0000 7fff.
+
+
+         Return Value :
+                   32 bit long signed integer (int32) whose value falls in the
+                   range : 0x8000 0000 <= L_var_out <= 0x7fff ffff.
+
+     ----------------------------------------------------------------------------*/
+
+    __inline  int32 msu_16by16_from_int32(int32 L_var3, int16 var1, int16 var2)
+    {
+        return sub_int32(L_var3, mul_16by16_to_int32(var1, var2));
+    }
+
+
+    /*----------------------------------------------------------------------------
+
          Function Name : amr_wb_round
 
          Round the lower 16 bits of the 32 bit input number into the MS 16 bits
@@ -447,7 +400,7 @@
      ----------------------------------------------------------------------------*/
     __inline int16 amr_wb_round(int32 L_var1)
     {
-        if (L_var1 != MAX_32)
+        if (L_var1 <= (MAX_32 - 0x00008000L))
         {
             L_var1 +=  0x00008000L;
         }
diff --git a/media/mediaserver/mediaserver.rc b/media/mediaserver/mediaserver.rc
index 89c3896..b777d5c 100644
--- a/media/mediaserver/mediaserver.rc
+++ b/media/mediaserver/mediaserver.rc
@@ -3,3 +3,4 @@
     user media
     group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
     ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
diff --git a/media/ndk/Android.mk b/media/ndk/Android.mk
index f287761..7f6b66b 100644
--- a/media/ndk/Android.mk
+++ b/media/ndk/Android.mk
@@ -45,6 +45,7 @@
 LOCAL_SHARED_LIBRARIES := \
     libbinder \
     libmedia \
+    libmediadrm \
     libstagefright \
     libstagefright_foundation \
     liblog \
diff --git a/media/ndk/NdkMediaCrypto.cpp b/media/ndk/NdkMediaCrypto.cpp
index 67d12a4..32aabdd 100644
--- a/media/ndk/NdkMediaCrypto.cpp
+++ b/media/ndk/NdkMediaCrypto.cpp
@@ -29,7 +29,6 @@
 #include <binder/IServiceManager.h>
 #include <media/ICrypto.h>
 #include <media/IMediaDrmService.h>
-#include <media/IMediaPlayerService.h>
 #include <android_runtime/AndroidRuntime.h>
 #include <android_util_Binder.h>
 
@@ -39,34 +38,17 @@
 
 static sp<ICrypto> makeCrypto() {
     sp<IServiceManager> sm = defaultServiceManager();
-    sp<ICrypto> crypto;
+    sp<IBinder> binder = sm->getService(String16("media.drm"));
 
-    char value[PROPERTY_VALUE_MAX];
-    if (property_get("media.mediadrmservice.enable", value, NULL)
-        && (!strcmp("1", value) || !strcasecmp("true", value))) {
-        sp<IBinder> binder =
-            sm->getService(String16("media.drm"));
-        sp<IMediaDrmService> service =
-            interface_cast<IMediaDrmService>(binder);
-        if (service == NULL) {
-            return NULL;
-        }
-        crypto = service->makeCrypto();
-    } else {
-        sp<IBinder> binder =
-            sm->getService(String16("media.player"));
-        sp<IMediaPlayerService> service =
-            interface_cast<IMediaPlayerService>(binder);
-        if (service == NULL) {
-            return NULL;
-        }
-        crypto = service->makeCrypto();
-    }
-
-    if (crypto == NULL || (crypto->initCheck() != OK && crypto->initCheck() != NO_INIT)) {
+    sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
+    if (service == NULL) {
         return NULL;
     }
 
+    sp<ICrypto> crypto = service->makeCrypto();
+    if (crypto == NULL || (crypto->initCheck() != OK && crypto->initCheck() != NO_INIT)) {
+        return NULL;
+    }
     return crypto;
 }
 
diff --git a/media/ndk/NdkMediaDrm.cpp b/media/ndk/NdkMediaDrm.cpp
index e98b124..be71f43 100644
--- a/media/ndk/NdkMediaDrm.cpp
+++ b/media/ndk/NdkMediaDrm.cpp
@@ -29,7 +29,6 @@
 #include <media/stagefright/MediaErrors.h>
 #include <binder/IServiceManager.h>
 #include <media/IMediaDrmService.h>
-#include <media/IMediaPlayerService.h>
 #include <ndk/NdkMediaCrypto.h>
 
 
@@ -150,34 +149,17 @@
 
 static sp<IDrm> CreateDrm() {
     sp<IServiceManager> sm = defaultServiceManager();
-    sp<IDrm> drm;
+    sp<IBinder> binder = sm->getService(String16("media.drm"));
 
-    char value[PROPERTY_VALUE_MAX];
-    if (property_get("media.mediadrmservice.enable", value, NULL)
-        && (!strcmp("1", value) || !strcasecmp("true", value))) {
-        sp<IBinder> binder =
-            sm->getService(String16("media.drm"));
-        sp<IMediaDrmService> service =
-            interface_cast<IMediaDrmService>(binder);
-        if (service == NULL) {
-            return NULL;
-        }
-        drm = service->makeDrm();
-    } else {
-        sp<IBinder> binder =
-            sm->getService(String16("media.player"));
-        sp<IMediaPlayerService> service =
-            interface_cast<IMediaPlayerService>(binder);
-        if (service == NULL) {
-            return NULL;
-        }
-        drm = service->makeDrm();
-    }
-
-    if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
+    sp<IMediaDrmService> service = interface_cast<IMediaDrmService>(binder);
+    if (service == NULL) {
         return NULL;
     }
 
+    sp<IDrm> drm = service->makeDrm();
+    if (drm == NULL || (drm->initCheck() != OK && drm->initCheck() != NO_INIT)) {
+        return NULL;
+    }
     return drm;
 }
 
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 26cd1f9..546ef25 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -77,7 +77,7 @@
     mSinkChannelMask = audio_channel_out_mask_from_count(mSinkChannelCount);
 
     unsigned i;
-    for (i = 0; i < FastMixerState::kMaxFastTracks; ++i) {
+    for (i = 0; i < FastMixerState::sMaxFastTracks; ++i) {
         mFastTrackNames[i] = -1;
         mGenerations[i] = 0;
     }
@@ -187,7 +187,7 @@
             // FIXME new may block for unbounded time at internal mutex of the heap
             //       implementation; it would be better to have normal mixer allocate for us
             //       to avoid blocking here and to prevent possible priority inversion
-            mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::kMaxFastTracks);
+            mMixer = new AudioMixer(frameCount, mSampleRate, FastMixerState::sMaxFastTracks);
             const size_t mixerFrameSize = mSinkChannelCount
                     * audio_bytes_per_sample(mMixerBufferFormat);
             mMixerBufferSize = mixerFrameSize * frameCount;
@@ -214,7 +214,7 @@
         }
         mMixerBufferState = UNDEFINED;
 #if !LOG_NDEBUG
-        for (unsigned i = 0; i < FastMixerState::kMaxFastTracks; ++i) {
+        for (unsigned i = 0; i < FastMixerState::sMaxFastTracks; ++i) {
             mFastTrackNames[i] = -1;
         }
 #endif
diff --git a/services/audioflinger/FastMixerDumpState.cpp b/services/audioflinger/FastMixerDumpState.cpp
index b10942b..2326e2a 100644
--- a/services/audioflinger/FastMixerDumpState.cpp
+++ b/services/audioflinger/FastMixerDumpState.cpp
@@ -166,10 +166,10 @@
     // Instead we always display all tracks, with an indication
     // of whether we think the track is active.
     uint32_t trackMask = mTrackMask;
-    dprintf(fd, "  Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
-            FastMixerState::kMaxFastTracks, trackMask);
+    dprintf(fd, "  Fast tracks: sMaxFastTracks=%u activeMask=%#x\n",
+            FastMixerState::sMaxFastTracks, trackMask);
     dprintf(fd, "  Index Active Full Partial Empty  Recent Ready\n");
-    for (uint32_t i = 0; i < FastMixerState::kMaxFastTracks; ++i, trackMask >>= 1) {
+    for (uint32_t i = 0; i < FastMixerState::sMaxFastTracks; ++i, trackMask >>= 1) {
         bool isActive = trackMask & 1;
         const FastTrackDump *ftDump = &mTracks[i];
         const FastTrackUnderruns& underruns = ftDump->mUnderruns;
diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/FastMixerState.cpp
index a8c2634..ad471fb 100644
--- a/services/audioflinger/FastMixerState.cpp
+++ b/services/audioflinger/FastMixerState.cpp
@@ -14,6 +14,7 @@
  * limitations under the License.
  */
 
+#include <cutils/properties.h>
 #include "FastMixerState.h"
 
 namespace android {
@@ -33,6 +34,10 @@
     mFastTracksGen(0), mTrackMask(0), mOutputSink(NULL), mOutputSinkGen(0),
     mFrameCount(0), mTeeSink(NULL)
 {
+    int ok = pthread_once(&sMaxFastTracksOnce, sMaxFastTracksInit);
+    if (ok != 0) {
+        ALOGE("%s pthread_once failed: %d", __func__, ok);
+    }
 }
 
 FastMixerState::~FastMixerState()
@@ -40,6 +45,12 @@
 }
 
 // static
+unsigned FastMixerState::sMaxFastTracks = kDefaultFastTracks;
+
+// static
+pthread_once_t FastMixerState::sMaxFastTracksOnce = PTHREAD_ONCE_INIT;
+
+// static
 const char *FastMixerState::commandToString(Command command)
 {
     const char *str = FastThreadState::commandToString(command);
@@ -54,4 +65,18 @@
     LOG_ALWAYS_FATAL("%s", __func__);
 }
 
+// static
+void FastMixerState::sMaxFastTracksInit()
+{
+    char value[PROPERTY_VALUE_MAX];
+    if (property_get("ro.audio.max_fast_tracks", value, NULL) > 0) {
+        char *endptr;
+        unsigned long ul = strtoul(value, &endptr, 0);
+        if (*endptr == '\0' && kMinFastTracks <= ul && ul <= kMaxFastTracks) {
+            sMaxFastTracks = (unsigned) ul;
+        }
+    }
+    ALOGI("sMaxFastTracks = %u", sMaxFastTracks);
+}
+
 }   // namespace android
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index 916514f..5a55c7a 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -54,7 +54,13 @@
                 FastMixerState();
     /*virtual*/ ~FastMixerState();
 
-    static const unsigned kMaxFastTracks = 8;   // must be between 2 and 32 inclusive
+    // These are the minimum, maximum, and default values for maximum number of fast tracks
+    static const unsigned kMinFastTracks = 2;
+    static const unsigned kMaxFastTracks = 32;
+    static const unsigned kDefaultFastTracks = 8;
+
+    static unsigned sMaxFastTracks;             // Configured maximum number of fast tracks
+    static pthread_once_t sMaxFastTracksOnce;   // Protects initializer for sMaxFastTracks
 
     // all pointer fields use raw pointers; objects are owned and ref-counted by the normal mixer
     FastTrack   mFastTracks[kMaxFastTracks];
@@ -76,6 +82,10 @@
 
     // never returns NULL; asserts if command is invalid
     static const char *commandToString(Command command);
+
+    // initialize sMaxFastTracks
+    static void sMaxFastTracksInit();
+
 };  // struct FastMixerState
 
 }   // namespace android
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index ff67fb2..69b5591 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -182,13 +182,9 @@
 static const int kPriorityFastMixer = 3;
 static const int kPriorityFastCapture = 3;
 
-// IAudioFlinger::createTrack() reports back to client the total size of shared memory area
-// for the track.  The client then sub-divides this into smaller buffers for its use.
-// Currently the client uses N-buffering by default, but doesn't tell us about the value of N.
-// So for now we just assume that client is double-buffered for fast tracks.
-// FIXME It would be better for client to tell AudioFlinger the value of N,
-// so AudioFlinger could allocate the right amount of memory.
-// See the client's minBufCount and mNotificationFramesAct calculations for details.
+// IAudioFlinger::createTrack() has an in/out parameter 'pFrameCount' for the total size of the
+// track buffer in shared memory.  Zero on input means to use a default value.  For fast tracks,
+// AudioFlinger derives the default from HAL buffer size and 'fast track multiplier'.
 
 // This is the default value, if not specified by property.
 static const int kFastTrackMultiplier = 2;
@@ -1602,7 +1598,7 @@
         mSignalPending(false),
         mScreenState(AudioFlinger::mScreenState),
         // index 0 is reserved for normal mixer's submix
-        mFastTrackAvailMask(((1 << FastMixerState::kMaxFastTracks) - 1) & ~1),
+        mFastTrackAvailMask(((1 << FastMixerState::sMaxFastTracks) - 1) & ~1),
         mHwSupportsPause(false), mHwPaused(false), mFlushPending(false)
 {
     snprintf(mThreadName, kThreadNameLength, "AudioOut_%X", id);
@@ -2103,7 +2099,7 @@
     track->mName = -1;
     if (track->isFastTrack()) {
         int index = track->mFastIndex;
-        ALOG_ASSERT(0 < index && index < (int)FastMixerState::kMaxFastTracks);
+        ALOG_ASSERT(0 < index && index < (int)FastMixerState::sMaxFastTracks);
         ALOG_ASSERT(!(mFastTrackAvailMask & (1 << index)));
         mFastTrackAvailMask |= 1 << index;
         // redundant as track is about to be destroyed, for dumpsys only
@@ -3859,7 +3855,7 @@
             // at the identical fast mixer slot within the same normal mix cycle,
             // is impossible because the slot isn't marked available until the end of each cycle.
             int j = track->mFastIndex;
-            ALOG_ASSERT(0 < j && j < (int)FastMixerState::kMaxFastTracks);
+            ALOG_ASSERT(0 < j && j < (int)FastMixerState::sMaxFastTracks);
             ALOG_ASSERT(!(mFastTrackAvailMask & (1 << j)));
             FastTrack *fastTrack = &state->mFastTracks[j];
 
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index e71840d..16238f8 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -913,7 +913,7 @@
 public:
     virtual     bool        hasFastMixer() const { return mFastMixer != 0; }
     virtual     FastTrackUnderruns getFastTrackUnderruns(size_t fastIndex) const {
-                              ALOG_ASSERT(fastIndex < FastMixerState::kMaxFastTracks);
+                              ALOG_ASSERT(fastIndex < FastMixerState::sMaxFastTracks);
                               return mFastMixerDumpState.mTracks[fastIndex].mUnderruns;
                             }
 
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 61b30c1..9d430aa 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -402,7 +402,7 @@
         //mAudioTrackServerProxy->framesReadyIsCalledByMultipleThreads();
         ALOG_ASSERT(thread->mFastTrackAvailMask != 0);
         int i = __builtin_ctz(thread->mFastTrackAvailMask);
-        ALOG_ASSERT(0 < i && i < (int)FastMixerState::kMaxFastTracks);
+        ALOG_ASSERT(0 < i && i < (int)FastMixerState::sMaxFastTracks);
         // FIXME This is too eager.  We allocate a fast track index before the
         //       fast track becomes active.  Since fast tracks are a scarce resource,
         //       this means we are potentially denying other more important fast tracks from
diff --git a/services/camera/libcameraservice/CameraFlashlight.cpp b/services/camera/libcameraservice/CameraFlashlight.cpp
index 0afd945..ad08a68 100644
--- a/services/camera/libcameraservice/CameraFlashlight.cpp
+++ b/services/camera/libcameraservice/CameraFlashlight.cpp
@@ -679,7 +679,8 @@
     status_t res;
     if (enabled) {
         bool hasFlash = false;
-        res = hasFlashUnitLocked(cameraId, &hasFlash);
+        // Check if it has a flash unit and leave camera device open.
+        res = hasFlashUnitLocked(cameraId, &hasFlash, /*keepDeviceOpen*/true);
         // invalid camera?
         if (res) {
             // hasFlashUnitLocked() returns BAD_INDEX if mDevice is connected to
@@ -688,6 +689,8 @@
         }
         // no flash unit?
         if (!hasFlash) {
+            // Disconnect camera device if it has no flash.
+            disconnectCameraDevice();
             return -ENOSYS;
         }
     } else if (mDevice == NULL || cameraId != mCameraId) {
@@ -716,21 +719,28 @@
 status_t CameraHardwareInterfaceFlashControl::hasFlashUnit(
         const String8& cameraId, bool *hasFlash) {
     Mutex::Autolock l(mLock);
-    return hasFlashUnitLocked(cameraId, hasFlash);
+    // Close device after checking if it has a flash unit.
+    return hasFlashUnitLocked(cameraId, hasFlash, /*keepDeviceOpen*/false);
 }
 
 status_t CameraHardwareInterfaceFlashControl::hasFlashUnitLocked(
-        const String8& cameraId, bool *hasFlash) {
+        const String8& cameraId, bool *hasFlash, bool keepDeviceOpen) {
+    bool closeCameraDevice = false;
+
     if (!hasFlash) {
         return BAD_VALUE;
     }
 
     status_t res;
     if (mDevice == NULL) {
+        // Connect to camera device to query if it has a flash unit.
         res = connectCameraDevice(cameraId);
         if (res) {
             return res;
         }
+        // Close camera device only when it is just opened and the caller doesn't want to keep
+        // the camera device open.
+        closeCameraDevice = !keepDeviceOpen;
     }
 
     if (cameraId != mCameraId) {
@@ -745,6 +755,15 @@
         *hasFlash = false;
     }
 
+    if (closeCameraDevice) {
+        res = disconnectCameraDevice();
+        if (res != OK) {
+            ALOGE("%s: Failed to disconnect camera device. %s (%d)", __FUNCTION__,
+                    strerror(-res), res);
+            return res;
+        }
+    }
+
     return OK;
 }
 
@@ -869,9 +888,13 @@
         return OK;
     }
 
-    mParameters.set(CameraParameters::KEY_FLASH_MODE,
-            CameraParameters::FLASH_MODE_OFF);
-    mDevice->setParameters(mParameters);
+    if (mParameters.get(CameraParameters::KEY_FLASH_MODE)) {
+        // There is a flash, turn if off.
+        // (If there isn't one, leave the parameter null)
+        mParameters.set(CameraParameters::KEY_FLASH_MODE,
+                CameraParameters::FLASH_MODE_OFF);
+        mDevice->setParameters(mParameters);
+    }
     mDevice->stopPreview();
     status_t res = native_window_api_disconnect(mSurface.get(),
             NATIVE_WINDOW_API_CAMERA);
diff --git a/services/camera/libcameraservice/CameraFlashlight.h b/services/camera/libcameraservice/CameraFlashlight.h
index 4d5fe8d..5cde372 100644
--- a/services/camera/libcameraservice/CameraFlashlight.h
+++ b/services/camera/libcameraservice/CameraFlashlight.h
@@ -203,7 +203,11 @@
         status_t getSmallestSurfaceSize(int32_t *width, int32_t *height);
 
         // protected by mLock
-        status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash);
+        // If this function opens camera device in order to check if it has a flash unit, the
+        // camera device will remain open if keepDeviceOpen is true and the camera device will be
+        // closed if keepDeviceOpen is false. If camera device is already open when calling this
+        // function, keepDeviceOpen is ignored.
+        status_t hasFlashUnitLocked(const String8& cameraId, bool *hasFlash, bool keepDeviceOpen);
 
         CameraModule *mCameraModule;
         const camera_module_callbacks_t *mCallbacks;
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index fcb72e8..13691e7 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -464,6 +464,12 @@
     if (rc.isOk()) {
         cameraInfo->facing = info.facing;
         cameraInfo->orientation = info.orientation;
+        // CameraInfo is for android.hardware.Camera which does not
+        // support external camera facing. The closest approximation would be
+        // front camera.
+        if (cameraInfo->orientation == CAMERA_FACING_EXTERNAL) {
+            cameraInfo->orientation = CAMERA_FACING_FRONT;
+        }
     }
     return rc;
 }
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 63e44fd..dbec34e 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -234,6 +234,7 @@
             res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
                     msg.string());
         } else {
+            Mutex::Autolock idLock(mStreamingRequestIdLock);
             mStreamingRequestId = submitInfo->mRequestId;
         }
     } else {
@@ -271,6 +272,7 @@
         return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
     }
 
+    Mutex::Autolock idLock(mStreamingRequestIdLock);
     if (mStreamingRequestId != requestId) {
         String8 msg = String8::format("Camera %d: Canceling request ID %d doesn't match "
                 "current request ID %d", mCameraId, requestId, mStreamingRequestId);
@@ -760,6 +762,7 @@
     }
 
     // FIXME: Also need check repeating burst.
+    Mutex::Autolock idLock(mStreamingRequestIdLock);
     if (mStreamingRequestId != REQUEST_ID_NONE) {
         String8 msg = String8::format(
             "Camera %d: Try to waitUntilIdle when there are active streaming requests",
@@ -792,6 +795,7 @@
         return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
     }
 
+    Mutex::Autolock idLock(mStreamingRequestIdLock);
     mStreamingRequestId = REQUEST_ID_NONE;
     status_t err = mDevice->flush(lastFrameNumber);
     if (err != OK) {
@@ -982,7 +986,7 @@
         remoteCb->onRepeatingRequestError(lastFrameNumber);
     }
 
-    Mutex::Autolock icl(mBinderSerializationLock);
+    Mutex::Autolock idLock(mStreamingRequestIdLock);
     mStreamingRequestId = REQUEST_ID_NONE;
 }
 
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.h b/services/camera/libcameraservice/api2/CameraDeviceClient.h
index 3660a18..d792b7d 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.h
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.h
@@ -208,6 +208,7 @@
 
     // Streaming request ID
     int32_t mStreamingRequestId;
+    Mutex mStreamingRequestIdLock;
     static const int32_t REQUEST_ID_NONE = -1;
 
     int32_t mRequestIdCounter;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 0de80bd..0e4e244 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1970,7 +1970,7 @@
     if (mIsConstrainedHighSpeedConfiguration) {
         pid_t requestThreadTid = mRequestThread->getTid();
         res = requestPriority(getpid(), requestThreadTid,
-                kConstrainedHighSpeedThreadPriority, true);
+                kConstrainedHighSpeedThreadPriority, /*asynchronous*/ false);
         if (res != OK) {
             ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
                     strerror(-res), res);
diff --git a/services/camera/libcameraservice/utils/AutoConditionLock.cpp b/services/camera/libcameraservice/utils/AutoConditionLock.cpp
index c8ee965..ed80a95 100644
--- a/services/camera/libcameraservice/utils/AutoConditionLock.cpp
+++ b/services/camera/libcameraservice/utils/AutoConditionLock.cpp
@@ -24,13 +24,15 @@
 
 // Locks manager-owned mutex
 AutoConditionLock::AutoConditionLock(const std::shared_ptr<WaitableMutexWrapper>& manager) :
-        mManager{manager}, mAutoLock{manager->mMutex} {}
+        mManager{manager}, mAutoLock{manager->mMutex}, mAcquired(false) {}
 
 // Unlocks manager-owned mutex
 AutoConditionLock::~AutoConditionLock() {
     // Unset the condition and wake everyone up before releasing lock
-    mManager->mState = false;
-    mManager->mCondition.broadcast();
+    if (mAcquired) {
+        mManager->mState = false;
+        mManager->mCondition.broadcast();
+    }
 }
 
 std::unique_ptr<AutoConditionLock> AutoConditionLock::waitAndAcquire(
@@ -59,6 +61,7 @@
 
     // Set the condition and return
     manager->mState = true;
+    scopedLock->mAcquired = true;
     return scopedLock;
 }
 
@@ -84,6 +87,7 @@
 
     // Set the condition and return
     manager->mState = true;
+    scopedLock->mAcquired = true;
     return scopedLock;
 }
 
diff --git a/services/camera/libcameraservice/utils/AutoConditionLock.h b/services/camera/libcameraservice/utils/AutoConditionLock.h
index 9a3eafc..b7f167b 100644
--- a/services/camera/libcameraservice/utils/AutoConditionLock.h
+++ b/services/camera/libcameraservice/utils/AutoConditionLock.h
@@ -92,6 +92,7 @@
 
     std::shared_ptr<WaitableMutexWrapper> mManager;
     Mutex::Autolock mAutoLock;
+    bool mAcquired;
 };
 
 }; // namespace android
diff --git a/services/mediacodec/mediacodec.rc b/services/mediacodec/mediacodec.rc
index e8df7be..d78e0a4 100644
--- a/services/mediacodec/mediacodec.rc
+++ b/services/mediacodec/mediacodec.rc
@@ -3,3 +3,4 @@
     user mediacodec
     group camera drmrpc mediadrm
     ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
diff --git a/services/mediadrm/Android.mk b/services/mediadrm/Android.mk
index f6ddf94..8baaf13 100644
--- a/services/mediadrm/Android.mk
+++ b/services/mediadrm/Android.mk
@@ -22,14 +22,15 @@
     main_mediadrmserver.cpp
 
 LOCAL_SHARED_LIBRARIES:= \
-    libui \
-    liblog \
-    libutils \
     libbinder \
     libcutils \
-    libstagefright \
-    libmediaplayerservice \
+    liblog \
     libmedia \
+    libmediadrm \
+    libmediaplayerservice \
+    libstagefright \
+    libui \
+    libutils \
 
 LOCAL_C_INCLUDES := \
     frameworks/av/media/libmediaplayerservice \
diff --git a/services/mediadrm/MediaDrmService.cpp b/services/mediadrm/MediaDrmService.cpp
index 36ab8fe..331c568 100644
--- a/services/mediadrm/MediaDrmService.cpp
+++ b/services/mediadrm/MediaDrmService.cpp
@@ -19,13 +19,13 @@
 
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaDrmService"
-#include <utils/Log.h>
 
-#include <binder/IServiceManager.h>
 #include "MediaDrmService.h"
 
-#include "Crypto.h"
-#include "Drm.h"
+#include <binder/IServiceManager.h>
+#include <media/Crypto.h>
+#include <media/Drm.h>
+#include <utils/Log.h>
 
 namespace android {
 
diff --git a/services/mediadrm/mediadrmserver.rc b/services/mediadrm/mediadrmserver.rc
index 374d24b..359c2cf 100644
--- a/services/mediadrm/mediadrmserver.rc
+++ b/services/mediadrm/mediadrmserver.rc
@@ -3,3 +3,4 @@
     user media
     group mediadrm drmrpc
     ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks
diff --git a/services/mediaextractor/mediaextractor.rc b/services/mediaextractor/mediaextractor.rc
index f733a2b..5fc2941 100644
--- a/services/mediaextractor/mediaextractor.rc
+++ b/services/mediaextractor/mediaextractor.rc
@@ -3,3 +3,4 @@
     user mediaex
     group drmrpc mediadrm
     ioprio rt 4
+    writepid /dev/cpuset/foreground/tasks