am a4a81aef: am e7cedad2: am 2edbdcc6: Merge "After a seek there\'s a brief period where audio time isn\'t reestablished." into honeycomb-mr1

* commit 'a4a81aef39b15649bda146476d98f23ac554887f':
  After a seek there's a brief period where audio time isn't reestablished.
diff --git a/camera/Android.mk b/camera/Android.mk
index 2f16923..b17b3d2 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -13,7 +13,6 @@
 	libutils \
 	libbinder \
 	libhardware \
-	libsurfaceflinger_client \
 	libui \
 	libgui
 
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index 1b13dd9..e9642f7 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -8,7 +8,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libstagefright libmedia libutils libbinder libstagefright_foundation \
-        libskia libsurfaceflinger_client libgui
+        libskia libgui
 
 LOCAL_C_INCLUDES:= \
 	$(JNI_H_INCLUDE) \
@@ -107,7 +107,7 @@
         stream.cpp    \
 
 LOCAL_SHARED_LIBRARIES := \
-	libstagefright liblog libutils libbinder libsurfaceflinger_client \
+	libstagefright liblog libutils libbinder libgui \
         libstagefright_foundation libmedia
 
 LOCAL_C_INCLUDES:= \
@@ -132,7 +132,7 @@
 
 LOCAL_SHARED_LIBRARIES := \
 	libstagefright liblog libutils libbinder libstagefright_foundation \
-        libmedia libsurfaceflinger_client libcutils libui
+        libmedia libgui libcutils libui
 
 LOCAL_C_INCLUDES:= \
 	$(JNI_H_INCLUDE) \
diff --git a/drm/common/DrmInfoEvent.cpp b/drm/common/DrmInfoEvent.cpp
index 8d115a8..27a5a2d 100644
--- a/drm/common/DrmInfoEvent.cpp
+++ b/drm/common/DrmInfoEvent.cpp
@@ -19,7 +19,7 @@
 
 using namespace android;
 
-DrmInfoEvent::DrmInfoEvent(int uniqueId, int infoType, const String8& message)
+DrmInfoEvent::DrmInfoEvent(int uniqueId, int infoType, const String8 message)
     : mUniqueId(uniqueId),
       mInfoType(infoType),
       mMessage(message) {
@@ -34,7 +34,7 @@
     return mInfoType;
 }
 
-const String8& DrmInfoEvent::getMessage() const {
+const String8 DrmInfoEvent::getMessage() const {
     return mMessage;
 }
 
diff --git a/drm/common/DrmSupportInfo.cpp b/drm/common/DrmSupportInfo.cpp
index c0bff0e..3dee435 100644
--- a/drm/common/DrmSupportInfo.cpp
+++ b/drm/common/DrmSupportInfo.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <drm/DrmSupportInfo.h>
+#include <strings.h>
 
 using namespace android;
 
@@ -152,4 +153,3 @@
     mIndex++;
     return value;
 }
-
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 346934b..c37b4f8 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -650,11 +650,6 @@
 
     remote()->transact(CLOSE_DECRYPT_SESSION, data, &reply);
 
-    if (NULL != decryptHandle->decryptInfo) {
-        LOGV("deleting decryptInfo");
-        delete decryptHandle->decryptInfo; decryptHandle->decryptInfo = NULL;
-    }
-    delete decryptHandle; decryptHandle = NULL;
     return reply.readInt32();
 }
 
diff --git a/drm/drmserver/Android.mk b/drm/drmserver/Android.mk
index f94f9a3..e3cd44f 100644
--- a/drm/drmserver/Android.mk
+++ b/drm/drmserver/Android.mk
@@ -22,6 +22,7 @@
     DrmManagerService.cpp
 
 LOCAL_SHARED_LIBRARIES := \
+    libmedia \
     libutils \
     libbinder
 
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index 1eee5f2..2fee59c 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -37,7 +37,6 @@
 
 using namespace android;
 
-Vector<int> DrmManager::mUniqueIdVector;
 const String8 DrmManager::EMPTY_STRING("");
 
 DrmManager::DrmManager() :
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index 0901a44..583669e 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -19,6 +19,7 @@
 #include <utils/Log.h>
 
 #include <private/android_filesystem_config.h>
+#include <media/MemoryLeakTrackUtil.h>
 
 #include <errno.h>
 #include <utils/threads.h>
@@ -256,3 +257,31 @@
     return mDrmManager->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
 }
 
+status_t DrmManagerService::dump(int fd, const Vector<String16>& args)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    String8 result;
+    if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+        snprintf(buffer, SIZE, "Permission Denial: "
+                "can't dump DrmManagerService from pid=%d, uid=%d\n",
+                IPCThreadState::self()->getCallingPid(),
+                IPCThreadState::self()->getCallingUid());
+        result.append(buffer);
+    } else {
+#if DRM_MEMORY_LEAK_TRACK
+        bool dumpMem = false;
+        for (size_t i = 0; i < args.size(); i++) {
+            if (args[i] == String16("-m")) {
+                dumpMem = true;
+            }
+        }
+        if (dumpMem) {
+            dumpMemoryAddresses(fd);
+        }
+#endif
+    }
+    write(fd, result.string(), result.size());
+    return NO_ERROR;
+}
+
diff --git a/drm/libdrmframework/Android.mk b/drm/libdrmframework/Android.mk
index 99133ba..f1526a4 100644
--- a/drm/libdrmframework/Android.mk
+++ b/drm/libdrmframework/Android.mk
@@ -40,7 +40,7 @@
     $(TOP)/frameworks/base/drm/libdrmframework/include \
     $(TOP)/frameworks/base/include
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_MODULE_TAGS := optional
 
diff --git a/drm/libdrmframework/DrmManagerClient.cpp b/drm/libdrmframework/DrmManagerClient.cpp
index c1f382a..b50199f 100644
--- a/drm/libdrmframework/DrmManagerClient.cpp
+++ b/drm/libdrmframework/DrmManagerClient.cpp
@@ -76,12 +76,13 @@
     return mDrmManagerClientImpl->checkRightsStatus(mUniqueId, path, action);
 }
 
-status_t DrmManagerClient::consumeRights(DecryptHandle* decryptHandle, int action, bool reserve) {
+status_t DrmManagerClient::consumeRights(
+            sp<DecryptHandle> &decryptHandle, int action, bool reserve) {
     return mDrmManagerClientImpl->consumeRights(mUniqueId, decryptHandle, action, reserve);
 }
 
 status_t DrmManagerClient::setPlaybackStatus(
-            DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+            sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position) {
     return mDrmManagerClientImpl
             ->setPlaybackStatus(mUniqueId, decryptHandle, playbackStatus, position);
 }
@@ -115,37 +116,39 @@
     return mDrmManagerClientImpl->getAllSupportInfo(mUniqueId, length, drmSupportInfoArray);
 }
 
-DecryptHandle* DrmManagerClient::openDecryptSession(int fd, off64_t offset, off64_t length) {
+sp<DecryptHandle> DrmManagerClient::openDecryptSession(int fd, off64_t offset, off64_t length) {
     return mDrmManagerClientImpl->openDecryptSession(mUniqueId, fd, offset, length);
 }
 
-DecryptHandle* DrmManagerClient::openDecryptSession(const char* uri) {
+sp<DecryptHandle> DrmManagerClient::openDecryptSession(const char* uri) {
     return mDrmManagerClientImpl->openDecryptSession(mUniqueId, uri);
 }
 
-status_t DrmManagerClient::closeDecryptSession(DecryptHandle* decryptHandle) {
+status_t DrmManagerClient::closeDecryptSession(sp<DecryptHandle> &decryptHandle) {
     return mDrmManagerClientImpl->closeDecryptSession(mUniqueId, decryptHandle);
 }
 
 status_t DrmManagerClient::initializeDecryptUnit(
-            DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
+            sp<DecryptHandle> &decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo) {
     return mDrmManagerClientImpl->initializeDecryptUnit(
             mUniqueId, decryptHandle, decryptUnitId, headerInfo);
 }
 
 status_t DrmManagerClient::decrypt(
-    DecryptHandle* decryptHandle, int decryptUnitId,
-    const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+            sp<DecryptHandle> &decryptHandle, int decryptUnitId,
+            const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
     return mDrmManagerClientImpl->decrypt(
             mUniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
 }
 
-status_t DrmManagerClient::finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId) {
-    return mDrmManagerClientImpl->finalizeDecryptUnit(mUniqueId, decryptHandle, decryptUnitId);
+status_t DrmManagerClient::finalizeDecryptUnit(
+            sp<DecryptHandle> &decryptHandle, int decryptUnitId) {
+    return mDrmManagerClientImpl->finalizeDecryptUnit(mUniqueId,
+            decryptHandle, decryptUnitId);
 }
 
 ssize_t DrmManagerClient::pread(
-            DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off64_t offset) {
+            sp<DecryptHandle> &decryptHandle, void* buffer, ssize_t numBytes, off64_t offset) {
     return mDrmManagerClientImpl->pread(mUniqueId, decryptHandle, buffer, numBytes, offset);
 }
 
diff --git a/drm/libdrmframework/DrmManagerClientImpl.cpp b/drm/libdrmframework/DrmManagerClientImpl.cpp
index 9c7fed3..a57dd98 100644
--- a/drm/libdrmframework/DrmManagerClientImpl.cpp
+++ b/drm/libdrmframework/DrmManagerClientImpl.cpp
@@ -81,14 +81,16 @@
 }
 
 status_t DrmManagerClientImpl::setOnInfoListener(
-            int uniqueId, const sp<DrmManagerClient::OnInfoListener>& infoListener) {
+            int uniqueId,
+            const sp<DrmManagerClient::OnInfoListener>& infoListener) {
     Mutex::Autolock _l(mLock);
     mOnInfoListener = infoListener;
     return getDrmManagerService()->setDrmServiceListener(uniqueId,
             (NULL != infoListener.get()) ? this : NULL);
 }
 
-status_t DrmManagerClientImpl::installDrmEngine(int uniqueId, const String8& drmEngineFile) {
+status_t DrmManagerClientImpl::installDrmEngine(
+        int uniqueId, const String8& drmEngineFile) {
     status_t status = DRM_ERROR_UNKNOWN;
     if (EMPTY_STRING != drmEngineFile) {
         status = getDrmManagerService()->installDrmEngine(uniqueId, drmEngineFile);
@@ -100,7 +102,8 @@
         int uniqueId, const String8* path, const int action) {
     DrmConstraints *drmConstraints = NULL;
     if ((NULL != path) && (EMPTY_STRING != *path)) {
-        drmConstraints = getDrmManagerService()->getConstraints(uniqueId, path, action);
+        drmConstraints =
+            getDrmManagerService()->getConstraints(uniqueId, path, action);
     }
     return drmConstraints;
 }
@@ -113,7 +116,8 @@
     return drmMetadata;
 }
 
-bool DrmManagerClientImpl::canHandle(int uniqueId, const String8& path, const String8& mimeType) {
+bool DrmManagerClientImpl::canHandle(
+        int uniqueId, const String8& path, const String8& mimeType) {
     bool retCode = false;
     if ((EMPTY_STRING != path) || (EMPTY_STRING != mimeType)) {
         retCode = getDrmManagerService()->canHandle(uniqueId, path, mimeType);
@@ -121,7 +125,8 @@
     return retCode;
 }
 
-DrmInfoStatus* DrmManagerClientImpl::processDrmInfo(int uniqueId, const DrmInfo* drmInfo) {
+DrmInfoStatus* DrmManagerClientImpl::processDrmInfo(
+        int uniqueId, const DrmInfo* drmInfo) {
     DrmInfoStatus *drmInfoStatus = NULL;
     if (NULL != drmInfo) {
         drmInfoStatus = getDrmManagerService()->processDrmInfo(uniqueId, drmInfo);
@@ -129,7 +134,8 @@
     return drmInfoStatus;
 }
 
-DrmInfo* DrmManagerClientImpl::acquireDrmInfo(int uniqueId, const DrmInfoRequest* drmInfoRequest) {
+DrmInfo* DrmManagerClientImpl::acquireDrmInfo(
+        int uniqueId, const DrmInfoRequest* drmInfoRequest) {
     DrmInfo* drmInfo = NULL;
     if (NULL != drmInfoRequest) {
         drmInfo = getDrmManagerService()->acquireDrmInfo(uniqueId, drmInfoRequest);
@@ -140,13 +146,12 @@
 status_t DrmManagerClientImpl::saveRights(int uniqueId, const DrmRights& drmRights,
             const String8& rightsPath, const String8& contentPath) {
     status_t status = DRM_ERROR_UNKNOWN;
-    if (EMPTY_STRING != contentPath) {
-        status = getDrmManagerService()->saveRights(uniqueId, drmRights, rightsPath, contentPath);
-    }
-    return status;
+    return getDrmManagerService()->saveRights(
+                uniqueId, drmRights, rightsPath, contentPath);
 }
 
-String8 DrmManagerClientImpl::getOriginalMimeType(int uniqueId, const String8& path) {
+String8 DrmManagerClientImpl::getOriginalMimeType(
+        int uniqueId, const String8& path) {
     String8 mimeType = EMPTY_STRING;
     if (EMPTY_STRING != path) {
         mimeType = getDrmManagerService()->getOriginalMimeType(uniqueId, path);
@@ -158,7 +163,8 @@
             int uniqueId, const String8& path, const String8& mimeType) {
     int drmOjectType = DrmObjectType::UNKNOWN;
     if ((EMPTY_STRING != path) || (EMPTY_STRING != mimeType)) {
-         drmOjectType = getDrmManagerService()->getDrmObjectType(uniqueId, path, mimeType);
+         drmOjectType =
+             getDrmManagerService()->getDrmObjectType(uniqueId, path, mimeType);
     }
     return drmOjectType;
 }
@@ -167,35 +173,41 @@
             int uniqueId, const String8& path, int action) {
     int rightsStatus = RightsStatus::RIGHTS_INVALID;
     if (EMPTY_STRING != path) {
-        rightsStatus = getDrmManagerService()->checkRightsStatus(uniqueId, path, action);
+        rightsStatus =
+            getDrmManagerService()->checkRightsStatus(uniqueId, path, action);
     }
     return rightsStatus;
 }
 
 status_t DrmManagerClientImpl::consumeRights(
-            int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
+            int uniqueId, sp<DecryptHandle> &decryptHandle,
+            int action, bool reserve) {
     status_t status = DRM_ERROR_UNKNOWN;
-    if (NULL != decryptHandle) {
-        status = getDrmManagerService()->consumeRights(uniqueId, decryptHandle, action, reserve);
+    if (NULL != decryptHandle.get()) {
+        status = getDrmManagerService()->consumeRights(
+                uniqueId, decryptHandle.get(), action, reserve);
     }
     return status;
 }
 
 status_t DrmManagerClientImpl::setPlaybackStatus(
-            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
+            int uniqueId, sp<DecryptHandle> &decryptHandle,
+            int playbackStatus, int64_t position) {
     status_t status = DRM_ERROR_UNKNOWN;
-    if (NULL != decryptHandle) {
+    if (NULL != decryptHandle.get()) {
         status = getDrmManagerService()->setPlaybackStatus(
-                uniqueId, decryptHandle, playbackStatus, position);
+                uniqueId, decryptHandle.get(), playbackStatus, position);
     }
     return status;
 }
 
 bool DrmManagerClientImpl::validateAction(
-            int uniqueId, const String8& path, int action, const ActionDescription& description) {
+            int uniqueId, const String8& path,
+            int action, const ActionDescription& description) {
     bool retCode = false;
     if (EMPTY_STRING != path) {
-        retCode = getDrmManagerService()->validateAction(uniqueId, path, action, description);
+        retCode = getDrmManagerService()->validateAction(
+                uniqueId, path, action, description);
     }
     return retCode;
 }
@@ -212,7 +224,8 @@
     return getDrmManagerService()->removeAllRights(uniqueId);
 }
 
-int DrmManagerClientImpl::openConvertSession(int uniqueId, const String8& mimeType) {
+int DrmManagerClientImpl::openConvertSession(
+        int uniqueId, const String8& mimeType) {
     int retCode = INVALID_VALUE;
     if (EMPTY_STRING != mimeType) {
         retCode = getDrmManagerService()->openConvertSession(uniqueId, mimeType);
@@ -224,12 +237,14 @@
             int uniqueId, int convertId, const DrmBuffer* inputData) {
     DrmConvertedStatus* drmConvertedStatus = NULL;
     if (NULL != inputData) {
-         drmConvertedStatus = getDrmManagerService()->convertData(uniqueId, convertId, inputData);
+         drmConvertedStatus =
+             getDrmManagerService()->convertData(uniqueId, convertId, inputData);
     }
     return drmConvertedStatus;
 }
 
-DrmConvertedStatus* DrmManagerClientImpl::closeConvertSession(int uniqueId, int convertId) {
+DrmConvertedStatus* DrmManagerClientImpl::closeConvertSession(
+        int uniqueId, int convertId) {
     return getDrmManagerService()->closeConvertSession(uniqueId, convertId);
 }
 
@@ -237,17 +252,19 @@
             int uniqueId, int* length, DrmSupportInfo** drmSupportInfoArray) {
     status_t status = DRM_ERROR_UNKNOWN;
     if ((NULL != drmSupportInfoArray) && (NULL != length)) {
-        status = getDrmManagerService()->getAllSupportInfo(uniqueId, length, drmSupportInfoArray);
+        status = getDrmManagerService()->getAllSupportInfo(
+                uniqueId, length, drmSupportInfoArray);
     }
     return status;
 }
 
-DecryptHandle* DrmManagerClientImpl::openDecryptSession(
+sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession(
             int uniqueId, int fd, off64_t offset, off64_t length) {
     return getDrmManagerService()->openDecryptSession(uniqueId, fd, offset, length);
 }
 
-DecryptHandle* DrmManagerClientImpl::openDecryptSession(int uniqueId, const char* uri) {
+sp<DecryptHandle> DrmManagerClientImpl::openDecryptSession(
+        int uniqueId, const char* uri) {
     DecryptHandle* handle = NULL;
     if (NULL != uri) {
         handle = getDrmManagerService()->openDecryptSession(uniqueId, uri);
@@ -255,50 +272,57 @@
     return handle;
 }
 
-status_t DrmManagerClientImpl::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
+status_t DrmManagerClientImpl::closeDecryptSession(
+        int uniqueId, sp<DecryptHandle> &decryptHandle) {
     status_t status = DRM_ERROR_UNKNOWN;
-    if (NULL != decryptHandle) {
-        status = getDrmManagerService()->closeDecryptSession( uniqueId, decryptHandle);
+    if (NULL != decryptHandle.get()) {
+        status = getDrmManagerService()->closeDecryptSession(
+                uniqueId, decryptHandle.get());
     }
     return status;
 }
 
-status_t DrmManagerClientImpl::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* headerInfo) {
+status_t DrmManagerClientImpl::initializeDecryptUnit(
+        int uniqueId, sp<DecryptHandle> &decryptHandle,
+        int decryptUnitId, const DrmBuffer* headerInfo) {
     status_t status = DRM_ERROR_UNKNOWN;
-    if ((NULL != decryptHandle) && (NULL != headerInfo)) {
+    if ((NULL != decryptHandle.get()) && (NULL != headerInfo)) {
         status = getDrmManagerService()->initializeDecryptUnit(
-                uniqueId, decryptHandle, decryptUnitId, headerInfo);
+                uniqueId, decryptHandle.get(), decryptUnitId, headerInfo);
     }
     return status;
 }
 
-status_t DrmManagerClientImpl::decrypt(int uniqueId, DecryptHandle* decryptHandle,
-            int decryptUnitId, const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
+status_t DrmManagerClientImpl::decrypt(
+        int uniqueId, sp<DecryptHandle> &decryptHandle,
+        int decryptUnitId, const DrmBuffer* encBuffer,
+        DrmBuffer** decBuffer, DrmBuffer* IV) {
     status_t status = DRM_ERROR_UNKNOWN;
-    if ((NULL != decryptHandle) && (NULL != encBuffer)
+    if ((NULL != decryptHandle.get()) && (NULL != encBuffer)
         && (NULL != decBuffer) && (NULL != *decBuffer)) {
         status = getDrmManagerService()->decrypt(
-                uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
+                uniqueId, decryptHandle.get(), decryptUnitId,
+                encBuffer, decBuffer, IV);
     }
     return status;
 }
 
 status_t DrmManagerClientImpl::finalizeDecryptUnit(
-            int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
+            int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId) {
     status_t status = DRM_ERROR_UNKNOWN;
-    if (NULL != decryptHandle) {
-        status
-            = getDrmManagerService()->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
+    if (NULL != decryptHandle.get()) {
+        status = getDrmManagerService()->finalizeDecryptUnit(
+                    uniqueId, decryptHandle.get(), decryptUnitId);
     }
     return status;
 }
 
-ssize_t DrmManagerClientImpl::pread(int uniqueId, DecryptHandle* decryptHandle,
+ssize_t DrmManagerClientImpl::pread(int uniqueId, sp<DecryptHandle> &decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset) {
     ssize_t retCode = INVALID_VALUE;
-    if ((NULL != decryptHandle) && (NULL != buffer) && (0 < numBytes)) {
-        retCode = getDrmManagerService()->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
+    if ((NULL != decryptHandle.get()) && (NULL != buffer) && (0 < numBytes)) {
+        retCode = getDrmManagerService()->pread(
+                uniqueId, decryptHandle.get(), buffer, numBytes, offset);
     }
     return retCode;
 }
diff --git a/drm/libdrmframework/include/DrmManager.h b/drm/libdrmframework/include/DrmManager.h
index c7276f9..af2c2a8 100644
--- a/drm/libdrmframework/include/DrmManager.h
+++ b/drm/libdrmframework/include/DrmManager.h
@@ -30,7 +30,6 @@
 class DrmRegistrationInfo;
 class DrmUnregistrationInfo;
 class DrmRightsAcquisitionInfo;
-class DrmContentIds;
 class DrmConstraints;
 class DrmMetadata;
 class DrmRights;
@@ -141,7 +140,7 @@
     bool canHandle(int uniqueId, const String8& path);
 
 private:
-    static Vector<int> mUniqueIdVector;
+    Vector<int> mUniqueIdVector;
     static const String8 EMPTY_STRING;
 
     int mDecryptSessionId;
diff --git a/drm/libdrmframework/include/DrmManagerClientImpl.h b/drm/libdrmframework/include/DrmManagerClientImpl.h
index 429e4c3..564896b 100644
--- a/drm/libdrmframework/include/DrmManagerClientImpl.h
+++ b/drm/libdrmframework/include/DrmManagerClientImpl.h
@@ -189,7 +189,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t consumeRights(int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t consumeRights(int uniqueId, sp<DecryptHandle> &decryptHandle, int action, bool reserve);
 
     /**
      * Informs the DRM engine about the playback actions performed on the DRM files.
@@ -203,7 +203,7 @@
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
     status_t setPlaybackStatus(
-            int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+            int uniqueId, sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position);
 
     /**
      * Validates whether an action on the DRM content is allowed or not.
@@ -303,7 +303,7 @@
      * @return
      *     Handle for the decryption session
      */
-    DecryptHandle* openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length);
+    sp<DecryptHandle> openDecryptSession(int uniqueId, int fd, off64_t offset, off64_t length);
 
     /**
      * Open the decrypt session to decrypt the given protected content
@@ -313,7 +313,7 @@
      * @return
      *     Handle for the decryption session
      */
-    DecryptHandle* openDecryptSession(int uniqueId, const char* uri);
+    sp<DecryptHandle> openDecryptSession(int uniqueId, const char* uri);
 
     /**
      * Close the decrypt session for the given handle
@@ -323,7 +323,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle);
+    status_t closeDecryptSession(int uniqueId, sp<DecryptHandle> &decryptHandle);
 
     /**
      * Initialize decryption for the given unit of the protected content
@@ -335,7 +335,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
+    status_t initializeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle,
             int decryptUnitId, const DrmBuffer* headerInfo);
 
     /**
@@ -355,7 +355,7 @@
      *     DRM_ERROR_SESSION_NOT_OPENED, DRM_ERROR_DECRYPT_UNIT_NOT_INITIALIZED,
      *     DRM_ERROR_DECRYPT for failure.
      */
-    status_t decrypt(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
+    status_t decrypt(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV);
 
     /**
@@ -367,7 +367,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t finalizeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t finalizeDecryptUnit(int uniqueId, sp<DecryptHandle> &decryptHandle, int decryptUnitId);
 
     /**
      * Reads the specified number of bytes from an open DRM file.
@@ -380,7 +380,7 @@
      *
      * @return Number of bytes read. Returns -1 for Failure.
      */
-    ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
+    ssize_t pread(int uniqueId, sp<DecryptHandle> &decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset);
 
     /**
diff --git a/drm/libdrmframework/include/DrmManagerService.h b/drm/libdrmframework/include/DrmManagerService.h
index d0a0db7..227496a 100644
--- a/drm/libdrmframework/include/DrmManagerService.h
+++ b/drm/libdrmframework/include/DrmManagerService.h
@@ -115,6 +115,8 @@
     ssize_t pread(int uniqueId, DecryptHandle* decryptHandle,
             void* buffer, ssize_t numBytes, off64_t offset);
 
+    virtual status_t dump(int fd, const Vector<String16>& args);
+
 private:
     DrmManager* mDrmManager;
 };
diff --git a/drm/libdrmframework/include/IDrmManagerService.h b/drm/libdrmframework/include/IDrmManagerService.h
index 2424ea5..7727e55 100644
--- a/drm/libdrmframework/include/IDrmManagerService.h
+++ b/drm/libdrmframework/include/IDrmManagerService.h
@@ -25,7 +25,6 @@
 
 namespace android {
 
-class DrmContentIds;
 class DrmConstraints;
 class DrmMetadata;
 class DrmRights;
diff --git a/drm/libdrmframework/plugins/common/include/IDrmEngine.h b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
index d05c24f..77460f6 100644
--- a/drm/libdrmframework/plugins/common/include/IDrmEngine.h
+++ b/drm/libdrmframework/plugins/common/include/IDrmEngine.h
@@ -21,7 +21,6 @@
 
 namespace android {
 
-class DrmContentIds;
 class DrmConstraints;
 class DrmMetadata;
 class DrmRights;
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
index af67aa3..9805a40 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
@@ -47,7 +47,7 @@
     libfwdlock-converter \
     libfwdlock-decoder
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_C_INCLUDES += \
     $(JNI_H_INCLUDE) \
diff --git a/drm/libdrmframework/plugins/passthru/Android.mk b/drm/libdrmframework/plugins/passthru/Android.mk
index 7856d37..be18b64 100644
--- a/drm/libdrmframework/plugins/passthru/Android.mk
+++ b/drm/libdrmframework/plugins/passthru/Android.mk
@@ -32,7 +32,7 @@
  LOCAL_SHARED_LIBRARIES += libdl
 endif
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_C_INCLUDES += \
     $(TOP)/frameworks/base/drm/libdrmframework/include \
diff --git a/include/drm/DrmInfoEvent.h b/include/drm/DrmInfoEvent.h
index add33d3..dfca228 100644
--- a/include/drm/DrmInfoEvent.h
+++ b/include/drm/DrmInfoEvent.h
@@ -77,7 +77,7 @@
      * @param[in] infoType Type of information
      * @param[in] message Message description
      */
-    DrmInfoEvent(int uniqueId, int infoType, const String8& message);
+    DrmInfoEvent(int uniqueId, int infoType, const String8 message);
 
     /**
      * Destructor for DrmInfoEvent
@@ -104,12 +104,12 @@
      *
      * @return Message description
      */
-    const String8& getMessage() const;
+    const String8 getMessage() const;
 
 private:
     int mUniqueId;
     int mInfoType;
-    const String8& mMessage;
+    const String8 mMessage;
 };
 
 };
diff --git a/include/drm/DrmManagerClient.h b/include/drm/DrmManagerClient.h
index 7a0bf4f..b8fe46d 100644
--- a/include/drm/DrmManagerClient.h
+++ b/include/drm/DrmManagerClient.h
@@ -69,7 +69,7 @@
      * @return
      *     Handle for the decryption session
      */
-    DecryptHandle* openDecryptSession(int fd, off64_t offset, off64_t length);
+    sp<DecryptHandle> openDecryptSession(int fd, off64_t offset, off64_t length);
 
     /**
      * Open the decrypt session to decrypt the given protected content
@@ -78,7 +78,7 @@
      * @return
      *     Handle for the decryption session
      */
-    DecryptHandle* openDecryptSession(const char* uri);
+    sp<DecryptHandle> openDecryptSession(const char* uri);
 
     /**
      * Close the decrypt session for the given handle
@@ -87,7 +87,7 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t closeDecryptSession(DecryptHandle* decryptHandle);
+    status_t closeDecryptSession(sp<DecryptHandle> &decryptHandle);
 
     /**
      * Consumes the rights for a content.
@@ -101,7 +101,7 @@
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure.
      *     In case license has been expired, DRM_ERROR_LICENSE_EXPIRED will be returned.
      */
-    status_t consumeRights(DecryptHandle* decryptHandle, int action, bool reserve);
+    status_t consumeRights(sp<DecryptHandle> &decryptHandle, int action, bool reserve);
 
     /**
      * Informs the DRM engine about the playback actions performed on the DRM files.
@@ -113,7 +113,8 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t setPlaybackStatus(DecryptHandle* decryptHandle, int playbackStatus, int64_t position);
+    status_t setPlaybackStatus(
+            sp<DecryptHandle> &decryptHandle, int playbackStatus, int64_t position);
 
     /**
      * Initialize decryption for the given unit of the protected content
@@ -125,7 +126,7 @@
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
     status_t initializeDecryptUnit(
-            DecryptHandle* decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo);
+            sp<DecryptHandle> &decryptHandle, int decryptUnitId, const DrmBuffer* headerInfo);
 
     /**
      * Decrypt the protected content buffers for the given unit
@@ -144,7 +145,7 @@
      *     DRM_ERROR_DECRYPT for failure.
      */
     status_t decrypt(
-            DecryptHandle* decryptHandle, int decryptUnitId,
+            sp<DecryptHandle> &decryptHandle, int decryptUnitId,
             const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV = NULL);
 
     /**
@@ -155,7 +156,8 @@
      * @return status_t
      *     Returns DRM_NO_ERROR for success, DRM_ERROR_UNKNOWN for failure
      */
-    status_t finalizeDecryptUnit(DecryptHandle* decryptHandle, int decryptUnitId);
+    status_t finalizeDecryptUnit(
+            sp<DecryptHandle> &decryptHandle, int decryptUnitId);
 
     /**
      * Reads the specified number of bytes from an open DRM file.
@@ -167,7 +169,8 @@
      *
      * @return Number of bytes read. Returns -1 for Failure.
      */
-    ssize_t pread(DecryptHandle* decryptHandle, void* buffer, ssize_t numBytes, off64_t offset);
+    ssize_t pread(sp<DecryptHandle> &decryptHandle,
+            void* buffer, ssize_t numBytes, off64_t offset);
 
     /**
      * Validates whether an action on the DRM content is allowed or not.
diff --git a/include/drm/drm_framework_common.h b/include/drm/drm_framework_common.h
index 454fc99..d2d1d7e 100644
--- a/include/drm/drm_framework_common.h
+++ b/include/drm/drm_framework_common.h
@@ -19,6 +19,7 @@
 
 #include <utils/Vector.h>
 #include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
 #include <utils/String8.h>
 #include <utils/Errors.h>
 
@@ -251,7 +252,7 @@
 /**
  * Defines decryption handle
  */
-class DecryptHandle {
+class DecryptHandle : public RefBase {
 public:
     /**
      * Decryption session Handle
@@ -307,10 +308,15 @@
             decryptId(INVALID_VALUE),
             mimeType(""),
             decryptApiType(INVALID_VALUE),
-            status(INVALID_VALUE) {
+            status(INVALID_VALUE),
+            decryptInfo(NULL) {
 
     }
 
+    ~DecryptHandle() {
+        delete decryptInfo; decryptInfo = NULL;
+    }
+
     bool operator<(const DecryptHandle& handle) const {
         return (decryptId < handle.decryptId);
     }
diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h
index 8e3cdbb..1c1c268 100644
--- a/include/media/IMediaMetadataRetriever.h
+++ b/include/media/IMediaMetadataRetriever.h
@@ -18,10 +18,11 @@
 #ifndef ANDROID_IMEDIAMETADATARETRIEVER_H
 #define ANDROID_IMEDIAMETADATARETRIEVER_H
 
-#include <utils/RefBase.h>
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
 #include <binder/IMemory.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
 
 namespace android {
 
@@ -30,7 +31,11 @@
 public:
     DECLARE_META_INTERFACE(MediaMetadataRetriever);
     virtual void            disconnect() = 0;
-    virtual status_t        setDataSource(const char* srcUrl) = 0;
+
+    virtual status_t        setDataSource(
+            const char *srcUrl,
+            const KeyedVector<String8, String8> *headers = NULL) = 0;
+
     virtual status_t        setDataSource(int fd, int64_t offset, int64_t length) = 0;
     virtual sp<IMemory>     getFrameAtTime(int64_t timeUs, int option) = 0;
     virtual sp<IMemory>     extractAlbumArt() = 0;
diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h
index 0449122..27b7e4d 100644
--- a/include/media/MediaMetadataRetrieverInterface.h
+++ b/include/media/MediaMetadataRetrieverInterface.h
@@ -30,7 +30,11 @@
 public:
                         MediaMetadataRetrieverBase() {}
     virtual             ~MediaMetadataRetrieverBase() {}
-    virtual status_t    setDataSource(const char *url) = 0;
+
+    virtual status_t    setDataSource(
+            const char *url,
+            const KeyedVector<String8, String8> *headers = NULL) = 0;
+
     virtual status_t    setDataSource(int fd, int64_t offset, int64_t length) = 0;
     virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) = 0;
     virtual MediaAlbumArt* extractAlbumArt() = 0;
diff --git a/include/media/MemoryLeakTrackUtil.h b/include/media/MemoryLeakTrackUtil.h
new file mode 100644
index 0000000..290b748
--- /dev/null
+++ b/include/media/MemoryLeakTrackUtil.h
@@ -0,0 +1,28 @@
+
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MEMORY_LEAK_TRACK_UTIL_H
+#define MEMORY_LEAK_TRACK_UTIL_H
+
+namespace android {
+/*
+ * Dump the memory adddress of the calling process to the given fd.
+ */
+extern void dumpMemoryAddresses(int fd);
+
+};
+
+#endif  // MEMORY_LEAK_TRACK_UTIL_H
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index e905006..3e343e0 100644
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -47,6 +47,12 @@
     METADATA_KEY_ALBUMARTIST     = 13,
     METADATA_KEY_DISC_NUMBER     = 14,
     METADATA_KEY_COMPILATION     = 15,
+    METADATA_KEY_HAS_AUDIO       = 16,
+    METADATA_KEY_HAS_VIDEO       = 17,
+    METADATA_KEY_VIDEO_WIDTH     = 18,
+    METADATA_KEY_VIDEO_HEIGHT    = 19,
+    METADATA_KEY_BITRATE         = 20,
+
     // Add more here...
 };
 
@@ -56,7 +62,11 @@
     MediaMetadataRetriever();
     ~MediaMetadataRetriever();
     void disconnect();
-    status_t setDataSource(const char* dataSourceUrl);
+
+    status_t setDataSource(
+            const char *dataSourceUrl,
+            const KeyedVector<String8, String8> *headers = NULL);
+
     status_t setDataSource(int fd, int64_t offset, int64_t length);
     sp<IMemory> getFrameAtTime(int64_t timeUs, int option);
     sp<IMemory> extractAlbumArt();
diff --git a/include/media/mediarecorder.h b/include/media/mediarecorder.h
index a710546..67d940b 100644
--- a/include/media/mediarecorder.h
+++ b/include/media/mediarecorder.h
@@ -104,35 +104,62 @@
 };
 
 /*
- * The state machine of the media_recorder uses a set of different state names.
- * The mapping between the media_recorder and the pvauthorengine is shown below:
- *
- *    mediarecorder                        pvauthorengine
- * ----------------------------------------------------------------
- *    MEDIA_RECORDER_ERROR                 ERROR
- *    MEDIA_RECORDER_IDLE                  IDLE
- *    MEDIA_RECORDER_INITIALIZED           OPENED
- *    MEDIA_RECORDER_DATASOURCE_CONFIGURED
- *    MEDIA_RECORDER_PREPARED              INITIALIZED
- *    MEDIA_RECORDER_RECORDING             RECORDING
+ * The state machine of the media_recorder.
  */
 enum media_recorder_states {
+    // Error state.
     MEDIA_RECORDER_ERROR                 =      0,
+
+    // Recorder was just created.
     MEDIA_RECORDER_IDLE                  = 1 << 0,
+
+    // Recorder has been initialized.
     MEDIA_RECORDER_INITIALIZED           = 1 << 1,
+
+    // Configuration of the recorder has been completed.
     MEDIA_RECORDER_DATASOURCE_CONFIGURED = 1 << 2,
+
+    // Recorder is ready to start.
     MEDIA_RECORDER_PREPARED              = 1 << 3,
+
+    // Recording is in progress.
     MEDIA_RECORDER_RECORDING             = 1 << 4,
 };
 
 // The "msg" code passed to the listener in notify.
 enum media_recorder_event_type {
+    MEDIA_RECORDER_EVENT_LIST_START               = 1,
     MEDIA_RECORDER_EVENT_ERROR                    = 1,
-    MEDIA_RECORDER_EVENT_INFO                     = 2
+    MEDIA_RECORDER_EVENT_INFO                     = 2,
+    MEDIA_RECORDER_EVENT_LIST_END                 = 99,
+
+    // Track related event types
+    MEDIA_RECORDER_TRACK_EVENT_LIST_START         = 100,
+    MEDIA_RECORDER_TRACK_EVENT_ERROR              = 100,
+    MEDIA_RECORDER_TRACK_EVENT_INFO               = 101,
+    MEDIA_RECORDER_TRACK_EVENT_LIST_END           = 1000,
 };
 
+/*
+ * The (part of) "what" code passed to the listener in notify.
+ * When the error or info type is track specific, the what has
+ * the following layout:
+ * the left-most 16-bit is meant for error or info type.
+ * the right-most 4-bit is meant for track id.
+ * the rest is reserved.
+ *
+ * | track id | reserved |     error or info type     |
+ * 31         28         16                           0
+ *
+ */
 enum media_recorder_error_type {
-    MEDIA_RECORDER_ERROR_UNKNOWN                  = 1
+    MEDIA_RECORDER_ERROR_UNKNOWN                   = 1,
+
+    // Track related error type
+    MEDIA_RECORDER_TRACK_ERROR_LIST_START          = 100,
+    MEDIA_RECORDER_TRACK_ERROR_GENERAL             = 100,
+    MEDIA_RECORDER_ERROR_VIDEO_NO_SYNC_FRAME       = 200,
+    MEDIA_RECORDER_TRACK_ERROR_LIST_END            = 1000,
 };
 
 // The codes are distributed as follow:
@@ -141,11 +168,15 @@
 //
 enum media_recorder_info_type {
     MEDIA_RECORDER_INFO_UNKNOWN                   = 1,
+
     MEDIA_RECORDER_INFO_MAX_DURATION_REACHED      = 800,
     MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED      = 801,
-    MEDIA_RECORDER_INFO_COMPLETION_STATUS         = 802,
-    MEDIA_RECORDER_INFO_PROGRESS_FRAME_STATUS     = 803,
-    MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS      = 804,
+
+    // All track related informtional events start here
+    MEDIA_RECORDER_TRACK_INFO_LIST_START           = 1000,
+    MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS    = 1000,
+    MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME     = 1001,
+    MEDIA_RECORDER_TRACK_INFO_LIST_END             = 2000,
 };
 
 // ----------------------------------------------------------------------------
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index d12ee9c..0b79324 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -108,6 +108,8 @@
 
     void reset();
 
+    uint32_t getNumFramesPendingPlayout() const;
+
     AudioPlayer(const AudioPlayer &);
     AudioPlayer &operator=(const AudioPlayer &);
 };
diff --git a/include/media/stagefright/DataSource.h b/include/media/stagefright/DataSource.h
index f95e56a..d30e908 100644
--- a/include/media/stagefright/DataSource.h
+++ b/include/media/stagefright/DataSource.h
@@ -75,10 +75,10 @@
     static void RegisterDefaultSniffers();
 
     // for DRM
-    virtual DecryptHandle* DrmInitialization() {
+    virtual sp<DecryptHandle> DrmInitialization() {
         return NULL;
     }
-    virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {};
+    virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {};
 
     virtual String8 getUri() {
         return String8();
diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h
index 51a4343..6cf86dc 100644
--- a/include/media/stagefright/FileSource.h
+++ b/include/media/stagefright/FileSource.h
@@ -38,9 +38,9 @@
 
     virtual status_t getSize(off64_t *size);
 
-    virtual DecryptHandle* DrmInitialization();
+    virtual sp<DecryptHandle> DrmInitialization();
 
-    virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client);
+    virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
 
 protected:
     virtual ~FileSource();
@@ -52,7 +52,7 @@
     Mutex mLock;
 
     /*for DRM*/
-    DecryptHandle *mDecryptHandle;
+    sp<DecryptHandle> mDecryptHandle;
     DrmManagerClient *mDrmManagerClient;
     int64_t mDrmBufOffset;
     int64_t mDrmBufSize;
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index 5c5229d..15f86ea 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -157,7 +157,7 @@
     bool use32BitFileOffset() const;
     bool exceedsFileDurationLimit();
     bool isFileStreamable() const;
-    void trackProgressStatus(const Track* track, int64_t timeUs, status_t err = OK);
+    void trackProgressStatus(size_t trackId, int64_t timeUs, status_t err = OK);
     void writeCompositionMatrix(int32_t degrees);
 
     MPEG4Writer(const MPEG4Writer &);
diff --git a/media/libeffects/lvm/lib/Android.mk b/media/libeffects/lvm/lib/Android.mk
index ff34707..f49267e 100644
--- a/media/libeffects/lvm/lib/Android.mk
+++ b/media/libeffects/lvm/lib/Android.mk
@@ -105,7 +105,7 @@
 
 LOCAL_MODULE:= libmusicbundle
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_C_INCLUDES += \
     $(LOCAL_PATH)/Eq/lib \
@@ -168,7 +168,7 @@
 
 LOCAL_MODULE:= libreverb
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_C_INCLUDES += \
     $(LOCAL_PATH)/Reverb/lib \
diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk
index 2e9b9b4..99cfdfa 100644
--- a/media/libeffects/lvm/wrapper/Android.mk
+++ b/media/libeffects/lvm/wrapper/Android.mk
@@ -13,7 +13,7 @@
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_STATIC_LIBRARIES += libmusicbundle
 
@@ -47,7 +47,7 @@
 
 LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_STATIC_LIBRARIES += libreverb
 
diff --git a/media/libeffects/visualizer/Android.mk b/media/libeffects/visualizer/Android.mk
index e6ff654..3a0f438 100644
--- a/media/libeffects/visualizer/Android.mk
+++ b/media/libeffects/visualizer/Android.mk
@@ -25,6 +25,6 @@
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, graphics corecg)
 
-LOCAL_PRELINK_MODULE := false
+
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index fd4c6c6..ca7441a 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -33,11 +33,12 @@
     IEffectClient.cpp \
     AudioEffect.cpp \
     Visualizer.cpp \
+    MemoryLeakTrackUtil.cpp \
     fixedfft.cpp.arm
 
 LOCAL_SHARED_LIBRARIES := \
 	libui libcutils libutils libbinder libsonivox libicuuc libexpat \
-        libsurfaceflinger_client libcamera_client libstagefright_foundation \
+        libcamera_client libstagefright_foundation \
         libgui
 
 LOCAL_MODULE:= libmedia
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index a18bedb..cee1c75 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -722,9 +722,12 @@
     // Manage overrun callback
     if (mActive && (cblk->framesAvailable() == 0)) {
         LOGV("Overrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
+        AutoMutex _l(cblk->lock);
         if ((cblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) {
-            mCbf(EVENT_OVERRUN, mUserData, 0);
             cblk->flags |= CBLK_UNDERRUN_ON;
+            cblk->lock.unlock();
+            mCbf(EVENT_OVERRUN, mUserData, 0);
+            cblk->lock.lock();
         }
     }
 
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 8d8f67b..fb2ee0f 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -329,6 +329,7 @@
     if (mActive == 0) {
         mActive = 1;
         mNewPosition = cblk->server + mUpdatePeriod;
+        cblk->lock.lock();
         cblk->bufferTimeoutMs = MAX_STARTUP_TIMEOUT_MS;
         cblk->waitTimeMs = 0;
         cblk->flags &= ~CBLK_DISABLED_ON;
@@ -339,7 +340,6 @@
         }
 
         LOGV("start %p before lock cblk %p", this, mCblk);
-        cblk->lock.lock();
         if (!(cblk->flags & CBLK_INVALID_MSK)) {
             cblk->lock.unlock();
             status = mAudioTrack->start();
@@ -546,12 +546,13 @@
     }
 
     if (loopStart >= loopEnd ||
-        loopEnd - loopStart > cblk->frameCount) {
+        loopEnd - loopStart > cblk->frameCount ||
+        cblk->server > loopStart) {
         LOGE("setLoop invalid value: loopStart %d, loopEnd %d, loopCount %d, framecount %d, user %d", loopStart, loopEnd, loopCount, cblk->frameCount, cblk->user);
         return BAD_VALUE;
     }
 
-    if ((mSharedBuffer != 0) && (loopEnd   > cblk->frameCount)) {
+    if ((mSharedBuffer != 0) && (loopEnd > cblk->frameCount)) {
         LOGE("setLoop invalid value: loop markers beyond data: loopStart %d, loopEnd %d, framecount %d",
             loopStart, loopEnd, cblk->frameCount);
         return BAD_VALUE;
@@ -825,6 +826,12 @@
 
     uint32_t framesAvail = cblk->framesAvailable();
 
+    cblk->lock.lock();
+    if (cblk->flags & CBLK_INVALID_MSK) {
+        goto create_new_track;
+    }
+    cblk->lock.unlock();
+
     if (framesAvail == 0) {
         cblk->lock.lock();
         goto start_loop_here;
@@ -893,9 +900,14 @@
 
     // restart track if it was disabled by audioflinger due to previous underrun
     if (mActive && (cblk->flags & CBLK_DISABLED_MSK)) {
-        cblk->flags &= ~CBLK_DISABLED_ON;
-        LOGW("obtainBuffer() track %p disabled, restarting", this);
-        mAudioTrack->start();
+        AutoMutex _l(cblk->lock);
+        if (mActive && (cblk->flags & CBLK_DISABLED_MSK)) {
+            cblk->flags &= ~CBLK_DISABLED_ON;
+            cblk->lock.unlock();
+            LOGW("obtainBuffer() track %p disabled, restarting", this);
+            mAudioTrack->start();
+            cblk->lock.lock();
+        }
     }
 
     cblk->waitTimeMs = 0;
@@ -957,9 +969,10 @@
     ssize_t written = 0;
     const int8_t *src = (const int8_t *)buffer;
     Buffer audioBuffer;
+    size_t frameSz = (size_t)frameSize();
 
     do {
-        audioBuffer.frameCount = userSize/frameSize();
+        audioBuffer.frameCount = userSize/frameSz;
 
         // Calling obtainBuffer() with a negative wait count causes
         // an (almost) infinite wait time.
@@ -991,7 +1004,7 @@
         written += toWrite;
 
         releaseBuffer(&audioBuffer);
-    } while (userSize);
+    } while (userSize >= frameSz);
 
     return written;
 }
@@ -1015,12 +1028,15 @@
     // Manage underrun callback
     if (mActive && (cblk->framesReady() == 0)) {
         LOGV("Underrun user: %x, server: %x, flags %04x", cblk->user, cblk->server, cblk->flags);
+        AutoMutex _l(cblk->lock);
         if ((cblk->flags & CBLK_UNDERRUN_MSK) == CBLK_UNDERRUN_OFF) {
+            cblk->flags |= CBLK_UNDERRUN_ON;
+            cblk->lock.unlock();
             mCbf(EVENT_UNDERRUN, mUserData, 0);
             if (cblk->server == cblk->frameCount) {
                 mCbf(EVENT_BUFFER_END, mUserData, 0);
             }
-            cblk->flags |= CBLK_UNDERRUN_ON;
+            cblk->lock.lock();
             if (mSharedBuffer != 0) return false;
         }
     }
@@ -1139,6 +1155,7 @@
              fromStart ? "start()" : "obtainBuffer()");
 
         cblk->flags |= CBLK_RESTORING_ON;
+
         // signal old cblk condition so that other threads waiting for available buffers stop
         // waiting now
         cblk->cv.broadcast();
@@ -1158,10 +1175,20 @@
                                false);
 
         if (result == NO_ERROR) {
+            // restore write index and set other indexes to reflect empty buffer status
+            mCblk->user = cblk->user;
+            mCblk->server = cblk->user;
+            mCblk->userBase = cblk->user;
+            mCblk->serverBase = cblk->user;
+            // restore loop: this is not guaranteed to succeed if new frame count is not
+            // compatible with loop length
+            setLoop_l(cblk->loopStart, cblk->loopEnd, cblk->loopCount);
             if (!fromStart) {
                 mCblk->bufferTimeoutMs = MAX_RUN_TIMEOUT_MS;
             }
-            result = mAudioTrack->start();
+            if (mActive) {
+                result = mAudioTrack->start();
+            }
             if (fromStart && result == NO_ERROR) {
                 mNewPosition = mCblk->server + mUpdatePeriod;
             }
@@ -1279,7 +1306,12 @@
     this->user = u;
 
     // Clear flow control error condition as new data has been written/read to/from buffer.
-    flags &= ~CBLK_UNDERRUN_MSK;
+    if (flags & CBLK_UNDERRUN_MSK) {
+        AutoMutex _l(lock);
+        if (flags & CBLK_UNDERRUN_MSK) {
+            flags &= ~CBLK_UNDERRUN_MSK;
+        }
+    }
 
     return u;
 }
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index d5298c9..ebe821f 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -20,6 +20,7 @@
 #include <binder/Parcel.h>
 #include <SkBitmap.h>
 #include <media/IMediaMetadataRetriever.h>
+#include <utils/String8.h>
 
 // The binder is supposed to propagate the scheduler group across
 // the binder interface so that remote calls are executed with
@@ -102,11 +103,24 @@
         remote()->transact(DISCONNECT, data, &reply);
     }
 
-    status_t setDataSource(const char* srcUrl)
+    status_t setDataSource(
+            const char *srcUrl, const KeyedVector<String8, String8> *headers)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
         data.writeCString(srcUrl);
+
+        if (headers == NULL) {
+            data.writeInt32(0);
+        } else {
+            // serialize the headers
+            data.writeInt32(headers->size());
+            for (size_t i = 0; i < headers->size(); ++i) {
+                data.writeString8(headers->keyAt(i));
+                data.writeString8(headers->valueAt(i));
+            }
+        }
+
         remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
         return reply.readInt32();
     }
@@ -188,7 +202,18 @@
         case SET_DATA_SOURCE_URL: {
             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
             const char* srcUrl = data.readCString();
-            reply->writeInt32(setDataSource(srcUrl));
+
+            KeyedVector<String8, String8> headers;
+            int32_t numHeaders = data.readInt32();
+            for (int i = 0; i < numHeaders; ++i) {
+                String8 key = data.readString8();
+                String8 value = data.readString8();
+                headers.add(key, value);
+            }
+
+            reply->writeInt32(
+                    setDataSource(srcUrl, numHeaders > 0 ? &headers : NULL));
+
             return NO_ERROR;
         } break;
         case SET_DATA_SOURCE_FD: {
diff --git a/media/libmedia/MemoryLeakTrackUtil.cpp b/media/libmedia/MemoryLeakTrackUtil.cpp
new file mode 100644
index 0000000..6a108ae
--- /dev/null
+++ b/media/libmedia/MemoryLeakTrackUtil.cpp
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2011, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <media/MemoryLeakTrackUtil.h>
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+/*
+ * The code here originally resided in MediaPlayerService.cpp and was
+ * shamelessly copied over to support memory leak tracking from
+ * multiple places.
+ */
+namespace android {
+
+#if defined(__arm__)
+
+extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
+        size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
+
+extern "C" void free_malloc_leak_info(uint8_t* info);
+
+// Use the String-class below instead of String8 to allocate all memory
+// beforehand and not reenter the heap while we are examining it...
+struct MyString8 {
+    static const size_t MAX_SIZE = 256 * 1024;
+
+    MyString8()
+        : mPtr((char *)malloc(MAX_SIZE)) {
+        *mPtr = '\0';
+    }
+
+    ~MyString8() {
+        free(mPtr);
+    }
+
+    void append(const char *s) {
+        strcat(mPtr, s);
+    }
+
+    const char *string() const {
+        return mPtr;
+    }
+
+    size_t size() const {
+        return strlen(mPtr);
+    }
+
+private:
+    char *mPtr;
+
+    MyString8(const MyString8 &);
+    MyString8 &operator=(const MyString8 &);
+};
+
+void dumpMemoryAddresses(int fd)
+{
+    const size_t SIZE = 256;
+    char buffer[SIZE];
+    MyString8 result;
+
+    typedef struct {
+        size_t size;
+        size_t dups;
+        intptr_t * backtrace;
+    } AllocEntry;
+
+    uint8_t *info = NULL;
+    size_t overallSize = 0;
+    size_t infoSize = 0;
+    size_t totalMemory = 0;
+    size_t backtraceSize = 0;
+
+    get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize);
+    if (info) {
+        uint8_t *ptr = info;
+        size_t count = overallSize / infoSize;
+
+        snprintf(buffer, SIZE, " Allocation count %i\n", count);
+        result.append(buffer);
+        snprintf(buffer, SIZE, " Total memory %i\n", totalMemory);
+        result.append(buffer);
+
+        AllocEntry * entries = new AllocEntry[count];
+
+        for (size_t i = 0; i < count; i++) {
+            // Each entry should be size_t, size_t, intptr_t[backtraceSize]
+            AllocEntry *e = &entries[i];
+
+            e->size = *reinterpret_cast<size_t *>(ptr);
+            ptr += sizeof(size_t);
+
+            e->dups = *reinterpret_cast<size_t *>(ptr);
+            ptr += sizeof(size_t);
+
+            e->backtrace = reinterpret_cast<intptr_t *>(ptr);
+            ptr += sizeof(intptr_t) * backtraceSize;
+        }
+
+        // Now we need to sort the entries.  They come sorted by size but
+        // not by stack trace which causes problems using diff.
+        bool moved;
+        do {
+            moved = false;
+            for (size_t i = 0; i < (count - 1); i++) {
+                AllocEntry *e1 = &entries[i];
+                AllocEntry *e2 = &entries[i+1];
+
+                bool swap = e1->size < e2->size;
+                if (e1->size == e2->size) {
+                    for(size_t j = 0; j < backtraceSize; j++) {
+                        if (e1->backtrace[j] == e2->backtrace[j]) {
+                            continue;
+                        }
+                        swap = e1->backtrace[j] < e2->backtrace[j];
+                        break;
+                    }
+                }
+                if (swap) {
+                    AllocEntry t = entries[i];
+                    entries[i] = entries[i+1];
+                    entries[i+1] = t;
+                    moved = true;
+                }
+            }
+        } while (moved);
+
+        for (size_t i = 0; i < count; i++) {
+            AllocEntry *e = &entries[i];
+
+            snprintf(buffer, SIZE, "size %8i, dup %4i, ", e->size, e->dups);
+            result.append(buffer);
+            for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) {
+                if (ct) {
+                    result.append(", ");
+                }
+                snprintf(buffer, SIZE, "0x%08x", e->backtrace[ct]);
+                result.append(buffer);
+            }
+            result.append("\n");
+        }
+
+        delete[] entries;
+        free_malloc_leak_info(info);
+    }
+
+    write(fd, result.string(), result.size());
+}
+
+#else
+// Does nothing
+void dumpMemoryAddresses(int fd) {}
+
+#endif
+}  // namespace android
diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 8dfcb3b..cee06ab 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -92,7 +92,8 @@
     }
 }
 
-status_t MediaMetadataRetriever::setDataSource(const char* srcUrl)
+status_t MediaMetadataRetriever::setDataSource(
+        const char *srcUrl, const KeyedVector<String8, String8> *headers)
 {
     LOGV("setDataSource");
     Mutex::Autolock _l(mLock);
@@ -105,7 +106,7 @@
         return UNKNOWN_ERROR;
     }
     LOGV("data source (%s)", srcUrl);
-    return mRetriever->setDataSource(srcUrl);
+    return mRetriever->setDataSource(srcUrl, headers);
 }
 
 status_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index e65f6d8..fadad28 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -31,8 +31,7 @@
 	libandroid_runtime    			\
 	libstagefright        			\
 	libstagefright_omx    			\
-	libstagefright_foundation               \
-	libsurfaceflinger_client                \
+	libstagefright_foundation       \
 	libgui
 
 LOCAL_STATIC_LIBRARIES := \
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 0156634..5eecbde 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -51,6 +51,7 @@
 #include <media/MediaMetadataRetrieverInterface.h>
 #include <media/Metadata.h>
 #include <media/AudioTrack.h>
+#include <media/MemoryLeakTrackUtil.h>
 
 #include <private/android_filesystem_config.h>
 
@@ -392,139 +393,6 @@
 #endif
 }
 
-#if defined(__arm__)
-extern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize,
-        size_t* infoSize, size_t* totalMemory, size_t* backtraceSize);
-extern "C" void free_malloc_leak_info(uint8_t* info);
-
-// Use the String-class below instead of String8 to allocate all memory
-// beforehand and not reenter the heap while we are examining it...
-struct MyString8 {
-    static const size_t MAX_SIZE = 256 * 1024;
-
-    MyString8()
-        : mPtr((char *)malloc(MAX_SIZE)) {
-        *mPtr = '\0';
-    }
-
-    ~MyString8() {
-        free(mPtr);
-    }
-
-    void append(const char *s) {
-        strcat(mPtr, s);
-    }
-
-    const char *string() const {
-        return mPtr;
-    }
-
-    size_t size() const {
-        return strlen(mPtr);
-    }
-
-private:
-    char *mPtr;
-
-    MyString8(const MyString8 &);
-    MyString8 &operator=(const MyString8 &);
-};
-
-void memStatus(int fd, const Vector<String16>& args)
-{
-    const size_t SIZE = 256;
-    char buffer[SIZE];
-    MyString8 result;
-
-    typedef struct {
-        size_t size;
-        size_t dups;
-        intptr_t * backtrace;
-    } AllocEntry;
-
-    uint8_t *info = NULL;
-    size_t overallSize = 0;
-    size_t infoSize = 0;
-    size_t totalMemory = 0;
-    size_t backtraceSize = 0;
-
-    get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize);
-    if (info) {
-        uint8_t *ptr = info;
-        size_t count = overallSize / infoSize;
-
-        snprintf(buffer, SIZE, " Allocation count %i\n", count);
-        result.append(buffer);
-        snprintf(buffer, SIZE, " Total memory %i\n", totalMemory);
-        result.append(buffer);
-
-        AllocEntry * entries = new AllocEntry[count];
-
-        for (size_t i = 0; i < count; i++) {
-            // Each entry should be size_t, size_t, intptr_t[backtraceSize]
-            AllocEntry *e = &entries[i];
-
-            e->size = *reinterpret_cast<size_t *>(ptr);
-            ptr += sizeof(size_t);
-
-            e->dups = *reinterpret_cast<size_t *>(ptr);
-            ptr += sizeof(size_t);
-
-            e->backtrace = reinterpret_cast<intptr_t *>(ptr);
-            ptr += sizeof(intptr_t) * backtraceSize;
-        }
-
-        // Now we need to sort the entries.  They come sorted by size but
-        // not by stack trace which causes problems using diff.
-        bool moved;
-        do {
-            moved = false;
-            for (size_t i = 0; i < (count - 1); i++) {
-                AllocEntry *e1 = &entries[i];
-                AllocEntry *e2 = &entries[i+1];
-
-                bool swap = e1->size < e2->size;
-                if (e1->size == e2->size) {
-                    for(size_t j = 0; j < backtraceSize; j++) {
-                        if (e1->backtrace[j] == e2->backtrace[j]) {
-                            continue;
-                        }
-                        swap = e1->backtrace[j] < e2->backtrace[j];
-                        break;
-                    }
-                }
-                if (swap) {
-                    AllocEntry t = entries[i];
-                    entries[i] = entries[i+1];
-                    entries[i+1] = t;
-                    moved = true;
-                }
-            }
-        } while (moved);
-
-        for (size_t i = 0; i < count; i++) {
-            AllocEntry *e = &entries[i];
-
-            snprintf(buffer, SIZE, "size %8i, dup %4i, ", e->size, e->dups);
-            result.append(buffer);
-            for (size_t ct = 0; (ct < backtraceSize) && e->backtrace[ct]; ct++) {
-                if (ct) {
-                    result.append(", ");
-                }
-                snprintf(buffer, SIZE, "0x%08x", e->backtrace[ct]);
-                result.append(buffer);
-            }
-            result.append("\n");
-        }
-
-        delete[] entries;
-        free_malloc_leak_info(info);
-    }
-
-    write(fd, result.string(), result.size());
-}
-#endif
-
 status_t MediaPlayerService::dump(int fd, const Vector<String16>& args)
 {
     const size_t SIZE = 256;
@@ -623,7 +491,6 @@
             result.append("\n");
         }
 
-#if defined(__arm__)
         bool dumpMem = false;
         for (size_t i = 0; i < args.size(); i++) {
             if (args[i] == String16("-m")) {
@@ -631,9 +498,8 @@
             }
         }
         if (dumpMem) {
-            memStatus(fd, args);
+            dumpMemoryAddresses(fd);
         }
-#endif
     }
     write(fd, result.string(), result.size());
     return NO_ERROR;
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 5fcf2a7..8f776b4 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -120,7 +120,8 @@
     return p;
 }
 
-status_t MetadataRetrieverClient::setDataSource(const char *url)
+status_t MetadataRetrieverClient::setDataSource(
+        const char *url, const KeyedVector<String8, String8> *headers)
 {
     LOGV("setDataSource(%s)", url);
     Mutex::Autolock lock(mLock);
@@ -131,7 +132,7 @@
     LOGV("player type = %d", playerType);
     sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
     if (p == NULL) return NO_INIT;
-    status_t ret = p->setDataSource(url);
+    status_t ret = p->setDataSource(url, headers);
     if (ret == NO_ERROR) mRetriever = p;
     return ret;
 }
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h
index b834715..f08f933 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.h
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.h
@@ -41,7 +41,10 @@
     // Implements IMediaMetadataRetriever interface
     // These methods are called in IMediaMetadataRetriever.cpp?
     virtual void                    disconnect();
-    virtual status_t                setDataSource(const char *url);
+
+    virtual status_t                setDataSource(
+            const char *url, const KeyedVector<String8, String8> *headers);
+
     virtual status_t                setDataSource(int fd, int64_t offset, int64_t length);
     virtual sp<IMemory>             getFrameAtTime(int64_t timeUs, int option);
     virtual sp<IMemory>             extractAlbumArt();
diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.cpp b/media/libmediaplayerservice/MidiMetadataRetriever.cpp
index ad95fac..aaf2d18 100644
--- a/media/libmediaplayerservice/MidiMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/MidiMetadataRetriever.cpp
@@ -35,7 +35,8 @@
     mMetadataValues[0][0] = '\0';
 }
 
-status_t MidiMetadataRetriever::setDataSource(const char *url)
+status_t MidiMetadataRetriever::setDataSource(
+        const char *url, const KeyedVector<String8, String8> *headers)
 {
     LOGV("setDataSource: %s", url? url: "NULL pointer");
     Mutex::Autolock lock(mLock);
@@ -43,8 +44,7 @@
     if (mMidiPlayer == 0) {
         mMidiPlayer = new MidiFile();
     }
-    // TODO: support headers in MetadataRetriever interface!
-    return mMidiPlayer->setDataSource(url, NULL /* headers */);
+    return mMidiPlayer->setDataSource(url, headers);
 }
 
 status_t MidiMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.h b/media/libmediaplayerservice/MidiMetadataRetriever.h
index 73ff347..4cee42d 100644
--- a/media/libmediaplayerservice/MidiMetadataRetriever.h
+++ b/media/libmediaplayerservice/MidiMetadataRetriever.h
@@ -31,7 +31,9 @@
                                    MidiMetadataRetriever() {}
                                    ~MidiMetadataRetriever() {}
 
-    virtual status_t                setDataSource(const char *url);
+    virtual status_t                setDataSource(
+            const char *url, const KeyedVector<String8, String8> *headers);
+
     virtual status_t                setDataSource(int fd, int64_t offset, int64_t length);
     virtual const char*             extractMetadata(int keyCode);
 
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 369a3a8..828e008 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -198,18 +198,21 @@
 }
 
 void NuPlayer::Renderer::onDrainAudioQueue() {
-    uint32_t numFramesPlayed;
-    CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
 
-    ssize_t numFramesAvailableToWrite =
-        mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
+    for (;;) {
+        uint32_t numFramesPlayed;
+        CHECK_EQ(mAudioSink->getPosition(&numFramesPlayed), (status_t)OK);
 
-    CHECK_GE(numFramesAvailableToWrite, 0);
+        ssize_t numFramesAvailableToWrite =
+            mAudioSink->frameCount() - (mNumFramesWritten - numFramesPlayed);
 
-    size_t numBytesAvailableToWrite =
-        numFramesAvailableToWrite * mAudioSink->frameSize();
+        size_t numBytesAvailableToWrite =
+            numFramesAvailableToWrite * mAudioSink->frameSize();
 
-    while (numBytesAvailableToWrite > 0) {
+        if (numBytesAvailableToWrite == 0) {
+            break;
+        }
+
         if (mAudioQueue.empty()) {
             break;
         }
@@ -264,10 +267,10 @@
         if (entry->mOffset == entry->mBuffer->size()) {
             entry->mNotifyConsumed->post();
             mAudioQueue.erase(mAudioQueue.begin());
+
             entry = NULL;
         }
 
-        numBytesAvailableToWrite -= copy;
         mNumFramesWritten += copy / mAudioSink->frameSize();
     }
 
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index 0db3d1d..b10d52c 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -37,7 +37,7 @@
       mPaused(false),
       mResumed(false) {
 
-    mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC);
+    mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR);
     if (mFd >= 0) {
         mInitCheck = OK;
     }
@@ -269,7 +269,7 @@
     }
 
     if (stoppedPrematurely) {
-        notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_INFO_COMPLETION_STATUS, UNKNOWN_ERROR);
+        notify(MEDIA_RECORDER_EVENT_INFO, MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS, UNKNOWN_ERROR);
     }
 
     close(mFd);
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 88069e9..d2e8b46 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -19,6 +19,7 @@
         ESDS.cpp                          \
         FileSource.cpp                    \
         FLACExtractor.cpp                 \
+        HTTPBase.cpp                      \
         HTTPStream.cpp                    \
         JPEGSource.cpp                    \
         MP3Extractor.cpp                  \
@@ -69,13 +70,12 @@
         libui             \
         libsonivox        \
         libvorbisidec     \
-        libsurfaceflinger_client \
         libstagefright_yuv \
         libcamera_client \
         libdrmframework  \
         libcrypto        \
         libssl           \
-        libgui
+        libgui           \
 
 LOCAL_STATIC_LIBRARIES := \
         libstagefright_color_conversion \
@@ -101,6 +101,60 @@
         libstagefright_g711dec \
         libFLAC \
 
+################################################################################
+
+# The following was shamelessly copied from external/webkit/Android.mk and
+# currently must follow the same logic to determine how webkit was built and
+# if it's safe to link against libchromium.net
+
+# V8 also requires an ARMv7 CPU, and since we must use jsc, we cannot
+# use the Chrome http stack either.
+ifneq ($(strip $(ARCH_ARM_HAVE_ARMV7A)),true)
+  USE_ALT_HTTP := true
+endif
+
+# See if the user has specified a stack they want to use
+HTTP_STACK = $(HTTP)
+# We default to the Chrome HTTP stack.
+DEFAULT_HTTP = chrome
+ALT_HTTP = android
+
+ifneq ($(HTTP_STACK),chrome)
+  ifneq ($(HTTP_STACK),android)
+    # No HTTP stack is specified, pickup the one we want as default.
+    ifeq ($(USE_ALT_HTTP),true)
+      HTTP_STACK = $(ALT_HTTP)
+    else
+      HTTP_STACK = $(DEFAULT_HTTP)
+    endif
+  endif
+endif
+
+ifeq ($(HTTP_STACK),chrome)
+
+LOCAL_SHARED_LIBRARIES += \
+        liblog           \
+        libicuuc         \
+        libicui18n       \
+        libz             \
+        libdl            \
+
+LOCAL_STATIC_LIBRARIES += \
+        libstagefright_chromium_http \
+        libchromium_net         \
+        libwebcore              \
+
+ifneq ($(TARGET_SIMULATOR),true)
+LOCAL_SHARED_LIBRARIES += libstlport
+include external/stlport/libstlport.mk
+endif
+
+LOCAL_CPPFLAGS += -DCHROMIUM_AVAILABLE=1
+
+endif  # ifeq ($(HTTP_STACK),chrome)
+
+################################################################################
+
 LOCAL_SHARED_LIBRARIES += \
         libstagefright_amrnb_common \
         libstagefright_enc_common \
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index bd04a26..162d2e6 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -280,6 +280,26 @@
     buffer->size = numBytesWritten;
 }
 
+uint32_t AudioPlayer::getNumFramesPendingPlayout() const {
+    uint32_t numFramesPlayedOut;
+    status_t err;
+
+    if (mAudioSink != NULL) {
+        err = mAudioSink->getPosition(&numFramesPlayedOut);
+    } else {
+        err = mAudioTrack->getPosition(&numFramesPlayedOut);
+    }
+
+    if (err != OK || mNumFramesPlayed < numFramesPlayedOut) {
+        return 0;
+    }
+
+    // mNumFramesPlayed is the number of frames submitted
+    // to the audio sink for playback, but not all of them
+    // may have played out by now.
+    return mNumFramesPlayed - numFramesPlayedOut;
+}
+
 size_t AudioPlayer::fillBuffer(void *data, size_t size) {
     if (mNumFramesPlayed == 0) {
         LOGV("AudioCallback");
@@ -342,7 +362,34 @@
 
             if (err != OK) {
                 if (mObserver && !mReachedEOS) {
-                    mObserver->postAudioEOS();
+                    // We don't want to post EOS right away but only
+                    // after all frames have actually been played out.
+
+                    // These are the number of frames submitted to the
+                    // AudioTrack that you haven't heard yet.
+                    uint32_t numFramesPendingPlayout =
+                        getNumFramesPendingPlayout();
+
+                    // These are the number of frames we're going to
+                    // submit to the AudioTrack by returning from this
+                    // callback.
+                    uint32_t numAdditionalFrames = size_done / mFrameSize;
+
+                    numFramesPendingPlayout += numAdditionalFrames;
+
+                    int64_t timeToCompletionUs =
+                        (1000000ll * numFramesPendingPlayout) / mSampleRate;
+
+                    LOGV("total number of frames played: %lld (%lld us)",
+                            (mNumFramesPlayed + numAdditionalFrames),
+                            1000000ll * (mNumFramesPlayed + numAdditionalFrames)
+                                / mSampleRate);
+
+                    LOGV("%d frames left to play, %lld us (%.2f secs)",
+                         numFramesPendingPlayout,
+                         timeToCompletionUs, timeToCompletionUs / 1E6);
+
+                    mObserver->postAudioEOS(timeToCompletionUs + mLatencyUs);
                 }
 
                 mReachedEOS = true;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 37a93a4..7940de0 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -308,7 +308,7 @@
         return UNKNOWN_ERROR;
     }
 
-    dataSource->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
+    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
     if (mDecryptHandle != NULL) {
         CHECK(mDrmManagerClient);
         if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
@@ -880,6 +880,17 @@
              cropLeft, cropTop, cropRight, cropBottom);
     }
 
+    int32_t displayWidth;
+    if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
+        LOGV("Display width changed (%d=>%d)", mDisplayWidth, displayWidth);
+        mDisplayWidth = displayWidth;
+    }
+    int32_t displayHeight;
+    if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
+        LOGV("Display height changed (%d=>%d)", mDisplayHeight, displayHeight);
+        mDisplayHeight = displayHeight;
+    }
+
     int32_t usableWidth = cropRight - cropLeft + 1;
     int32_t usableHeight = cropBottom - cropTop + 1;
     if (mDisplayWidth != 0) {
@@ -1132,7 +1143,6 @@
 
         mWatchForAudioSeekComplete = true;
         mWatchForAudioEOS = true;
-        mSeekNotificationSent = false;
 
         if (mDecryptHandle != NULL) {
             mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
@@ -1291,11 +1301,11 @@
         // If we're playing video only, report seek complete now,
         // otherwise audio player will notify us later.
         notifyListener_l(MEDIA_SEEK_COMPLETE);
+        mSeekNotificationSent = true;
     }
 
     mFlags |= FIRST_FRAME;
     mSeeking = NO_SEEK;
-    mSeekNotificationSent = false;
 
     if (mDecryptHandle != NULL) {
         mDrmManagerClient->setPlaybackStatus(mDecryptHandle,
@@ -1555,12 +1565,12 @@
     mQueue.postEventWithDelay(mVideoLagEvent, 1000000ll);
 }
 
-void AwesomePlayer::postCheckAudioStatusEvent_l() {
+void AwesomePlayer::postCheckAudioStatusEvent_l(int64_t delayUs) {
     if (mAudioStatusEventPending) {
         return;
     }
     mAudioStatusEventPending = true;
-    mQueue.postEvent(mCheckAudioStatusEvent);
+    mQueue.postEventWithDelay(mCheckAudioStatusEvent, delayUs);
 }
 
 void AwesomePlayer::onCheckAudioStatus() {
@@ -1656,8 +1666,10 @@
 
     if (!strncasecmp("http://", mUri.string(), 7)
             || !strncasecmp("https://", mUri.string(), 8)) {
-        mConnectingDataSource = new NuHTTPDataSource(
-                (mFlags & INCOGNITO) ? NuHTTPDataSource::kFlagIncognito : 0);
+        mConnectingDataSource = HTTPBase::Create(
+                (mFlags & INCOGNITO)
+                    ? HTTPBase::kFlagIncognito
+                    : 0);
 
         mLock.unlock();
         status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
@@ -1746,7 +1758,8 @@
         return UNKNOWN_ERROR;
     }
 
-    dataSource->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
+    dataSource->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
+
     if (mDecryptHandle != NULL) {
         CHECK(mDrmManagerClient);
         if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
@@ -1844,12 +1857,12 @@
     return mExtractorFlags;
 }
 
-void AwesomePlayer::postAudioEOS() {
-    postCheckAudioStatusEvent_l();
+void AwesomePlayer::postAudioEOS(int64_t delayUs) {
+    postCheckAudioStatusEvent_l(delayUs);
 }
 
 void AwesomePlayer::postAudioSeekComplete() {
-    postCheckAudioStatusEvent_l();
+    postCheckAudioStatusEvent_l(0 /* delayUs */);
 }
 
 }  // namespace android
diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp
index 2809df5..c4ed516 100644
--- a/media/libstagefright/DRMExtractor.cpp
+++ b/media/libstagefright/DRMExtractor.cpp
@@ -41,7 +41,7 @@
 class DRMSource : public MediaSource {
 public:
     DRMSource(const sp<MediaSource> &mediaSource,
-            DecryptHandle *decryptHandle,
+            const sp<DecryptHandle> &decryptHandle,
             DrmManagerClient *managerClient,
             int32_t trackId, DrmBuffer *ipmpBox);
 
@@ -56,7 +56,7 @@
 
 private:
     sp<MediaSource> mOriginalMediaSource;
-    DecryptHandle* mDecryptHandle;
+    sp<DecryptHandle> mDecryptHandle;
     DrmManagerClient* mDrmManagerClient;
     size_t mTrackId;
     mutable Mutex mDRMLock;
@@ -70,7 +70,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 DRMSource::DRMSource(const sp<MediaSource> &mediaSource,
-        DecryptHandle *decryptHandle,
+        const sp<DecryptHandle> &decryptHandle,
         DrmManagerClient *managerClient,
         int32_t trackId, DrmBuffer *ipmpBox)
     : mOriginalMediaSource(mediaSource),
@@ -245,7 +245,7 @@
     mOriginalExtractor->setDrmFlag(true);
     mOriginalExtractor->getMetaData()->setInt32(kKeyIsDRM, 1);
 
-    source->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
+    source->getDrmInfo(mDecryptHandle, &mDrmManagerClient);
 }
 
 DRMExtractor::~DRMExtractor() {
@@ -281,7 +281,7 @@
 bool SniffDRM(
     const sp<DataSource> &source, String8 *mimeType, float *confidence,
         sp<AMessage> *) {
-    DecryptHandle *decryptHandle = source->DrmInitialization();
+    sp<DecryptHandle> decryptHandle = source->DrmInitialization();
 
     if (decryptHandle != NULL) {
         if (decryptHandle->decryptApiType == DecryptApiType::CONTAINER_BASED) {
diff --git a/media/libstagefright/DataSource.cpp b/media/libstagefright/DataSource.cpp
index 3b38208..b5c51f4 100644
--- a/media/libstagefright/DataSource.cpp
+++ b/media/libstagefright/DataSource.cpp
@@ -21,7 +21,7 @@
 #include "include/OggExtractor.h"
 #include "include/MPEG2TSExtractor.h"
 #include "include/NuCachedSource2.h"
-#include "include/NuHTTPDataSource.h"
+#include "include/HTTPBase.h"
 #include "include/DRMExtractor.h"
 #include "include/FLACExtractor.h"
 #include "include/AACExtractor.h"
@@ -127,7 +127,7 @@
         source = new FileSource(uri + 7);
     } else if (!strncasecmp("http://", uri, 7)
             || !strncasecmp("https://", uri, 8)) {
-        sp<NuHTTPDataSource> httpSource = new NuHTTPDataSource;
+        sp<HTTPBase> httpSource = HTTPBase::Create();
         if (httpSource->connect(uri, headers) != OK) {
             return NULL;
         }
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index 02a78c9..f2f3500 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -125,7 +125,7 @@
     return OK;
 }
 
-DecryptHandle* FileSource::DrmInitialization() {
+sp<DecryptHandle> FileSource::DrmInitialization() {
     if (mDrmManagerClient == NULL) {
         mDrmManagerClient = new DrmManagerClient();
     }
@@ -147,8 +147,8 @@
     return mDecryptHandle;
 }
 
-void FileSource::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
-    *handle = mDecryptHandle;
+void FileSource::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {
+    handle = mDecryptHandle;
 
     *client = mDrmManagerClient;
 }
diff --git a/media/libstagefright/HTTPBase.cpp b/media/libstagefright/HTTPBase.cpp
new file mode 100644
index 0000000..58b17a7
--- /dev/null
+++ b/media/libstagefright/HTTPBase.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "include/HTTPBase.h"
+
+#if CHROMIUM_AVAILABLE
+#include "include/ChromiumHTTPDataSource.h"
+#endif
+
+#include "include/NuHTTPDataSource.h"
+
+#include <cutils/properties.h>
+
+namespace android {
+
+HTTPBase::HTTPBase() {}
+
+// static
+sp<HTTPBase> HTTPBase::Create(uint32_t flags) {
+#if CHROMIUM_AVAILABLE
+    char value[PROPERTY_VALUE_MAX];
+    if (!property_get("media.stagefright.use-chromium", value, NULL)
+            || (strcasecmp("false", value) && strcmp("0", value))) {
+        return new ChromiumHTTPDataSource(flags);
+    } else
+#endif
+    {
+        return new NuHTTPDataSource(flags);
+    }
+}
+
+}  // namespace android
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 7b96d01..1ca2d6d 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -262,7 +262,7 @@
 
 MPEG4Extractor::MPEG4Extractor(const sp<DataSource> &source)
     : mDataSource(source),
-      mHaveMetadata(false),
+      mInitCheck(NO_INIT),
       mHasVideo(false),
       mFirstTrack(NULL),
       mLastTrack(NULL),
@@ -361,8 +361,8 @@
 }
 
 status_t MPEG4Extractor::readMetaData() {
-    if (mHaveMetadata) {
-        return OK;
+    if (mInitCheck != NO_INIT) {
+        return mInitCheck;
     }
 
     off64_t offset = 0;
@@ -370,17 +370,20 @@
     while ((err = parseChunk(&offset, 0)) == OK) {
     }
 
-    if (mHaveMetadata) {
+    if (mInitCheck == OK) {
         if (mHasVideo) {
             mFileMetaData->setCString(kKeyMIMEType, "video/mp4");
         } else {
             mFileMetaData->setCString(kKeyMIMEType, "audio/mp4");
         }
 
-        return OK;
+        mInitCheck = verifyIfStreamable();
+    } else {
+        mInitCheck = err;
     }
 
-    return err;
+    CHECK_NE(err, (status_t)NO_INIT);
+    return mInitCheck;
 }
 
 void MPEG4Extractor::setDrmFlag(bool flag) {
@@ -755,7 +758,7 @@
                     return err;
                 }
             } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
-                mHaveMetadata = true;
+                mInitCheck = OK;
 
                 if (!mIsDrm) {
                     return UNKNOWN_ERROR;  // Return a dummy error.
@@ -2077,6 +2080,101 @@
     }
 }
 
+MPEG4Extractor::Track *MPEG4Extractor::findTrackByMimePrefix(
+        const char *mimePrefix) {
+    for (Track *track = mFirstTrack; track != NULL; track = track->next) {
+        const char *mime;
+        if (track->meta != NULL
+                && track->meta->findCString(kKeyMIMEType, &mime)
+                && !strncasecmp(mime, mimePrefix, strlen(mimePrefix))) {
+            return track;
+        }
+    }
+
+    return NULL;
+}
+
+status_t MPEG4Extractor::verifyIfStreamable() {
+    if (!(mDataSource->flags() & DataSource::kIsCachingDataSource)) {
+        return OK;
+    }
+
+    Track *audio = findTrackByMimePrefix("audio/");
+    Track *video = findTrackByMimePrefix("video/");
+
+    if (audio == NULL || video == NULL) {
+        return OK;
+    }
+
+    sp<SampleTable> audioSamples = audio->sampleTable;
+    sp<SampleTable> videoSamples = video->sampleTable;
+
+    off64_t maxOffsetDiff = 0;
+    int64_t maxOffsetTimeUs = -1;
+
+    for (uint32_t i = 0; i < videoSamples->countSamples(); ++i) {
+        off64_t videoOffset;
+        uint32_t videoTime;
+        bool isSync;
+        CHECK_EQ((status_t)OK, videoSamples->getMetaDataForSample(
+                    i, &videoOffset, NULL, &videoTime, &isSync));
+
+        int64_t videoTimeUs = (int64_t)(videoTime * 1E6 / video->timescale);
+
+        uint32_t reqAudioTime = (videoTimeUs * audio->timescale) / 1000000;
+        uint32_t j;
+        if (audioSamples->findSampleAtTime(
+            reqAudioTime, &j, SampleTable::kFlagClosest) != OK) {
+            continue;
+        }
+
+        off64_t audioOffset;
+        uint32_t audioTime;
+        CHECK_EQ((status_t)OK, audioSamples->getMetaDataForSample(
+                    j, &audioOffset, NULL, &audioTime));
+
+        int64_t audioTimeUs = (int64_t)(audioTime * 1E6 / audio->timescale);
+
+        off64_t offsetDiff = videoOffset - audioOffset;
+        if (offsetDiff < 0) {
+            offsetDiff = -offsetDiff;
+        }
+
+#if 0
+        printf("%s%d/%d videoTime %.2f secs audioTime %.2f secs "
+               "videoOffset %lld audioOffset %lld offsetDiff %lld\n",
+               isSync ? "*" : " ",
+               i,
+               j,
+               videoTimeUs / 1E6,
+               audioTimeUs / 1E6,
+               videoOffset,
+               audioOffset,
+               offsetDiff);
+#endif
+
+        if (offsetDiff > maxOffsetDiff) {
+            maxOffsetDiff = offsetDiff;
+            maxOffsetTimeUs = videoTimeUs;
+        }
+    }
+
+#if 0
+    printf("max offset diff: %lld at video time: %.2f secs\n",
+           maxOffsetDiff, maxOffsetTimeUs / 1E6);
+#endif
+
+    if (maxOffsetDiff < 1024 * 1024) {
+        return OK;
+    }
+
+    LOGE("This content is not streamable, "
+         "max offset diff: %lld at video time: %.2f secs",
+         maxOffsetDiff, maxOffsetTimeUs / 1E6);
+
+    return ERROR_UNSUPPORTED;
+}
+
 static bool LegacySniffMPEG4(
         const sp<DataSource> &source, String8 *mimeType, float *confidence) {
     uint8_t header[8];
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 5d6ea7c..e13b67e 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -52,7 +52,7 @@
 
 class MPEG4Writer::Track {
 public:
-    Track(MPEG4Writer *owner, const sp<MediaSource> &source);
+    Track(MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId);
 
     ~Track();
 
@@ -82,6 +82,7 @@
     bool mIsAvc;
     bool mIsAudio;
     bool mIsMPEG4;
+    int32_t mTrackId;
     int64_t mTrackDurationUs;
 
     // For realtime applications, we need to adjust the media clock
@@ -231,7 +232,7 @@
       mEstimatedMoovBoxSize(0),
       mInterleaveDurationUs(1000000) {
 
-    mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC);
+    mFd = open(filename, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR);
     if (mFd >= 0) {
         mInitCheck = OK;
     }
@@ -295,7 +296,12 @@
 }
 
 status_t MPEG4Writer::addSource(const sp<MediaSource> &source) {
-    Track *track = new Track(this, source);
+    Mutex::Autolock l(mLock);
+    if (mStarted) {
+        LOGE("Attempt to add source AFTER recording is started");
+        return UNKNOWN_ERROR;
+    }
+    Track *track = new Track(this, source, mTracks.size());
     mTracks.push_back(track);
 
     return OK;
@@ -945,7 +951,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 MPEG4Writer::Track::Track(
-        MPEG4Writer *owner, const sp<MediaSource> &source)
+        MPEG4Writer *owner, const sp<MediaSource> &source, size_t trackId)
     : mOwner(owner),
       mMeta(source->getFormat()),
       mSource(source),
@@ -953,6 +959,7 @@
       mPaused(false),
       mResumed(false),
       mStarted(false),
+      mTrackId(trackId),
       mTrackDurationUs(0),
       mEstimatedTrackSizeBytes(0),
       mSamplesHaveSameSize(true),
@@ -2030,7 +2037,7 @@
         (OK != checkCodecSpecificData())) {          // no codec specific data
         err = ERROR_MALFORMED;
     }
-    mOwner->trackProgressStatus(this, -1, err);
+    mOwner->trackProgressStatus(mTrackId, -1, err);
 
     // Last chunk
     if (mOwner->numTracks() == 1) {
@@ -2077,41 +2084,34 @@
     if (mTrackEveryTimeDurationUs > 0 &&
         timeUs - mPreviousTrackTimeUs >= mTrackEveryTimeDurationUs) {
         LOGV("Fire time tracking progress status at %lld us", timeUs);
-        mOwner->trackProgressStatus(this, timeUs - mPreviousTrackTimeUs, err);
+        mOwner->trackProgressStatus(mTrackId, timeUs - mPreviousTrackTimeUs, err);
         mPreviousTrackTimeUs = timeUs;
     }
 }
 
 void MPEG4Writer::trackProgressStatus(
-        const MPEG4Writer::Track* track, int64_t timeUs, status_t err) {
+        size_t trackId, int64_t timeUs, status_t err) {
     Mutex::Autolock lock(mLock);
-    int32_t nTracks = mTracks.size();
-    CHECK(nTracks >= 1);
-    CHECK(nTracks < 64);  // Arbitrary number
-
-    int32_t trackNum = 0;
-    CHECK(trackNum < nTracks);
-    trackNum <<= 16;
+    int32_t trackNum = (trackId << 28);
 
     // Error notification
     // Do not consider ERROR_END_OF_STREAM an error
     if (err != OK && err != ERROR_END_OF_STREAM) {
-        notify(MEDIA_RECORDER_EVENT_ERROR,
-               trackNum | MEDIA_RECORDER_ERROR_UNKNOWN,
+        notify(MEDIA_RECORDER_TRACK_EVENT_ERROR,
+               trackNum | MEDIA_RECORDER_TRACK_ERROR_GENERAL,
                err);
         return;
     }
 
     if (timeUs == -1) {
         // Send completion notification
-        notify(MEDIA_RECORDER_EVENT_INFO,
-               trackNum | MEDIA_RECORDER_INFO_COMPLETION_STATUS,
+        notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+               trackNum | MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS,
                err);
-        return;
     } else {
         // Send progress status
-        notify(MEDIA_RECORDER_EVENT_INFO,
-               trackNum | MEDIA_RECORDER_INFO_PROGRESS_TIME_STATUS,
+        notify(MEDIA_RECORDER_TRACK_EVENT_INFO,
+               trackNum | MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME,
                timeUs / 1000);
     }
 }
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 248b678..3c99d1c 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -481,11 +481,11 @@
     restartPrefetcherIfNecessary_l(true /* ignore low water threshold */);
 }
 
-DecryptHandle* NuCachedSource2::DrmInitialization() {
+sp<DecryptHandle> NuCachedSource2::DrmInitialization() {
     return mSource->DrmInitialization();
 }
 
-void NuCachedSource2::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
+void NuCachedSource2::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {
     mSource->getDrmInfo(handle, client);
 }
 
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
index b24343f..73daf12 100644
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ b/media/libstagefright/NuHTTPDataSource.cpp
@@ -530,7 +530,7 @@
     }
 }
 
-DecryptHandle* NuHTTPDataSource::DrmInitialization() {
+sp<DecryptHandle> NuHTTPDataSource::DrmInitialization() {
     if (mDrmManagerClient == NULL) {
         mDrmManagerClient = new DrmManagerClient();
     }
@@ -554,8 +554,8 @@
     return mDecryptHandle;
 }
 
-void NuHTTPDataSource::getDrmInfo(DecryptHandle **handle, DrmManagerClient **client) {
-    *handle = mDecryptHandle;
+void NuHTTPDataSource::getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client) {
+    handle = mDecryptHandle;
 
     *client = mDrmManagerClient;
 }
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 3e26a95..a6a34b3 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -2215,13 +2215,15 @@
 
             if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
                 onPortSettingsChanged(data1);
-            } else if (data1 == kPortIndexOutput
-                    && data2 == OMX_IndexConfigCommonOutputCrop) {
+            } else if (data1 == kPortIndexOutput &&
+                        (data2 == OMX_IndexConfigCommonOutputCrop ||
+                         data2 == OMX_IndexConfigCommonScale)) {
 
                 sp<MetaData> oldOutputFormat = mOutputFormat;
                 initOutputFormat(mSource->getFormat());
 
-                if (formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) {
+                if (data2 == OMX_IndexConfigCommonOutputCrop &&
+                    formatHasNotablyChanged(oldOutputFormat, mOutputFormat)) {
                     mOutputPortSettingsHaveChanged = true;
 
                     if (mNativeWindow != NULL) {
@@ -2240,6 +2242,39 @@
                         // already invalid, we'll know soon enough.
                         native_window_set_crop(mNativeWindow.get(), &crop);
                     }
+                } else if (data2 == OMX_IndexConfigCommonScale) {
+                    OMX_CONFIG_SCALEFACTORTYPE scale;
+                    InitOMXParams(&scale);
+                    scale.nPortIndex = kPortIndexOutput;
+
+                    // Change display dimension only when necessary.
+                    if (OK == mOMX->getConfig(
+                                        mNode,
+                                        OMX_IndexConfigCommonScale,
+                                        &scale, sizeof(scale))) {
+                        int32_t left, top, right, bottom;
+                        CHECK(mOutputFormat->findRect(kKeyCropRect,
+                                                      &left, &top,
+                                                      &right, &bottom));
+
+                        // The scale is in 16.16 format.
+                        // scale 1.0 = 0x010000. When there is no
+                        // need to change the display, skip it.
+                        LOGV("Get OMX_IndexConfigScale: 0x%lx/0x%lx",
+                                scale.xWidth, scale.xHeight);
+
+                        if (scale.xWidth != 0x010000) {
+                            mOutputFormat->setInt32(kKeyDisplayWidth,
+                                    ((right - left +  1) * scale.xWidth)  >> 16);
+                            mOutputPortSettingsHaveChanged = true;
+                        }
+
+                        if (scale.xHeight != 0x010000) {
+                            mOutputFormat->setInt32(kKeyDisplayHeight,
+                                    ((bottom  - top + 1) * scale.xHeight) >> 16);
+                            mOutputPortSettingsHaveChanged = true;
+                        }
+                    }
                 }
             }
             break;
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index ea3b801..4095fbf 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -48,7 +48,8 @@
     mClient.disconnect();
 }
 
-status_t StagefrightMetadataRetriever::setDataSource(const char *uri) {
+status_t StagefrightMetadataRetriever::setDataSource(
+        const char *uri, const KeyedVector<String8, String8> *headers) {
     LOGV("setDataSource(%s)", uri);
 
     mParsedMetaData = false;
@@ -56,7 +57,7 @@
     delete mAlbumArt;
     mAlbumArt = NULL;
 
-    mSource = DataSource::CreateFromURI(uri);
+    mSource = DataSource::CreateFromURI(uri, headers);
 
     if (mSource == NULL) {
         return UNKNOWN_ERROR;
@@ -231,6 +232,14 @@
     frame->mData = new uint8_t[frame->mSize];
     frame->mRotationAngle = rotationAngle;
 
+    int32_t displayWidth, displayHeight;
+    if (meta->findInt32(kKeyDisplayWidth, &displayWidth)) {
+        frame->mDisplayWidth = displayWidth;
+    }
+    if (meta->findInt32(kKeyDisplayHeight, &displayHeight)) {
+        frame->mDisplayHeight = displayHeight;
+    }
+
     int32_t srcFormat;
     CHECK(meta->findInt32(kKeyColorFormat, &srcFormat));
 
@@ -411,6 +420,12 @@
 
     mMetaData.add(METADATA_KEY_NUM_TRACKS, String8(tmp));
 
+    bool hasAudio = false;
+    bool hasVideo = false;
+    int32_t videoWidth = -1;
+    int32_t videoHeight = -1;
+    int32_t audioBitrate = -1;
+
     // The overall duration is the duration of the longest track.
     int64_t maxDurationUs = 0;
     for (size_t i = 0; i < numTracks; ++i) {
@@ -422,12 +437,55 @@
                 maxDurationUs = durationUs;
             }
         }
+
+        const char *mime;
+        if (trackMeta->findCString(kKeyMIMEType, &mime)) {
+            if (!hasAudio && !strncasecmp("audio/", mime, 6)) {
+                hasAudio = true;
+
+                if (!trackMeta->findInt32(kKeyBitRate, &audioBitrate)) {
+                    audioBitrate = -1;
+                }
+            } else if (!hasVideo && !strncasecmp("video/", mime, 6)) {
+                hasVideo = true;
+
+                CHECK(trackMeta->findInt32(kKeyWidth, &videoWidth));
+                CHECK(trackMeta->findInt32(kKeyHeight, &videoHeight));
+            }
+        }
     }
 
     // The duration value is a string representing the duration in ms.
     sprintf(tmp, "%lld", (maxDurationUs + 500) / 1000);
     mMetaData.add(METADATA_KEY_DURATION, String8(tmp));
 
+    if (hasAudio) {
+        mMetaData.add(METADATA_KEY_HAS_AUDIO, String8("yes"));
+    }
+
+    if (hasVideo) {
+        mMetaData.add(METADATA_KEY_HAS_VIDEO, String8("yes"));
+
+        sprintf(tmp, "%d", videoWidth);
+        mMetaData.add(METADATA_KEY_VIDEO_WIDTH, String8(tmp));
+
+        sprintf(tmp, "%d", videoHeight);
+        mMetaData.add(METADATA_KEY_VIDEO_HEIGHT, String8(tmp));
+    }
+
+    if (numTracks == 1 && hasAudio && audioBitrate >= 0) {
+        sprintf(tmp, "%d", audioBitrate);
+        mMetaData.add(METADATA_KEY_BITRATE, String8(tmp));
+    } else {
+        off64_t sourceSize;
+        if (mSource->getSize(&sourceSize) == OK) {
+            int64_t avgBitRate = (int64_t)(sourceSize * 8E6 / maxDurationUs);
+
+            sprintf(tmp, "%lld", avgBitRate);
+            mMetaData.add(METADATA_KEY_BITRATE, String8(tmp));
+        }
+    }
+
     if (numTracks == 1) {
         const char *fileMIME;
         CHECK(meta->findCString(kKeyMIMEType, &fileMIME));
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index 9332120..e9e5ef9 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -353,8 +353,6 @@
         return ERROR_END_OF_STREAM;
     }
 
-    mCurrentPos += n;
-
     buffer->set_range(0, n);
 
     if (mWaveFormat == WAVE_FORMAT_PCM) {
@@ -406,6 +404,7 @@
                 / (mNumChannels * bytesPerSample) / mSampleRate);
 
     buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
+    mCurrentPos += n;
 
     *out = buffer;
 
diff --git a/media/libstagefright/chromium_http/Android.mk b/media/libstagefright/chromium_http/Android.mk
new file mode 100644
index 0000000..80b2478
--- /dev/null
+++ b/media/libstagefright/chromium_http/Android.mk
@@ -0,0 +1,25 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:=       \
+        ChromiumHTTPDataSource.cpp        \
+        support.cpp                     \
+
+LOCAL_C_INCLUDES:= \
+        $(JNI_H_INCLUDE) \
+        frameworks/base/media/libstagefright \
+        $(TOP)/frameworks/base/include/media/stagefright/openmax \
+        external/chromium \
+        external/chromium/android
+
+LOCAL_CFLAGS += -Wno-multichar
+
+ifneq ($(TARGET_SIMULATOR),true)
+LOCAL_SHARED_LIBRARIES += libstlport
+include external/stlport/libstlport.mk
+endif
+
+LOCAL_MODULE:= libstagefright_chromium_http
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
new file mode 100644
index 0000000..949a5e4
--- /dev/null
+++ b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ChromiumHTTPDataSource"
+#include <media/stagefright/foundation/ADebug.h>
+
+#include "include/ChromiumHTTPDataSource.h"
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/MediaErrors.h>
+
+#include "support.h"
+
+namespace android {
+
+ChromiumHTTPDataSource::ChromiumHTTPDataSource(uint32_t flags)
+    : mFlags(flags),
+      mState(DISCONNECTED),
+      mDelegate(new SfDelegate),
+      mCurrentOffset(0),
+      mIOResult(OK),
+      mContentSize(-1),
+      mNumBandwidthHistoryItems(0),
+      mTotalTransferTimeUs(0),
+      mTotalTransferBytes(0),
+      mDecryptHandle(NULL),
+      mDrmManagerClient(NULL) {
+    mDelegate->setOwner(this);
+}
+
+ChromiumHTTPDataSource::~ChromiumHTTPDataSource() {
+    disconnect();
+
+    delete mDelegate;
+    mDelegate = NULL;
+
+    if (mDrmManagerClient != NULL) {
+        delete mDrmManagerClient;
+        mDrmManagerClient = NULL;
+    }
+}
+
+status_t ChromiumHTTPDataSource::connect(
+        const char *uri,
+        const KeyedVector<String8, String8> *headers,
+        off64_t offset) {
+    Mutex::Autolock autoLock(mLock);
+
+    return connect_l(uri, headers, offset);
+}
+
+status_t ChromiumHTTPDataSource::connect_l(
+        const char *uri,
+        const KeyedVector<String8, String8> *headers,
+        off64_t offset) {
+    if (mState != DISCONNECTED) {
+        disconnect_l();
+    }
+
+    if (!(mFlags & kFlagIncognito)) {
+        LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "connect to %s @%lld", uri, offset);
+    } else {
+        LOG_PRI(ANDROID_LOG_INFO, LOG_TAG,
+                "connect to <URL suppressed> @%lld", offset);
+    }
+
+    mURI = uri;
+
+    if (headers != NULL) {
+        mHeaders = *headers;
+    } else {
+        mHeaders.clear();
+    }
+
+    mState = CONNECTING;
+    mContentSize = -1;
+    mCurrentOffset = offset;
+
+    mDelegate->initiateConnection(mURI.c_str(), &mHeaders, offset);
+
+    while (mState == CONNECTING) {
+        mCondition.wait(mLock);
+    }
+
+    return mState == CONNECTED ? OK : mIOResult;
+}
+
+void ChromiumHTTPDataSource::onConnectionEstablished(int64_t contentSize) {
+    Mutex::Autolock autoLock(mLock);
+    mState = CONNECTED;
+    mContentSize = (contentSize < 0) ? -1 : contentSize + mCurrentOffset;
+    mCondition.broadcast();
+}
+
+void ChromiumHTTPDataSource::onConnectionFailed(status_t err) {
+    Mutex::Autolock autoLock(mLock);
+    mState = DISCONNECTED;
+    mCondition.broadcast();
+
+    mURI.clear();
+
+    mIOResult = err;
+
+    clearDRMState_l();
+}
+
+void ChromiumHTTPDataSource::disconnect() {
+    Mutex::Autolock autoLock(mLock);
+    disconnect_l();
+}
+
+void ChromiumHTTPDataSource::disconnect_l() {
+    if (mState == DISCONNECTED) {
+        return;
+    }
+
+    mState = DISCONNECTING;
+    mIOResult = -EINTR;
+
+    mDelegate->initiateDisconnect();
+
+    while (mState == DISCONNECTING) {
+        mCondition.wait(mLock);
+    }
+
+    CHECK_EQ((int)mState, (int)DISCONNECTED);
+}
+
+status_t ChromiumHTTPDataSource::initCheck() const {
+    Mutex::Autolock autoLock(mLock);
+
+    return mState == CONNECTED ? OK : NO_INIT;
+}
+
+ssize_t ChromiumHTTPDataSource::readAt(off64_t offset, void *data, size_t size) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mState != CONNECTED) {
+        return ERROR_NOT_CONNECTED;
+    }
+
+    if (offset != mCurrentOffset) {
+        AString tmp = mURI;
+        KeyedVector<String8, String8> tmpHeaders = mHeaders;
+
+        disconnect_l();
+
+        status_t err = connect_l(tmp.c_str(), &tmpHeaders, offset);
+
+        if (err != OK) {
+            return err;
+        }
+    }
+
+    mState = READING;
+
+    int64_t startTimeUs = ALooper::GetNowUs();
+
+    mDelegate->initiateRead(data, size);
+
+    while (mState == READING) {
+        mCondition.wait(mLock);
+    }
+
+    if (mIOResult < OK) {
+        return mIOResult;
+    }
+
+    if (mState == CONNECTED) {
+        int64_t delayUs = ALooper::GetNowUs() - startTimeUs;
+
+        // The read operation was successful, mIOResult contains
+        // the number of bytes read.
+        addBandwidthMeasurement_l(mIOResult, delayUs);
+
+        mCurrentOffset += mIOResult;
+        return mIOResult;
+    }
+
+    return ERROR_IO;
+}
+
+void ChromiumHTTPDataSource::onReadCompleted(ssize_t size) {
+    Mutex::Autolock autoLock(mLock);
+
+    mIOResult = size;
+
+    if (mState == READING) {
+        mState = CONNECTED;
+        mCondition.broadcast();
+    }
+}
+
+status_t ChromiumHTTPDataSource::getSize(off64_t *size) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mContentSize < 0) {
+        return ERROR_UNSUPPORTED;
+    }
+
+    *size = mContentSize;
+
+    return OK;
+}
+
+uint32_t ChromiumHTTPDataSource::flags() {
+    return kWantsPrefetching;
+}
+
+// static
+void ChromiumHTTPDataSource::InitiateRead(
+        ChromiumHTTPDataSource *me, void *data, size_t size) {
+    me->initiateRead(data, size);
+}
+
+void ChromiumHTTPDataSource::initiateRead(void *data, size_t size) {
+    mDelegate->initiateRead(data, size);
+}
+
+void ChromiumHTTPDataSource::onDisconnectComplete() {
+    Mutex::Autolock autoLock(mLock);
+    CHECK_EQ((int)mState, (int)DISCONNECTING);
+
+    mState = DISCONNECTED;
+    mURI.clear();
+
+    mCondition.broadcast();
+
+    clearDRMState_l();
+}
+
+void ChromiumHTTPDataSource::addBandwidthMeasurement_l(
+        size_t numBytes, int64_t delayUs) {
+    BandwidthEntry entry;
+    entry.mDelayUs = delayUs;
+    entry.mNumBytes = numBytes;
+    mTotalTransferTimeUs += delayUs;
+    mTotalTransferBytes += numBytes;
+
+    mBandwidthHistory.push_back(entry);
+    if (++mNumBandwidthHistoryItems > 100) {
+        BandwidthEntry *entry = &*mBandwidthHistory.begin();
+        mTotalTransferTimeUs -= entry->mDelayUs;
+        mTotalTransferBytes -= entry->mNumBytes;
+        mBandwidthHistory.erase(mBandwidthHistory.begin());
+        --mNumBandwidthHistoryItems;
+    }
+}
+
+bool ChromiumHTTPDataSource::estimateBandwidth(int32_t *bandwidth_bps) {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mNumBandwidthHistoryItems < 2) {
+        return false;
+    }
+
+    *bandwidth_bps = ((double)mTotalTransferBytes * 8E6 / mTotalTransferTimeUs);
+
+    return true;
+}
+
+sp<DecryptHandle> ChromiumHTTPDataSource::DrmInitialization() {
+    Mutex::Autolock autoLock(mLock);
+
+    if (mDrmManagerClient == NULL) {
+        mDrmManagerClient = new DrmManagerClient();
+    }
+
+    if (mDrmManagerClient == NULL) {
+        return NULL;
+    }
+
+    if (mDecryptHandle == NULL) {
+        /* Note if redirect occurs, mUri is the redirect uri instead of the
+         * original one
+         */
+        mDecryptHandle = mDrmManagerClient->openDecryptSession(
+                String8(mURI.c_str()));
+    }
+
+    if (mDecryptHandle == NULL) {
+        delete mDrmManagerClient;
+        mDrmManagerClient = NULL;
+    }
+
+    return mDecryptHandle;
+}
+
+void ChromiumHTTPDataSource::getDrmInfo(
+        sp<DecryptHandle> &handle, DrmManagerClient **client) {
+    Mutex::Autolock autoLock(mLock);
+
+    handle = mDecryptHandle;
+    *client = mDrmManagerClient;
+}
+
+String8 ChromiumHTTPDataSource::getUri() {
+    Mutex::Autolock autoLock(mLock);
+
+    return String8(mURI.c_str());
+}
+
+void ChromiumHTTPDataSource::clearDRMState_l() {
+    if (mDecryptHandle != NULL) {
+        // To release mDecryptHandle
+        CHECK(mDrmManagerClient);
+        mDrmManagerClient->closeDecryptSession(mDecryptHandle);
+        mDecryptHandle = NULL;
+    }
+}
+
+}  // namespace android
+
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
new file mode 100644
index 0000000..7ac56e8
--- /dev/null
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -0,0 +1,457 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ChromiumHTTPDataSourceSupport"
+#include <utils/Log.h>
+
+#include <media/stagefright/foundation/AString.h>
+
+#include "support.h"
+
+#include "android/net/android_network_library_impl.h"
+#include "base/thread.h"
+#include "net/base/host_resolver.h"
+#include "net/base/ssl_config_service.h"
+#include "net/http/http_auth_handler_factory.h"
+#include "net/http/http_cache.h"
+#include "net/proxy/proxy_config_service_android.h"
+
+#include "include/ChromiumHTTPDataSource.h"
+
+#include <cutils/properties.h>
+#include <media/stagefright/MediaErrors.h>
+
+namespace android {
+
+static Mutex gNetworkThreadLock;
+static base::Thread *gNetworkThread = NULL;
+static scoped_refptr<URLRequestContext> gReqContext;
+
+static void InitializeNetworkThreadIfNecessary() {
+    Mutex::Autolock autoLock(gNetworkThreadLock);
+    if (gNetworkThread == NULL) {
+        gNetworkThread = new base::Thread("network");
+        base::Thread::Options options;
+        options.message_loop_type = MessageLoop::TYPE_IO;
+        CHECK(gNetworkThread->StartWithOptions(options));
+
+        gReqContext = new SfRequestContext;
+
+        net::AndroidNetworkLibrary::RegisterSharedInstance(
+                new SfNetworkLibrary);
+    }
+}
+
+static void MY_LOGI(const char *s) {
+    LOG_PRI(ANDROID_LOG_INFO, LOG_TAG, "%s", s);
+}
+
+static void MY_LOGV(const char *s) {
+#if !defined(LOG_NDEBUG) || LOG_NDEBUG == 0
+    LOG_PRI(ANDROID_LOG_VERBOSE, LOG_TAG, "%s", s);
+#endif
+}
+
+SfNetLog::SfNetLog()
+    : mNextID(1) {
+}
+
+void SfNetLog::AddEntry(
+        EventType type,
+        const base::TimeTicks &time,
+        const Source &source,
+        EventPhase phase,
+        EventParameters *params) {
+#if 0
+    MY_LOGI(StringPrintf(
+                "AddEntry time=%s type=%s source=%s phase=%s\n",
+                TickCountToString(time).c_str(),
+                EventTypeToString(type),
+                SourceTypeToString(source.type),
+                EventPhaseToString(phase)).c_str());
+#endif
+}
+
+uint32 SfNetLog::NextID() {
+    return mNextID++;
+}
+
+net::NetLog::LogLevel SfNetLog::GetLogLevel() const {
+    return LOG_ALL;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SfRequestContext::SfRequestContext() {
+    AString ua;
+    ua.append("stagefright/1.2 (Linux;Android ");
+
+#if (PROPERTY_VALUE_MAX < 8)
+#error "PROPERTY_VALUE_MAX must be at least 8"
+#endif
+
+    char value[PROPERTY_VALUE_MAX];
+    property_get("ro.build.version.release", value, "Unknown");
+    ua.append(value);
+    ua.append(")");
+
+    mUserAgent = ua.c_str();
+
+    net_log_ = new SfNetLog;
+
+    host_resolver_ =
+        net::CreateSystemHostResolver(
+                net::HostResolver::kDefaultParallelism,
+                NULL /* resolver_proc */,
+                net_log_);
+
+    ssl_config_service_ =
+        net::SSLConfigService::CreateSystemSSLConfigService();
+
+    proxy_service_ = net::ProxyService::CreateWithoutProxyResolver(
+            new net::ProxyConfigServiceAndroid, net_log_);
+
+    http_transaction_factory_ = new net::HttpCache(
+            host_resolver_,
+            dnsrr_resolver_,
+            dns_cert_checker_.get(),
+            proxy_service_.get(),
+            ssl_config_service_.get(),
+            net::HttpAuthHandlerFactory::CreateDefault(host_resolver_),
+            network_delegate_,
+            net_log_,
+            NULL);  // backend_factory
+}
+
+const std::string &SfRequestContext::GetUserAgent(const GURL &url) const {
+    return mUserAgent;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SfNetworkLibrary::SfNetworkLibrary() {}
+
+SfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain(
+        const std::vector<std::string>& cert_chain,
+        const std::string& hostname,
+        const std::string& auth_type) {
+    return VERIFY_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+SfDelegate::SfDelegate()
+    : mOwner(NULL),
+      mURLRequest(NULL),
+      mReadBuffer(new net::IOBufferWithSize(8192)),
+      mNumBytesRead(0),
+      mNumBytesTotal(0),
+      mDataDestination(NULL),
+      mAtEOS(false) {
+    InitializeNetworkThreadIfNecessary();
+}
+
+SfDelegate::~SfDelegate() {
+    CHECK(mURLRequest == NULL);
+}
+
+void SfDelegate::setOwner(ChromiumHTTPDataSource *owner) {
+    mOwner = owner;
+}
+
+void SfDelegate::OnReceivedRedirect(
+            URLRequest *request, const GURL &new_url, bool *defer_redirect) {
+    MY_LOGI("OnReceivedRedirect");
+}
+
+void SfDelegate::OnAuthRequired(
+            URLRequest *request, net::AuthChallengeInfo *auth_info) {
+    MY_LOGI("OnAuthRequired");
+
+    inherited::OnAuthRequired(request, auth_info);
+}
+
+void SfDelegate::OnCertificateRequested(
+            URLRequest *request, net::SSLCertRequestInfo *cert_request_info) {
+    MY_LOGI("OnCertificateRequested");
+
+    inherited::OnCertificateRequested(request, cert_request_info);
+}
+
+void SfDelegate::OnSSLCertificateError(
+            URLRequest *request, int cert_error, net::X509Certificate *cert) {
+    fprintf(stderr, "OnSSLCertificateError cert_error=%d\n", cert_error);
+
+    inherited::OnSSLCertificateError(request, cert_error, cert);
+}
+
+void SfDelegate::OnGetCookies(URLRequest *request, bool blocked_by_policy) {
+    MY_LOGI("OnGetCookies");
+}
+
+void SfDelegate::OnSetCookie(
+        URLRequest *request,
+        const std::string &cookie_line,
+        const net::CookieOptions &options,
+        bool blocked_by_policy) {
+    MY_LOGI("OnSetCookie");
+}
+
+void SfDelegate::OnResponseStarted(URLRequest *request) {
+    if (request->status().status() != URLRequestStatus::SUCCESS) {
+        MY_LOGI(StringPrintf(
+                    "Request failed with status %d and os_error %d",
+                    request->status().status(),
+                    request->status().os_error()).c_str());
+
+        delete mURLRequest;
+        mURLRequest = NULL;
+
+        mOwner->onConnectionFailed(ERROR_IO);
+        return;
+    } else if (mRangeRequested && request->GetResponseCode() != 206) {
+        MY_LOGI(StringPrintf(
+                    "We requested a content range, but server didn't "
+                    "support that. (responded with %d)",
+                    request->GetResponseCode()).c_str());
+
+        delete mURLRequest;
+        mURLRequest = NULL;
+
+        mOwner->onConnectionFailed(-EPIPE);
+        return;
+    } else if ((request->GetResponseCode() / 100) != 2) {
+        MY_LOGI(StringPrintf(
+                    "Server responded with http status %d",
+                    request->GetResponseCode()).c_str());
+
+        delete mURLRequest;
+        mURLRequest = NULL;
+
+        mOwner->onConnectionFailed(ERROR_IO);
+        return;
+    }
+
+    MY_LOGV("OnResponseStarted");
+
+    std::string headers;
+    request->GetAllResponseHeaders(&headers);
+
+    MY_LOGV(StringPrintf("response headers: %s", headers.c_str()).c_str());
+
+    mOwner->onConnectionEstablished(request->GetExpectedContentSize());
+}
+
+void SfDelegate::OnReadCompleted(URLRequest *request, int bytes_read) {
+    if (bytes_read == -1) {
+        MY_LOGI(StringPrintf(
+                    "OnReadCompleted, read failed, status %d",
+                    request->status().status()).c_str());
+
+        mOwner->onReadCompleted(ERROR_IO);
+        return;
+    }
+
+    MY_LOGV(StringPrintf("OnReadCompleted, read %d bytes", bytes_read).c_str());
+
+    if (bytes_read < 0) {
+        MY_LOGI(StringPrintf(
+                    "Read failed w/ status %d\n",
+                    request->status().status()).c_str());
+
+        mOwner->onReadCompleted(ERROR_IO);
+        return;
+    } else if (bytes_read == 0) {
+        mAtEOS = true;
+        mOwner->onReadCompleted(mNumBytesRead);
+        return;
+    }
+
+    CHECK_GT(bytes_read, 0);
+    CHECK_LE(mNumBytesRead + bytes_read, mNumBytesTotal);
+
+    memcpy((uint8_t *)mDataDestination + mNumBytesRead,
+           mReadBuffer->data(),
+           bytes_read);
+
+    mNumBytesRead += bytes_read;
+
+    readMore(request);
+}
+
+void SfDelegate::readMore(URLRequest *request) {
+    while (mNumBytesRead < mNumBytesTotal) {
+        size_t copy = mNumBytesTotal - mNumBytesRead;
+        if (copy > mReadBuffer->size()) {
+            copy = mReadBuffer->size();
+        }
+
+        int n;
+        if (request->Read(mReadBuffer, copy, &n)) {
+            MY_LOGV(StringPrintf("Read %d bytes directly.", n).c_str());
+
+            CHECK_LE((size_t)n, copy);
+
+            memcpy((uint8_t *)mDataDestination + mNumBytesRead,
+                   mReadBuffer->data(),
+                   n);
+
+            mNumBytesRead += n;
+
+            if (n == 0) {
+                mAtEOS = true;
+                break;
+            }
+        } else {
+            MY_LOGV("readMore pending read");
+
+            if (request->status().status() != URLRequestStatus::IO_PENDING) {
+                MY_LOGI(StringPrintf(
+                            "Direct read failed w/ status %d\n",
+                            request->status().status()).c_str());
+
+                mOwner->onReadCompleted(ERROR_IO);
+                return;
+            }
+
+            return;
+        }
+    }
+
+    mOwner->onReadCompleted(mNumBytesRead);
+}
+
+void SfDelegate::initiateConnection(
+        const char *uri,
+        const KeyedVector<String8, String8> *headers,
+        off64_t offset) {
+    GURL url(uri);
+
+    MessageLoop *loop = gNetworkThread->message_loop();
+    loop->PostTask(
+            FROM_HERE,
+            NewRunnableFunction(
+                &SfDelegate::OnInitiateConnectionWrapper,
+                this,
+                url,
+                headers,
+                offset));
+
+}
+
+// static
+void SfDelegate::OnInitiateConnectionWrapper(
+        SfDelegate *me, GURL url,
+        const KeyedVector<String8, String8> *headers,
+        off64_t offset) {
+    me->onInitiateConnection(url, headers, offset);
+}
+
+void SfDelegate::onInitiateConnection(
+        const GURL &url,
+        const KeyedVector<String8, String8> *extra,
+        off64_t offset) {
+    CHECK(mURLRequest == NULL);
+
+    mURLRequest = new URLRequest(url, this);
+    mAtEOS = false;
+
+    mRangeRequested = false;
+
+    if (offset != 0 || extra != NULL) {
+        net::HttpRequestHeaders headers =
+            mURLRequest->extra_request_headers();
+
+        if (offset != 0) {
+            headers.AddHeaderFromString(
+                    StringPrintf("Range: bytes=%lld-", offset).c_str());
+
+            mRangeRequested = true;
+        }
+
+        if (extra != NULL) {
+            for (size_t i = 0; i < extra->size(); ++i) {
+                AString s;
+                s.append(extra->keyAt(i).string());
+                s.append(": ");
+                s.append(extra->valueAt(i).string());
+
+                headers.AddHeaderFromString(s.c_str());
+            }
+        }
+
+        mURLRequest->SetExtraRequestHeaders(headers);
+    }
+
+    mURLRequest->set_context(gReqContext);
+
+    mURLRequest->Start();
+}
+
+void SfDelegate::initiateDisconnect() {
+    MessageLoop *loop = gNetworkThread->message_loop();
+    loop->PostTask(
+            FROM_HERE,
+            NewRunnableFunction(
+                &SfDelegate::OnInitiateDisconnectWrapper, this));
+}
+
+// static
+void SfDelegate::OnInitiateDisconnectWrapper(SfDelegate *me) {
+    me->onInitiateDisconnect();
+}
+
+void SfDelegate::onInitiateDisconnect() {
+    mURLRequest->Cancel();
+
+    delete mURLRequest;
+    mURLRequest = NULL;
+
+    mOwner->onDisconnectComplete();
+}
+
+void SfDelegate::initiateRead(void *data, size_t size) {
+    MessageLoop *loop = gNetworkThread->message_loop();
+    loop->PostTask(
+            FROM_HERE,
+            NewRunnableFunction(
+                &SfDelegate::OnInitiateReadWrapper, this, data, size));
+}
+
+// static
+void SfDelegate::OnInitiateReadWrapper(
+        SfDelegate *me, void *data, size_t size) {
+    me->onInitiateRead(data, size);
+}
+
+void SfDelegate::onInitiateRead(void *data, size_t size) {
+    CHECK(mURLRequest != NULL);
+
+    mNumBytesRead = 0;
+    mNumBytesTotal = size;
+    mDataDestination = data;
+
+    if (mAtEOS) {
+        mOwner->onReadCompleted(0);
+        return;
+    }
+
+    readMore(mURLRequest);
+}
+
+}  // namespace android
+
diff --git a/media/libstagefright/chromium_http/support.h b/media/libstagefright/chromium_http/support.h
new file mode 100644
index 0000000..634ac93
--- /dev/null
+++ b/media/libstagefright/chromium_http/support.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef SUPPORT_H_
+
+#define SUPPORT_H_
+
+#include <assert.h>
+
+#include "net/base/net_log.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_context.h"
+#include "net/base/android_network_library.h"
+#include "net/base/io_buffer.h"
+
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
+namespace android {
+
+struct SfNetLog : public net::NetLog {
+    SfNetLog();
+
+    virtual void AddEntry(
+            EventType type,
+            const base::TimeTicks &time,
+            const Source &source,
+            EventPhase phase,
+            EventParameters *params);
+
+    virtual uint32 NextID();
+    virtual LogLevel GetLogLevel() const;
+
+private:
+    uint32 mNextID;
+
+    DISALLOW_EVIL_CONSTRUCTORS(SfNetLog);
+};
+
+struct SfRequestContext : public URLRequestContext {
+    SfRequestContext();
+
+    virtual const std::string &GetUserAgent(const GURL &url) const;
+
+private:
+    std::string mUserAgent;
+
+    DISALLOW_EVIL_CONSTRUCTORS(SfRequestContext);
+};
+
+// This is required for https support, we don't really verify certificates,
+// we accept anything...
+struct SfNetworkLibrary : public net::AndroidNetworkLibrary {
+    SfNetworkLibrary();
+
+    virtual VerifyResult VerifyX509CertChain(
+            const std::vector<std::string>& cert_chain,
+            const std::string& hostname,
+            const std::string& auth_type);
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(SfNetworkLibrary);
+};
+
+struct ChromiumHTTPDataSource;
+
+struct SfDelegate : public URLRequest::Delegate {
+    SfDelegate();
+    virtual ~SfDelegate();
+
+    void initiateConnection(
+            const char *uri,
+            const KeyedVector<String8, String8> *headers,
+            off64_t offset);
+
+    void initiateDisconnect();
+    void initiateRead(void *data, size_t size);
+
+    void setOwner(ChromiumHTTPDataSource *mOwner);
+
+    virtual void OnReceivedRedirect(
+            URLRequest *request, const GURL &new_url, bool *defer_redirect);
+
+    virtual void OnAuthRequired(
+            URLRequest *request, net::AuthChallengeInfo *auth_info);
+
+    virtual void OnCertificateRequested(
+            URLRequest *request, net::SSLCertRequestInfo *cert_request_info);
+
+    virtual void OnSSLCertificateError(
+            URLRequest *request, int cert_error, net::X509Certificate *cert);
+
+    virtual void OnGetCookies(URLRequest *request, bool blocked_by_policy);
+
+    virtual void OnSetCookie(
+            URLRequest *request,
+            const std::string &cookie_line,
+            const net::CookieOptions &options,
+            bool blocked_by_policy);
+
+    virtual void OnResponseStarted(URLRequest *request);
+
+    virtual void OnReadCompleted(URLRequest *request, int bytes_read);
+
+private:
+    typedef Delegate inherited;
+
+    ChromiumHTTPDataSource *mOwner;
+
+    URLRequest *mURLRequest;
+    scoped_refptr<net::IOBufferWithSize> mReadBuffer;
+
+    size_t mNumBytesRead;
+    size_t mNumBytesTotal;
+    void *mDataDestination;
+
+    bool mRangeRequested;
+    bool mAtEOS;
+
+    void readMore(URLRequest *request);
+
+    static void OnInitiateConnectionWrapper(
+            SfDelegate *me,
+            GURL url,
+            const KeyedVector<String8, String8> *headers,
+            off64_t offset);
+
+    static void OnInitiateDisconnectWrapper(SfDelegate *me);
+
+    static void OnInitiateReadWrapper(
+            SfDelegate *me, void *data, size_t size);
+
+    void onInitiateConnection(
+            const GURL &url,
+            const KeyedVector<String8, String8> *headers,
+            off64_t offset);
+
+    void onInitiateDisconnect();
+    void onInitiateRead(void *data, size_t size);
+
+    DISALLOW_EVIL_CONSTRUCTORS(SfDelegate);
+};
+
+}  // namespace android
+
+#endif  // SUPPORT_H_
diff --git a/media/libstagefright/codecs/aacdec/sbr_dec.cpp b/media/libstagefright/codecs/aacdec/sbr_dec.cpp
index 8fcc3ce..8519b17 100644
--- a/media/libstagefright/codecs/aacdec/sbr_dec.cpp
+++ b/media/libstagefright/codecs/aacdec/sbr_dec.cpp
@@ -1,5 +1,5 @@
 /* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
+ * Copyright (C) 1998-2010 PacketVideo
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -447,7 +447,12 @@
 
             if (xoverBand > sbrDec->highSubband)
             {
-                xoverBand = 32; /* error condition, default to upsampling mode */
+                /*
+                 * error condition, default to upsampling mode
+                 * and make sure that the number of bands for xover does
+                 * not exceed the number of high freq bands.
+                 */
+                xoverBand = (sbrDec->highSubband > 32)? 32: sbrDec->highSubband;
             }
 
             m = sbrDec->bufReadOffs + i;    /*  2 + i */
@@ -558,18 +563,22 @@
         /*
          *  Set Circular buffer for PS hybrid analysis
          */
+
+        int32_t *pt_temp = &scratch_mem[2][32];
+
         for (i = 0, j = 0; i < 3; i++)
         {
 
-            pv_memmove(&scratch_mem[2][32 + j     ],
+            pv_memmove(&pt_temp[ j],
                        hParametricStereoDec->hHybrid->mQmfBufferReal[i],
                        HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferReal));
-            pv_memmove(&scratch_mem[2][32 + j + 44],
+            pv_memmove(&pt_temp[ j + 44],
                        hParametricStereoDec->hHybrid->mQmfBufferImag[i],
                        HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferImag));
             j += 88;
         }
 
+
         pv_memset((void *)&qmf_PS_generated_Real[hParametricStereoDec->usb],
                   0,
                   (64 - hParametricStereoDec->usb)*sizeof(*qmf_PS_generated_Real));
@@ -626,19 +635,23 @@
          *  Save Circular buffer history used on PS hybrid analysis
          */
 
+
+        pt_temp = &scratch_mem[2][64];
+
         for (i = 0, j = 0; i < 3; i++)
         {
             pv_memmove(hParametricStereoDec->hHybrid->mQmfBufferReal[i],
-                       &scratch_mem[2][ 64 + j     ],
+                       &pt_temp[ j],
                        HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferReal));
 
             pv_memmove(hParametricStereoDec->hHybrid->mQmfBufferImag[i],
-                       &scratch_mem[2][ 64 + j + 44],
+                       &pt_temp[ j + 44],
                        HYBRID_FILTER_LENGTH_m_1*sizeof(*hParametricStereoDec->hHybrid->mQmfBufferImag));
 
             j += 88;
         }
 
+
         pv_memmove(hFrameData->V, &circular_buffer_s[0], 1152*sizeof(*circular_buffer_s));
 
         /*
@@ -746,7 +759,12 @@
 
                 if (xoverBand > sbrDec->highSubband)
                 {
-                    xoverBand = 32; /* error condition, default to upsampling mode */
+                    /*
+                     * error condition, default to upsampling mode
+                     * and make sure that the number of bands for xover does
+                     * not exceed the number of high freq bands.
+                     */
+                    xoverBand = (sbrDec->highSubband > 32)? 32: sbrDec->highSubband;
                 }
             }
             else
diff --git a/media/libstagefright/codecs/aacenc/Android.mk b/media/libstagefright/codecs/aacenc/Android.mk
index cda4f9d..f9cc6a3 100644
--- a/media/libstagefright/codecs/aacenc/Android.mk
+++ b/media/libstagefright/codecs/aacenc/Android.mk
@@ -2,7 +2,7 @@
 include $(CLEAR_VARS)
 include frameworks/base/media/libstagefright/codecs/common/Config.mk
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_SRC_FILES := basic_op/basicop2.c basic_op/oper_32b.c
 
diff --git a/media/libstagefright/codecs/aacenc/SampleCode/AAC_E_SAMPLES.c b/media/libstagefright/codecs/aacenc/SampleCode/AAC_E_SAMPLES.c
index 64d012d..774da7b 100644
--- a/media/libstagefright/codecs/aacenc/SampleCode/AAC_E_SAMPLES.c
+++ b/media/libstagefright/codecs/aacenc/SampleCode/AAC_E_SAMPLES.c
@@ -188,7 +188,7 @@
 	useData.memflag = VO_IMF_USERMEMOPERATOR;

 	useData.memData = (VO_PTR)(&moper);

 	// open encoder dll;

-	handle = dlopen("/data/local/tmp/libvoAACEncv7.so", RTLD_NOW);

+	handle = dlopen("libstagefright.so", RTLD_NOW);

 	if(handle == 0)

 	{

 		printf("open dll error......");

diff --git a/media/libstagefright/codecs/aacenc/SampleCode/Android.mk b/media/libstagefright/codecs/aacenc/SampleCode/Android.mk
index 52c9c07..ba3f4d2 100644
--- a/media/libstagefright/codecs/aacenc/SampleCode/Android.mk
+++ b/media/libstagefright/codecs/aacenc/SampleCode/Android.mk
@@ -1,24 +1,25 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := 	AAC_E_SAMPLES.c
-	
-LOCAL_SRC_FILES += 	\
-	../../../Common/cmnMemory.c 
+LOCAL_SRC_FILES := \
+    AAC_E_SAMPLES.c \
+    ../../common/cmnMemory.c
 
-LOCAL_MODULE := TestvoAACEnc
+LOCAL_CFLAGS += $(VO_CFLAGS)
+
+LOCAL_MODULE_TAGS := debug
+
+LOCAL_MODULE := AACEncTest
 
 LOCAL_ARM_MODE := arm
 
-LOCAL_STATIC_LIBRARIES := 
-
-LOCAL_SHARED_LIBRARIES := libvoAACEnc
+LOCAL_SHARED_LIBRARIES := \
+    libstagefright \
+    libdl
 
 LOCAL_C_INCLUDES := \
-	$(LOCAL_PATH)/ \
-	$(LOCAL_PATH)/../../../Common \
-	$(LOCAL_PATH)/../../../Include \
+    $(LOCAL_PATH)/ \
+    $(LOCAL_PATH)/../../common \
+    $(LOCAL_PATH)/../../common/include \
 
-LOCAL_CFLAGS := $(VO_CFLAGS)
-	
 include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/aacenc/SampleCode/eclair/Makefile b/media/libstagefright/codecs/aacenc/SampleCode/eclair/Makefile
deleted file mode 100644
index 22c5dc1..0000000
--- a/media/libstagefright/codecs/aacenc/SampleCode/eclair/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-#/*

-#** Copyright 2003-2010, VisualOn, Inc.

-#**

-#** Licensed under the Apache License, Version 2.0 (the "License");

-#** you may not use this file except in compliance with the License.

-#** You may obtain a copy of the License at

-#**

-#**     http://www.apache.org/licenses/LICENSE-2.0

-#**

-#** Unless required by applicable law or agreed to in writing, software

-#** distributed under the License is distributed on an "AS IS" BASIS,

-#** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-#** See the License for the specific language governing permissions and

-#** limitations under the License.

-#*/

-

-# target6

-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)

-VOTT:= v7

-

-

-# module type

-# please specify the type of your module: lib or exe

-VOMT:= exe

-

-

-# module macros

-# please append the additional macro definitions here for your module if necessary. 

-# e.g. -DVISUALON, macro VISUALON defined for your module 

-VOMM:= #ARMV5E

-

-

-

-# please specify the name of your module

-VOTARGET:= voAACEncTestv7

-

-

-# please modify here to be sure to see the g1.mk

-include ../../../../Tools/eclair.mk 

-

-# dependent libraries.

-VODEPLIBS:=-ldl

-

-# module source

-# please modify here to be sure to see the ms.mk which specifies all source info of your module

-include ../ms.mk

-

-

-# please specify where is the voRelease on your PC, relative path is suggested

-VORELDIR:=../../../../../Release/

-

-

-# please modify here to be sure to see the doit.mk

-include ../../../../Tools/doit.mk 

-

diff --git a/media/libstagefright/codecs/aacenc/SampleCode/ms.mk b/media/libstagefright/codecs/aacenc/SampleCode/ms.mk
deleted file mode 100644
index 771a569..0000000
--- a/media/libstagefright/codecs/aacenc/SampleCode/ms.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-#/*

-#** Copyright 2003-2010, VisualOn, Inc.

-#**

-#** Licensed under the Apache License, Version 2.0 (the "License");

-#** you may not use this file except in compliance with the License.

-#** You may obtain a copy of the License at

-#**

-#**     http://www.apache.org/licenses/LICENSE-2.0

-#**

-#** Unless required by applicable law or agreed to in writing, software

-#** distributed under the License is distributed on an "AS IS" BASIS,

-#** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-#** See the License for the specific language governing permissions and

-#** limitations under the License.

-#*/

-

-# please list all objects needed by your target here

-OBJS:=AAC_E_SAMPLES.o	cmnMemory.o

-			

-# please list all directories that all source files relative with your module(.h .c .cpp) locate 

-VOSRCDIR:=../ ../../../../include  ../../../../Common

-					

-				

diff --git a/media/libstagefright/codecs/aacenc/Tools/doit.mk b/media/libstagefright/codecs/aacenc/Tools/doit.mk
deleted file mode 100644
index dea0b0a..0000000
--- a/media/libstagefright/codecs/aacenc/Tools/doit.mk
+++ /dev/null
@@ -1,133 +0,0 @@
-#/*
-# ** Copyright 2003-2010, VisualOn, Inc.
-# **
-# ** Licensed under the Apache License, Version 2.0 (the "License");
-# ** you may not use this file except in compliance with the License.
-# ** You may obtain a copy of the License at
-# **
-# **     http://www.apache.org/licenses/LICENSE-2.0
-# **
-# ** Unless required by applicable law or agreed to in writing, software
-# ** distributed under the License is distributed on an "AS IS" BASIS,
-# ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# ** See the License for the specific language governing permissions and
-# ** limitations under the License.
-# */
-
-VERBOSE:=@
-
-
-VOMT ?= lib
-
-ifeq ($(VOMT), lib)
-LIB_STATIC=$(VOTARGET).a
-LIB_DYNAMIC=$(VOTARGET).so
-endif
-
-ifeq ($(VOMT), exe)
-TARGET=$(VOTARGET)
-endif
-
-CFLAGS=$(VOCFLAGS) $(addprefix -I, $(VOSRCDIR)) 
-CPPFLAGS=$(VOCPPFLAGS) $(addprefix -I, $(VOSRCDIR)) 
-ifneq ($(VOTT), pc)
-ASFLAGS=$(VOASFLAGS) $(addprefix -I, $(VOSRCDIR)) 
-endif
-
-LDFLAGS:=$(VOLDFLAGS)
-VOTEDEPS+=$(VODEPLIBS)
-VOTLDEPS+=$(VODEPLIBS)
-VOSTCLIBS ?=
-
-vpath %.c $(VOSRCDIR)
-vpath %.cpp $(VOSRCDIR)
-ifneq ($(VOTT), pc)
-vpath %.s $(VOSRCDIR)
-endif
-
-ifeq ($(VOTT), pc)
-BLTDIRS=$(VORELDIR)/Linux/static
-BLTDIRD=$(VORELDIR)/Linux/shared
-else
-BLTDIRS=$(VORELDIR)/Google/$(VONJ)/lib/$(VOTT)
-BLTDIRD=$(VORELDIR)/Google/$(VONJ)/so/$(VOTT)
-endif
-
-
-.PRECIOUS: $(OBJDIR)/%.o
-
-ifeq ($(VOMT), lib)
-all: mkdirs $(LIB_STATIC) $(LIB_DYNAMIC)
-mkdirs: $(OBJDIR) $(BLTDIRS) $(BLTDIRD)
-else
-all: mkdirs $(TARGET)
-mkdirs: $(OBJDIR)
-endif
-
-$(OBJDIR):
-	@if test ! -d $@; then \
-		mkdir -p $@; \
-	fi;
-
-ifeq ($(VOMT), lib)
-$(BLTDIRS):
-	@if test ! -d $@; then \
-		mkdir -p $@; \
-	fi;
-$(BLTDIRD):
-	@if test ! -d $@; then \
-		mkdir -p $@; \
-	fi;
-endif
-
-
-ifeq ($(VOMT), lib)
-$(LIB_STATIC):$(OBJS)
-	$(AR) cr $@ $(OBJDIR)/*.o $(VOSTCLIBS)
-	$(RANLIB) $@
-ifneq ($(VODBG), yes)
-	#$(STRIP) $@
-endif
-
-$(LIB_DYNAMIC):$(OBJS)
-	$(GG) $(LDFLAGS) -o $@ $(OBJDIR)/*.o -Wl,--whole-archive $(VOSTCLIBS) -Wl,--no-whole-archive $(VOTLDEPS) 
-ifneq ($(VODBG), yes)
-		$(STRIP) $@
-endif
-
-else
-
-$(TARGET):$(OBJS)
-	$(GG) $(LDFLAGS) -o $@ $(OBJDIR)/*.o -Wl,--whole-archive $(VOSTCLIBS) -Wl,--no-whole-archive $(VOTEDEPS)
-ifneq ($(VODBG), yes)
-	$(STRIP) $@
-endif
-
-endif
-
-
-.SUFFIXES: .c .cpp .s .o
-.c.o:
-	$(VERBOSE) $(CC) $(CFLAGS) -o $(OBJDIR)/$@ -c $<
-#%.c:$(OBJDIR)/%.o
-#	$(VERBOSE) $(CC) $(CFLAGS) -o $@ -c $<
-.cpp.o:
-	$(VERBOSE) $(GG) $(CPPFLAGS) -o $(OBJDIR)/$@ -c $<
-ifneq ($(VOTT), pc)
-.s.o:
-	$(VERBOSE) $(AS) $(ASFLAGS) -o $(OBJDIR)/$@ $<
-endif
-
-
-.PHONY: clean devel
-clean:
-ifeq ($(VOMT), lib)
-	-rm -fr $(OBJDIR) .*.sw* $(VOTARGET).*
-else
-	-rm -fr $(OBJDIR) .*.sw* $(VOTARGET)
-endif
-
-devel:
-	cp -a $(LIB_STATIC) $(BLTDIRS)
-	cp -a $(LIB_DYNAMIC) $(BLTDIRD)
-
diff --git a/media/libstagefright/codecs/aacenc/Tools/eclair.mk b/media/libstagefright/codecs/aacenc/Tools/eclair.mk
deleted file mode 100644
index 1688361..0000000
--- a/media/libstagefright/codecs/aacenc/Tools/eclair.mk
+++ /dev/null
@@ -1,172 +0,0 @@
-#/*
-# ** Copyright 2003-2010, VisualOn, Inc.
-# **
-# ** Licensed under the Apache License, Version 2.0 (the "License");
-# ** you may not use this file except in compliance with the License.
-# ** You may obtain a copy of the License at
-# **
-# **     http://www.apache.org/licenses/LICENSE-2.0
-# **
-# ** Unless required by applicable law or agreed to in writing, software
-# ** distributed under the License is distributed on an "AS IS" BASIS,
-# ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# ** See the License for the specific language governing permissions and
-# ** limitations under the License.
-# */
-
-# special macro definitions for building 
-VOPREDEF=-DLINUX -D_LINUX 
-
-VOPRJ ?= 
-VONJ ?= eclair
-VOTT ?= v6
-# control the version to release out
-# available: eva(evaluation), rel(release)
-VOVER=
-ifeq ($(VOVER), eva)
-VOPREDEF+=-D__VOVER_EVA__
-endif
-
-# for debug or not: yes for debug, any other for release
-VODBG?=ye
-
-# for detecting memory leak
-VODML=
-ifeq ($(VODML), yes)
-VOPREDEF+=-DDMEMLEAK
-endif
-
-VOPREDEF+=-D__VOTT_ARM__ -D__VONJ_ECLAIR__
-TCROOTPATH:=/opt/eclair
-GCCVER:=4.4.0
-TCPATH:=$(TCROOTPATH)/prebuilt/linux-x86/toolchain/arm-eabi-$(GCCVER)
-CCTPRE:=$(TCPATH)/bin/arm-eabi-
-AS:=$(CCTPRE)as
-AR:=$(CCTPRE)ar
-NM:=$(CCTPRE)nm
-CC:=$(CCTPRE)gcc
-GG:=$(CCTPRE)g++
-LD:=$(CCTPRE)ld
-SIZE:=$(CCTPRE)size
-STRIP:=$(CCTPRE)strip
-RANLIB:=$(CCTPRE)ranlib
-OBJCOPY:=$(CCTPRE)objcopy
-OBJDUMP:=$(CCTPRE)objdump
-READELF:=$(CCTPRE)readelf
-STRINGS:=$(CCTPRE)strings
-
-# target product dependcy
-# available: dream, generic
-VOTP:=sapphire-open
-CCTLIB:=$(TCROOTPATH)/out/target/product/$(VOTP)/obj/lib
-CCTINC:=-I$(TCROOTPATH)/system/core/include \
-	-I$(TCROOTPATH)/hardware/libhardware/include \
-	-I$(TCROOTPATH)/hardware/ril/include \
-	-I$(TCROOTPATH)/hardware/libhardware_legacy/include \
-	-I$(TCROOTPATH)/dalvik/libnativehelper/include \
-	-I$(TCROOTPATH)/dalvik/libnativehelper/include/nativehelper \
-	-I$(TCROOTPATH)/frameworks/base/include \
-	-I$(TCROOTPATH)/frameworks/base/core/jni \
-	-I$(TCROOTPATH)/frameworks/base/libs/audioflinger \
-	-I$(TCROOTPATH)/external/skia/include \
-	-I$(TCROOTPATH)/out/target/product/$(VOTP)/obj/include \
-	-I$(TCROOTPATH)/bionic/libc/arch-arm/include \
-	-I$(TCROOTPATH)/bionic/libc/include \
-	-I$(TCROOTPATH)/bionic/libstdc++/include \
-	-I$(TCROOTPATH)/bionic/libc/kernel/common \
-	-I$(TCROOTPATH)/bionic/libc/kernel/arch-arm \
-	-I$(TCROOTPATH)/bionic/libm/include \
-	-I$(TCROOTPATH)/bionic/libm/include/arm \
-	-I$(TCROOTPATH)/bionic/libthread_db/include \
-	-I$(TCROOTPATH)/bionic/libm/arm \
-	-I$(TCROOTPATH)/bionic/libm \
-	-I$(TCROOTPATH)/frameworks/base/include/android_runtime 
-	#-I$(TCROOTPATH)/out/target/product/$(VOTP)/obj/SHARED_LIBRARIES/libm_intermediates
-
-CCTCFLAGS:=-msoft-float -mthumb-interwork -fno-exceptions -ffunction-sections -funwind-tables -fstack-protector -fno-short-enums -fmessage-length=0 -finline-functions -finline-limit=600 -fno-inline-functions-called-once -fgcse-after-reload -frerun-cse-after-loop -frename-registers -fstrict-aliasing -funswitch-loops
-#-fwide-exec-charset=charset=UTF-32 
-
-# for target exe
-TELDFLAGS:=-nostdlib -Bdynamic -Wl,-T,$(TCROOTPATH)/build/core/armelf.x -Wl,-dynamic-linker,/system/bin/linker -Wl,--gc-sections -Wl,-z,nocopyreloc -Wl,--no-undefined -Wl,-rpath-link=$(CCTLIB) -L$(CCTLIB) 
-
-VOTEDEPS:=$(CCTLIB)/crtbegin_dynamic.o $(CCTLIB)/crtend_android.o $(TCPATH)/lib/gcc/arm-eabi/$(GCCVER)/interwork/libgcc.a -lc -lm
-
-# for target lib
-TLLDFLAGS:=-nostdlib -Wl,-T,$(TCROOTPATH)/build/core/armelf.xsc -Wl,--gc-sections -Wl,-shared,-Bsymbolic -L$(CCTLIB) -Wl,--no-whole-archive -Wl,--no-undefined $(TCPATH)/lib/gcc/arm-eabi/$(GCCVER)/interwork/libgcc.a 
-
-VOTLDEPS:=-lm -lc
-
-
-ifeq ($(VOTT), v4)
-VOCFLAGS:=-mtune=arm9tdmi -march=armv4t
-VOASFLAGS:=-march=armv4t -mfpu=softfpa
-endif
-
-ifeq ($(VOTT), v5)
-VOCFLAGS:=-march=armv5te
-VOASFLAGS:=-march=armv5te -mfpu=vfp
-endif
-
-ifeq ($(VOTT), v5x)
-VOCFLAGS:=-march=armv5te -mtune=xscale
-VOASFLAGS:=-march=armv5te -mfpu=vfp
-endif
-
-ifeq ($(VOTT), v6)
-#VOCFLAGS:=-march=armv6 -mtune=arm1136jf-s 
-#VOASFLAGS:=-march=armv6
-VOCFLAGS:=-march=armv6j -mtune=arm1136jf-s -mfpu=vfp -mfloat-abi=softfp -mapcs -mtpcs-leaf-frame -mlong-calls
-VOASFLAGS:=-march=armv6j -mcpu=arm1136jf-s -mfpu=arm1136jf-s -mfloat-abi=softfp -mapcs-float -mapcs-reentrant
-endif
-
-#
-# global link options
-VOLDFLAGS:=-Wl,-x,-X,--as-needed
-
-
-ifeq ($(VOTT), v7)
-VOCFLAGS+=-march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp
-VOASFLAGS+=-march=armv7-a -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp
-VOLDFLAGS+=-Wl,--fix-cortex-a8
-endif
-
-#global compiling options for ARM target
-ifneq ($(VOTT), pc)
-VOASFLAGS+=--strip-local-absolute -R
-endif 
-
-
-ifeq ($(VODBG), yes)
-VOCFLAGS+=-D_DEBUG -g
-else
-VOCFLAGS+=-DNDEBUG -O3
-endif
-
-VOCFLAGS+=$(VOPREDEF) $(VOMM) -Wall -fsigned-char -fomit-frame-pointer -fno-leading-underscore -fpic -fPIC -pipe -ftracer -fforce-addr -fno-bounds-check #-fvisibility=hidden #-fvisibility-inlines-hidden ##-ftree-loop-linear  -mthumb -nostdinc  -dD -fprefetch-loop-arrays
-
-
-ifneq ($(VOTT), pc)
-VOCFLAGS+=$(CCTCFLAGS) $(CCTINC)
-VOCPPFLAGS:=-fno-rtti $(VOCFLAGS)
-
-ifeq ($(VOMT), exe)
-VOLDFLAGS+=$(TELDFLAGS)
-endif
-
-ifeq ($(VOMT), lib)
-VOLDFLAGS+=$(TLLDFLAGS)
-endif
-else
-VOCPPFLAGS:=$(VOCFLAGS)
-ifeq ($(VOMT), lib)
-VOLDFLAGS+=-shared
-endif
-endif
-
-ifeq ($(VODBG), yes)
-#VOLDFLAGS:=
-endif
-
-# where to place object files 
-OBJDIR=obj
-
diff --git a/media/libstagefright/codecs/aacenc/build/eclair/ARMV5E/Makefile b/media/libstagefright/codecs/aacenc/build/eclair/ARMV5E/Makefile
deleted file mode 100644
index b4f63af..0000000
--- a/media/libstagefright/codecs/aacenc/build/eclair/ARMV5E/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-#/*

-#** Copyright 2003-2010, VisualOn, Inc.

-#**

-#** Licensed under the Apache License, Version 2.0 (the "License");

-#** you may not use this file except in compliance with the License.

-#** You may obtain a copy of the License at

-#**

-#**     http://www.apache.org/licenses/LICENSE-2.0

-#**

-#** Unless required by applicable law or agreed to in writing, software

-#** distributed under the License is distributed on an "AS IS" BASIS,

-#** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-#** See the License for the specific language governing permissions and

-#** limitations under the License.

-#*/

-

-# target6

-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)

-VOTT:= v5

-

-

-# module type

-# please specify the type of your module: lib or exe

-VOMT:= lib

-

-

-# module macros

-# please append the additional macro definitions here for your module if necessary. 

-# e.g. -DVISUALON, macro VISUALON defined for your module 

-VOMM:= -DARMV5E -DARM_INASM -DARMV5_INASM 

-

-

-

-# please specify the name of your module

-VOTARGET:=libvoAACEncv5

-

-

-# please modify here to be sure to see the g1.mk

-include ../../../../../Tools/eclair.mk 

-

-# dependent libraries.

-VODEPLIBS:=#-ldl -lstdc++ 

-

-# module source

-# please modify here to be sure to see the ms.mk which specifies all source info of your module

-include ../../ms.mk

-

-

-# please specify where is the voRelease on your PC, relative path is suggested

-VORELDIR:=../../../../../../Release

-

-

-# please modify here to be sure to see the doit.mk

-include ../../../../../Tools/doit.mk 

-

diff --git a/media/libstagefright/codecs/aacenc/build/eclair/ARMV7/Makefile b/media/libstagefright/codecs/aacenc/build/eclair/ARMV7/Makefile
deleted file mode 100644
index cdce2c1..0000000
--- a/media/libstagefright/codecs/aacenc/build/eclair/ARMV7/Makefile
+++ /dev/null
@@ -1,55 +0,0 @@
-#/*

-#** Copyright 2003-2010, VisualOn, Inc.

-#**

-#** Licensed under the Apache License, Version 2.0 (the "License");

-#** you may not use this file except in compliance with the License.

-#** You may obtain a copy of the License at

-#**

-#**     http://www.apache.org/licenses/LICENSE-2.0

-#**

-#** Unless required by applicable law or agreed to in writing, software

-#** distributed under the License is distributed on an "AS IS" BASIS,

-#** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-#** See the License for the specific language governing permissions and

-#** limitations under the License.

-#*/

-

-# target6

-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)

-VOTT:= v7

-

-

-# module type

-# please specify the type of your module: lib or exe

-VOMT:= lib

-

-

-# module macros

-# please append the additional macro definitions here for your module if necessary. 

-# e.g. -DVISUALON, macro VISUALON defined for your module 

-VOMM:= -DARMV5E -DARMV7Neon -DARM_INASM -DARMV5_INASM 

-

-

-

-# please specify the name of your module

-VOTARGET:=libvoAACEncv7

-

-

-# please modify here to be sure to see the g1.mk

-include ../../../../../Tools/eclair.mk 

-

-# dependent libraries.

-VODEPLIBS:=#-ldl -lstdc++ 

-

-# module source

-# please modify here to be sure to see the ms.mk which specifies all source info of your module

-include ../../ms.mk

-

-

-# please specify where is the voRelease on your PC, relative path is suggested

-VORELDIR:=../../../../../../Release

-

-

-# please modify here to be sure to see the doit.mk

-include ../../../../../Tools/doit.mk  

-

diff --git a/media/libstagefright/codecs/aacenc/build/eclair/makefile b/media/libstagefright/codecs/aacenc/build/eclair/makefile
deleted file mode 100644
index 6bb3c13..0000000
--- a/media/libstagefright/codecs/aacenc/build/eclair/makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-#/*
-#** Copyright 2003-2010, VisualOn, Inc.
-#**
-#** Licensed under the Apache License, Version 2.0 (the "License");
-#** you may not use this file except in compliance with the License.
-#** You may obtain a copy of the License at
-#**
-#**     http://www.apache.org/licenses/LICENSE-2.0
-#**
-#** Unless required by applicable law or agreed to in writing, software
-#** distributed under the License is distributed on an "AS IS" BASIS,
-#** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#** See the License for the specific language governing permissions and
-#** limitations under the License.
-#*/
-
-# Just acting as Father Makefile of Modules
-# please keep the name 'makefile' unchanged
- 
-# Module Subdirs
-VOMSD:=$(dir $(shell find . -name 'Makefile'))
-
-all:
-	for dir in $(VOMSD); \
-		do \
-			$(MAKE) -C $$dir; \
-		done
-
-.PHONY:clean devel
-clean:
-	for dir in $(VOMSD); \
-		do \
-			$(MAKE) -C $$dir clean; \
-		done
-
-devel:
-	for dir in $(VOMSD); \
-		do \
-			$(MAKE) -C $$dir devel; \
-		done
diff --git a/media/libstagefright/codecs/aacenc/build/ms.mk b/media/libstagefright/codecs/aacenc/build/ms.mk
deleted file mode 100644
index b67efbc..0000000
--- a/media/libstagefright/codecs/aacenc/build/ms.mk
+++ /dev/null
@@ -1,42 +0,0 @@
-#/*

-#** Copyright 2003-2010, VisualOn, Inc.

-#**

-#** Licensed under the Apache License, Version 2.0 (the "License");

-#** you may not use this file except in compliance with the License.

-#** You may obtain a copy of the License at

-#**

-#**     http://www.apache.org/licenses/LICENSE-2.0

-#**

-#** Unless required by applicable law or agreed to in writing, software

-#** distributed under the License is distributed on an "AS IS" BASIS,

-#** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-#** See the License for the specific language governing permissions and

-#** limitations under the License.

-#*/

-

-

-# please list all objects needed by your target here

-OBJS:=basicop2.o oper_32b.o aac_rom.o aacenc.o aacenc_core.o adj_thr.o \

-			band_nrg.o bit_cnt.o bitbuffer.o bitenc.o block_switch.o channel_map.o \

-			dyn_bits.o grp_data.o interface.o line_pe.o memalign.o ms_stereo.o \

-			pre_echo_control.o psy_configuration.o psy_main.o qc_main.o quantize.o sf_estim.o \

-			spreading.o stat_bits.o tns.o transform.o

-			

-# please list all directories that all source files relative with your module(.h .c .cpp) locate 

-VOSRCDIR:=../../../src \

-					../../../inc \

-					../../../basic_op\

-					../../../../../Include 

-					

-ifeq ($(VOTT), v5)

-OBJS+= AutoCorrelation_v5.o band_nrg_v5.o CalcWindowEnergy_v5.o \

-				PrePostMDCT_v5.o R4R8First_v5.o Radix4FFT_v5.o

-VOSRCDIR+= ../../../src/asm/ARMV5E/

-endif	

-

-ifeq ($(VOTT), v7)

-OBJS+= AutoCorrelation_v5.o band_nrg_v5.o CalcWindowEnergy_v5.o \

-			 PrePostMDCT_v7.o R4R8First_v7.o Radix4FFT_v7.o

-VOSRCDIR+= ../../../src/asm/ARMV5E/

-VOSRCDIR+= ../../../src/asm/ARMV7/

-endif		
\ No newline at end of file
diff --git a/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp b/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp
index fb300da..a11d46b 100644
--- a/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/AMRNBDecoder.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+//#define LOG_NDEBUG 0
+#define LOG_TAG "AMRNBDecoder"
+#include <utils/Log.h>
+
 #include "AMRNBDecoder.h"
 
 #include "gsmamr_dec.h"
@@ -154,18 +158,24 @@
     const uint8_t *inputPtr =
         (const uint8_t *)mInputBuffer->data() + mInputBuffer->range_offset();
 
-    size_t numBytesRead =
+    int32_t numBytesRead =
         AMRDecode(mState,
           (Frame_Type_3GPP)((inputPtr[0] >> 3) & 0x0f),
           (UWord8 *)&inputPtr[1],
           static_cast<int16_t *>(buffer->data()),
           MIME_IETF);
 
+    if (numBytesRead == -1 ) {
+        LOGE("PV AMR decoder AMRDecode() call failed");
+        buffer->release();
+        buffer = NULL;
+        return ERROR_MALFORMED;
+    }
     ++numBytesRead;  // Include the frame type header byte.
 
     buffer->set_range(0, kNumSamplesPerFrame * sizeof(int16_t));
 
-    if (numBytesRead > mInputBuffer->range_length()) {
+    if (static_cast<size_t>(numBytesRead) > mInputBuffer->range_length()) {
         // This is bad, should never have happened, but did. Abort now.
 
         buffer->release();
diff --git a/media/libstagefright/codecs/amrwbenc/Android.mk b/media/libstagefright/codecs/amrwbenc/Android.mk
index 4293287..5179380 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/Android.mk
@@ -2,7 +2,7 @@
 include $(CLEAR_VARS)
 include frameworks/base/media/libstagefright/codecs/common/Config.mk
 
-LOCAL_PRELINK_MODULE := false
+
  	
 LOCAL_SRC_FILES := \
 	AMRWBEncoder.cpp \
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
index 792d3cc..5e71a5b 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
@@ -129,7 +129,7 @@
 	useData.memData = (VO_PTR)(&moper);

 

 #ifdef LINUX

-	handle = dlopen("/data/local/tmp/voAMRWBEnc.so", RTLD_NOW);

+	handle = dlopen("libstagefright.so", RTLD_NOW);

 	if(handle == 0)

 	{

 		printf("open dll error......");

diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
index 7edb166..85ddceb 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
@@ -1,26 +1,26 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := 	AMRWB_E_SAMPLE.c
-	
-LOCAL_SRC_FILES += 	\
-	../../../Common/cmnMemory.c 
+LOCAL_SRC_FILES := \
+    AMRWB_E_SAMPLE.c \
+    ../../common/cmnMemory.c
 
-LOCAL_MODULE := TestvoAMRWBEnc
+LOCAL_MODULE_TAGS := debug
+LOCAL_MODULE := AMRWBEncTest
 
 LOCAL_ARM_MODE := arm
 
-LOCAL_STATIC_LIBRARIES := 
+LOCAL_CFLAGS := $(VO_CFLAGS)
 
-LOCAL_SHARED_LIBRARIES := libvoAMRWBEnc
+LOCAL_SHARED_LIBRARIES := \
+    libstagefright \
+    libdl
 
 LOCAL_C_INCLUDES := \
-	$(LOCAL_PATH)/ \
-	$(LOCAL_PATH)/../../../Common \
-	$(LOCAL_PATH)/../../../Include \
+    $(LOCAL_PATH)/ \
+    $(LOCAL_PATH)/../../common \
+    $(LOCAL_PATH)/../../common/include
 
-LOCAL_CFLAGS := $(VO_CFLAGS)
-	
 include $(BUILD_EXECUTABLE)
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/eclair/Makefile b/media/libstagefright/codecs/amrwbenc/SampleCode/eclair/Makefile
deleted file mode 100644
index 55b876a..0000000
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/eclair/Makefile
+++ /dev/null
@@ -1,56 +0,0 @@
-#/*

-# ** Copyright 2003-2010, VisualOn, Inc.

-# **

-# ** Licensed under the Apache License, Version 2.0 (the "License");

-# ** you may not use this file except in compliance with the License.

-# ** You may obtain a copy of the License at

-# **

-# **     http://www.apache.org/licenses/LICENSE-2.0

-# **

-# ** Unless required by applicable law or agreed to in writing, software

-# ** distributed under the License is distributed on an "AS IS" BASIS,

-# ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-# ** See the License for the specific language governing permissions and

-# ** limitations under the License.

-# */

-

-# target6

-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)

-VOTT:= v6

-

-

-# module type

-# please specify the type of your module: lib or exe

-VOMT:= exe

-

-

-# module macros

-# please append the additional macro definitions here for your module if necessary. 

-# e.g. -DVISUALON, macro VISUALON defined for your module 

-VOMM:= #ARMV5E

-

-

-

-# please specify the name of your module

-VOTARGET:= voAMRWBEnc_Test

-

-

-# please modify here to be sure to see the g1.mk

-include ../../../../Tools/eclair.mk 

-

-# dependent libraries.

-VODEPLIBS:=-ldl

-

-

-# module source

-# please modify here to be sure to see the ms.mk which specifies all source info of your module

-include ../ms.mk

-

-

-# please specify where is the voRelease on your PC, relative path is suggested

-VORELDIR:=../

-

-

-# please modify here to be sure to see the doit.mk

-include ../../../../Tools/doit.mk 

-

diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/ms.mk b/media/libstagefright/codecs/amrwbenc/SampleCode/ms.mk
deleted file mode 100644
index 74e8913..0000000
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/ms.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-#/*

-# ** Copyright 2003-2010, VisualOn, Inc.

-# **

-# ** Licensed under the Apache License, Version 2.0 (the "License");

-# ** you may not use this file except in compliance with the License.

-# ** You may obtain a copy of the License at

-# **

-# **     http://www.apache.org/licenses/LICENSE-2.0

-# **

-# ** Unless required by applicable law or agreed to in writing, software

-# ** distributed under the License is distributed on an "AS IS" BASIS,

-# ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-# ** See the License for the specific language governing permissions and

-# ** limitations under the License.

-# */

-# please list all objects needed by your target here

-OBJS:=AMRWB_E_SAMPLE.o cmnMemory.o

-			

-# please list all directories that all source files relative with your module(.h .c .cpp) locate 

-VOSRCDIR:=../ \

-          ../../../../Common \

-	  ../../../../Include

-					

-				

diff --git a/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV5E/Makefile b/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV5E/Makefile
deleted file mode 100644
index 58fda29..0000000
--- a/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV5E/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-#/*

-# ** Copyright 2003-2010, VisualOn, Inc.

-# **

-# ** Licensed under the Apache License, Version 2.0 (the "License");

-# ** you may not use this file except in compliance with the License.

-# ** You may obtain a copy of the License at

-# **

-# **     http://www.apache.org/licenses/LICENSE-2.0

-# **

-# ** Unless required by applicable law or agreed to in writing, software

-# ** distributed under the License is distributed on an "AS IS" BASIS,

-# ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-# ** See the License for the specific language governing permissions and

-# ** limitations under the License.

-# */

-

-# target type

-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)

-VOTT:= v5

-

-

-# module type

-# please specify the type of your module: lib or exe

-VOMT:= lib

-

-

-# module macros

-# please append the additional macro definitions here for your module if necessary. 

-ifeq ($(VOTT), v5)

-VOMM:=-DARM -DASM_OPT

-endif

-

-# please specify the name of your module

-VOTARGET:= libvoAMRWBEncv5

-

-

-# please modify here to be sure to see the g1.mk

-include ../../../../../Tools/eclair.mk 

-

-# dependent libraries.

-VODEPLIBS:=-ldl -lstdc++ -lcutils

-

-# module source

-# please modify here to be sure to see the ms.mk which specifies all source info of your module

-include ../ms.mk

-

-

-# please specify where is the voRelease on your PC, relative path is suggested

-VORELDIR:=../../../../../../Release

-

-# please modify here to be sure to see the doit.mk

-include ../../../../../Tools/doit.mk 

-

diff --git a/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV7/Makefile b/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV7/Makefile
deleted file mode 100644
index 5686411..0000000
--- a/media/libstagefright/codecs/amrwbenc/build/eclair/ARMV7/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-#/*

-# ** Copyright 2003-2010, VisualOn, Inc.

-# **

-# ** Licensed under the Apache License, Version 2.0 (the "License");

-# ** you may not use this file except in compliance with the License.

-# ** You may obtain a copy of the License at

-# **

-# **     http://www.apache.org/licenses/LICENSE-2.0

-# **

-# ** Unless required by applicable law or agreed to in writing, software

-# ** distributed under the License is distributed on an "AS IS" BASIS,

-# ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-# ** See the License for the specific language governing permissions and

-# ** limitations under the License.

-# */

-

-# target type

-# available: pc, v4(armv4), v5(armv5), v5x(armv5 xscale), v6(armv6), v7(cortex-a8 neon)

-VOTT:= v7

-

-

-# module type

-# please specify the type of your module: lib or exe

-VOMT:= lib

-

-

-# module macros

-# please append the additional macro definitions here for your module if necessary. 

-ifeq ($(VOTT), v7)

-VOMM:=-DARM -DARMV7 -DASM_OPT

-endif

-

-# please specify the name of your module

-VOTARGET:= libvoAMRWBEncv7

-

-

-# please modify here to be sure to see the g1.mk

-include ../../../../../Tools/eclair.mk 

-

-# dependent libraries.

-VODEPLIBS:=-ldl -lstdc++ -lcutils

-

-# module source

-# please modify here to be sure to see the ms.mk which specifies all source info of your module

-include ../ms.mk

-

-

-# please specify where is the voRelease on your PC, relative path is suggested

-VORELDIR:=../../../../../../Release

-

-# please modify here to be sure to see the doit.mk

-include ../../../../../Tools/doit.mk 

-

diff --git a/media/libstagefright/codecs/amrwbenc/build/eclair/makefile b/media/libstagefright/codecs/amrwbenc/build/eclair/makefile
deleted file mode 100644
index 3473a1a..0000000
--- a/media/libstagefright/codecs/amrwbenc/build/eclair/makefile
+++ /dev/null
@@ -1,39 +0,0 @@
-#/*
-# ** Copyright 2003-2010, VisualOn, Inc.
-# **
-# ** Licensed under the Apache License, Version 2.0 (the "License");
-# ** you may not use this file except in compliance with the License.
-# ** You may obtain a copy of the License at
-# **
-# **     http://www.apache.org/licenses/LICENSE-2.0
-# **
-# ** Unless required by applicable law or agreed to in writing, software
-# ** distributed under the License is distributed on an "AS IS" BASIS,
-# ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# ** See the License for the specific language governing permissions and
-# ** limitations under the License.
-# */
-# Just acting as Father Makefile of Modules
-# please keep the name 'makefile' unchanged
- 
-# Module Subdirs
-VOMSD:=$(dir $(shell find . -name 'Makefile'))
-
-all:
-	for dir in $(VOMSD); \
-		do \
-			$(MAKE) -C $$dir; \
-		done
-
-.PHONY:clean devel
-clean:
-	for dir in $(VOMSD); \
-		do \
-			$(MAKE) -C $$dir clean; \
-		done
-
-devel:
-	for dir in $(VOMSD); \
-		do \
-			$(MAKE) -C $$dir devel; \
-		done
diff --git a/media/libstagefright/codecs/amrwbenc/build/eclair/ms.mk b/media/libstagefright/codecs/amrwbenc/build/eclair/ms.mk
deleted file mode 100644
index bd6620c..0000000
--- a/media/libstagefright/codecs/amrwbenc/build/eclair/ms.mk
+++ /dev/null
@@ -1,43 +0,0 @@
-#/*

-# ** Copyright 2003-2010, VisualOn, Inc.

-# **

-# ** Licensed under the Apache License, Version 2.0 (the "License");

-# ** you may not use this file except in compliance with the License.

-# ** You may obtain a copy of the License at

-# **

-# **     http://www.apache.org/licenses/LICENSE-2.0

-# **

-# ** Unless required by applicable law or agreed to in writing, software

-# ** distributed under the License is distributed on an "AS IS" BASIS,

-# ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

-# ** See the License for the specific language governing permissions and

-# ** limitations under the License.

-# */

-# please list all directories that all source files relative with your module(.h .c .cpp) locate 

-VOSRCDIR:=../../../inc \

-          ../../../src \

-	  ../../../../../Include 

-

-# please list all objects needed by your target here

-OBJS:= autocorr.o az_isp.o bits.o c2t64fx.o c4t64fx.o convolve.o cor_h_x.o decim54.o \

-       deemph.o dtx.o g_pitch.o gpclip.o homing.o hp400.o hp50.o hp6k.o hp_wsp.o \

-       int_lpc.o isp_az.o isp_isf.o lag_wind.o levinson.o log2.o lp_dec2.o math_op.o mem_align.o \

-       oper_32b.o p_med_ol.o pit_shrp.o pitch_f4.o pred_lt4.o preemph.o q_gain2.o q_pulse.o \

-       qisf_ns.o qpisf_2s.o random.o residu.o scale.o stream.o syn_filt.o updt_tar.o util.o \

-       voAMRWBEnc.o voicefac.o wb_vad.o weight_a.o

-			

-

-ifeq ($(VOTT), v5)

-OBJS += cor_h_vec_opt.o Deemph_32_opt.o Dot_p_opt.o Filt_6k_7k_opt.o residu_asm_opt.o \

-       scale_sig_opt.o Syn_filt_32_opt.o syn_filt_opt.o pred_lt4_1_opt.o convolve_opt.o \

-       Norm_Corr_opt.o

-VOSRCDIR+= ../../../src/asm/ARMV5E

-endif

-

-ifeq ($(VOTT), v7)

-OBJS+= cor_h_vec_neon.o Deemph_32_neon.o Dot_p_neon.o Filt_6k_7k_neon.o residu_asm_neon.o \

-       scale_sig_neon.o Syn_filt_32_neon.o syn_filt_neon.o pred_lt4_1_neon.o convolve_neon.o \

-       Norm_Corr_neon.o

-VOSRCDIR+= ../../../src/asm/ARMV7

-endif

-

diff --git a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp b/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
index 5bbba35..490129f 100644
--- a/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
+++ b/media/libstagefright/codecs/avc/dec/AVCDecoder.cpp
@@ -534,7 +534,8 @@
             default:
             {
                 LOGE("Should not be here, unknown nalType %d", nalType);
-                CHECK(!"Should not be here");
+
+                err = ERROR_MALFORMED;
                 break;
             }
         }
diff --git a/media/libstagefright/codecs/common/Android.mk b/media/libstagefright/codecs/common/Android.mk
index fffb2ad..af8795a 100644
--- a/media/libstagefright/codecs/common/Android.mk
+++ b/media/libstagefright/codecs/common/Android.mk
@@ -1,7 +1,7 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
 
-LOCAL_PRELINK_MODULE := false
+
 
 LOCAL_SRC_FILES := cmnMemory.c
 
diff --git a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
index 59dd740..0ba42ff 100644
--- a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
+++ b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
@@ -14,6 +14,9 @@
  * limitations under the License.
  */
 
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MP3Decoder"
+
 #include "MP3Decoder.h"
 
 #include "include/pvmp3decoder_api.h"
@@ -175,7 +178,12 @@
             != NO_DECODING_ERROR) {
         LOGV("mp3 decoder returned error %d", decoderErr);
 
-        if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR) {
+        if (decoderErr != NO_ENOUGH_MAIN_DATA_ERROR ||
+                mConfig->outputFrameSize == 0) {
+
+            if (mConfig->outputFrameSize == 0) {
+                LOGE("Output frame size is 0");
+            }
             buffer->release();
             buffer = NULL;
 
diff --git a/media/libstagefright/foundation/Android.mk b/media/libstagefright/foundation/Android.mk
index 4e07f6f..d5025a1 100644
--- a/media/libstagefright/foundation/Android.mk
+++ b/media/libstagefright/foundation/Android.mk
@@ -25,6 +25,6 @@
 
 LOCAL_MODULE:= libstagefright_foundation
 
-LOCAL_PRELINK_MODULE:= false
+
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index f0cd6a0..8e1bdf3 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -23,7 +23,7 @@
 #include "LiveDataSource.h"
 
 #include "include/M3UParser.h"
-#include "include/NuHTTPDataSource.h"
+#include "include/HTTPBase.h"
 
 #include <cutils/properties.h>
 #include <media/stagefright/foundation/hexdump.h>
@@ -45,9 +45,9 @@
     : mFlags(flags),
       mDataSource(new LiveDataSource),
       mHTTPDataSource(
-              new NuHTTPDataSource(
+              HTTPBase::Create(
                   (mFlags & kFlagIncognito)
-                    ? NuHTTPDataSource::kFlagIncognito
+                    ? HTTPBase::kFlagIncognito
                     : 0)),
       mPrevBandwidthIndex(-1),
       mLastPlaylistFetchTimeUs(-1),
@@ -625,7 +625,12 @@
     } else {
         key = new ABuffer(16);
 
-        sp<NuHTTPDataSource> keySource = new NuHTTPDataSource;
+        sp<HTTPBase> keySource =
+              HTTPBase::Create(
+                  (mFlags & kFlagIncognito)
+                    ? HTTPBase::kFlagIncognito
+                    : 0);
+
         status_t err = keySource->connect(keyURI.c_str());
 
         if (err == OK) {
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 4e6f75c..a9b7ae8 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -18,7 +18,7 @@
 
 #define AWESOME_PLAYER_H_
 
-#include "NuHTTPDataSource.h"
+#include "HTTPBase.h"
 #include "TimedEventQueue.h"
 
 #include <media/MediaPlayerInterface.h>
@@ -93,7 +93,7 @@
     // This is a mask of MediaExtractor::Flags.
     uint32_t flags() const;
 
-    void postAudioEOS();
+    void postAudioEOS(int64_t delayUs = 0ll);
     void postAudioSeekComplete();
 
 private:
@@ -203,13 +203,13 @@
     void postVideoEvent_l(int64_t delayUs = -1);
     void postBufferingEvent_l();
     void postStreamDoneEvent_l(status_t status);
-    void postCheckAudioStatusEvent_l();
+    void postCheckAudioStatusEvent_l(int64_t delayUs);
     void postVideoLagEvent_l();
     status_t play_l();
 
     MediaBuffer *mVideoBuffer;
 
-    sp<NuHTTPDataSource> mConnectingDataSource;
+    sp<HTTPBase> mConnectingDataSource;
     sp<NuCachedSource2> mCachedSource;
 
     sp<ALooper> mLooper;
@@ -217,7 +217,7 @@
     sp<ARTSPController> mConnectingRTSPController;
 
     DrmManagerClient *mDrmManagerClient;
-    DecryptHandle *mDecryptHandle;
+    sp<DecryptHandle> mDecryptHandle;
 
     status_t setDataSource_l(
             const char *uri,
diff --git a/media/libstagefright/include/ChromiumHTTPDataSource.h b/media/libstagefright/include/ChromiumHTTPDataSource.h
new file mode 100644
index 0000000..af49059
--- /dev/null
+++ b/media/libstagefright/include/ChromiumHTTPDataSource.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CHROME_HTTP_DATA_SOURCE_H_
+
+#define CHROME_HTTP_DATA_SOURCE_H_
+
+#include <media/stagefright/foundation/AString.h>
+#include <utils/threads.h>
+
+#include "HTTPBase.h"
+
+namespace android {
+
+struct SfDelegate;
+
+struct ChromiumHTTPDataSource : public HTTPBase {
+    ChromiumHTTPDataSource(uint32_t flags = 0);
+
+    virtual status_t connect(
+            const char *uri,
+            const KeyedVector<String8, String8> *headers = NULL,
+            off64_t offset = 0);
+
+    virtual void disconnect();
+
+    virtual status_t initCheck() const;
+
+    virtual ssize_t readAt(off64_t offset, void *data, size_t size);
+    virtual status_t getSize(off64_t *size);
+    virtual uint32_t flags();
+
+    virtual bool estimateBandwidth(int32_t *bandwidth_bps);
+
+    virtual sp<DecryptHandle> DrmInitialization();
+
+    virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
+
+    virtual String8 getUri();
+
+protected:
+    virtual ~ChromiumHTTPDataSource();
+
+private:
+    friend struct SfDelegate;
+
+    enum State {
+        DISCONNECTED,
+        CONNECTING,
+        CONNECTED,
+        READING,
+        DISCONNECTING
+    };
+
+    struct BandwidthEntry {
+        int64_t mDelayUs;
+        size_t mNumBytes;
+    };
+
+    const uint32_t mFlags;
+
+    mutable Mutex mLock;
+    Condition mCondition;
+
+    State mState;
+
+    SfDelegate *mDelegate;
+
+    AString mURI;
+    KeyedVector<String8, String8> mHeaders;
+
+    off64_t mCurrentOffset;
+
+    // Any connection error or the result of a read operation
+    // (for the lattter this is the number of bytes read, if successful).
+    ssize_t mIOResult;
+
+    int64_t mContentSize;
+
+    List<BandwidthEntry> mBandwidthHistory;
+    size_t mNumBandwidthHistoryItems;
+    int64_t mTotalTransferTimeUs;
+    size_t mTotalTransferBytes;
+
+    sp<DecryptHandle> mDecryptHandle;
+    DrmManagerClient *mDrmManagerClient;
+
+    void disconnect_l();
+
+    status_t connect_l(
+            const char *uri,
+            const KeyedVector<String8, String8> *headers,
+            off64_t offset);
+
+    static void InitiateRead(
+            ChromiumHTTPDataSource *me, void *data, size_t size);
+
+    void initiateRead(void *data, size_t size);
+
+    void onConnectionEstablished(int64_t contentSize);
+    void onConnectionFailed(status_t err);
+    void onReadCompleted(ssize_t size);
+    void onDisconnectComplete();
+
+    void addBandwidthMeasurement_l(size_t numBytes, int64_t delayUs);
+
+    void clearDRMState_l();
+
+    DISALLOW_EVIL_CONSTRUCTORS(ChromiumHTTPDataSource);
+};
+
+}  // namespace android
+
+#endif  // CHROME_HTTP_DATA_SOURCE_H_
diff --git a/media/libstagefright/include/DRMExtractor.h b/media/libstagefright/include/DRMExtractor.h
index 9881cc1..b4e4afb 100644
--- a/media/libstagefright/include/DRMExtractor.h
+++ b/media/libstagefright/include/DRMExtractor.h
@@ -45,7 +45,7 @@
     sp<DataSource> mDataSource;
 
     sp<MediaExtractor> mOriginalExtractor;
-    DecryptHandle* mDecryptHandle;
+    sp<DecryptHandle> mDecryptHandle;
     DrmManagerClient* mDrmManagerClient;
 
     DRMExtractor(const DRMExtractor &);
diff --git a/media/libstagefright/include/HTTPBase.h b/media/libstagefright/include/HTTPBase.h
new file mode 100644
index 0000000..6cec390
--- /dev/null
+++ b/media/libstagefright/include/HTTPBase.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef HTTP_BASE_H_
+
+#define HTTP_BASE_H_
+
+#include <media/stagefright/foundation/ABase.h>
+#include <media/stagefright/DataSource.h>
+
+namespace android {
+
+struct HTTPBase : public DataSource {
+    enum Flags {
+        // Don't log any URLs.
+        kFlagIncognito = 1
+    };
+
+    HTTPBase();
+
+    virtual status_t connect(
+            const char *uri,
+            const KeyedVector<String8, String8> *headers = NULL,
+            off64_t offset = 0) = 0;
+
+    virtual void disconnect() = 0;
+
+    // Returns true if bandwidth could successfully be estimated,
+    // false otherwise.
+    virtual bool estimateBandwidth(int32_t *bandwidth_bps) = 0;
+
+    static sp<HTTPBase> Create(uint32_t flags = 0);
+
+private:
+    DISALLOW_EVIL_CONSTRUCTORS(HTTPBase);
+};
+
+}  // namespace android
+
+#endif  // HTTP_BASE_H_
diff --git a/media/libstagefright/include/LiveSession.h b/media/libstagefright/include/LiveSession.h
index 3fe5d4e..2b5ea0e 100644
--- a/media/libstagefright/include/LiveSession.h
+++ b/media/libstagefright/include/LiveSession.h
@@ -26,7 +26,7 @@
 struct DataSource;
 struct LiveDataSource;
 struct M3UParser;
-struct NuHTTPDataSource;
+struct HTTPBase;
 
 struct LiveSession : public AHandler {
     enum Flags {
@@ -75,7 +75,7 @@
 
     sp<LiveDataSource> mDataSource;
 
-    sp<NuHTTPDataSource> mHTTPDataSource;
+    sp<HTTPBase> mHTTPDataSource;
 
     AString mMasterURL;
     Vector<BandwidthItem> mBandwidthItems;
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index 04e8a6a..d9ef208 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -57,7 +57,7 @@
     };
 
     sp<DataSource> mDataSource;
-    bool mHaveMetadata;
+    status_t mInitCheck;
     bool mHasVideo;
 
     Track *mFirstTrack, *mLastTrack;
@@ -90,6 +90,10 @@
 
     status_t parseTrackHeader(off64_t data_offset, off64_t data_size);
 
+    Track *findTrackByMimePrefix(const char *mimePrefix);
+
+    status_t verifyIfStreamable();
+
     MPEG4Extractor(const MPEG4Extractor &);
     MPEG4Extractor &operator=(const MPEG4Extractor &);
 };
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index 022804c..02d5817 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -37,8 +37,8 @@
     virtual status_t getSize(off64_t *size);
     virtual uint32_t flags();
 
-    virtual DecryptHandle* DrmInitialization();
-    virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client);
+    virtual sp<DecryptHandle> DrmInitialization();
+    virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
     virtual String8 getUri();
     ////////////////////////////////////////////////////////////////////////////
 
diff --git a/media/libstagefright/include/NuHTTPDataSource.h b/media/libstagefright/include/NuHTTPDataSource.h
index 2569568..7dd5d59 100644
--- a/media/libstagefright/include/NuHTTPDataSource.h
+++ b/media/libstagefright/include/NuHTTPDataSource.h
@@ -18,28 +18,24 @@
 
 #define NU_HTTP_DATA_SOURCE_H_
 
-#include <media/stagefright/DataSource.h>
 #include <utils/List.h>
 #include <utils/String8.h>
 #include <utils/threads.h>
 
 #include "HTTPStream.h"
+#include "include/HTTPBase.h"
 
 namespace android {
 
-struct NuHTTPDataSource : public DataSource {
-    enum Flags {
-        // Don't log any URLs.
-        kFlagIncognito = 1
-    };
+struct NuHTTPDataSource : public HTTPBase {
     NuHTTPDataSource(uint32_t flags = 0);
 
-    status_t connect(
+    virtual status_t connect(
             const char *uri,
             const KeyedVector<String8, String8> *headers = NULL,
             off64_t offset = 0);
 
-    void disconnect();
+    virtual void disconnect();
 
     virtual status_t initCheck() const;
 
@@ -49,10 +45,10 @@
 
     // Returns true if bandwidth could successfully be estimated,
     // false otherwise.
-    bool estimateBandwidth(int32_t *bandwidth_bps);
+    virtual bool estimateBandwidth(int32_t *bandwidth_bps);
 
-    virtual DecryptHandle* DrmInitialization();
-    virtual void getDrmInfo(DecryptHandle **handle, DrmManagerClient **client);
+    virtual sp<DecryptHandle> DrmInitialization();
+    virtual void getDrmInfo(sp<DecryptHandle> &handle, DrmManagerClient **client);
     virtual String8 getUri();
 
 protected:
@@ -98,7 +94,7 @@
     int64_t mTotalTransferTimeUs;
     size_t mTotalTransferBytes;
 
-    DecryptHandle *mDecryptHandle;
+    sp<DecryptHandle> mDecryptHandle;
     DrmManagerClient *mDrmManagerClient;
 
     status_t connect(
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h
index 07b1ec8..b02ed0e 100644
--- a/media/libstagefright/include/StagefrightMetadataRetriever.h
+++ b/media/libstagefright/include/StagefrightMetadataRetriever.h
@@ -32,7 +32,10 @@
     StagefrightMetadataRetriever();
     virtual ~StagefrightMetadataRetriever();
 
-    virtual status_t setDataSource(const char *url);
+    virtual status_t setDataSource(
+            const char *url,
+            const KeyedVector<String8, String8> *headers);
+
     virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
 
     virtual VideoFrame *getFrameAtTime(int64_t timeUs, int option);
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 733de92b..b3e29b9 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -60,7 +60,10 @@
     virtual int Length(long long* total, long long* available) {
         off64_t size;
         if (mSource->getSize(&size) != OK) {
-            return -1;
+            *total = -1;
+            *available = (long long)((1ull << 63) - 1);
+
+            return 0;
         }
 
         if (total) {
@@ -84,7 +87,7 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 struct BlockIterator {
-    BlockIterator(mkvparser::Segment *segment, unsigned long trackNum);
+    BlockIterator(MatroskaExtractor *extractor, unsigned long trackNum);
 
     bool eos() const;
 
@@ -96,11 +99,14 @@
     int64_t blockTimeUs() const;
 
 private:
-    mkvparser::Segment *mSegment;
+    MatroskaExtractor *mExtractor;
     unsigned long mTrackNum;
 
-    mkvparser::Cluster *mCluster;
+    const mkvparser::Cluster *mCluster;
     const mkvparser::BlockEntry *mBlockEntry;
+    long mBlockEntryIndex;
+
+    void advance_l();
 
     BlockIterator(const BlockIterator &);
     BlockIterator &operator=(const BlockIterator &);
@@ -150,7 +156,7 @@
     : mExtractor(extractor),
       mTrackIndex(index),
       mType(OTHER),
-      mBlockIter(mExtractor->mSegment,
+      mBlockIter(mExtractor.get(),
                  mExtractor->mTracks.itemAt(index).mTrackNum),
       mNALSizeLen(0) {
     sp<MetaData> meta = mExtractor->mTracks.itemAt(index).mMeta;
@@ -199,11 +205,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 BlockIterator::BlockIterator(
-        mkvparser::Segment *segment, unsigned long trackNum)
-    : mSegment(segment),
+        MatroskaExtractor *extractor, unsigned long trackNum)
+    : mExtractor(extractor),
       mTrackNum(trackNum),
       mCluster(NULL),
-      mBlockEntry(NULL) {
+      mBlockEntry(NULL),
+      mBlockEntryIndex(0) {
     reset();
 }
 
@@ -212,45 +219,97 @@
 }
 
 void BlockIterator::advance() {
-    while (!eos()) {
-        if (mBlockEntry != NULL) {
-            mBlockEntry = mCluster->GetNext(mBlockEntry);
-        } else if (mCluster != NULL) {
-            mCluster = mSegment->GetNext(mCluster);
+    Mutex::Autolock autoLock(mExtractor->mLock);
+    advance_l();
+}
 
-            if (eos()) {
+void BlockIterator::advance_l() {
+    for (;;) {
+        long res = mCluster->GetEntry(mBlockEntryIndex, mBlockEntry);
+        LOGV("GetEntry returned %ld", res);
+
+        long long pos;
+        long len;
+        if (res < 0) {
+            // Need to parse this cluster some more
+
+            CHECK_EQ(res, mkvparser::E_BUFFER_NOT_FULL);
+
+            res = mCluster->Parse(pos, len);
+            LOGV("Parse returned %ld", res);
+
+            if (res < 0) {
+                // I/O error
+
+                LOGE("Cluster::Parse returned result %ld", res);
+
+                mCluster = NULL;
                 break;
             }
 
-            mBlockEntry = mCluster->GetFirst();
+            continue;
+        } else if (res == 0) {
+            // We're done with this cluster
+
+            const mkvparser::Cluster *nextCluster;
+            res = mExtractor->mSegment->ParseNext(
+                    mCluster, nextCluster, pos, len);
+            LOGV("ParseNext returned %ld", res);
+
+            if (res > 0) {
+                // EOF
+
+                mCluster = NULL;
+                break;
+            }
+
+            CHECK_EQ(res, 0);
+            CHECK(nextCluster != NULL);
+            CHECK(!nextCluster->EOS());
+
+            mCluster = nextCluster;
+
+            res = mCluster->Parse(pos, len);
+            LOGV("Parse (2) returned %ld", res);
+            CHECK_GE(res, 0);
+
+            mBlockEntryIndex = 0;
+            continue;
         }
 
-        if (mBlockEntry != NULL
-                && mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) {
+        CHECK(mBlockEntry != NULL);
+        CHECK(mBlockEntry->GetBlock() != NULL);
+        ++mBlockEntryIndex;
+
+        if (mBlockEntry->GetBlock()->GetTrackNumber() == mTrackNum) {
             break;
         }
     }
 }
 
 void BlockIterator::reset() {
-    mCluster = mSegment->GetFirst();
-    mBlockEntry = mCluster->GetFirst();
+    Mutex::Autolock autoLock(mExtractor->mLock);
 
-    while (!eos() && block()->GetTrackNumber() != mTrackNum) {
-        advance();
-    }
+    mCluster = mExtractor->mSegment->GetFirst();
+    mBlockEntryIndex = 0;
+
+    do {
+        advance_l();
+    } while (!eos() && block()->GetTrackNumber() != mTrackNum);
 }
 
 void BlockIterator::seek(int64_t seekTimeUs) {
-    mCluster = mSegment->FindCluster(seekTimeUs * 1000ll);
-    mBlockEntry = mCluster != NULL ? mCluster->GetFirst() : NULL;
+    Mutex::Autolock autoLock(mExtractor->mLock);
+
+    mCluster = mExtractor->mSegment->FindCluster(seekTimeUs * 1000ll);
+    mBlockEntryIndex = 0;
 
     while (!eos() && block()->GetTrackNumber() != mTrackNum) {
-        advance();
+        advance_l();
     }
 
     while (!eos() && !mBlockEntry->GetBlock()->IsKey()) {
-        advance();
+        advance_l();
     }
 }
 
@@ -291,16 +350,6 @@
     }
 }
 
-#define BAIL(err) \
-    do {                        \
-        if (bigbuf) {           \
-            bigbuf->release();  \
-            bigbuf = NULL;      \
-        }                       \
-                                \
-        return err;             \
-    } while (0)
-
 status_t MatroskaSource::readBlock() {
     CHECK(mPendingFrames.empty());
 
@@ -310,181 +359,39 @@
 
     const mkvparser::Block *block = mBlockIter.block();
 
-    size_t size = block->GetSize();
     int64_t timeUs = mBlockIter.blockTimeUs();
-    int32_t isSync = block->IsKey();
 
-    MediaBuffer *bigbuf = new MediaBuffer(size);
+    for (int i = 0; i < block->GetFrameCount(); ++i) {
+        const mkvparser::Block::Frame &frame = block->GetFrame(i);
 
-    long res = block->Read(
-            mExtractor->mReader, (unsigned char *)bigbuf->data());
+        MediaBuffer *mbuf = new MediaBuffer(frame.len);
+        mbuf->meta_data()->setInt64(kKeyTime, timeUs);
+        mbuf->meta_data()->setInt32(kKeyIsSyncFrame, block->IsKey());
 
-    if (res != 0) {
-        bigbuf->release();
-        bigbuf = NULL;
+        long n = frame.Read(mExtractor->mReader, (unsigned char *)mbuf->data());
+        if (n != 0) {
+            mPendingFrames.clear();
 
-        return ERROR_END_OF_STREAM;
+            mBlockIter.advance();
+            return ERROR_IO;
+        }
+
+        mPendingFrames.push_back(mbuf);
     }
 
     mBlockIter.advance();
 
-    bigbuf->meta_data()->setInt64(kKeyTime, timeUs);
-    bigbuf->meta_data()->setInt32(kKeyIsSyncFrame, isSync);
-
-    unsigned lacing = (block->Flags() >> 1) & 3;
-
-    if (lacing == 0) {
-        mPendingFrames.push_back(bigbuf);
-        return OK;
-    }
-
-    LOGV("lacing = %u, size = %d", lacing, size);
-
-    const uint8_t *data = (const uint8_t *)bigbuf->data();
-    // hexdump(data, size);
-
-    if (size == 0) {
-        BAIL(ERROR_MALFORMED);
-    }
-
-    unsigned numFrames = (unsigned)data[0] + 1;
-    ++data;
-    --size;
-
-    Vector<uint64_t> frameSizes;
-
-    switch (lacing) {
-        case 1:  // Xiph
-        {
-            for (size_t i = 0; i < numFrames - 1; ++i) {
-                size_t frameSize = 0;
-                uint8_t byte;
-                do {
-                    if (size == 0) {
-                        BAIL(ERROR_MALFORMED);
-                    }
-                    byte = data[0];
-                    ++data;
-                    --size;
-
-                    frameSize += byte;
-                } while (byte == 0xff);
-
-                frameSizes.push(frameSize);
-            }
-
-            break;
-        }
-
-        case 2:  // fixed-size
-        {
-            if ((size % numFrames) != 0) {
-                BAIL(ERROR_MALFORMED);
-            }
-
-            size_t frameSize = size / numFrames;
-            for (size_t i = 0; i < numFrames - 1; ++i) {
-                frameSizes.push(frameSize);
-            }
-
-            break;
-        }
-
-        case 3:  // EBML
-        {
-            uint64_t lastFrameSize = 0;
-            for (size_t i = 0; i < numFrames - 1; ++i) {
-                uint8_t byte;
-
-                if (size == 0) {
-                    BAIL(ERROR_MALFORMED);
-                }
-                byte = data[0];
-                ++data;
-                --size;
-
-                size_t numLeadingZeroes = clz(byte);
-
-                uint64_t frameSize = byte & ~(0x80 >> numLeadingZeroes);
-                for (size_t j = 0; j < numLeadingZeroes; ++j) {
-                    if (size == 0) {
-                        BAIL(ERROR_MALFORMED);
-                    }
-
-                    frameSize = frameSize << 8;
-                    frameSize |= data[0];
-                    ++data;
-                    --size;
-                }
-
-                if (i == 0) {
-                    frameSizes.push(frameSize);
-                } else {
-                    size_t shift =
-                        7 - numLeadingZeroes + 8 * numLeadingZeroes;
-
-                    int64_t delta =
-                        (int64_t)frameSize - (1ll << (shift - 1)) + 1;
-
-                    frameSize = lastFrameSize + delta;
-
-                    frameSizes.push(frameSize);
-                }
-
-                lastFrameSize = frameSize;
-            }
-            break;
-        }
-
-        default:
-            TRESPASS();
-    }
-
-#if 0
-    AString out;
-    for (size_t i = 0; i < frameSizes.size(); ++i) {
-        if (i > 0) {
-            out.append(", ");
-        }
-        out.append(StringPrintf("%llu", frameSizes.itemAt(i)));
-    }
-    LOGV("sizes = [%s]", out.c_str());
-#endif
-
-    for (size_t i = 0; i < frameSizes.size(); ++i) {
-        uint64_t frameSize = frameSizes.itemAt(i);
-
-        if (size < frameSize) {
-            BAIL(ERROR_MALFORMED);
-        }
-
-        MediaBuffer *mbuf = new MediaBuffer(frameSize);
-        mbuf->meta_data()->setInt64(kKeyTime, timeUs);
-        mbuf->meta_data()->setInt32(kKeyIsSyncFrame, isSync);
-        memcpy(mbuf->data(), data, frameSize);
-        mPendingFrames.push_back(mbuf);
-
-        data += frameSize;
-        size -= frameSize;
-    }
-
-    size_t offset = bigbuf->range_length() - size;
-    bigbuf->set_range(offset, size);
-
-    mPendingFrames.push_back(bigbuf);
-
     return OK;
 }
 
-#undef BAIL
-
 status_t MatroskaSource::read(
         MediaBuffer **out, const ReadOptions *options) {
     *out = NULL;
 
     int64_t seekTimeUs;
     ReadOptions::SeekMode mode;
-    if (options && options->getSeekTo(&seekTimeUs, &mode)) {
+    if (options && options->getSeekTo(&seekTimeUs, &mode)
+            && !mExtractor->isLiveStreaming()) {
         clearPendingFrames();
         mBlockIter.seek(seekTimeUs);
     }
@@ -584,6 +491,13 @@
       mReader(new DataSourceReader(mDataSource)),
       mSegment(NULL),
       mExtractedThumbnails(false) {
+    off64_t size;
+    mIsLiveStreaming =
+        (mDataSource->flags()
+            & (DataSource::kWantsPrefetching
+                | DataSource::kIsCachingDataSource))
+        && mDataSource->getSize(&size) != OK;
+
     mkvparser::EBMLHeader ebmlHeader;
     long long pos;
     if (ebmlHeader.Parse(mReader, pos) < 0) {
@@ -598,7 +512,16 @@
         return;
     }
 
-    ret = mSegment->Load();
+    if (isLiveStreaming()) {
+        ret = mSegment->ParseHeaders();
+        CHECK_EQ(ret, 0);
+
+        long len;
+        ret = mSegment->LoadCluster(pos, len);
+        CHECK_EQ(ret, 0);
+    } else {
+        ret = mSegment->Load();
+    }
 
     if (ret < 0) {
         delete mSegment;
@@ -635,7 +558,8 @@
         return NULL;
     }
 
-    if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails) {
+    if ((flags & kIncludeExtensiveMetaData) && !mExtractedThumbnails
+            && !isLiveStreaming()) {
         findThumbnails();
         mExtractedThumbnails = true;
     }
@@ -643,6 +567,10 @@
     return mTracks.itemAt(index).mMeta;
 }
 
+bool MatroskaExtractor::isLiveStreaming() const {
+    return mIsLiveStreaming;
+}
+
 static void addESDSFromAudioSpecificInfo(
         const sp<MetaData> &meta, const void *asi, size_t asiSize) {
     static const uint8_t kStaticESDS[] = {
@@ -794,7 +722,7 @@
             continue;
         }
 
-        BlockIterator iter(mSegment, info->mTrackNum);
+        BlockIterator iter(this, info->mTrackNum);
         int32_t i = 0;
         int64_t thumbnailTimeUs = 0;
         size_t maxBlockSize = 0;
@@ -802,7 +730,11 @@
             if (iter.block()->IsKey()) {
                 ++i;
 
-                size_t blockSize = iter.block()->GetSize();
+                size_t blockSize = 0;
+                for (int i = 0; i < iter.block()->GetFrameCount(); ++i) {
+                    blockSize += iter.block()->GetFrame(i).len;
+                }
+
                 if (blockSize > maxBlockSize) {
                     maxBlockSize = blockSize;
                     thumbnailTimeUs = iter.blockTimeUs();
@@ -821,6 +753,15 @@
     return meta;
 }
 
+uint32_t MatroskaExtractor::flags() const {
+    uint32_t x = CAN_PAUSE;
+    if (!isLiveStreaming()) {
+        x |= CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK;
+    }
+
+    return x;
+}
+
 bool SniffMatroska(
         const sp<DataSource> &source, String8 *mimeType, float *confidence,
         sp<AMessage> *) {
diff --git a/media/libstagefright/matroska/MatroskaExtractor.h b/media/libstagefright/matroska/MatroskaExtractor.h
index fa20b84..38ebd61 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.h
+++ b/media/libstagefright/matroska/MatroskaExtractor.h
@@ -20,6 +20,7 @@
 
 #include <media/stagefright/MediaExtractor.h>
 #include <utils/Vector.h>
+#include <utils/threads.h>
 
 namespace mkvparser {
 struct Segment;
@@ -45,26 +46,34 @@
 
     virtual sp<MetaData> getMetaData();
 
+    virtual uint32_t flags() const;
+
 protected:
     virtual ~MatroskaExtractor();
 
 private:
     friend struct MatroskaSource;
+    friend struct BlockIterator;
 
     struct TrackInfo {
         unsigned long mTrackNum;
         sp<MetaData> mMeta;
     };
+
+    Mutex mLock;
     Vector<TrackInfo> mTracks;
 
     sp<DataSource> mDataSource;
     DataSourceReader *mReader;
     mkvparser::Segment *mSegment;
     bool mExtractedThumbnails;
+    bool mIsLiveStreaming;
 
     void addTracks();
     void findThumbnails();
 
+    bool isLiveStreaming() const;
+
     MatroskaExtractor(const MatroskaExtractor &);
     MatroskaExtractor &operator=(const MatroskaExtractor &);
 };
diff --git a/media/libstagefright/yuv/Android.mk b/media/libstagefright/yuv/Android.mk
index 7697e3c..a4253f6 100644
--- a/media/libstagefright/yuv/Android.mk
+++ b/media/libstagefright/yuv/Android.mk
@@ -10,6 +10,6 @@
 
 LOCAL_MODULE:= libstagefright_yuv
 
-LOCAL_PRELINK_MODULE := false
+
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 2b08ab5..2702242 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1738,7 +1738,10 @@
                     LOGV("BUFFER TIMEOUT: remove(%d) from active list on thread %p", track->name(), this);
                     tracksToRemove->add(track);
                     // indicate to client process that the track was disabled because of underrun
-                    cblk->flags |= CBLK_DISABLED_ON;
+                    {
+                        AutoMutex _l(cblk->lock);
+                        cblk->flags |= CBLK_DISABLED_ON;
+                    }
                 } else if (mixerStatus != MIXER_TRACKS_READY) {
                     mixerStatus = MIXER_TRACKS_ENABLED;
                 }
@@ -1787,10 +1790,9 @@
     for (size_t i = 0; i < size; i++) {
         sp<Track> t = mTracks[i];
         if (t->type() == streamType) {
-            t->mCblk->lock.lock();
+            AutoMutex _lcblk(t->mCblk->lock);
             t->mCblk->flags |= CBLK_INVALID_ON;
             t->mCblk->cv.signal();
-            t->mCblk->lock.unlock();
         }
     }
 }
@@ -2948,6 +2950,7 @@
 
     if (mCblk->framesReady() >= mCblk->frameCount ||
             (mCblk->flags & CBLK_FORCEREADY_MSK)) {
+        AutoMutex _l(mCblk->lock);
         mFillingUpStatus = FS_FILLED;
         mCblk->flags &= ~CBLK_FORCEREADY_MSK;
         return true;
@@ -3063,19 +3066,18 @@
         // STOPPED state
         mState = STOPPED;
 
-        mCblk->lock.lock();
         // NOTE: reset() will reset cblk->user and cblk->server with
         // the risk that at the same time, the AudioMixer is trying to read
         // data. In this case, getNextBuffer() would return a NULL pointer
         // as audio buffer => the AudioMixer code MUST always test that pointer
         // returned by getNextBuffer() is not NULL!
         reset();
-        mCblk->lock.unlock();
     }
 }
 
 void AudioFlinger::PlaybackThread::Track::reset()
 {
+    AutoMutex _l(mCblk->lock);
     // Do not reset twice to avoid discarding data written just after a flush and before
     // the audioflinger thread detects the track is stopped.
     if (!mResetDone) {
@@ -3209,10 +3211,13 @@
     if (thread != 0) {
         RecordThread *recordThread = (RecordThread *)thread.get();
         recordThread->stop(this);
-        TrackBase::reset();
-        // Force overerrun condition to avoid false overrun callback until first data is
-        // read from buffer
-        mCblk->flags |= CBLK_UNDERRUN_ON;
+        {
+            AutoMutex _l(mCblk->lock);
+            TrackBase::reset();
+            // Force overerrun condition to avoid false overrun callback until first data is
+            // read from buffer
+            mCblk->flags |= CBLK_UNDERRUN_ON;
+        }
     }
 }
 
diff --git a/services/camera/libcameraservice/Android.mk b/services/camera/libcameraservice/Android.mk
index b52fc69..14f1e8b 100644
--- a/services/camera/libcameraservice/Android.mk
+++ b/services/camera/libcameraservice/Android.mk
@@ -49,7 +49,6 @@
     libcutils \
     libmedia \
     libcamera_client \
-    libsurfaceflinger_client \
     libgui
 
 LOCAL_MODULE:= libcameraservice
diff --git a/services/camera/tests/CameraServiceTest/Android.mk b/services/camera/tests/CameraServiceTest/Android.mk
index cf4e42f..cf7302a 100644
--- a/services/camera/tests/CameraServiceTest/Android.mk
+++ b/services/camera/tests/CameraServiceTest/Android.mk
@@ -19,7 +19,7 @@
                 libutils \
                 libui \
                 libcamera_client \
-                libsurfaceflinger_client
+                libgui
 
 # Disable it because the ISurface interface may change, and before we have a
 # chance to fix this test, we don't want to break normal builds.