Merge "Add multi-mic support for the noise suppression pre-processing effect"
diff --git a/media/libeffects/preprocessing/Android.mk b/media/libeffects/preprocessing/Android.mk
index 82415d5..4e4b094 100644
--- a/media/libeffects/preprocessing/Android.mk
+++ b/media/libeffects/preprocessing/Android.mk
@@ -12,7 +12,7 @@
 
 LOCAL_C_INCLUDES += \
     external/webrtc \
-    external/webrtc/webrtc/modules/interface \
+    external/webrtc/webrtc/modules/include \
     external/webrtc/webrtc/modules/audio_processing/include \
     $(call include-path-for, audio-effects)
 
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index 0a3298e..0b4ab3d 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -934,8 +934,8 @@
 int Session_SetConfig(preproc_session_t *session, effect_config_t *config)
 {
     uint32_t sr;
-    uint32_t inCnl = audio_channel_count_from_out_mask(config->inputCfg.channels);
-    uint32_t outCnl = audio_channel_count_from_out_mask(config->outputCfg.channels);
+    uint32_t inCnl = audio_channel_count_from_in_mask(config->inputCfg.channels);
+    uint32_t outCnl = audio_channel_count_from_in_mask(config->outputCfg.channels);
 
     if (config->inputCfg.samplingRate != config->outputCfg.samplingRate ||
         config->inputCfg.format != config->outputCfg.format ||
@@ -958,10 +958,10 @@
     }
 
     const webrtc::ProcessingConfig processing_config = {
-      {{static_cast<int>(session->apmSamplingRate), static_cast<int>(inCnl)},
-       {static_cast<int>(session->apmSamplingRate), static_cast<int>(outCnl)},
-       {static_cast<int>(session->apmSamplingRate), static_cast<int>(inCnl)},
-       {static_cast<int>(session->apmSamplingRate), static_cast<int>(inCnl)}}};
+      {{static_cast<int>(session->apmSamplingRate), inCnl},
+       {static_cast<int>(session->apmSamplingRate), outCnl},
+       {static_cast<int>(session->apmSamplingRate), inCnl},
+       {static_cast<int>(session->apmSamplingRate), inCnl}}};
     status = session->apm->Initialize(processing_config);
     if (status < 0) {
         return -EINVAL;
@@ -1079,14 +1079,10 @@
     }
     uint32_t inCnl = audio_channel_count_from_out_mask(config->inputCfg.channels);
     const webrtc::ProcessingConfig processing_config = {
-       {{static_cast<int>(session->apmSamplingRate),
-         static_cast<int>(session->inChannelCount)},
-        {static_cast<int>(session->apmSamplingRate),
-         static_cast<int>(session->outChannelCount)},
-        {static_cast<int>(session->apmSamplingRate),
-         static_cast<int>(inCnl)},
-        {static_cast<int>(session->apmSamplingRate),
-         static_cast<int>(inCnl)}}};
+       {{static_cast<int>(session->apmSamplingRate), session->inChannelCount},
+        {static_cast<int>(session->apmSamplingRate), session->outChannelCount},
+        {static_cast<int>(session->apmSamplingRate), inCnl},
+        {static_cast<int>(session->apmSamplingRate), inCnl}}};
     int status = session->apm->Initialize(processing_config);
     if (status < 0) {
         return -EINVAL;
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index 666b747..9d5d996 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -240,6 +240,7 @@
             errno = 0;
             (void) syscall(__NR_futex, &cblk->mFutex,
                     mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts);
+            status_t error = errno; // clock_gettime can affect errno
             // update total elapsed time spent waiting
             if (measure) {
                 struct timespec after;
@@ -257,7 +258,7 @@
                 before = after;
                 beforeIsValid = true;
             }
-            switch (errno) {
+            switch (error) {
             case 0:            // normal wakeup by server, or by binderDied()
             case EWOULDBLOCK:  // benign race condition with server
             case EINTR:        // wait was interrupted by signal or other spurious wakeup
@@ -265,7 +266,7 @@
                 // FIXME these error/non-0 status are being dropped
                 break;
             default:
-                status = errno;
+                status = error;
                 ALOGE("%s unexpected error %s", __func__, strerror(status));
                 goto end;
             }
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 1c44285..72bae5c 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -1,7 +1,6 @@
 LOCAL_PATH:= $(call my-dir)
 include $(CLEAR_VARS)
 
-include frameworks/av/media/libstagefright/codecs/common/Config.mk
 
 LOCAL_SRC_FILES:=                         \
         ACodec.cpp                        \
diff --git a/media/libstagefright/codecs/aacenc/Android.mk b/media/libstagefright/codecs/aacenc/Android.mk
index 88690cf..266f01b 100644
--- a/media/libstagefright/codecs/aacenc/Android.mk
+++ b/media/libstagefright/codecs/aacenc/Android.mk
@@ -1,6 +1,5 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
-include frameworks/av/media/libstagefright/codecs/common/Config.mk
 
 AAC_LIBRARY = fraunhofer
 
@@ -35,24 +34,28 @@
 	src/transform.c \
 	src/memalign.c
 
-ifeq ($(VOTT), v5)
-LOCAL_SRC_FILES += \
-	src/asm/ARMV5E/AutoCorrelation_v5.s \
-	src/asm/ARMV5E/band_nrg_v5.s \
-	src/asm/ARMV5E/CalcWindowEnergy_v5.s \
-	src/asm/ARMV5E/PrePostMDCT_v5.s \
-	src/asm/ARMV5E/R4R8First_v5.s \
-	src/asm/ARMV5E/Radix4FFT_v5.s
-endif
+ifneq ($(ARCH_ARM_HAVE_NEON),true)
+    LOCAL_SRC_FILES_arm := \
+        src/asm/ARMV5E/AutoCorrelation_v5.s \
+        src/asm/ARMV5E/band_nrg_v5.s \
+        src/asm/ARMV5E/CalcWindowEnergy_v5.s \
+        src/asm/ARMV5E/PrePostMDCT_v5.s \
+        src/asm/ARMV5E/R4R8First_v5.s \
+        src/asm/ARMV5E/Radix4FFT_v5.s
 
-ifeq ($(VOTT), v7)
-LOCAL_SRC_FILES += \
-	src/asm/ARMV5E/AutoCorrelation_v5.s \
-	src/asm/ARMV5E/band_nrg_v5.s \
-	src/asm/ARMV5E/CalcWindowEnergy_v5.s \
-	src/asm/ARMV7/PrePostMDCT_v7.s \
-	src/asm/ARMV7/R4R8First_v7.s \
-	src/asm/ARMV7/Radix4FFT_v7.s
+    LOCAL_CFLAGS_arm := -DARMV5E -DARM_INASM -DARMV5_INASM
+    LOCAL_C_INCLUDES_arm := $(LOCAL_PATH)/src/asm/ARMV5E
+else
+    LOCAL_SRC_FILES_arm := \
+        src/asm/ARMV5E/AutoCorrelation_v5.s \
+        src/asm/ARMV5E/band_nrg_v5.s \
+        src/asm/ARMV5E/CalcWindowEnergy_v5.s \
+        src/asm/ARMV7/PrePostMDCT_v7.s \
+        src/asm/ARMV7/R4R8First_v7.s \
+        src/asm/ARMV7/Radix4FFT_v7.s
+    LOCAL_CFLAGS_arm := -DARMV5E -DARMV7Neon -DARM_INASM -DARMV5_INASM -DARMV6_INASM
+    LOCAL_C_INCLUDES_arm := $(LOCAL_PATH)/src/asm/ARMV5E
+    LOCAL_C_INCLUDES_arm += $(LOCAL_PATH)/src/asm/ARMV7
 endif
 
 LOCAL_MODULE := libstagefright_aacenc
@@ -71,17 +74,6 @@
 	$(LOCAL_PATH)/inc \
 	$(LOCAL_PATH)/basic_op
 
-ifeq ($(VOTT), v5)
-LOCAL_CFLAGS += -DARMV5E -DARM_INASM -DARMV5_INASM
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
-endif
-
-ifeq ($(VOTT), v7)
-LOCAL_CFLAGS += -DARMV5E -DARMV7Neon -DARM_INASM -DARMV5_INASM -DARMV6_INASM
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV7
-endif
-
 LOCAL_CFLAGS += -Werror
 LOCAL_CLANG := true
 LOCAL_SANITIZE := signed-integer-overflow unsigned-integer-overflow
diff --git a/media/libstagefright/codecs/amrwbenc/Android.mk b/media/libstagefright/codecs/amrwbenc/Android.mk
index fd6d007..4d12f82 100644
--- a/media/libstagefright/codecs/amrwbenc/Android.mk
+++ b/media/libstagefright/codecs/amrwbenc/Android.mk
@@ -1,8 +1,5 @@
 LOCAL_PATH := $(call my-dir)
 include $(CLEAR_VARS)
-include frameworks/av/media/libstagefright/codecs/common/Config.mk
-
-
 
 LOCAL_SRC_FILES := \
 	src/autocorr.c \
@@ -53,37 +50,39 @@
 	src/weight_a.c \
 	src/mem_align.c
 
+ifneq ($(ARCH_ARM_HAVE_NEON),true)
+    LOCAL_SRC_FILES_arm := \
+        src/asm/ARMV5E/convolve_opt.s \
+        src/asm/ARMV5E/cor_h_vec_opt.s \
+        src/asm/ARMV5E/Deemph_32_opt.s \
+        src/asm/ARMV5E/Dot_p_opt.s \
+        src/asm/ARMV5E/Filt_6k_7k_opt.s \
+        src/asm/ARMV5E/Norm_Corr_opt.s \
+        src/asm/ARMV5E/pred_lt4_1_opt.s \
+        src/asm/ARMV5E/residu_asm_opt.s \
+        src/asm/ARMV5E/scale_sig_opt.s \
+        src/asm/ARMV5E/Syn_filt_32_opt.s \
+        src/asm/ARMV5E/syn_filt_opt.s
 
-ifeq ($(VOTT), v5)
-LOCAL_SRC_FILES += \
-	src/asm/ARMV5E/convolve_opt.s \
-	src/asm/ARMV5E/cor_h_vec_opt.s \
-	src/asm/ARMV5E/Deemph_32_opt.s \
-	src/asm/ARMV5E/Dot_p_opt.s \
-	src/asm/ARMV5E/Filt_6k_7k_opt.s \
-	src/asm/ARMV5E/Norm_Corr_opt.s \
-	src/asm/ARMV5E/pred_lt4_1_opt.s \
-	src/asm/ARMV5E/residu_asm_opt.s \
-	src/asm/ARMV5E/scale_sig_opt.s \
-	src/asm/ARMV5E/Syn_filt_32_opt.s \
-	src/asm/ARMV5E/syn_filt_opt.s
+    LOCAL_CFLAGS_arm := -DARM -DASM_OPT
+    LOCAL_C_INCLUDES_arm = $(LOCAL_PATH)/src/asm/ARMV5E
+else
+    LOCAL_SRC_FILES_arm := \
+        src/asm/ARMV7/convolve_neon.s \
+        src/asm/ARMV7/cor_h_vec_neon.s \
+        src/asm/ARMV7/Deemph_32_neon.s \
+        src/asm/ARMV7/Dot_p_neon.s \
+        src/asm/ARMV7/Filt_6k_7k_neon.s \
+        src/asm/ARMV7/Norm_Corr_neon.s \
+        src/asm/ARMV7/pred_lt4_1_neon.s \
+        src/asm/ARMV7/residu_asm_neon.s \
+        src/asm/ARMV7/scale_sig_neon.s \
+        src/asm/ARMV7/Syn_filt_32_neon.s \
+        src/asm/ARMV7/syn_filt_neon.s
 
-endif
-
-ifeq ($(VOTT), v7)
-LOCAL_SRC_FILES += \
-	src/asm/ARMV7/convolve_neon.s \
-	src/asm/ARMV7/cor_h_vec_neon.s \
-	src/asm/ARMV7/Deemph_32_neon.s \
-	src/asm/ARMV7/Dot_p_neon.s \
-	src/asm/ARMV7/Filt_6k_7k_neon.s \
-	src/asm/ARMV7/Norm_Corr_neon.s \
-	src/asm/ARMV7/pred_lt4_1_neon.s \
-	src/asm/ARMV7/residu_asm_neon.s \
-	src/asm/ARMV7/scale_sig_neon.s \
-	src/asm/ARMV7/Syn_filt_32_neon.s \
-	src/asm/ARMV7/syn_filt_neon.s
-
+    LOCAL_CFLAGS_arm := -DARM -DARMV7 -DASM_OPT
+    LOCAL_C_INCLUDES_arm := $(LOCAL_PATH)/src/asm/ARMV5E
+    LOCAL_C_INCLUDES_arm += $(LOCAL_PATH)/src/asm/ARMV7
 endif
 
 LOCAL_MODULE := libstagefright_amrwbenc
@@ -101,20 +100,9 @@
 	$(LOCAL_PATH)/src \
 	$(LOCAL_PATH)/inc
 
-ifeq ($(VOTT), v5)
-LOCAL_CFLAGS += -DARM -DASM_OPT
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
-endif
-
-ifeq ($(VOTT), v7)
-LOCAL_CFLAGS += -DARM -DARMV7 -DASM_OPT
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV5E
-LOCAL_C_INCLUDES += $(LOCAL_PATH)/src/asm/ARMV7
-endif
-
 LOCAL_CFLAGS += -Werror
 LOCAL_CLANG := true
-LOCAL_SANITIZE := signed-integer-overflow
+#LOCAL_SANITIZE := signed-integer-overflow
 
 include $(BUILD_STATIC_LIBRARY)
 
@@ -132,7 +120,7 @@
 
 LOCAL_CFLAGS += -Werror
 LOCAL_CLANG := true
-LOCAL_SANITIZE := signed-integer-overflow
+#LOCAL_SANITIZE := signed-integer-overflow
 
 LOCAL_STATIC_LIBRARIES := \
         libstagefright_amrwbenc
diff --git a/media/libstagefright/codecs/amrwbenc/inc/basic_op.h b/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
index 4021579..5808437 100644
--- a/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
+++ b/media/libstagefright/codecs/amrwbenc/inc/basic_op.h
@@ -608,6 +608,7 @@
 |___________________________________________________________________________|
 */
 
+__attribute__((no_sanitize("integer")))
 static_vo Word32 L_sub (Word32 L_var1, Word32 L_var2)
 {
     Word32 L_var_out;
diff --git a/media/libstagefright/codecs/amrwbenc/src/deemph.c b/media/libstagefright/codecs/amrwbenc/src/deemph.c
index a25a2c8..cc27f6e 100644
--- a/media/libstagefright/codecs/amrwbenc/src/deemph.c
+++ b/media/libstagefright/codecs/amrwbenc/src/deemph.c
@@ -64,24 +64,16 @@
     Word32 i;
     Word32 L_tmp;
     L_tmp = x[0] << 15;
-    L_tmp += ((*mem) * mu)<<1;
-    x[0] = (L_tmp + 0x8000)>>16;
+    i = L_mult(*mem, mu);
+    L_tmp = L_add(L_tmp, i);
+    x[0] = voround(L_tmp);
     for (i = 1; i < L; i++)
     {
         Word32 tmp;
         L_tmp = x[i] << 15;
         tmp = (x[i - 1] * mu)<<1;
-        if (tmp > 0 && L_tmp > INT_MAX - tmp) {
-            L_tmp = INT_MAX;
-        } else if (tmp < 0 && L_tmp < INT_MIN - tmp) {
-            L_tmp = INT_MIN;
-        } else {
-            L_tmp += tmp;
-        }
-        if (L_tmp > INT32_MAX - 0x8000) {
-            L_tmp = INT_MAX - 0x8000;
-        }
-        x[i] = (L_tmp + 0x8000)>>16;
+        L_tmp = L_add(L_tmp, tmp);
+        x[i] = voround(L_tmp);
     }
     *mem = x[L - 1];
     return;
diff --git a/media/libstagefright/codecs/amrwbenc/src/math_op.c b/media/libstagefright/codecs/amrwbenc/src/math_op.c
index 3b237da..9d7c74e 100644
--- a/media/libstagefright/codecs/amrwbenc/src/math_op.c
+++ b/media/libstagefright/codecs/amrwbenc/src/math_op.c
@@ -205,9 +205,14 @@
     L_sum = 0;
     for (i = 0; i < lg; i++)
     {
-        L_sum += x[i] * y[i];
+        Word32 tmp = (Word32) x[i] * (Word32) y[i];
+        if (tmp == (Word32) 0x40000000L) {
+            tmp = MAX_32;
+        }
+        L_sum = L_add(L_sum, tmp);
     }
-    L_sum = (L_sum << 1) + 1;
+    L_sum = L_shl2(L_sum, 1);
+    L_sum = L_add(L_sum, 1);
     /* Normalize acc in Q31 */
     sft = norm_l(L_sum);
     L_sum = L_sum << sft;
diff --git a/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c b/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c
index 525bf16..5d2b4bd 100644
--- a/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c
+++ b/media/libstagefright/codecs/amrwbenc/src/p_med_ol.c
@@ -129,7 +129,7 @@
     R2 = (R2 << exp_R2);
 
 
-    R1 = vo_L_mult(vo_round(R1), vo_round(R2));
+    R1 = vo_L_mult(voround(R1), voround(R2));
 
     i = norm_l(R1);
     R1 = (R1 << i);
diff --git a/media/libstagefright/codecs/amrwbenc/src/updt_tar.c b/media/libstagefright/codecs/amrwbenc/src/updt_tar.c
index f312ca3..ba7c2ff 100644
--- a/media/libstagefright/codecs/amrwbenc/src/updt_tar.c
+++ b/media/libstagefright/codecs/amrwbenc/src/updt_tar.c
@@ -33,12 +33,13 @@
          )
 {
     Word32 i;
-    Word32 L_tmp;
+    Word32 L_tmp, L_tmp2;
 
     for (i = 0; i < L; i++)
     {
         L_tmp = x[i] << 15;
-        L_tmp -= (y[i] * gain)<<1;
+        L_tmp2 = L_mult(y[i], gain);
+        L_tmp = L_sub(L_tmp, L_tmp2);
         x2[i] = extract_h(L_shl2(L_tmp, 1));
     }
 
diff --git a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
index 7b578ca..4cafb01 100644
--- a/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
+++ b/media/libstagefright/codecs/amrwbenc/src/voAMRWBEnc.c
@@ -673,8 +673,10 @@
             exc2[i] = exc[i] >> Q_new;
         }
         L_tmp = 0;
-        for (i = 0; i < L_FRAME; i++)
-            L_tmp += (exc2[i] * exc2[i])<<1;
+        for (i = 0; i < L_FRAME; i++) {
+            Word32 tmp = L_mult(exc2[i], exc2[i]); // (exc2[i] * exc2[i])<<1;
+            L_tmp = L_add(L_tmp, tmp);
+        }
         L_tmp >>= 1;
 
         dtx_buffer(st->dtx_encSt, isf, L_tmp, codec_mode);
@@ -1216,10 +1218,12 @@
 
         for (i = 0; i < L_SUBFR; i++)
         {
+            Word32 tmp;
             /* code in Q9, gain_pit in Q14 */
             L_tmp = (gain_code * code[i])<<1;
             L_tmp = (L_tmp << 5);
-            L_tmp += (exc[i + i_subfr] * gain_pit)<<1;
+            tmp = L_mult(exc[i + i_subfr], gain_pit); // (exc[i + i_subfr] * gain_pit)<<1
+            L_tmp = L_add(L_tmp, tmp);
             L_tmp = L_shl2(L_tmp, 1);
             exc[i + i_subfr] = extract_h(L_add(L_tmp, 0x8000));
         }
@@ -1301,7 +1305,7 @@
                 L_tmp = (L_tmp << 5);
                 L_tmp += (exc2[i] * gain_pit)<<1;
                 L_tmp = (L_tmp << 1);
-                exc2[i] = vo_round(L_tmp);
+                exc2[i] = voround(L_tmp);
             }
 
             corr_gain = synthesis(p_Aq, exc2, Q_new, &speech16k[i_subfr * 5 / 4], st);
diff --git a/media/libstagefright/codecs/common/Config.mk b/media/libstagefright/codecs/common/Config.mk
deleted file mode 100644
index a843cef..0000000
--- a/media/libstagefright/codecs/common/Config.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-#
-# This configure file is just for Linux projects against Android
-#
-
-VOPRJ :=
-VONJ :=
-
-# WARNING:
-# Using v7 breaks generic build
-ifeq ($(TARGET_ARCH),arm)
-VOTT := v5
-else
-VOTT := pc
-endif
-
-# Do we also need to check on ARCH_ARM_HAVE_ARMV7A? - probably not
-ifeq ($(TARGET_ARCH),arm)
-  ifeq ($(ARCH_ARM_HAVE_NEON),true)
-    VOTT := v7
-  endif
-endif
-
-VOTEST := 0
-
diff --git a/media/libstagefright/codecs/mp3dec/Android.mk b/media/libstagefright/codecs/mp3dec/Android.mk
index 38618da..11581c1 100644
--- a/media/libstagefright/codecs/mp3dec/Android.mk
+++ b/media/libstagefright/codecs/mp3dec/Android.mk
@@ -28,19 +28,22 @@
  	src/pvmp3_stereo_proc.cpp \
  	src/pvmp3_reorder.cpp \
 
-ifeq ($(TARGET_ARCH),arm)
-LOCAL_SRC_FILES += \
+LOCAL_SRC_FILES_arm += \
 	src/asm/pvmp3_polyphase_filter_window_gcc.s \
  	src/asm/pvmp3_mdct_18_gcc.s \
  	src/asm/pvmp3_dct_9_gcc.s \
 	src/asm/pvmp3_dct_16_gcc.s
-else
-LOCAL_SRC_FILES += \
+LOCAL_SRC_FILES_other_archs := \
  	src/pvmp3_polyphase_filter_window.cpp \
  	src/pvmp3_mdct_18.cpp \
  	src/pvmp3_dct_9.cpp \
  	src/pvmp3_dct_16.cpp
-endif
+
+LOCAL_SRC_FILES_arm64  := $(LOCAL_SRC_FILES_other_archs)
+LOCAL_SRC_FILES_mips   := $(LOCAL_SRC_FILES_other_archs)
+LOCAL_SRC_FILES_mips64 := $(LOCAL_SRC_FILES_other_archs)
+LOCAL_SRC_FILES_x86    := $(LOCAL_SRC_FILES_other_archs)
+LOCAL_SRC_FILES_x86_64 := $(LOCAL_SRC_FILES_other_archs)
 
 LOCAL_C_INCLUDES := \
         frameworks/av/media/libstagefright/include \
diff --git a/media/libstagefright/codecs/on2/h264dec/Android.mk b/media/libstagefright/codecs/on2/h264dec/Android.mk
index e7492b1..7159674 100644
--- a/media/libstagefright/codecs/on2/h264dec/Android.mk
+++ b/media/libstagefright/codecs/on2/h264dec/Android.mk
@@ -84,17 +84,15 @@
 	./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.S \
 	./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantChromaDCFromPair_s.S \
 
-ifeq ($(TARGET_ARCH),arm)
-  ifeq ($(ARCH_ARM_HAVE_NEON),true)
+
+ifeq ($(ARCH_ARM_HAVE_NEON),true)
     LOCAL_ARM_NEON   := true
-#    LOCAL_CFLAGS     := -std=c99 -D._NEON -D._OMXDL
-    LOCAL_CFLAGS     := -DH264DEC_NEON -DH264DEC_OMXDL
-    LOCAL_SRC_FILES  += $(MY_ASM) $(MY_OMXDL_C_SRC) $(MY_OMXDL_ASM_SRC)
-    LOCAL_C_INCLUDES += $(LOCAL_PATH)/./source/arm_neon_asm_gcc
-    LOCAL_C_INCLUDES += $(LOCAL_PATH)/./omxdl/arm_neon/api \
+    LOCAL_CFLAGS_arm     := -DH264DEC_NEON -DH264DEC_OMXDL
+    LOCAL_SRC_FILES_arm  := $(MY_ASM) $(MY_OMXDL_C_SRC) $(MY_OMXDL_ASM_SRC)
+    LOCAL_C_INCLUDES_arm := $(LOCAL_PATH)/./source/arm_neon_asm_gcc
+    LOCAL_C_INCLUDES_arm += $(LOCAL_PATH)/./omxdl/arm_neon/api \
                         $(LOCAL_PATH)/./omxdl/arm_neon/vc/api \
                         $(LOCAL_PATH)/./omxdl/arm_neon/vc/m4p10/api
-  endif
 endif
 
 LOCAL_CLANG := true
diff --git a/media/mediaserver/main_mediaserver.cpp b/media/mediaserver/main_mediaserver.cpp
index 4a485ed..315aff4 100644
--- a/media/mediaserver/main_mediaserver.cpp
+++ b/media/mediaserver/main_mediaserver.cpp
@@ -125,7 +125,11 @@
             prctl(PR_SET_PDEATHSIG, SIGKILL);   // if parent media.log dies before me, kill me also
             setpgid(0, 0);                      // but if I die first, don't kill my parent
         }
+#ifndef __BRILLO__
+        // Brillo is headless and very resource constrained. As such, it doesn't
+        // need an internationalization library for now.
         InitializeIcuOrDie();
+#endif
         sp<ProcessState> proc(ProcessState::self());
         sp<IServiceManager> sm = defaultServiceManager();
         ALOGI("ServiceManager: %p", sm.get());
diff --git a/media/mtp/MtpUtils.cpp b/media/mtp/MtpUtils.cpp
index 0667bdd..ebf3601 100644
--- a/media/mtp/MtpUtils.cpp
+++ b/media/mtp/MtpUtils.cpp
@@ -19,8 +19,6 @@
 #include <stdio.h>
 #include <time.h>
 
-#include <../private/bionic_time.h> /* TODO: switch this code to icu4c! */
-
 #include "MtpUtils.h"
 
 namespace android {
@@ -32,38 +30,40 @@
 DD replaced by the day (01-31), T is a constant character 'T' delimiting time from date,
 hh is replaced by the hour (00-23), mm is replaced by the minute (00-59), and ss by the
 second (00-59). The ".s" is optional, and represents tenths of a second.
+This is followed by a UTC offset given as "[+-]zzzz" or the literal "Z", meaning UTC.
 */
 
 bool parseDateTime(const char* dateTime, time_t& outSeconds) {
     int year, month, day, hour, minute, second;
-    struct tm tm;
-
     if (sscanf(dateTime, "%04d%02d%02dT%02d%02d%02d",
-            &year, &month, &day, &hour, &minute, &second) != 6)
+               &year, &month, &day, &hour, &minute, &second) != 6)
         return false;
-    const char* tail = dateTime + 15;
+
     // skip optional tenth of second
-    if (tail[0] == '.' && tail[1])
-        tail += 2;
-    //FIXME - support +/-hhmm
+    const char* tail = dateTime + 15;
+    if (tail[0] == '.' && tail[1]) tail += 2;
+
+    // FIXME: "Z" means UTC, but non-"Z" doesn't mean local time.
+    // It might be that you're in Asia/Seoul on vacation and your Android
+    // device has noticed this via the network, but your camera was set to
+    // America/Los_Angeles once when you bought it and doesn't know where
+    // it is right now, so the camera says "20160106T081700-0800" but we
+    // just ignore the "-0800" and assume local time which is actually "+0900".
+    // I think to support this (without switching to Java or using icu4c)
+    // you'd want to always use timegm(3) and then manually add/subtract
+    // the UTC offset parsed from the string (taking care of wrapping).
+    // mktime(3) ignores the tm_gmtoff field, so you can't let it do the work.
     bool useUTC = (tail[0] == 'Z');
 
-    // hack to compute timezone
-    time_t dummy;
-    localtime_r(&dummy, &tm);
-
+    struct tm tm = {};
     tm.tm_sec = second;
     tm.tm_min = minute;
     tm.tm_hour = hour;
     tm.tm_mday = day;
     tm.tm_mon = month - 1;  // mktime uses months in 0 - 11 range
     tm.tm_year = year - 1900;
-    tm.tm_wday = 0;
     tm.tm_isdst = -1;
-    if (useUTC)
-        outSeconds = mktime(&tm);
-    else
-        outSeconds = mktime_tz(&tm, tm.tm_zone);
+    outSeconds = useUTC ? timegm(&tm) : mktime(&tm);
 
     return true;
 }
@@ -73,7 +73,7 @@
 
     localtime_r(&seconds, &tm);
     snprintf(buffer, bufferLength, "%04d%02d%02dT%02d%02d%02d",
-        tm.tm_year + 1900, 
+        tm.tm_year + 1900,
         tm.tm_mon + 1, // localtime_r uses months in 0 - 11 range
         tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
 }
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index 30b462b..4153658 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -236,11 +236,6 @@
         return;
     }
 
-    if (mClientPid <= 0) {
-        LOG1("camera is unlocked (mClientPid = %d), don't tear down hardware", mClientPid);
-        return;
-    }
-
     // Make sure disconnect() is done once and once only, whether it is called
     // from the user directly, or called by the destructor.
     if (mHardware == 0) return;