Merge "Hal : Merge DSD and native changes on 8916 platform"
diff --git a/configs/msm8937/msm8937.mk b/configs/msm8937/msm8937.mk
index b7a7a39..3d932b0 100644
--- a/configs/msm8937/msm8937.mk
+++ b/configs/msm8937/msm8937.mk
@@ -147,9 +147,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 audio.deep_buffer.media=true
 
-#Default pcm audio sink buffer size in msec. This is used in calculating framecount
+#QC property used when calculating client heap size in audio flinger
 PRODUCT_PROPERTY_OVERRIDES += \
-media.stagefright.audio.sink=280
+audio.heap.size.multiplier=7
 
 #enable voice path for PCM VoIP by default
 PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/configs/msm8953/msm8953.mk b/configs/msm8953/msm8953.mk
index 3106942..96c9a5d 100644
--- a/configs/msm8953/msm8953.mk
+++ b/configs/msm8953/msm8953.mk
@@ -148,9 +148,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 audio.deep_buffer.media=true
 
-#Default pcm audio sink buffer size in msec. This is used in calculating framecount
+#QC property used when calculating client heap size in audio flinger
 PRODUCT_PROPERTY_OVERRIDES += \
-media.stagefright.audio.sink=280
+audio.heap.size.multiplier=7
 
 #enable voice path for PCM VoIP by default
 PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/configs/msm8996/msm8996.mk b/configs/msm8996/msm8996.mk
index 5b240e9..6d3fa4b 100644
--- a/configs/msm8996/msm8996.mk
+++ b/configs/msm8996/msm8996.mk
@@ -143,9 +143,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 audio.deep_buffer.media=true
 
-#Default pcm audio sink buffer size in msec. This is used in calculating framecount
+#QC property used when calculating client heap size in audio flinger
 PRODUCT_PROPERTY_OVERRIDES += \
-media.stagefright.audio.sink=280
+audio.heap.size.multiplier=7
 
 #enable voice path for PCM VoIP by default
 PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/configs/msmcobalt/audio_platform_info.xml b/configs/msmcobalt/audio_platform_info.xml
index a1bd9a1..a8bce46 100644
--- a/configs/msmcobalt/audio_platform_info.xml
+++ b/configs/msmcobalt/audio_platform_info.xml
@@ -28,6 +28,9 @@
     <acdb_ids>
         <device name="SND_DEVICE_OUT_SPEAKER" acdb_id="15"/>
         <device name="SND_DEVICE_OUT_SPEAKER_PROTECTED" acdb_id="124"/>
+        <device name="SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE" acdb_id="131"/>
+        <device name="SND_DEVICE_IN_VOICE_REC_TMIC" acdb_id="131"/>
+        <device name="SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE" acdb_id="132"/>
     </acdb_ids>
     <bit_width_configs>
         <device name="SND_DEVICE_OUT_SPEAKER" bit_width="24"/>
diff --git a/configs/msmcobalt/msmcobalt.mk b/configs/msmcobalt/msmcobalt.mk
index 12a922c..7117bd8 100644
--- a/configs/msmcobalt/msmcobalt.mk
+++ b/configs/msmcobalt/msmcobalt.mk
@@ -152,9 +152,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 audio.deep_buffer.media=true
 
-#Default pcm audio sink buffer size in msec. This is used in calculating framecount
+#QC property used when calculating client heap size in audio flinger
 PRODUCT_PROPERTY_OVERRIDES += \
-media.stagefright.audio.sink=280
+audio.heap.size.multiplier=7
 
 #enable voice path for PCM VoIP by default
 PRODUCT_PROPERTY_OVERRIDES += \
@@ -214,3 +214,7 @@
 #Disable FM a2dp concurrency
 PRODUCT_PROPERTY_OVERRIDES += \
 fm.a2dp.conc.disabled=true
+
+#audio becoming noisy intent broadcast delay
+PRODUCT_PROPERTY_OVERRIDES += \
+audio.noisy.broadcast.delay=600
diff --git a/configs/msmfalcon/msmfalcon.mk b/configs/msmfalcon/msmfalcon.mk
index 554f32b..509c159 100644
--- a/configs/msmfalcon/msmfalcon.mk
+++ b/configs/msmfalcon/msmfalcon.mk
@@ -137,9 +137,9 @@
 PRODUCT_PROPERTY_OVERRIDES += \
 audio.deep_buffer.media=true
 
-#Default pcm audio sink buffer size in msec. This is used in calculating framecount
+#QC property used when calculating client heap size in audio flinger
 PRODUCT_PROPERTY_OVERRIDES += \
-media.stagefright.audio.sink=280
+audio.heap.size.multiplier=7
 
 #enable voice path for PCM VoIP by default
 PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 9542fbd..eb3213c 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -666,6 +666,18 @@
         if ((24 == usecase->stream.out->bit_width) &&
             (usecase->stream.out->devices & AUDIO_DEVICE_OUT_SPEAKER)) {
             usecase->stream.out->app_type_cfg.sample_rate = DEFAULT_OUTPUT_SAMPLING_RATE;
+        } else if ((snd_device == SND_DEVICE_OUT_HDMI ||
+                    snd_device == SND_DEVICE_OUT_USB_HEADSET ||
+                    snd_device == SND_DEVICE_OUT_DISPLAY_PORT) &&
+                   (usecase->stream.out->sample_rate >= OUTPUT_SAMPLING_RATE_44100)) {
+             /*
+              * To best utlize DSP, check if the stream sample rate is supported/multiple of
+              * configured device sample rate, if not update the COPP rate to be equal to the
+              * device sample rate, else open COPP at stream sample rate
+              */
+              platform_check_and_update_copp_sample_rate(adev->platform, snd_device,
+                                      usecase->stream.out->sample_rate,
+                                      &usecase->stream.out->app_type_cfg.sample_rate);
         } else if ((snd_device != SND_DEVICE_OUT_HEADPHONES_44_1 &&
             usecase->stream.out->sample_rate == OUTPUT_SAMPLING_RATE_44100) ||
             (usecase->stream.out->sample_rate < OUTPUT_SAMPLING_RATE_44100)) {
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 13e4ae9..bf2908f 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -796,8 +796,10 @@
             audio_extn_dev_arbi_release(snd_device);
             return -EINVAL;
         }
-    } else if (platform_can_split_snd_device(adev->platform, snd_device,
-            &num_devices, new_snd_devices)) {
+    } else if (platform_split_snd_device(adev->platform,
+                                         snd_device,
+                                         &num_devices,
+                                         new_snd_devices) == 0) {
         for (i = 0; i < num_devices; i++) {
             enable_snd_device(adev, new_snd_devices[i]);
         }
@@ -870,8 +872,10 @@
         if (platform_can_enable_spkr_prot_on_device(snd_device) &&
              audio_extn_spkr_prot_is_enabled()) {
             audio_extn_spkr_prot_stop_processing(snd_device);
-        } else if (platform_can_split_snd_device(adev->platform, snd_device,
-                    &num_devices, new_snd_devices)) {
+        } else if (platform_split_snd_device(adev->platform,
+                                             snd_device,
+                                             &num_devices,
+                                             new_snd_devices) == 0) {
             for (i = 0; i < num_devices; i++) {
                 disable_snd_device(adev, new_snd_devices[i]);
             }
@@ -908,6 +912,115 @@
     return 0;
 }
 
+/*
+  legend:
+  uc - existing usecase
+  new_uc - new usecase
+  d1, d11, d2 - SND_DEVICE enums
+  a1, a2 - corresponding ANDROID device enums
+  B1, B2 - backend strings
+
+case 1
+  uc->dev  d1 (a1)               B1
+  new_uc->dev d1 (a1), d2 (a2)   B1, B2
+
+  resolution: disable and enable uc->dev on d1
+
+case 2
+  uc->dev d1 (a1)        B1
+  new_uc->dev d11 (a1)   B1
+
+  resolution: need to switch uc since d1 and d11 are related
+  (e.g. speaker and voice-speaker)
+  use ANDROID_DEVICE_OUT enums to match devices since SND_DEVICE enums may vary
+
+case 3
+  uc->dev d1 (a1)        B1
+  new_uc->dev d2 (a2)    B2
+
+  resolution: no need to switch uc
+
+case 4
+  uc->dev d1 (a1)      B1
+  new_uc->dev d2 (a2)  B1
+
+  resolution: disable enable uc-dev on d2 since backends match
+  we cannot enable two streams on two different devices if they
+  share the same backend. e.g. if offload is on speaker device using
+  QUAD_MI2S backend and a low-latency stream is started on voice-handset
+  using the same backend, offload must also be switched to voice-handset.
+
+case 5
+  uc->dev  d1 (a1)                  B1
+  new_uc->dev d1 (a1), d2 (a2)      B1
+
+  resolution: disable enable uc-dev on d2 since backends match
+  we cannot enable two streams on two different devices if they
+  share the same backend.
+
+case 6
+  uc->dev  d1 (a1)    B1
+  new_uc->dev d2 (a1) B2
+
+  resolution: no need to switch
+
+case 7
+  uc->dev d1 (a1), d2 (a2)       B1, B2
+  new_uc->dev d1 (a1)            B1
+
+  resolution: no need to switch
+
+*/
+static snd_device_t derive_playback_snd_device(void * platform,
+                                               struct audio_usecase *uc,
+                                               struct audio_usecase *new_uc,
+                                               snd_device_t new_snd_device)
+{
+    audio_devices_t a1 = uc->stream.out->devices;
+    audio_devices_t a2 = new_uc->stream.out->devices;
+
+    snd_device_t d1 = uc->out_snd_device;
+    snd_device_t d2 = new_snd_device;
+
+    // Treat as a special case when a1 and a2 are not disjoint
+    if ((a1 != a2) && (a1 & a2)) {
+        snd_device_t d3[2];
+        int num_devices = 0;
+        int ret = platform_split_snd_device(platform,
+                                            popcount(a1) > 1 ? d1 : d2,
+                                            &num_devices,
+                                            d3);
+        if (ret < 0) {
+            if (ret != -ENOSYS) {
+                ALOGW("%s failed to split snd_device %d",
+                      __func__,
+                      popcount(a1) > 1 ? d1 : d2);
+            }
+            goto end;
+        }
+
+        // NB: case 7 is hypothetical and isn't a practical usecase yet.
+        // But if it does happen, we need to give priority to d2 if
+        // the combo devices active on the existing usecase share a backend.
+        // This is because we cannot have a usecase active on a combo device
+        // and a new usecase requests one device in this combo pair.
+        if (platform_check_backends_match(d3[0], d3[1])) {
+            return d2; // case 5
+        } else {
+            return d1; // case 1
+        }
+    } else {
+        if (platform_check_backends_match(d1, d2)) {
+            return d2; // case 2, 4
+        } else {
+            return d1; // case 6, 3
+        }
+    }
+
+end:
+    return d2; // return whatever was calculated before.
+}
+
 static void check_usecases_codec_backend(struct audio_device *adev,
                                               struct audio_usecase *uc_info,
                                               snd_device_t snd_device)
@@ -963,7 +1076,9 @@
               platform_check_backends_match(snd_device, usecase->out_snd_device));
         if (usecase->type != PCM_CAPTURE &&
             usecase != uc_info &&
-            (usecase->out_snd_device != snd_device || force_routing) &&
+            (derive_playback_snd_device(adev->platform,
+                                        usecase, uc_info,
+                                        snd_device) != usecase->out_snd_device || force_routing) &&
             ((usecase->devices & AUDIO_DEVICE_OUT_ALL_CODEC_BACKEND) ||
              (usecase->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) ||
              (usecase->devices & AUDIO_DEVICE_OUT_USB_DEVICE) ||
diff --git a/hal/edid.c b/hal/edid.c
index 8f183d0..e889530 100644
--- a/hal/edid.c
+++ b/hal/edid.c
@@ -86,57 +86,109 @@
     return format_str;
 }
 
-static int get_edid_sf(unsigned char byte)
+static bool is_supported_sr(unsigned char sr_byte, int sampling_rate )
+{
+    int result = 0;
+
+    ALOGV("%s: sr_byte: %d, sampling_freq: %d",__func__, sr_byte, sampling_rate);
+    switch (sampling_rate) {
+    case 192000:
+        result = (sr_byte & BIT(6));
+        break;
+    case 176400:
+        result = (sr_byte & BIT(5));
+        break;
+    case 96000:
+        result = (sr_byte & BIT(4));
+        break;
+    case 88200:
+        result = (sr_byte & BIT(3));
+        break;
+    case 48000:
+        result = (sr_byte & BIT(2));
+        break;
+    case 44100:
+        result = (sr_byte & BIT(1));
+        break;
+    case 32000:
+        result = (sr_byte & BIT(0));
+        break;
+     default:
+        break;
+    }
+
+    if (result)
+        return true;
+
+    return false;
+}
+
+static unsigned char get_edid_bps_byte(unsigned char byte,
+                        unsigned char format)
+{
+    if (format == 0) {
+        ALOGV("%s: not lpcm format, return 0",__func__);
+        return 0;
+    }
+    return byte;
+}
+
+static bool is_supported_bps(unsigned char bps_byte, int bps)
+{
+    int result = 0;
+
+    switch (bps) {
+    case 24:
+        ALOGV("24bit");
+        result = (bps_byte & BIT(2));
+        break;
+    case 20:
+        ALOGV("20bit");
+        result = (bps_byte & BIT(1));
+        break;
+    case 16:
+        ALOGV("16bit");
+        result = (bps_byte & BIT(0));
+        break;
+     default:
+        break;
+    }
+
+    if (result)
+        return true;
+
+    return false;
+}
+
+static int get_highest_edid_sf(unsigned char byte)
 {
     int nfreq = 0;
 
     if (byte & BIT(6)) {
-        ALOGV("192kHz");
+        ALOGV("Highest: 192kHz");
         nfreq = 192000;
     } else if (byte & BIT(5)) {
-        ALOGV("176kHz");
+        ALOGV("Highest: 176kHz");
         nfreq = 176000;
     } else if (byte & BIT(4)) {
-        ALOGV("96kHz");
+        ALOGV("Highest: 96kHz");
         nfreq = 96000;
     } else if (byte & BIT(3)) {
-        ALOGV("88.2kHz");
+        ALOGV("Highest: 88.2kHz");
         nfreq = 88200;
     } else if (byte & BIT(2)) {
-        ALOGV("48kHz");
+        ALOGV("Highest: 48kHz");
         nfreq = 48000;
     } else if (byte & BIT(1)) {
-        ALOGV("44.1kHz");
+        ALOGV("Highest: 44.1kHz");
         nfreq = 44100;
     } else if (byte & BIT(0)) {
-        ALOGV("32kHz");
+        ALOGV("Highest: 32kHz");
         nfreq = 32000;
     }
     return nfreq;
 }
 
-static int get_edid_bps(unsigned char byte,
-                        unsigned char format)
-{
-    int bits_per_sample = 0;
-    if (format == 1) {
-        if (byte & BIT(2)) {
-            ALOGV("24bit");
-            bits_per_sample = 24;
-        } else if (byte & BIT(1)) {
-            ALOGV("20bit");
-            bits_per_sample = 20;
-        } else if (byte & BIT(0)) {
-            ALOGV("16bit");
-            bits_per_sample = 16;
-        }
-    } else {
-        ALOGV("not lpcm format, return 0");
-        return 0;
-    }
-    return bits_per_sample;
-}
-
 static void update_channel_map(edid_audio_info* info)
 {
     /* HDMI Cable follows CEA standard so SAD is received in CEA
@@ -589,8 +641,8 @@
     for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
         ALOGV("%s:FormatId:%d rate:%d bps:%d channels:%d", __func__,
               info->audio_blocks_array[i].format_id,
-              info->audio_blocks_array[i].sampling_freq,
-              info->audio_blocks_array[i].bits_per_sample,
+              info->audio_blocks_array[i].sampling_freq_bitmask,
+              info->audio_blocks_array[i].bits_per_sample_bitmask,
               info->audio_blocks_array[i].channels);
     }
     ALOGV("%s:no of audio blocks:%d", __func__, info->audio_blocks);
@@ -670,16 +722,16 @@
         ALOGD("info->audio_blocks_array[i].format_id %s",
               edid_format_to_str(formats[i]));
 
-        ALOGV("Frequency Byte %d\n", frequency[i]);
-        info->audio_blocks_array[i].sampling_freq = get_edid_sf(frequency[i]);
-        ALOGV("info->audio_blocks_array[i].sampling_freq %d",
-              info->audio_blocks_array[i].sampling_freq);
+        ALOGV("Frequency Bitmask %d\n", frequency[i]);
+        info->audio_blocks_array[i].sampling_freq_bitmask = frequency[i];
+        ALOGV("info->audio_blocks_array[i].sampling_freq_bitmask %d",
+              info->audio_blocks_array[i].sampling_freq_bitmask);
 
-        ALOGV("BitsPerSample Byte %d\n", bitrate[i]);
-        info->audio_blocks_array[i].bits_per_sample =
-                   get_edid_bps(bitrate[i],formats[i]);
-        ALOGV("info->audio_blocks_array[i].bits_per_sample %d",
-              info->audio_blocks_array[i].bits_per_sample);
+        ALOGV("BitsPerSample Bitmask %d\n", bitrate[i]);
+        info->audio_blocks_array[i].bits_per_sample_bitmask =
+                   get_edid_bps_byte(bitrate[i],formats[i]);
+        ALOGV("info->audio_blocks_array[i].bits_per_sample_bitmask %d",
+              info->audio_blocks_array[i].bits_per_sample_bitmask);
     }
     dump_speaker_allocation(info);
     dump_edid_data(info);
@@ -691,7 +743,7 @@
     int i = 0;
     if (info != NULL && sr != 0) {
         for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
-            if (info->audio_blocks_array[i].sampling_freq == sr) {
+        if (is_supported_sr(info->audio_blocks_array[i].sampling_freq_bitmask , sr)) {
                 ALOGV("%s: returns true for sample rate [%d]",
                       __func__, sr);
                 return true;
@@ -715,7 +767,7 @@
 
     if (info != NULL && bps != 0) {
         for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
-            if (info->audio_blocks_array[i].bits_per_sample == bps) {
+            if (is_supported_bps(info->audio_blocks_array[i].bits_per_sample_bitmask, bps)) {
                 ALOGV("%s: returns true for bit width [%d]",
                       __func__, bps);
                 return true;
@@ -726,3 +778,24 @@
            __func__, bps);
     return false;
 }
+
+int edid_get_highest_supported_sr(edid_audio_info* info)
+{
+    int sr = 0;
+    int highest_sr = 0;
+    int i;
+
+    if (info != NULL) {
+        for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
+          sr = get_highest_edid_sf(info->audio_blocks_array[i].sampling_freq_bitmask);
+          if (sr > highest_sr)
+            highest_sr = sr;
+        }
+    }
+    else
+        ALOGE("%s: info is NULL", __func__);
+
+    ALOGV("%s: returns [%d] for highest supported sr",
+        __func__, highest_sr);
+    return highest_sr;
+}
\ No newline at end of file
diff --git a/hal/edid.h b/hal/edid.h
index 387b17e..6a82103 100644
--- a/hal/edid.h
+++ b/hal/edid.h
@@ -79,8 +79,8 @@
 
 typedef struct edid_audio_block_info {
     edid_audio_format_id format_id;
-    int sampling_freq;
-    int bits_per_sample;
+    int sampling_freq_bitmask;
+    int bits_per_sample_bitmask;
     int channels;
 } edid_audio_block_info;
 
@@ -100,5 +100,6 @@
 
 bool edid_is_supported_sr(edid_audio_info* info, int sr);
 bool edid_is_supported_bps(edid_audio_info* info, int bps);
+int edid_get_highest_supported_sr(edid_audio_info* info);
 
 #endif /* EDID_H */
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index c8980d0..9416887 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -448,6 +448,7 @@
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = "quad-mic",
     [SND_DEVICE_IN_THREE_MIC] = "three-mic",
     [SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
+    [SND_DEVICE_IN_VOICE_REC_TMIC] = "three-mic",
     [SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
     [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = "voice-rec-dmic-ef",
     [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "three-mic",
@@ -578,6 +579,7 @@
     [SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS] = 129,
     [SND_DEVICE_IN_THREE_MIC] = 46, /* for APSS Surround Sound Recording */
     [SND_DEVICE_IN_HANDSET_TMIC] = 125, /* for 3mic recording with fluence */
+    [SND_DEVICE_IN_VOICE_REC_TMIC] = 125,
     [SND_DEVICE_IN_UNPROCESSED_MIC] = 143,
     [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = 144,
     [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = 145,
@@ -710,6 +712,7 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS)},
     {TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_TMIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_STEREO_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_THREE_MIC)},
@@ -2591,7 +2594,8 @@
         snd_device = usecase->in_snd_device;
     acdb_dev_id = acdb_device_table[platform_get_spkr_prot_snd_device(snd_device)];
 
-    if(!platform_can_split_snd_device(platform, snd_device, &num_devices, new_snd_device)) {
+    if (platform_split_snd_device(platform, snd_device, &num_devices,
+                                  new_snd_device) < 0) {
         new_snd_device[0] = snd_device;
     }
 
@@ -2893,22 +2897,21 @@
     return ret;
 }
 
-bool platform_can_split_snd_device(void *platform,
-                                   snd_device_t snd_device,
-                                   int *num_devices,
-                                   snd_device_t *new_snd_devices)
+int platform_split_snd_device(void *platform,
+                              snd_device_t snd_device,
+                              int *num_devices,
+                              snd_device_t *new_snd_devices)
 {
-    bool status = false;
+    int ret = -EINVAL;
     struct platform_data *my_data = (struct platform_data *)platform;
-
     if (NULL == num_devices || NULL == new_snd_devices) {
         ALOGE("%s: NULL pointer ..", __func__);
-        return false;
+        return -EINVAL;
     }
 
     /*
      * If wired headset/headphones/line devices share the same backend
-     * with speaker/earpiece this routine returns false.
+     * with speaker/earpiece this routine returns -EINVAL.
      */
     if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES &&
         !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HEADPHONES)) {
@@ -2922,7 +2925,7 @@
              new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
 
         new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
-        status = true;
+        ret = 0;
     } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI &&
                !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HDMI)) {
         *num_devices = 2;
@@ -2935,7 +2938,7 @@
             new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
 
         new_snd_devices[1] = SND_DEVICE_OUT_HDMI;
-        status = true;
+        ret = 0;
     } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_DISPLAY_PORT &&
                !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_DISPLAY_PORT)) {
         *num_devices = 2;
@@ -2948,24 +2951,24 @@
             new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
 
         new_snd_devices[1] = SND_DEVICE_OUT_DISPLAY_PORT;
-        status = true;
+        ret = 0;
     } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET &&
                !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_USB_HEADSET)) {
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_USB_HEADSET;
-        status = true;
+        ret = 0;
     } else if (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device) {
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
-        status = true;
+        ret = 0;
     }
 
     ALOGD("%s: snd_device(%d) num devices(%d) new_snd_devices(%d)", __func__,
         snd_device, *num_devices, *new_snd_devices);
 
-    return status;
+    return ret;
 }
 
 int platform_get_ext_disp_type(void *platform)
@@ -3414,7 +3417,7 @@
                      snd_device = SND_DEVICE_IN_HANDSET_QMIC;
                 } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
                     (my_data->source_mic_type & SOURCE_THREE_MIC)) {
-                    snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+                    snd_device = SND_DEVICE_IN_VOICE_REC_TMIC;
                 } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
                     (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                     snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
@@ -4559,8 +4562,12 @@
 
         //Check EDID info for supported samplerate
         if (!edid_is_supported_sr(edid_info,sample_rate)) {
-            //reset to current sample rate
-            sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
+            //check to see if current BE sample rate is supported by EDID
+            //else assign the highest sample rate supported by EDID
+            if (edid_is_supported_sr(edid_info,my_data->current_backend_cfg[backend_idx].sample_rate))
+                sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
+            else
+                sample_rate = edid_get_highest_supported_sr(edid_info);
         }
 
         //Check EDID info for supported bit width
@@ -4847,8 +4854,8 @@
           backend_cfg.sample_rate,  backend_cfg.channels, backend_idx, usecase->id,
           platform_get_snd_device_name(snd_device));
 
-    if (!platform_can_split_snd_device(adev->platform, snd_device,
-            &num_devices, new_snd_devices))
+    if (platform_split_snd_device(adev->platform, snd_device,
+                                  &num_devices, new_snd_devices) < 0)
         new_snd_devices[0] = snd_device;
 
     for (i = 0; i < num_devices; i++) {
@@ -5110,6 +5117,29 @@
     return ret;
 }
 
+void platform_check_and_update_copp_sample_rate(void* platform, snd_device_t snd_device,
+                                                unsigned int stream_sr, int* sample_rate)
+{
+    struct platform_data* my_data = (struct platform_data *)platform;
+    int backend_idx = platform_get_backend_index(snd_device);
+    int device_sr = my_data->current_backend_cfg[backend_idx].sample_rate;
+    /*Check if device SR is multiple of 8K or 11.025 Khz
+     *check if the stream SR is multiple of same base, if not set
+     *copp sample rate equal to device sample rate.
+     */
+     if (!(((sample_rate_multiple(device_sr, SAMPLE_RATE_8000)) &&
+                 (sample_rate_multiple(stream_sr, SAMPLE_RATE_8000))) ||
+           ((sample_rate_multiple(device_sr, SAMPLE_RATE_11025)) &&
+                 (sample_rate_multiple(stream_sr, SAMPLE_RATE_11025))))) {
+         *sample_rate = device_sr;
+     } else
+         *sample_rate = stream_sr;
+
+     ALOGI("sn_device %d device sr %d stream sr %d copp sr %d", snd_device, device_sr, stream_sr
+, *sample_rate);
+
+}
+
 int platform_get_edid_info(void *platform)
 {
     struct platform_data *my_data = (struct platform_data *)platform;
@@ -5369,24 +5399,13 @@
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     edid_audio_info *info = NULL;
-    int i, ret;
+    int ret = 0;
 
     ret = platform_get_edid_info(platform);
     info = (edid_audio_info *)my_data->edid_info;
     if (ret == 0 && info != NULL) {
-        for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
-             /*
-              * To check
-              *  is there any special for CONFIG_HDMI_PASSTHROUGH_CONVERT
-              *  & DOLBY_DIGITAL_PLUS
-              */
-            if (info->audio_blocks_array[i].sampling_freq == sample_rate) {
-                ALOGV("%s: returns true %d", __func__, sample_rate);
-                return true;
-            }
-        }
+        return edid_is_supported_sr(info, sample_rate);
     }
-    ALOGV("%s: returns false %d", __func__, sample_rate);
 
     return false;
 }
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index bd34fa0..a0ae7d0 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -203,6 +203,7 @@
     SND_DEVICE_IN_SPEAKER_QMIC_AEC_NS,
     SND_DEVICE_IN_THREE_MIC,
     SND_DEVICE_IN_HANDSET_TMIC,
+    SND_DEVICE_IN_VOICE_REC_TMIC,
     SND_DEVICE_IN_UNPROCESSED_MIC,
     SND_DEVICE_IN_UNPROCESSED_STEREO_MIC,
     SND_DEVICE_IN_UNPROCESSED_THREE_MIC,
diff --git a/hal/msm8960/platform.c b/hal/msm8960/platform.c
index e025772..33bbc2f 100644
--- a/hal/msm8960/platform.c
+++ b/hal/msm8960/platform.c
@@ -1237,12 +1237,14 @@
 int platform_spkr_prot_is_wsa_analog_mode(void *adev __unused)
 {
     return 0;
-bool platform_can_split_snd_device(void *platform __unused,
-                                   snd_device_t in_snd_device __unused,
-                                   int *num_devices __unused,
-                                   snd_device_t *out_snd_devices __unused)
+
+}
+
+int platform_can_split_snd_device(snd_device_t in_snd_device __unused,
+                                  int *num_devices __unused,
+                                  snd_device_t *out_snd_devices __unused)
 {
-    return false;
+    return -ENOSYS;
 }
 
 bool platform_check_backends_match(snd_device_t snd_device1 __unused,
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index e947f91..3551006 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -446,6 +446,7 @@
     [SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE] = "quad-mic",
     [SND_DEVICE_IN_THREE_MIC] = "three-mic",
     [SND_DEVICE_IN_HANDSET_TMIC] = "three-mic",
+    [SND_DEVICE_IN_VOICE_REC_TMIC] = "three-mic",
     [SND_DEVICE_IN_UNPROCESSED_MIC] = "unprocessed-mic",
     [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = "voice-rec-dmic-ef",
     [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "three-mic",
@@ -570,6 +571,7 @@
     [SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE] = 125,
     [SND_DEVICE_IN_THREE_MIC] = 46, /* for APSS Surround Sound Recording */
     [SND_DEVICE_IN_HANDSET_TMIC] = 125, /* for 3mic recording with fluence */
+    [SND_DEVICE_IN_VOICE_REC_TMIC] = 125,
     [SND_DEVICE_IN_UNPROCESSED_MIC] = 143,
     [SND_DEVICE_IN_UNPROCESSED_STEREO_MIC] = 144,
     [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = 145,
@@ -693,6 +695,7 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE)},
     {TO_NAME_INDEX(SND_DEVICE_IN_THREE_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_TMIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_VOICE_REC_TMIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_STEREO_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_THREE_MIC)},
@@ -2393,8 +2396,8 @@
         return -EINVAL;
     }
 
-    if(!platform_can_split_snd_device(my_data, snd_device,
-            &num_devices, new_snd_device)) {
+    if (platform_split_snd_device(my_data, snd_device,
+                                  &num_devices, new_snd_device) < 0) {
         new_snd_device[0] = snd_device;
     }
 
@@ -2697,58 +2700,58 @@
     return ret;
 }
 
-bool platform_can_split_snd_device(void *platform,
-                                   snd_device_t snd_device,
-                                   int *num_devices,
-                                   snd_device_t *new_snd_devices)
+int platform_split_snd_device(void *platform,
+                              snd_device_t snd_device,
+                              int *num_devices,
+                              snd_device_t *new_snd_devices)
 {
-    bool status = false;
+    int ret = -EINVAL;
     struct platform_data *my_data = (struct platform_data *)platform;
 
     if ( NULL == num_devices || NULL == new_snd_devices || NULL == my_data) {
         ALOGE("%s: NULL pointer ..", __func__);
-        return false;
+        return -EINVAL;
     }
 
     /*
      * If wired headset/headphones/line devices share the same backend
-     * with speaker/earpiece this routine returns false.
+     * with speaker/earpiece this routine returns -EINVAL.
      */
     if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HEADPHONES &&
         !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HEADPHONES)) {
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_HEADPHONES;
-        status = true;
+        ret = 0;
     } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_HDMI &&
                !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_HDMI)) {
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_HDMI;
-        status = true;
+        ret = 0;
     } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_DISPLAY_PORT &&
                !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_DISPLAY_PORT)) {
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_DISPLAY_PORT;
-        status = true;
+        ret = 0;
     } else if (snd_device == SND_DEVICE_OUT_SPEAKER_AND_USB_HEADSET &&
                !platform_check_backends_match(SND_DEVICE_OUT_SPEAKER, SND_DEVICE_OUT_USB_HEADSET)) {
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_USB_HEADSET;
-        status = true;
+        ret = 0;
     } else if (SND_DEVICE_OUT_SPEAKER_AND_BT_A2DP == snd_device) {
         *num_devices = 2;
         new_snd_devices[0] = SND_DEVICE_OUT_SPEAKER;
         new_snd_devices[1] = SND_DEVICE_OUT_BT_A2DP;
-        status = true;
+        ret = 0;
     }
 
     ALOGD("%s: snd_device(%d) num devices(%d) new_snd_devices(%d)", __func__,
         snd_device, *num_devices, *new_snd_devices);
 
-    return status;
+    return ret;
 }
 
 int platform_get_ext_disp_type(void *platform)
@@ -3138,7 +3141,7 @@
                      snd_device = SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE;
                 } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
                     (my_data->source_mic_type & SOURCE_THREE_MIC)) {
-                    snd_device = SND_DEVICE_IN_HANDSET_TMIC;
+                    snd_device = SND_DEVICE_IN_VOICE_REC_TMIC;
                 } else if ((my_data->fluence_type & FLUENCE_DUAL_MIC) &&
                     (my_data->source_mic_type & SOURCE_DUAL_MIC)) {
                     snd_device = SND_DEVICE_IN_VOICE_REC_DMIC_FLUENCE;
@@ -4562,8 +4565,12 @@
 
         //Check EDID info for supported samplerate
         if (!edid_is_supported_sr(edid_info,sample_rate)) {
-            //reset to current sample rate
-            sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
+            //check to see if current BE sample rate is supported by EDID
+            //else assign the highest sample rate supported by EDID
+            if (edid_is_supported_sr(edid_info,my_data->current_backend_cfg[backend_idx].sample_rate))
+                sample_rate = my_data->current_backend_cfg[backend_idx].sample_rate;
+            else
+                sample_rate = edid_get_highest_supported_sr(edid_info);
         }
 
         //Check EDID info for supported bit width
@@ -4829,7 +4836,8 @@
           backend_cfg.sample_rate, backend_cfg.channels, backend_idx, usecase->id,
           platform_get_snd_device_name(snd_device));
 
-    if (!platform_can_split_snd_device(my_data, snd_device, &num_devices, new_snd_devices))
+    if (platform_split_snd_device(my_data, snd_device, &num_devices,
+                                  new_snd_devices) < 0)
         new_snd_devices[0] = snd_device;
 
     for (i = 0; i < num_devices; i++) {
@@ -5299,6 +5307,32 @@
     return fragment_size;
 }
 
+void platform_check_and_update_copp_sample_rate(void* platform, snd_device_t snd_device,
+                                                unsigned int stream_sr, int* sample_rate)
+{
+    struct platform_data* my_data = (struct platform_data *)platform;
+    int backend_idx = platform_get_backend_index(snd_device);
+    int device_sr = my_data->current_backend_cfg[backend_idx].sample_rate;
+    /*
+     *Check if device SR is multiple of 8K or 11.025 Khz
+     *check if the stream SR is multiple of same base, if yes
+     *then have copp SR equal to stream SR, this ensures that
+     *post processing happens at stream SR, else have
+     *copp SR equal to device SR.
+     */
+     if (!(((sample_rate_multiple(device_sr, SAMPLE_RATE_8000)) &&
+                 (sample_rate_multiple(stream_sr, SAMPLE_RATE_8000))) ||
+           ((sample_rate_multiple(device_sr, SAMPLE_RATE_11025)) &&
+                 (sample_rate_multiple(stream_sr, SAMPLE_RATE_11025))))) {
+         *sample_rate = device_sr;
+     } else
+         *sample_rate = stream_sr;
+
+     ALOGI("sn_device %d device sr %d stream sr %d copp sr %d", snd_device, device_sr, stream_sr
+, *sample_rate);
+
+}
+
 void platform_reset_edid_info(void *platform) {
 
     ALOGV("%s:", __func__);
@@ -5347,24 +5381,13 @@
 {
     struct platform_data *my_data = (struct platform_data *)platform;
     edid_audio_info *info = NULL;
-    int i, ret;
+    int ret = 0;
 
     ret = platform_get_edid_info(platform);
     info = (edid_audio_info *)my_data->edid_info;
     if (ret == 0 && info != NULL) {
-        for (i = 0; i < info->audio_blocks && i < MAX_EDID_BLOCKS; i++) {
-             /*
-              * To check
-              *  is there any special for CONFIG_HDMI_PASSTHROUGH_CONVERT
-              *  & DOLBY_DIGITAL_PLUS
-              */
-            if (info->audio_blocks_array[i].sampling_freq == sample_rate) {
-                ALOGV("%s: returns true %d", __func__, sample_rate);
-                return true;
-            }
-        }
+        return edid_is_supported_sr(info, sample_rate);
     }
-    ALOGV("%s: returns false %d", __func__, sample_rate);
 
     return false;
 }
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index c231843..fcfe4d1 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -197,6 +197,7 @@
     SND_DEVICE_IN_VOICE_REC_QMIC_FLUENCE,
     SND_DEVICE_IN_THREE_MIC,
     SND_DEVICE_IN_HANDSET_TMIC,
+    SND_DEVICE_IN_VOICE_REC_TMIC,
     SND_DEVICE_IN_UNPROCESSED_MIC,
     SND_DEVICE_IN_UNPROCESSED_STEREO_MIC,
     SND_DEVICE_IN_UNPROCESSED_THREE_MIC,
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 61f42de..d3cb23f 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -25,7 +25,9 @@
 #define CODEC_BACKEND_DEFAULT_SAMPLE_RATE 48000
 #define CODEC_BACKEND_DEFAULT_CHANNELS 2
 #define CODEC_BACKEND_DEFAULT_TX_CHANNELS 1
-
+#define SAMPLE_RATE_8000 8000
+#define SAMPLE_RATE_11025 11025
+#define sample_rate_multiple(sr, base) ((sr % base)== 0?true:false)
 
 enum {
     NATIVE_AUDIO_MODE_SRC = 1,
@@ -147,10 +149,10 @@
 int platform_get_spkr_prot_snd_device(snd_device_t snd_device);
 int platform_get_vi_feedback_snd_device(snd_device_t snd_device);
 int platform_spkr_prot_is_wsa_analog_mode(void *adev);
-bool platform_can_split_snd_device(void *platform,
-                                   snd_device_t snd_device,
-                                   int *num_devices,
-                                   snd_device_t *new_snd_devices);
+int platform_split_snd_device(void *platform,
+                              snd_device_t snd_device,
+                              int *num_devices,
+                              snd_device_t *new_snd_devices);
 
 bool platform_check_backends_match(snd_device_t snd_device1, snd_device_t snd_device2);
 int platform_set_sidetone(struct audio_device *adev,
@@ -187,4 +189,6 @@
 
 unsigned char* platform_get_license(void* platform, int* size);
 int platform_get_max_mic_count(void *platform);
+void platform_check_and_update_copp_sample_rate(void *platform, snd_device_t snd_device,
+     unsigned int stream_sr,int *sample_rate);
 #endif // AUDIO_PLATFORM_API_H
diff --git a/mm-audio/Makefile.am b/mm-audio/Makefile.am
index e423acb..cd7d635 100644
--- a/mm-audio/Makefile.am
+++ b/mm-audio/Makefile.am
@@ -2,4 +2,4 @@
 #
 ACLOCAL_AMFLAGS = -I m4
 
-SUBDIRS = adec-aac adec-mp3 aenc-aac
+SUBDIRS = aenc-aac aenc-amrnb aenc-g711
diff --git a/mm-audio/aenc-aac/qdsp6/Makefile.am b/mm-audio/aenc-aac/qdsp6/Makefile.am
index 5af028a..d5103a4 100644
--- a/mm-audio/aenc-aac/qdsp6/Makefile.am
+++ b/mm-audio/aenc-aac/qdsp6/Makefile.am
@@ -15,16 +15,18 @@
 AM_CPPFLAGS += -DFEATURE_DSM_DUP_ITEMS
 AM_CPPFLAGS += -D_DEBUG
 AM_CPPFLAGS += -Iinc
+AM_CPPFLAGS += -I ${WORKSPACE}/hardware/qcom/media/mm-core/inc/
 
-c_sources  =src/omx_aac_aenc.cpp
+c_sources =src/omx_aac_aenc.cpp
 c_sources +=src/aenc_svr.c
 
 lib_LTLIBRARIES = libOmxAacEnc.la
 libOmxAacEnc_la_SOURCES = $(c_sources)
-libOmxAacEnc_la_CFLAGS = $(AM_CFLAGS) -fPIC
-libOmxAacEnc_la_LDLIBS = -lOmxCore -lstdc++ -lpthread
-libOmxAacEnc_la_LDFLAGS = -shared -version-info $(OMXAUDIO_LIBRARY_VERSION)
+libOmxAacEnc_la_CFLAGS = $(AM_CFLAGS) -fPIC $(GLIB_CFLAGS) -include glib.h -Dstrlcpy=g_strlcpy
+libOmxAacEnc_la_CPPFLAGS = $(AM_CPPFLAGS) -fPIC $(GLIB_CFLAGS) -include glib.h -Dstrlcpy=g_strlcpy
+libOmxAacEnc_la_LDLIBS = -lmm-omxcore -lstdc++ -lpthread $(GLIB_LIBS) -ldl -llog
+libOmxAacEnc_la_LDFLAGS = -shared $(GLIB_LIBS) -version-info $(OMXAUDIO_LIBRARY_VERSION)
 
 bin_PROGRAMS = mm-aenc-omxaac-test
-mm_aenc_omxaac_test_SOURCES = test/omx_aac_enc_test.c
-mm_aenc_omxaac_test_LDADD = -lOmxCore -ldl -lpthread libOmxAacEnc.la
+mm_aenc_omxaac_test_SOURCES = ./test/omx_aac_enc_test.c
+mm_aenc_omxaac_test_LDADD = -lmm-omxcore -ldl -lpthread -llog libOmxAacEnc.la
diff --git a/mm-audio/aenc-amrnb/Makefile.am b/mm-audio/aenc-amrnb/Makefile.am
new file mode 100644
index 0000000..24c1af2
--- /dev/null
+++ b/mm-audio/aenc-amrnb/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = qdsp6
diff --git a/mm-audio/aenc-amrnb/qdsp6/Makefile.am b/mm-audio/aenc-amrnb/qdsp6/Makefile.am
new file mode 100644
index 0000000..b63130c
--- /dev/null
+++ b/mm-audio/aenc-amrnb/qdsp6/Makefile.am
@@ -0,0 +1,42 @@
+AM_CFLAGS = -Wundef \
+        -Wstrict-prototypes \
+        -Wno-trigraphs \
+        -g  -O0 \
+        -fno-inline \
+        -fno-short-enums \
+        -fpic \
+        -I inc \
+        -I ${WORKSPACE}/hardware/qcom/media/mm-core/inc/
+
+# required pre-processor flags
+AM_CPPFLAGS = -D__packed__=
+AM_CPPFLAGS += -DIMAGE_APPS_PROC
+AM_CPPFLAGS += -DFEATURE_Q_SINGLE_LINK
+AM_CPPFLAGS += -DFEATURE_Q_NO_SELF_QPTR
+AM_CPPFLAGS += -DFEATURE_LINUX
+AM_CPPFLAGS += -DFEATURE_NATIVELINUX -Dstrlcpy=g_strlcpy
+AM_CPPFLAGS += -DFEATURE_DSM_DUP_ITEMS
+AM_CPPFLAGS += -I ${WORKSPACE}/hardware/qcom/media/mm-core/inc/
+
+AM_CPPFLAGS += -g
+AM_CPPFLAGS += -D_DEBUG
+AM_CPPFLAGS += -Iinc
+
+c_sources = src/omx_amr_aenc.cpp \
+            src/aenc_svr.c
+
+lib_LTLIBRARIES = libOmxAmrEnc.la
+libOmxAmrEnc_la_CC = @CC@
+libOmxAmrEnc_la_SOURCES = $(c_sources)
+libOmxAmrEnc_la_LIBADD  = -lcutils -llog
+libOmxAmrEnc_la_CFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) $(GLIB_CFLAGS) -include glib.h -Dstrlcpy=g_strlcpy
+libOmxAmrEnc_la_CPPFLAGS = $(AM_CFLAGS) $(AM_CPPFLAGS) $(GLIB_CFLAGS) -include glib.h -Dstrlcpy=g_strlcpy
+libOmxAmrEnc_la_LDFLAGS = $(GLIB_LIBS) -shared -version-info 1:0:0
+
+bin_PROGRAMS = mm_aenc_omxamr_test
+
+mm_aenc_omxamr_test_c_sources = test/omx_amr_enc_test.c
+mm_aenc_omxamr_test_CC = @CC@
+mm_aenc_omxamr_test_SOURCES = $(mm_aenc_omxamr_test_c_sources)
+mm_aenc_omxamr_test_LDADD = libOmxAmrEnc.la -lmm-omxcore
+mm_aenc_omxamr_test_CPPFLAGS = $(AM_CPPFLAGS) $(AM_CFLAGS)
diff --git a/mm-audio/aenc-amrnb/qdsp6/inc/omx_amr_aenc.h b/mm-audio/aenc-amrnb/qdsp6/inc/omx_amr_aenc.h
index 2d72eb2..f4fcf8e 100644
--- a/mm-audio/aenc-amrnb/qdsp6/inc/omx_amr_aenc.h
+++ b/mm-audio/aenc-amrnb/qdsp6/inc/omx_amr_aenc.h
@@ -60,6 +60,8 @@
 #include <semaphore.h>
 #include <linux/msm_audio.h>
 #include <linux/msm_audio_amrnb.h>
+#include <linux/msm_audio_amrwb.h>
+
 extern "C" {
     void * get_omx_component_factory_fn(void);
 }
@@ -144,6 +146,7 @@
 class omx_amr_aenc: public qc_omx_component
 {
 public:
+    int amrwb_enable;
     omx_amr_aenc();                             // constructor
     virtual ~omx_amr_aenc();                    // destructor
 
diff --git a/mm-audio/aenc-amrnb/qdsp6/src/omx_amr_aenc.cpp b/mm-audio/aenc-amrnb/qdsp6/src/omx_amr_aenc.cpp
index ba66d1b..5278671 100644
--- a/mm-audio/aenc-amrnb/qdsp6/src/omx_amr_aenc.cpp
+++ b/mm-audio/aenc-amrnb/qdsp6/src/omx_amr_aenc.cpp
@@ -1102,13 +1102,28 @@
     component_Role.nVersion.nVersion = OMX_SPEC_VERSION;
     if (!strcmp(role,"OMX.qcom.audio.encoder.amrnb"))
     {
+        amrwb_enable = 0;
         pcm_input = 1;
         component_Role.nSize = (OMX_U32)sizeof(role);
         strlcpy((char *)component_Role.cRole, (const char*)role,
 		sizeof(component_Role.cRole));
         DEBUG_PRINT("\ncomponent_init: Component %s LOADED \n", role);
-    } else if (!strcmp(role,"OMX.qcom.audio.encoder.tunneled.amrnb"))
-    {
+    } else if (!strcmp(role,"OMX.qcom.audio.encoder.tunneled.amrnb")) {
+        amrwb_enable = 0;
+        pcm_input = 0;
+        component_Role.nSize = (OMX_U32)sizeof(role);
+        strlcpy((char *)component_Role.cRole, (const char*)role,
+		sizeof(component_Role.cRole));
+        DEBUG_PRINT("\ncomponent_init: Component %s LOADED \n", role);
+    } else if (!strcmp(role,"OMX.qcom.audio.encoder.amrwb")) {
+        amrwb_enable = 1;
+        pcm_input = 1;
+        component_Role.nSize = (OMX_U32)sizeof(role);
+        strlcpy((char *)component_Role.cRole, (const char*)role,
+		sizeof(component_Role.cRole));
+        DEBUG_PRINT("\ncomponent_init: Component %s LOADED \n", role);
+    } else if (!strcmp(role,"OMX.qcom.audio.encoder.tunneled.amrwb")) {
+        amrwb_enable = 1;
         pcm_input = 0;
         component_Role.nSize = (OMX_U32)sizeof(role);
         strlcpy((char *)component_Role.cRole, (const char*)role,
@@ -1124,12 +1139,12 @@
     if(pcm_input)
     {
         m_tmp_meta_buf = (OMX_U8*) malloc(sizeof(OMX_U8) *
-                         (OMX_CORE_INPUT_BUFFER_SIZE + sizeof(META_IN)));
+                (OMX_CORE_INPUT_BUFFER_SIZE + sizeof(META_IN)));
 
         if (m_tmp_meta_buf == NULL){
             DEBUG_PRINT_ERROR("Mem alloc failed for tmp meta buf\n");
-                return OMX_ErrorInsufficientResources;
-	}
+            return OMX_ErrorInsufficientResources;
+        }
     }
     m_tmp_out_meta_buf =
 		(OMX_U8*)malloc(sizeof(OMX_U8)*OMX_AMR_OUTPUT_BUFFER_SIZE);
@@ -1138,16 +1153,29 @@
                 return OMX_ErrorInsufficientResources;
             }
 
-    if(0 == pcm_input)
-    {
-        m_drv_fd = open("/dev/msm_amrnb_in",O_RDONLY);
-    DEBUG_PRINT("Driver in Tunnel mode open\n");
-    }
-    else
-    {
-        m_drv_fd = open("/dev/msm_amrnb_in",O_RDWR);
-    DEBUG_PRINT("Driver in Non Tunnel mode open\n");
-    }
+    if(!amrwb_enable) {
+        if(0 == pcm_input)
+        {
+            m_drv_fd = open("/dev/msm_amrnb_in",O_RDONLY);
+            DEBUG_PRINT("Driver in Tunnel mode open\n");
+        }
+        else
+        {
+            m_drv_fd = open("/dev/msm_amrnb_in",O_RDWR);
+            DEBUG_PRINT("Driver in Non Tunnel mode open\n");
+        }
+    } else {
+        if(0 == pcm_input)
+        {
+            m_drv_fd = open("/dev/msm_amrwb_in",O_RDONLY);
+            DEBUG_PRINT("Driver in Tunnel mode open\n");
+        }
+        else
+        {
+            m_drv_fd = open("/dev/msm_amrwb_in",O_RDWR);
+            DEBUG_PRINT("Driver in Non Tunnel mode open\n");
+        }
+	}
     if (m_drv_fd < 0)
     {
         DEBUG_PRINT_ERROR("Component_init Open Failed[%d] errno[%d]",\
@@ -1417,6 +1445,7 @@
             {
 
                 struct msm_audio_amrnb_enc_config_v2 drv_amr_enc_config;
+                struct msm_audio_amrwb_enc_config drv_amrwb_enc_config;
                 struct msm_audio_stream_config drv_stream_config;
                 struct msm_audio_buf_cfg buf_cfg;
                 struct msm_audio_config pcm_cfg;
@@ -1433,22 +1462,49 @@
                     DEBUG_PRINT_ERROR("ioctl AUDIO_SET_STREAM_CONFIG failed, \
 					errno[%d]\n", errno);
                 }
+                if(!amrwb_enable)
+                {
+                    if(ioctl(m_drv_fd, AUDIO_GET_AMRNB_ENC_CONFIG_V2,
+                                &drv_amr_enc_config) == -1)
+                    {
+                        DEBUG_PRINT_ERROR("ioctl AUDIO_GET_AMRNB_ENC_CONFIG_V2 \
+                                failed, errno[%d]\n", errno);
+                    }
+                } else {
+                    if(ioctl(m_drv_fd, AUDIO_GET_AMRWB_ENC_CONFIG,
+                                &drv_amrwb_enc_config) == -1)
+                    {
+                        DEBUG_PRINT_ERROR("ioctl AUDIO_GET_AMRWB_ENC_CONFIG \
+                                failed, errno[%d]\n", errno);
+                    }
+                }
+                if(!amrwb_enable) {
+                    drv_amr_enc_config.band_mode = m_amr_param.eAMRBandMode;
+                    drv_amr_enc_config.dtx_enable = m_amr_param.eAMRDTXMode;
+                    drv_amr_enc_config.frame_format = m_amr_param.eAMRFrameFormat;
+                } else {
+                    drv_amrwb_enc_config.band_mode = m_amr_param.eAMRBandMode;
+                    drv_amrwb_enc_config.dtx_enable = m_amr_param.eAMRDTXMode;
+                    drv_amrwb_enc_config.frame_format = m_amr_param.eAMRFrameFormat;
+                }
 
-                if(ioctl(m_drv_fd, AUDIO_GET_AMRNB_ENC_CONFIG_V2,
-			&drv_amr_enc_config) == -1)
+                if(!amrwb_enable)
                 {
-                    DEBUG_PRINT_ERROR("ioctl AUDIO_GET_AMRNB_ENC_CONFIG_V2 \
-					failed, errno[%d]\n", errno);
+                    if(ioctl(m_drv_fd, AUDIO_SET_AMRNB_ENC_CONFIG_V2, &drv_amr_enc_config)
+                            == -1)
+                    {
+                        DEBUG_PRINT_ERROR("ioctl AUDIO_SET_AMRNB_ENC_CONFIG_V2 \
+                                failed, errno[%d]\n", errno);
+                    }
+                } else {
+                    if(ioctl(m_drv_fd, AUDIO_SET_AMRWB_ENC_CONFIG, &drv_amrwb_enc_config)
+                            == -1)
+                    {
+                        DEBUG_PRINT_ERROR("ioctl AUDIO_SET_AMRWB_ENC_CONFIG \
+                                failed, errno[%d]\n", errno);
+                    }
                 }
-        drv_amr_enc_config.band_mode = m_amr_param.eAMRBandMode;
-        drv_amr_enc_config.dtx_enable = m_amr_param.eAMRDTXMode;
-        drv_amr_enc_config.frame_format = m_amr_param.eAMRFrameFormat;
-        if(ioctl(m_drv_fd, AUDIO_SET_AMRNB_ENC_CONFIG_V2, &drv_amr_enc_config)
-		== -1)
-                {
-                    DEBUG_PRINT_ERROR("ioctl AUDIO_SET_AMRNB_ENC_CONFIG_V2 \
-					failed, errno[%d]\n", errno);
-                }
+
                 if (ioctl(m_drv_fd, AUDIO_GET_BUF_CFG, &buf_cfg) == -1)
                 {
                     DEBUG_PRINT_ERROR("ioctl AUDIO_GET_BUF_CFG, errno[%d]\n",
diff --git a/mm-audio/aenc-amrnb/qdsp6/test/omx_amr_enc_test.c b/mm-audio/aenc-amrnb/qdsp6/test/omx_amr_enc_test.c
index e509748..3448bff 100644
--- a/mm-audio/aenc-amrnb/qdsp6/test/omx_amr_enc_test.c
+++ b/mm-audio/aenc-amrnb/qdsp6/test/omx_amr_enc_test.c
@@ -89,6 +89,7 @@
 uint32_t pcmplayback = 0;
 uint32_t tunnel      = 0;
 uint32_t format = 1;
+uint32_t amrwb_enable=0;
 #define DEBUG_PRINT printf
 unsigned to_idle_transition = 0;
 unsigned long total_pcm_bytes;
@@ -110,6 +111,7 @@
 #define MIN_BITRATE 4 /* Bit rate 1 - 13.6 , 2 - 6.2 , 3 - 2.7 , 4 - 1.0 kbps*/
 #define MAX_BITRATE 4
 #define AMR_HEADER_SIZE 6
+#define AMRWB_HEADER_SIZE 9
 #define FAILED(result) (result != OMX_ErrorNone)
 
 #define SUCCEEDED(result) (result == OMX_ErrorNone)
@@ -499,6 +501,7 @@
 
     struct sigaction sa;
     char amr_header[6] = {0x23, 0x21, 0x41, 0x4D, 0x52, 0x0A};
+    char amrwb_header[9] = {0x23, 0x21, 0x41, 0x4D, 0x52,0x2D, 0x57, 0x42, 0x0A};
     memset(&sa, 0, sizeof(sa));
     sa.sa_handler = &signal_handler;
     sigaction(SIGABRT, &sa, NULL);
@@ -513,7 +516,7 @@
     pthread_mutex_init(&etb_lock, 0);
     pthread_mutex_init(&etb_lock1, 0);
 
-    if (argc >= 8) {
+    if (argc >= 9) {
         in_filename = argv[1];
           out_filename = argv[2];
     tunnel =  (uint32_t)atoi(argv[3]);
@@ -521,23 +524,35 @@
         dtxenable  = (uint32_t)atoi(argv[5]);
         recpath      = (uint32_t)atoi(argv[6]); // No configuration support yet..
         rectime      = (uint32_t)atoi(argv[7]);
+        amrwb_enable = (uint32_t)atoi(argv[8]);
 
     } else {
           DEBUG_PRINT(" invalid format: \n");
-          DEBUG_PRINT("ex: ./mm-aenc-omxamr-test INPUTFILE OUTPUTFILE Tunnel BANDMODE DTXENABLE RECORDPATH RECORDTIME\n");
+          DEBUG_PRINT("ex: ./mm-aenc-omxamr-test INPUTFILE OUTPUTFILE Tunnel BANDMODE DTXENABLE RECORDPATH RECORDTIME amrwb_enable \n");
           DEBUG_PRINT("Bandmode 1-7, dtxenable 0-1\n");
           DEBUG_PRINT("RECORDPATH 0(TX),1(RX),2(BOTH),3(MIC)\n");
           DEBUG_PRINT("RECORDTIME in seconds for AST Automation\n");
+	  DEBUG_PRINT("amrwb_enable:1-amrwb 0-amrnb\n");
           return 0;
     }
     if(recpath != 3) {
           DEBUG_PRINT("For RECORDPATH Only MIC supported\n");
           return 0;
     }
-    if(tunnel == 0)
-        aud_comp = "OMX.qcom.audio.encoder.amrnb";
-    else
-        aud_comp = "OMX.qcom.audio.encoder.tunneled.amrnb";
+    if(!amrwb_enable)
+    {
+        if(tunnel == 0)
+            aud_comp = "OMX.qcom.audio.encoder.amrnb";
+        else
+            aud_comp = "OMX.qcom.audio.encoder.tunneled.amrnb";
+    }
+    else {
+        if(tunnel == 0)
+            aud_comp = "OMX.qcom.audio.encoder.amrwb";
+        else
+            aud_comp = "OMX.qcom.audio.encoder.tunneled.amrwb";
+    }
+
     if(Init_Encoder(aud_comp)!= 0x00)
     {
         DEBUG_PRINT("Decoder Init failed\n");
@@ -589,7 +604,10 @@
             }
             wait_for_event();
             fseek(outputBufferFile, 0,SEEK_SET);
-            fwrite(amr_header,1,AMR_HEADER_SIZE,outputBufferFile);
+            if(!amrwb_enable)
+                fwrite(amr_header,1,AMR_HEADER_SIZE,outputBufferFile);
+            else
+                fwrite(amrwb_header,1,AMRWB_HEADER_SIZE,outputBufferFile);
 
             result = OMX_FreeHandle(amr_enc_handle);
             if (result != OMX_ErrorNone) {
@@ -1013,7 +1031,11 @@
     error_code = -1;
     return error_code;
     }
-    fseek(outputBufferFile, AMR_HEADER_SIZE, SEEK_SET);
+    if(!amrwb_enable) {
+        fseek(outputBufferFile, AMR_HEADER_SIZE, SEEK_SET);
+    } else {
+        fseek(outputBufferFile, AMRWB_HEADER_SIZE, SEEK_SET);
+    }
     return error_code;
 }
 
diff --git a/mm-audio/aenc-g711/Makefile.am b/mm-audio/aenc-g711/Makefile.am
new file mode 100644
index 0000000..24c1af2
--- /dev/null
+++ b/mm-audio/aenc-g711/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = qdsp6
diff --git a/mm-audio/aenc-g711/qdsp6/Makefile.am b/mm-audio/aenc-g711/qdsp6/Makefile.am
new file mode 100644
index 0000000..572b87d
--- /dev/null
+++ b/mm-audio/aenc-g711/qdsp6/Makefile.am
@@ -0,0 +1,29 @@
+AM_CFLAGS = -Wall \
+            -Wundef \
+            -Wstrict-prototypes \
+            -Wno-trigraphs \
+            -fPIC \
+            -g -O3 \
+            -DQC_MODIFIED \
+            -D_ANDROID_ \
+            -D_ENABLE_QC_MSG_LOG_ \
+            -DVERBOSE \
+            -D_DEBUG \
+            -DAUDIOV2 \
+            -I inc \
+            -I ${WORKSPACE}/hardware/qcom/media/mm-core/inc/
+
+C_SOURCES = src/aenc_svr.c \
+            src/omx_g711_aenc.cpp \
+            src/omx_log.cpp
+
+lib_LTLIBRARIES = libOmxG711Enc.la
+libOmxG711Enc_la_SOURCES = $(C_SOURCES)
+libOmxG711Enc_la_CFLAGS = $(AM_CFLAGS) -Dstrlcpy=g_strlcpy $(GLIB_CFLAGS) -include glib.h
+libOmxG711Enc_la_CPPFLAGS = $(AM_CFLAGS) -Dstrlcpy=g_strlcpy $(GLIB_CFLAGS) -include glib.h
+libOmxG711Enc_la_LDFLAGS = $(GLIB_LIBS) -lcutils -llog -lstdc++
+
+bin_PROGRAMS = mm_aenc_omxg711_test
+mm_aenc_omxg711_test_SOURCES = ./test/omx_g711_enc_test.c
+mm_aenc_omxg711_test_CFLAGS = $(AM_CFLAGS) -Dstrlcpy=g_strlcpy $(GLIB_CFLAGS) -include glib.h
+mm_aenc_omxg711_test_LDADD = $(GLIB_LIBS) -lmm-omxcore -lpthread libOmxG711Enc.la
diff --git a/mm-audio/configure.ac b/mm-audio/configure.ac
index b75d2ed..6eabd87 100644
--- a/mm-audio/configure.ac
+++ b/mm-audio/configure.ac
@@ -1,14 +1,14 @@
 #                                               -*- Autoconf -*-
 
-# configure.ac -- Autoconf script for mm-omxaudio
+# configure.ac -- Autoconf script for encoders
 #
 
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.61)
-AC_INIT([omxaudio],
+AC_INIT([encoders],
 	1.0.0)
-AM_INIT_AUTOMAKE([-Wall -Werror gnu foreign])
+AM_INIT_AUTOMAKE([foreign])
 AM_MAINTAINER_MODE
 AC_CONFIG_HEADER([config.h])
 AC_CONFIG_MACRO_DIR([m4])
@@ -21,6 +21,30 @@
 OMXAUDIO_LIBRARY_VERSION=$OMXAUDIO_MAJOR_VERSION:$OMXAUDIO_MINOR_VERSION:$OMXAUDIO_MICRO_VERSION
 AC_SUBST(OMXAUDIO_LIBRARY_VERSION)
 
+AC_ARG_WITH(sanitized-headers,
+        AS_HELP_STRING([--with-sanitized-headers=DIR],
+                [Specify the location of the sanitized Linux headers]),
+        [CPPFLAGS="$CPPFLAGS -idirafter $withval"])
+
+AC_ARG_WITH([glib],
+      AC_HELP_STRING([--with-glib],
+         [enable glib, Build against glib. Use this when building for HLOS systems which use glib]))
+
+if (test "x${with_glib}" = "xyes"); then
+        PKG_CHECK_MODULES(GTHREAD, gthread-2.0 >= 2.16, dummy=yes,
+                                AC_MSG_ERROR(GThread >= 2.16 is required))
+        PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
+                                AC_MSG_ERROR(GLib >= 2.16 is required))
+        GLIB_CFLAGS="$GLIB_CFLAGS $GTHREAD_CFLAGS"
+        GLIB_LIBS="$GLIB_LIBS $GTHREAD_LIBS"
+
+        AC_SUBST(GLIB_CFLAGS)
+        AC_SUBST(GLIB_LIBS)
+fi
+
+AM_CONDITIONAL(USE_GLIB, test "x${with_glib}" = "xyes")
+
+
 # Checks for programs.
 AC_PROG_CC
 AC_PROG_CPP
@@ -34,11 +58,11 @@
 
 AC_CONFIG_FILES([     \
 	Makefile \
-	adec-aac/Makefile \
-	adec-mp3/Makefile \
 	aenc-aac/Makefile \
-	adec-aac/qdsp6/Makefile \
-	adec-mp3/qdsp6/Makefile \
 	aenc-aac/qdsp6/Makefile \
+	aenc-amrnb/Makefile \
+	aenc-amrnb/qdsp6/Makefile \
+	aenc-g711/Makefile \
+	aenc-g711/qdsp6/Makefile
 	])
 AC_OUTPUT
diff --git a/policy_hal/AudioPolicyManager.cpp b/policy_hal/AudioPolicyManager.cpp
index 089efc5..3396054 100644
--- a/policy_hal/AudioPolicyManager.cpp
+++ b/policy_hal/AudioPolicyManager.cpp
@@ -1409,6 +1409,7 @@
 {
     bool playerDirectPCM = false; // Output request for Track created by mediaplayer
     bool trackDirectPCM = false;  // Output request for track created by other apps
+    bool offloadDisabled = property_get_bool("audio.offload.disable", false);
 
     // Direct PCM is allowed only if
     // In case of mediaPlayer playback
@@ -1417,6 +1418,10 @@
     // In case of AudioTracks created by apps
     // track offload is enabled and FLAG requested is FLAG_NONE.
 
+    if (offloadDisabled) {
+        ALOGI("offload disabled by audio.offload.disable=%d", offloadDisabled);
+    }
+
     if (*flags == AUDIO_OUTPUT_FLAG_DIRECT_PCM) {
        if (bitWidth == 24 || bitWidth == 32)
            playerDirectPCM =
@@ -1431,8 +1436,10 @@
         trackDirectPCM = property_get_bool("audio.offload.track.enable", true);
     }
 
-    ALOGI("%s for Direct PCM",trackDirectPCM || playerDirectPCM?"Check":"Dont check");
-    return trackDirectPCM || playerDirectPCM;
+    ALOGI("Direct PCM %s for this request",
+       (!offloadDisabled && (trackDirectPCM || playerDirectPCM))?"can be enabled":"is disabled");
+
+    return (!offloadDisabled && (trackDirectPCM || playerDirectPCM));
 }
 
 status_t AudioPolicyManagerCustom::getOutputForAttr(const audio_attributes_t *attr,
@@ -1449,15 +1456,11 @@
 {
     audio_offload_info_t tOffloadInfo = AUDIO_INFO_INITIALIZER;
 
-    bool offloadDisabled = property_get_bool("audio.offload.disable", false);
     uint32_t bitWidth = (audio_bytes_per_sample(format) * 8);
 
-    if (offloadDisabled) {
-        ALOGI("offload disabled by audio.offload.disable=%d", offloadDisabled);
-    }
 
-    if (!offloadDisabled && (offloadInfo == NULL) &&
-        tryForDirectPCM(bitWidth, &flags)) {
+    if (tryForDirectPCM(bitWidth, &flags) &&
+        (offloadInfo == NULL)) {
 
         tOffloadInfo.sample_rate  = samplingRate;
         tOffloadInfo.channel_mask = channelMask;
diff --git a/visualizer/offload_visualizer.c b/visualizer/offload_visualizer.c
index f49c434..ef2835a 100644
--- a/visualizer/offload_visualizer.c
+++ b/visualizer/offload_visualizer.c
@@ -896,6 +896,14 @@
         break;
 
     case VISUALIZER_CMD_MEASURE: {
+        if (pReplyData == NULL || replySize == NULL ||
+                *replySize < (sizeof(int32_t) * MEASUREMENT_COUNT)) {
+            ALOGV("%s VISUALIZER_CMD_MEASURE error *replySize %d <"
+                    "(sizeof(int32_t) * MEASUREMENT_COUNT) %d",
+                    __func__, *replySize, sizeof(int32_t) * MEASUREMENT_COUNT);
+            android_errorWriteLog(0x534e4554, "30229821");
+            return -EINVAL;
+        }
         uint16_t peak_u16 = 0;
         float sum_rms_squared = 0.0f;
         uint8_t nb_valid_meas = 0;