Merge "Part of fix for bug 5065047 build libchromium as a shared lib"
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index 9392cf2..d8fef09 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -84,6 +84,8 @@
 const char CameraParameters::KEY_VIDEO_SIZE[] = "video-size";
 const char CameraParameters::KEY_SUPPORTED_VIDEO_SIZES[] = "video-size-values";
 const char CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO[] = "preferred-preview-size-for-video";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_HW[] = "max-num-detected-faces-hw";
+const char CameraParameters::KEY_MAX_NUM_DETECTED_FACES_SW[] = "max-num-detected-faces-sw";
 
 const char CameraParameters::TRUE[] = "true";
 const char CameraParameters::FALSE[] = "false";
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 2d8e877..986f32c 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -110,11 +110,11 @@
     handle->extendedData.clear();
 }
 
-int BpDrmManagerService::addUniqueId(int uniqueId) {
+int BpDrmManagerService::addUniqueId(bool isNative) {
     LOGV("add uniqueid");
     Parcel data, reply;
     data.writeInterfaceToken(IDrmManagerService::getInterfaceDescriptor());
-    data.writeInt32(uniqueId);
+    data.writeInt32(isNative);
     remote()->transact(ADD_UNIQUEID, data, &reply);
     return reply.readInt32();
 }
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 1809619..3e4fe8c 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -49,32 +49,42 @@
 
 }
 
-int DrmManager::addUniqueId(int uniqueId) {
+int DrmManager::addUniqueId(bool isNative) {
     Mutex::Autolock _l(mLock);
-    if (0 == uniqueId) {
-        int temp = 0;
-        bool foundUniqueId = false;
-        srand(time(NULL));
 
-        while (!foundUniqueId) {
-            const int size = mUniqueIdVector.size();
-            temp = rand() % 100;
+    int temp = 0;
+    bool foundUniqueId = false;
+    const int size = mUniqueIdVector.size();
+    const int uniqueIdRange = 0xfff;
+    int maxLoopTimes = (uniqueIdRange - 1) / 2;
+    srand(time(NULL));
 
-            int index = 0;
-            for (; index < size; ++index) {
-                if (mUniqueIdVector.itemAt(index) == temp) {
-                    foundUniqueId = false;
-                    break;
-                }
-            }
-            if (index == size) {
-                foundUniqueId = true;
+    while (!foundUniqueId) {
+        temp = rand() & uniqueIdRange;
+
+        if (isNative) {
+            // set a flag to differentiate DrmManagerClient
+            // created from native side and java side
+            temp |= 0x1000;
+        }
+
+        int index = 0;
+        for (; index < size; ++index) {
+            if (mUniqueIdVector.itemAt(index) == temp) {
+                foundUniqueId = false;
+                break;
             }
         }
-        uniqueId = temp;
+        if (index == size) {
+            foundUniqueId = true;
+        }
+
+        maxLoopTimes --;
+        LOG_FATAL_IF(maxLoopTimes <= 0, "cannot find an unique ID for this session");
     }
-    mUniqueIdVector.push(uniqueId);
-    return uniqueId;
+
+    mUniqueIdVector.push(temp);
+    return temp;
 }
 
 void DrmManager::removeUniqueId(int uniqueId) {
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index 583669e..7ebcac3 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -78,8 +78,8 @@
     delete mDrmManager; mDrmManager = NULL;
 }
 
-int DrmManagerService::addUniqueId(int uniqueId) {
-    return mDrmManager->addUniqueId(uniqueId);
+int DrmManagerService::addUniqueId(bool isNative) {
+    return mDrmManager->addUniqueId(isNative);
 }
 
 void DrmManagerService::removeUniqueId(int uniqueId) {
diff --git a/drm/libdrmframework/DrmManagerClient.cpp b/drm/libdrmframework/DrmManagerClient.cpp
index b50199f..c9c0d57 100644
--- a/drm/libdrmframework/DrmManagerClient.cpp
+++ b/drm/libdrmframework/DrmManagerClient.cpp
@@ -24,7 +24,7 @@
 
 DrmManagerClient::DrmManagerClient():
         mUniqueId(0), mDrmManagerClientImpl(NULL) {
-    mDrmManagerClientImpl = DrmManagerClientImpl::create(&mUniqueId);
+    mDrmManagerClientImpl = DrmManagerClientImpl::create(&mUniqueId, true);
     mDrmManagerClientImpl->addClient(mUniqueId);
 }
 
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index a36bd4a..67f58ca 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -33,13 +33,10 @@
 sp<DrmManagerClientImpl::DeathNotifier> DrmManagerClientImpl::sDeathNotifier;
 const String8 DrmManagerClientImpl::EMPTY_STRING("");
 
-DrmManagerClientImpl* DrmManagerClientImpl::create(int* pUniqueId) {
-    if (0 == *pUniqueId) {
-        int uniqueId = getDrmManagerService()->addUniqueId(*pUniqueId);
-        *pUniqueId = uniqueId;
-    } else {
-        getDrmManagerService()->addUniqueId(*pUniqueId);
-    }
+DrmManagerClientImpl* DrmManagerClientImpl::create(
+        int* pUniqueId, bool isNative) {
+    *pUniqueId = getDrmManagerService()->addUniqueId(isNative);
+
     return new DrmManagerClientImpl();
 }
 
diff --git a/drm/libdrmframework/include/DrmManager.h b/drm/libdrmframework/include/DrmManager.h
index af2c2a8..ac2b946 100644
--- a/drm/libdrmframework/include/DrmManager.h
+++ b/drm/libdrmframework/include/DrmManager.h
@@ -53,7 +53,7 @@
     virtual ~DrmManager();
 
 public:
-    int addUniqueId(int uniqueId);
+    int addUniqueId(bool isNative);
 
     void removeUniqueId(int uniqueId);
 
diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h
index 564896b..e3338d9 100644
--- a/drm/libdrmframework/include/DrmManagerClientImpl.h
+++ b/drm/libdrmframework/include/DrmManagerClientImpl.h
@@ -38,7 +38,7 @@
     DrmManagerClientImpl() { }
 
 public:
-    static DrmManagerClientImpl* create(int* pUniqueId);
+    static DrmManagerClientImpl* create(int* pUniqueId, bool isNative);
 
     static void remove(int uniqueId);
 
diff --git a/drm/libdrmframework/include/DrmManagerService.h b/drm/libdrmframework/include/DrmManagerService.h
index 227496a..9cb5804 100644
--- a/drm/libdrmframework/include/DrmManagerService.h
+++ b/drm/libdrmframework/include/DrmManagerService.h
@@ -46,7 +46,7 @@
     virtual ~DrmManagerService();
 
 public:
-    int addUniqueId(int uniqueId);
+    int addUniqueId(bool isNative);
 
     void removeUniqueId(int uniqueId);
 
diff --git a/drm/libdrmframework/include/IDrmManagerService.h b/drm/libdrmframework/include/IDrmManagerService.h
index 7727e55..b9618bb 100644
--- a/drm/libdrmframework/include/IDrmManagerService.h
+++ b/drm/libdrmframework/include/IDrmManagerService.h
@@ -81,7 +81,7 @@
     DECLARE_META_INTERFACE(DrmManagerService);
 
 public:
-    virtual int addUniqueId(int uniqueId) = 0;
+    virtual int addUniqueId(bool isNative) = 0;
 
     virtual void removeUniqueId(int uniqueId) = 0;
 
@@ -167,7 +167,7 @@
     BpDrmManagerService(const sp<IBinder>& impl)
             : BpInterface<IDrmManagerService>(impl) {}
 
-    virtual int addUniqueId(int uniqueId);
+    virtual int addUniqueId(bool isNative);
 
     virtual void removeUniqueId(int uniqueId);
 
diff --git a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
index b61e3d3..4a5afcf 100644
--- a/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
+++ b/drm/libdrmframework/plugins/common/include/DrmEngineBase.h
@@ -143,7 +143,13 @@
      * Register a callback to be invoked when the caller required to
      * receive necessary information
      *
-     * @param[in] uniqueId Unique identifier for a session
+     * @param[in] uniqueId Unique identifier for a session. uniqueId is a random
+     *                     number generated in the DRM service. If the DrmManagerClient
+     *                     is created in native code, uniqueId will be a number ranged
+     *                     from 0x1000 to 0x1fff. If it comes from Java code, the uniqueId
+     *                     will be a number ranged from 0x00 to 0xfff. So bit 0x1000 in
+     *                     uniqueId could be used in DRM plugins to differentiate native
+     *                     OnInfoListener and Java OnInfoListener.
      * @param[in] infoListener Listener
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h
index 83d4f6d..d2f398a 100644
--- a/include/camera/CameraParameters.h
+++ b/include/camera/CameraParameters.h
@@ -455,6 +455,16 @@
     // Example: "176x144,1280x720". Read only.
     static const char KEY_SUPPORTED_VIDEO_SIZES[];
 
+    // The maximum number of detected faces supported by hardware face
+    // detection. If the value is 0, hardware face detection is not supported.
+    // Example: "5". Read only
+    static const char KEY_MAX_NUM_DETECTED_FACES_HW[];
+
+    // The maximum number of detected faces supported by software face
+    // detection. If the value is 0, software face detection is not supported.
+    // Example: "5". Read only
+    static const char KEY_MAX_NUM_DETECTED_FACES_SW[];
+
     // Preferred preview frame size in pixels for video recording.
     // The width and height must be one of the supported sizes retrieved
     // via KEY_SUPPORTED_PREVIEW_SIZES. This key can be used only when
diff --git a/include/media/AudioEffect.h b/include/media/AudioEffect.h
index 496b23e..1417416 100644
--- a/include/media/AudioEffect.h
+++ b/include/media/AudioEffect.h
@@ -21,6 +21,7 @@
 #include <sys/types.h>
 
 #include <media/IAudioFlinger.h>
+#include <media/IAudioPolicyService.h>
 #include <media/IEffect.h>
 #include <media/IEffectClient.h>
 #include <hardware/audio_effect.h>
@@ -111,6 +112,36 @@
 
 
     /*
+     * Returns a list of descriptors corresponding to the pre processings enabled by default
+     * on an AudioRecord with the supplied audio session ID.
+     *
+     * Parameters:
+     *      audioSession:  audio session ID.
+     *      descriptors: address where the effect descriptors should be returned.
+     *      count: as input, the maximum number of descriptor than should be returned
+     *             as output, the number of descriptor returned if status is NO_ERROR or the actual
+     *             number of enabled pre processings if status is NO_MEMORY
+     *
+     * Returned status (from utils/Errors.h) can be:
+     *      NO_ERROR        successful operation.
+     *      NO_MEMORY       the number of descriptor to return is more than the maximum number
+     *                      indicated by count.
+     *      PERMISSION_DENIED could not get AudioFlinger interface
+     *      NO_INIT         effect library failed to initialize
+     *      BAD_VALUE       invalid audio session or descriptor pointers
+     *
+     * Returned value
+     *   *descriptor updated with descriptors of pre processings enabled by default
+     *   *count      number of descriptors returned if returned status is N_ERROR.
+     *               total number of pre processing enabled by default if returned status is
+     *               NO_MEMORY. This happens if the count passed as input is less than the number
+     *               of descriptors to return
+     */
+    static status_t queryDefaultPreProcessing(int audioSession,
+                                              effect_descriptor_t *descriptors,
+                                              uint32_t *count);
+
+    /*
      * Events used by callback function (effect_callback_t).
      */
     enum event_type {
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 86b9f85..ed265e1 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -85,6 +85,9 @@
                                     int id) = 0;
     virtual status_t unregisterEffect(int id) = 0;
     virtual bool     isStreamActive(int stream, uint32_t inPastMs = 0) const = 0;
+    virtual status_t queryDefaultPreProcessing(int audioSession,
+                                              effect_descriptor_t *descriptors,
+                                              uint32_t *count) = 0;
 };
 
 
diff --git a/include/media/IMediaRecorder.h b/include/media/IMediaRecorder.h
index 007aea6..ec84e25 100644
--- a/include/media/IMediaRecorder.h
+++ b/include/media/IMediaRecorder.h
@@ -43,7 +43,6 @@
     virtual status_t setAudioEncoder(int ae) = 0;
     virtual status_t setOutputFile(const char* path) = 0;
     virtual status_t setOutputFile(int fd, int64_t offset, int64_t length) = 0;
-    virtual status_t setOutputFileAuxiliary(int fd) = 0;
     virtual status_t setVideoSize(int width, int height) = 0;
     virtual status_t setVideoFrameRate(int frames_per_second) = 0;
     virtual status_t setParameters(const String8& params) = 0;
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 1136f6c..1a67671 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -130,13 +130,22 @@
     MEDIA_PLAYER_PLAYBACK_COMPLETE  = 1 << 7
 };
 
-enum media_set_parameter_keys {
-    KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX = 1000,
-    KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE = 1001,
+// Keep KEY_PARAMETER_* in sync with MediaPlayer.java.
+// The same enum space is used for both set and get, in case there are future keys that
+// can be both set and get.  But as of now, all parameters are either set only or get only.
+enum media_parameter_keys {
+    KEY_PARAMETER_TIMED_TEXT_TRACK_INDEX = 1000,                // set only
+    KEY_PARAMETER_TIMED_TEXT_ADD_OUT_OF_BAND_SOURCE = 1001,     // set only
 
     // Streaming/buffering parameters
-    KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS = 1100,
+    KEY_PARAMETER_CACHE_STAT_COLLECT_FREQ_MS = 1100,            // set only
+
+    // Return a Parcel containing a single int, which is the channel count of the
+    // audio track, or zero for error (e.g. no audio track) or unknown.
+    KEY_PARAMETER_AUDIO_CHANNEL_COUNT = 1200,                   // get only
+
 };
+
 // ----------------------------------------------------------------------------
 // ref-counted object for callbacks
 class MediaPlayerListener: virtual public RefBase
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index 72d3736..30db642 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -215,7 +215,6 @@
     status_t    setAudioEncoder(int ae);
     status_t    setOutputFile(const char* path);
     status_t    setOutputFile(int fd, int64_t offset, int64_t length);
-    status_t    setOutputFileAuxiliary(int fd);
     status_t    setVideoSize(int width, int height);
     status_t    setVideoFrameRate(int frames_per_second);
     status_t    setParameters(const String8& params);
@@ -249,7 +248,6 @@
     bool                        mIsAudioEncoderSet;
     bool                        mIsVideoEncoderSet;
     bool                        mIsOutputFileSet;
-    bool                        mIsAuxiliaryOutputFileSet;
     Mutex                       mLock;
     Mutex                       mNotifyLock;
 };
diff --git a/include/media/stagefright/CameraSourceTimeLapse.h b/include/media/stagefright/CameraSourceTimeLapse.h
index f07ebba..0e264c7 100644
--- a/include/media/stagefright/CameraSourceTimeLapse.h
+++ b/include/media/stagefright/CameraSourceTimeLapse.h
@@ -53,27 +53,10 @@
     void startQuickReadReturns();
 
 private:
-    // If true, will use still camera takePicture() for time lapse frames
-    // If false, will use the videocamera frames instead.
-    bool mUseStillCameraForTimeLapse;
-
-    // Size of picture taken from still camera. This may be larger than the size
-    // of the video, as still camera may not support the exact video resolution
-    // demanded. See setPictureSizeToClosestSupported().
-    int32_t mPictureWidth;
-    int32_t mPictureHeight;
-
     // size of the encoded video.
     int32_t mVideoWidth;
     int32_t mVideoHeight;
 
-    // True if we need to crop the still camera image to get the video frame.
-    bool mNeedCropping;
-
-    // Start location of the cropping rectangle.
-    int32_t mCropRectStartX;
-    int32_t mCropRectStartY;
-
     // Time between capture of two frames during time lapse recording
     // Negative value indicates that timelapse is disabled.
     int64_t mTimeBetweenTimeLapseFrameCaptureUs;
@@ -84,9 +67,6 @@
     // Real timestamp of the last encoded time lapse frame
     int64_t mLastTimeLapseFrameRealTimestampUs;
 
-    // Thread id of thread which takes still picture and sleeps in a loop.
-    pthread_t mThreadTimeLapse;
-
     // Variable set in dataCallbackTimestamp() to help skipCurrentFrame()
     // to know if current frame needs to be skipped.
     bool mSkipCurrentFrame;
@@ -111,9 +91,6 @@
     // Lock for accessing quick stop variables.
     Mutex mQuickStopLock;
 
-    // Condition variable to wake up still picture thread.
-    Condition mTakePictureCondition;
-
     // mQuickStop is set to true if we use quick read() returns, otherwise it is set
     // to false. Once in this mode read() return a copy of the last read frame
     // with the same time stamp. See startQuickReadReturns().
@@ -148,32 +125,13 @@
     // Wrapper over CameraSource::read() to implement quick stop.
     virtual status_t read(MediaBuffer **buffer, const ReadOptions *options = NULL);
 
-    // For still camera case starts a thread which calls camera's takePicture()
-    // in a loop. For video camera case, just starts the camera's video recording.
-    virtual void startCameraRecording();
-
-    // For still camera case joins the thread created in startCameraRecording().
     // For video camera case, just stops the camera's video recording.
     virtual void stopCameraRecording();
 
-    // For still camera case don't need to do anything as memory is locally
-    // allocated with refcounting.
-    // For video camera case just tell the camera to release the frame.
-    virtual void releaseRecordingFrame(const sp<IMemory>& frame);
-
     // mSkipCurrentFrame is set to true in dataCallbackTimestamp() if the current
     // frame needs to be skipped and this function just returns the value of mSkipCurrentFrame.
     virtual bool skipCurrentFrame(int64_t timestampUs);
 
-    // Handles the callback to handle raw frame data from the still camera.
-    // Creates a copy of the frame data as the camera can reuse the frame memory
-    // once this callback returns. The function also sets a new timstamp corresponding
-    // to one frame time ahead of the last encoded frame's time stamp. It then
-    // calls dataCallbackTimestamp() of the base class with the copied data and the
-    // modified timestamp, which will think that it recieved the frame from a video
-    // camera and proceed as usual.
-    virtual void dataCallback(int32_t msgType, const sp<IMemory> &data);
-
     // In the video camera case calls skipFrameAndModifyTimeStamp() to modify
     // timestamp and set mSkipCurrentFrame.
     // Then it calls the base CameraSource::dataCallbackTimestamp()
@@ -189,24 +147,6 @@
     // Otherwise returns false.
     bool trySettingVideoSize(int32_t width, int32_t height);
 
-    // The still camera may not support the demanded video width and height.
-    // We look for the supported picture sizes from the still camera and
-    // choose the smallest one with either dimensions higher than the corresponding
-    // video dimensions. The still picture will be cropped to get the video frame.
-    // The function returns true if the camera supports picture sizes greater than
-    // or equal to the passed in width and height, and false otherwise.
-    bool setPictureSizeToClosestSupported(int32_t width, int32_t height);
-
-    // Computes the offset of the rectangle from where to start cropping the
-    // still image into the video frame. We choose the center of the image to be
-    // cropped. The offset is stored in (mCropRectStartX, mCropRectStartY).
-    bool computeCropRectangleOffset();
-
-    // Crops the source data into a smaller image starting at
-    // (mCropRectStartX, mCropRectStartY) and of the size of the video frame.
-    // The data is returned into a newly allocated IMemory.
-    sp<IMemory> cropYUVImage(const sp<IMemory> &source_data);
-
     // When video camera is used for time lapse capture, returns true
     // until enough time has passed for the next time lapse frame. When
     // the frame needs to be encoded, it returns false and also modifies
@@ -217,22 +157,6 @@
     // Wrapper to enter threadTimeLapseEntry()
     static void *ThreadTimeLapseWrapper(void *me);
 
-    // Runs a loop which sleeps until a still picture is required
-    // and then calls mCamera->takePicture() to take the still picture.
-    // Used only in the case mUseStillCameraForTimeLapse = true.
-    void threadTimeLapseEntry();
-
-    // Wrapper to enter threadStartPreview()
-    static void *ThreadStartPreviewWrapper(void *me);
-
-    // Starts the camera's preview.
-    void threadStartPreview();
-
-    // Starts thread ThreadStartPreviewWrapper() for restarting preview.
-    // Needs to be done in a thread so that dataCallback() which calls this function
-    // can return, and the camera can know that takePicture() is done.
-    void restartPreview();
-
     // Creates a copy of source_data into a new memory of final type MemoryBase.
     sp<IMemory> createIMemoryCopy(const sp<IMemory> &source_data);
 
diff --git a/include/media/stagefright/MetadataBufferType.h b/include/media/stagefright/MetadataBufferType.h
index 52a3257..4eaf8ac 100644
--- a/include/media/stagefright/MetadataBufferType.h
+++ b/include/media/stagefright/MetadataBufferType.h
@@ -69,6 +69,16 @@
      * kMetadataBufferTypeGrallocSource is used to indicate that
      * the payload of the metadata buffers can be interpreted as
      * a buffer_handle_t.
+     * So in this case,the metadata that the encoder receives
+     * will have a byte stream that consists of two parts:
+     * 1. First, there is an integer indicating that it is a GRAlloc
+     * source (kMetadataBufferTypeGrallocSource)
+     * 2. This is followed by the buffer_handle_t that is a handle to the
+     * GRalloc buffer. The encoder needs to interpret this GRalloc handle
+     * and encode the frames.
+     * --------------------------------------------------------------
+     * |  kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
+     * --------------------------------------------------------------
      */
     kMetadataBufferTypeGrallocSource = 1,
 
diff --git a/include/media/stagefright/SurfaceMediaSource.h b/include/media/stagefright/SurfaceMediaSource.h
index 56bd9c3..fab258c 100644
--- a/include/media/stagefright/SurfaceMediaSource.h
+++ b/include/media/stagefright/SurfaceMediaSource.h
@@ -63,6 +63,10 @@
             MediaBuffer **buffer, const ReadOptions *options = NULL);
     virtual sp<MetaData> getFormat();
 
+    // Pass the metadata over to the buffer, call when you have the lock
+    void passMetadataBufferLocked(MediaBuffer **buffer);
+    bool checkBufferMatchesSlot(int slot, MediaBuffer *buffer);
+
     // Get / Set the frame rate used for encoding. Default fps = 30
     status_t setFrameRate(int32_t fps) ;
     int32_t getFrameRate( ) const;
@@ -152,7 +156,7 @@
     status_t setBufferCountServer(int bufferCount);
 
     // getTimestamp retrieves the timestamp associated with the image
-    // set by the most recent call to updateFrameInfoLocked().
+    // set by the most recent call to read()
     //
     // The timestamp is in nanoseconds, and is monotonically increasing. Its
     // other semantics (zero point, etc) are source-dependent and should be
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp
index 3919551..0633744 100644
--- a/media/libmedia/AudioEffect.cpp
+++ b/media/libmedia/AudioEffect.cpp
@@ -419,6 +419,15 @@
     return af->getEffectDescriptor(uuid, descriptor);
 }
 
+
+status_t AudioEffect::queryDefaultPreProcessing(int audioSession,
+                                          effect_descriptor_t *descriptors,
+                                          uint32_t *count)
+{
+    const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
+    if (aps == 0) return PERMISSION_DENIED;
+    return aps->queryDefaultPreProcessing(audioSession, descriptors, count);
+}
 // -------------------------------------------------------------------------
 
 status_t AudioEffect::stringToGuid(const char *str, effect_uuid_t *guid)
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 1ec596e..16554c2 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -590,7 +590,7 @@
 audio_io_handle_t AudioRecord::getInput()
 {
     AutoMutex lock(mLock);
-    return getInput_l();
+    return mInput;
 }
 
 // must be called with mLock held
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 49d410f..15f4be0 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -53,6 +53,7 @@
     UNREGISTER_EFFECT,
     IS_STREAM_ACTIVE,
     GET_DEVICES_FOR_STREAM,
+    QUERY_DEFAULT_PRE_PROCESSING
 };
 
 class BpAudioPolicyService : public BpInterface<IAudioPolicyService>
@@ -321,6 +322,31 @@
         remote()->transact(IS_STREAM_ACTIVE, data, &reply);
         return reply.readInt32();
     }
+
+    virtual status_t queryDefaultPreProcessing(int audioSession,
+                                               effect_descriptor_t *descriptors,
+                                               uint32_t *count)
+    {
+        if (descriptors == NULL || count == NULL) {
+            return BAD_VALUE;
+        }
+        Parcel data, reply;
+        data.writeInterfaceToken(IAudioPolicyService::getInterfaceDescriptor());
+        data.writeInt32(audioSession);
+        data.writeInt32(*count);
+        status_t status = remote()->transact(QUERY_DEFAULT_PRE_PROCESSING, data, &reply);
+        if (status != NO_ERROR) {
+            return status;
+        }
+        status = static_cast <status_t> (reply.readInt32());
+        uint32_t retCount = reply.readInt32();
+        if (retCount != 0) {
+            uint32_t numDesc = (retCount < *count) ? retCount : *count;
+            reply.read(descriptors, sizeof(effect_descriptor_t) * numDesc);
+        }
+        *count = retCount;
+        return status;
+    }
 };
 
 IMPLEMENT_META_INTERFACE(AudioPolicyService, "android.media.IAudioPolicyService");
@@ -559,6 +585,29 @@
             return NO_ERROR;
         } break;
 
+        case QUERY_DEFAULT_PRE_PROCESSING: {
+            CHECK_INTERFACE(IAudioPolicyService, data, reply);
+            int audioSession = data.readInt32();
+            uint32_t count = data.readInt32();
+            uint32_t retCount = count;
+            effect_descriptor_t *descriptors =
+                    (effect_descriptor_t *)new char[count * sizeof(effect_descriptor_t)];
+            status_t status = queryDefaultPreProcessing(audioSession, descriptors, &retCount);
+            reply->writeInt32(status);
+            if (status != NO_ERROR && status != NO_MEMORY) {
+                retCount = 0;
+            }
+            reply->writeInt32(retCount);
+            if (retCount) {
+                if (retCount < count) {
+                    count = retCount;
+                }
+                reply->write(descriptors, sizeof(effect_descriptor_t) * count);
+            }
+            delete[] descriptors;
+            return status;
+        }
+
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index 7e44c29..38e111e 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -46,7 +46,6 @@
     SET_AUDIO_ENCODER,
     SET_OUTPUT_FILE_PATH,
     SET_OUTPUT_FILE_FD,
-    SET_OUTPUT_FILE_AUXILIARY_FD,
     SET_VIDEO_SIZE,
     SET_VIDEO_FRAMERATE,
     SET_PARAMETERS,
@@ -177,15 +176,6 @@
         return reply.readInt32();
     }
 
-    status_t setOutputFileAuxiliary(int fd) {
-        LOGV("setOutputFileAuxiliary(%d)", fd);
-        Parcel data, reply;
-        data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
-        data.writeFileDescriptor(fd);
-        remote()->transact(SET_OUTPUT_FILE_AUXILIARY_FD, data, &reply);
-        return reply.readInt32();
-    }
-
     status_t setVideoSize(int width, int height)
     {
         LOGV("setVideoSize(%dx%d)", width, height);
@@ -404,13 +394,6 @@
             ::close(fd);
             return NO_ERROR;
         } break;
-        case SET_OUTPUT_FILE_AUXILIARY_FD: {
-            LOGV("SET_OUTPUT_FILE_AUXILIARY_FD");
-            CHECK_INTERFACE(IMediaRecorder, data, reply);
-            int fd = dup(data.readFileDescriptor());
-            reply->writeInt32(setOutputFileAuxiliary(fd));
-            return NO_ERROR;
-        } break;
         case SET_VIDEO_SIZE: {
             LOGV("SET_VIDEO_SIZE");
             CHECK_INTERFACE(IMediaRecorder, data, reply);
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index fab674c..11d281f 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -322,32 +322,6 @@
     return ret;
 }
 
-status_t MediaRecorder::setOutputFileAuxiliary(int fd)
-{
-    LOGV("setOutputFileAuxiliary(%d)", fd);
-    if(mMediaRecorder == NULL) {
-        LOGE("media recorder is not initialized yet");
-        return INVALID_OPERATION;
-    }
-    if (mIsAuxiliaryOutputFileSet) {
-        LOGE("output file has already been set");
-        return INVALID_OPERATION;
-    }
-    if (!(mCurrentState & MEDIA_RECORDER_DATASOURCE_CONFIGURED)) {
-        LOGE("setOutputFile called in an invalid state(%d)", mCurrentState);
-        return INVALID_OPERATION;
-    }
-
-    status_t ret = mMediaRecorder->setOutputFileAuxiliary(fd);
-    if (OK != ret) {
-        LOGV("setOutputFileAuxiliary failed: %d", ret);
-        mCurrentState = MEDIA_RECORDER_ERROR;
-        return ret;
-    }
-    mIsAuxiliaryOutputFileSet = true;
-    return ret;
-}
-
 status_t MediaRecorder::setVideoSize(int width, int height)
 {
     LOGV("setVideoSize(%d, %d)", width, height);
@@ -629,7 +603,6 @@
     mIsAudioEncoderSet = false;
     mIsVideoEncoderSet = false;
     mIsOutputFileSet   = false;
-    mIsAuxiliaryOutputFileSet = false;
 }
 
 // Release should be OK in any state
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 905b885..6f80b35 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -178,17 +178,6 @@
     return mRecorder->setOutputFile(fd, offset, length);
 }
 
-status_t MediaRecorderClient::setOutputFileAuxiliary(int fd)
-{
-    LOGV("setOutputFileAuxiliary(%d)", fd);
-    Mutex::Autolock lock(mLock);
-    if (mRecorder == NULL) {
-        LOGE("recorder is not initialized");
-        return NO_INIT;
-    }
-    return mRecorder->setOutputFileAuxiliary(fd);
-}
-
 status_t MediaRecorderClient::setVideoSize(int width, int height)
 {
     LOGV("setVideoSize(%dx%d)", width, height);
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index c87a3c0..c9ccf22 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -41,7 +41,6 @@
     virtual     status_t   setOutputFile(const char* path);
     virtual     status_t   setOutputFile(int fd, int64_t offset,
                                                   int64_t length);
-    virtual     status_t   setOutputFileAuxiliary(int fd);
     virtual     status_t   setVideoSize(int width, int height);
     virtual     status_t   setVideoFrameRate(int frames_per_second);
     virtual     status_t   setParameters(const String8& params);
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 6427bb7..6fdb726 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -28,9 +28,7 @@
 #include <media/stagefright/AMRWriter.h>
 #include <media/stagefright/AACWriter.h>
 #include <media/stagefright/CameraSource.h>
-#include <media/stagefright/VideoSourceDownSampler.h>
 #include <media/stagefright/CameraSourceTimeLapse.h>
-#include <media/stagefright/MediaSourceSplitter.h>
 #include <media/stagefright/MPEG2TSWriter.h>
 #include <media/stagefright/MPEG4Writer.h>
 #include <media/stagefright/MediaDebug.h>
@@ -67,8 +65,8 @@
 
 
 StagefrightRecorder::StagefrightRecorder()
-    : mWriter(NULL), mWriterAux(NULL),
-      mOutputFd(-1), mOutputFdAux(-1),
+    : mWriter(NULL),
+      mOutputFd(-1),
       mAudioSource(AUDIO_SOURCE_CNT),
       mVideoSource(VIDEO_SOURCE_LIST_END),
       mStarted(false), mSurfaceMediaSource(NULL) {
@@ -259,24 +257,6 @@
     return OK;
 }
 
-status_t StagefrightRecorder::setOutputFileAuxiliary(int fd) {
-    LOGV("setOutputFileAuxiliary: %d", fd);
-
-    if (fd < 0) {
-        LOGE("Invalid file descriptor: %d", fd);
-        return -EBADF;
-    }
-
-    mCaptureAuxVideo = true;
-
-    if (mOutputFdAux >= 0) {
-        ::close(mOutputFdAux);
-    }
-    mOutputFdAux = dup(fd);
-
-    return OK;
-}
-
 // Attempt to parse an int64 literal optionally surrounded by whitespace,
 // returns true on success, false otherwise.
 static bool safe_strtoi64(const char *s, int64_t *val) {
@@ -573,42 +553,6 @@
     return OK;
 }
 
-status_t StagefrightRecorder::setParamAuxVideoWidth(int32_t width) {
-    LOGV("setParamAuxVideoWidth : %d", width);
-
-    if (width <= 0) {
-        LOGE("Width (%d) is not positive", width);
-        return BAD_VALUE;
-    }
-
-    mAuxVideoWidth = width;
-    return OK;
-}
-
-status_t StagefrightRecorder::setParamAuxVideoHeight(int32_t height) {
-    LOGV("setParamAuxVideoHeight : %d", height);
-
-    if (height <= 0) {
-        LOGE("Height (%d) is not positive", height);
-        return BAD_VALUE;
-    }
-
-    mAuxVideoHeight = height;
-    return OK;
-}
-
-status_t StagefrightRecorder::setParamAuxVideoEncodingBitRate(int32_t bitRate) {
-    LOGV("StagefrightRecorder::setParamAuxVideoEncodingBitRate: %d", bitRate);
-
-    if (bitRate <= 0) {
-        LOGE("Invalid video encoding bit rate: %d", bitRate);
-        return BAD_VALUE;
-    }
-
-    mAuxVideoBitRate = bitRate;
-    return OK;
-}
-
 status_t StagefrightRecorder::setParamGeoDataLongitude(
     int32_t longitudex10000) {
 
@@ -738,21 +682,6 @@
             return setParamTimeBetweenTimeLapseFrameCapture(
                     1000LL * timeBetweenTimeLapseFrameCaptureMs);
         }
-    } else if (key == "video-aux-param-width") {
-        int32_t auxWidth;
-        if (safe_strtoi32(value.string(), &auxWidth)) {
-            return setParamAuxVideoWidth(auxWidth);
-        }
-    } else if (key == "video-aux-param-height") {
-        int32_t auxHeight;
-        if (safe_strtoi32(value.string(), &auxHeight)) {
-            return setParamAuxVideoHeight(auxHeight);
-        }
-    } else if (key == "video-aux-param-encoding-bitrate") {
-        int32_t auxVideoBitRate;
-        if (safe_strtoi32(value.string(), &auxVideoBitRate)) {
-            return setParamAuxVideoEncodingBitRate(auxVideoBitRate);
-        }
     } else {
         LOGE("setParameter: failed to find key %s", key.string());
     }
@@ -1517,7 +1446,6 @@
 }
 
 status_t StagefrightRecorder::setupMPEG4Recording(
-        bool useSplitCameraSource,
         int outputFd,
         int32_t videoWidth, int32_t videoHeight,
         int32_t videoBitRate,
@@ -1531,28 +1459,7 @@
     if (mVideoSource < VIDEO_SOURCE_LIST_END) {
 
         sp<MediaSource> mediaSource;
-        if (useSplitCameraSource) {
-            // TODO: Check if there is a better way to handle this
-            if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
-                LOGE("Cannot use split camera when encoding frames");
-                return INVALID_OPERATION;
-            }
-            LOGV("Using Split camera source");
-            mediaSource = mCameraSourceSplitter->createClient();
-        } else {
-           err = setupMediaSource(&mediaSource);
-        }
-
-        if ((videoWidth != mVideoWidth) || (videoHeight != mVideoHeight)) {
-            // TODO: Might be able to handle downsampling even if using GRAlloc
-            if (mVideoSource == VIDEO_SOURCE_GRALLOC_BUFFER) {
-                LOGE("Cannot change size or Downsample when encoding frames");
-                return INVALID_OPERATION;
-            }
-            // Use downsampling from the original source.
-            mediaSource =
-                new VideoSourceDownSampler(mediaSource, videoWidth, videoHeight);
-        }
+        err = setupMediaSource(&mediaSource);
         if (err != OK) {
             return err;
         }
@@ -1620,24 +1527,8 @@
 }
 
 status_t StagefrightRecorder::startMPEG4Recording() {
-    if (mCaptureAuxVideo) {
-        if (!mCaptureTimeLapse) {
-            LOGE("Auxiliary video can be captured only in time lapse mode");
-            return UNKNOWN_ERROR;
-        }
-        LOGV("Creating MediaSourceSplitter");
-        sp<CameraSource> cameraSource;
-        status_t err = setupCameraSource(&cameraSource);
-        if (err != OK) {
-            return err;
-        }
-        mCameraSourceSplitter = new MediaSourceSplitter(cameraSource);
-    } else {
-        mCameraSourceSplitter = NULL;
-    }
-
     int32_t totalBitRate;
-    status_t err = setupMPEG4Recording(mCaptureAuxVideo,
+    status_t err = setupMPEG4Recording(
             mOutputFd, mVideoWidth, mVideoHeight,
             mVideoBitRate, &totalBitRate, &mWriter);
     if (err != OK) {
@@ -1653,33 +1544,6 @@
         return err;
     }
 
-    if (mCaptureAuxVideo) {
-        CHECK(mOutputFdAux >= 0);
-        if (mWriterAux != NULL) {
-            LOGE("Auxiliary File writer is not avaialble");
-            return UNKNOWN_ERROR;
-        }
-        if ((mAuxVideoWidth > mVideoWidth) || (mAuxVideoHeight > mVideoHeight) ||
-                ((mAuxVideoWidth == mVideoWidth) && mAuxVideoHeight == mVideoHeight)) {
-            LOGE("Auxiliary video size (%d x %d) same or larger than the main video size (%d x %d)",
-                    mAuxVideoWidth, mAuxVideoHeight, mVideoWidth, mVideoHeight);
-            return UNKNOWN_ERROR;
-        }
-
-        int32_t totalBitrateAux;
-        err = setupMPEG4Recording(mCaptureAuxVideo,
-                mOutputFdAux, mAuxVideoWidth, mAuxVideoHeight,
-                mAuxVideoBitRate, &totalBitrateAux, &mWriterAux);
-        if (err != OK) {
-            return err;
-        }
-
-        sp<MetaData> metaAux = new MetaData;
-        setupMPEG4MetaData(startTimeUs, totalBitrateAux, &metaAux);
-
-        return mWriterAux->start(metaAux.get());
-    }
-
     return OK;
 }
 
@@ -1690,13 +1554,6 @@
     }
     mWriter->pause();
 
-    if (mCaptureAuxVideo) {
-        if (mWriterAux == NULL) {
-            return UNKNOWN_ERROR;
-        }
-        mWriterAux->pause();
-    }
-
     if (mStarted) {
         mStarted = false;
 
@@ -1724,13 +1581,6 @@
         mCameraSourceTimeLapse = NULL;
     }
 
-    if (mCaptureAuxVideo) {
-        if (mWriterAux != NULL) {
-            mWriterAux->stop();
-            mWriterAux.clear();
-        }
-    }
-
     if (mWriter != NULL) {
         err = mWriter->stop();
         mWriter.clear();
@@ -1741,13 +1591,6 @@
         mOutputFd = -1;
     }
 
-    if (mCaptureAuxVideo) {
-        if (mOutputFdAux >= 0) {
-            ::close(mOutputFdAux);
-            mOutputFdAux = -1;
-        }
-    }
-
     if (mStarted) {
         mStarted = false;
 
@@ -1787,11 +1630,8 @@
     mVideoEncoder  = VIDEO_ENCODER_H263;
     mVideoWidth    = 176;
     mVideoHeight   = 144;
-    mAuxVideoWidth    = 176;
-    mAuxVideoHeight   = 144;
     mFrameRate     = -1;
     mVideoBitRate  = 192000;
-    mAuxVideoBitRate = 192000;
     mSampleRate    = 8000;
     mAudioChannels = 1;
     mAudioBitRate  = 12200;
@@ -1811,8 +1651,6 @@
     mTrackEveryTimeDurationUs = 0;
     mCaptureTimeLapse = false;
     mTimeBetweenTimeLapseFrameCaptureUs = -1;
-    mCaptureAuxVideo = false;
-    mCameraSourceSplitter = NULL;
     mCameraSourceTimeLapse = NULL;
     mIsMetaDataStoredInVideoBuffers = false;
     mEncoderProfiles = MediaProfiles::getInstance();
@@ -1821,7 +1659,6 @@
     mLongitudex10000 = -3600000;
 
     mOutputFd = -1;
-    mOutputFdAux = -1;
 
     return OK;
 }
@@ -1858,8 +1695,6 @@
     snprintf(buffer, SIZE, "   Recorder: %p\n", this);
     snprintf(buffer, SIZE, "   Output file (fd %d):\n", mOutputFd);
     result.append(buffer);
-    snprintf(buffer, SIZE, "   Output file Auxiliary (fd %d):\n", mOutputFdAux);
-    result.append(buffer);
     snprintf(buffer, SIZE, "     File format: %d\n", mOutputFormat);
     result.append(buffer);
     snprintf(buffer, SIZE, "     Max file size (bytes): %lld\n", mMaxFileSizeBytes);
@@ -1904,14 +1739,10 @@
     result.append(buffer);
     snprintf(buffer, SIZE, "     Frame size (pixels): %dx%d\n", mVideoWidth, mVideoHeight);
     result.append(buffer);
-    snprintf(buffer, SIZE, "     Aux Frame size (pixels): %dx%d\n", mAuxVideoWidth, mAuxVideoHeight);
-    result.append(buffer);
     snprintf(buffer, SIZE, "     Frame rate (fps): %d\n", mFrameRate);
     result.append(buffer);
     snprintf(buffer, SIZE, "     Bit rate (bps): %d\n", mVideoBitRate);
     result.append(buffer);
-    snprintf(buffer, SIZE, "     Aux Bit rate (bps): %d\n", mAuxVideoBitRate);
-    result.append(buffer);
     ::write(fd, result.string(), result.size());
     return OK;
 }
diff --git a/media/libmediaplayerservice/StagefrightRecorder.h b/media/libmediaplayerservice/StagefrightRecorder.h
index 1618b92..5c5f05c 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.h
+++ b/media/libmediaplayerservice/StagefrightRecorder.h
@@ -30,7 +30,6 @@
 class ICameraRecordingProxy;
 class CameraSource;
 class CameraSourceTimeLapse;
-class MediaSourceSplitter;
 struct MediaSource;
 struct MediaWriter;
 class MetaData;
@@ -55,7 +54,6 @@
     virtual status_t setPreviewSurface(const sp<Surface>& surface);
     virtual status_t setOutputFile(const char *path);
     virtual status_t setOutputFile(int fd, int64_t offset, int64_t length);
-    virtual status_t setOutputFileAuxiliary(int fd);
     virtual status_t setParameters(const String8& params);
     virtual status_t setListener(const sp<IMediaRecorderClient>& listener);
     virtual status_t prepare();
@@ -74,8 +72,8 @@
     sp<ICameraRecordingProxy> mCameraProxy;
     sp<Surface> mPreviewSurface;
     sp<IMediaRecorderClient> mListener;
-    sp<MediaWriter> mWriter, mWriterAux;
-    int mOutputFd, mOutputFdAux;
+    sp<MediaWriter> mWriter;
+    int mOutputFd;
     sp<AudioSource> mAudioSourceNode;
 
     audio_source_t mAudioSource;
@@ -85,9 +83,8 @@
     video_encoder mVideoEncoder;
     bool mUse64BitFileOffset;
     int32_t mVideoWidth, mVideoHeight;
-    int32_t mAuxVideoWidth, mAuxVideoHeight;
     int32_t mFrameRate;
-    int32_t mVideoBitRate, mAuxVideoBitRate;
+    int32_t mVideoBitRate;
     int32_t mAudioBitRate;
     int32_t mAudioChannels;
     int32_t mSampleRate;
@@ -109,8 +106,6 @@
 
     bool mCaptureTimeLapse;
     int64_t mTimeBetweenTimeLapseFrameCaptureUs;
-    bool mCaptureAuxVideo;
-    sp<MediaSourceSplitter> mCameraSourceSplitter;
     sp<CameraSourceTimeLapse> mCameraSourceTimeLapse;
 
 
@@ -127,7 +122,6 @@
     sp<SurfaceMediaSource> mSurfaceMediaSource;
 
     status_t setupMPEG4Recording(
-        bool useSplitCameraSource,
         int outputFd,
         int32_t videoWidth, int32_t videoHeight,
         int32_t videoBitRate,
@@ -166,9 +160,6 @@
     status_t setParamAudioTimeScale(int32_t timeScale);
     status_t setParamTimeLapseEnable(int32_t timeLapseEnable);
     status_t setParamTimeBetweenTimeLapseFrameCapture(int64_t timeUs);
-    status_t setParamAuxVideoHeight(int32_t height);
-    status_t setParamAuxVideoWidth(int32_t width);
-    status_t setParamAuxVideoEncodingBitRate(int32_t bitRate);
     status_t setParamVideoEncodingBitRate(int32_t bitRate);
     status_t setParamVideoIFramesInterval(int32_t seconds);
     status_t setParamVideoEncoderProfile(int32_t profile);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 0098537..67f6c79 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -2238,7 +2238,22 @@
 }
 
 status_t AwesomePlayer::getParameter(int key, Parcel *reply) {
-    return OK;
+    switch (key) {
+    case KEY_PARAMETER_AUDIO_CHANNEL_COUNT:
+        {
+            int32_t channelCount;
+            if (mAudioTrack == 0 ||
+                    !mAudioTrack->getFormat()->findInt32(kKeyChannelCount, &channelCount)) {
+                channelCount = 0;
+            }
+            reply->writeInt32(channelCount);
+        }
+        return OK;
+    default:
+        {
+            return ERROR_UNSUPPORTED;
+        }
+    }
 }
 
 bool AwesomePlayer::isStreamingHTTP() const {
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index fe78c46..1ba79e5 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -24,15 +24,10 @@
 #include <media/stagefright/CameraSourceTimeLapse.h>
 #include <media/stagefright/MediaDebug.h>
 #include <media/stagefright/MetaData.h>
-#include <media/stagefright/YUVImage.h>
-#include <media/stagefright/YUVCanvas.h>
 #include <camera/Camera.h>
 #include <camera/CameraParameters.h>
-#include <ui/Rect.h>
 #include <utils/String8.h>
 #include <utils/Vector.h>
-#include "OMX_Video.h"
-#include <limits.h>
 
 namespace android {
 
@@ -74,20 +69,14 @@
       mLastTimeLapseFrameRealTimestampUs(0),
       mSkipCurrentFrame(false) {
 
-    LOGD("starting time lapse mode: %lld us", mTimeBetweenTimeLapseFrameCaptureUs);
+    LOGD("starting time lapse mode: %lld us",
+        mTimeBetweenTimeLapseFrameCaptureUs);
+
     mVideoWidth = videoSize.width;
     mVideoHeight = videoSize.height;
 
-    if (trySettingVideoSize(videoSize.width, videoSize.height)) {
-        mUseStillCameraForTimeLapse = false;
-    } else {
-        // TODO: Add a check to see that mTimeBetweenTimeLapseFrameCaptureUs is greater
-        // than the fastest rate at which the still camera can take pictures.
-        mUseStillCameraForTimeLapse = true;
-        CHECK(setPictureSizeToClosestSupported(videoSize.width, videoSize.height));
-        mNeedCropping = computeCropRectangleOffset();
-        mMeta->setInt32(kKeyWidth, videoSize.width);
-        mMeta->setInt32(kKeyHeight, videoSize.height);
+    if (!trySettingVideoSize(videoSize.width, videoSize.height)) {
+        mInitCheck = NO_INIT;
     }
 
     // Initialize quick stop variables.
@@ -101,24 +90,22 @@
 }
 
 void CameraSourceTimeLapse::startQuickReadReturns() {
+    LOGV("startQuickReadReturns");
     Mutex::Autolock autoLock(mQuickStopLock);
-    LOGV("Enabling quick read returns");
 
     // Enable quick stop mode.
     mQuickStop = true;
 
-    if (mUseStillCameraForTimeLapse) {
-        // wake up the thread right away.
-        mTakePictureCondition.signal();
-    } else {
-        // Force dataCallbackTimestamp() coming from the video camera to not skip the
-        // next frame as we want read() to get a get a frame right away.
-        mForceRead = true;
-    }
+    // Force dataCallbackTimestamp() coming from the video camera to
+    // not skip the next frame as we want read() to get a get a frame
+    // right away.
+    mForceRead = true;
 }
 
-bool CameraSourceTimeLapse::trySettingVideoSize(int32_t width, int32_t height) {
-    LOGV("trySettingVideoSize: %dx%d", width, height);
+bool CameraSourceTimeLapse::trySettingVideoSize(
+        int32_t width, int32_t height) {
+
+    LOGV("trySettingVideoSize");
     int64_t token = IPCThreadState::self()->clearCallingIdentity();
     String8 s = mCamera->getParameters();
 
@@ -162,53 +149,8 @@
     return isSuccessful;
 }
 
-bool CameraSourceTimeLapse::setPictureSizeToClosestSupported(int32_t width, int32_t height) {
-    LOGV("setPictureSizeToClosestSupported: %dx%d", width, height);
-    int64_t token = IPCThreadState::self()->clearCallingIdentity();
-    String8 s = mCamera->getParameters();
-    IPCThreadState::self()->restoreCallingIdentity(token);
-
-    CameraParameters params(s);
-    Vector<Size> supportedSizes;
-    params.getSupportedPictureSizes(supportedSizes);
-
-    int32_t minPictureSize = INT_MAX;
-    for (uint32_t i = 0; i < supportedSizes.size(); ++i) {
-        int32_t pictureWidth = supportedSizes[i].width;
-        int32_t pictureHeight = supportedSizes[i].height;
-
-        if ((pictureWidth >= width) && (pictureHeight >= height)) {
-            int32_t pictureSize = pictureWidth*pictureHeight;
-            if (pictureSize < minPictureSize) {
-                minPictureSize = pictureSize;
-                mPictureWidth = pictureWidth;
-                mPictureHeight = pictureHeight;
-            }
-        }
-    }
-    LOGV("Picture size = (%d, %d)", mPictureWidth, mPictureHeight);
-    return (minPictureSize != INT_MAX);
-}
-
-bool CameraSourceTimeLapse::computeCropRectangleOffset() {
-    if ((mPictureWidth == mVideoWidth) && (mPictureHeight == mVideoHeight)) {
-        return false;
-    }
-
-    CHECK((mPictureWidth > mVideoWidth) && (mPictureHeight > mVideoHeight));
-
-    int32_t widthDifference = mPictureWidth - mVideoWidth;
-    int32_t heightDifference = mPictureHeight - mVideoHeight;
-
-    mCropRectStartX = widthDifference/2;
-    mCropRectStartY = heightDifference/2;
-
-    LOGV("setting crop rectangle offset to (%d, %d)", mCropRectStartX, mCropRectStartY);
-
-    return true;
-}
-
 void CameraSourceTimeLapse::signalBufferReturned(MediaBuffer* buffer) {
+    LOGV("signalBufferReturned");
     Mutex::Autolock autoLock(mQuickStopLock);
     if (mQuickStop && (buffer == mLastReadBufferCopy)) {
         buffer->setObserver(NULL);
@@ -218,7 +160,12 @@
     }
 }
 
-void createMediaBufferCopy(const MediaBuffer& sourceBuffer, int64_t frameTime, MediaBuffer **newBuffer) {
+void createMediaBufferCopy(
+        const MediaBuffer& sourceBuffer,
+        int64_t frameTime,
+        MediaBuffer **newBuffer) {
+
+    LOGV("createMediaBufferCopy");
     size_t sourceSize = sourceBuffer.size();
     void* sourcePointer = sourceBuffer.data();
 
@@ -229,6 +176,7 @@
 }
 
 void CameraSourceTimeLapse::fillLastReadBufferCopy(MediaBuffer& sourceBuffer) {
+    LOGV("fillLastReadBufferCopy");
     int64_t frameTime;
     CHECK(sourceBuffer.meta_data()->findInt64(kKeyTime, &frameTime));
     createMediaBufferCopy(sourceBuffer, frameTime, &mLastReadBufferCopy);
@@ -238,11 +186,12 @@
 
 status_t CameraSourceTimeLapse::read(
         MediaBuffer **buffer, const ReadOptions *options) {
+    LOGV("read");
     if (mLastReadBufferCopy == NULL) {
         mLastReadStatus = CameraSource::read(buffer, options);
 
-        // mQuickStop may have turned to true while read was blocked. Make a copy of
-        // the buffer in that case.
+        // mQuickStop may have turned to true while read was blocked.
+        // Make a copy of the buffer in that case.
         Mutex::Autolock autoLock(mQuickStopLock);
         if (mQuickStop && *buffer) {
             fillLastReadBufferCopy(**buffer);
@@ -255,105 +204,19 @@
     }
 }
 
-// static
-void *CameraSourceTimeLapse::ThreadTimeLapseWrapper(void *me) {
-    CameraSourceTimeLapse *source = static_cast<CameraSourceTimeLapse *>(me);
-    source->threadTimeLapseEntry();
-    return NULL;
-}
-
-void CameraSourceTimeLapse::threadTimeLapseEntry() {
-    while (mStarted) {
-        {
-            Mutex::Autolock autoLock(mCameraIdleLock);
-            if (!mCameraIdle) {
-                mCameraIdleCondition.wait(mCameraIdleLock);
-            }
-            CHECK(mCameraIdle);
-            mCameraIdle = false;
-        }
-
-        // Even if mQuickStop == true we need to take one more picture
-        // as a read() may be blocked, waiting for a frame to get available.
-        // After this takePicture, if mQuickStop == true, we can safely exit
-        // this thread as read() will make a copy of this last frame and keep
-        // returning it in the quick stop mode.
-        Mutex::Autolock autoLock(mQuickStopLock);
-        CHECK_EQ(OK, mCamera->takePicture(CAMERA_MSG_RAW_IMAGE));
-        if (mQuickStop) {
-            LOGV("threadTimeLapseEntry: Exiting due to mQuickStop = true");
-            return;
-        }
-        mTakePictureCondition.waitRelative(mQuickStopLock,
-                mTimeBetweenTimeLapseFrameCaptureUs * 1000);
-    }
-    LOGV("threadTimeLapseEntry: Exiting due to mStarted = false");
-}
-
-void CameraSourceTimeLapse::startCameraRecording() {
-    if (mUseStillCameraForTimeLapse) {
-        LOGV("start time lapse recording using still camera");
-
-        int64_t token = IPCThreadState::self()->clearCallingIdentity();
-        String8 s = mCamera->getParameters();
-
-        CameraParameters params(s);
-        params.setPictureSize(mPictureWidth, mPictureHeight);
-        mCamera->setParameters(params.flatten());
-        mCameraIdle = true;
-        mStopWaitingForIdleCamera = false;
-
-        // disable shutter sound and play the recording sound.
-        mCamera->sendCommand(CAMERA_CMD_ENABLE_SHUTTER_SOUND, 0, 0);
-        mCamera->sendCommand(CAMERA_CMD_PLAY_RECORDING_SOUND, 0, 0);
-        IPCThreadState::self()->restoreCallingIdentity(token);
-
-        // create a thread which takes pictures in a loop
-        pthread_attr_t attr;
-        pthread_attr_init(&attr);
-        pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
-        pthread_create(&mThreadTimeLapse, &attr, ThreadTimeLapseWrapper, this);
-        pthread_attr_destroy(&attr);
-    } else {
-        LOGV("start time lapse recording using video camera");
-        CameraSource::startCameraRecording();
-    }
-}
-
 void CameraSourceTimeLapse::stopCameraRecording() {
-    if (mUseStillCameraForTimeLapse) {
-        void *dummy;
-        pthread_join(mThreadTimeLapse, &dummy);
-
-        // Last takePicture may still be underway. Wait for the camera to get
-        // idle.
-        Mutex::Autolock autoLock(mCameraIdleLock);
-        mStopWaitingForIdleCamera = true;
-        if (!mCameraIdle) {
-            mCameraIdleCondition.wait(mCameraIdleLock);
-        }
-        CHECK(mCameraIdle);
-        mCamera->setListener(NULL);
-
-        // play the recording sound.
-        mCamera->sendCommand(CAMERA_CMD_PLAY_RECORDING_SOUND, 0, 0);
-    } else {
-        CameraSource::stopCameraRecording();
-    }
+    LOGV("stopCameraRecording");
+    CameraSource::stopCameraRecording();
     if (mLastReadBufferCopy) {
         mLastReadBufferCopy->release();
         mLastReadBufferCopy = NULL;
     }
 }
 
-void CameraSourceTimeLapse::releaseRecordingFrame(const sp<IMemory>& frame) {
-    if (!mUseStillCameraForTimeLapse) {
-        CameraSource::releaseRecordingFrame(frame);
-    }
-}
+sp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(
+        const sp<IMemory> &source_data) {
 
-sp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(const sp<IMemory> &source_data) {
+    LOGV("createIMemoryCopy");
     size_t source_size = source_data->size();
     void* source_pointer = source_data->pointer();
 
@@ -363,102 +226,8 @@
     return newMemory;
 }
 
-// Allocates IMemory of final type MemoryBase with the given size.
-sp<IMemory> allocateIMemory(size_t size) {
-    sp<MemoryHeapBase> newMemoryHeap = new MemoryHeapBase(size);
-    sp<MemoryBase> newMemory = new MemoryBase(newMemoryHeap, 0, size);
-    return newMemory;
-}
-
-// static
-void *CameraSourceTimeLapse::ThreadStartPreviewWrapper(void *me) {
-    CameraSourceTimeLapse *source = static_cast<CameraSourceTimeLapse *>(me);
-    source->threadStartPreview();
-    return NULL;
-}
-
-void CameraSourceTimeLapse::threadStartPreview() {
-    CHECK_EQ(OK, mCamera->startPreview());
-    Mutex::Autolock autoLock(mCameraIdleLock);
-    mCameraIdle = true;
-    mCameraIdleCondition.signal();
-}
-
-void CameraSourceTimeLapse::restartPreview() {
-    // Start this in a different thread, so that the dataCallback can return
-    LOGV("restartPreview");
-    pthread_attr_t attr;
-    pthread_attr_init(&attr);
-    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-
-    pthread_t threadPreview;
-    pthread_create(&threadPreview, &attr, ThreadStartPreviewWrapper, this);
-    pthread_attr_destroy(&attr);
-}
-
-sp<IMemory> CameraSourceTimeLapse::cropYUVImage(const sp<IMemory> &source_data) {
-    // find the YUV format
-    int32_t srcFormat;
-    CHECK(mMeta->findInt32(kKeyColorFormat, &srcFormat));
-    YUVImage::YUVFormat yuvFormat;
-    if (srcFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
-        yuvFormat = YUVImage::YUV420SemiPlanar;
-    } else {
-        CHECK_EQ(srcFormat, OMX_COLOR_FormatYUV420Planar);
-        yuvFormat = YUVImage::YUV420Planar;
-    }
-
-    // allocate memory for cropped image and setup a canvas using it.
-    sp<IMemory> croppedImageMemory = allocateIMemory(
-            YUVImage::bufferSize(yuvFormat, mVideoWidth, mVideoHeight));
-    YUVImage yuvImageCropped(yuvFormat,
-            mVideoWidth, mVideoHeight,
-            (uint8_t *)croppedImageMemory->pointer());
-    YUVCanvas yuvCanvasCrop(yuvImageCropped);
-
-    YUVImage yuvImageSource(yuvFormat,
-            mPictureWidth, mPictureHeight,
-            (uint8_t *)source_data->pointer());
-    yuvCanvasCrop.CopyImageRect(
-            Rect(mCropRectStartX, mCropRectStartY,
-                mCropRectStartX + mVideoWidth,
-                mCropRectStartY + mVideoHeight),
-            0, 0,
-            yuvImageSource);
-
-    return croppedImageMemory;
-}
-
-void CameraSourceTimeLapse::dataCallback(int32_t msgType, const sp<IMemory> &data) {
-    if (msgType == CAMERA_MSG_COMPRESSED_IMAGE) {
-        // takePicture will complete after this callback, so restart preview.
-        restartPreview();
-        return;
-    }
-    if (msgType != CAMERA_MSG_RAW_IMAGE) {
-        return;
-    }
-
-    LOGV("dataCallback for timelapse still frame");
-    CHECK_EQ(true, mUseStillCameraForTimeLapse);
-
-    int64_t timestampUs;
-    if (mNumFramesReceived == 0) {
-        timestampUs = mStartTimeUs;
-    } else {
-        timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
-    }
-
-    if (mNeedCropping) {
-        sp<IMemory> croppedImageData = cropYUVImage(data);
-        dataCallbackTimestamp(timestampUs, msgType, croppedImageData);
-    } else {
-        sp<IMemory> dataCopy = createIMemoryCopy(data);
-        dataCallbackTimestamp(timestampUs, msgType, dataCopy);
-    }
-}
-
 bool CameraSourceTimeLapse::skipCurrentFrame(int64_t timestampUs) {
+    LOGV("skipCurrentFrame");
     if (mSkipCurrentFrame) {
         mSkipCurrentFrame = false;
         return true;
@@ -468,72 +237,58 @@
 }
 
 bool CameraSourceTimeLapse::skipFrameAndModifyTimeStamp(int64_t *timestampUs) {
-    if (!mUseStillCameraForTimeLapse) {
-        if (mLastTimeLapseFrameRealTimestampUs == 0) {
-            // First time lapse frame. Initialize mLastTimeLapseFrameRealTimestampUs
-            // to current time (timestampUs) and save frame data.
-            LOGV("dataCallbackTimestamp timelapse: initial frame");
+    LOGV("skipFrameAndModifyTimeStamp");
+    if (mLastTimeLapseFrameRealTimestampUs == 0) {
+        // First time lapse frame. Initialize mLastTimeLapseFrameRealTimestampUs
+        // to current time (timestampUs) and save frame data.
+        LOGV("dataCallbackTimestamp timelapse: initial frame");
 
-            mLastTimeLapseFrameRealTimestampUs = *timestampUs;
+        mLastTimeLapseFrameRealTimestampUs = *timestampUs;
+        return false;
+    }
+
+    {
+        Mutex::Autolock autoLock(mQuickStopLock);
+
+        // mForceRead may be set to true by startQuickReadReturns(). In that
+        // case don't skip this frame.
+        if (mForceRead) {
+            LOGV("dataCallbackTimestamp timelapse: forced read");
+            mForceRead = false;
+            *timestampUs =
+                mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
             return false;
         }
+    }
 
-        {
-            Mutex::Autolock autoLock(mQuickStopLock);
+    // Workaround to bypass the first 2 input frames for skipping.
+    // The first 2 output frames from the encoder are: decoder specific info and
+    // the compressed video frame data for the first input video frame.
+    if (mNumFramesEncoded >= 1 && *timestampUs <
+        (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenTimeLapseFrameCaptureUs)) {
+        // Skip all frames from last encoded frame until
+        // sufficient time (mTimeBetweenTimeLapseFrameCaptureUs) has passed.
+        // Tell the camera to release its recording frame and return.
+        LOGV("dataCallbackTimestamp timelapse: skipping intermediate frame");
+        return true;
+    } else {
+        // Desired frame has arrived after mTimeBetweenTimeLapseFrameCaptureUs time:
+        // - Reset mLastTimeLapseFrameRealTimestampUs to current time.
+        // - Artificially modify timestampUs to be one frame time (1/framerate) ahead
+        // of the last encoded frame's time stamp.
+        LOGV("dataCallbackTimestamp timelapse: got timelapse frame");
 
-            // mForceRead may be set to true by startQuickReadReturns(). In that
-            // case don't skip this frame.
-            if (mForceRead) {
-                LOGV("dataCallbackTimestamp timelapse: forced read");
-                mForceRead = false;
-                *timestampUs =
-                    mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
-                return false;
-            }
-        }
-
-        // Workaround to bypass the first 2 input frames for skipping.
-        // The first 2 output frames from the encoder are: decoder specific info and
-        // the compressed video frame data for the first input video frame.
-        if (mNumFramesEncoded >= 1 && *timestampUs <
-                (mLastTimeLapseFrameRealTimestampUs + mTimeBetweenTimeLapseFrameCaptureUs)) {
-            // Skip all frames from last encoded frame until
-            // sufficient time (mTimeBetweenTimeLapseFrameCaptureUs) has passed.
-            // Tell the camera to release its recording frame and return.
-            LOGV("dataCallbackTimestamp timelapse: skipping intermediate frame");
-            return true;
-        } else {
-            // Desired frame has arrived after mTimeBetweenTimeLapseFrameCaptureUs time:
-            // - Reset mLastTimeLapseFrameRealTimestampUs to current time.
-            // - Artificially modify timestampUs to be one frame time (1/framerate) ahead
-            // of the last encoded frame's time stamp.
-            LOGV("dataCallbackTimestamp timelapse: got timelapse frame");
-
-            mLastTimeLapseFrameRealTimestampUs = *timestampUs;
-            *timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
-            return false;
-        }
+        mLastTimeLapseFrameRealTimestampUs = *timestampUs;
+        *timestampUs = mLastFrameTimestampUs + mTimeBetweenTimeLapseVideoFramesUs;
+        return false;
     }
     return false;
 }
 
 void CameraSourceTimeLapse::dataCallbackTimestamp(int64_t timestampUs, int32_t msgType,
             const sp<IMemory> &data) {
-    if (!mUseStillCameraForTimeLapse) {
-        mSkipCurrentFrame = skipFrameAndModifyTimeStamp(&timestampUs);
-    } else {
-        Mutex::Autolock autoLock(mCameraIdleLock);
-        // If we are using the still camera and stop() has been called, it may
-        // be waiting for the camera to get idle. In that case return
-        // immediately. Calling CameraSource::dataCallbackTimestamp() will lead
-        // to a deadlock since it tries to access CameraSource::mLock which in
-        // this case is held by CameraSource::stop() currently waiting for the
-        // camera to get idle. And camera will not get idle until this call
-        // returns.
-        if (mStopWaitingForIdleCamera) {
-            return;
-        }
-    }
+    LOGV("dataCallbackTimestamp");
+    mSkipCurrentFrame = skipFrameAndModifyTimeStamp(&timestampUs);
     CameraSource::dataCallbackTimestamp(timestampUs, msgType, data);
 }
 
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index ff4b08f..3d8c56a 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -23,6 +23,7 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaDebug.h>
 #include <media/stagefright/openmax/OMX_IVCommon.h>
+#include <media/stagefright/MetadataBufferType.h>
 
 #include <surfaceflinger/ISurfaceComposer.h>
 #include <surfaceflinger/SurfaceComposerClient.h>
@@ -710,9 +711,9 @@
     mCurrentBuf = mSlots[mCurrentSlot].mGraphicBuffer;
     mCurrentTimestamp = mSlots[mCurrentSlot].mTimestamp;
 
-    // Pass the data to the MediaBuffer
-    // TODO: Change later to pass in only the metadata
-    *buffer = new MediaBuffer(mCurrentBuf);
+    // Pass the data to the MediaBuffer. Pass in only the metadata
+    passMetadataBufferLocked(buffer);
+
     (*buffer)->setObserver(this);
     (*buffer)->add_ref();
     (*buffer)->meta_data()->setInt64(kKeyTime, mCurrentTimestamp);
@@ -720,6 +721,34 @@
     return OK;
 }
 
+// Pass the data to the MediaBuffer. Pass in only the metadata
+// The metadata passed consists of two parts:
+// 1. First, there is an integer indicating that it is a GRAlloc
+// source (kMetadataBufferTypeGrallocSource)
+// 2. This is followed by the buffer_handle_t that is a handle to the
+// GRalloc buffer. The encoder needs to interpret this GRalloc handle
+// and encode the frames.
+// --------------------------------------------------------------
+// |  kMetadataBufferTypeGrallocSource | sizeof(buffer_handle_t) |
+// --------------------------------------------------------------
+// Note: Call only when you have the lock
+void SurfaceMediaSource::passMetadataBufferLocked(MediaBuffer **buffer) {
+    LOGV("passMetadataBuffer");
+    // MediaBuffer allocates and owns this data
+    MediaBuffer *tempBuffer =
+        new MediaBuffer(4 + sizeof(buffer_handle_t));
+    char *data = (char *)tempBuffer->data();
+    if (data == NULL) {
+        LOGE("Cannot allocate memory for passing buffer metadata!");
+        return;
+    }
+    OMX_U32 type = kMetadataBufferTypeGrallocSource;
+    memcpy(data, &type, 4);
+    memcpy(data + 4, &(mCurrentBuf->handle), sizeof(buffer_handle_t));
+    *buffer = tempBuffer;
+}
+
+
 void SurfaceMediaSource::signalBufferReturned(MediaBuffer *buffer) {
     LOGV("signalBufferReturned");
 
@@ -727,14 +756,13 @@
     Mutex::Autolock autoLock(mMutex);
 
     if (!mStarted) {
-        LOGV("started = false. Nothing to do");
+        LOGW("signalBufferReturned: mStarted = false! Nothing to do!");
         return;
     }
 
     for (Fifo::iterator it = mQueue.begin(); it != mQueue.end(); ++it) {
-        if (mSlots[*it].mGraphicBuffer  ==  buffer->graphicBuffer()) {
-            LOGV("Buffer %d returned. Setting it 'FREE'. New Queue size = %d",
-                    *it, mQueue.size()-1);
+        CHECK(mSlots[*it].mGraphicBuffer != NULL);
+        if (checkBufferMatchesSlot(*it, buffer)) {
             mSlots[*it].mBufferState = BufferSlot::FREE;
             mQueue.erase(it);
             buffer->setObserver(0);
@@ -751,6 +779,14 @@
     }
 }
 
+bool SurfaceMediaSource::checkBufferMatchesSlot(int slot, MediaBuffer *buffer) {
+    LOGV("Check if Buffer matches slot");
+    // need to convert to char* for pointer arithmetic and then
+    // copy the byte stream into our handle
+    buffer_handle_t bufferHandle ;
+    memcpy( &bufferHandle, (char *)(buffer->data()) + 4, sizeof(buffer_handle_t));
+    return mSlots[slot].mGraphicBuffer->handle  ==  bufferHandle;
+}
 
 
 } // end of namespace android
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
index f4b3668..eb10ab7 100644
--- a/media/libstagefright/chromium_http/support.cpp
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -25,6 +25,7 @@
 #include "android/net/android_network_library_impl.h"
 #include "base/threading/thread.h"
 #include "net/base/cert_verifier.h"
+#include "net/base/cookie_monster.h"
 #include "net/base/host_resolver.h"
 #include "net/base/ssl_config_service.h"
 #include "net/http/http_auth_handler_factory.h"
@@ -140,6 +141,8 @@
             network_delegate(),
             net_log(),
             NULL));  // backend_factory
+
+    set_cookie_store(new net::CookieMonster(NULL, NULL));
 }
 
 const std::string &SfRequestContext::GetUserAgent(const GURL &url) const {
diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXMaster.cpp
index 504d470..c8278ab 100644
--- a/media/libstagefright/omx/OMXMaster.cpp
+++ b/media/libstagefright/omx/OMXMaster.cpp
@@ -57,6 +57,9 @@
     typedef OMXPluginBase *(*CreateOMXPluginFunc)();
     CreateOMXPluginFunc createOMXPlugin =
         (CreateOMXPluginFunc)dlsym(
+                mVendorLibHandle, "createOMXPlugin");
+    if (!createOMXPlugin)
+        createOMXPlugin = (CreateOMXPluginFunc)dlsym(
                 mVendorLibHandle, "_ZN7android15createOMXPluginEv");
 
     if (createOMXPlugin) {
@@ -96,11 +99,19 @@
 void OMXMaster::clearPlugins() {
     Mutex::Autolock autoLock(mLock);
 
+    typedef void (*DestroyOMXPluginFunc)(OMXPluginBase*);
+    DestroyOMXPluginFunc destroyOMXPlugin =
+        (DestroyOMXPluginFunc)dlsym(
+                mVendorLibHandle, "destroyOMXPlugin");
+
     mPluginByComponentName.clear();
 
     for (List<OMXPluginBase *>::iterator it = mPlugins.begin();
-         it != mPlugins.end(); ++it) {
-        delete *it;
+            it != mPlugins.end(); ++it) {
+        if (destroyOMXPlugin)
+            destroyOMXPlugin(*it);
+        else
+            delete *it;
         *it = NULL;
     }
 
diff --git a/media/libstagefright/tests/SurfaceMediaSource_test.cpp b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
index ce10812..dc6f2c9 100644
--- a/media/libstagefright/tests/SurfaceMediaSource_test.cpp
+++ b/media/libstagefright/tests/SurfaceMediaSource_test.cpp
@@ -71,8 +71,8 @@
         mANW.clear();
     }
 
-    const int mYuvTexWidth;//  = 64;
-    const int mYuvTexHeight;// = 66;
+    const int mYuvTexWidth;
+    const int mYuvTexHeight;
 
     sp<SurfaceMediaSource> mSMS;
     sp<SurfaceTextureClient> mSTC;
@@ -124,7 +124,6 @@
     // TODO: overwriting the colorformat since the format set by GRAlloc
     // could be wrong or not be read by OMX
     enc_meta->setInt32(kKeyColorFormat, OMX_COLOR_FormatYUV420Planar);
-    // colorFormat);
 
 
     sp<MediaSource> encoder =
@@ -225,7 +224,6 @@
 
     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
             0, 0, HAL_PIXEL_FORMAT_YV12));
-                                // OMX_COLOR_FormatYUV420Planar)); // ));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
@@ -239,7 +237,6 @@
     // setting the client side buffer size different than the server size
     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
              10, 10, HAL_PIXEL_FORMAT_YV12));
-                                // OMX_COLOR_FormatYUV420Planar)); // ));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
 
@@ -258,6 +255,7 @@
             0, 0, HAL_PIXEL_FORMAT_YV12));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
     SimpleDummyRecorder writer(mSMS);
     writer.start();
 
@@ -276,10 +274,12 @@
 // A dummy writer is used to simulate actual MPEG4Writer
 TEST_F(SurfaceMediaSourceTest,  EncodingFromCpuFilledYV12BufferNpotMultiBufferPassLag) {
     LOGV("Testing MultiBufferPass, Dummy Recorder Lagging **************");
+
     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
             0, 0, HAL_PIXEL_FORMAT_YV12));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
+
     SimpleDummyRecorder writer(mSMS);
     writer.start();
 
@@ -322,10 +322,9 @@
 TEST_F(SurfaceMediaSourceTest, DISABLED_EncodingFromCpuFilledYV12BufferNpotWrite) {
     LOGV("Testing the whole pipeline with actual Recorder");
     ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(),
-            0, 0, HAL_PIXEL_FORMAT_YV12)); // OMX_COLOR_FormatYUV420Planar)); // ));
+            0, 0, HAL_PIXEL_FORMAT_YV12));
     ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(),
             GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN));
-
     OMXClient client;
     CHECK_EQ(OK, client.connect());
 
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index a0407b9..fa49592 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -21,7 +21,8 @@
     libhardware \
     libhardware_legacy \
     libeffects \
-    libdl
+    libdl \
+    libpowermanager
 
 LOCAL_STATIC_LIBRARIES := \
     libcpustats \
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 0323fe0..ec45530 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -53,6 +53,7 @@
 #include <audio_effects/effect_visualizer.h>
 
 #include <cpustats/ThreadCpuUsage.h>
+#include <powermanager/PowerManager.h>
 // #define DEBUG_CPU_USAGE 10  // log statistics every n wall clock seconds
 
 // ----------------------------------------------------------------------------
@@ -887,14 +888,18 @@
 AudioFlinger::ThreadBase::ThreadBase(const sp<AudioFlinger>& audioFlinger, int id, uint32_t device)
     :   Thread(false),
         mAudioFlinger(audioFlinger), mSampleRate(0), mFrameCount(0), mChannelCount(0),
-        mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false), mDevice(device)
+        mFrameSize(1), mFormat(0), mStandby(false), mId(id), mExiting(false),
+        mDevice(device)
 {
+    mDeathRecipient = new PMDeathRecipient(this);
 }
 
 AudioFlinger::ThreadBase::~ThreadBase()
 {
     mParamCond.broadcast();
     mNewParameters.clear();
+    // do not lock the mutex in destructor
+    releaseWakeLock_l();
 }
 
 void AudioFlinger::ThreadBase::exit()
@@ -1043,6 +1048,88 @@
     return NO_ERROR;
 }
 
+status_t AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+
+    snprintf(buffer, SIZE, "\n- %d Effect Chains:\n", mEffectChains.size());
+    write(fd, buffer, strlen(buffer));
+
+    for (size_t i = 0; i < mEffectChains.size(); ++i) {
+        sp<EffectChain> chain = mEffectChains[i];
+        if (chain != 0) {
+            chain->dump(fd, args);
+        }
+    }
+    return NO_ERROR;
+}
+
+void AudioFlinger::ThreadBase::acquireWakeLock()
+{
+    Mutex::Autolock _l(mLock);
+    acquireWakeLock_l();
+}
+
+void AudioFlinger::ThreadBase::acquireWakeLock_l()
+{
+    if (mPowerManager == 0) {
+        // use checkService() to avoid blocking if power service is not up yet
+        sp<IBinder> binder =
+            defaultServiceManager()->checkService(String16("power"));
+        if (binder == 0) {
+            LOGW("Thread %s cannot connect to the power manager service", mName);
+        } else {
+            mPowerManager = interface_cast<IPowerManager>(binder);
+            binder->linkToDeath(mDeathRecipient);
+        }
+    }
+    if (mPowerManager != 0) {
+        sp<IBinder> binder = new BBinder();
+        status_t status = mPowerManager->acquireWakeLock(POWERMANAGER_PARTIAL_WAKE_LOCK,
+                                                         binder,
+                                                         String16(mName));
+        if (status == NO_ERROR) {
+            mWakeLockToken = binder;
+        }
+        LOGV("acquireWakeLock_l() %s status %d", mName, status);
+    }
+}
+
+void AudioFlinger::ThreadBase::releaseWakeLock()
+{
+    Mutex::Autolock _l(mLock);
+    releaseWakeLock_l();
+}
+
+void AudioFlinger::ThreadBase::releaseWakeLock_l()
+{
+    if (mWakeLockToken != 0) {
+        LOGV("releaseWakeLock_l() %s", mName);
+        if (mPowerManager != 0) {
+            mPowerManager->releaseWakeLock(mWakeLockToken, 0);
+        }
+        mWakeLockToken.clear();
+    }
+}
+
+void AudioFlinger::ThreadBase::clearPowerManager()
+{
+    Mutex::Autolock _l(mLock);
+    releaseWakeLock_l();
+    mPowerManager.clear();
+}
+
+void AudioFlinger::ThreadBase::PMDeathRecipient::binderDied(const wp<IBinder>& who)
+{
+    sp<ThreadBase> thread = mThread.promote();
+    if (thread != 0) {
+        thread->clearPowerManager();
+    }
+    LOGW("power manager service died !!!");
+}
+
 // ----------------------------------------------------------------------------
 
 AudioFlinger::PlaybackThread::PlaybackThread(const sp<AudioFlinger>& audioFlinger,
@@ -1053,6 +1140,8 @@
         mMixBuffer(0), mSuspended(0), mBytesWritten(0), mOutput(output),
         mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
 {
+    snprintf(mName, kNameLength, "AudioOut_%d", id);
+
     readOutputParameters();
 
     mMasterVolume = mAudioFlinger->masterVolume();
@@ -1111,24 +1200,6 @@
     return NO_ERROR;
 }
 
-status_t AudioFlinger::PlaybackThread::dumpEffectChains(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    String8 result;
-
-    snprintf(buffer, SIZE, "\n- %d Effect Chains:\n", mEffectChains.size());
-    write(fd, buffer, strlen(buffer));
-
-    for (size_t i = 0; i < mEffectChains.size(); ++i) {
-        sp<EffectChain> chain = mEffectChains[i];
-        if (chain != 0) {
-            chain->dump(fd, args);
-        }
-    }
-    return NO_ERROR;
-}
-
 status_t AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>& args)
 {
     const size_t SIZE = 256;
@@ -1169,12 +1240,7 @@
 
 void AudioFlinger::PlaybackThread::onFirstRef()
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "Playback Thread %p", this);
-
-    run(buffer, ANDROID_PRIORITY_URGENT_AUDIO);
+    run(mName, ANDROID_PRIORITY_URGENT_AUDIO);
 }
 
 // PlaybackThread::createTrack_l() must be called with AudioFlinger::mLock held
@@ -1521,6 +1587,8 @@
     const CentralTendencyStatistics& stats = cpu.statistics();
 #endif
 
+    acquireWakeLock();
+
     while (!exitPending())
     {
 #ifdef DEBUG_CPU_USAGE
@@ -1584,10 +1652,12 @@
 
                     if (exitPending()) break;
 
+                    releaseWakeLock_l();
                     // wait until we have something to do...
                     LOGV("MixerThread %p TID %d going to sleep\n", this, gettid());
                     mWaitWorkCV.wait(mLock);
                     LOGV("MixerThread %p TID %d waking up\n", this, gettid());
+                    acquireWakeLock_l();
 
                     if (mMasterMute == false) {
                         char value[PROPERTY_VALUE_MAX];
@@ -1688,6 +1758,8 @@
         mOutput->stream->common.standby(&mOutput->stream->common);
     }
 
+    releaseWakeLock();
+
     LOGV("MixerThread %p exiting", this);
     return false;
 }
@@ -2175,6 +2247,8 @@
     // hardware resources as soon as possible
     nsecs_t standbyDelay = microseconds(activeSleepTime*2);
 
+    acquireWakeLock();
+
     while (!exitPending())
     {
         bool rampVolume;
@@ -2214,9 +2288,11 @@
 
                     if (exitPending()) break;
 
+                    releaseWakeLock_l();
                     LOGV("DirectOutputThread %p TID %d going to sleep\n", this, gettid());
                     mWaitWorkCV.wait(mLock);
                     LOGV("DirectOutputThread %p TID %d waking up in active mode\n", this, gettid());
+                    acquireWakeLock_l();
 
                     if (mMasterMute == false) {
                         char value[PROPERTY_VALUE_MAX];
@@ -2435,6 +2511,8 @@
         mOutput->stream->common.standby(&mOutput->stream->common);
     }
 
+    releaseWakeLock();
+
     LOGV("DirectOutputThread %p exiting", this);
     return false;
 }
@@ -2560,6 +2638,8 @@
     uint32_t sleepTime = idleSleepTime;
     Vector< sp<EffectChain> > effectChains;
 
+    acquireWakeLock();
+
     while (!exitPending())
     {
         processConfigEvents();
@@ -2600,9 +2680,12 @@
 
                     if (exitPending()) break;
 
+                    releaseWakeLock_l();
                     LOGV("DuplicatingThread %p TID %d going to sleep\n", this, gettid());
                     mWaitWorkCV.wait(mLock);
                     LOGV("DuplicatingThread %p TID %d waking up\n", this, gettid());
+                    acquireWakeLock_l();
+
                     if (mMasterMute == false) {
                         char value[PROPERTY_VALUE_MAX];
                         property_get("ro.audio.silent", value, "0");
@@ -2689,6 +2772,8 @@
         effectChains.clear();
     }
 
+    releaseWakeLock();
+
     return false;
 }
 
@@ -3813,6 +3898,9 @@
     mInput(input), mTrack(NULL), mResampler(0), mRsmpOutBuffer(0), mRsmpInBuffer(0)
 {
     mType = ThreadBase::RECORD;
+
+    snprintf(mName, kNameLength, "AudioIn_%d", id);
+
     mReqChannelCount = popcount(channels);
     mReqSampleRate = sampleRate;
     readInputParameters();
@@ -3830,12 +3918,7 @@
 
 void AudioFlinger::RecordThread::onFirstRef()
 {
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-
-    snprintf(buffer, SIZE, "Record Thread %p", this);
-
-    run(buffer, PRIORITY_URGENT_AUDIO);
+    run(mName, PRIORITY_URGENT_AUDIO);
 }
 
 bool AudioFlinger::RecordThread::threadLoop()
@@ -3846,6 +3929,8 @@
 
     nsecs_t lastWarning = 0;
 
+    acquireWakeLock();
+
     // start recording
     while (!exitPending()) {
 
@@ -3862,10 +3947,12 @@
 
                 if (exitPending()) break;
 
+                releaseWakeLock_l();
                 LOGV("RecordThread: loop stopping");
                 // go to sleep
                 mWaitWorkCV.wait(mLock);
                 LOGV("RecordThread: loop starting");
+                acquireWakeLock_l();
                 continue;
             }
             if (mActiveTrack != 0) {
@@ -3906,8 +3993,6 @@
             for (size_t i = 0; i < effectChains.size(); i ++) {
                 effectChains[i]->process_l();
             }
-            // enable changes in effect chain
-            unlockEffectChains(effectChains);
 
             buffer.frameCount = mFrameCount;
             if (LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
@@ -4007,9 +4092,9 @@
                 // clear the overflow.
                 usleep(kRecordThreadSleepUs);
             }
-        } else {
-            unlockEffectChains(effectChains);
         }
+        // enable changes in effect chain
+        unlockEffectChains(effectChains);
         effectChains.clear();
     }
 
@@ -4020,6 +4105,8 @@
 
     mStartStopCond.broadcast();
 
+    releaseWakeLock();
+
     LOGV("RecordThread %p exiting", this);
     return false;
 }
@@ -4178,6 +4265,7 @@
     write(fd, result.string(), result.size());
 
     dumpBase(fd, args);
+    dumpEffectChains(fd, args);
 
     return NO_ERROR;
 }
@@ -5579,13 +5667,11 @@
         }
     }
 
-    // Release effect engine here so that it is done immediately. Otherwise it will be released
-    // by the destructor when the last strong reference on the this object is released which can
-    // happen after next process is called on this effect.
-    if (size == 0 && mEffectInterface != NULL) {
-        // release effect engine
-        EffectRelease(mEffectInterface);
-        mEffectInterface = NULL;
+    // Prevent calls to process() and other functions on effect interface from now on.
+    // The effect engine will be released by the destructor when the last strong reference on
+    // this object is released which can happen after next process is called.
+    if (size == 0) {
+        mState = DESTROYED;
     }
 
     return size;
@@ -5635,7 +5721,7 @@
             mState = IDLE;
         }
         break;
-    default: //IDLE , ACTIVE
+    default: //IDLE , ACTIVE, DESTROYED
         break;
     }
 }
@@ -5644,7 +5730,7 @@
 {
     Mutex::Autolock _l(mLock);
 
-    if (mEffectInterface == NULL ||
+    if (mState == DESTROYED || mEffectInterface == NULL ||
             mConfig.inputCfg.buffer.raw == NULL ||
             mConfig.outputCfg.buffer.raw == NULL) {
         return;
@@ -5820,6 +5906,12 @@
     return status;
 }
 
+status_t AudioFlinger::EffectModule::stop()
+{
+    Mutex::Autolock _l(mLock);
+    return stop_l();
+}
+
 status_t AudioFlinger::EffectModule::stop_l()
 {
     if (mEffectInterface == NULL) {
@@ -5856,7 +5948,7 @@
     Mutex::Autolock _l(mLock);
 //    LOGV("command(), cmdCode: %d, mEffectInterface: %p", cmdCode, mEffectInterface);
 
-    if (mEffectInterface == NULL) {
+    if (mState == DESTROYED || mEffectInterface == NULL) {
         return NO_INIT;
     }
     status_t status = (*mEffectInterface)->command(mEffectInterface,
@@ -5905,6 +5997,8 @@
         case ACTIVE:
             mState = STOPPING;
             break;
+        case DESTROYED:
+            return NO_ERROR; // simply ignore as we are being destroyed
         }
         for (size_t i = 1; i < mHandles.size(); i++) {
             sp<EffectHandle> h = mHandles[i].promote();
@@ -5926,6 +6020,7 @@
     case IDLE:
     case STOPPING:
     case STOPPED:
+    case DESTROYED:
     default:
         return false;
     }
@@ -5941,6 +6036,7 @@
         return true;
     case IDLE:
     case STARTING:
+    case DESTROYED:
     default:
         return false;
     }
@@ -6542,6 +6638,10 @@
 
     for (i = 0; i < size; i++) {
         if (effect == mEffects[i]) {
+            // calling stop here will remove pre-processing effect from the audio HAL.
+            // This is safe as we hold the EffectChain mutex which guarantees that we are not in
+            // the middle of a read from audio HAL
+            mEffects[i]->stop();
             if (type == EFFECT_FLAG_TYPE_AUXILIARY) {
                 delete[] effect->inBuffer();
             } else {
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index fff4f06..7b6215f 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -43,6 +43,8 @@
 
 #include "AudioBufferProvider.h"
 
+#include <powermanager/IPowerManager.h>
+
 namespace android {
 
 class audio_track_cblk_t;
@@ -285,6 +287,9 @@
         };
 
         status_t dumpBase(int fd, const Vector<String16>& args);
+        status_t dumpEffectChains(int fd, const Vector<String16>& args);
+
+        void clearPowerManager();
 
         // base for record and playback
         class TrackBase : public AudioBufferProvider, public RefBase {
@@ -385,6 +390,21 @@
             int mParam;
         };
 
+        class PMDeathRecipient : public IBinder::DeathRecipient {
+        public:
+                        PMDeathRecipient(const wp<ThreadBase>& thread) : mThread(thread) {}
+            virtual     ~PMDeathRecipient() {}
+
+            // IBinder::DeathRecipient
+            virtual     void        binderDied(const wp<IBinder>& who);
+
+        private:
+                        PMDeathRecipient(const PMDeathRecipient&);
+                        PMDeathRecipient& operator = (const PMDeathRecipient&);
+
+            wp<ThreadBase> mThread;
+        };
+
         virtual     status_t    initCheck() const = 0;
                     int         type() const { return mType; }
                     uint32_t    sampleRate() const;
@@ -461,6 +481,11 @@
 
     protected:
 
+                    void        acquireWakeLock();
+                    void        acquireWakeLock_l();
+                    void        releaseWakeLock();
+                    void        releaseWakeLock_l();
+
         friend class Track;
         friend class TrackBase;
         friend class PlaybackThread;
@@ -489,6 +514,11 @@
                     Vector< sp<EffectChain> > mEffectChains;
                     uint32_t                mDevice;    // output device for PlaybackThread
                                                         // input + output devices for RecordThread
+                    static const int        kNameLength = 32;
+                    char                    mName[kNameLength];
+                    sp<IPowerManager>       mPowerManager;
+                    sp<IBinder>             mWakeLockToken;
+                    sp<PMDeathRecipient>    mDeathRecipient;
     };
 
     // --- PlaybackThread ---
@@ -724,7 +754,6 @@
 
         virtual status_t    dumpInternals(int fd, const Vector<String16>& args);
         status_t    dumpTracks(int fd, const Vector<String16>& args);
-        status_t    dumpEffectChains(int fd, const Vector<String16>& args);
 
         SortedVector< sp<Track> >       mTracks;
         // mStreamTypes[] uses 1 additionnal stream type internally for the OutputTrack used by DuplicatingThread
@@ -995,7 +1024,8 @@
             STARTING,
             ACTIVE,
             STOPPING,
-            STOPPED
+            STOPPED,
+            DESTROYED
         };
 
         int         id() { return mId; }
@@ -1040,6 +1070,7 @@
         status_t         setDevice(uint32_t device);
         status_t         setVolume(uint32_t *left, uint32_t *right, bool controller);
         status_t         setMode(uint32_t mode);
+        status_t         stop();
 
         status_t         dump(int fd, const Vector<String16>& args);
 
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index dd1e153..6d06d83 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -497,6 +497,43 @@
     return mpAudioPolicy->is_stream_active(mpAudioPolicy, stream, inPastMs);
 }
 
+status_t AudioPolicyService::queryDefaultPreProcessing(int audioSession,
+                                                       effect_descriptor_t *descriptors,
+                                                       uint32_t *count)
+{
+
+    if (mpAudioPolicy == NULL) {
+        *count = 0;
+        return NO_INIT;
+    }
+    Mutex::Autolock _l(mLock);
+    status_t status = NO_ERROR;
+
+    size_t index;
+    for (index = 0; index < mInputs.size(); index++) {
+        if (mInputs.valueAt(index)->mSessionId == audioSession) {
+            break;
+        }
+    }
+    if (index == mInputs.size()) {
+        *count = 0;
+        return BAD_VALUE;
+    }
+    Vector< sp<AudioEffect> > effects = mInputs.valueAt(index)->mEffects;
+
+    for (size_t i = 0; i < effects.size(); i++) {
+        effect_descriptor_t desc = effects[i]->descriptor();
+        if (i < *count) {
+            memcpy(descriptors + i, &desc, sizeof(effect_descriptor_t));
+        }
+    }
+    if (effects.size() > *count) {
+        status = NO_MEMORY;
+    }
+    *count = effects.size();
+    return status;
+}
+
 void AudioPolicyService::binderDied(const wp<IBinder>& who) {
     LOGW("binderDied() %p, tid %d, calling tid %d", who.unsafe_get(), gettid(),
             IPCThreadState::self()->getCallingPid());
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index 62ad29e..834b794 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -104,6 +104,9 @@
     virtual status_t unregisterEffect(int id);
     virtual bool isStreamActive(int stream, uint32_t inPastMs = 0) const;
 
+    virtual status_t queryDefaultPreProcessing(int audioSession,
+                                              effect_descriptor_t *descriptors,
+                                              uint32_t *count);
     virtual     status_t    onTransact(
                                 uint32_t code,
                                 const Parcel& data,
diff --git a/services/camera/libcameraservice/CameraHardwareInterface.h b/services/camera/libcameraservice/CameraHardwareInterface.h
index a583aad..31544b3 100644
--- a/services/camera/libcameraservice/CameraHardwareInterface.h
+++ b/services/camera/libcameraservice/CameraHardwareInterface.h
@@ -38,6 +38,7 @@
 
 typedef void (*data_callback)(int32_t msgType,
                             const sp<IMemory> &dataPtr,
+                            camera_frame_metadata_t *metadata,
                             void* user);
 
 typedef void (*data_callback_timestamp)(nsecs_t timestamp,
@@ -386,7 +387,10 @@
         if (mDevice->ops->get_parameters) {
             char *temp = mDevice->ops->get_parameters(mDevice);
             String8 str_parms(temp);
-            free(temp);
+            if (mDevice->ops->put_parameters)
+                mDevice->ops->put_parameters(mDevice, temp);
+            else
+                free(temp);
             parms.unflatten(str_parms);
         }
         return parms;
@@ -439,6 +443,7 @@
 
     static void __data_cb(int32_t msg_type,
                           const camera_memory_t *data, unsigned int index,
+                          camera_frame_metadata_t *metadata,
                           void *user)
     {
         LOGV("%s", __FUNCTION__);
@@ -450,7 +455,7 @@
                  index, mem->mNumBufs);
             return;
         }
-        __this->mDataCb(msg_type, mem->mBuffers[index], __this->mCbUser);
+        __this->mDataCb(msg_type, mem->mBuffers[index], metadata, __this->mCbUser);
     }
 
     static void __data_cb_timestamp(nsecs_t timestamp, int32_t msg_type,
diff --git a/services/camera/libcameraservice/CameraHardwareStub.cpp b/services/camera/libcameraservice/CameraHardwareStub.cpp
index 07b5a37..863f19e 100644
--- a/services/camera/libcameraservice/CameraHardwareStub.cpp
+++ b/services/camera/libcameraservice/CameraHardwareStub.cpp
@@ -180,7 +180,7 @@
 
         // Notify the client of a new frame.
         if (mMsgEnabled & CAMERA_MSG_PREVIEW_FRAME)
-            mDataCb(CAMERA_MSG_PREVIEW_FRAME, buffer, mCallbackCookie);
+            mDataCb(CAMERA_MSG_PREVIEW_FRAME, buffer, NULL, mCallbackCookie);
 
         // Advance the buffer pointer.
         mCurrentPreviewFrame = (mCurrentPreviewFrame + 1) % kBufferCount;
@@ -290,14 +290,14 @@
         sp<MemoryBase> mem = new MemoryBase(mRawHeap, 0, w * h * 3 / 2);
         FakeCamera cam(w, h);
         cam.getNextFrameAsYuv420((uint8_t *)mRawHeap->base());
-        mDataCb(CAMERA_MSG_RAW_IMAGE, mem, mCallbackCookie);
+        mDataCb(CAMERA_MSG_RAW_IMAGE, mem, NULL, mCallbackCookie);
     }
 
     if (mMsgEnabled & CAMERA_MSG_COMPRESSED_IMAGE) {
         sp<MemoryHeapBase> heap = new MemoryHeapBase(kCannedJpegSize);
         sp<MemoryBase> mem = new MemoryBase(heap, 0, kCannedJpegSize);
         memcpy(heap->base(), kCannedJpeg, kCannedJpegSize);
-        mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, mCallbackCookie);
+        mDataCb(CAMERA_MSG_COMPRESSED_IMAGE, mem, NULL, mCallbackCookie);
     }
     return NO_ERROR;
 }
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 96b26e7..b03649e 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -988,7 +988,7 @@
 }
 
 void CameraService::Client::dataCallback(int32_t msgType,
-        const sp<IMemory>& dataPtr, void* user) {
+        const sp<IMemory>& dataPtr, camera_frame_metadata_t *metadata, void* user) {
     LOG2("dataCallback(%d)", msgType);
 
     sp<Client> client = getClientFromCookie(user);
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index c5fefb8..af7f06e 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -140,7 +140,8 @@
 
         // these are static callback functions
         static void             notifyCallback(int32_t msgType, int32_t ext1, int32_t ext2, void* user);
-        static void             dataCallback(int32_t msgType, const sp<IMemory>& dataPtr, void* user);
+        static void             dataCallback(int32_t msgType, const sp<IMemory>& dataPtr,
+                                             camera_frame_metadata_t *metadata, void* user);
         static void             dataCallbackTimestamp(nsecs_t timestamp, int32_t msgType, const sp<IMemory>& dataPtr, void* user);
         // convert client from cookie
         static sp<Client>       getClientFromCookie(void* user);