am dd6a1764: am c08872f9: Merge "NuPlayerRenderer: handle error when resuming an offloaded track" into mnc-dev

* commit 'dd6a17649106fd48b0e69703d339bbc5a1ae9a0b':
  NuPlayerRenderer: handle error when resuming an offloaded track
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index 9765f0d..dbf524e 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -240,7 +240,7 @@
         } break;
         case SET_DATA_SOURCE_FD: {
             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
-            int fd = dup(data.readFileDescriptor());
+            int fd = data.readFileDescriptor();
             int64_t offset = data.readInt64();
             int64_t length = data.readInt64();
             reply->writeInt32(setDataSource(fd, offset, length));
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index c5790fb..2a17696 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -23,7 +23,7 @@
 #include <utils/Log.h>
 #include <utils/Vector.h>
 #include <cutils/properties.h>
-#include <libexpat/expat.h>
+#include <expat.h>
 #include <media/MediaProfiles.h>
 #include <media/stagefright/foundation/ADebug.h>
 #include <OMX_Video.h>
diff --git a/media/libmediaplayerservice/Drm.cpp b/media/libmediaplayerservice/Drm.cpp
index a7f6f8b..b9cfe80 100644
--- a/media/libmediaplayerservice/Drm.cpp
+++ b/media/libmediaplayerservice/Drm.cpp
@@ -40,9 +40,6 @@
 }
 
 static bool checkPermission(const char* permissionString) {
-#ifndef HAVE_ANDROID_OS
-    return true;
-#endif
     if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
     bool ok = checkCallingPermission(String16(permissionString));
     if (!ok) ALOGE("Request requires %s", permissionString);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 56521a2..05a65a3 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -253,9 +253,6 @@
 
 
 static bool checkPermission(const char* permissionString) {
-#ifndef HAVE_ANDROID_OS
-    return true;
-#endif
     if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
     bool ok = checkCallingPermission(String16(permissionString));
     if (!ok) ALOGE("Request requires %s", permissionString);
@@ -749,7 +746,6 @@
 
     if (offset >= sb.st_size) {
         ALOGE("offset error");
-        ::close(fd);
         return UNKNOWN_ERROR;
     }
     if (offset + length > sb.st_size) {
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index f761dec..08c7899 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -46,9 +46,6 @@
 const char* recordAudioPermission = "android.permission.RECORD_AUDIO";
 
 static bool checkPermission(const char* permissionString) {
-#ifndef HAVE_ANDROID_OS
-    return true;
-#endif
     if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
     bool ok = checkCallingPermission(String16(permissionString));
     if (!ok) ALOGE("Request requires %s", permissionString);
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index a5a1fa5..b45fd4f 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -149,7 +149,6 @@
 
     if (offset >= sb.st_size) {
         ALOGE("offset (%lld) bigger than file size (%llu)", offset, sb.st_size);
-        ::close(fd);
         return BAD_VALUE;
     }
     if (offset + length > sb.st_size) {
@@ -165,12 +164,10 @@
     ALOGV("player type = %d", playerType);
     sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
     if (p == NULL) {
-        ::close(fd);
         return NO_INIT;
     }
     status_t status = p->setDataSource(fd, offset, length);
     if (status == NO_ERROR) mRetriever = p;
-    ::close(fd);
     return status;
 }
 
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index 3fedd9b..8fc4b29 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -64,7 +64,7 @@
 // the method returns, if you want to keep it, dup it!
 status_t StagefrightPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
     ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length);
-    return mPlayer->setDataSource(dup(fd), offset, length);
+    return mPlayer->setDataSource(fd, offset, length);
 }
 
 status_t StagefrightPlayer::setDataSource(const sp<IStreamSource> &source) {
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 4e6c2a6..b451021 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -343,6 +343,7 @@
 
     reset_l();
 
+    fd = dup(fd);
     sp<DataSource> dataSource = new FileSource(fd, offset, length);
 
     status_t err = dataSource->initCheck();
diff --git a/media/libstagefright/MediaCodecList.cpp b/media/libstagefright/MediaCodecList.cpp
index 5edc04c..c657195 100644
--- a/media/libstagefright/MediaCodecList.cpp
+++ b/media/libstagefright/MediaCodecList.cpp
@@ -39,7 +39,7 @@
 #include <utils/threads.h>
 
 #include <cutils/properties.h>
-#include <libexpat/expat.h>
+#include <expat.h>
 
 namespace android {
 
diff --git a/media/libstagefright/codecs/amrnb/common/Android.mk b/media/libstagefright/codecs/amrnb/common/Android.mk
index 5e632a6..80b67bb 100644
--- a/media/libstagefright/codecs/amrnb/common/Android.mk
+++ b/media/libstagefright/codecs/amrnb/common/Android.mk
@@ -7,7 +7,6 @@
  	src/bitno_tab.cpp \
  	src/bitreorder_tab.cpp \
  	src/bits2prm.cpp \
- 	src/bytesused.cpp \
  	src/c2_9pf_tab.cpp \
  	src/copy.cpp \
  	src/div_32.cpp \
@@ -38,7 +37,6 @@
  	src/mult_r.cpp \
  	src/norm_l.cpp \
  	src/norm_s.cpp \
- 	src/overflow_tbl.cpp \
  	src/ph_disp_tab.cpp \
  	src/pow2.cpp \
  	src/pow2_tbl.cpp \
diff --git a/media/libstagefright/codecs/amrnb/common/include/bytesused.h b/media/libstagefright/codecs/amrnb/common/include/bytesused.h
deleted file mode 100644
index 934efbe..0000000
--- a/media/libstagefright/codecs/amrnb/common/include/bytesused.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
-    3GPP TS 26.073
-    ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
-    Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Pathname: .audio/gsm-amr/c/include/BytesUsed.h
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Added #ifdef __cplusplus after Include section.
-
- Who:                       Date:
- Description:
-
-------------------------------------------------------------------------------
- INCLUDE DESCRIPTION
-
- This file declares a table BytesUsed.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; CONTINUE ONLY IF NOT ALREADY DEFINED
-----------------------------------------------------------------------------*/
-#ifndef BYTESUSED_H
-#define BYTESUSED_H
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-    /*----------------------------------------------------------------------------
-    ; MACROS
-    ; Define module specific macros here
-    ----------------------------------------------------------------------------*/
-
-    /*----------------------------------------------------------------------------
-    ; DEFINES
-    ; Include all pre-processor statements here.
-    ----------------------------------------------------------------------------*/
-
-    /*----------------------------------------------------------------------------
-    ; EXTERNAL VARIABLES REFERENCES
-    ; Declare variables used in this module but defined elsewhere
-    ----------------------------------------------------------------------------*/
-    extern const short BytesUsed[];
-
-    /*----------------------------------------------------------------------------
-    ; SIMPLE TYPEDEF'S
-    ----------------------------------------------------------------------------*/
-
-    /*----------------------------------------------------------------------------
-    ; ENUMERATED TYPEDEF'S
-    ----------------------------------------------------------------------------*/
-
-    /*----------------------------------------------------------------------------
-    ; STRUCTURES TYPEDEF'S
-    ----------------------------------------------------------------------------*/
-
-
-    /*----------------------------------------------------------------------------
-    ; GLOBAL FUNCTION DEFINITIONS
-    ; Function Prototype declaration
-    ----------------------------------------------------------------------------*/
-
-
-    /*----------------------------------------------------------------------------
-    ; END
-    ----------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-
diff --git a/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp b/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp
deleted file mode 100644
index b61bac4..0000000
--- a/media/libstagefright/codecs/amrnb/common/src/bytesused.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
-    3GPP TS 26.073
-    ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
-    Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Pathname: ./audio/gsm-amr/c/src/BytesUsed.c
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Corrected entries for all SID frames and updated function
-              description. Updated copyright year.
-
- Description: Added #ifdef __cplusplus and removed "extern" from table
-              definition. Removed corresponding header file from Include
-              section.
-
- Description: Put "extern" back.
-
- Who:                       Date:
- Description:
-
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
-    None
-
- Local Stores/Buffers/Pointers Needed:
-    None
-
- Global Stores/Buffers/Pointers Needed:
-    None
-
- Outputs:
-    None
-
- Pointers and Buffers Modified:
-    None
-
- Local Stores Modified:
-    None
-
- Global Stores Modified:
-    None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- This function creates a table called BytesUsed that holds the value that
- describes the number of bytes required to hold one frame worth of data in
- the WMF (non-IF2) frame format. Each table entry is the sum of the frame
- type byte and the number of bytes used up by the core speech data for each
- 3GPP frame type.
-
-------------------------------------------------------------------------------
- REQUIREMENTS
-
- None
-
-------------------------------------------------------------------------------
- REFERENCES
-
- [1] "AMR Speech Codec Frame Structure", 3GPP TS 26.101 version 4.1.0
-     Release 4, June 2001, page 13.
-
-------------------------------------------------------------------------------
- PSEUDO-CODE
-
-
-------------------------------------------------------------------------------
- RESOURCES USED
-   When the code is written for a specific target processor the
-     the resources used should be documented below.
-
- STACK USAGE: [stack count for this module] + [variable to represent
-          stack usage for each subroutine called]
-
-     where: [stack usage variable] = stack usage for [subroutine
-         name] (see [filename].ext)
-
- DATA MEMORY USED: x words
-
- PROGRAM MEMORY USED: x words
-
- CLOCK CYCLES: [cycle count equation for this module] + [variable
-           used to represent cycle count for each subroutine
-           called]
-
-     where: [cycle count variable] = cycle count for [subroutine
-        name] (see [filename].ext)
-
-------------------------------------------------------------------------------
-*/
-
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "typedef.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-    /*----------------------------------------------------------------------------
-    ; MACROS
-    ; Define module specific macros here
-    ----------------------------------------------------------------------------*/
-
-
-    /*----------------------------------------------------------------------------
-    ; DEFINES
-    ; Include all pre-processor statements here. Include conditional
-    ; compile variables also.
-    ----------------------------------------------------------------------------*/
-
-    /*----------------------------------------------------------------------------
-    ; LOCAL FUNCTION DEFINITIONS
-    ; Function Prototype declaration
-    ----------------------------------------------------------------------------*/
-
-
-    /*----------------------------------------------------------------------------
-    ; LOCAL STORE/BUFFER/POINTER DEFINITIONS
-    ; Variable declaration - defined here and used outside this module
-    ----------------------------------------------------------------------------*/
-    const short BytesUsed[16] =
-    {
-        13, /* 4.75 */
-        14, /* 5.15 */
-        16, /* 5.90 */
-        18, /* 6.70 */
-        20, /* 7.40 */
-        21, /* 7.95 */
-        27, /* 10.2 */
-        32, /* 12.2 */
-        6, /* GsmAmr comfort noise */
-        7, /* Gsm-Efr comfort noise */
-        6, /* IS-641 comfort noise */
-        6, /* Pdc-Efr comfort noise */
-        0, /* future use */
-        0, /* future use */
-        0, /* future use */
-        1 /* No transmission */
-    };
-    /*----------------------------------------------------------------------------
-    ; EXTERNAL FUNCTION REFERENCES
-    ; Declare functions defined elsewhere and referenced in this module
-    ----------------------------------------------------------------------------*/
-
-
-    /*----------------------------------------------------------------------------
-    ; EXTERNAL GLOBAL STORE/BUFFER/POINTER REFERENCES
-    ; Declare variables used in this module but defined elsewhere
-    ----------------------------------------------------------------------------*/
-
-
-    /*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-
-/*----------------------------------------------------------------------------
-; Define all local variables
-----------------------------------------------------------------------------*/
-
-
-/*----------------------------------------------------------------------------
-; Function body here
-----------------------------------------------------------------------------*/
-
-
-/*----------------------------------------------------------------------------
-; Return nothing or data or data pointer
-----------------------------------------------------------------------------*/
-
diff --git a/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp b/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp
deleted file mode 100644
index c4a016d..0000000
--- a/media/libstagefright/codecs/amrnb/common/src/overflow_tbl.cpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/* ------------------------------------------------------------------
- * Copyright (C) 1998-2009 PacketVideo
- *
- * 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.
- * -------------------------------------------------------------------
- */
-/****************************************************************************************
-Portions of this file are derived from the following 3GPP standard:
-
-    3GPP TS 26.073
-    ANSI-C code for the Adaptive Multi-Rate (AMR) speech codec
-    Available from http://www.3gpp.org
-
-(C) 2004, 3GPP Organizational Partners (ARIB, ATIS, CCSA, ETSI, TTA, TTC)
-Permission to distribute, modify and use this file under the standard license
-terms listed above has been obtained from the copyright holder.
-****************************************************************************************/
-/*
-
- Filename: /audio/gsm_amr/c/src/overflow_tbl.c
-
-------------------------------------------------------------------------------
- REVISION HISTORY
-
- Description: Added #ifdef __cplusplus and removed "extern" from table
-              definition.
-
- Description: Put "extern" back.
-
- Who:                       Date:
- Description:
-
-------------------------------------------------------------------------------
- MODULE DESCRIPTION
-
- This file contains the declaration for overflow_tbl[] used by the l_shl()
- and l_shr() functions.
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; INCLUDES
-----------------------------------------------------------------------------*/
-#include "typedef.h"
-
-/*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-    /*----------------------------------------------------------------------------
-    ; MACROS
-    ; [Define module specific macros here]
-    ----------------------------------------------------------------------------*/
-
-    /*----------------------------------------------------------------------------
-    ; DEFINES
-    ; [Include all pre-processor statements here. Include conditional
-    ; compile variables also.]
-    ----------------------------------------------------------------------------*/
-
-    /*----------------------------------------------------------------------------
-    ; LOCAL FUNCTION DEFINITIONS
-    ; [List function prototypes here]
-    ----------------------------------------------------------------------------*/
-
-    /*----------------------------------------------------------------------------
-    ; LOCAL VARIABLE DEFINITIONS
-    ; [Variable declaration - defined here and used outside this module]
-    ----------------------------------------------------------------------------*/
-    const Word32 overflow_tbl [32]   = {0x7fffffffL, 0x3fffffffL,
-        0x1fffffffL, 0x0fffffffL,
-        0x07ffffffL, 0x03ffffffL,
-        0x01ffffffL, 0x00ffffffL,
-        0x007fffffL, 0x003fffffL,
-        0x001fffffL, 0x000fffffL,
-        0x0007ffffL, 0x0003ffffL,
-        0x0001ffffL, 0x0000ffffL,
-        0x00007fffL, 0x00003fffL,
-        0x00001fffL, 0x00000fffL,
-        0x000007ffL, 0x000003ffL,
-        0x000001ffL, 0x000000ffL,
-        0x0000007fL, 0x0000003fL,
-        0x0000001fL, 0x0000000fL,
-        0x00000007L, 0x00000003L,
-        0x00000001L, 0x00000000L
-    };
-
-    /*--------------------------------------------------------------------------*/
-#ifdef __cplusplus
-}
-#endif
-
-/*
-------------------------------------------------------------------------------
- FUNCTION NAME:
-------------------------------------------------------------------------------
- INPUT AND OUTPUT DEFINITIONS
-
- Inputs:
-    None
-
- Outputs:
-    None
-
- Returns:
-    None
-
- Global Variables Used:
-    None
-
- Local Variables Needed:
-    None
-
-------------------------------------------------------------------------------
- FUNCTION DESCRIPTION
-
- None
-
-------------------------------------------------------------------------------
- REQUIREMENTS
-
- None
-
-------------------------------------------------------------------------------
- REFERENCES
-
- [1] l_shl() function in basic_op2.c,  UMTS GSM AMR speech codec, R99 -
- Version 3.2.0, March 2, 2001
-
-------------------------------------------------------------------------------
- PSEUDO-CODE
-
-
-------------------------------------------------------------------------------
- RESOURCES USED [optional]
-
- When the code is written for a specific target processor the
- the resources used should be documented below.
-
- HEAP MEMORY USED: x bytes
-
- STACK MEMORY USED: x bytes
-
- CLOCK CYCLES: (cycle count equation for this function) + (variable
-                used to represent cycle count for each subroutine
-                called)
-     where: (cycle count variable) = cycle count for [subroutine
-                                     name]
-
-------------------------------------------------------------------------------
- CAUTION [optional]
- [State any special notes, constraints or cautions for users of this function]
-
-------------------------------------------------------------------------------
-*/
-
-/*----------------------------------------------------------------------------
-; FUNCTION CODE
-----------------------------------------------------------------------------*/
-
diff --git a/media/libstagefright/codecs/amrnb/enc/Android.mk b/media/libstagefright/codecs/amrnb/enc/Android.mk
index bdba8a9..e8b010e 100644
--- a/media/libstagefright/codecs/amrnb/enc/Android.mk
+++ b/media/libstagefright/codecs/amrnb/enc/Android.mk
@@ -103,3 +103,25 @@
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+    test/amrnb_enc_test.cpp
+
+LOCAL_C_INCLUDES := \
+    $(LOCAL_PATH)/src \
+    $(LOCAL_PATH)/../common/include
+
+
+LOCAL_STATIC_LIBRARIES := \
+    libstagefright_amrnbenc
+
+LOCAL_SHARED_LIBRARIES := \
+    libstagefright_amrnb_common
+
+LOCAL_MODULE := libstagefright_amrnbenc_test
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/amrnb/enc/src/l_negate.cpp b/media/libstagefright/codecs/amrnb/enc/src/l_negate.cpp
index 588abbb..523e482 100644
--- a/media/libstagefright/codecs/amrnb/enc/src/l_negate.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/src/l_negate.cpp
@@ -147,7 +147,7 @@
 /*----------------------------------------------------------------------------
 ; FUNCTION CODE
 ----------------------------------------------------------------------------*/
-Word32 L_negate(register Word32 L_var1)
+Word32 L_negate(Word32 L_var1)
 {
     /*----------------------------------------------------------------------------
     ; Define all local variables
diff --git a/media/libstagefright/codecs/amrnb/enc/test/amrnb_enc_test.cpp b/media/libstagefright/codecs/amrnb/enc/test/amrnb_enc_test.cpp
new file mode 100644
index 0000000..e2d198e
--- /dev/null
+++ b/media/libstagefright/codecs/amrnb/enc/test/amrnb_enc_test.cpp
@@ -0,0 +1,237 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdint.h>
+#include <assert.h>
+#include "gsmamr_enc.h"
+
+enum {
+    kInputSize = 320, // 160 samples * 16-bit per sample.
+    kOutputSize = 1024
+};
+
+struct AmrNbEncState {
+    void *encCtx;
+    void *pidSyncCtx;
+};
+
+void usage(void) {
+    printf("Usage:\n");
+    printf("AMRNBEnc [options] <input file> <output file>\n");
+    printf("\n");
+    printf("Options +M* for setting compression bitrate mode, default is 4.75 kbps\n");
+    printf(" +M0 = 4.75 kbps\n");
+    printf(" +M1 = 5.15 kbps\n");
+    printf(" +M2 = 5.90 kbps\n");
+    printf(" +M3 = 6.70 kbps\n");
+    printf(" +M4 = 7.40 kbps\n");
+    printf(" +M5 = 7.95 kbps\n");
+    printf(" +M6 = 10.2 kbps\n");
+    printf(" +M7 = 12.2 kbps\n");
+    printf("\n");
+}
+
+int encode(int mode, const char *srcFile, const char *dstFile) {
+    int           retVal     = EXIT_SUCCESS;
+    FILE          *fSrc      = NULL;
+    FILE          *fDst      = NULL;
+    int           frameNum   = 0;
+    bool          eofReached = false;
+    uint16_t      *inputBuf  = NULL;
+    uint8_t       *outputBuf = NULL;
+    AmrNbEncState *amr       = NULL;
+
+    clock_t   start, finish;
+    double    duration = 0.0;
+
+    // Open input file.
+    fSrc = fopen(srcFile, "rb");
+    if (fSrc == NULL) {
+        fprintf(stderr, "Error opening input file\n");
+        retVal = EXIT_FAILURE;
+        goto safe_exit;
+    }
+
+    // Open output file.
+    fDst = fopen(dstFile, "wb");
+    if (fDst == NULL) {
+        fprintf(stderr, "Error opening output file\n");
+        retVal = EXIT_FAILURE;
+        goto safe_exit;
+    }
+
+    // Allocate input buffer.
+    inputBuf = (uint16_t*) malloc(kInputSize);
+    assert(inputBuf != NULL);
+
+    // Allocate output buffer.
+    outputBuf = (uint8_t*) malloc(kOutputSize);
+    assert(outputBuf != NULL);
+
+    // Initialize encoder.
+    amr = (AmrNbEncState*) malloc(sizeof(AmrNbEncState));
+    AMREncodeInit(&amr->encCtx, &amr->pidSyncCtx, 0);
+
+    // Write file header.
+    fwrite("#!AMR\n", 1, 6, fDst);
+
+    while (1) {
+        // Read next input frame.
+        int bytesRead;
+        bytesRead = fread(inputBuf, 1, kInputSize, fSrc);
+        if (bytesRead != kInputSize && !feof(fSrc)) {
+            retVal = EXIT_FAILURE; // Invalid magic number.
+            fprintf(stderr, "Error reading input file\n");
+            goto safe_exit;
+        } else if (feof(fSrc) && bytesRead == 0) {
+            eofReached = true;
+            break;
+        }
+
+        start = clock();
+
+        // Encode the frame.
+        Frame_Type_3GPP frame_type = (Frame_Type_3GPP) mode;
+        int bytesGenerated;
+        bytesGenerated = AMREncode(amr->encCtx, amr->pidSyncCtx, (Mode)mode,
+                                   (Word16*)inputBuf, outputBuf, &frame_type,
+                                   AMR_TX_WMF);
+
+        // Convert from WMF to RFC 3267 format.
+        if (bytesGenerated > 0) {
+            outputBuf[0] = ((outputBuf[0] << 3) | 4) & 0x7c;
+        }
+
+        finish = clock();
+        duration += finish - start;
+
+        if (bytesGenerated < 0) {
+            retVal = EXIT_FAILURE;
+            fprintf(stderr, "Encoding error\n");
+            goto safe_exit;
+        }
+
+        frameNum++;
+        printf(" Frames processed: %d\n", frameNum);
+
+        // Write the output.
+        fwrite(outputBuf, 1, bytesGenerated, fDst);
+    }
+
+    // Dump the time taken by encode.
+    printf("\n%2.5lf seconds\n", (double)duration/CLOCKS_PER_SEC);
+
+safe_exit:
+
+    // Free the encoder instance.
+    if (amr) {
+        AMREncodeExit(&amr->encCtx, &amr->pidSyncCtx);
+        free(amr);
+    }
+
+    // Free input and output buffer.
+    free(inputBuf);
+    free(outputBuf);
+
+    // Close the input and output files.
+    if (fSrc) {
+        fclose(fSrc);
+    }
+    if (fDst) {
+        fclose(fDst);
+    }
+
+    return retVal;
+}
+
+int main(int argc, char *argv[]) {
+    Mode  mode = MR475;
+    int   retVal;
+    char  *inFileName = NULL;
+    char  *outFileName = NULL;
+    int   arg, filename = 0;
+
+    if (argc < 3) {
+        usage();
+        return EXIT_FAILURE;
+    } else {
+        for (arg = 1; arg < argc; arg++) {
+            if (argv[arg][0] == '+') {
+                if (argv[arg][1] == 'M') {
+                    switch (argv[arg][2]) {
+                    case '0': mode = MR475;
+                        break;
+                    case '1': mode = MR515;
+                        break;
+                    case '2': mode = MR59;
+                        break;
+                    case '3': mode = MR67;
+                        break;
+                    case '4': mode = MR74;
+                        break;
+                    case '5': mode = MR795;
+                        break;
+                    case '6': mode = MR102;
+                        break;
+                    case '7': mode = MR122;
+                        break;
+                    default:
+                        usage();
+                        fprintf(stderr, "Invalid parameter '%s'.\n", argv[arg]);
+                        return EXIT_FAILURE;
+                        break;
+                    }
+                } else {
+                    usage();
+                    fprintf(stderr, "Invalid parameter '%s'.\n", argv[arg]);
+                    return EXIT_FAILURE;
+                }
+            } else {
+                switch (filename) {
+                case 0:
+                    inFileName  = argv[arg];
+                    break;
+                case 1:
+                    outFileName = argv[arg];
+                    break;
+                default:
+                    usage();
+                    fprintf(stderr, "Invalid parameter '%s'.\n", argv[arg]);
+                    return EXIT_FAILURE;
+                }
+                filename++;
+            }
+        }
+    }
+
+    retVal = encode(mode, inFileName, outFileName);
+    return retVal;
+}
+
diff --git a/media/libstagefright/codecs/amrwb/Android.mk b/media/libstagefright/codecs/amrwb/Android.mk
index 686f7a3..6ce20ca 100644
--- a/media/libstagefright/codecs/amrwb/Android.mk
+++ b/media/libstagefright/codecs/amrwb/Android.mk
@@ -55,3 +55,24 @@
 LOCAL_MODULE := libstagefright_amrwbdec
 
 include $(BUILD_STATIC_LIBRARY)
+
+################################################################################
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+        test/amrwbdec_test.cpp
+
+LOCAL_C_INCLUDES := \
+        $(LOCAL_PATH)/src \
+        $(LOCAL_PATH)/include \
+        $(call include-path-for, audio-utils)
+
+LOCAL_STATIC_LIBRARIES := \
+        libstagefright_amrwbdec libsndfile
+
+LOCAL_SHARED_LIBRARIES := \
+        libaudioutils
+
+LOCAL_MODULE := libstagefright_amrwbdec_test
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/amrwb/test/amrwbdec_test.cpp b/media/libstagefright/codecs/amrwb/test/amrwbdec_test.cpp
new file mode 100644
index 0000000..b04bafd
--- /dev/null
+++ b/media/libstagefright/codecs/amrwb/test/amrwbdec_test.cpp
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "pvamrwbdecoder.h"
+#include <audio_utils/sndfile.h>
+
+// Constants for AMR-WB.
+enum {
+    kInputBufferSize = 64,
+    kSamplesPerFrame = 320,
+    kBitsPerSample = 16,
+    kOutputBufferSize = kSamplesPerFrame * kBitsPerSample/8,
+    kSampleRate = 16000,
+    kChannels = 1,
+    kFileHeaderSize = 9,
+    kMaxSourceDataUnitSize = 477 * sizeof(int16_t)
+};
+
+const uint32_t kFrameSizes[] = { 17, 23, 32, 36, 40, 46, 50, 58, 60 };
+
+int main(int argc, char *argv[]) {
+
+    if (argc != 3) {
+        fprintf(stderr, "Usage %s <input file> <output file>\n", argv[0]);
+        return EXIT_FAILURE;
+    }
+
+    // Open the input file.
+    FILE* fpInput = fopen(argv[1], "rb");
+    if (fpInput == NULL) {
+        fprintf(stderr, "Could not open %s\n", argv[1]);
+        return EXIT_FAILURE;
+    }
+
+    // Validate the input AMR file.
+    char header[kFileHeaderSize];
+    int bytesRead = fread(header, 1, kFileHeaderSize, fpInput);
+    if ((bytesRead != kFileHeaderSize) ||
+        (memcmp(header, "#!AMR-WB\n", kFileHeaderSize) != 0)) {
+        fprintf(stderr, "Invalid AMR-WB file\n");
+        fclose(fpInput);
+        return EXIT_FAILURE;
+    }
+
+    // Open the output file.
+    SF_INFO sfInfo;
+    memset(&sfInfo, 0, sizeof(SF_INFO));
+    sfInfo.channels = kChannels;
+    sfInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+    sfInfo.samplerate = kSampleRate;
+    SNDFILE *handle = sf_open(argv[2], SFM_WRITE, &sfInfo);
+    if (handle == NULL) {
+        fprintf(stderr, "Could not create %s\n", argv[2]);
+        fclose(fpInput);
+        return EXIT_FAILURE;
+    }
+
+    // Allocate the decoder memory.
+    uint32_t memRequirements = pvDecoder_AmrWbMemRequirements();
+    void *decoderBuf = malloc(memRequirements);
+    assert(decoderBuf != NULL);
+
+    // Create AMR-WB decoder instance.
+    void *amrHandle;
+    int16_t *decoderCookie;
+    pvDecoder_AmrWb_Init(&amrHandle, decoderBuf, &decoderCookie);
+
+    // Allocate input buffer.
+    uint8_t *inputBuf = (uint8_t*) malloc(kInputBufferSize);
+    assert(inputBuf != NULL);
+
+    // Allocate input sample buffer.
+    int16_t *inputSampleBuf = (int16_t*) malloc(kMaxSourceDataUnitSize);
+    assert(inputSampleBuf != NULL);
+
+    // Allocate output buffer.
+    int16_t *outputBuf = (int16_t*) malloc(kOutputBufferSize);
+    assert(outputBuf != NULL);
+
+    // Decode loop.
+    int retVal = EXIT_SUCCESS;
+    while (1) {
+        // Read mode.
+        uint8_t modeByte;
+        bytesRead = fread(&modeByte, 1, 1, fpInput);
+        if (bytesRead != 1) break;
+        int16 mode = ((modeByte >> 3) & 0x0f);
+
+        // AMR-WB file format cannot have mode 10, 11, 12 and 13.
+        if (mode >= 10 && mode <= 13) {
+            fprintf(stderr, "Encountered illegal frame type %d\n", mode);
+            retVal = EXIT_FAILURE;
+            break;
+        }
+
+        if (mode >= 9) {
+            // Produce silence for comfort noise, speech lost and no data.
+            memset(outputBuf, 0, kOutputBufferSize);
+        } else /* if (mode < 9) */ {
+            // Read rest of the frame.
+            int32_t frameSize = kFrameSizes[mode];
+            bytesRead = fread(inputBuf, 1, frameSize, fpInput);
+            if (bytesRead != frameSize) break;
+
+            int16 frameType, frameMode;
+            RX_State_wb rx_state;
+            frameMode = mode;
+            mime_unsorting(
+                    (uint8_t *)inputBuf,
+                    inputSampleBuf,
+                    &frameType, &frameMode, 1, &rx_state);
+
+            int16_t numSamplesOutput;
+            pvDecoder_AmrWb(
+                    frameMode, inputSampleBuf,
+                    outputBuf,
+                    &numSamplesOutput,
+                    decoderBuf, frameType, decoderCookie);
+
+            if (numSamplesOutput != kSamplesPerFrame) {
+                fprintf(stderr, "Decoder encountered error\n");
+                retVal = EXIT_FAILURE;
+                break;
+            }
+
+            for (int i = 0; i < kSamplesPerFrame; ++i) {
+                outputBuf[i] &= 0xfffC;
+            }
+        }
+
+        // Write output to wav.
+        sf_writef_short(handle, outputBuf, kSamplesPerFrame / kChannels);
+    }
+
+    // Close input and output file.
+    fclose(fpInput);
+    sf_close(handle);
+
+    // Free allocated memory.
+    free(inputBuf);
+    free(inputSampleBuf);
+    free(outputBuf);
+
+    return retVal;
+}
diff --git a/media/libstagefright/codecs/amrwbenc/Android.mk b/media/libstagefright/codecs/amrwbenc/Android.mk
index 024a292..c7692cb 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/Android.mk
@@ -86,9 +86,6 @@
 
 endif
 
-# ARMV5E/Filt_6k_7k_opt.s does not compile with Clang.
-LOCAL_CLANG_ASFLAGS_arm += -no-integrated-as
-
 LOCAL_MODULE := libstagefright_amrwbenc
 
 LOCAL_ARM_MODE := arm
@@ -144,3 +141,6 @@
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
index 4ff5f10..0cb0097 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/AMRWB_E_SAMPLE.c
@@ -21,6 +21,7 @@
 
 #include      <stdio.h>
 #include      <stdlib.h>
+#include      <string.h>
 #include      <time.h>
 #include      "voAMRWB.h"
 #include      "cmnMemory.h"
@@ -222,12 +223,12 @@
 					fflush(fdst);
 				}
 			}
-			else if(returnCode == VO_ERR_LICENSE_ERROR)
+			else if((unsigned)returnCode == VO_ERR_LICENSE_ERROR)
 			{
 		        printf("Encoder time reach upper limit......");
 		        goto safe_exit;
 			}
-		} while(returnCode != VO_ERR_INPUT_BUFFER_SMALL);
+		} while((unsigned)returnCode != VO_ERR_INPUT_BUFFER_SMALL);
 
 		finish = clock();
 		duration += finish - start;
diff --git a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
index c203f77..65d69a2 100644
--- a/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/SampleCode/Android.mk
@@ -5,17 +5,20 @@
     AMRWB_E_SAMPLE.c \
     ../../common/cmnMemory.c
 
-LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_TAGS := tests
 LOCAL_MODULE := AMRWBEncTest
 
 LOCAL_ARM_MODE := arm
 
-LOCAL_CFLAGS := -DLINUX
+LOCAL_CFLAGS :=
 
 LOCAL_SHARED_LIBRARIES := \
     libstagefright \
     libdl
 
+LOCAL_STATIC_LIBRARIES := \
+    libstagefright_amrwbenc
+
 LOCAL_C_INCLUDES := \
     $(LOCAL_PATH)/ \
     $(LOCAL_PATH)/../../common \
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
index 282db92..42ebc32 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Deemph_32_opt.s
@@ -99,6 +99,6 @@
            LDMFD   	r13!, {r4 - r12, r15}
 
 	   @ENDP
-	   .END
+	   .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
index 4aa317e..3f060ff 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Dot_p_opt.s
@@ -75,6 +75,6 @@
 
           LDMFD   	    r13!, {r4 - r12, r15}
           @ENDFUNC
-          .END
+          .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
index f23b5a0..9cad479 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
@@ -183,6 +183,6 @@
 Lable1:
           .word   		fir_6k_7k-Lable1
           @ENDFUNC
-          .END
+          .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
index 49bdc2b..ffedbde 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Norm_Corr_opt.s
@@ -226,6 +226,6 @@
         ADD            r13, r13, #voSTACK
         LDMFD          r13!, {r4 - r12, r15}
 
-        .END
+        .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
index 3f4930c..9743b9e 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Syn_filt_32_opt.s
@@ -221,6 +221,6 @@
 
           LDMFD   	    r13!, {r4 - r12, r15}
           @ENDFUNC
-          .END
+          .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
index 71bb532..cd75179 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/convolve_opt.s
@@ -181,6 +181,6 @@
         LDMFD      r13!, {r4 - r12, r15}
 
         @ENDFUNC
-        .END
+        .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
index 2d4c7cc..eedccc7 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/cor_h_vec_opt.s
@@ -143,7 +143,7 @@
          LDMFD         r13!, {r4 - r12, r15}
 
          @ENDFUNC
-         .END
+         .end
 
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
index deb7efc..60c2a47 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
@@ -45,7 +45,8 @@
          SUBLT     r5, r5, #2                         @x--
          SUB       r5, r5, #30                        @x -= 15
          RSB       r4, r2, #3                         @k = 3 - frac
-         ADRL      r8, Table
+         ADR       r8, Table
+         NOP                      @space for fixed up relative address of ADR
          LDR       r6, [r8]
          ADD       r6, r8
 	 MOV       r8, r4, LSL #6
@@ -456,7 +457,7 @@
 Table:
          .word       inter4_2-Table
 	 @ENDFUNC
-	 .END
+	 .end
 
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
index 5ff0964..d71d790 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/residu_asm_opt.s
@@ -220,7 +220,7 @@
 	LDMFD	r13!, {r4 -r12,pc}
 
         @ENDFUNC
-        .END
+        .end
 
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
index b300224..e8802f5 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/scale_sig_opt.s
@@ -67,7 +67,7 @@
          LDMFD         r13!, {r4 - r12, r15}
 
          @ENDFUNC
-         .END
+         .end
 
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
index 0c287a4..2a1e0d7 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/syn_filt_opt.s
@@ -233,6 +233,6 @@
           ADD           r13, r13, #700
           LDMFD   	r13!, {r4 - r12, r15}
           @ENDFUNC
-          .END
+          .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
index 1d5893f..91feea0 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Deemph_32_neon.s
@@ -98,5 +98,5 @@
 
            LDMFD   	r13!, {r4 - r12, r15}
 
-	   .END
+	   .end
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
index 8230944..7149a49 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Dot_p_neon.s
@@ -123,5 +123,5 @@
 
           LDMFD   	    r13!, {r4 - r12, r15}
 
-          .END
+          .end
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
index 8df0caa..e0f992f 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
@@ -226,6 +226,6 @@
 Lable1:
           .word   		fir_6k_7k-Lable1
           @ENDFUNC
-          .END
+          .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
index 4263cd4..28e6d6c 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Norm_Corr_neon.s
@@ -265,6 +265,6 @@
         ADD            r13, r13, #voSTACK
         LDMFD          r13!, {r4 - r12, r15}
 
-        .END
+        .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
index e786dde..9687431 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Syn_filt_32_neon.s
@@ -128,6 +128,6 @@
 
           LDMFD   	    r13!, {r4 - r12, r15}
           @ENDFUNC
-          .END
+          .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
index 8efa9fb..9fb3a6e 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/convolve_neon.s
@@ -174,5 +174,5 @@
         LDMFD      r13!, {r4 - r12, r15}
 
         @ENDFUNC
-        .END
+        .end
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
index 8904289..a4deda3 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/cor_h_vec_neon.s
@@ -143,7 +143,7 @@
 the_end:
              LDMFD         r13!, {r4 - r12, r15}
 
-	     .END
+	     .end
 
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
index 67be1ed..f8b634f 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
@@ -99,5 +99,5 @@
 Lable1:
           .word   	inter4_2-Lable1
           @ENDFUNC
-          .END
+          .end
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
index 394fa83..bc3d780 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/residu_asm_neon.s
@@ -122,6 +122,6 @@
         LDMFD      r13!, {r4 - r12, r15}
 
         @ENDFUNC
-        .END
+        .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
index e45daac..89c0572 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/scale_sig_neon.s
@@ -133,6 +133,6 @@
 
           LDMFD   	r13!, {r4 - r12, r15}
           @ENDFUNC
-          .END
+          .end
 
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
index 5731bdb..029560e 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/syn_filt_neon.s
@@ -101,6 +101,6 @@
           ADD           r13, r13, #700
           LDMFD   	r13!, {r4 - r12, r15}
           @ENDFUNC
-          .END
+          .end
 
 
diff --git a/media/libstagefright/codecs/avc/enc/Android.mk b/media/libstagefright/codecs/avc/enc/Android.mk
index 2ceebc8..d5131cb 100644
--- a/media/libstagefright/codecs/avc/enc/Android.mk
+++ b/media/libstagefright/codecs/avc/enc/Android.mk
@@ -74,3 +74,31 @@
 LOCAL_CFLAGS += -Werror
 
 include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+        test/h264_enc_test.cpp
+
+LOCAL_C_INCLUDES := \
+        $(LOCAL_PATH)/src \
+        $(LOCAL_PATH)/include \
+        $(LOCAL_PATH)/../common/include \
+        $(LOCAL_PATH)/../common
+
+LOCAL_CFLAGS := \
+    -DOSCL_IMPORT_REF= -DOSCL_UNUSED_ARG= -DOSCL_EXPORT_REF=
+
+LOCAL_STATIC_LIBRARIES := \
+        libstagefright_avcenc
+
+LOCAL_SHARED_LIBRARIES := \
+        libstagefright_avc_common
+
+LOCAL_MODULE := libstagefright_h264enc_test
+
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/avc/enc/src/findhalfpel.cpp b/media/libstagefright/codecs/avc/enc/src/findhalfpel.cpp
index 0b8d9e2..d0bbee2 100644
--- a/media/libstagefright/codecs/avc/enc/src/findhalfpel.cpp
+++ b/media/libstagefright/codecs/avc/enc/src/findhalfpel.cpp
@@ -23,19 +23,6 @@
 
 #define PREF_16_VEC 129     /* 1MV bias versus 4MVs*/
 
-const static int distance_tab[9][9] =   /* [hp_guess][k] */
-{
-    {0, 1, 1, 1, 1, 1, 1, 1, 1},
-    {1, 0, 1, 2, 3, 4, 3, 2, 1},
-    {1, 0, 0, 0, 1, 2, 3, 2, 1},
-    {1, 2, 1, 0, 1, 2, 3, 4, 3},
-    {1, 2, 1, 0, 0, 0, 1, 2, 3},
-    {1, 4, 3, 2, 1, 0, 1, 2, 3},
-    {1, 2, 3, 2, 1, 0, 0, 0, 1},
-    {1, 2, 3, 4, 3, 2, 1, 0, 1},
-    {1, 0, 1, 2, 3, 2, 1, 0, 0}
-};
-
 #define CLIP_RESULT(x)      if((uint)x > 0xFF){ \
                  x = 0xFF & (~(x>>31));}
 
diff --git a/media/libstagefright/codecs/avc/enc/test/h264_enc_test.cpp b/media/libstagefright/codecs/avc/enc/test/h264_enc_test.cpp
new file mode 100644
index 0000000..7a782a8
--- /dev/null
+++ b/media/libstagefright/codecs/avc/enc/test/h264_enc_test.cpp
@@ -0,0 +1,357 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "avcenc_api.h"
+#include "avcenc_int.h"
+
+// Constants.
+enum {
+    kMaxWidth         = 720,
+    kMaxHeight        = 480,
+    kMaxFrameRate     = 30,
+    kMaxBitrate       = 2048, // in kbps.
+    kInputBufferSize  = (kMaxWidth * kMaxHeight * 3) / 2, // For YUV 420 format.
+    kOutputBufferSize = kInputBufferSize,
+    kMaxDpbBuffers    = 17,
+    kIDRFrameRefreshIntervalInSec = 1,
+};
+
+
+static void *MallocCb(void * /*userData*/, int32_t size, int32_t /*attrs*/) {
+    void *ptr = calloc(size, 1);
+    return ptr;
+}
+
+static void FreeCb(void * /*userData*/, void *ptr) {
+    free(ptr);
+}
+
+static int32_t DpbAllocCb(void * /*userData*/,
+        unsigned int sizeInMbs, unsigned int numBuffers) {
+
+    size_t frameSize = (sizeInMbs << 7) * 3;
+    if(numBuffers < kMaxDpbBuffers && frameSize <= kInputBufferSize) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+
+static int32_t BindFrameCb(void *userData, int32_t index, uint8_t **yuv) {
+     assert(index < kMaxDpbBuffers);
+     uint8_t** dpbBuffer = static_cast<uint8_t**>(userData);
+     *yuv = dpbBuffer[index];
+     return 1;
+}
+
+static void UnbindFrameCb(void * /*userData*/, int32_t /*index*/) {
+}
+
+int main(int argc, char *argv[]) {
+
+    if (argc < 7) {
+        fprintf(stderr, "Usage %s <input yuv> <output file> <width> <height>"
+                        " <frame rate> <bitrate in kbps>\n", argv[0]);
+        fprintf(stderr, "Max width %d\n", kMaxWidth);
+        fprintf(stderr, "Max height %d\n", kMaxHeight);
+        fprintf(stderr, "Max framerate %d\n", kMaxFrameRate);
+        fprintf(stderr, "Max bitrate %d kbps\n", kMaxBitrate);
+        return EXIT_FAILURE;
+    }
+
+    // Read height and width.
+    int32_t width;
+    int32_t height;
+    width = atoi(argv[3]);
+    height = atoi(argv[4]);
+    if (width > kMaxWidth || height > kMaxHeight || width <= 0 || height <= 0) {
+        fprintf(stderr, "Unsupported dimensions %dx%d\n", width, height);
+        return EXIT_FAILURE;
+    }
+
+    if (width % 16 != 0 || height % 16 != 0) {
+        fprintf(stderr, "Video frame size %dx%d must be a multiple of 16\n",
+            width, height);
+        return EXIT_FAILURE;
+    }
+
+    // Read frame rate.
+    int32_t frameRate;
+    frameRate = atoi(argv[5]);
+    if (frameRate > kMaxFrameRate || frameRate <= 0) {
+        fprintf(stderr, "Unsupported frame rate %d\n", frameRate);
+        return EXIT_FAILURE;
+    }
+
+    // Read bit rate.
+    int32_t bitrate;
+    bitrate = atoi(argv[6]);
+    if (bitrate > kMaxBitrate || bitrate <= 0) {
+        fprintf(stderr, "Unsupported bitrate %d\n", bitrate);
+        return EXIT_FAILURE;
+    }
+    bitrate *= 1024; // kbps to bps.
+
+    // Open the input file.
+    FILE *fpInput = fopen(argv[1], "rb");
+    if (!fpInput) {
+        fprintf(stderr, "Could not open %s\n", argv[1]);
+        return EXIT_FAILURE;
+    }
+
+    // Open the output file.
+    FILE *fpOutput = fopen(argv[2], "wb");
+    if (!fpOutput) {
+        fprintf(stderr, "Could not open %s\n", argv[2]);
+        fclose(fpInput);
+        return EXIT_FAILURE;
+    }
+
+    // Allocate input buffer.
+    uint8_t *inputBuf = (uint8_t *)malloc(kInputBufferSize);
+    assert(inputBuf != NULL);
+
+    // Allocate output buffer.
+    uint8_t *outputBuf = (uint8_t *)malloc(kOutputBufferSize);
+    assert(outputBuf != NULL);
+
+    // Allocate dpb buffers.
+    uint8_t * dpbBuffers[kMaxDpbBuffers];
+    for (int i = 0; i < kMaxDpbBuffers; ++i) {
+        dpbBuffers[i] = (uint8_t *)malloc(kInputBufferSize);
+        assert(dpbBuffers[i] != NULL);
+    }
+
+    // Initialize the encoder parameters.
+    tagAVCEncParam encParams;
+    memset(&encParams, 0, sizeof(tagAVCEncParam));
+    encParams.rate_control = AVC_ON;
+    encParams.initQP = 0;
+    encParams.init_CBP_removal_delay = 1600;
+
+    encParams.intramb_refresh = 0;
+    encParams.auto_scd = AVC_ON;
+    encParams.out_of_band_param_set = AVC_ON;
+    encParams.poc_type = 2;
+    encParams.log2_max_poc_lsb_minus_4 = 12;
+    encParams.delta_poc_zero_flag = 0;
+    encParams.offset_poc_non_ref = 0;
+    encParams.offset_top_bottom = 0;
+    encParams.num_ref_in_cycle = 0;
+    encParams.offset_poc_ref = NULL;
+
+    encParams.num_ref_frame = 1;
+    encParams.num_slice_group = 1;
+    encParams.fmo_type = 0;
+
+    encParams.db_filter = AVC_ON;
+    encParams.disable_db_idc = 0;
+
+    encParams.alpha_offset = 0;
+    encParams.beta_offset = 0;
+    encParams.constrained_intra_pred = AVC_OFF;
+
+    encParams.data_par = AVC_OFF;
+    encParams.fullsearch = AVC_OFF;
+    encParams.search_range = 16;
+    encParams.sub_pel = AVC_OFF;
+    encParams.submb_pred = AVC_OFF;
+    encParams.rdopt_mode = AVC_OFF;
+    encParams.bidir_pred = AVC_OFF;
+
+    encParams.use_overrun_buffer = AVC_OFF;
+
+    encParams.width = width;
+    encParams.height = height;
+    encParams.bitrate = bitrate;
+    encParams.frame_rate = 1000 * frameRate;  // In frames/ms.
+    encParams.CPB_size = (uint32_t) (bitrate >> 1);
+
+    int32_t  IDRFrameRefreshIntervalInSec = kIDRFrameRefreshIntervalInSec;
+    if (IDRFrameRefreshIntervalInSec == 0) {
+        encParams.idr_period = 1;  // All I frames.
+    } else {
+        encParams.idr_period = (IDRFrameRefreshIntervalInSec * frameRate);
+    }
+
+    int32_t nMacroBlocks = ((((width + 15) >> 4) << 4) *
+            (((height + 15) >> 4) << 4)) >> 8;
+    uint32_t *sliceGroup = (uint32_t *) malloc(sizeof(uint32_t) * nMacroBlocks);
+    assert(sliceGroup != NULL);
+    for (int i = 0, idx = 0; i < nMacroBlocks; ++i) {
+        sliceGroup[i] = idx++;
+        if (idx >= encParams.num_slice_group) {
+            idx = 0;
+        }
+    }
+    encParams.slice_group = sliceGroup;
+    encParams.profile = AVC_BASELINE;
+    encParams.level = AVC_LEVEL2;
+
+    // Initialize the handle.
+    tagAVCHandle handle;
+    memset(&handle, 0, sizeof(tagAVCHandle));
+    handle.AVCObject = NULL;
+    handle.userData = dpbBuffers;
+    handle.CBAVC_DPBAlloc = DpbAllocCb;
+    handle.CBAVC_FrameBind = BindFrameCb;
+    handle.CBAVC_FrameUnbind = UnbindFrameCb;
+    handle.CBAVC_Malloc = MallocCb;
+    handle.CBAVC_Free = FreeCb;
+
+    // Initialize the encoder.
+    AVCEnc_Status status;
+    status = PVAVCEncInitialize(&handle, &encParams, NULL, NULL);
+    if (status != AVCENC_SUCCESS) {
+        fprintf(stderr, "Failed to initialize the encoder\n");
+
+        // Release resources.
+        fclose(fpInput);
+        fclose(fpOutput);
+        free(sliceGroup);
+        free(inputBuf);
+        free(outputBuf);
+        for (int i = 0; i < kMaxDpbBuffers; ++i) {
+            free(dpbBuffers[i]);
+        }
+        return EXIT_FAILURE;
+    }
+
+    // Encode Sequence Parameter Set.
+    uint32_t dataLength = kOutputBufferSize;
+    int32_t type;
+    status = PVAVCEncodeNAL(&handle, outputBuf, &dataLength, &type);
+    assert(type == AVC_NALTYPE_SPS);
+    fwrite("\x00\x00\x00\x01", 1, 4, fpOutput); // Start Code.
+    fwrite(outputBuf, 1, dataLength, fpOutput); // SPS.
+
+    // Encode Picture Paramater Set.
+    dataLength = kOutputBufferSize;
+    status = PVAVCEncodeNAL(&handle, outputBuf, &dataLength, &type);
+    assert(type == AVC_NALTYPE_PPS);
+    fwrite("\x00\x00\x00\x01", 1, 4, fpOutput); // Start Code.
+    fwrite(outputBuf, 1, dataLength, fpOutput); // PPS.
+
+    // Core loop.
+    int32_t retVal = EXIT_SUCCESS;
+    int32_t frameSize = (width * height * 3) / 2;
+    int32_t numInputFrames = 0;
+    int32_t numNalEncoded = 0;
+    bool readyForNextFrame = true;
+
+    while (1) {
+        if (readyForNextFrame == true) {
+            // Read the input frame.
+            int32_t bytesRead;
+            bytesRead = fread(inputBuf, 1, frameSize, fpInput);
+            if (bytesRead != frameSize) {
+                break; // End of file.
+            }
+
+            // Set the input frame.
+            AVCFrameIO vin;
+            memset(&vin, 0, sizeof(vin));
+            vin.height = ((height + 15) >> 4) << 4;
+            vin.pitch  = ((width  + 15) >> 4) << 4;
+            vin.coding_timestamp = (numInputFrames * 1000) / frameRate;  // in ms
+            vin.YCbCr[0] = inputBuf;
+            vin.YCbCr[1] = vin.YCbCr[0] + vin.height * vin.pitch;
+            vin.YCbCr[2] = vin.YCbCr[1] + ((vin.height * vin.pitch) >> 2);
+            vin.disp_order = numInputFrames;
+
+            status = PVAVCEncSetInput(&handle, &vin);
+            if (status == AVCENC_SUCCESS || status == AVCENC_NEW_IDR) {
+                readyForNextFrame = false;
+                ++numInputFrames;
+            } else if (status < AVCENC_SUCCESS) {
+                fprintf(stderr, "Error %d while setting input frame\n", status);
+                retVal = EXIT_FAILURE;
+                break;
+            } else {
+                fprintf(stderr, "Frame drop\n");
+                readyForNextFrame = true;
+                ++numInputFrames;
+                continue;
+            }
+        }
+
+        // Encode the input frame.
+        dataLength = kOutputBufferSize;
+        status = PVAVCEncodeNAL(&handle, outputBuf, &dataLength, &type);
+        if (status == AVCENC_SUCCESS) {
+            PVAVCEncGetOverrunBuffer(&handle);
+        } else if (status == AVCENC_PICTURE_READY) {
+            PVAVCEncGetOverrunBuffer(&handle);
+            readyForNextFrame = true;
+            AVCFrameIO recon;
+            if (PVAVCEncGetRecon(&handle, &recon) == AVCENC_SUCCESS) {
+                PVAVCEncReleaseRecon(&handle, &recon);
+            }
+        } else {
+            dataLength = 0;
+            readyForNextFrame = true;
+        }
+
+        if (status < AVCENC_SUCCESS) {
+            fprintf(stderr, "Error %d while encoding frame\n", status);
+            retVal = EXIT_FAILURE;
+            break;
+        }
+
+        numNalEncoded++;
+
+        // Write the output.
+        if (dataLength > 0) {
+            fwrite("\x00\x00\x00\x01", 1, 4, fpOutput); // Start Code.
+            fwrite(outputBuf, 1, dataLength, fpOutput); // NAL.
+            printf("NAL %d of size %d written\n", numNalEncoded, dataLength + 4);
+        }
+    }
+
+    // Close input and output file.
+    fclose(fpInput);
+    fclose(fpOutput);
+
+    // Free allocated memory.
+    free(sliceGroup);
+    free(inputBuf);
+    free(outputBuf);
+    for (int i = 0; i < kMaxDpbBuffers; ++i) {
+        free(dpbBuffers[i]);
+    }
+
+    // Close encoder instance.
+    PVAVCCleanUpEncoder(&handle);
+
+    return retVal;
+}
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index 26568ab..c627be4 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -637,6 +637,7 @@
         for (size_t i = 0; i < MAX_CONVERSION_BUFFERS; i++) {
             if (mConversionBuffers[i] != NULL) {
                 free(mConversionBuffers[i]);
+                mConversionBuffers[i] = 0;
             }
 
             if (((uint64_t)mStride * mHeight) > (((uint64_t)INT32_MAX / 3) * 2)) {
diff --git a/media/libstagefright/codecs/m4v_h263/enc/Android.mk b/media/libstagefright/codecs/m4v_h263/enc/Android.mk
index 7117692..762e6fe 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/Android.mk
+++ b/media/libstagefright/codecs/m4v_h263/enc/Android.mk
@@ -77,3 +77,23 @@
 LOCAL_CFLAGS += -Werror
 
 include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+        test/m4v_h263_enc_test.cpp
+
+LOCAL_C_INCLUDES := \
+        $(LOCAL_PATH)/src \
+        $(LOCAL_PATH)/include
+
+LOCAL_CFLAGS := -DOSCL_EXPORT_REF= -DOSCL_IMPORT_REF= -DBX_RC
+
+LOCAL_STATIC_LIBRARIES := \
+        libstagefright_m4vh263enc
+
+LOCAL_MODULE := libstagefright_m4vh263enc_test
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp b/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
new file mode 100644
index 0000000..db2c61a
--- /dev/null
+++ b/media/libstagefright/codecs/m4v_h263/enc/test/m4v_h263_enc_test.cpp
@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+#include <stdlib.h>
+
+#include "mp4enc_api.h"
+
+// Constants.
+enum {
+    kMaxWidth         = 720,
+    kMaxHeight        = 480,
+    kMaxFrameRate     = 30,
+    kMaxBitrate       = 2048, // in kbps.
+    kOutputBufferSize = 250 * 1024,
+    kIDRFrameRefreshIntervalInSec = 1, // in seconds.
+};
+
+int main(int argc, char *argv[]) {
+
+    if (argc < 8) {
+        fprintf(stderr, "Usage %s <input yuv> <output file> <mode> <width> "
+                        "<height> <frame rate> <bitrate in kbps>\n", argv[0]);
+        fprintf(stderr, "mode : h263 or mpeg4\n");
+        fprintf(stderr, "Max width %d\n", kMaxWidth);
+        fprintf(stderr, "Max height %d\n", kMaxHeight);
+        fprintf(stderr, "Max framerate %d\n", kMaxFrameRate);
+        fprintf(stderr, "Max bitrate %d kbps\n", kMaxBitrate);
+        return EXIT_FAILURE;
+    }
+
+    // Read mode.
+    bool isH263mode;
+    if (strcmp(argv[3], "mpeg4") == 0) {
+        isH263mode = false;
+    } else if (strcmp(argv[3], "h263") == 0) {
+        isH263mode = true;
+    } else {
+        fprintf(stderr, "Unsupported mode %s\n", argv[3]);
+        return EXIT_FAILURE;
+    }
+
+    // Read height and width.
+    int32_t width;
+    int32_t height;
+    width = atoi(argv[4]);
+    height = atoi(argv[5]);
+    if (width > kMaxWidth || height > kMaxHeight || width <= 0 || height <= 0) {
+        fprintf(stderr, "Unsupported dimensions %dx%d\n", width, height);
+        return EXIT_FAILURE;
+    }
+
+    if (width % 16 != 0 || height % 16 != 0) {
+        fprintf(stderr, "Video frame size %dx%d must be a multiple of 16\n",
+            width, height);
+        return EXIT_FAILURE;
+    }
+
+    // Read frame rate.
+    int32_t frameRate;
+    frameRate = atoi(argv[6]);
+    if (frameRate > kMaxFrameRate || frameRate <= 0) {
+        fprintf(stderr, "Unsupported frame rate %d\n", frameRate);
+        return EXIT_FAILURE;
+    }
+
+    // Read bitrate.
+    int32_t bitrate;
+    bitrate = atoi(argv[7]);
+    if (bitrate > kMaxBitrate || bitrate <= 0) {
+        fprintf(stderr, "Unsupported bitrate %d\n", bitrate);
+        return EXIT_FAILURE;
+    }
+
+    // Allocate input buffer.
+    uint8_t *inputBuf = (uint8_t *)malloc((width * height * 3) / 2);
+    assert(inputBuf != NULL);
+
+    // Allocate output buffer.
+    uint8_t *outputBuf = (uint8_t *)malloc(kOutputBufferSize);
+    assert(outputBuf != NULL);
+
+    // Open the input file.
+    FILE *fpInput = fopen(argv[1], "rb");
+    if (fpInput == NULL) {
+        fprintf(stderr, "Could not open %s\n", argv[1]);
+        free(inputBuf);
+        free(outputBuf);
+        return EXIT_FAILURE;
+    }
+
+    // Open the output file.
+    FILE *fpOutput = fopen(argv[2], "wb");
+    if (fpOutput == NULL) {
+        fprintf(stderr, "Could not open %s\n", argv[2]);
+        free(inputBuf);
+        free(outputBuf);
+        fclose(fpInput);
+        return EXIT_FAILURE;
+    }
+
+    // Initialize the encoder parameters.
+    tagvideoEncOptions encParams;
+    memset(&encParams, 0, sizeof(tagvideoEncOptions));
+    if (!PVGetDefaultEncOption(&encParams, 0)) {
+        fprintf(stderr, "Failed to get default encoding parameters\n");
+        free(inputBuf);
+        free(outputBuf);
+        fclose(fpInput);
+        fclose(fpOutput);
+        return EXIT_FAILURE;
+    }
+
+    if (isH263mode == false) {
+        encParams.encMode = COMBINE_MODE_WITH_ERR_RES;
+    } else {
+        encParams.encMode = H263_MODE;
+    }
+    encParams.encWidth[0] = width;
+    encParams.encHeight[0] = height;
+    encParams.encFrameRate[0] = frameRate;
+    encParams.rcType = VBR_1;
+    encParams.vbvDelay = 5.0f;
+    encParams.profile_level = CORE_PROFILE_LEVEL2;
+    encParams.packetSize = 32;
+    encParams.rvlcEnable = PV_OFF;
+    encParams.numLayers = 1;
+    encParams.timeIncRes = 1000;
+    encParams.tickPerSrc = encParams.timeIncRes / frameRate;
+
+    encParams.bitRate[0] = bitrate * 1024;
+    encParams.iQuant[0] = 15;
+    encParams.pQuant[0] = 12;
+    encParams.quantType[0] = 0;
+    encParams.noFrameSkipped = PV_OFF;
+
+    int32_t  IDRFrameRefreshIntervalInSec = kIDRFrameRefreshIntervalInSec;
+    if (IDRFrameRefreshIntervalInSec == 0) {
+        encParams.intraPeriod = 1;  // All I frames.
+    } else {
+        encParams.intraPeriod = (IDRFrameRefreshIntervalInSec * frameRate);
+    }
+
+    encParams.numIntraMB = 0;
+    encParams.sceneDetect = PV_ON;
+    encParams.searchRange = 16;
+    encParams.mv8x8Enable = PV_OFF;
+    encParams.gobHeaderInterval = 0;
+    encParams.useACPred = PV_ON;
+    encParams.intraDCVlcTh = 0;
+
+    // Initialize the handle.
+    tagvideoEncControls handle;
+    memset(&handle, 0, sizeof(tagvideoEncControls));
+
+    // Initialize the encoder.
+    if (!PVInitVideoEncoder(&handle, &encParams)) {
+        fprintf(stderr, "Failed to initialize the encoder\n");
+        return EXIT_FAILURE;
+    }
+
+    // Generate the header.
+    int32_t headerLength = kOutputBufferSize;
+    if (!PVGetVolHeader(&handle, outputBuf, &headerLength, 0)) {
+        fprintf(stderr, "Failed to get VOL header\n");
+        return EXIT_FAILURE;
+    }
+    fwrite(outputBuf, 1, headerLength, fpOutput);
+
+    // Core loop.
+    int32_t retVal = EXIT_SUCCESS;
+    int32_t frameSize = (width * height * 3) / 2;
+    int32_t numFramesEncoded = 0;
+
+    while (1) {
+        // Read the input frame.
+        int32_t bytesRead;
+        bytesRead = fread(inputBuf, 1, frameSize, fpInput);
+        if (bytesRead != frameSize) {
+            break; // End of file.
+        }
+
+        // Encode the input frame.
+        VideoEncFrameIO vin, vout;
+        memset(&vin, 0, sizeof(vin));
+        memset(&vout, 0, sizeof(vout));
+        vin.height = height; // height is multiple of 16.
+        vin.pitch = width; // width is multiple of 16.
+        vin.timestamp = (numFramesEncoded * 1000) / frameRate;  // in ms.
+        vin.yChan = inputBuf;
+        vin.uChan = vin.yChan + vin.height * vin.pitch;
+        vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2);
+
+        uint32_t modTimeMs = 0;
+        int32_t nLayer = 0;
+        MP4HintTrack hintTrack;
+        int32_t dataLength = kOutputBufferSize;
+        if (!PVEncodeVideoFrame(&handle, &vin, &vout,
+                &modTimeMs, outputBuf, &dataLength, &nLayer) ||
+            !PVGetHintTrack(&handle, &hintTrack)) {
+            fprintf(stderr, "Failed to encode frame or get hink track at "
+                    " frame %d\n", numFramesEncoded);
+            retVal = EXIT_FAILURE;
+            break;
+        }
+        PVGetOverrunBuffer(&handle);
+        numFramesEncoded++;
+
+        // Write the output.
+        fwrite(outputBuf, 1, dataLength, fpOutput);
+    }
+
+    // Close input and output file.
+    fclose(fpInput);
+    fclose(fpOutput);
+
+    // Free allocated memory.
+    free(inputBuf);
+    free(outputBuf);
+
+    // Close encoder instance.
+    PVCleanUpVideoEncoder(&handle);
+    return retVal;
+}
diff --git a/media/libstagefright/codecs/mp3dec/Android.mk b/media/libstagefright/codecs/mp3dec/Android.mk
index 948ae29..e611f68 100644
--- a/media/libstagefright/codecs/mp3dec/Android.mk
+++ b/media/libstagefright/codecs/mp3dec/Android.mk
@@ -83,3 +83,25 @@
 LOCAL_MODULE_TAGS := optional
 
 include $(BUILD_SHARED_LIBRARY)
+
+################################################################################
+include $(CLEAR_VARS)
+LOCAL_SRC_FILES := \
+        test/mp3dec_test.cpp  \
+        test/mp3reader.cpp
+
+LOCAL_C_INCLUDES := \
+        $(LOCAL_PATH)/src \
+        $(LOCAL_PATH)/include \
+        $(LOCAL_PATH)/test/include \
+        $(call include-path-for, audio-utils)
+
+LOCAL_STATIC_LIBRARIES := \
+        libstagefright_mp3dec libsndfile
+
+LOCAL_SHARED_LIBRARIES := libaudioutils
+
+LOCAL_MODULE := libstagefright_mp3dec_test
+LOCAL_MODULE_TAGS := tests
+
+include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/codecs/mp3dec/test/mp3dec_test.cpp b/media/libstagefright/codecs/mp3dec/test/mp3dec_test.cpp
new file mode 100644
index 0000000..26d62f3
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/test/mp3dec_test.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#include "pvmp3decoder_api.h"
+#include "mp3reader.h"
+#include <audio_utils/sndfile.h>
+
+using namespace std;
+
+enum {
+    kInputBufferSize = 10 * 1024,
+    kOutputBufferSize = 4608 * 2,
+};
+
+int main(int argc, const char **argv) {
+
+    if (argc != 3) {
+        fprintf(stderr, "Usage %s <input file> <output file>\n", argv[0]);
+        return EXIT_FAILURE;
+    }
+
+    // Initialize the config.
+    tPVMP3DecoderExternal config;
+    config.equalizerType = flat;
+    config.crcEnabled = false;
+
+    // Allocate the decoder memory.
+    uint32_t memRequirements = pvmp3_decoderMemRequirements();
+    void *decoderBuf = malloc(memRequirements);
+    assert(decoderBuf != NULL);
+
+    // Initialize the decoder.
+    pvmp3_InitDecoder(&config, decoderBuf);
+
+    // Open the input file.
+    Mp3Reader mp3Reader;
+    bool success = mp3Reader.init(argv[1]);
+    if (!success) {
+        fprintf(stderr, "Encountered error reading %s\n", argv[1]);
+        free(decoderBuf);
+        return EXIT_FAILURE;
+    }
+
+    // Open the output file.
+    SF_INFO sfInfo;
+    memset(&sfInfo, 0, sizeof(SF_INFO));
+    sfInfo.channels = mp3Reader.getNumChannels();
+    sfInfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16;
+    sfInfo.samplerate = mp3Reader.getSampleRate();
+    SNDFILE *handle = sf_open(argv[2], SFM_WRITE, &sfInfo);
+    if (handle == NULL) {
+        fprintf(stderr, "Encountered error writing %s\n", argv[2]);
+        mp3Reader.close();
+        free(decoderBuf);
+        return EXIT_FAILURE;
+    }
+
+    // Allocate input buffer.
+    uint8_t *inputBuf = static_cast<uint8_t*>(malloc(kInputBufferSize));
+    assert(inputBuf != NULL);
+
+    // Allocate output buffer.
+    int16_t *outputBuf = static_cast<int16_t*>(malloc(kOutputBufferSize));
+    assert(outputBuf != NULL);
+
+    // Decode loop.
+    int retVal = EXIT_SUCCESS;
+    while (1) {
+        // Read input from the file.
+        uint32_t bytesRead;
+        bool success = mp3Reader.getFrame(inputBuf, &bytesRead);
+        if (!success) break;
+
+        // Set the input config.
+        config.inputBufferCurrentLength = bytesRead;
+        config.inputBufferMaxLength = 0;
+        config.inputBufferUsedLength = 0;
+        config.pInputBuffer = inputBuf;
+        config.pOutputBuffer = outputBuf;
+        config.outputFrameSize = kOutputBufferSize / sizeof(int16_t);
+
+        ERROR_CODE decoderErr;
+        decoderErr = pvmp3_framedecoder(&config, decoderBuf);
+        if (decoderErr != NO_DECODING_ERROR) {
+            fprintf(stderr, "Decoder encountered error\n");
+            retVal = EXIT_FAILURE;
+            break;
+        }
+        sf_writef_short(handle, outputBuf,
+                        config.outputFrameSize / sfInfo.channels);
+    }
+
+    // Close input reader and output writer.
+    mp3Reader.close();
+    sf_close(handle);
+
+    // Free allocated memory.
+    free(inputBuf);
+    free(outputBuf);
+    free(decoderBuf);
+
+    return retVal;
+}
diff --git a/media/libstagefright/codecs/mp3dec/test/mp3reader.cpp b/media/libstagefright/codecs/mp3dec/test/mp3reader.cpp
new file mode 100644
index 0000000..b3138ec
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/test/mp3reader.cpp
@@ -0,0 +1,425 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <stdint.h>
+#include "mp3reader.h"
+
+static uint32_t U32_AT(const uint8_t *ptr) {
+    return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
+}
+
+static bool parseHeader(
+        uint32_t header, size_t *frame_size,
+        uint32_t *out_sampling_rate = NULL, uint32_t *out_channels = NULL ,
+        uint32_t *out_bitrate = NULL, uint32_t *out_num_samples = NULL) {
+    *frame_size = 0;
+
+    if (out_sampling_rate) {
+        *out_sampling_rate = 0;
+    }
+
+    if (out_channels) {
+        *out_channels = 0;
+    }
+
+    if (out_bitrate) {
+        *out_bitrate = 0;
+    }
+
+    if (out_num_samples) {
+        *out_num_samples = 1152;
+    }
+
+    if ((header & 0xffe00000) != 0xffe00000) {
+        return false;
+    }
+
+    unsigned version = (header >> 19) & 3;
+
+    if (version == 0x01) {
+        return false;
+    }
+
+    unsigned layer = (header >> 17) & 3;
+
+    if (layer == 0x00) {
+        return false;
+    }
+
+    unsigned bitrate_index = (header >> 12) & 0x0f;
+
+    if (bitrate_index == 0 || bitrate_index == 0x0f) {
+        // Disallow "free" bitrate.
+        return false;
+    }
+
+    unsigned sampling_rate_index = (header >> 10) & 3;
+
+    if (sampling_rate_index == 3) {
+        return false;
+    }
+
+    static const int kSamplingRateV1[] = { 44100, 48000, 32000 };
+    int sampling_rate = kSamplingRateV1[sampling_rate_index];
+    if (version == 2 /* V2 */) {
+        sampling_rate /= 2;
+    } else if (version == 0 /* V2.5 */) {
+        sampling_rate /= 4;
+    }
+
+    unsigned padding = (header >> 9) & 1;
+
+    if (layer == 3) {
+        // layer I
+
+        static const int kBitrateV1[] = {
+            32, 64, 96, 128, 160, 192, 224, 256,
+            288, 320, 352, 384, 416, 448
+        };
+
+        static const int kBitrateV2[] = {
+            32, 48, 56, 64, 80, 96, 112, 128,
+            144, 160, 176, 192, 224, 256
+        };
+
+        int bitrate =
+            (version == 3 /* V1 */)
+                ? kBitrateV1[bitrate_index - 1]
+                : kBitrateV2[bitrate_index - 1];
+
+        if (out_bitrate) {
+            *out_bitrate = bitrate;
+        }
+
+        *frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
+
+        if (out_num_samples) {
+            *out_num_samples = 384;
+        }
+    } else {
+        // layer II or III
+
+        static const int kBitrateV1L2[] = {
+            32, 48, 56, 64, 80, 96, 112, 128,
+            160, 192, 224, 256, 320, 384
+        };
+
+        static const int kBitrateV1L3[] = {
+            32, 40, 48, 56, 64, 80, 96, 112,
+            128, 160, 192, 224, 256, 320
+        };
+
+        static const int kBitrateV2[] = {
+            8, 16, 24, 32, 40, 48, 56, 64,
+            80, 96, 112, 128, 144, 160
+        };
+
+        int bitrate;
+        if (version == 3 /* V1 */) {
+            bitrate = (layer == 2 /* L2 */)
+                ? kBitrateV1L2[bitrate_index - 1]
+                : kBitrateV1L3[bitrate_index - 1];
+
+            if (out_num_samples) {
+                *out_num_samples = 1152;
+            }
+        } else {
+            // V2 (or 2.5)
+
+            bitrate = kBitrateV2[bitrate_index - 1];
+            if (out_num_samples) {
+                *out_num_samples = (layer == 1 /* L3 */) ? 576 : 1152;
+            }
+        }
+
+        if (out_bitrate) {
+            *out_bitrate = bitrate;
+        }
+
+        if (version == 3 /* V1 */) {
+            *frame_size = 144000 * bitrate / sampling_rate + padding;
+        } else {
+            // V2 or V2.5
+            size_t tmp = (layer == 1 /* L3 */) ? 72000 : 144000;
+            *frame_size = tmp * bitrate / sampling_rate + padding;
+        }
+    }
+
+    if (out_sampling_rate) {
+        *out_sampling_rate = sampling_rate;
+    }
+
+    if (out_channels) {
+        int channel_mode = (header >> 6) & 3;
+
+        *out_channels = (channel_mode == 3) ? 1 : 2;
+    }
+
+    return true;
+}
+
+// Mask to extract the version, layer, sampling rate parts of the MP3 header,
+// which should be same for all MP3 frames.
+static const uint32_t kMask = 0xfffe0c00;
+
+static ssize_t sourceReadAt(FILE *fp, off64_t offset, void *data, size_t size) {
+    int retVal = fseek(fp, offset, SEEK_SET);
+    if (retVal != EXIT_SUCCESS) {
+        return 0;
+    } else {
+       return fread(data, 1, size, fp);
+    }
+}
+
+// Resync to next valid MP3 frame in the file.
+static bool resync(
+        FILE *fp, uint32_t match_header,
+        off64_t *inout_pos, uint32_t *out_header) {
+
+    if (*inout_pos == 0) {
+        // Skip an optional ID3 header if syncing at the very beginning
+        // of the datasource.
+
+        for (;;) {
+            uint8_t id3header[10];
+            int retVal = sourceReadAt(fp, *inout_pos, id3header,
+                                      sizeof(id3header));
+            if (retVal < (ssize_t)sizeof(id3header)) {
+                // If we can't even read these 10 bytes, we might as well bail
+                // out, even if there _were_ 10 bytes of valid mp3 audio data...
+                return false;
+            }
+
+            if (memcmp("ID3", id3header, 3)) {
+                break;
+            }
+
+            // Skip the ID3v2 header.
+
+            size_t len =
+                ((id3header[6] & 0x7f) << 21)
+                | ((id3header[7] & 0x7f) << 14)
+                | ((id3header[8] & 0x7f) << 7)
+                | (id3header[9] & 0x7f);
+
+            len += 10;
+
+            *inout_pos += len;
+        }
+
+    }
+
+    off64_t pos = *inout_pos;
+    bool valid = false;
+
+    const int32_t kMaxReadBytes = 1024;
+    const int32_t kMaxBytesChecked = 128 * 1024;
+    uint8_t buf[kMaxReadBytes];
+    ssize_t bytesToRead = kMaxReadBytes;
+    ssize_t totalBytesRead = 0;
+    ssize_t remainingBytes = 0;
+    bool reachEOS = false;
+    uint8_t *tmp = buf;
+
+    do {
+        if (pos >= *inout_pos + kMaxBytesChecked) {
+            // Don't scan forever.
+            break;
+        }
+
+        if (remainingBytes < 4) {
+            if (reachEOS) {
+                break;
+            } else {
+                memcpy(buf, tmp, remainingBytes);
+                bytesToRead = kMaxReadBytes - remainingBytes;
+
+                /*
+                 * The next read position should start from the end of
+                 * the last buffer, and thus should include the remaining
+                 * bytes in the buffer.
+                 */
+                totalBytesRead = sourceReadAt(fp, pos + remainingBytes,
+                                             buf + remainingBytes, bytesToRead);
+
+                if (totalBytesRead <= 0) {
+                    break;
+                }
+                reachEOS = (totalBytesRead != bytesToRead);
+                remainingBytes += totalBytesRead;
+                tmp = buf;
+                continue;
+            }
+        }
+
+        uint32_t header = U32_AT(tmp);
+
+        if (match_header != 0 && (header & kMask) != (match_header & kMask)) {
+            ++pos;
+            ++tmp;
+            --remainingBytes;
+            continue;
+        }
+
+        size_t frame_size;
+        uint32_t sample_rate, num_channels, bitrate;
+        if (!parseHeader(
+                    header, &frame_size,
+                    &sample_rate, &num_channels, &bitrate)) {
+            ++pos;
+            ++tmp;
+            --remainingBytes;
+            continue;
+        }
+
+        // We found what looks like a valid frame,
+        // now find its successors.
+
+        off64_t test_pos = pos + frame_size;
+
+        valid = true;
+        const int FRAME_MATCH_REQUIRED = 3;
+        for (int j = 0; j < FRAME_MATCH_REQUIRED; ++j) {
+            uint8_t tmp[4];
+            ssize_t retval = sourceReadAt(fp, test_pos, tmp, sizeof(tmp));
+            if (retval < (ssize_t)sizeof(tmp)) {
+                valid = false;
+                break;
+            }
+
+            uint32_t test_header = U32_AT(tmp);
+
+            if ((test_header & kMask) != (header & kMask)) {
+                valid = false;
+                break;
+            }
+
+            size_t test_frame_size;
+            if (!parseHeader(test_header, &test_frame_size)) {
+                valid = false;
+                break;
+            }
+
+            test_pos += test_frame_size;
+        }
+
+        if (valid) {
+            *inout_pos = pos;
+
+            if (out_header != NULL) {
+                *out_header = header;
+            }
+        }
+
+        ++pos;
+        ++tmp;
+        --remainingBytes;
+    } while (!valid);
+
+    return valid;
+}
+
+Mp3Reader::Mp3Reader() : mFp(NULL) {
+}
+
+// Initialize the MP3 reader.
+bool Mp3Reader::init(const char *file) {
+
+    // Open the file.
+    mFp = fopen(file, "rb");
+    if (mFp == NULL) return false;
+
+    // Sync to the first valid frame.
+    off64_t pos = 0;
+    uint32_t header;
+    bool success = resync(mFp, 0 /*match_header*/, &pos, &header);
+    if (success == false) return false;
+
+    mCurrentPos  = pos;
+    mFixedHeader = header;
+
+    size_t frame_size;
+    return parseHeader(header, &frame_size, &mSampleRate,
+                       &mNumChannels, &mBitrate);
+}
+
+// Get the next valid MP3 frame.
+bool Mp3Reader::getFrame(void *buffer, uint32_t *size) {
+
+    size_t frame_size;
+    uint32_t bitrate;
+    uint32_t num_samples;
+    uint32_t sample_rate;
+    for (;;) {
+        ssize_t n = sourceReadAt(mFp, mCurrentPos, buffer, 4);
+        if (n < 4) {
+            return false;
+        }
+
+        uint32_t header = U32_AT((const uint8_t *)buffer);
+
+        if ((header & kMask) == (mFixedHeader & kMask)
+            && parseHeader(
+                header, &frame_size, &sample_rate, NULL /*out_channels*/,
+                &bitrate, &num_samples)) {
+            break;
+        }
+
+        // Lost sync.
+        off64_t pos = mCurrentPos;
+        if (!resync(mFp, mFixedHeader, &pos, NULL /*out_header*/)) {
+            // Unable to resync. Signalling end of stream.
+            return false;
+        }
+
+        mCurrentPos = pos;
+
+        // Try again with the new position.
+    }
+    ssize_t n = sourceReadAt(mFp, mCurrentPos, buffer, frame_size);
+    if (n < (ssize_t)frame_size) {
+        return false;
+    }
+
+    *size = frame_size;
+    mCurrentPos += frame_size;
+    return true;
+}
+
+// Close the MP3 reader.
+void Mp3Reader::close() {
+    assert(mFp != NULL);
+    fclose(mFp);
+}
+
+Mp3Reader::~Mp3Reader() {
+}
diff --git a/media/libstagefright/codecs/mp3dec/test/mp3reader.h b/media/libstagefright/codecs/mp3dec/test/mp3reader.h
new file mode 100644
index 0000000..871f664
--- /dev/null
+++ b/media/libstagefright/codecs/mp3dec/test/mp3reader.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef MP3READER_H_
+#define MP3READER_H_
+
+class Mp3Reader {
+public:
+    Mp3Reader();
+    bool init(const char *file);
+    bool getFrame(void *buffer, uint32_t *size);
+    uint32_t getSampleRate() { return mSampleRate;}
+    uint32_t getNumChannels() { return mNumChannels;}
+    void close();
+    ~Mp3Reader();
+private:
+    FILE    *mFp;
+    uint32_t mFixedHeader;
+    off64_t  mCurrentPos;
+    uint32_t mSampleRate;
+    uint32_t mNumChannels;
+    uint32_t mBitrate;
+};
+
+
+#endif /* MP3READER_H_ */
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index e161fb8..cd6c3b1 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -102,7 +102,6 @@
 }
 
 bool SoftVPX::outputBuffers(bool flushDecoder, bool display, bool eos, bool *portWillReset) {
-    List<BufferInfo *> &inQueue = getPortQueue(0);
     List<BufferInfo *> &outQueue = getPortQueue(1);
     BufferInfo *outInfo = NULL;
     OMX_BUFFERHEADERTYPE *outHeader = NULL;
@@ -193,7 +192,6 @@
     List<BufferInfo *> &inQueue = getPortQueue(0);
     List<BufferInfo *> &outQueue = getPortQueue(1);
     bool EOSseen = false;
-    vpx_codec_err_t err;
     bool portWillReset = false;
 
     while ((mEOSStatus == INPUT_EOS_SEEN || !inQueue.empty())
@@ -217,8 +215,6 @@
         OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
         mTimeStamps[mTimeStampIdx] = inHeader->nTimeStamp;
 
-        BufferInfo *outInfo = *outQueue.begin();
-        OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
         if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
             mEOSStatus = INPUT_EOS_SEEN;
             EOSseen = true;
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h
index 91e38b8..1992885 100644
--- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/armCOMM.h
@@ -86,7 +86,7 @@
 
 /* Alignment operation */
 
-#define armAlignToBytes(Ptr,N)      (Ptr + ( ((N-(int)Ptr)&(N-1)) / sizeof(*Ptr) ))
+#define armAlignToBytes(Ptr,N)      (Ptr + ( ((N-(intptr_t)Ptr)&(N-1)) / sizeof(*Ptr) ))
 #define armAlignTo2Bytes(Ptr)       armAlignToBytes(Ptr,2)
 #define armAlignTo4Bytes(Ptr)       armAlignToBytes(Ptr,4)
 #define armAlignTo8Bytes(Ptr)       armAlignToBytes(Ptr,8)
@@ -98,8 +98,8 @@
 #define armRetDataErrIf(condition, code) if(condition) { return (code); }
 
 #ifndef ALIGNMENT_DOESNT_MATTER
-#define armIsByteAligned(Ptr,N)     ((((int)(Ptr)) % N)==0)
-#define armNotByteAligned(Ptr,N)    ((((int)(Ptr)) % N)!=0)
+#define armIsByteAligned(Ptr,N)     ((((intptr_t)(Ptr)) % N)==0)
+#define armNotByteAligned(Ptr,N)    ((((intptr_t)(Ptr)) % N)!=0)
 #else
 #define armIsByteAligned(Ptr,N)     (1)
 #define armNotByteAligned(Ptr,N)    (0)
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h
index fbb97e2..7304863 100644
--- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/armCOMM.h
@@ -86,7 +86,7 @@
 
 /* Alignment operation */
 
-#define armAlignToBytes(Ptr,N)      (Ptr + ( ((N-(int)Ptr)&(N-1)) / sizeof(*Ptr) ))
+#define armAlignToBytes(Ptr,N)      (Ptr + ( ((N-(intptr_t)Ptr)&(N-1)) / sizeof(*Ptr) ))
 #define armAlignTo2Bytes(Ptr)       armAlignToBytes(Ptr,2)
 #define armAlignTo4Bytes(Ptr)       armAlignToBytes(Ptr,4)
 #define armAlignTo8Bytes(Ptr)       armAlignToBytes(Ptr,8)
@@ -98,8 +98,8 @@
 #define armRetDataErrIf(condition, code) if(condition) { return (code); }
 
 #ifndef ALIGNMENT_DOESNT_MATTER
-#define armIsByteAligned(Ptr,N)     ((((int)(Ptr)) % N)==0)
-#define armNotByteAligned(Ptr,N)    ((((int)(Ptr)) % N)!=0)
+#define armIsByteAligned(Ptr,N)     ((((intptr_t)(Ptr)) % N)==0)
+#define armNotByteAligned(Ptr,N)    ((((intptr_t)(Ptr)) % N)!=0)
 #else
 #define armIsByteAligned(Ptr,N)     (1)
 #define armNotByteAligned(Ptr,N)    (0)
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index 855ffdc..5620cf8 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -898,11 +898,6 @@
     if (!strncmp(value.c_str(), "Basic", 5)) {
         mAuthType = BASIC;
     } else {
-#if !defined(HAVE_ANDROID_OS)
-        // We don't have access to the MD5 implementation on the simulator,
-        // so we won't support digest authentication.
-        return false;
-#endif
 
         CHECK(!strncmp(value.c_str(), "Digest", 6));
         mAuthType = DIGEST;
@@ -919,7 +914,6 @@
     return true;
 }
 
-#if defined(HAVE_ANDROID_OS)
 static void H(const AString &s, AString *out) {
     out->clear();
 
@@ -948,7 +942,6 @@
         out->append(&nibble, 1);
     }
 }
-#endif
 
 static void GetMethodAndURL(
         const AString &request, AString *method, AString *url) {
@@ -990,7 +983,6 @@
         return;
     }
 
-#if defined(HAVE_ANDROID_OS)
     CHECK_EQ((int)mAuthType, (int)DIGEST);
 
     AString method, url;
@@ -1039,7 +1031,6 @@
     fragment.append("\r\n");
 
     request->insert(fragment, i + 2);
-#endif
 }
 
 void ARTSPConnection::addUserAgent(AString *request) const {
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index 07199e3..3e0f239 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -214,10 +214,11 @@
             mResponse.setTransactionID(transaction);
             ALOGV("sending response %04X", mResponse.getResponseCode());
             ret = mResponse.write(fd);
+            const int savedErrno = errno;
             mResponse.dump();
             if (ret < 0) {
                 ALOGE("request write returned %d, errno: %d", ret, errno);
-                if (errno == ECANCELED) {
+                if (savedErrno == ECANCELED) {
                     // return to top of loop and wait for next command
                     continue;
                 }
@@ -787,15 +788,19 @@
 
     // then transfer the file
     int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr);
+    if (ret < 0) {
+        if (errno == ECANCELED) {
+            result = MTP_RESPONSE_TRANSACTION_CANCELLED;
+        } else {
+            result = MTP_RESPONSE_GENERAL_ERROR;
+        }
+    } else {
+        result = MTP_RESPONSE_OK;
+    }
+
     ALOGV("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret);
     close(mfr.fd);
-    if (ret < 0) {
-        if (errno == ECANCELED)
-            return MTP_RESPONSE_TRANSACTION_CANCELLED;
-        else
-            return MTP_RESPONSE_GENERAL_ERROR;
-    }
-    return MTP_RESPONSE_OK;
+    return result;
 }
 
 MtpResponseCode MtpServer::doGetThumb() {
@@ -864,14 +869,15 @@
     // transfer the file
     int ret = ioctl(mFD, MTP_SEND_FILE_WITH_HEADER, (unsigned long)&mfr);
     ALOGV("MTP_SEND_FILE_WITH_HEADER returned %d\n", ret);
-    close(mfr.fd);
+    result = MTP_RESPONSE_OK;
     if (ret < 0) {
         if (errno == ECANCELED)
-            return MTP_RESPONSE_TRANSACTION_CANCELLED;
+            result = MTP_RESPONSE_TRANSACTION_CANCELLED;
         else
-            return MTP_RESPONSE_GENERAL_ERROR;
+            result = MTP_RESPONSE_GENERAL_ERROR;
     }
-    return MTP_RESPONSE_OK;
+    close(mfr.fd);
+    return result;
 }
 
 MtpResponseCode MtpServer::doSendObjectInfo() {
@@ -985,6 +991,7 @@
     MtpResponseCode result = MTP_RESPONSE_OK;
     mode_t mask;
     int ret, initialData;
+    bool isCanceled = false;
 
     if (mSendObjectHandle == kInvalidObjectHandle) {
         ALOGE("Expected SendObjectInfo before SendObject");
@@ -1032,6 +1039,10 @@
             ALOGV("receiving %s\n", (const char *)mSendObjectFilePath);
             // transfer the file
             ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr);
+            if ((ret < 0) && (errno == ECANCELED)) {
+                isCanceled = true;
+            }
+
             ALOGV("MTP_RECEIVE_FILE returned %d\n", ret);
         }
     }
@@ -1039,7 +1050,7 @@
 
     if (ret < 0) {
         unlink(mSendObjectFilePath);
-        if (errno == ECANCELED)
+        if (isCanceled)
             result = MTP_RESPONSE_TRANSACTION_CANCELLED;
         else
             result = MTP_RESPONSE_GENERAL_ERROR;
@@ -1208,6 +1219,7 @@
         length -= initialData;
     }
 
+    bool isCanceled = false;
     if (ret < 0) {
         ALOGE("failed to write initial data");
     } else {
@@ -1219,12 +1231,15 @@
 
             // transfer the file
             ret = ioctl(mFD, MTP_RECEIVE_FILE, (unsigned long)&mfr);
+            if ((ret < 0) && (errno == ECANCELED)) {
+                isCanceled = true;
+            }
             ALOGV("MTP_RECEIVE_FILE returned %d", ret);
         }
     }
     if (ret < 0) {
         mResponse.setParameter(1, 0);
-        if (errno == ECANCELED)
+        if (isCanceled)
             return MTP_RESPONSE_TRANSACTION_CANCELLED;
         else
             return MTP_RESPONSE_GENERAL_ERROR;