Merge "configs: sdm845: Add compress-voip bt-a2dp path entries"
diff --git a/Android.mk b/Android.mk
index 5101724..e590854 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,4 +1,4 @@
-ifneq ($(filter mpq8092 msm8960 msm8226 msm8x26 msm8610 msm8974 msm8x74 apq8084 msm8916 msm8994 msm8992 msm8909 msm8996 msm8952 msm8937 thorium msm8953 msmgold msm8998 sdm660 sdm845 msmpeafowl apq8098_latv,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter mpq8092 msm8960 msm8226 msm8x26 msm8610 msm8974 msm8x74 apq8084 msm8916 msm8994 msm8992 msm8909 msm8996 msm8952 msm8937 thorium msm8953 msmgold msm8998 sdm660 sdm845 sdm670 apq8098_latv,$(TARGET_BOARD_PLATFORM)),)
 
 MY_LOCAL_PATH := $(call my-dir)
 
diff --git a/configs/msm8996/audio_platform_info_i2s.xml b/configs/msm8996/audio_platform_info_i2s.xml
index 7e12aa8..f45cbac 100644
--- a/configs/msm8996/audio_platform_info_i2s.xml
+++ b/configs/msm8996/audio_platform_info_i2s.xml
@@ -34,4 +34,10 @@
         <device name="SND_DEVICE_OUT_SPEAKER" acdb_id="10" />
         <device name="SND_DEVICE_OUT_VOICE_SPEAKER" acdb_id="10" />
     </acdb_ids>
+    <pcm_ids>
+        <usecase name="USECASE_VOICEMMODE1_CALL" type="in" id="2"/>
+        <usecase name="USECASE_VOICEMMODE1_CALL" type="out" id="2"/>
+        <usecase name="USECASE_VOICEMMODE2_CALL" type="in" id="2"/>
+        <usecase name="USECASE_VOICEMMODE2_CALL" type="out" id="2"/>
+    </pcm_ids>
 </audio_platform_info_i2s>
diff --git a/configs/msm8996/mixer_paths_i2s.xml b/configs/msm8996/mixer_paths_i2s.xml
index 256305e..76a28c9 100644
--- a/configs/msm8996/mixer_paths_i2s.xml
+++ b/configs/msm8996/mixer_paths_i2s.xml
@@ -123,12 +123,16 @@
     </path>
 
     <path name="voicemmode2-call">
-        <ctl name="Voice2 Stub Tx Mixer TERT_MI2S_TX" value="1" />
-        <ctl name="QUAT_MI2S_RX_Voice Mixer Voice2 Stub" value="1" />
-        <ctl name="Voice2 Stub Tx Mixer QUAT_MI2S_TX" value="1" />
-        <ctl name="TERT_MI2S_RX_Voice Mixer Voice2 Stub" value="1" />
-        <ctl name="QUAT_MI2S_RX Port Mixer TERT_MI2S_TX" value="1" />
-        <ctl name="TERT_MI2S_RX Port Mixer QUAT_MI2S_TX" value="1" />
+        <ctl name="Voice Stub Tx Mixer PRI_MI2S_TX" value="1" />
+        <ctl name="QUAT_MI2S_RX_Voice Mixer Voice Stub" value="1" />
+        <ctl name="Voice Stub Tx Mixer QUAT_MI2S_TX" value="1" />
+        <ctl name="PRI_MI2S_RX_Voice Mixer Voice Stub" value="1" />
+        <ctl name="QUAT_MI2S_RX Port Mixer PRI_MI2S_TX" value="1" />
+        <ctl name="PRI_MI2S_RX Port Mixer QUAT_MI2S_TX" value="1" />
+    </path>
+
+    <path name="gsm-mode">
+        <ctl name="GSM mode Enable" value="ON" />
     </path>
 
     <!-- These are actual sound device specific mixer settings -->
diff --git a/configs/msmpeafowl/audio_effects.conf b/configs/sdm670/audio_effects.conf
similarity index 100%
rename from configs/msmpeafowl/audio_effects.conf
rename to configs/sdm670/audio_effects.conf
diff --git a/configs/msmpeafowl/audio_output_policy.conf b/configs/sdm670/audio_output_policy.conf
similarity index 100%
rename from configs/msmpeafowl/audio_output_policy.conf
rename to configs/sdm670/audio_output_policy.conf
diff --git a/configs/msmpeafowl/audio_platform_info.xml b/configs/sdm670/audio_platform_info.xml
similarity index 100%
rename from configs/msmpeafowl/audio_platform_info.xml
rename to configs/sdm670/audio_platform_info.xml
diff --git a/configs/msmpeafowl/audio_platform_info_i2s.xml b/configs/sdm670/audio_platform_info_i2s.xml
similarity index 100%
rename from configs/msmpeafowl/audio_platform_info_i2s.xml
rename to configs/sdm670/audio_platform_info_i2s.xml
diff --git a/configs/msmpeafowl/audio_platform_info_intcodec.xml b/configs/sdm670/audio_platform_info_intcodec.xml
similarity index 98%
rename from configs/msmpeafowl/audio_platform_info_intcodec.xml
rename to configs/sdm670/audio_platform_info_intcodec.xml
index 7ef1e4c..d04ced2 100644
--- a/configs/msmpeafowl/audio_platform_info_intcodec.xml
+++ b/configs/sdm670/audio_platform_info_intcodec.xml
@@ -65,8 +65,8 @@
         <!-- In the below value string, the value indicates default mono -->
         <!-- speaker. It can be set to either left or right              -->
         <param key="mono_speaker" value="right"/>
-        <param key="spkr_1_tz_name" value="wsatz.13"/>
-        <param key="spkr_2_tz_name" value="wsatz.14"/>
+        <param key="spkr_1_tz_name" value="wsatz.11"/>
+        <param key="spkr_2_tz_name" value="wsatz.12"/>
         <param key="true_32_bit" value="true"/>
         <param key="native_audio_mode" value="true"/>
         <param key="hfp_pcm_dev_id" value="39"/>
diff --git a/configs/msmpeafowl/audio_policy.conf b/configs/sdm670/audio_policy.conf
similarity index 100%
rename from configs/msmpeafowl/audio_policy.conf
rename to configs/sdm670/audio_policy.conf
diff --git a/configs/msmpeafowl/audio_policy_configuration.xml b/configs/sdm670/audio_policy_configuration.xml
similarity index 100%
rename from configs/msmpeafowl/audio_policy_configuration.xml
rename to configs/sdm670/audio_policy_configuration.xml
diff --git a/configs/msmpeafowl/audio_tuning_mixer.txt b/configs/sdm670/audio_tuning_mixer.txt
similarity index 100%
rename from configs/msmpeafowl/audio_tuning_mixer.txt
rename to configs/sdm670/audio_tuning_mixer.txt
diff --git a/configs/msmpeafowl/audio_tuning_mixer_tasha.txt b/configs/sdm670/audio_tuning_mixer_tasha.txt
similarity index 100%
rename from configs/msmpeafowl/audio_tuning_mixer_tasha.txt
rename to configs/sdm670/audio_tuning_mixer_tasha.txt
diff --git a/configs/msmpeafowl/audio_tuning_mixer_tavil.txt b/configs/sdm670/audio_tuning_mixer_tavil.txt
similarity index 100%
rename from configs/msmpeafowl/audio_tuning_mixer_tavil.txt
rename to configs/sdm670/audio_tuning_mixer_tavil.txt
diff --git a/configs/msmpeafowl/graphite_ipc_platform_info.xml b/configs/sdm670/graphite_ipc_platform_info.xml
similarity index 100%
rename from configs/msmpeafowl/graphite_ipc_platform_info.xml
rename to configs/sdm670/graphite_ipc_platform_info.xml
diff --git a/configs/msmpeafowl/listen_platform_info.xml b/configs/sdm670/listen_platform_info.xml
similarity index 100%
rename from configs/msmpeafowl/listen_platform_info.xml
rename to configs/sdm670/listen_platform_info.xml
diff --git a/configs/msmpeafowl/mixer_paths.xml b/configs/sdm670/mixer_paths.xml
similarity index 100%
rename from configs/msmpeafowl/mixer_paths.xml
rename to configs/sdm670/mixer_paths.xml
diff --git a/configs/msmpeafowl/mixer_paths_i2s.xml b/configs/sdm670/mixer_paths_i2s.xml
similarity index 100%
rename from configs/msmpeafowl/mixer_paths_i2s.xml
rename to configs/sdm670/mixer_paths_i2s.xml
diff --git a/configs/msmpeafowl/mixer_paths_mtp.xml b/configs/sdm670/mixer_paths_mtp.xml
similarity index 99%
rename from configs/msmpeafowl/mixer_paths_mtp.xml
rename to configs/sdm670/mixer_paths_mtp.xml
index 145a1dd..b08059c 100644
--- a/configs/msmpeafowl/mixer_paths_mtp.xml
+++ b/configs/sdm670/mixer_paths_mtp.xml
@@ -1600,7 +1600,7 @@
     </path>
 
     <path name="handset">
-        <ctl name="EAR SPKR PA Gain" value="G_6_DB" />
+        <ctl name="EAR SPKR PA Gain" value="G_3_DB" />
         <path name="speaker-mono" />
     </path>
 
@@ -1612,7 +1612,7 @@
     </path>
 
     <path name="handset-mic-cdp">
-        <path name="adc1" />
+        <path name="dmic2" />
     </path>
 
     <path name="handset-mic-sbc">
diff --git a/configs/msmpeafowl/mixer_paths_tasha.xml b/configs/sdm670/mixer_paths_tasha.xml
similarity index 95%
rename from configs/msmpeafowl/mixer_paths_tasha.xml
rename to configs/sdm670/mixer_paths_tasha.xml
index 2971282..be2f56b 100644
--- a/configs/msmpeafowl/mixer_paths_tasha.xml
+++ b/configs/sdm670/mixer_paths_tasha.xml
@@ -530,6 +530,13 @@
     <!-- ssr qmic -->
     <ctl name="AIF1_CAP Mixer SLIM TX10" value="0" />
     <!-- ssr qmic end-->
+    <!-- vbat related data -->
+    <ctl name="GSM mode Enable" value="OFF" />
+    <ctl name="RX INT5 VBAT LO3 VBAT Enable" value="0" />
+    <ctl name="RX INT6 VBAT LO4 VBAT Enable" value="0" />
+    <ctl name="RX INT7 VBAT SPKRL VBAT Enable" value="0" />
+    <ctl name="RX INT8 VBAT SPKRR VBAT Enable" value="0" />
+    <!-- vbat related data end-->
     <!-- audio record compress-->
     <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="0" />
     <ctl name="MultiMedia8 Mixer SLIM_7_TX" value="0" />
@@ -564,6 +571,33 @@
         <ctl name="GSM mode Enable" value="ON" />
     </path>
 
+    <path name="echo-reference speaker-vbat-mono">
+        <ctl name="AIF3_CAP Mixer SLIM TX1" value="1" />
+        <ctl name="SLIM TX1 MUX" value="RX_MIX_TX1" />
+        <ctl name="RX MIX TX1 MUX" value="RX_MIX_VBAT7" />
+        <ctl name="SLIM_1_TX Channels" value="One" />
+        <ctl name="VOC_EXT_EC MUX" value="SLIM_1_TX" />
+   </path>
+
+    <path name="echo-reference speaker-vbat-mono-2">
+        <ctl name="AIF3_CAP Mixer SLIM TX2" value="1" />
+        <ctl name="SLIM TX2 MUX" value="RX_MIX_TX2" />
+        <ctl name="RX MIX TX2 MUX" value="RX_MIX_VBAT8" />
+        <ctl name="SLIM_1_TX Channels" value="One" />
+        <ctl name="VOC_EXT_EC MUX" value="SLIM_1_TX" />
+   </path>
+
+   <path name="echo-reference speaker-vbat">
+        <ctl name="AIF3_CAP Mixer SLIM TX1" value="1" />
+        <ctl name="AIF3_CAP Mixer SLIM TX2" value="1" />
+        <ctl name="SLIM TX1 MUX" value="RX_MIX_TX1" />
+        <ctl name="SLIM TX2 MUX" value="RX_MIX_TX2" />
+        <ctl name="RX MIX TX1 MUX" value="RX_MIX_VBAT7" />
+        <ctl name="RX MIX TX2 MUX" value="RX_MIX_VBAT8" />
+        <ctl name="SLIM_1_TX Channels" value="Two" />
+        <ctl name="AUDIO_REF_EC_UL1 MUX" value="SLIM_1_TX" />
+    </path>
+
     <path name="echo-reference">
         <ctl name="AUDIO_REF_EC_UL1 MUX" value="SLIM_RX" />
     </path>
@@ -1536,6 +1570,16 @@
         <ctl name="Voip_Tx Mixer USB_AUDIO_TX_Voip" value="1" />
     </path>
 
+    <path name="compress-voip-call voice-speaker-vbat">
+        <path name="echo-reference speaker-vbat-mono" />
+        <path name="compress-voip-call"/>
+    </path>
+
+    <path name="compress-voip-call voice-speaker-2-vbat">
+        <path name="echo-reference speaker-vbat-mono-2" />
+        <path name="compress-voip-call"/>
+    </path>
+
     <path name="vowlan-call">
         <ctl name="SLIM_0_RX_Voice Mixer VoWLAN" value="1" />
         <ctl name="VoWLAN_Tx Mixer SLIM_0_TX_VoWLAN" value="1" />
@@ -1571,6 +1615,16 @@
         <ctl name="VoWLAN_Tx Mixer USB_AUDIO_TX_VoWLAN" value="1" />
     </path>
 
+    <path name="vowlan-call voice-speaker-vbat">
+        <path name="echo-reference speaker-vbat-mono" />
+        <path name="vowlan-call"/>
+    </path>
+
+    <path name="vowlan-call voice-speaker-2-vbat">
+        <path name="echo-reference speaker-vbat-mono-2" />
+        <path name="vowlan-call"/>
+    </path>
+
     <path name="voicemmode1-call">
         <ctl name="SLIM_0_RX_Voice Mixer VoiceMMode1" value="1" />
         <ctl name="VoiceMMode1_Tx Mixer SLIM_0_TX_MMode1" value="1" />
@@ -1606,6 +1660,16 @@
         <ctl name="VoiceMMode1_Tx Mixer USB_AUDIO_TX_MMode1" value="1" />
     </path>
 
+    <path name="voicemmode1-call voice-speaker-vbat">
+        <path name="echo-reference speaker-vbat-mono" />
+        <path name="voicemmode1-call"/>
+    </path>
+
+    <path name="voicemmode1-call voice-speaker-2-vbat">
+        <path name="echo-reference speaker-vbat-mono-2" />
+        <path name="voicemmode1-call"/>
+    </path>
+
     <path name="voicemmode2-call">
         <ctl name="SLIM_0_RX_Voice Mixer VoiceMMode2" value="1" />
         <ctl name="VoiceMMode2_Tx Mixer SLIM_0_TX_MMode2" value="1" />
@@ -1641,6 +1705,16 @@
         <ctl name="VoiceMMode2_Tx Mixer USB_AUDIO_TX_MMode2" value="1" />
     </path>
 
+    <path name="voicemmode2-call voice-speaker-vbat">
+        <path name="echo-reference speaker-vbat-mono" />
+        <path name="voicemmode2-call"/>
+    </path>
+
+    <path name="voicemmode2-call voice-speaker-2-vbat">
+        <path name="echo-reference speaker-vbat-mono-2" />
+        <path name="voicemmode2-call"/>
+    </path>
+
     <path name="listen-voice-wakeup-1">
         <ctl name="LSM1 MUX" value="SLIMBUS_5_TX" />
         <ctl name="SLIMBUS_5_TX LSM Function" value="AUDIO" />
@@ -1828,6 +1902,22 @@
         <path name="speaker" />
     </path>
 
+   <path name="speaker-vbat-mono">
+       <path name="speaker-mono" />
+       <ctl name="RX INT7 VBAT SPKRL VBAT Enable" value="1" />
+   </path>
+
+   <path name="speaker-vbat-mono-2">
+       <path name="speaker-mono-2" />
+       <ctl name="RX INT8 VBAT SPKRL VBAT Enable" value="1" />
+   </path>
+
+   <path name="speaker-vbat">
+       <path name="speaker" />
+       <ctl name="RX INT7 VBAT SPKRL VBAT Enable" value="1" />
+       <ctl name="RX INT8 VBAT SPKRR VBAT Enable" value="1" />
+   </path>
+
    <path name="sidetone-iir">
         <ctl name="IIR0 Enable Band1" value="1" />
         <ctl name="IIR0 Enable Band2" value="1" />
@@ -1898,6 +1988,22 @@
     <path name="vi-feedback-mono-2">
     </path>
 
+    <path name="speaker-protected-vbat">
+        <path name="speaker-protected" />
+        <ctl name="RX INT7 VBAT SPKRL VBAT Enable" value="1" />
+        <ctl name="RX INT8 VBAT SPKRR VBAT Enable" value="1" />
+    </path>
+
+    <path name="voice-speaker-protected-vbat">
+        <path name="voice-speaker-protected" />
+        <ctl name="RX INT7 VBAT SPKRL VBAT Enable" value="1" />
+    </path>
+
+    <path name="voice-speaker-2-protected-vbat">
+        <path name="voice-speaker-2-protected" />
+        <ctl name="RX INT8 VBAT SPKRL VBAT Enable" value="1" />
+    </path>
+
     <path name="handset">
         <ctl name="COMP7 Switch" value="1" />
         <ctl name="SLIM RX0 MUX" value="AIF_MIX1_PB" />
@@ -2036,6 +2142,14 @@
         <path name="speaker-mic" />
     </path>
 
+    <path name="voice-speaker-vbat">
+        <path name="speaker-vbat-mono" />
+    </path>
+
+    <path name="voice-speaker-2-vbat">
+        <path name="speaker-vbat-mono-2" />
+    </path>
+
     <path name="voice-headphones">
         <path name="headphones" />
         <ctl name="RX HPH Mode" value="CLS_H_LP" />
diff --git a/configs/msmpeafowl/mixer_paths_tashalite.xml b/configs/sdm670/mixer_paths_tashalite.xml
similarity index 95%
rename from configs/msmpeafowl/mixer_paths_tashalite.xml
rename to configs/sdm670/mixer_paths_tashalite.xml
index 33cb226..65dec6a 100644
--- a/configs/msmpeafowl/mixer_paths_tashalite.xml
+++ b/configs/sdm670/mixer_paths_tashalite.xml
@@ -530,6 +530,13 @@
     <!-- ssr qmic -->
     <ctl name="AIF1_CAP Mixer SLIM TX10" value="0" />
     <!-- ssr qmic end-->
+    <!-- vbat related data -->
+    <ctl name="GSM mode Enable" value="OFF" />
+    <ctl name="RX INT5 VBAT LO3 VBAT Enable" value="0" />
+    <ctl name="RX INT6 VBAT LO4 VBAT Enable" value="0" />
+    <ctl name="RX INT7 VBAT SPKRL VBAT Enable" value="0" />
+    <ctl name="RX INT8 VBAT SPKRR VBAT Enable" value="0" />
+    <!-- vbat related data end-->
     <!-- audio record compress-->
     <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="0" />
     <ctl name="MultiMedia8 Mixer SLIM_7_TX" value="0" />
@@ -564,6 +571,33 @@
         <ctl name="GSM mode Enable" value="ON" />
     </path>
 
+    <path name="echo-reference speaker-vbat-mono">
+        <ctl name="AIF3_CAP Mixer SLIM TX1" value="1" />
+        <ctl name="SLIM TX1 MUX" value="RX_MIX_TX1" />
+        <ctl name="RX MIX TX1 MUX" value="RX_MIX_VBAT7" />
+        <ctl name="SLIM_1_TX Channels" value="One" />
+        <ctl name="VOC_EXT_EC MUX" value="SLIM_1_TX" />
+   </path>
+
+    <path name="echo-reference speaker-vbat-mono-2">
+        <ctl name="AIF3_CAP Mixer SLIM TX2" value="1" />
+        <ctl name="SLIM TX2 MUX" value="RX_MIX_TX2" />
+        <ctl name="RX MIX TX2 MUX" value="RX_MIX_VBAT8" />
+        <ctl name="SLIM_1_TX Channels" value="One" />
+        <ctl name="VOC_EXT_EC MUX" value="SLIM_1_TX" />
+   </path>
+
+   <path name="echo-reference speaker-vbat">
+        <ctl name="AIF3_CAP Mixer SLIM TX1" value="1" />
+        <ctl name="AIF3_CAP Mixer SLIM TX2" value="1" />
+        <ctl name="SLIM TX1 MUX" value="RX_MIX_TX1" />
+        <ctl name="SLIM TX2 MUX" value="RX_MIX_TX2" />
+        <ctl name="RX MIX TX1 MUX" value="RX_MIX_VBAT7" />
+        <ctl name="RX MIX TX2 MUX" value="RX_MIX_VBAT8" />
+        <ctl name="SLIM_1_TX Channels" value="Two" />
+        <ctl name="AUDIO_REF_EC_UL1 MUX" value="SLIM_1_TX" />
+    </path>
+
     <path name="echo-reference">
         <ctl name="AUDIO_REF_EC_UL1 MUX" value="SLIM_RX" />
     </path>
@@ -1536,6 +1570,16 @@
         <ctl name="Voip_Tx Mixer USB_AUDIO_TX_Voip" value="1" />
     </path>
 
+    <path name="compress-voip-call voice-speaker-vbat">
+        <path name="echo-reference speaker-vbat-mono" />
+        <path name="compress-voip-call"/>
+    </path>
+
+    <path name="compress-voip-call voice-speaker-2-vbat">
+        <path name="echo-reference speaker-vbat-mono-2" />
+        <path name="compress-voip-call"/>
+    </path>
+
     <path name="vowlan-call">
         <ctl name="SLIM_0_RX_Voice Mixer VoWLAN" value="1" />
         <ctl name="VoWLAN_Tx Mixer SLIM_0_TX_VoWLAN" value="1" />
@@ -1571,6 +1615,16 @@
         <ctl name="VoWLAN_Tx Mixer USB_AUDIO_TX_VoWLAN" value="1" />
     </path>
 
+    <path name="vowlan-call voice-speaker-vbat">
+        <path name="echo-reference speaker-vbat-mono" />
+        <path name="vowlan-call"/>
+    </path>
+
+    <path name="vowlan-call voice-speaker-2-vbat">
+        <path name="echo-reference speaker-vbat-mono-2" />
+        <path name="vowlan-call"/>
+    </path>
+
     <path name="voicemmode1-call">
         <ctl name="SLIM_0_RX_Voice Mixer VoiceMMode1" value="1" />
         <ctl name="VoiceMMode1_Tx Mixer SLIM_0_TX_MMode1" value="1" />
@@ -1606,6 +1660,16 @@
         <ctl name="VoiceMMode1_Tx Mixer USB_AUDIO_TX_MMode1" value="1" />
     </path>
 
+    <path name="voicemmode1-call voice-speaker-vbat">
+        <path name="echo-reference speaker-vbat-mono" />
+        <path name="voicemmode1-call"/>
+    </path>
+
+    <path name="voicemmode1-call voice-speaker-2-vbat">
+        <path name="echo-reference speaker-vbat-mono-2" />
+        <path name="voicemmode1-call"/>
+    </path>
+
     <path name="voicemmode2-call">
         <ctl name="SLIM_0_RX_Voice Mixer VoiceMMode2" value="1" />
         <ctl name="VoiceMMode2_Tx Mixer SLIM_0_TX_MMode2" value="1" />
@@ -1641,6 +1705,16 @@
         <ctl name="VoiceMMode2_Tx Mixer USB_AUDIO_TX_MMode2" value="1" />
     </path>
 
+    <path name="voicemmode2-call voice-speaker-vbat">
+        <path name="echo-reference speaker-vbat-mono" />
+        <path name="voicemmode2-call"/>
+    </path>
+
+    <path name="voicemmode2-call voice-speaker-2-vbat">
+        <path name="echo-reference speaker-vbat-mono-2" />
+        <path name="voicemmode2-call"/>
+    </path>
+
     <path name="listen-voice-wakeup-1">
         <ctl name="LSM1 MUX" value="SLIMBUS_5_TX" />
         <ctl name="SLIMBUS_5_TX LSM Function" value="AUDIO" />
@@ -1828,6 +1902,22 @@
         <path name="speaker" />
     </path>
 
+   <path name="speaker-vbat-mono">
+       <path name="speaker-mono" />
+       <ctl name="RX INT7 VBAT SPKRL VBAT Enable" value="1" />
+   </path>
+
+   <path name="speaker-vbat-mono-2">
+       <path name="speaker-mono-2" />
+       <ctl name="RX INT8 VBAT SPKRL VBAT Enable" value="1" />
+   </path>
+
+   <path name="speaker-vbat">
+       <path name="speaker" />
+       <ctl name="RX INT7 VBAT SPKRL VBAT Enable" value="1" />
+       <ctl name="RX INT8 VBAT SPKRR VBAT Enable" value="1" />
+   </path>
+
    <path name="sidetone-iir">
         <ctl name="IIR0 Enable Band1" value="1" />
         <ctl name="IIR0 Enable Band2" value="1" />
@@ -1898,6 +1988,22 @@
     <path name="vi-feedback-mono-2">
     </path>
 
+    <path name="speaker-protected-vbat">
+        <path name="speaker-protected" />
+        <ctl name="RX INT7 VBAT SPKRL VBAT Enable" value="1" />
+        <ctl name="RX INT8 VBAT SPKRR VBAT Enable" value="1" />
+    </path>
+
+    <path name="voice-speaker-protected-vbat">
+        <path name="voice-speaker-protected" />
+        <ctl name="RX INT7 VBAT SPKRL VBAT Enable" value="1" />
+    </path>
+
+    <path name="voice-speaker-2-protected-vbat">
+        <path name="voice-speaker-2-protected" />
+        <ctl name="RX INT8 VBAT SPKRL VBAT Enable" value="1" />
+    </path>
+
     <path name="handset">
         <ctl name="COMP7 Switch" value="1" />
         <ctl name="SLIM RX0 MUX" value="AIF_MIX1_PB" />
@@ -2036,6 +2142,14 @@
         <path name="speaker-mic" />
     </path>
 
+    <path name="voice-speaker-vbat">
+        <path name="speaker-vbat-mono" />
+    </path>
+
+    <path name="voice-speaker-2-vbat">
+        <path name="speaker-vbat-mono-2" />
+    </path>
+
     <path name="voice-headphones">
         <path name="headphones" />
         <ctl name="RX HPH Mode" value="CLS_H_LP" />
diff --git a/configs/msmpeafowl/mixer_paths_tavil.xml b/configs/sdm670/mixer_paths_tavil.xml
similarity index 99%
rename from configs/msmpeafowl/mixer_paths_tavil.xml
rename to configs/sdm670/mixer_paths_tavil.xml
index 03b10f1..8a8783b 100644
--- a/configs/msmpeafowl/mixer_paths_tavil.xml
+++ b/configs/sdm670/mixer_paths_tavil.xml
@@ -485,8 +485,8 @@
     <ctl name="IIR0 Band3" id ="1" value="0" />
     <ctl name="IIR0 Band3" id ="2" value="0" />
     <ctl name="IIR0 Band3" id ="3" value="0" />
-    <ctl name="IIR0 Band3" id ="4" value="268435456" />
-    <ctl name="IIR0 Band4" id ="0" value="0" />
+    <ctl name="IIR0 Band3" id ="4" value="0" />
+    <ctl name="IIR0 Band4" id ="0" value="268435456" />
     <ctl name="IIR0 Band4" id ="1" value="0" />
     <ctl name="IIR0 Band4" id ="2" value="0" />
     <ctl name="IIR0 Band4" id ="3" value="0" />
diff --git a/configs/msmpeafowl/msmpeafowl.mk b/configs/sdm670/sdm670.mk
similarity index 71%
rename from configs/msmpeafowl/msmpeafowl.mk
rename to configs/sdm670/sdm670.mk
index 389d7ca..7efcc2f 100644
--- a/configs/msmpeafowl/msmpeafowl.mk
+++ b/configs/sdm670/sdm670.mk
@@ -75,36 +75,36 @@
     device/qcom/common/media/audio_policy.conf:system/etc/audio_policy.conf
 else
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msmpeafowl/audio_policy.conf:system/etc/audio_policy.conf
+    hardware/qcom/audio/configs/sdm670/audio_policy.conf:system/etc/audio_policy.conf
 endif
 
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msmpeafowl/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
-    hardware/qcom/audio/configs/msmpeafowl/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
-    hardware/qcom/audio/configs/msmpeafowl/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
-    hardware/qcom/audio/configs/msmpeafowl/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
-    hardware/qcom/audio/configs/msmpeafowl/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
-    hardware/qcom/audio/configs/msmpeafowl/mixer_paths_tasha.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tasha.xml \
-    hardware/qcom/audio/configs/msmpeafowl/mixer_paths_tashalite.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tashalite.xml \
-    hardware/qcom/audio/configs/msmpeafowl/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
-    hardware/qcom/audio/configs/msmpeafowl/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
-    hardware/qcom/audio/configs/msmpeafowl/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
-    hardware/qcom/audio/configs/msmpeafowl/audio_tuning_mixer_tasha.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tasha.txt \
-    hardware/qcom/audio/configs/msmpeafowl/audio_platform_info_intcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_intcodec.xml \
-    hardware/qcom/audio/configs/msmpeafowl/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
-    hardware/qcom/audio/configs/msmpeafowl/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
-    hardware/qcom/audio/configs/msmpeafowl/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
-    hardware/qcom/audio/configs/msmpeafowl/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
-    hardware/qcom/audio/configs/msmpeafowl/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
-    hardware/qcom/audio/configs/msmpeafowl/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/msmpeafowl/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
-    hardware/qcom/audio/configs/msmpeafowl/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
+    hardware/qcom/audio/configs/sdm670/audio_output_policy.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_output_policy.conf \
+    hardware/qcom/audio/configs/sdm670/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
+    hardware/qcom/audio/configs/sdm670/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
+    hardware/qcom/audio/configs/sdm670/mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths.xml \
+    hardware/qcom/audio/configs/sdm670/mixer_paths_mtp.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_mtp.xml \
+    hardware/qcom/audio/configs/sdm670/mixer_paths_tasha.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tasha.xml \
+    hardware/qcom/audio/configs/sdm670/mixer_paths_tashalite.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tashalite.xml \
+    hardware/qcom/audio/configs/sdm670/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
+    hardware/qcom/audio/configs/sdm670/audio_tuning_mixer.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer.txt \
+    hardware/qcom/audio/configs/sdm670/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
+    hardware/qcom/audio/configs/sdm670/audio_tuning_mixer_tasha.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tasha.txt \
+    hardware/qcom/audio/configs/sdm670/audio_platform_info_intcodec.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_intcodec.xml \
+    hardware/qcom/audio/configs/sdm670/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
+    hardware/qcom/audio/configs/sdm670/audio_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info.xml \
+    hardware/qcom/audio/configs/sdm670/sound_trigger_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_platform_info.xml \
+    hardware/qcom/audio/configs/sdm670/sound_trigger_mixer_paths.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths.xml \
+    hardware/qcom/audio/configs/sdm670/sound_trigger_mixer_paths_wcd9335.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9335.xml \
+    hardware/qcom/audio/configs/sdm670/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
+    hardware/qcom/audio/configs/sdm670/sound_trigger_mixer_paths_wcd9340.xml:$(TARGET_COPY_OUT_VENDOR)/etc/sound_trigger_mixer_paths_wcd9340.xml \
+    hardware/qcom/audio/configs/sdm670/graphite_ipc_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/graphite_ipc_platform_info.xml \
 
 #XML Audio configuration files
 ifeq ($(USE_XML_AUDIO_POLICY_CONF), 1)
 ifneq ($(TARGET_USES_AOSP_FOR_AUDIO), true)
 PRODUCT_COPY_FILES += \
-    $(TOPDIR)hardware/qcom/audio/configs/msmpeafowl/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
+    $(TOPDIR)hardware/qcom/audio/configs/sdm670/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio/audio_policy_configuration.xml
 endif
 PRODUCT_COPY_FILES += \
     $(TOPDIR)hardware/qcom/audio/configs/common/audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_policy_configuration.xml \
@@ -117,7 +117,7 @@
 
 # Listen configuration file
 PRODUCT_COPY_FILES += \
-    hardware/qcom/audio/configs/msmpeafowl/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
+    hardware/qcom/audio/configs/sdm670/listen_platform_info.xml:$(TARGET_COPY_OUT_VENDOR)/etc/listen_platform_info.xml
 
 # Reduce client buffer size for fast audio output tracks
 PRODUCT_PROPERTY_OVERRIDES += \
diff --git a/configs/msmpeafowl/sound_trigger_mixer_paths.xml b/configs/sdm670/sound_trigger_mixer_paths.xml
similarity index 100%
rename from configs/msmpeafowl/sound_trigger_mixer_paths.xml
rename to configs/sdm670/sound_trigger_mixer_paths.xml
diff --git a/configs/msmpeafowl/sound_trigger_mixer_paths_wcd9335.xml b/configs/sdm670/sound_trigger_mixer_paths_wcd9335.xml
similarity index 100%
rename from configs/msmpeafowl/sound_trigger_mixer_paths_wcd9335.xml
rename to configs/sdm670/sound_trigger_mixer_paths_wcd9335.xml
diff --git a/configs/msmpeafowl/sound_trigger_mixer_paths_wcd9340.xml b/configs/sdm670/sound_trigger_mixer_paths_wcd9340.xml
similarity index 100%
rename from configs/msmpeafowl/sound_trigger_mixer_paths_wcd9340.xml
rename to configs/sdm670/sound_trigger_mixer_paths_wcd9340.xml
diff --git a/configs/msmpeafowl/sound_trigger_platform_info.xml b/configs/sdm670/sound_trigger_platform_info.xml
similarity index 100%
rename from configs/msmpeafowl/sound_trigger_platform_info.xml
rename to configs/sdm670/sound_trigger_platform_info.xml
diff --git a/configs/msmpeafowl/mixer_paths_tavil.xml b/configs/sdm845/mixer_paths_qvr.xml
similarity index 87%
copy from configs/msmpeafowl/mixer_paths_tavil.xml
copy to configs/sdm845/mixer_paths_qvr.xml
index 03b10f1..43d8dd9 100644
--- a/configs/msmpeafowl/mixer_paths_tavil.xml
+++ b/configs/sdm845/mixer_paths_qvr.xml
@@ -22,6 +22,7 @@
 <!-- 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.                          -->
 <mixer>
@@ -72,6 +73,9 @@
     <ctl name="MultiMedia8 Mixer SLIM_0_TX" value="0" />
     <ctl name="MultiMedia8 Mixer SLIM_4_TX" value="0" />
     <ctl name="MultiMedia8 Mixer SLIM_7_TX" value="0" />
+    <ctl name="MultiMedia10 Mixer SLIM_0_TX" value="0" />
+    <ctl name="MultiMedia10 Mixer SLIM_7_TX" value="0" />
+    <ctl name="MultiMedia10 Mixer AFE_PCM_TX" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia1" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia3" value="0" />
@@ -88,9 +92,6 @@
     <ctl name="DISPLAY_PORT Mixer MultiMedia14" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia15" value="0" />
     <ctl name="DISPLAY_PORT Mixer MultiMedia16" value="0" />
-    <ctl name="Display Port RX Bit Format" value="S16_LE" />
-    <ctl name="Display Port RX SampleRate" value="KHZ_48" />
-    <ctl name="Display Port RX Channels" value="Two" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia1" value="0" />
     <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia1" value="0" />
     <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia2" value="0" />
@@ -153,15 +154,10 @@
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia14" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia15" value="0" />
     <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia16" value="0" />
-    <ctl name="USB_AUDIO_RX Format" value="S16_LE" />
-    <ctl name="USB_AUDIO_RX SampleRate" value="KHZ_48" />
-    <ctl name="USB_AUDIO_RX Channels" value="Two" />
     <ctl name="MultiMedia1 Mixer USB_AUDIO_TX" value="0" />
     <ctl name="MultiMedia5 Mixer USB_AUDIO_TX" value="0" />
     <ctl name="MultiMedia8 Mixer USB_AUDIO_TX" value="0" />
-    <ctl name="USB_AUDIO_TX Format" value="S16_LE" />
-    <ctl name="USB_AUDIO_TX SampleRate" value="KHZ_48" />
-    <ctl name="USB_AUDIO_TX Channels" value="One" />
+    <ctl name="MultiMedia10 Mixer USB_AUDIO_TX" value="0" />
     <ctl name="MultiMedia6 Mixer SLIM_0_TX" value="0" />
     <ctl name="SLIM_2_RX Format" value="UNPACKED" />
     <ctl name="SLIM_2_RX SampleRate" value="KHZ_48" />
@@ -191,9 +187,8 @@
     <ctl name="SLIM_4_TX Format" value="UNPACKED" />
     <ctl name="AANC_SLIM_0_RX MUX" value="ZERO" />
     <!-- HFP start -->
-    <ctl name="HFP_SLIM7_UL_HL Switch" value="0" />
+    <ctl name="HFP_PRI_AUX_UL_HL Switch" value="0" />
     <ctl name="SLIMBUS_0_RX Port Mixer SLIM_7_TX" value="0" />
-    <ctl name="SLIMBUS_6_RX Port Mixer SLIM_7_TX" value="0" />
     <!-- HFP end -->
     <!-- echo reference -->
     <ctl name="AUDIO_REF_EC_UL1 MUX" value="None" />
@@ -471,27 +466,27 @@
     <ctl name="ASRC1 Output Mode" value="INT" />
 
     <!-- IIR/voice anc -->
-    <ctl name="IIR0 Band1" id ="0" value="268435456" />
+    <ctl name="IIR0 Band1" id ="0" value="0" />
     <ctl name="IIR0 Band1" id ="1" value="0" />
     <ctl name="IIR0 Band1" id ="2" value="0" />
     <ctl name="IIR0 Band1" id ="3" value="0" />
     <ctl name="IIR0 Band1" id ="4" value="0" />
-    <ctl name="IIR0 Band2" id ="0" value="268435456" />
+    <ctl name="IIR0 Band2" id ="0" value="0" />
     <ctl name="IIR0 Band2" id ="1" value="0" />
     <ctl name="IIR0 Band2" id ="2" value="0" />
     <ctl name="IIR0 Band2" id ="3" value="0" />
     <ctl name="IIR0 Band2" id ="4" value="0" />
-    <ctl name="IIR0 Band3" id ="0" value="268435456" />
+    <ctl name="IIR0 Band3" id ="0" value="0" />
     <ctl name="IIR0 Band3" id ="1" value="0" />
     <ctl name="IIR0 Band3" id ="2" value="0" />
     <ctl name="IIR0 Band3" id ="3" value="0" />
-    <ctl name="IIR0 Band3" id ="4" value="268435456" />
+    <ctl name="IIR0 Band3" id ="4" value="0" />
     <ctl name="IIR0 Band4" id ="0" value="0" />
     <ctl name="IIR0 Band4" id ="1" value="0" />
     <ctl name="IIR0 Band4" id ="2" value="0" />
     <ctl name="IIR0 Band4" id ="3" value="0" />
     <ctl name="IIR0 Band4" id ="4" value="0" />
-    <ctl name="IIR0 Band5" id ="0" value="268435456" />
+    <ctl name="IIR0 Band5" id ="0" value="0" />
     <ctl name="IIR0 Band5" id ="1" value="0" />
     <ctl name="IIR0 Band5" id ="2" value="0" />
     <ctl name="IIR0 Band5" id ="3" value="0" />
@@ -522,7 +517,15 @@
 
     <!-- Codec controls end -->
 
+    <!-- mixer control to disable lowlatency qos voting -->
+    <ctl name="MultiMedia5_RX QOS Vote" value="Disable" />
+    <!-- mixer control to disable lowlatency qos voting end -->
+
     <!-- These are audio route (FE to BE) specific mixer settings -->
+    <path name="gsm-mode">
+        <ctl name="GSM mode Enable" value="ON" />
+    </path>
+
     <path name="echo-reference">
         <ctl name="AUDIO_REF_EC_UL1 MUX" value="SLIM_RX" />
     </path>
@@ -586,6 +589,16 @@
         <path name="deep-buffer-playback" />
     </path>
 
+    <path name="deep-buffer-playback speaker-and-bt-sco">
+        <path name="deep-buffer-playback bt-sco" />
+        <path name="deep-buffer-playback" />
+    </path>
+
+    <path name="deep-buffer-playback speaker-and-bt-sco-wb">
+        <path name="deep-buffer-playback bt-sco-wb" />
+        <path name="deep-buffer-playback" />
+    </path>
+
     <path name="low-latency-playback">
         <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia5" value="1" />
     </path>
@@ -638,6 +651,20 @@
         <path name="low-latency-playback" />
     </path>
 
+    <path name="low-latency-playback resume">
+        <ctl name="MultiMedia5_RX QOS Vote" value="Enable" />
+    </path>
+
+    <path name="low-latency-playback speaker-and-bt-sco">
+        <path name="low-latency-playback bt-sco" />
+        <path name="low-latency-playback" />
+    </path>
+
+    <path name="low-latency-playback speaker-and-bt-sco-wb">
+        <path name="low-latency-playback bt-sco-wb" />
+        <path name="low-latency-playback" />
+    </path>
+
     <path name="audio-ull-playback">
         <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia8" value="1" />
     </path>
@@ -685,6 +712,16 @@
         <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia8" value="1" />
     </path>
 
+    <path name="audio-ull-playback speaker-and-bt-sco">
+        <path name="audio-ull-playback bt-sco" />
+        <path name="audio-ull-playback" />
+    </path>
+
+    <path name="audio-ull-playback speaker-and-bt-sco-wb">
+        <path name="audio-ull-playback bt-sco-wb" />
+        <path name="audio-ull-playback" />
+    </path>
+
     <path name="multi-channel-playback display-port">
         <ctl name="DISPLAY_PORT Mixer MultiMedia2" value="1" />
     </path>
@@ -757,6 +794,16 @@
         <path name="compress-offload-playback" />
     </path>
 
+    <path name="compress-offload-playback speaker-and-bt-sco">
+        <path name="compress-offload-playback bt-sco" />
+        <path name="compress-offload-playback" />
+    </path>
+
+    <path name="compress-offload-playback speaker-and-bt-sco-wb">
+        <path name="compress-offload-playback bt-sco-wb" />
+        <path name="compress-offload-playback" />
+    </path>
+
     <path name="compress-offload-playback2">
         <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia7" value="1" />
     </path>
@@ -813,6 +860,16 @@
         <path name="compress-offload-playback2" />
     </path>
 
+    <path name="compress-offload-playback2 speaker-and-bt-sco">
+        <path name="compress-offload-playback2 bt-sco" />
+        <path name="compress-offload-playback2" />
+    </path>
+
+    <path name="compress-offload-playback2 speaker-and-bt-sco-wb">
+        <path name="compress-offload-playback2 bt-sco-wb" />
+        <path name="compress-offload-playback2" />
+    </path>
+
     <path name="compress-offload-playback3">
         <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia10" value="1" />
     </path>
@@ -869,6 +926,16 @@
         <path name="compress-offload-playback3" />
     </path>
 
+    <path name="compress-offload-playback3 speaker-and-bt-sco">
+        <path name="compress-offload-playback3 bt-sco" />
+        <path name="compress-offload-playback3" />
+    </path>
+
+    <path name="compress-offload-playback3 speaker-and-bt-sco-wb">
+        <path name="compress-offload-playback3 bt-sco-wb" />
+        <path name="compress-offload-playback3" />
+    </path>
+
     <path name="compress-offload-playback4">
         <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia11" value="1" />
     </path>
@@ -926,6 +993,16 @@
         <path name="compress-offload-playback4" />
     </path>
 
+    <path name="compress-offload-playback4 speaker-and-bt-sco">
+        <path name="compress-offload-playback4 bt-sco" />
+        <path name="compress-offload-playback4" />
+    </path>
+
+    <path name="compress-offload-playback4 speaker-and-bt-sco-wb">
+        <path name="compress-offload-playback4 bt-sco-wb" />
+        <path name="compress-offload-playback4" />
+    </path>
+
     <path name="compress-offload-playback5">
         <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia12" value="1" />
     </path>
@@ -982,6 +1059,16 @@
         <path name="compress-offload-playback5" />
     </path>
 
+    <path name="compress-offload-playback5 speaker-and-bt-sco">
+        <path name="compress-offload-playback5 bt-sco" />
+        <path name="compress-offload-playback5" />
+    </path>
+
+    <path name="compress-offload-playback5 speaker-and-bt-sco-wb">
+        <path name="compress-offload-playback5 bt-sco-wb" />
+        <path name="compress-offload-playback5" />
+    </path>
+
     <path name="compress-offload-playback6">
         <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia13" value="1" />
     </path>
@@ -1038,6 +1125,16 @@
         <path name="compress-offload-playback6" />
     </path>
 
+    <path name="compress-offload-playback6 speaker-and-bt-sco">
+        <path name="compress-offload-playback6 bt-sco" />
+        <path name="compress-offload-playback6" />
+    </path>
+
+    <path name="compress-offload-playback6 speaker-and-bt-sco-wb">
+        <path name="compress-offload-playback6 bt-sco-wb" />
+        <path name="compress-offload-playback6" />
+    </path>
+
     <path name="compress-offload-playback7">
         <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia14" value="1" />
     </path>
@@ -1094,6 +1191,16 @@
         <path name="compress-offload-playback7" />
     </path>
 
+    <path name="compress-offload-playback7 speaker-and-bt-sco">
+        <path name="compress-offload-playback7 bt-sco" />
+        <path name="compress-offload-playback7" />
+    </path>
+
+    <path name="compress-offload-playback7 speaker-and-bt-sco-wb">
+        <path name="compress-offload-playback7 bt-sco-wb" />
+        <path name="compress-offload-playback7" />
+    </path>
+
     <path name="compress-offload-playback8">
         <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia15" value="1" />
     </path>
@@ -1150,6 +1257,16 @@
         <path name="compress-offload-playback8" />
     </path>
 
+    <path name="compress-offload-playback8 speaker-and-bt-sco">
+        <path name="compress-offload-playback8 bt-sco" />
+        <path name="compress-offload-playback8" />
+    </path>
+
+    <path name="compress-offload-playback8 speaker-and-bt-sco-wb">
+        <path name="compress-offload-playback8 bt-sco-wb" />
+        <path name="compress-offload-playback8" />
+    </path>
+
     <path name="compress-offload-playback9">
         <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia16" value="1" />
     </path>
@@ -1206,6 +1323,16 @@
         <path name="compress-offload-playback9" />
     </path>
 
+    <path name="compress-offload-playback9 speaker-and-bt-sco">
+        <path name="compress-offload-playback9 bt-sco" />
+        <path name="compress-offload-playback9" />
+    </path>
+
+    <path name="compress-offload-playback9 speaker-and-bt-sco-wb">
+        <path name="compress-offload-playback9 bt-sco-wb" />
+        <path name="compress-offload-playback9" />
+    </path>
+
     <path name="audio-record">
         <ctl name="MultiMedia1 Mixer SLIM_0_TX" value="1" />
     </path>
@@ -1404,28 +1531,16 @@
     </path>
 
     <path name="hfp-sco">
-        <ctl name="HFP_SLIM7_UL_HL Switch" value="1" />
-        <ctl name="SLIMBUS_0_RX Port Mixer SLIM_7_TX" value="1" />
-        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia6" value="1" />
-        <ctl name="MultiMedia6 Mixer SLIM_0_TX" value="1" />
-        <ctl name="SLIMBUS_DL_HL Switch" value="1" />
     </path>
 
     <path name="hfp-sco headphones">
-        <ctl name="HFP_SLIM7_UL_HL Switch" value="1" />
-        <ctl name="SLIMBUS_6_RX Port Mixer SLIM_7_TX" value="1" />
-        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia6" value="1" />
-        <ctl name="MultiMedia6 Mixer SLIM_0_TX" value="1" />
-        <ctl name="SLIMBUS6_DL_HL Switch" value="1" />
     </path>
 
    <path name="hfp-sco-wb">
-        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="hfp-sco" />
    </path>
 
     <path name="hfp-sco-wb headphones">
-        <ctl name="BT SampleRate" value="KHZ_16" />
         <path name="hfp-sco headphones" />
     </path>
 
@@ -1434,16 +1549,12 @@
         <ctl name="Voip_Tx Mixer SLIM_0_TX_Voip" value="1" />
     </path>
 
-    <path name="compress-voip-call bt-a2dp">
-        <ctl name="SLIM_7_RX_Voice Mixer Voip" value="1" />
-        <ctl name="Voip_Tx Mixer SLIM_0_TX_Voip" value="1" />
-    </path>
-
     <path name="compress-voip-call headphones">
         <ctl name="SLIM_6_RX_Voice Mixer Voip" value="1" />
         <ctl name="Voip_Tx Mixer SLIM_0_TX_Voip" value="1" />
     </path>
 
+
     <path name="compress-voip-call bt-sco">
         <ctl name="SLIM_7_RX_Voice Mixer Voip" value="1" />
         <ctl name="Voip_Tx Mixer SLIM_7_TX_Voip" value="1" />
@@ -1539,6 +1650,62 @@
         <ctl name="VoiceMMode2_Tx Mixer USB_AUDIO_TX_MMode2" value="1" />
     </path>
 
+    <!-- VoIP Rx settings -->
+    <path name="audio-playback-voip">
+        <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia10" value="1" />
+    </path>
+
+    <path name="audio-playback-voip headphones">
+        <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia10" value="1" />
+    </path>
+
+    <path name="audio-playback-voip bt-sco">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia10" value="1" />
+    </path>
+
+    <path name="audio-playback-voip bt-sco-wb">
+        <ctl name="BT SampleRate" value="KHZ_16" />
+        <path name="audio-playback-voip bt-sco" />
+    </path>
+
+    <path name="audio-playback-voip afe-proxy">
+        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="1" />
+    </path>
+
+    <path name="audio-playback-voip usb-headphones">
+        <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia10" value="1" />
+    </path>
+
+    <path name="audio-playback-voip usb-headset">
+        <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia10" value="1" />
+    </path>
+
+    <path name="audio-playback-voip display-port">
+        <ctl name="DISPLAY_PORT Mixer MultiMedia10" value="1" />
+    </path>
+
+    <path name="audio-playback-voip speaker-and-display-port">
+        <path name="audio-playback-voip display-port" />
+        <path name="audio-playback-voip" />
+    </path>
+
+    <!-- VoIP Tx settings -->
+    <path name="audio-record-voip">
+        <ctl name="MultiMedia10 Mixer SLIM_0_TX" value="1" />
+    </path>
+
+    <path name="audio-record-voip usb-headset-mic">
+        <ctl name="MultiMedia10 Mixer USB_AUDIO_TX" value="1" />
+    </path>
+
+    <path name="audio-record-voip bt-sco">
+        <ctl name="MultiMedia10 Mixer SLIM_7_TX" value="1" />
+    </path>
+
+    <path name="audio-record-voip bt-sco-wb">
+        <ctl name="BT SampleRate" value="KHZ_16" />
+        <path name="audio-record-voip bt-sco" />
+    </path>
    <path name="spkr-rx-calib">
         <ctl name="SLIMBUS_DL_HL Switch"  value="1" />
     </path>
@@ -1677,6 +1844,31 @@
     </path>
 
    <path name="sidetone-iir">
+        <ctl name="IIR0 Band1" id ="0" value="268435456" />
+        <ctl name="IIR0 Band1" id ="1" value="0" />
+        <ctl name="IIR0 Band1" id ="2" value="0" />
+        <ctl name="IIR0 Band1" id ="3" value="0" />
+        <ctl name="IIR0 Band1" id ="4" value="0" />
+        <ctl name="IIR0 Band2" id ="0" value="268435456" />
+        <ctl name="IIR0 Band2" id ="1" value="0" />
+        <ctl name="IIR0 Band2" id ="2" value="0" />
+        <ctl name="IIR0 Band2" id ="3" value="0" />
+        <ctl name="IIR0 Band2" id ="4" value="0" />
+        <ctl name="IIR0 Band3" id ="0" value="268435456" />
+        <ctl name="IIR0 Band3" id ="1" value="0" />
+        <ctl name="IIR0 Band3" id ="2" value="0" />
+        <ctl name="IIR0 Band3" id ="3" value="0" />
+        <ctl name="IIR0 Band3" id ="4" value="0" />
+        <ctl name="IIR0 Band4" id ="0" value="268435456" />
+        <ctl name="IIR0 Band4" id ="1" value="0" />
+        <ctl name="IIR0 Band4" id ="2" value="0" />
+        <ctl name="IIR0 Band4" id ="3" value="0" />
+        <ctl name="IIR0 Band4" id ="4" value="0" />
+        <ctl name="IIR0 Band5" id ="0" value="268435456" />
+        <ctl name="IIR0 Band5" id ="1" value="0" />
+        <ctl name="IIR0 Band5" id ="2" value="0" />
+        <ctl name="IIR0 Band5" id ="3" value="0" />
+        <ctl name="IIR0 Band5" id ="4" value="0" />
         <ctl name="IIR0 Enable Band1" value="1" />
         <ctl name="IIR0 Enable Band2" value="1" />
         <ctl name="IIR0 Enable Band3" value="1" />
@@ -1694,7 +1886,7 @@
     <path name="sidetone-handset">
         <path name="sidetone-iir" />
         <ctl name="IIR0 INP0 Volume" value="54" />
-        <ctl name="RX INT7 MIX2 INP" value="SRC0" />
+        <ctl name="RX INT0 MIX2 INP" value="SRC0" />
     </path>
 
     <path name="afe-sidetone">
@@ -1751,16 +1943,20 @@
         <ctl name="SLIM RX0 MUX" value="AIF1_PB" />
         <ctl name="CDC_IF RX0 MUX" value="SLIM RX0" />
         <ctl name="SLIM_0_RX Channels" value="One" />
-        <ctl name="RX INT7_1 MIX1 INP0" value="RX0" />
-        <ctl name="COMP7 Switch" value="1" />
-        <ctl name="SpkrLeft COMP Switch" value="1" />
-        <ctl name="SpkrLeft BOOST Switch" value="1" />
-        <ctl name="SpkrLeft SWR DAC_Port Switch" value="1" />
-        <ctl name="EAR SPKR PA Gain" value="G_6_DB" />
+        <ctl name="RX INT0_1 MIX1 INP0" value="RX0" />
+        <ctl name="EAR PA Gain" value="G_6_DB" />
+    </path>
+
+    <path name="handset-qrd">
+        <ctl name="SLIM RX0 MUX" value="AIF1_PB" />
+        <ctl name="CDC_IF RX0 MUX" value="SLIM RX0" />
+        <ctl name="SLIM_0_RX Channels" value="One" />
+        <ctl name="RX INT0_1 MIX1 INP0" value="RX0" />
+        <ctl name="EAR PA Gain" value="G_6_DB" />
     </path>
 
     <path name="handset-mic">
-        <path name="dmic3" />
+        <path name="dmic4" />
     </path>
 
     <path name="handset-mic-db">
@@ -1874,10 +2070,22 @@
         <path name="handset" />
     </path>
 
+    <path name="voice-handset-qrd">
+        <path name="handset-qrd" />
+    </path>
+
+    <path name="voice-handset-tmus-qrd">
+        <path name="handset-qrd" />
+    </path>
+
     <path name="voice-speaker">
         <path name="speaker-mono" />
     </path>
 
+    <path name="voice-speaker-qrd">
+        <path name="speaker-mono-2" />
+    </path>
+
     <path name="voice-speaker-2">
         <path name="speaker-mono-2" />
     </path>
@@ -1947,8 +2155,8 @@
         <ctl name="ADC4 Volume" value="8" />
         <ctl name="RX INT1_1 MIX1 INP0" value="RX2" />
         <ctl name="RX INT2_1 MIX1 INP0" value="RX3" />
-        <ctl name="RX1 Digital Volume" value="84" />
-        <ctl name="RX2 Digital Volume" value="84" />
+        <ctl name="RX1 Digital Volume" value="81" />
+        <ctl name="RX2 Digital Volume" value="81" />
         <ctl name="ANC OUT HPHL Enable Switch" value="1" />
         <ctl name="ANC OUT HPHR Enable Switch" value="1" />
     </path>
@@ -2042,9 +2250,6 @@
         <ctl name="DMIC MUX7" value="DMIC0" />
         <ctl name="IIR0 INP0 MUX" value="DEC6" />
     </path>
-    <path name="aanc-fluence-dmic-handset">
-        <path name="aanc-handset-mic" />
-    </path>
 
     <!-- Dual MIC devices -->
     <path name="handset-dmic-endfire">
@@ -2052,10 +2257,10 @@
         <ctl name="AIF1_CAP Mixer SLIM TX8" value="1" />
         <ctl name="CDC_IF TX7 MUX" value="DEC7" />
         <ctl name="ADC MUX7" value="DMIC" />
-        <ctl name="DMIC MUX7" value="DMIC2" />
+        <ctl name="DMIC MUX7" value="DMIC1" />
         <ctl name="CDC_IF TX8 MUX" value="DEC8" />
         <ctl name="ADC MUX8" value="DMIC" />
-        <ctl name="DMIC MUX8" value="DMIC4" />
+        <ctl name="DMIC MUX8" value="DMIC3" />
         <ctl name="SLIM_0_TX Channels" value="Two" />
     </path>
 
@@ -2067,7 +2272,7 @@
         <ctl name="DMIC MUX7" value="DMIC1" />
         <ctl name="CDC_IF TX8 MUX" value="DEC8" />
         <ctl name="ADC MUX8" value="DMIC" />
-        <ctl name="DMIC MUX8" value="DMIC5" />
+        <ctl name="DMIC MUX8" value="DMIC3" />
         <ctl name="SLIM_0_TX Channels" value="Two" />
     </path>
 
@@ -2217,6 +2422,11 @@
         <path name="handset" />
     </path>
 
+    <path name="voice-tty-hco-handset-qrd">
+        <ctl name="TTY Mode" value="HCO" />
+        <path name="handset-qrd" />
+    </path>
+
     <path name="voice-tty-full-headset-mic">
         <path name="amic2" />
         <ctl name="ADC2 Volume" value="0" />
@@ -2386,4 +2596,82 @@
         <path name="audio-ull-playback bt-a2dp" />
         <path name="audio-ull-playback" />
     </path>
+
+    <path name="mmap-playback">
+        <ctl name="SLIMBUS_0_RX Audio Mixer MultiMedia16" value="1" />
+    </path>
+
+    <path name="mmap-playback headphones">
+        <ctl name="SLIMBUS_6_RX Audio Mixer MultiMedia16" value="1" />
+    </path>
+
+    <path name="mmap-playback speaker-and-headphones">
+        <path name="mmap-playback" />
+        <path name="mmap-playback headphones" />
+    </path>
+
+    <path name="mmap-playback bt-sco">
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia16" value="1" />
+    </path>
+
+    <path name="mmap-playback bt-sco-wb">
+        <ctl name="BT SampleRate" value="16000" />
+        <path name="mmap-playback bt-sco" />
+    </path>
+
+    <path name="mmap-playback afe-proxy">
+        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia16" value="1" />
+    </path>
+
+    <path name="mmap-playback usb-headphones">
+        <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia16" value="1" />
+    </path>
+
+    <path name="mmap-playback usb-headset">
+        <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia16" value="1" />
+    </path>
+
+    <path name="mmap-playback display-port">
+        <ctl name="DISPLAY_PORT Mixer MultiMedia16" value="1" />
+    </path>
+
+    <path name="mmap-buffer-playback hdmi">
+        <ctl name="HDMI Mixer MultiMedia16" value="1" />
+    </path>
+
+    <path name="mmap-playback speaker-and-hdmi">
+        <path name="mmap-playback hdmi" />
+        <path name="mmap-playback" />
+    </path>
+
+    <path name="mmap-playback speaker-and-display-port">
+        <path name="mmap-playback display-port" />
+        <path name="mmap-playback" />
+    </path>
+
+    <path name="mmap-playback speaker-and-usb-headphones">
+        <path name="mmap-playback usb-headphones" />
+        <path name="mmap-playback" />
+    </path>
+
+    <path name="mmap-record">
+      <ctl name="MultiMedia16 Mixer SLIM_0_TX" value="1" />
+    </path>
+
+    <path name="mmap-record bt-sco">
+      <ctl name="MultiMedia16 Mixer SLIM_7_TX" value="1" />
+    </path>
+
+    <path name="mmap-record bt-sco-wb">
+        <ctl name="BT SampleRate" value="KHZ_16" />
+        <path name="mmap-record bt-sco" />
+    </path>
+
+    <path name="mmap-record capture-fm">
+      <ctl name="MultiMedia16 Mixer SLIM_8_TX" value="1" />
+    </path>
+
+    <path name="mmap-record usb-headset-mic">
+       <ctl name="MultiMedia16 Mixer USB_AUDIO_TX" value="1" />
+    </path>
 </mixer>
diff --git a/configs/sdm845/mixer_paths_tavil.xml b/configs/sdm845/mixer_paths_tavil.xml
index db65411..0c7cc96 100644
--- a/configs/sdm845/mixer_paths_tavil.xml
+++ b/configs/sdm845/mixer_paths_tavil.xml
@@ -1664,7 +1664,7 @@
     </path>
 
     <path name="audio-playback-voip bt-sco">
-        <ctl name="SLIMBUS_7_RX Mixer MultiMedia10" value="1" />
+        <ctl name="SLIMBUS_7_RX Audio Mixer MultiMedia10" value="1" />
     </path>
 
     <path name="audio-playback-voip bt-sco-wb">
@@ -1673,15 +1673,15 @@
     </path>
 
     <path name="audio-playback-voip afe-proxy">
-        <ctl name="AFE_PCM_RX Mixer MultiMedia10" value="1" />
+        <ctl name="AFE_PCM_RX Audio Mixer MultiMedia10" value="1" />
     </path>
 
     <path name="audio-playback-voip usb-headphones">
-        <ctl name="USB_AUDIO_RX Mixer MultiMedia10" value="1" />
+        <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia10" value="1" />
     </path>
 
     <path name="audio-playback-voip usb-headset">
-        <ctl name="USB_AUDIO_RX Mixer MultiMedia10" value="1" />
+        <ctl name="USB_AUDIO_RX Audio Mixer MultiMedia10" value="1" />
     </path>
 
     <path name="audio-playback-voip display-port">
diff --git a/configs/sdm845/sdm845.mk b/configs/sdm845/sdm845.mk
index 92c22de..7d3a51f 100644
--- a/configs/sdm845/sdm845.mk
+++ b/configs/sdm845/sdm845.mk
@@ -79,6 +79,7 @@
     hardware/qcom/audio/configs/sdm845/audio_effects.conf:$(TARGET_COPY_OUT_VENDOR)/etc/audio_effects.conf \
     hardware/qcom/audio/configs/sdm845/mixer_paths_tavil.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_tavil.xml \
     hardware/qcom/audio/configs/sdm845/mixer_paths_skuk.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_skuk.xml \
+    hardware/qcom/audio/configs/sdm845/mixer_paths_qvr.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_qvr.xml \
     hardware/qcom/audio/configs/sdm845/mixer_paths_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/mixer_paths_i2s.xml \
     hardware/qcom/audio/configs/sdm845/audio_tuning_mixer_tavil.txt:$(TARGET_COPY_OUT_VENDOR)/etc/audio_tuning_mixer_tavil.txt \
     hardware/qcom/audio/configs/sdm845/audio_platform_info_i2s.xml:$(TARGET_COPY_OUT_VENDOR)/etc/audio_platform_info_i2s.xml \
diff --git a/configure.ac b/configure.ac
index 978d235..9a17458 100644
--- a/configure.ac
+++ b/configure.ac
@@ -115,6 +115,7 @@
 AM_CONDITIONAL([AUDIO_PARSER], [test x$AUDIO_FEATURE_ENABLED_PARSER = xtrue])
 AM_CONDITIONAL([DTSHD_PARSER], [test x$AUDIO_FEATURE_ENABLED_DTSHD_PARSER = xtrue])
 AM_CONDITIONAL([QAP], [test x$AUDIO_FEATURE_ENABLED_QAP = xtrue])
+AM_CONDITIONAL([AUDIO_HW_FFV], [test x$AUDIO_FEATURE_ENABLED_FFV = xtrue])
 
 AC_CONFIG_FILES([ \
         Makefile \
diff --git a/hal/Android.mk b/hal/Android.mk
index db65517..d2ef726 100644
--- a/hal/Android.mk
+++ b/hal/Android.mk
@@ -8,7 +8,7 @@
 
 AUDIO_PLATFORM := $(TARGET_BOARD_PLATFORM)
 
-ifneq ($(filter msm8974 msm8226 msm8610 apq8084 msm8994 msm8992 msm8996 msm8998 apq8098_latv sdm845 msmpeafowl,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8974 msm8226 msm8610 apq8084 msm8994 msm8992 msm8996 msm8998 apq8098_latv sdm845 sdm670,$(TARGET_BOARD_PLATFORM)),)
   # B-family platform uses msm8974 code base
   AUDIO_PLATFORM = msm8974
   MULTIPLE_HW_VARIANTS_ENABLED := true
@@ -36,7 +36,7 @@
 ifneq ($(filter sdm845,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_SDM845
 endif
-ifneq ($(filter msmpeafowl,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter sdm670,$(TARGET_BOARD_PLATFORM)),)
   LOCAL_CFLAGS := -DPLATFORM_SDM670
 endif
 endif
diff --git a/hal/Makefile.am b/hal/Makefile.am
index 1d60f2d..0096bf7 100644
--- a/hal/Makefile.am
+++ b/hal/Makefile.am
@@ -189,6 +189,12 @@
 c_sources += audio_extn/hw_loopback.c
 endif
 
+if AUDIO_HW_FFV
+AM_CFLAGS += -DFFV_ENABLED \
+             -I $(PKG_CONFIG_SYSROOT_DIR)/usr/include/ffv/
+c_sources += audio_extn/ffv.c
+endif
+
 h_sources = audio_extn/audio_defs.h \
             audio_extn/audio_extn.h \
             audio_hw.h \
diff --git a/hal/audio_extn/a2dp.c b/hal/audio_extn/a2dp.c
index 9ebc0f2..4393418 100644
--- a/hal/audio_extn/a2dp.c
+++ b/hal/audio_extn/a2dp.c
@@ -221,7 +221,13 @@
     struct custom_enc_cfg_t  custom_cfg;
     struct celt_specific_enc_cfg_t celt_cfg;
 };
-
+/* In LE BT source code uses system/audio.h for below
+ * structure definition. To avoid multiple definition
+ * compilation error for audiohal in LE , masking structure
+ * definition under "LINUX_ENABLED" which is defined only
+ * in LE
+ */
+#ifndef LINUX_ENABLED
 /* TODO: Define the following structures only for O using PLATFORM_VERSION */
 /* Information about BT SBC encoder configuration
  * This data is used between audio HAL module and
@@ -238,7 +244,6 @@
     uint32_t bitrate;        /* 320kbps to 512kbps */
 } audio_sbc_encoder_config;
 
-
 /* Information about BT APTX encoder configuration
  * This data is used between audio HAL module and
  * BT IPC library to configure DSP encoder
@@ -261,6 +266,7 @@
     uint32_t sampling_rate;
     uint32_t bitrate;
 } audio_aac_encoder_config;
+#endif
 
 /* Information about BT CELT encoder configuration
  * This data is used between audio HAL module and
diff --git a/hal/audio_extn/audio_extn.c b/hal/audio_extn/audio_extn.c
index 84de66f..c1c4460 100644
--- a/hal/audio_extn/audio_extn.c
+++ b/hal/audio_extn/audio_extn.c
@@ -838,6 +838,7 @@
    if (adev->offload_effects_set_parameters != NULL)
        adev->offload_effects_set_parameters(parms);
    audio_extn_set_aptx_dec_bt_addr(adev, parms);
+   audio_extn_ffv_set_parameters(adev, parms);
 }
 
 void audio_extn_get_parameters(const struct audio_device *adev,
@@ -1254,6 +1255,8 @@
     ssr_supported = audio_extn_ssr_check_usecase(in);
     if (ssr_supported) {
         return audio_extn_ssr_set_usecase(in, config, update_params);
+    } else if (audio_extn_ffv_check_usecase(in)) {
+        return audio_extn_ffv_set_usecase(in);
     } else {
         return audio_extn_set_multichannel_mask(adev, in, config,
                                                 update_params);
@@ -1436,11 +1439,11 @@
     int ret = -EINVAL;
     struct stream_out out;
     uint32_t snd_device = 0, backend_idx = 0;
-    struct audio_device_config_param *adev_device_cfg_ptr = adev->device_cfg_params;
+    struct audio_device_config_param *adev_device_cfg_ptr;
 
     ALOGV("%s", __func__);
 
-    if (!device_cfg_params || !adev) {
+    if (!device_cfg_params || !adev || !adev->device_cfg_params) {
         ALOGE("%s:: Invalid Param", __func__);
         return ret;
     }
@@ -1451,6 +1454,7 @@
         return ret;
     }
 
+    adev_device_cfg_ptr = adev->device_cfg_params;
     /* Create an out stream to get snd device from audio device */
     out.devices = device_cfg_params->device;
     out.sample_rate = device_cfg_params->sample_rate;
diff --git a/hal/audio_extn/audio_extn.h b/hal/audio_extn/audio_extn.h
index c30f982..c62226a 100644
--- a/hal/audio_extn/audio_extn.h
+++ b/hal/audio_extn/audio_extn.h
@@ -465,12 +465,10 @@
 
 
 #if defined(DS1_DOLBY_DDP_ENABLED) || defined(DS2_DOLBY_DAP_ENABLED)
-bool audio_extn_is_dolby_format(audio_format_t format);
 int audio_extn_dolby_get_snd_codec_id(struct audio_device *adev,
                                       struct stream_out *out,
                                       audio_format_t format);
 #else
-#define audio_extn_is_dolby_format(format)              (0)
 #define audio_extn_dolby_get_snd_codec_id(adev, out, format)       (0)
 #endif
 
@@ -518,6 +516,7 @@
 #define audio_extn_passthru_get_channel_count(out) (0)
 #define audio_extn_passthru_update_dts_stream_configuration(out, buffer, bytes) (-ENOSYS)
 #define audio_extn_passthru_is_direct_passthrough(out)	(0)
+#define audio_extn_passthru_is_supported_backend_edid_cfg(adev, out) (0)
 #else
 bool audio_extn_passthru_is_convert_supported(struct audio_device *adev,
                                                  struct stream_out *out);
@@ -545,6 +544,8 @@
 int audio_extn_passthru_update_dts_stream_configuration(struct stream_out *out,
         const void *buffer, size_t bytes);
 bool audio_extn_passthru_is_direct_passthrough(struct stream_out *out);
+bool audio_extn_passthru_is_supported_backend_edid_cfg(struct audio_device *adev,
+                                                   struct stream_out *out);
 #endif
 
 #ifndef HFP_ENABLED
@@ -621,6 +622,7 @@
                                   struct audio_usecase *usecase);
 int audio_extn_utils_get_snd_card_num();
 bool audio_extn_is_dsp_bit_width_enforce_mode_supported(audio_output_flags_t flags);
+bool audio_extn_utils_is_dolby_format(audio_format_t format);
 
 #ifdef DS2_DOLBY_DAP_ENABLED
 #define LIB_DS2_DAP_HAL "vendor/lib/libhwdaphal.so"
@@ -971,4 +973,46 @@
 {
 }
 #endif
+
+#ifndef FFV_ENABLED
+#define audio_extn_ffv_init(adev) (0)
+#define audio_extn_ffv_deinit() (0)
+#define audio_extn_ffv_check_usecase(in) (0)
+#define audio_extn_ffv_set_usecase(in) (0)
+#define audio_extn_ffv_stream_init(in) (0)
+#define audio_extn_ffv_stream_deinit() (0)
+#define audio_extn_ffv_update_enabled() (0)
+#define audio_extn_ffv_get_enabled() (0)
+#define audio_extn_ffv_read(stream, buffer, bytes) (0)
+#define audio_extn_ffv_set_parameters(adev, parms) (0)
+#define audio_extn_ffv_get_stream() (0)
+#define audio_extn_ffv_update_pcm_config(config) (0)
+#define audio_extn_ffv_init_ec_ref_loopback(adev, snd_device) (0)
+#define audio_extn_ffv_deinit_ec_ref_loopback(adev, snd_device) (0)
+#define audio_extn_ffv_check_and_append_ec_ref_dev(device_name) (0)
+#define audio_extn_ffv_get_capture_snd_device() (0)
+#define audio_extn_ffv_append_ec_ref_dev_name(device_name) (0)
+#else
+int32_t audio_extn_ffv_init(struct audio_device *adev);
+int32_t audio_extn_ffv_deinit();
+bool audio_extn_ffv_check_usecase(struct stream_in *in);
+int audio_extn_ffv_set_usecase(struct stream_in *in);
+int32_t audio_extn_ffv_stream_init(struct stream_in *in);
+int32_t audio_extn_ffv_stream_deinit();
+void audio_extn_ffv_update_enabled();
+bool audio_extn_ffv_get_enabled();
+int32_t audio_extn_ffv_read(struct audio_stream_in *stream,
+                       void *buffer, size_t bytes);
+void audio_extn_ffv_set_parameters(struct audio_device *adev,
+                                   struct str_parms *parms);
+struct stream_in *audio_extn_ffv_get_stream();
+void audio_extn_ffv_update_pcm_config(struct pcm_config *config);
+int audio_extn_ffv_init_ec_ref_loopback(struct audio_device *adev,
+                                        snd_device_t snd_device);
+int audio_extn_ffv_deinit_ec_ref_loopback(struct audio_device *adev,
+                                          snd_device_t snd_device);
+void audio_extn_ffv_check_and_append_ec_ref_dev(char *device_name);
+snd_device_t audio_extn_ffv_get_capture_snd_device();
+void audio_extn_ffv_append_ec_ref_dev_name(char *device_name);
+#endif
 #endif /* AUDIO_EXTN_H */
diff --git a/hal/audio_extn/dolby.c b/hal/audio_extn/dolby.c
index bc7aa5c..fda9a1a 100644
--- a/hal/audio_extn/dolby.c
+++ b/hal/audio_extn/dolby.c
@@ -362,19 +362,6 @@
 }
 #endif /* DS1_DOLBY_DDP_ENABLED */
 
-#if defined(DS1_DOLBY_DDP_ENABLED) || defined(DS2_DOLBY_DAP_ENABLED)
-bool audio_extn_is_dolby_format(audio_format_t format)
-{
-    if (format == AUDIO_FORMAT_AC3 ||
-            format == AUDIO_FORMAT_E_AC3 ||
-            format == AUDIO_FORMAT_E_AC3_JOC)
-        return true;
-    else
-        return false;
-}
-#endif /* DS1_DOLBY_DDP_ENABLED || DS2_DOLBY_DAP_ENABLED */
-
-
 #ifdef DS1_DOLBY_DAP_ENABLED
 void audio_extn_dolby_set_endpoint(struct audio_device *adev)
 {
diff --git a/hal/audio_extn/ffv.c b/hal/audio_extn/ffv.c
new file mode 100644
index 0000000..cb4978f
--- /dev/null
+++ b/hal/audio_extn/ffv.c
@@ -0,0 +1,896 @@
+/*
+ * Copyright (c) 2017, The Linux Foundation. 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.
+ *   * Neither the name of The Linux Foundation nor the names of its
+ *     contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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.
+ */
+
+#define LOG_TAG "audio_hw_ffv"
+/*#define LOG_NDEBUG 0*/
+#define LOG_NDDEBUG 0
+/*#define VERY_VERY_VERBOSE_LOGGING*/
+#ifdef VERY_VERY_VERBOSE_LOGGING
+#define ALOGVV ALOGV
+#else
+#define ALOGVV(a...) do { } while(0)
+#endif
+
+#include <errno.h>
+#include <cutils/properties.h>
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <cutils/str_parms.h>
+#include <cutils/log.h>
+#include <pthread.h>
+#include <sys/resource.h>
+
+#include "audio_hw.h"
+#include "platform.h"
+#include "platform_api.h"
+
+#include "ffv_interface.h"
+
+#define AUDIO_PARAMETER_FFV_MODE_ON "ffvOn"
+#define AUDIO_PARAMETER_FFV_SPLIT_EC_REF_DATA "ffv_split_ec_ref_data"
+#define AUDIO_PARAMETER_FFV_EC_REF_CHANNEL_COUNT "ffv_ec_ref_channel_count"
+#define AUDIO_PARAMETER_FFV_EC_REF_DEVICE "ffv_ec_ref_dev"
+#define AUDIO_PARAMETER_FFV_CHANNEL_INDEX "ffv_channel_index"
+
+#define FFV_LIB "libffv.so"
+#define FFV_CONFIG_FILE_PATH "/etc/BF_1out.cfg"
+#define FFV_SAMPLING_RATE_16000 16000
+#define FFV_EC_REF_LOOPBACK_DEVICE_MONO "ec-ref-loopback-mono"
+#define FFV_EC_REF_LOOPBACK_DEVICE_STEREO "ec-ref-loopback-stereo"
+
+#define FFV_CHANNEL_MODE_MONO 1
+#define FFV_CHANNEL_MODE_STEREO 2
+#define FFV_CHANNEL_MODE_HEX 6
+#define FFV_CHANNEL_MODE_OCT 8
+
+#define FFV_PCM_BUFFER_DURATION_MS 160
+#define FFV_PCM_PERIOD_COUNT (8)
+#define FFV_PCM_PERIOD_SIZE \
+    ((((FFV_SAMPLING_RATE_16000 * FFV_PCM_BUFFER_DURATION_MS) \
+       /(FFV_PCM_PERIOD_COUNT * 1000)) + 0x1f) & ~0x1f)
+
+#define ALIGN(number, align) \
+        ((number + align - 1) & ~(align - 1))
+#define CALCULATE_PERIOD_SIZE(duration_ms, sample_rate, period_cnt, align) \
+       (ALIGN(((sample_rate * duration_ms) /(period_cnt * 1000)), align))
+
+#define FFV_PCM_MAX_RETRY 10
+#define FFV_PCM_SLEEP_WAIT 1000
+
+#define DLSYM(handle, name, err) \
+do {\
+    const char* error; \
+    *(void**)&name##_fn = dlsym(handle, #name);\
+    if ((error = dlerror())) {\
+        ALOGE("%s: dlsym failed for %s error %s", __func__, #name, error);\
+        err = -ENODEV;\
+    }\
+} while(0)\
+
+/* uncomment to collect pcm dumps */
+//#define FFV_PCM_DUMP
+
+static FfvStatusType (*ffv_init_fn)(void** handle, int num_tx_in_ch,
+    int num_out_ch, int num_ec_ref_ch, int frame_len, int sample_rate,
+    const char *config_file_name, char *svaModelBuffer,
+    uint32_t svaModelSize, int* totMemSize);
+static void (*ffv_deinit_fn)(void* handle);
+static void (*ffv_process_fn)(void *handle, const int16_t *in_pcm,
+    int16_t *out_pcm, const int16_t *ec_ref_pcm);
+static int (*ffv_read_fn)(void* handle, int16_t *buf_pcm,
+    int max_buf_len);
+static FfvStatusType (*ffv_get_param_fn)(void *handle, char *params_buffer_ptr,
+    int param_id, int buffer_size, int *param_size_ptr);
+static FfvStatusType (*ffv_set_param_fn)(void *handle, char *params_buffer_ptr,
+    int param_id, int param_size);
+static FfvStatusType (*ffv_register_event_callback_fn)(void *handle,
+    ffv_event_callback_fn_t *fun_ptr);
+
+struct ffvmodule {
+    void *ffv_lib_handle;
+    unsigned char *in_buf;
+    unsigned int in_buf_size;
+    unsigned char *ec_ref_buf;
+    unsigned int ec_ref_buf_size;
+    unsigned char *split_in_buf;
+    unsigned int split_in_buf_size;
+    unsigned char *out_buf;
+    unsigned int out_buf_size;
+
+    struct pcm_config capture_config;
+    struct pcm_config out_config;
+    struct pcm_config ec_ref_config;
+
+    int ec_ref_pcm_id;
+    struct pcm *ec_ref_pcm;
+    int ec_ref_ch_cnt;
+    audio_devices_t ec_ref_dev;
+    bool split_ec_ref_data;
+
+    bool is_ffv_enabled;
+    bool buffers_allocated;
+    struct stream_in *in;
+    bool is_ffvmode_on;
+    void *handle;
+    pthread_mutex_t init_lock;
+    bool capture_started;
+    int target_ch_idx;
+
+#ifdef FFV_PCM_DUMP
+    FILE *fp_input;
+    FILE *fp_ecref;
+    FILE *fp_split_input;
+    FILE *fp_output;
+#endif
+};
+
+static struct ffvmodule ffvmod = {
+    .ffv_lib_handle = NULL,
+    .in_buf = NULL,
+    .in_buf_size = 0,
+    .ec_ref_buf = NULL,
+    .ec_ref_buf_size = 0,
+    .split_in_buf = NULL,
+    .split_in_buf_size = 0,
+    .out_buf = NULL,
+    .out_buf_size = 0,
+
+    .ec_ref_pcm = NULL,
+    .ec_ref_ch_cnt = 1,
+    .ec_ref_dev = AUDIO_DEVICE_OUT_SPEAKER,
+    .is_ffv_enabled = false,
+    .buffers_allocated = false,
+    .in = NULL,
+    .is_ffvmode_on = false,
+    .handle = NULL,
+    .capture_started = false,
+    .target_ch_idx = -1,
+};
+
+static struct pcm_config ffv_pcm_config = {
+    .channels = FFV_CHANNEL_MODE_MONO,
+    .rate = FFV_SAMPLING_RATE_16000,
+    .period_size = FFV_PCM_PERIOD_SIZE,
+    .period_count = FFV_PCM_PERIOD_COUNT,
+    .format = PCM_FORMAT_S16_LE,
+};
+
+static int32_t ffv_init_lib()
+{
+    int status = 0;
+
+    if (ffvmod.ffv_lib_handle) {
+        ALOGE("%s: FFV library is already initialized", __func__);
+        return 0;
+    }
+
+    ffvmod.ffv_lib_handle = dlopen(FFV_LIB, RTLD_NOW);
+    if (!ffvmod.ffv_lib_handle) {
+        ALOGE("%s: Unable to open %s, error %s", __func__, FFV_LIB,
+            dlerror());
+        status = -ENOENT;
+        goto exit;
+    }
+
+    dlerror(); /* clear errors */
+    DLSYM(ffvmod.ffv_lib_handle, ffv_init, status);
+    if (status)
+        goto exit;
+    DLSYM(ffvmod.ffv_lib_handle, ffv_deinit, status);
+    if (status)
+        goto exit;
+    DLSYM(ffvmod.ffv_lib_handle, ffv_process, status);
+    if (status)
+        goto exit;
+    DLSYM(ffvmod.ffv_lib_handle, ffv_read, status);
+    if (status)
+        goto exit;
+    DLSYM(ffvmod.ffv_lib_handle, ffv_get_param, status);
+    if (status)
+        goto exit;
+    DLSYM(ffvmod.ffv_lib_handle, ffv_set_param, status);
+    if (status)
+        goto exit;
+    DLSYM(ffvmod.ffv_lib_handle, ffv_register_event_callback, status);
+    if (status)
+        goto exit;
+
+    return status;
+
+exit:
+    if (ffvmod.ffv_lib_handle)
+        dlclose(ffvmod.ffv_lib_handle);
+    ffvmod.ffv_lib_handle = NULL;
+
+    return status;
+}
+
+static int deallocate_buffers()
+{
+    if (ffvmod.in_buf) {
+        free(ffvmod.in_buf);
+        ffvmod.in_buf = NULL;
+    }
+
+    if (ffvmod.split_in_buf) {
+        free(ffvmod.split_in_buf);
+        ffvmod.split_in_buf = NULL;
+    }
+
+    if (ffvmod.ec_ref_buf) {
+        free(ffvmod.ec_ref_buf);
+        ffvmod.ec_ref_buf = NULL;
+    }
+
+    if (ffvmod.out_buf) {
+        free(ffvmod.out_buf);
+        ffvmod.out_buf = NULL;
+    }
+
+    ffvmod.buffers_allocated = false;
+    return 0;
+}
+
+static int allocate_buffers()
+{
+    int status = 0;
+
+    /* in_buf - buffer read from capture session */
+    ffvmod.in_buf_size = ffvmod.capture_config.period_size * ffvmod.capture_config.channels *
+                              (pcm_format_to_bits(ffvmod.capture_config.format) >> 3);
+    ffvmod.in_buf = (unsigned char *)calloc(1, ffvmod.in_buf_size);
+    if (!ffvmod.in_buf) {
+        ALOGE("%s: ERROR. Can not allocate in buffer size %d", __func__, ffvmod.in_buf_size);
+        status = -ENOMEM;
+        goto error_exit;
+    }
+    ALOGD("%s: Allocated in buffer size bytes =%d",
+          __func__, ffvmod.in_buf_size);
+
+    /* ec_buf - buffer read from ec ref capture session */
+    ffvmod.ec_ref_buf_size = ffvmod.ec_ref_config.period_size * ffvmod.ec_ref_config.channels *
+                              (pcm_format_to_bits(ffvmod.ec_ref_config.format) >> 3);
+    ffvmod.ec_ref_buf = (unsigned char *)calloc(1, ffvmod.ec_ref_buf_size);
+    if (!ffvmod.ec_ref_buf) {
+        ALOGE("%s: ERROR. Can not allocate ec ref buffer size %d",
+               __func__, ffvmod.ec_ref_buf_size);
+        status = -ENOMEM;
+        goto error_exit;
+    }
+    ALOGD("%s: Allocated ec ref buffer size bytes =%d",
+          __func__, ffvmod.ec_ref_buf_size);
+
+    if (ffvmod.split_ec_ref_data) {
+        ffvmod.split_in_buf_size = ffvmod.in_buf_size - ffvmod.ec_ref_buf_size;
+        ffvmod.split_in_buf = (unsigned char *)calloc(1, ffvmod.split_in_buf_size);
+        if (!ffvmod.split_in_buf) {
+            ALOGE("%s: ERROR. Can not allocate split in buffer size %d",
+                   __func__, ffvmod.split_in_buf_size);
+            status = -ENOMEM;
+            goto error_exit;
+        }
+        ALOGD("%s: Allocated split in buffer size bytes =%d",
+               __func__, ffvmod.split_in_buf_size);
+    }
+
+    /* out_buf - output buffer from FFV + SVA library */
+    ffvmod.out_buf_size = ffvmod.out_config.period_size * ffvmod.out_config.channels *
+                              (pcm_format_to_bits(ffvmod.out_config.format) >> 3);
+    ffvmod.out_buf = (unsigned char *)calloc(1, ffvmod.out_buf_size);
+    if (!ffvmod.out_buf) {
+        ALOGE("%s: ERROR. Can not allocate out buffer size %d", __func__, ffvmod.out_buf_size);
+        status = -ENOMEM;
+        goto error_exit;
+    }
+    ALOGD("%s: Allocated out buffer size bytes =%d",
+          __func__, ffvmod.out_buf_size);
+
+    ffvmod.buffers_allocated = true;
+    return 0;
+
+error_exit:
+    deallocate_buffers();
+    return status;
+}
+
+void audio_extn_ffv_update_enabled()
+{
+    char ffv_enabled[PROPERTY_VALUE_MAX] = "false";
+
+    property_get("ro.qc.sdk.audio.ffv", ffv_enabled, "0");
+    if (!strncmp("true", ffv_enabled, 4)) {
+        ALOGD("%s: ffv is supported", __func__);
+        ffvmod.is_ffv_enabled = true;
+    } else {
+        ALOGD("%s: ffv is not supported", __func__);
+        ffvmod.is_ffv_enabled = false;
+    }
+}
+
+bool audio_extn_ffv_get_enabled()
+{
+    ALOGV("%s: is_ffv_enabled:%d is_ffvmode_on:%d ", __func__, ffvmod.is_ffv_enabled, ffvmod.is_ffvmode_on);
+
+    if(ffvmod.is_ffv_enabled && ffvmod.is_ffvmode_on)
+        return true;
+
+    return false;
+}
+
+bool  audio_extn_ffv_check_usecase(struct stream_in *in) {
+    int ret = false;
+    int channel_count = audio_channel_count_from_in_mask(in->channel_mask);
+    audio_devices_t devices = in->device;
+    audio_source_t source = in->source;
+
+    if ((audio_extn_ffv_get_enabled()) &&
+            (channel_count == 1) &&
+            (AUDIO_SOURCE_MIC == source) &&
+            ((AUDIO_DEVICE_IN_BUILTIN_MIC == devices) || (AUDIO_DEVICE_IN_BACK_MIC == devices)) &&
+            (in->format == AUDIO_FORMAT_PCM_16_BIT) &&
+            (in->sample_rate == FFV_SAMPLING_RATE_16000)) {
+        in->config.channels = channel_count;
+        in->config.period_count = FFV_PCM_PERIOD_COUNT;
+        in->config.period_size = FFV_PCM_PERIOD_SIZE;
+        ALOGD("%s: FFV enabled", __func__);
+        ret = true;
+    }
+    return ret;
+}
+
+int audio_extn_ffv_set_usecase(struct stream_in *in)
+{
+    int ret = -EINVAL;
+
+    if (audio_extn_ffv_check_usecase(in)) {
+        if (!audio_extn_ffv_stream_init(in)) {
+            ALOGD("%s: Created FFV session succesfully", __func__);
+            ret = 0;
+        } else {
+            ALOGE("%s: Unable to start FFV record session", __func__);
+        }
+    }
+    return ret;
+}
+
+struct stream_in *audio_extn_ffv_get_stream()
+{
+    return ffvmod.in;
+}
+
+void audio_extn_ffv_update_pcm_config(struct pcm_config *config)
+{
+    config->channels = ffvmod.capture_config.channels;
+    config->period_count = ffvmod.capture_config.period_count;
+    config->period_size = ffvmod.capture_config.period_size;
+}
+
+int32_t audio_extn_ffv_init(struct audio_device *adev)
+{
+    int ret = 0;
+
+    ret = ffv_init_lib();
+    if (ret)
+        ALOGE("%s: ERROR. ffv_init_lib ret %d", __func__, ret);
+
+    pthread_mutex_init(&ffvmod.init_lock, NULL);
+    return ret;
+}
+
+int32_t audio_extn_ffv_deinit()
+{
+    pthread_mutex_destroy(&ffvmod.init_lock);
+    if (ffvmod.ffv_lib_handle) {
+        dlclose(ffvmod.ffv_lib_handle);
+        ffvmod.ffv_lib_handle = NULL;
+    }
+    return 0;
+}
+
+int32_t audio_extn_ffv_stream_init(struct stream_in *in)
+{
+    uint32_t ret = -EINVAL;
+    int num_tx_in_ch, num_out_ch, num_ec_ref_ch;
+    int frame_len;
+    int sample_rate;
+    const char *config_file_path = FFV_CONFIG_FILE_PATH;
+    int total_mem_size;
+    FfvStatusType status_type;
+    const char *sm_buffer = "DISABLE_KEYWORD_DETECTION";
+    ffv_target_channel_index_param_t ch_index_param;
+    char *params_buffer_ptr = NULL;
+    int param_size = 0;
+    int param_id;
+
+    if (!audio_extn_ffv_get_enabled()) {
+        ALOGE("Rejecting FFV -- init is called without enabling FFV");
+        goto fail;
+    }
+
+    if (ffvmod.handle != NULL) {
+        ALOGV("%s: reinitializing ffv library", __func__);
+        audio_extn_ffv_stream_deinit();
+    }
+
+    ffvmod.capture_config = ffv_pcm_config;
+    ffvmod.ec_ref_config = ffv_pcm_config;
+    ffvmod.out_config = ffv_pcm_config;
+    /* configure capture session with 6/8 channels */
+    ffvmod.capture_config.channels = ffvmod.split_ec_ref_data ?
+        FFV_CHANNEL_MODE_OCT : FFV_CHANNEL_MODE_HEX;
+    ffvmod.capture_config.period_size =
+                   CALCULATE_PERIOD_SIZE(FFV_PCM_BUFFER_DURATION_MS,
+                                         ffvmod.capture_config.rate,
+                                         FFV_PCM_PERIOD_COUNT, 32);
+
+    /* Update channels with ec ref channel count */
+    ffvmod.ec_ref_config.channels = ffvmod.ec_ref_ch_cnt;
+    ffvmod.ec_ref_config.period_size =
+               CALCULATE_PERIOD_SIZE(FFV_PCM_BUFFER_DURATION_MS,
+                                     ffvmod.ec_ref_config.rate,
+                                     FFV_PCM_PERIOD_COUNT, 32);
+    ret = allocate_buffers();
+    if (ret)
+        goto fail;
+
+    num_ec_ref_ch = ffvmod.ec_ref_config.channels;
+    num_tx_in_ch = ffvmod.split_ec_ref_data ?
+        (ffvmod.capture_config.channels - num_ec_ref_ch) :
+        ffvmod.capture_config.channels;
+    num_out_ch = ffvmod.out_config.channels;
+    frame_len = ffvmod.capture_config.period_size;
+    sample_rate = ffvmod.capture_config.rate;
+
+    ALOGD("%s: ec_ref_ch %d, tx_in_ch %d, out_ch %d, frame_len %d, sample_rate %d",
+           __func__, num_ec_ref_ch, num_tx_in_ch, num_out_ch, frame_len, sample_rate);
+    ALOGD("%s: config file path %s", __func__, config_file_path);
+    status_type = ffv_init_fn(&ffvmod.handle, num_tx_in_ch, num_out_ch, num_ec_ref_ch,
+                      frame_len, sample_rate, config_file_path, sm_buffer, 0,
+                      &total_mem_size);
+    if (status_type) {
+        ALOGE("%s: ERROR. ffv_init returned %d", __func__, status_type);
+        ret = -EINVAL;
+        goto fail;
+    }
+    ALOGD("%s: ffv_init success %p", __func__, ffvmod.handle);
+
+    /* set target channel index if received as part of setparams */
+    if (ffvmod.target_ch_idx != -1) {
+        ALOGD("%s: target channel index %d", __func__, ffvmod.target_ch_idx);
+        ch_index_param.target_chan_idx = ffvmod.target_ch_idx;
+        params_buffer_ptr = (char *)&ch_index_param;
+        param_size = sizeof(ch_index_param);
+        param_id = FFV_TARGET_CHANNEL_INDEX_PARAM;
+        status_type = ffv_set_param_fn(ffvmod.handle, params_buffer_ptr,
+                                       param_id, param_size);
+        if (status_type) {
+            ALOGE("%s: ERROR. ffv_set_param_fn ret %d", __func__, status_type);
+            ret = -EINVAL;
+            goto fail;
+        }
+    }
+
+    ffvmod.in = in;
+
+#ifdef FFV_PCM_DUMP
+    if (!ffvmod.fp_input) {
+        ALOGD("%s: Opening input dump file \n", __func__);
+        ffvmod.fp_input = fopen("/data/misc/audio/ffv_input.pcm", "wb");
+    }
+    if (!ffvmod.fp_ecref) {
+        ALOGD("%s: Opening ecref dump file \n", __func__);
+        ffvmod.fp_ecref = fopen("/data/misc/audio/ffv_ecref.pcm", "wb");
+    }
+    if (!ffvmod.fp_split_input && ffvmod.split_ec_ref_data) {
+        ALOGD("%s: Opening split input dump file \n", __func__);
+        ffvmod.fp_split_input = fopen("/data/misc/audio/ffv_split_input.pcm", "wb");
+    }
+    if (!ffvmod.fp_output) {
+        ALOGD("%s: Opening output dump file \n", __func__);
+        ffvmod.fp_output = fopen("/data/misc/audio/ffv_output.pcm", "wb");
+    }
+#endif
+    ALOGV("%s: exit", __func__);
+    return 0;
+
+fail:
+    audio_extn_ffv_stream_deinit();
+    return ret;
+}
+
+int32_t audio_extn_ffv_stream_deinit()
+{
+    ALOGV("%s: entry", __func__);
+
+#ifdef FFV_PCM_DUMP
+    if (ffvmod.fp_input)
+        fclose(ffvmod.fp_input);
+
+    if (ffvmod.fp_ecref)
+        fclose(ffvmod.fp_ecref);
+
+    if (ffvmod.fp_split_input)
+        fclose(ffvmod.fp_split_input);
+
+    if (ffvmod.fp_output)
+        fclose(ffvmod.fp_output);
+#endif
+
+    if (ffvmod.handle)
+        ffv_deinit_fn(ffvmod.handle);
+
+    if (ffvmod.buffers_allocated)
+        deallocate_buffers();
+
+    ffvmod.handle = NULL;
+    ffvmod.in = NULL;
+    ALOGV("%s: exit", __func__);
+    return 0;
+}
+
+snd_device_t audio_extn_ffv_get_capture_snd_device()
+{
+    if (ffvmod.capture_config.channels == FFV_CHANNEL_MODE_OCT) {
+        return SND_DEVICE_IN_HANDSET_8MIC;
+    } else if (ffvmod.capture_config.channels == FFV_CHANNEL_MODE_HEX) {
+        return SND_DEVICE_IN_HANDSET_6MIC;
+    } else {
+        ALOGE("%s: Invalid channels configured for capture", __func__);
+        return SND_DEVICE_NONE;
+    }
+}
+
+int audio_extn_ffv_init_ec_ref_loopback(struct audio_device *adev,
+                                        snd_device_t snd_device)
+{
+    struct audio_usecase *uc_info_tx = NULL;
+    snd_device_t in_snd_device;
+    char *params_buffer_ptr = NULL;
+    int param_id = FFV_RESET_AEC_PARAM;
+    int param_size = 0;
+    FfvStatusType status_type;
+    int ret = 0;
+
+    ALOGV("%s: entry", __func__);
+    /* notify library to reset AEC during each start */
+    status_type = ffv_set_param_fn(ffvmod.handle, params_buffer_ptr,
+                      param_id, param_size);
+    if (status_type) {
+        ALOGE("%s: ERROR. ffv_set_param_fn ret %d", __func__, status_type);
+        return -EINVAL;
+    }
+
+    if (ffvmod.split_ec_ref_data) {
+        ALOGV("%s: Ignore ec ref loopback init", __func__);
+        return 0;
+    }
+
+    in_snd_device = platform_get_ec_ref_loopback_snd_device(ffvmod.ec_ref_ch_cnt);
+    uc_info_tx = (struct audio_usecase *)calloc(1, sizeof(struct audio_usecase));
+    if (!uc_info_tx) {
+        return -ENOMEM;
+    }
+
+    pthread_mutex_lock(&ffvmod.init_lock);
+    uc_info_tx->id = USECASE_AUDIO_EC_REF_LOOPBACK;
+    uc_info_tx->type = PCM_CAPTURE;
+    uc_info_tx->in_snd_device = in_snd_device;
+    uc_info_tx->out_snd_device = SND_DEVICE_NONE;
+    ffvmod.ec_ref_pcm = NULL;
+    list_add_tail(&adev->usecase_list, &uc_info_tx->list);
+    enable_snd_device(adev, in_snd_device);
+    enable_audio_route(adev, uc_info_tx);
+
+    ffvmod.ec_ref_pcm_id = platform_get_pcm_device_id(uc_info_tx->id, PCM_CAPTURE);
+    if (ffvmod.ec_ref_pcm_id < 0) {
+        ALOGE("%s: Invalid pcm device for usecase (%d)",
+              __func__, uc_info_tx->id);
+        ret = -ENODEV;
+        goto exit;
+    }
+
+    ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d format %d",
+          __func__, adev->snd_card, ffvmod.ec_ref_pcm_id, ffvmod.ec_ref_config.channels,
+          ffvmod.ec_ref_config.format);
+    ffvmod.ec_ref_pcm = pcm_open(adev->snd_card,
+                             ffvmod.ec_ref_pcm_id,
+                             PCM_IN, &ffvmod.ec_ref_config);
+    if (ffvmod.ec_ref_pcm && !pcm_is_ready(ffvmod.ec_ref_pcm)) {
+        ALOGE("%s: %s", __func__, pcm_get_error(ffvmod.ec_ref_pcm));
+        ret = -EIO;
+        goto exit;
+    }
+
+    ALOGV("%s: pcm_prepare", __func__);
+    if (pcm_prepare(ffvmod.ec_ref_pcm) < 0) {
+        ALOGE("%s: pcm prepare for ec ref loopback failed", __func__);
+        ret = -EINVAL;
+    }
+
+    ffvmod.capture_started = false;
+    pthread_mutex_unlock(&ffvmod.init_lock);
+    ALOGV("%s: exit", __func__);
+    return 0;
+
+exit:
+    if (ffvmod.ec_ref_pcm) {
+        pcm_close(ffvmod.ec_ref_pcm);
+        ffvmod.ec_ref_pcm = NULL;
+    }
+    list_remove(&uc_info_tx->list);
+    disable_snd_device(adev, in_snd_device);
+    disable_audio_route(adev, uc_info_tx);
+    free(uc_info_tx);
+    pthread_mutex_unlock(&ffvmod.init_lock);
+    return ret;
+}
+
+void audio_extn_ffv_append_ec_ref_dev_name(char *device_name)
+{
+    if (ffvmod.ec_ref_dev == AUDIO_DEVICE_OUT_AUX_LINE)
+        strlcat(device_name, " lineout",  DEVICE_NAME_MAX_SIZE);
+    ALOGD("%s: ec ref dev name %s", __func__, device_name);
+}
+
+int audio_extn_ffv_deinit_ec_ref_loopback(struct audio_device *adev,
+                                          snd_device_t snd_device)
+{
+    struct audio_usecase *uc_info_tx = NULL;
+    snd_device_t in_snd_device;
+    int ret = 0;
+
+    ALOGV("%s: entry", __func__);
+    if (ffvmod.split_ec_ref_data) {
+        ALOGV("%s: Ignore ec ref loopback init", __func__);
+        return 0;
+    }
+
+    in_snd_device = platform_get_ec_ref_loopback_snd_device(ffvmod.ec_ref_ch_cnt);
+    uc_info_tx = get_usecase_from_list(adev, USECASE_AUDIO_EC_REF_LOOPBACK);
+    pthread_mutex_lock(&ffvmod.init_lock);
+    if (ffvmod.ec_ref_pcm) {
+        pcm_close(ffvmod.ec_ref_pcm);
+        ffvmod.ec_ref_pcm = NULL;
+    }
+    disable_snd_device(adev, in_snd_device);
+    if (uc_info_tx) {
+        list_remove(&uc_info_tx->list);
+        disable_audio_route(adev, uc_info_tx);
+        free(uc_info_tx);
+    }
+    pthread_mutex_unlock(&ffvmod.init_lock);
+    ALOGV("%s: exit", __func__);
+    return ret;
+}
+
+int32_t audio_extn_ffv_read(struct audio_stream_in *stream,
+                       void *buffer, size_t bytes)
+{
+    int status = 0;
+    int16_t *in_ptr = NULL, *process_in_ptr = NULL, *process_out_ptr = NULL;
+    int16_t *process_ec_ref_ptr = NULL;
+    size_t in_buf_size, out_buf_size, bytes_to_copy;
+    int retry_num = 0;
+    int i, j, ch;
+    int total_in_ch, in_ch, ec_ref_ch;
+
+    if (!ffvmod.ffv_lib_handle) {
+        ALOGE("%s: ffv_lib_handle not initialized", __func__);
+        return -EINVAL;
+    }
+
+    if (!ffvmod.handle) {
+        ALOGE("%s: ffv module handle not initialized", __func__);
+        return -EINVAL;
+    }
+
+    if (!ffvmod.in || !ffvmod.in->pcm) {
+        ALOGE("%s: capture session not initiliazed", __func__);
+        return -EINVAL;
+    }
+
+    if (!ffvmod.split_ec_ref_data && !ffvmod.ec_ref_pcm) {
+        ALOGE("%s: ec ref session not initiliazed", __func__);
+        return -EINVAL;
+    }
+
+    if (!ffvmod.capture_started) {
+        /* pcm_start of capture and ec ref session before read to reduce drift */
+        pcm_start(ffvmod.in->pcm);
+        while (status && (retry_num < FFV_PCM_MAX_RETRY)) {
+            usleep(FFV_PCM_SLEEP_WAIT);
+            retry_num++;
+            ALOGI("%s: pcm_start retrying..status %d errno %d, retry cnt %d",
+                   __func__, status, errno, retry_num);
+            status = pcm_start(ffvmod.in->pcm);
+        }
+        if (status) {
+            ALOGE("%s: ERROR. pcm_start failed, returned status %d - %s",
+                  __func__, status, pcm_get_error(ffvmod.in->pcm));
+            return status;
+        }
+        retry_num = 0;
+
+        if (!ffvmod.split_ec_ref_data) {
+            pcm_start(ffvmod.ec_ref_pcm);
+            while (status && (retry_num < FFV_PCM_MAX_RETRY)) {
+                usleep(FFV_PCM_SLEEP_WAIT);
+                retry_num++;
+                ALOGI("%s: pcm_start retrying..status %d errno %d, retry cnt %d",
+                      __func__, status, errno, retry_num);
+                status = pcm_start(ffvmod.ec_ref_pcm);
+            }
+            if (status) {
+                ALOGE("%s: ERROR. pcm_start failed, returned status %d - %s",
+                       __func__, status, pcm_get_error(ffvmod.ec_ref_pcm));
+                return status;
+            }
+        }
+        ffvmod.capture_started = true;
+    }
+
+    ALOGVV("%s: pcm_read reading bytes=%d", __func__, ffvmod.in_buf_size);
+    status = pcm_read(ffvmod.in->pcm, ffvmod.in_buf, ffvmod.in_buf_size);
+    if (status) {
+        ALOGE("%s: pcm read failed status %d - %s", __func__, status,
+              pcm_get_error(ffvmod.in->pcm));
+        goto exit;
+    }
+    ALOGVV("%s: pcm_read done", __func__);
+
+    if (!ffvmod.split_ec_ref_data) {
+        /* read EC ref data */
+        ALOGVV("%s: ec ref pcm_read reading bytes=%d", __func__, ffvmod.ec_ref_buf_size);
+        status = pcm_read(ffvmod.ec_ref_pcm, ffvmod.ec_ref_buf, ffvmod.ec_ref_buf_size);
+        if (status) {
+            ALOGE("%s: ec ref pcm read failed status %d - %s", __func__, status,
+                   pcm_get_error(ffvmod.ec_ref_pcm));
+            goto exit;
+        }
+        ALOGVV("%s: ec ref pcm_read done", __func__);
+        process_in_ptr = (int16_t *)ffvmod.in_buf;
+        process_ec_ref_ptr = (int16_t *)ffvmod.ec_ref_buf;
+        in_buf_size = ffvmod.in_buf_size;
+    } else {
+        /* split input buffer into actual input channels and EC ref channels */
+        in_ptr = (int16_t *)ffvmod.in_buf;
+        process_in_ptr = (int16_t *)ffvmod.split_in_buf;
+        process_ec_ref_ptr = (int16_t *)ffvmod.ec_ref_buf;
+        total_in_ch = ffvmod.capture_config.channels;
+        ec_ref_ch = ffvmod.ec_ref_config.channels;
+        in_ch = total_in_ch - ec_ref_ch;
+        for (i = 0; i < ffvmod.capture_config.period_size; i++) {
+            for (ch = 0; ch < in_ch; ch++) {
+                process_in_ptr[i*in_ch+ch] =
+                          in_ptr[i*total_in_ch+ch];
+            }
+            for (ch = 0; ch < ec_ref_ch; ch++) {
+                process_ec_ref_ptr[i*ec_ref_ch+ch] =
+                          in_ptr[i*total_in_ch+in_ch+ch];
+            }
+        }
+        in_buf_size = ffvmod.split_in_buf_size;
+    }
+    process_out_ptr = (int16_t *)ffvmod.out_buf;
+
+    ffv_process_fn(ffvmod.handle, process_in_ptr,
+            process_out_ptr, process_ec_ref_ptr);
+    out_buf_size = ffvmod.out_buf_size;
+    bytes_to_copy = (bytes <= out_buf_size) ? bytes : out_buf_size;
+    memcpy(buffer, process_out_ptr, bytes_to_copy);
+    if (bytes_to_copy != out_buf_size)
+        ALOGD("%s: out buffer data dropped, copied %d bytes",
+               __func__, bytes_to_copy);
+
+#ifdef FFV_PCM_DUMP
+    if (ffvmod.fp_input)
+        fwrite(ffvmod.in_buf, 1, ffvmod.in_buf_size, ffvmod.fp_input);
+    if (ffvmod.fp_ecref)
+        fwrite(ffvmod.ec_ref_buf, 1, ffvmod.ec_ref_buf_size, ffvmod.fp_ecref);
+    if (ffvmod.fp_split_input)
+        fwrite(ffvmod.split_in_buf, 1, ffvmod.split_in_buf_size, ffvmod.fp_split_input);
+    if (ffvmod.fp_output)
+        fwrite(process_out_ptr, 1, bytes_to_copy, ffvmod.fp_output);
+#endif
+
+exit:
+    return status;
+}
+
+void audio_extn_ffv_set_parameters(struct audio_device *adev __unused,
+                                   struct str_parms *parms)
+{
+    int err;
+    int val;
+    int ret = 0;
+    char value[128];
+
+    /* FFV params are required to be set before start of recording */
+    if (!ffvmod.handle) {
+        ret = str_parms_get_str(parms, AUDIO_PARAMETER_FFV_MODE_ON, value,
+                                sizeof(value));
+        if (ret >= 0) {
+            str_parms_del(parms, AUDIO_PARAMETER_FFV_MODE_ON);
+            if (strcmp(value, "true") == 0) {
+                ALOGD("%s: Setting FFV mode to true", __func__);
+                ffvmod.is_ffvmode_on = true;
+            } else {
+                ALOGD("%s: Resetting FFV mode to false", __func__);
+                ffvmod.is_ffvmode_on = false;
+            }
+        }
+
+        ret = str_parms_get_str(parms, AUDIO_PARAMETER_FFV_SPLIT_EC_REF_DATA, value,
+                                sizeof(value));
+        if (ret >= 0) {
+            str_parms_del(parms, AUDIO_PARAMETER_FFV_SPLIT_EC_REF_DATA);
+            if (strcmp(value, "true") == 0) {
+                ALOGD("%s: ec ref is packed with mic captured data", __func__);
+                ffvmod.split_ec_ref_data = true;
+            } else {
+                ALOGD("%s: ec ref is captured separately", __func__);
+                ffvmod.split_ec_ref_data = false;
+            }
+        }
+        ret = str_parms_get_int(parms, AUDIO_PARAMETER_FFV_EC_REF_CHANNEL_COUNT, &val);
+        if (ret >= 0) {
+            str_parms_del(parms, AUDIO_PARAMETER_FFV_EC_REF_CHANNEL_COUNT);
+            if (val == 1) {
+                ALOGD("%s: mono ec ref", __func__);
+                ffvmod.ec_ref_ch_cnt = FFV_CHANNEL_MODE_MONO;
+            } else if (val == 2) {
+                ALOGD("%s: stereo ec ref", __func__);
+                ffvmod.ec_ref_ch_cnt = FFV_CHANNEL_MODE_STEREO;
+            } else {
+                ALOGE("%s: Invalid ec ref", __func__);
+            }
+        }
+
+        ret = str_parms_get_int(parms, AUDIO_PARAMETER_FFV_EC_REF_DEVICE, &val);
+        if (ret >= 0) {
+            str_parms_del(parms, AUDIO_PARAMETER_FFV_EC_REF_DEVICE);
+            if (val & AUDIO_DEVICE_OUT_SPEAKER) {
+                ALOGD("%s: capture ec ref from speaker", __func__);
+                ffvmod.ec_ref_dev = AUDIO_DEVICE_OUT_SPEAKER;
+            } else if (val & AUDIO_DEVICE_OUT_AUX_LINE) {
+                ALOGD("%s: capture ec ref from line out", __func__);
+                ffvmod.ec_ref_dev = AUDIO_DEVICE_OUT_AUX_LINE;
+            } else {
+                ALOGE("%s: Invalid ec ref out device", __func__);
+            }
+        }
+
+        ret = str_parms_get_int(parms, AUDIO_PARAMETER_FFV_CHANNEL_INDEX, &val);
+        if (ret >= 0) {
+            str_parms_del(parms, AUDIO_PARAMETER_FFV_CHANNEL_INDEX);
+            ALOGD("%s: set target chan index %d", __func__, val);
+            ffvmod.target_ch_idx = val;
+        }
+    }
+}
diff --git a/hal/audio_extn/passthru.c b/hal/audio_extn/passthru.c
index 701084a..f8974c7 100644
--- a/hal/audio_extn/passthru.c
+++ b/hal/audio_extn/passthru.c
@@ -69,6 +69,8 @@
 
 #define MIN_COMPRESS_PASSTHROUGH_FRAGMENT_SIZE (2 * 1024)
 
+#define DDP_COMPRESS_PASSTHROUGH_FRAGMENT_SIZE (10 * 1024)
+
 static const audio_format_t audio_passthru_formats[] = {
     AUDIO_FORMAT_AC3,
     AUDIO_FORMAT_E_AC3,
@@ -348,11 +350,13 @@
     switch (out->format) {
     case AUDIO_FORMAT_E_AC3:
     case AUDIO_FORMAT_E_AC3_JOC:
-    case AUDIO_FORMAT_DTS_HD:
         if (!platform_is_edid_supported_format(adev->platform,
-            out->format)) {
-            ALOGD("%s:PASSTHROUGH_CONVERT supported", __func__);
-            convert = true;
+                                               out->format)) {
+            if (platform_is_edid_supported_format(adev->platform,
+                                                  AUDIO_FORMAT_AC3)) {
+                ALOGD("%s:PASSTHROUGH_CONVERT supported", __func__);
+                convert = true;
+            }
         }
         break;
     default:
@@ -449,7 +453,7 @@
                         out->format)) {
                     ALOGV("%s : return true",__func__);
                     return true;
-                } else if (audio_extn_is_dolby_format(out->format) &&
+                } else if (audio_extn_utils_is_dolby_format(out->format) &&
                             platform_is_edid_supported_format(out->dev->platform,
                                 AUDIO_FORMAT_AC3)){
                     //return true for EAC3/EAC3_JOC formats
@@ -488,8 +492,14 @@
                (info->format == AUDIO_FORMAT_DTS_HD)) {
         fragment_size = MAX_COMPRESS_PASSTHROUGH_FRAGMENT_SIZE;
         goto done;
+    } else if (info->format == AUDIO_FORMAT_E_AC3) {
+        fragment_size = DDP_COMPRESS_PASSTHROUGH_FRAGMENT_SIZE;
+        if(property_get("audio.ddp.buffer.size.kb", value, "") &&
+                atoi(value)) {
+            fragment_size = atoi(value) * 1024;
+        }
+        goto done;
     }
-
 done:
     return fragment_size;
 
@@ -504,3 +514,44 @@
 {
     return platform_set_device_params(out, DEVICE_PARAM_LATENCY_ID, latency);
 }
+
+bool audio_extn_passthru_is_supported_backend_edid_cfg(struct audio_device *adev,
+                                                   struct stream_out *out)
+{
+    struct audio_backend_cfg backend_cfg;
+    snd_device_t out_snd_device = SND_DEVICE_NONE;
+    int max_edid_channels = platform_edid_get_max_channels(out->dev->platform);
+
+    out_snd_device = platform_get_output_snd_device(adev->platform, out);
+
+    if (platform_get_codec_backend_cfg(adev, out_snd_device, &backend_cfg)) {
+        ALOGE("%s: ERROR: Unable to get current backend config!!!", __func__);
+        return false;
+    }
+
+    ALOGV("%s:becf: afe: bitwidth %d, samplerate %d channels %d format %d"
+          ", device (%s)", __func__,  backend_cfg.bit_width,
+          backend_cfg.sample_rate, backend_cfg.channels, backend_cfg.format,
+          platform_get_snd_device_name(out_snd_device));
+
+    /* Check if the channels are supported */
+    if (max_edid_channels < (int)backend_cfg.channels) {
+
+        ALOGE("%s: ERROR: Unsupported channels in passthru mode!!!"
+              " max_edid_channels - %d backend_channels - %d",
+              __func__, max_edid_channels, backend_cfg.channels);
+        return false;
+    }
+
+    /* Check if the sample rate supported */
+    if (!platform_is_edid_supported_sample_rate(adev->platform,
+                                       backend_cfg.sample_rate)) {
+
+        ALOGE("%s: ERROR: Unsupported sample rate in passthru mode!!!"
+              " backend_samplerate - %d",
+              __func__, backend_cfg.sample_rate);
+        return false;
+    }
+
+    return true;
+}
diff --git a/hal/audio_extn/qaf.c b/hal/audio_extn/qaf.c
index 6320b94..ca83b1d 100644
--- a/hal/audio_extn/qaf.c
+++ b/hal/audio_extn/qaf.c
@@ -31,12 +31,11 @@
 /*#define LOG_NDEBUG 0*/
 /*#define VERY_VERY_VERBOSE_LOGGING*/
 #ifdef VERY_VERY_VERBOSE_LOGGING
-#define ALOGVV ALOGV
+#define DEBUG_MSG_VV DEBUG_MSG
 #else
-#define ALOGVV(a...) do { } while(0)
+#define DEBUG_MSG_VV(a...) do { } while(0)
 #endif
 
-#define DEBUG_MSG_VV(arg,...) ALOGVV("%s: %d:  " arg, __func__, __LINE__, ##__VA_ARGS__)
 #define DEBUG_MSG(arg,...) ALOGV("%s: %d:  " arg, __func__, __LINE__, ##__VA_ARGS__)
 #define ERROR_MSG(arg,...) ALOGE("%s: %d:  " arg, __func__, __LINE__, ##__VA_ARGS__)
 
@@ -355,6 +354,22 @@
    return (qaf_mod->stream_in[QAF_IN_MAIN] && qaf_mod->stream_in[QAF_IN_MAIN_2]);
 }
 
+//Checks if any main or pcm stream is running in the session.
+static bool is_any_stream_running(struct qaf_module* qaf_mod)
+{
+    //Not checking associated stream.
+    struct stream_out *out = qaf_mod->stream_in[QAF_IN_MAIN];
+    struct stream_out *out_pcm = qaf_mod->stream_in[QAF_IN_PCM];
+    struct stream_out *out_main2 = qaf_mod->stream_in[QAF_IN_MAIN_2];
+
+    if ((out == NULL || (out != NULL && check_stream_state(out, STOPPED)))
+        && (out_main2 == NULL || (out_main2 != NULL && check_stream_state(out_main2, STOPPED)))
+        && (out_pcm == NULL || (out_pcm != NULL && check_stream_state(out_pcm, STOPPED)))) {
+        return false;
+    }
+    return true;
+}
+
 /* Gets the pcm output buffer size(in samples) for the mm module. */
 static uint32_t get_pcm_output_buffer_size_samples(struct qaf_module *qaf_mod)
 {
@@ -714,6 +729,10 @@
         return ret;
     }
 
+    //If data received on associated stream when all other stream are stopped then drop the data.
+    if (out == qaf_mod->stream_in[QAF_IN_ASSOC] && !is_any_stream_running(qaf_mod))
+        return bytes;
+
     if (out->qaf_stream_handle) {
         ret = qaf_mod->qaf_audio_stream_write(out->qaf_stream_handle, buffer, bytes);
         if(ret > 0) set_stream_state(out, RUN);
@@ -1050,6 +1069,9 @@
 {
     struct stream_out *out = (struct stream_out *)stream;
     int status = 0;
+    struct qaf_module *qaf_mod = NULL;
+
+    qaf_mod = get_qaf_module_for_input_stream(out);
     DEBUG_MSG("Output Stream %p", out);
 
     lock_output_stream(out);
@@ -1063,11 +1085,11 @@
                     (struct audio_stream_out *)p_qaf->passthrough_out, type);
         }
         pthread_mutex_unlock(&p_qaf->lock);
-    } else if (check_stream_state(out, STOPPED)) {
+    } else if (!is_any_stream_running(qaf_mod)) {
         //If stream is already stopped then send the drain ready.
         out->client_callback(STREAM_CBK_EVENT_DRAIN_READY, NULL, out->client_cookie);
+        set_stream_state(out, STOPPED);
     } else {
-
         //Drain the module input stream.
         /* Stream stop will trigger EOS and on EOS_EVENT received
          from callback DRAIN_READY command is sent */
@@ -1245,6 +1267,8 @@
     audio_qaf_media_format_t *media_fmt = NULL;
 
     DEBUG_MSG_VV("Device 0x%X, Event = 0x%X, Bytes to write %d", device, event_id, size);
+
+
     pthread_mutex_lock(&p_qaf->lock);
 
     /* Default config initialization. */
@@ -1383,7 +1407,8 @@
 
                 flags = (AUDIO_OUTPUT_FLAG_NON_BLOCKING
                          | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD
-                         | AUDIO_OUTPUT_FLAG_DIRECT);
+                         | AUDIO_OUTPUT_FLAG_DIRECT
+                         | AUDIO_OUTPUT_FLAG_COMPRESS_PASSTHROUGH);
                 devices = AUDIO_DEVICE_OUT_AUX_DIGITAL;
 
                 ret = adev_open_output_stream((struct audio_hw_device *)p_qaf->adev,
@@ -1399,7 +1424,7 @@
                     return;
                 }
 
-                if (format & AUDIO_FORMAT_E_AC3) {
+                if (format == AUDIO_FORMAT_E_AC3) {
                     qaf_mod->stream_out[QAF_OUT_TRANSCODE_PASSTHROUGH]->compr_config.fragment_size =
                             COMPRESS_PASSTHROUGH_DDP_FRAGMENT_SIZE;
                 }
@@ -1674,7 +1699,9 @@
                || event_id == AUDIO_EOS_MAIN_2_DD_DDP_EVENT
                || event_id == AUDIO_EOS_MAIN_AAC_EVENT
                || event_id == AUDIO_EOS_MAIN_AC4_EVENT
-               || event_id == AUDIO_EOS_ASSOC_DD_DDP_EVENT) {
+               || event_id == AUDIO_EOS_ASSOC_DD_DDP_EVENT
+               || event_id == AUDIO_EOS_ASSOC_AAC_EVENT
+               || event_id == AUDIO_EOS_ASSOC_AC4_EVENT) {
         struct stream_out *out = qaf_mod->stream_in[QAF_IN_MAIN];
         struct stream_out *out_pcm = qaf_mod->stream_in[QAF_IN_PCM];
         struct stream_out *out_main2 = qaf_mod->stream_in[QAF_IN_MAIN_2];
@@ -1693,7 +1720,9 @@
             set_stream_state(out_pcm, STOPPED);
             unlock_output_stream(out_pcm);
             DEBUG_MSG("sent pcm DRAIN_READY");
-        } else if (event_id == AUDIO_EOS_ASSOC_DD_DDP_EVENT
+        } else if ( (event_id == AUDIO_EOS_ASSOC_DD_DDP_EVENT
+                || event_id == AUDIO_EOS_ASSOC_AAC_EVENT
+                || event_id == AUDIO_EOS_ASSOC_AC4_EVENT)
                 && (out_assoc != NULL)
                 && (check_stream_state(out_assoc, STOPPING))) {
 
@@ -1799,6 +1828,8 @@
         return -EINVAL;
     }
 
+    pthread_mutex_lock(&p_qaf->lock);
+
     set_stream_state(out,STOPPED);
     qaf_mod->stream_in[index] = NULL;
     memset(&qaf_mod->adsp_hdlr_config[index], 0, sizeof(struct qaf_adsp_hdlr_config_state));
@@ -1813,6 +1844,8 @@
     //If all streams are closed then close the session.
     qaf_session_close(qaf_mod);
 
+    pthread_mutex_unlock(&p_qaf->lock);
+
     DEBUG_MSG();
     return ret;
 }
@@ -1974,7 +2007,11 @@
                                                 input_config,
                                                 devices,
                                                 AUDIO_STREAM_SYSTEM_TONE);
-        qaf_mod->stream_in[QAF_IN_PCM] = out;
+        if (status == 0) {
+            qaf_mod->stream_in[QAF_IN_PCM] = out;
+        } else {
+            ERROR_MSG("System tone stream open failed with QAF module !!!");
+        }
     } else if ((flags & AUDIO_OUTPUT_FLAG_MAIN) && (flags & AUDIO_OUTPUT_FLAG_ASSOCIATED)) {
         if (is_main_active(qaf_mod) || is_dual_main_active(qaf_mod)) {
             ERROR_MSG("Dual Main or Main already active. So, Cannot open main and associated stream");
diff --git a/hal/audio_extn/usb.c b/hal/audio_extn/usb.c
index 5327973..7b0309b 100644
--- a/hal/audio_extn/usb.c
+++ b/hal/audio_extn/usb.c
@@ -53,7 +53,7 @@
 #define SAMPLE_RATE_11025         11025
 // Supported sample rates for USB
 static uint32_t supported_sample_rates[] =
-    {44100, 48000, 64000, 88200, 96000, 176400, 192000, 352800, 384000};
+    {8000, 11025, 16000, 22050, 32000, 44100, 48000, 64000, 88200, 96000, 176400, 192000, 352800, 384000};
 
 #define  MAX_SAMPLE_RATE_SIZE  sizeof(supported_sample_rates)/sizeof(supported_sample_rates[0])
 
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index a236ccd..c01e6f7 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -822,7 +822,7 @@
                                                 &adev->streams_output_cfg_list,
                                                 usecase->stream.out->devices,
                                                 usecase->stream.out->flags,
-                                                usecase->stream.out->format,
+                                                usecase->stream.out->hal_op_format,
                                                 usecase->stream.out->sample_rate,
                                                 usecase->stream.out->bit_width,
                                                 usecase->stream.out->channel_mask,
@@ -878,7 +878,7 @@
     char value[PROPERTY_VALUE_MAX] = {0};
     struct streams_io_cfg *s_info = NULL;
     struct listnode *node = NULL;
-    int direct_app_type = 0;
+    int bd_app_type = 0;
 
     ALOGV("%s: usecase->out_snd_device %s, usecase->in_snd_device %s, split_snd_device %s",
           __func__, platform_get_snd_device_name(usecase->out_snd_device),
@@ -983,11 +983,13 @@
          */
         list_for_each(node, &adev->streams_output_cfg_list) {
             s_info = node_to_item(node, struct streams_io_cfg, list);
-            if (s_info->flags.out_flags == AUDIO_OUTPUT_FLAG_DIRECT)
-                direct_app_type = s_info->app_type_cfg.app_type;
+            if (s_info->flags.out_flags == (AUDIO_OUTPUT_FLAG_BD |
+                                            AUDIO_OUTPUT_FLAG_DIRECT_PCM |
+                                            AUDIO_OUTPUT_FLAG_DIRECT))
+                bd_app_type = s_info->app_type_cfg.app_type;
         }
         if (usecase->stream.out->flags == AUDIO_OUTPUT_FLAG_INTERACTIVE)
-            app_type = direct_app_type;
+            app_type = bd_app_type;
         else
             app_type = usecase->stream.out->app_type_cfg.app_type;
         app_type_cfg[len++] = app_type;
@@ -1676,7 +1678,7 @@
     struct mixer_ctl *ctl;
     ALOGV("%s: buffer %s bytes %zd", __func__, buffer, bytes);
 #ifdef HDMI_PASSTHROUGH_ENABLED
-    if (audio_extn_is_dolby_format(out->format) &&
+    if (audio_extn_utils_is_dolby_format(out->format) &&
         /*TODO:Extend code to support DTS passthrough*/
         /*set compressed channel status bits*/
         audio_extn_passthru_is_passthrough_stream(out)){
@@ -2254,8 +2256,8 @@
 {
     int ret = -EINVAL, i = 0, j = 0;
 
-    if (mm_params == NULL && out != NULL) {
-        ALOGE("%s:: Invalid mix matrix params", __func__);
+    if (mm_params == NULL || out == NULL) {
+        ALOGE("%s:: Invalid mix matrix or out param", __func__);
         goto exit;
     }
 
@@ -2303,7 +2305,7 @@
     struct audio_usecase *usecase = NULL;
 
     if (mm_params == NULL || out == NULL) {
-        ALOGE("%s:: Invalid mix matrix params", __func__);
+        ALOGE("%s:: Invalid mix matrix or out param", __func__);
         goto exit;
     }
 
@@ -2314,11 +2316,10 @@
         goto exit;
 
     usecase = get_usecase_from_list(out->dev, out->usecase);
-    if (usecase == NULL) {
-        ALOGE("%s: Invalid usecase", __func__);
+    if (!usecase) {
+        ALOGE("%s: Get usecase list failed!", __func__);
         goto exit;
     }
-
     out->downmix_params.num_output_channels = mm_params->num_output_channels;
     out->downmix_params.num_input_channels = mm_params->num_input_channels;
 
@@ -2351,3 +2352,15 @@
 exit:
     return ret;
 }
+
+bool audio_extn_utils_is_dolby_format(audio_format_t format)
+{
+    if (format == AUDIO_FORMAT_AC3 ||
+            format == AUDIO_FORMAT_E_AC3 ||
+            format == AUDIO_FORMAT_E_AC3_JOC)
+        return true;
+    else
+        return false;
+}
+
+
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 6653f6a..d0c0cfa 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -327,6 +327,8 @@
     [USECASE_AUDIO_PLAYBACK_INTERACTIVE_STREAM6] = "audio-interactive-stream6",
     [USECASE_AUDIO_PLAYBACK_INTERACTIVE_STREAM7] = "audio-interactive-stream7",
     [USECASE_AUDIO_PLAYBACK_INTERACTIVE_STREAM8] = "audio-interactive-stream8",
+
+    [USECASE_AUDIO_EC_REF_LOOPBACK] = "ec-ref-audio-capture"
 };
 
 static const audio_usecase_t offload_usecases[] = {
@@ -930,6 +932,11 @@
                                               "true-native-mode");
             adev->native_playback_enabled = true;
         }
+        if ((snd_device == SND_DEVICE_IN_HANDSET_6MIC) &&
+            (audio_extn_ffv_get_stream() == adev->active_input)) {
+            ALOGD("%s: init ec ref loopback", __func__);
+            audio_extn_ffv_init_ec_ref_loopback(adev, snd_device);
+        }
     }
     return 0;
 }
@@ -993,7 +1000,11 @@
             disable_asrc_mode(adev);
             audio_route_apply_and_update_path(adev->audio_route, "hph-lowpower-mode");
         }
-
+        if ((snd_device == SND_DEVICE_IN_HANDSET_6MIC) &&
+            (audio_extn_ffv_get_stream() == adev->active_input)) {
+            ALOGD("%s: deinit ec ref loopback", __func__);
+            audio_extn_ffv_deinit_ec_ref_loopback(adev, snd_device);
+        }
         audio_extn_dev_arbi_release(snd_device);
         audio_extn_sound_trigger_update_device_status(snd_device,
                                         ST_EVENT_SND_DEVICE_FREE);
@@ -2049,14 +2060,14 @@
     int ret = 0;
     struct audio_usecase *uc_info;
     struct audio_device *adev = in->dev;
-
+    struct pcm_config config = in->config;
     int usecase = platform_update_usecase_from_source(in->source,in->usecase);
+
     if (get_usecase_from_list(adev, usecase) == NULL)
         in->usecase = usecase;
     ALOGD("%s: enter: stream(%p)usecase(%d: %s)",
           __func__, &in->stream, in->usecase, use_case_table[in->usecase]);
 
-
     if (CARD_STATUS_OFFLINE == in->card_status||
         CARD_STATUS_OFFLINE == adev->card_status) {
         ALOGW("in->card_status or adev->card_status offline, try again");
@@ -2143,12 +2154,16 @@
             flags |= PCM_MMAP | PCM_NOIRQ;
         }
 
+        if (audio_extn_ffv_get_stream() == in) {
+           ALOGD("%s: ffv stream, update pcm config", __func__);
+           audio_extn_ffv_update_pcm_config(&config);
+        }
         ALOGV("%s: Opening PCM device card_id(%d) device_id(%d), channels %d",
               __func__, adev->snd_card, in->pcm_device_id, in->config.channels);
 
         while (1) {
             in->pcm = pcm_open(adev->snd_card, in->pcm_device_id,
-                               flags, &in->config);
+                               flags, &config);
             if (in->pcm == NULL || !pcm_is_ready(in->pcm)) {
                 ALOGE("%s: %s", __func__, pcm_get_error(in->pcm));
                 if (in->pcm != NULL) {
@@ -2781,7 +2796,7 @@
                                              out->playback_started);
 
 #ifdef DS1_DOLBY_DDP_ENABLED
-        if (audio_extn_is_dolby_format(out->format))
+        if (audio_extn_utils_is_dolby_format(out->format))
             audio_extn_dolby_send_ddp_endp_params(adev);
 #endif
         if (!(audio_extn_passthru_is_passthrough_stream(out)) &&
@@ -3383,7 +3398,7 @@
         lock_output_stream(out);
         audio_extn_utils_update_stream_output_app_type_cfg(adev->platform,
                                                           &adev->streams_output_cfg_list,
-                                                          out->devices, out->flags, out->format,
+                                                          out->devices, out->flags, out->hal_op_format,
                                                           out->sample_rate, out->bit_width,
                                                           out->channel_mask, out->profile,
                                                           &out->app_type_cfg);
@@ -3755,13 +3770,13 @@
         goto exit;
     }
 
-    if (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) {
-        channels = platform_edid_get_max_channels(out->dev->platform);
-        if (audio_extn_passthru_is_enabled() &&
-            !out->is_iec61937_info_available &&
-            audio_extn_passthru_is_passthrough_stream(out)) {
-            audio_extn_passthru_update_stream_configuration(adev, out,
-                    buffer, bytes);
+    if ((out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL) &&
+         !out->is_iec61937_info_available) {
+
+        if (!audio_extn_passthru_is_passthrough_stream(out)) {
+            out->is_iec61937_info_available = true;
+        } else if (audio_extn_passthru_is_enabled()) {
+            audio_extn_passthru_update_stream_configuration(adev, out, buffer, bytes);
             out->is_iec61937_info_available = true;
 
             if((out->format == AUDIO_FORMAT_DTS) ||
@@ -3773,7 +3788,7 @@
                         out->is_iec61937_info_available = false;
                         ALOGD("iec61937 transmission info not yet updated retry");
                     }
-                } else {
+                } else if (!out->standby) {
                     /* if stream has started and after that there is
                      * stream config change (iec transmission config)
                      * then trigger select_device to update backend configuration.
@@ -3781,6 +3796,10 @@
                     out->stream_config_changed = true;
                     pthread_mutex_lock(&adev->lock);
                     select_devices(adev, out->usecase);
+                    if (!audio_extn_passthru_is_supported_backend_edid_cfg(adev, out)) {
+                        ret = -EINVAL;
+                        goto exit;
+                    }
                     pthread_mutex_unlock(&adev->lock);
                     out->stream_config_changed = false;
                     out->is_iec61937_info_available = true;
@@ -3826,6 +3845,13 @@
             audio_hw_send_gain_dep_calibration(last_known_cal_step);
             last_known_cal_step = -1;
         }
+
+        if ((out->is_iec61937_info_available == true) &&
+            (audio_extn_passthru_is_passthrough_stream(out))&&
+            (!audio_extn_passthru_is_supported_backend_edid_cfg(adev, out))) {
+            ret = -EINVAL;
+            goto exit;
+        }
     }
 
     if (adev->is_channel_status_set == false && (out->devices & AUDIO_DEVICE_OUT_AUX_DIGITAL)){
@@ -4263,10 +4289,10 @@
         lock_output_stream(out);
         if (out->offload_state == OFFLOAD_STATE_PAUSED) {
             stop_compressed_output_l(out);
-            out->written = 0;
         } else {
             ALOGW("%s called in invalid state %d", __func__, out->offload_state);
         }
+        out->written = 0;
         pthread_mutex_unlock(&out->lock);
         ALOGD("copl(%p):out of compress flush", out);
         return 0;
@@ -4752,6 +4778,8 @@
             ret = audio_extn_compr_cap_read(in, buffer, bytes);
         } else if (use_mmap) {
             ret = pcm_mmap_read(in->pcm, buffer, bytes);
+        } else if (audio_extn_ffv_get_stream() == in) {
+            ret = audio_extn_ffv_read(stream, buffer, bytes);
         } else {
             ret = pcm_read(in->pcm, buffer, bytes);
             /* data from DSP comes in 24_8 format, convert it to 8_24 */
@@ -5040,7 +5068,7 @@
     out->flags = flags;
     out->devices = devices;
     out->dev = adev;
-    format = out->format = config->format;
+    out->hal_op_format = out->hal_ip_format = format = out->format = config->format;
     out->sample_rate = config->sample_rate;
     out->channel_mask = config->channel_mask;
     if (out->channel_mask == AUDIO_CHANNEL_NONE)
@@ -5197,7 +5225,7 @@
         out->bit_width = CODEC_BACKEND_DEFAULT_BIT_WIDTH;
 
         out->compr_config.codec->id = get_snd_codec_id(config->offload_info.format);
-        if (audio_extn_is_dolby_format(config->offload_info.format)) {
+        if (audio_extn_utils_is_dolby_format(config->offload_info.format)) {
             audio_extn_dolby_send_ddp_endp_params(adev);
             audio_extn_dolby_set_dmid(adev);
         }
@@ -5469,7 +5497,7 @@
         out->bit_width = 16;
     audio_extn_utils_update_stream_output_app_type_cfg(adev->platform,
                                                 &adev->streams_output_cfg_list,
-                                                devices, out->flags, format, out->sample_rate,
+                                                devices, out->flags, out->hal_op_format, out->sample_rate,
                                                 out->bit_width, out->channel_mask, out->profile,
                                                 &out->app_type_cfg);
     if ((out->usecase == USECASE_AUDIO_PLAYBACK_PRIMARY) ||
@@ -6159,7 +6187,7 @@
             ret = -EINVAL;
             goto err_open;
         }
-        ALOGD("%s: created surround sound session succesfully",__func__);
+        ALOGD("%s: created multi-channel session succesfully",__func__);
     } else if (audio_extn_compr_cap_enabled() &&
             audio_extn_compr_cap_format_supported(config->format) &&
             (in->dev->mode != AUDIO_MODE_IN_COMMUNICATION)) {
@@ -6259,6 +6287,10 @@
         audio_extn_ssr_deinit();
     }
 
+    if (audio_extn_ffv_get_stream() == in) {
+        audio_extn_ffv_stream_deinit();
+    }
+
     if (audio_extn_compr_cap_enabled() &&
             audio_extn_compr_cap_format_supported(in->config.format))
         audio_extn_compr_cap_deinit();
@@ -6343,6 +6375,7 @@
         audio_extn_adsp_hdlr_deinit();
         audio_extn_snd_mon_deinit();
         audio_extn_hw_loopback_deinit(adev);
+        audio_extn_ffv_deinit();
         if (adev->device_cfg_params) {
             free(adev->device_cfg_params);
             adev->device_cfg_params = NULL;
@@ -6606,6 +6639,7 @@
     audio_extn_listen_init(adev, adev->snd_card);
     audio_extn_gef_init(adev);
     audio_extn_hw_loopback_init(adev);
+    audio_extn_ffv_init(adev);
 
     if (access(OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH, R_OK) == 0) {
         adev->offload_effects_lib = dlopen(OFFLOAD_EFFECTS_BUNDLE_LIBRARY_PATH, RTLD_NOW);
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index f0b7077..fda0672 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -179,6 +179,8 @@
     USECASE_AUDIO_PLAYBACK_INTERACTIVE_STREAM6,
     USECASE_AUDIO_PLAYBACK_INTERACTIVE_STREAM7,
     USECASE_AUDIO_PLAYBACK_INTERACTIVE_STREAM8,
+
+    USECASE_AUDIO_EC_REF_LOOPBACK,
     AUDIO_USECASE_MAX
 };
 
diff --git a/hal/audio_hw_extn_api.c b/hal/audio_hw_extn_api.c
index 09d83f4..4e49a83 100644
--- a/hal/audio_hw_extn_api.c
+++ b/hal/audio_hw_extn_api.c
@@ -376,6 +376,9 @@
         return -EINVAL;
     }
 
+    if (flags & AUDIO_OUTPUT_FLAG_DIRECT_PCM)
+        flags = (flags & ~AUDIO_OUTPUT_FLAG_DIRECT_PCM ) | AUDIO_OUTPUT_FLAG_DIRECT;
+
     ret = adev->qahwi_dev.base.open_output_stream(dev, handle, devices, flags,
                                                  config, stream_out, address);
     if (ret)
diff --git a/hal/msm8916/platform.c b/hal/msm8916/platform.c
index f8c0aba..6dfa0eb 100644
--- a/hal/msm8916/platform.c
+++ b/hal/msm8916/platform.c
@@ -393,7 +393,7 @@
                      {PLAYBACK_INTERACTIVE_STRM_DEVICE7, PLAYBACK_INTERACTIVE_STRM_DEVICE7},
     [USECASE_AUDIO_PLAYBACK_INTERACTIVE_STREAM8] =
                      {PLAYBACK_INTERACTIVE_STRM_DEVICE8, PLAYBACK_INTERACTIVE_STRM_DEVICE8},
-
+    [USECASE_AUDIO_EC_REF_LOOPBACK] = {-1, -1}, /* pcm id updated from platform info file */
 };
 
 /* Array to store sound devices */
@@ -537,6 +537,10 @@
     [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = "three-mic",
     [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = "quad-mic",
     [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = "headset-mic",
+    [SND_DEVICE_IN_HANDSET_6MIC] = "handset-6mic",
+    [SND_DEVICE_IN_HANDSET_8MIC] = "handset-8mic",
+    [SND_DEVICE_IN_EC_REF_LOOPBACK_MONO] = "ec-ref-loopback-mono",
+    [SND_DEVICE_IN_EC_REF_LOOPBACK_STEREO] = "ec-ref-loopback-stereo",
 };
 
 // Platform specific backend bit width table
@@ -679,6 +683,10 @@
     [SND_DEVICE_IN_UNPROCESSED_THREE_MIC] = 145,
     [SND_DEVICE_IN_UNPROCESSED_QUAD_MIC] = 146,
     [SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC] = 147,
+    [SND_DEVICE_IN_HANDSET_6MIC] = 4,
+    [SND_DEVICE_IN_HANDSET_8MIC] = 4,
+    [SND_DEVICE_IN_EC_REF_LOOPBACK_MONO] = 4,
+    [SND_DEVICE_IN_EC_REF_LOOPBACK_STEREO] = 4
 };
 
 struct name_to_index {
@@ -823,6 +831,10 @@
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_THREE_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_QUAD_MIC)},
     {TO_NAME_INDEX(SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_6MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_HANDSET_8MIC)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_EC_REF_LOOPBACK_MONO)},
+    {TO_NAME_INDEX(SND_DEVICE_IN_EC_REF_LOOPBACK_STEREO)},
 };
 
 static char * backend_tag_table[SND_DEVICE_MAX] = {0};
@@ -869,6 +881,7 @@
     {TO_NAME_INDEX(USECASE_AUDIO_SPKR_CALIB_RX)},
     {TO_NAME_INDEX(USECASE_AUDIO_PLAYBACK_AFE_PROXY)},
     {TO_NAME_INDEX(USECASE_AUDIO_RECORD_AFE_PROXY)},
+    {TO_NAME_INDEX(USECASE_AUDIO_EC_REF_LOOPBACK)},
 };
 
 #define NO_COLS 2
@@ -1986,6 +1999,8 @@
 {
     // support max to mono, example if max count is 3, usecase supports Three, dual and mono mic
     switch (my_data->max_mic_count) {
+        case 6:
+            my_data->source_mic_type |= SOURCE_HEX_MIC;
         case 4:
             my_data->source_mic_type |= SOURCE_QUAD_MIC;
         case 3:
@@ -2184,7 +2199,9 @@
     be_dai_name_table = NULL;
 
     property_get("ro.vendor.audio.sdk.fluencetype", my_data->fluence_cap, "");
-    if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
+    if (!strncmp("fluenceffv", my_data->fluence_cap, sizeof("fluenceffv"))) {
+        my_data->fluence_type = FLUENCE_HEX_MIC | FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
+    } else if (!strncmp("fluencepro", my_data->fluence_cap, sizeof("fluencepro"))) {
         my_data->fluence_type = FLUENCE_QUAD_MIC | FLUENCE_DUAL_MIC;
     } else if (!strncmp("fluence", my_data->fluence_cap, sizeof("fluence"))) {
         my_data->fluence_type = FLUENCE_DUAL_MIC;
@@ -2432,6 +2449,7 @@
 
     /* Read one time ssr property */
     audio_extn_ssr_update_enabled();
+    audio_extn_ffv_update_enabled();
     audio_extn_spkr_prot_init(adev);
 
     /* init dap hal */
@@ -2679,6 +2697,10 @@
     if (snd_device >= SND_DEVICE_MIN && snd_device < SND_DEVICE_MAX) {
         strlcpy(device_name, device_table[snd_device], DEVICE_NAME_MAX_SIZE);
         hw_info_append_hw_type(my_data->hw_info, snd_device, device_name);
+
+        if ((snd_device == SND_DEVICE_IN_EC_REF_LOOPBACK_MONO) ||
+            (snd_device == SND_DEVICE_IN_EC_REF_LOOPBACK_STEREO))
+            audio_extn_ffv_append_ec_ref_dev_name(device_name);
     } else {
         strlcpy(device_name, "", DEVICE_NAME_MAX_SIZE);
         return -EINVAL;
@@ -2835,7 +2857,9 @@
     int ret = 0;
     struct platform_data *my_data = (struct platform_data *)platform;
 
-    if (my_data->fluence_type == FLUENCE_QUAD_MIC) {
+    if (my_data->fluence_type == FLUENCE_HEX_MIC) {
+        strlcpy(value, "hexmic", len);
+    } else if (my_data->fluence_type == FLUENCE_QUAD_MIC) {
         strlcpy(value, "quadmic", len);
     } else if (my_data->fluence_type == FLUENCE_DUAL_MIC) {
         strlcpy(value, "dualmic", len);
@@ -4288,9 +4312,13 @@
         }
     } else if (source == AUDIO_SOURCE_MIC) {
         if (in_device & AUDIO_DEVICE_IN_BUILTIN_MIC &&
-                channel_count == 1 ) {
+                channel_count == 1) {
             if(my_data->fluence_in_audio_rec) {
-                if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
+                if ((my_data->fluence_type & FLUENCE_HEX_MIC) &&
+                    (my_data->source_mic_type & SOURCE_HEX_MIC) &&
+                    (audio_extn_ffv_get_stream() == adev->active_input)) {
+                    snd_device = audio_extn_ffv_get_capture_snd_device();
+                } else if ((my_data->fluence_type & FLUENCE_QUAD_MIC) &&
                     (my_data->source_mic_type & SOURCE_QUAD_MIC)) {
                     snd_device = SND_DEVICE_IN_HANDSET_QMIC;
                     platform_set_echo_reference(adev, true, out_device);
@@ -4781,6 +4809,7 @@
     audio_extn_usb_set_sidetone_gain(parms, value, len);
     audio_extn_hfp_set_parameters(my_data->adev, parms);
     true_32_bit_set_params(parms, value, len);
+    audio_extn_ffv_set_parameters(my_data->adev, parms);
     ALOGV("%s: exit with code(%d)", __func__, ret);
     return ret;
 }
@@ -5383,49 +5412,68 @@
             char *rate_str = NULL;
             struct  mixer_ctl *ctl = NULL;
 
-            switch (sample_rate) {
-            case 32000:
-                if (passthrough_enabled) {
-                    rate_str = "KHZ_32";
+            if (backend_idx == USB_AUDIO_RX_BACKEND ||
+                    backend_idx == USB_AUDIO_TX_BACKEND) {
+                switch (sample_rate) {
+                case 32000:
+                        rate_str = "KHZ_32";
+                        break;
+                case 8000:
+                        rate_str = "KHZ_8";
+                        break;
+                case 11025:
+                        rate_str = "HZ_11P025";
+                        break;
+                case 16000:
+                        rate_str = "KHZ_16";
+                        break;
+                case 22050:
+                        rate_str = "KHZ_22P05";
+                        break;
+                }
+            }
+
+            if (rate_str == NULL) {
+                switch (sample_rate) {
+                case 32000:
+                    if (passthrough_enabled) {
+                        rate_str = "KHZ_32";
+                        break;
+                    }
+                case 48000:
+                    rate_str = "KHZ_48";
+                    break;
+                case 44100:
+                    rate_str = "KHZ_44P1";
+                    break;
+                case 64000:
+                case 96000:
+                    rate_str = "KHZ_96";
+                    break;
+                case 88200:
+                    rate_str = "KHZ_88P2";
+                    break;
+                case 176400:
+                    rate_str = "KHZ_176P4";
+                    break;
+                case 192000:
+                    rate_str = "KHZ_192";
+                    break;
+                case 352800:
+                    rate_str = "KHZ_352P8";
+                    break;
+                case 384000:
+                    rate_str = "KHZ_384";
+                    break;
+                case 144000:
+                    if (passthrough_enabled) {
+                        rate_str = "KHZ_144";
+                        break;
+                    }
+                default:
+                    rate_str = "KHZ_48";
                     break;
                 }
-            case 8000:
-            case 11025:
-            case 16000:
-            case 22050:
-            case 48000:
-                rate_str = "KHZ_48";
-                break;
-            case 44100:
-                rate_str = "KHZ_44P1";
-                break;
-            case 64000:
-            case 96000:
-                rate_str = "KHZ_96";
-                break;
-            case 88200:
-                rate_str = "KHZ_88P2";
-            break;
-            case 176400:
-                rate_str = "KHZ_176P4";
-                break;
-            case 192000:
-                rate_str = "KHZ_192";
-                break;
-            case 352800:
-                rate_str = "KHZ_352P8";
-                break;
-            case 384000:
-                rate_str = "KHZ_384";
-                break;
-            case 144000:
-                if (passthrough_enabled) {
-                    rate_str = "KHZ_144";
-                    break;
-                }
-            default:
-                rate_str = "KHZ_48";
-                break;
             }
 
             ctl = mixer_get_ctl_by_name(adev->mixer,
@@ -5545,6 +5593,33 @@
 }
 
 /*
+ * Get the backend configuration for current snd device
+ */
+int platform_get_codec_backend_cfg(struct audio_device* adev,
+                         snd_device_t snd_device,
+                         struct audio_backend_cfg *backend_cfg)
+{
+    int backend_idx = platform_get_backend_index(snd_device);
+    struct platform_data *my_data = (struct platform_data *)adev->platform;
+
+    backend_cfg->bit_width = my_data->current_backend_cfg[backend_idx].bit_width;
+    backend_cfg->sample_rate =
+                       my_data->current_backend_cfg[backend_idx].sample_rate;
+    backend_cfg->channels =
+                       my_data->current_backend_cfg[backend_idx].channels;
+    backend_cfg->format =
+                       my_data->current_backend_cfg[backend_idx].format;
+
+    ALOGV("%s:becf: afe: bitwidth %d, samplerate %d channels %d format %d"
+          ", backend_idx %d device (%s)", __func__,  backend_cfg->bit_width,
+          backend_cfg->sample_rate, backend_cfg->channels, backend_cfg->format,
+          backend_idx, platform_get_snd_device_name(snd_device));
+
+   return 0;
+}
+
+
+/*
  *Validate the selected bit_width, sample_rate and channels using the edid
  *of the connected sink device.
  */
@@ -7186,6 +7261,20 @@
     }
 }
 
+int platform_get_ec_ref_loopback_snd_device(int channel_count)
+{
+    snd_device_t snd_device;
+
+    if (channel_count == 1)
+        snd_device = SND_DEVICE_IN_EC_REF_LOOPBACK_MONO;
+    else if (channel_count == 2)
+        snd_device = SND_DEVICE_IN_EC_REF_LOOPBACK_STEREO;
+    else
+        snd_device = SND_DEVICE_NONE;
+
+    return snd_device;
+}
+
 int platform_set_sidetone(struct audio_device *adev,
                           snd_device_t out_snd_device,
                           bool enable,
diff --git a/hal/msm8916/platform.h b/hal/msm8916/platform.h
index a53a38f..13247ff 100644
--- a/hal/msm8916/platform.h
+++ b/hal/msm8916/platform.h
@@ -25,6 +25,7 @@
     FLUENCE_NONE,
     FLUENCE_DUAL_MIC = 0x1,
     FLUENCE_QUAD_MIC = 0x2,
+    FLUENCE_HEX_MIC = 0x4,
 };
 
 enum {
@@ -37,6 +38,7 @@
     SOURCE_DUAL_MIC  = 0x2,            /* Target contains 2 mics */
     SOURCE_THREE_MIC = 0x4,            /* Target contains 3 mics */
     SOURCE_QUAD_MIC  = 0x8,            /* Target contains 4 mics */
+    SOURCE_HEX_MIC   = 0x16,           /* Target contains 6 mics */
 };
 
 enum {
@@ -222,6 +224,10 @@
     SND_DEVICE_IN_UNPROCESSED_THREE_MIC,
     SND_DEVICE_IN_UNPROCESSED_QUAD_MIC,
     SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC,
+    SND_DEVICE_IN_HANDSET_6MIC,
+    SND_DEVICE_IN_HANDSET_8MIC,
+    SND_DEVICE_IN_EC_REF_LOOPBACK_MONO,
+    SND_DEVICE_IN_EC_REF_LOOPBACK_STEREO,
     SND_DEVICE_IN_END,
 
     SND_DEVICE_MAX = SND_DEVICE_IN_END,
@@ -438,12 +444,4 @@
     char interface_name[100];
 };
 
-struct audio_backend_cfg {
-    unsigned int   sample_rate;
-    unsigned int   channels;
-    unsigned int   bit_width;
-    bool           passthrough_enabled;
-    audio_format_t format;
-};
-
 #endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/msm8974/platform.c b/hal/msm8974/platform.c
index ec99fe3..61ef223 100644
--- a/hal/msm8974/platform.c
+++ b/hal/msm8974/platform.c
@@ -5259,49 +5259,68 @@
             char *rate_str = NULL;
             struct  mixer_ctl *ctl = NULL;
 
-            switch (sample_rate) {
-            case 32000:
-                if (passthrough_enabled) {
-                    rate_str = "KHZ_32";
+            if (backend_idx == USB_AUDIO_RX_BACKEND ||
+                    backend_idx == USB_AUDIO_TX_BACKEND) {
+                switch (sample_rate) {
+                case 32000:
+                        rate_str = "KHZ_32";
+                        break;
+                case 8000:
+                        rate_str = "KHZ_8";
+                        break;
+                case 11025:
+                        rate_str = "HZ_11P025";
+                        break;
+                case 16000:
+                        rate_str = "KHZ_16";
+                        break;
+                case 22050:
+                        rate_str = "KHZ_22P05";
+                        break;
+                }
+            }
+
+            if (rate_str == NULL) {
+                switch (sample_rate) {
+                case 32000:
+                    if (passthrough_enabled) {
+                        rate_str = "KHZ_32";
+                        break;
+                    }
+                case 48000:
+                    rate_str = "KHZ_48";
+                    break;
+                case 44100:
+                    rate_str = "KHZ_44P1";
+                    break;
+                case 64000:
+                case 96000:
+                    rate_str = "KHZ_96";
+                    break;
+                case 88200:
+                    rate_str = "KHZ_88P2";
+                    break;
+                case 176400:
+                    rate_str = "KHZ_176P4";
+                    break;
+                case 192000:
+                    rate_str = "KHZ_192";
+                    break;
+                case 352800:
+                    rate_str = "KHZ_352P8";
+                    break;
+                case 384000:
+                    rate_str = "KHZ_384";
+                    break;
+                case 144000:
+                    if (passthrough_enabled) {
+                        rate_str = "KHZ_144";
+                        break;
+                    }
+                default:
+                    rate_str = "KHZ_48";
                     break;
                 }
-            case 8000:
-            case 11025:
-            case 16000:
-            case 22050:
-            case 48000:
-                rate_str = "KHZ_48";
-                break;
-            case 44100:
-                rate_str = "KHZ_44P1";
-                break;
-            case 64000:
-            case 96000:
-                rate_str = "KHZ_96";
-                break;
-            case 88200:
-                rate_str = "KHZ_88P2";
-                break;
-            case 176400:
-                rate_str = "KHZ_176P4";
-                break;
-            case 192000:
-                rate_str = "KHZ_192";
-                break;
-            case 352800:
-                rate_str = "KHZ_352P8";
-                break;
-            case 384000:
-                rate_str = "KHZ_384";
-                break;
-            case 144000:
-                if (passthrough_enabled) {
-                    rate_str = "KHZ_144";
-                    break;
-                }
-           default:
-                rate_str = "KHZ_48";
-                break;
             }
 
             ctl = mixer_get_ctl_by_name(adev->mixer,
@@ -5420,6 +5439,32 @@
 }
 
 /*
+ * Get the backend configuration for current snd device
+ */
+int platform_get_codec_backend_cfg(struct audio_device* adev,
+                         snd_device_t snd_device,
+                         struct audio_backend_cfg *backend_cfg)
+{
+    int backend_idx = platform_get_backend_index(snd_device);
+    struct platform_data *my_data = (struct platform_data *)adev->platform;
+
+    backend_cfg->bit_width = my_data->current_backend_cfg[backend_idx].bit_width;
+    backend_cfg->sample_rate =
+                       my_data->current_backend_cfg[backend_idx].sample_rate;
+    backend_cfg->channels =
+                       my_data->current_backend_cfg[backend_idx].channels;
+    backend_cfg->format =
+                       my_data->current_backend_cfg[backend_idx].format;
+
+    ALOGV("%s:becf: afe: bitwidth %d, samplerate %d channels %d format %d"
+          ", backend_idx %d device (%s)", __func__,  backend_cfg->bit_width,
+          backend_cfg->sample_rate, backend_cfg->channels, backend_cfg->format,
+          backend_idx, platform_get_snd_device_name(snd_device));
+
+   return 0;
+}
+
+/*
  *Validate the selected bit_width, sample_rate and channels using the edid
  *of the connected sink device.
  */
diff --git a/hal/msm8974/platform.h b/hal/msm8974/platform.h
index b5bbbdf..ba1a195 100644
--- a/hal/msm8974/platform.h
+++ b/hal/msm8974/platform.h
@@ -25,6 +25,7 @@
     FLUENCE_NONE,
     FLUENCE_DUAL_MIC = 0x1,
     FLUENCE_QUAD_MIC = 0x2,
+    FLUENCE_HEX_MIC = 0x4,
 };
 
 enum {
@@ -37,6 +38,7 @@
     SOURCE_DUAL_MIC  = 0x2,            /* Target contains 2 mics */
     SOURCE_THREE_MIC = 0x4,            /* Target contains 3 mics */
     SOURCE_QUAD_MIC  = 0x8,            /* Target contains 4 mics */
+    SOURCE_HEX_MIC   = 0x16,           /* Target contains 6 mics */
 };
 
 enum {
@@ -222,6 +224,10 @@
     SND_DEVICE_IN_UNPROCESSED_THREE_MIC,
     SND_DEVICE_IN_UNPROCESSED_QUAD_MIC,
     SND_DEVICE_IN_UNPROCESSED_HEADSET_MIC,
+    SND_DEVICE_IN_HANDSET_6MIC,
+    SND_DEVICE_IN_HANDSET_8MIC,
+    SND_DEVICE_IN_EC_REF_LOOPBACK_MONO,
+    SND_DEVICE_IN_EC_REF_LOOPBACK_STEREO,
     SND_DEVICE_IN_END,
 
     SND_DEVICE_MAX = SND_DEVICE_IN_END,
@@ -556,12 +562,4 @@
     char interface_name[100];
 };
 
-struct audio_backend_cfg {
-    unsigned int   sample_rate;
-    unsigned int   channels;
-    unsigned int   bit_width;
-    bool           passthrough_enabled;
-    audio_format_t format;
-};
-
 #endif // QCOM_AUDIO_PLATFORM_H
diff --git a/hal/platform_api.h b/hal/platform_api.h
index 6f8cf7e..924c1a4 100644
--- a/hal/platform_api.h
+++ b/hal/platform_api.h
@@ -37,6 +37,14 @@
     ACDB_EXTN,
 } caller_t;
 
+struct audio_backend_cfg {
+    unsigned int   sample_rate;
+    unsigned int   channels;
+    unsigned int   bit_width;
+    bool           passthrough_enabled;
+    audio_format_t format;
+};
+
 struct amp_db_and_gain_table {
     float amp;
     float db;
@@ -153,6 +161,9 @@
 
 struct audio_offload_info_t;
 uint32_t platform_get_compress_offload_buffer_size(audio_offload_info_t* info);
+int platform_get_codec_backend_cfg(struct audio_device* adev,
+                                   snd_device_t snd_device,
+                                   struct audio_backend_cfg *backend_cfg);
 
 bool platform_check_and_set_codec_backend_cfg(struct audio_device* adev,
                    struct audio_usecase *usecase, snd_device_t snd_device);
@@ -239,4 +250,5 @@
 int platform_get_max_codec_backend();
 int platform_get_mmap_data_fd(void *platform, int dev, int dir,
                                int *fd, uint32_t *size);
+int platform_get_ec_ref_loopback_snd_device(int channel_count);
 #endif // AUDIO_PLATFORM_API_H
diff --git a/mm-audio/aenc-aac/qdsp6/Android.mk b/mm-audio/aenc-aac/qdsp6/Android.mk
index c817181..40e6744 100644
--- a/mm-audio/aenc-aac/qdsp6/Android.mk
+++ b/mm-audio/aenc-aac/qdsp6/Android.mk
@@ -42,6 +42,29 @@
 
 include $(BUILD_SHARED_LIBRARY)
 
+# ---------------------------------------------------------------------------------
+#             Make the apps-test (mm-aenc-omxaac-test)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+mm-aac-enc-test-inc    := $(LOCAL_PATH)/inc
+mm-aac-enc-test-inc    += $(LOCAL_PATH)/test
+mm-aac-enc-test-inc    += $(TARGET_OUT_HEADERS)/mm-audio/audio-alsa
+mm-aac-enc-test-inc    += $(TARGET_OUT_HEADERS)/mm-core/omxcore
+
+LOCAL_MODULE            := mm-aenc-omxaac-test
+LOCAL_MODULE_TAGS       := optional
+LOCAL_CFLAGS            := $(libOmxAacEnc-def)
+LOCAL_C_INCLUDES        := $(mm-aac-enc-test-inc)
+LOCAL_PRELINK_MODULE    := false
+LOCAL_SHARED_LIBRARIES  := libmm-omxcore
+LOCAL_SHARED_LIBRARIES  += libOmxAacEnc
+LOCAL_SHARED_LIBRARIES  += libaudioalsa
+LOCAL_SRC_FILES         := test/omx_aac_enc_test.c
+
+include $(BUILD_EXECUTABLE)
+
 endif
 
 # ---------------------------------------------------------------------------------
diff --git a/mm-audio/aenc-aac/qdsp6/Makefile b/mm-audio/aenc-aac/qdsp6/Makefile
index e9da876..5421d45 100644
--- a/mm-audio/aenc-aac/qdsp6/Makefile
+++ b/mm-audio/aenc-aac/qdsp6/Makefile
@@ -39,7 +39,7 @@
 # ---------------------------------------------------------------------------------
 #					BUILD
 # ---------------------------------------------------------------------------------
-all: libOmxAacEnc.so.$(LIBVER)
+all: libOmxAacEnc.so.$(LIBVER) mm-aenc-omxaac-test
 
 install:
 	echo "intalling aenc-aac in $(DESTDIR)"
@@ -49,7 +49,8 @@
 	install -m 555 libOmxAacEnc.so.$(LIBVER) $(LIBINSTALLDIR)
 	cd $(LIBINSTALLDIR) && ln -s libOmxAacEnc.so.$(LIBVER) libOmxAacEnc.so.$(LIBMAJOR)
 	cd $(LIBINSTALLDIR) && ln -s libOmxAacEnc.so.$(LIBMAJOR) libOmxAacEnc.so
-
+	install -m 555 mm-aenc-omxaac-test $(BININSTALLDIR)
+	
 # ---------------------------------------------------------------------------------
 #				COMPILE LIBRARY
 # ---------------------------------------------------------------------------------
@@ -64,5 +65,17 @@
 	$(CC) $(CPPFLAGS) $(CFLAGS_SO) $(LDFLAGS_SO) -Wl,-soname,libOmxAacEnc.so.$(LIBMAJOR) -o $@ $^ $(LDFLAGS) $(LDLIBS)
 
 # ---------------------------------------------------------------------------------
+#				COMPILE TEST APP
+# ---------------------------------------------------------------------------------
+TEST_LDLIBS := -lpthread
+TEST_LDLIBS += -ldl
+TEST_LDLIBS += -lOmxCore
+
+TEST_SRCS := test/omx_aac_enc_test.c
+
+mm-aenc-omxaac-test: libOmxAacEnc.so.$(LIBVER) $(TEST_SRCS)
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $^ $(TEST_LDLIBS)
+
+# ---------------------------------------------------------------------------------
 #					END
 # ---------------------------------------------------------------------------------
diff --git a/mm-audio/aenc-aac/qdsp6/Makefile.am b/mm-audio/aenc-aac/qdsp6/Makefile.am
index 2f63d0a..a79ce70 100644
--- a/mm-audio/aenc-aac/qdsp6/Makefile.am
+++ b/mm-audio/aenc-aac/qdsp6/Makefile.am
@@ -26,3 +26,8 @@
 libOmxAacEnc_la_CPPFLAGS = $(AM_CPPFLAGS) -fPIC $(GLIB_CFLAGS) -include glib.h -Dstrlcpy=g_strlcpy
 libOmxAacEnc_la_LIBADD = -lmm-omxcore -lstdc++ -lpthread $(GLIB_LIBS) -ldl -llog
 libOmxAacEnc_la_LDFLAGS = -shared $(GLIB_LIBS) -avoid-version $(OMXAUDIO_LIBRARY_VERSION)
+
+bin_PROGRAMS = mm-aenc-omxaac-test
+mm_aenc_omxaac_test_SOURCES = ./test/omx_aac_enc_test.c
+mm_aenc_omxaac_test_CFLAGS = -include errno.h -include limits.h
+mm_aenc_omxaac_test_LDADD = -lmm-omxcore -ldl -lpthread -llog libOmxAacEnc.la
diff --git a/mm-audio/aenc-aac/qdsp6/test/omx_aac_enc_test.c b/mm-audio/aenc-aac/qdsp6/test/omx_aac_enc_test.c
new file mode 100644
index 0000000..b4b0be8
--- /dev/null
+++ b/mm-audio/aenc-aac/qdsp6/test/omx_aac_enc_test.c
@@ -0,0 +1,1367 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2014, 2016-2017 The Linux Foundation. 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.
+    * Neither the name of The Linux Foundation nor
+      the names of its contributors may be used to endorse or promote
+      products derived from this software without specific prior written
+      permission.
+
+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, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT 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.
+--------------------------------------------------------------------------*/
+
+
+/*
+    An Open max test application ....
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include "OMX_Core.h"
+#include "OMX_Component.h"
+#include "pthread.h"
+#include <signal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include<unistd.h>
+#include<string.h>
+#include <pthread.h>
+#include "QOMX_AudioExtensions.h"
+#include "QOMX_AudioIndexExtensions.h"
+#ifdef AUDIOV2 
+#include "control.h" 
+#endif
+#include <linux/ioctl.h>
+
+typedef unsigned char uint8;
+typedef unsigned char byte;
+typedef unsigned int  uint32;
+typedef unsigned int  uint16;
+#define AUDAAC_MAX_ADIF_HEADER_LENGTH 64
+/* ADTS variable frame header, frame length field  */
+#define AUDAAC_ADTS_FRAME_LENGTH_SIZE    13
+QOMX_AUDIO_STREAM_INFO_DATA streaminfoparam;
+void audaac_rec_install_bits
+(
+  uint8   *input,
+  byte    num_bits_reqd,
+  uint32  value,
+  uint16  *hdr_bit_index
+);
+
+/* maximum ADTS frame header length                */
+#define AUDAAC_MAX_ADTS_HEADER_LENGTH 7
+void audaac_rec_install_adts_header_variable (uint16  byte_num);
+void Release_Encoder();
+
+#ifdef AUDIOV2
+unsigned short session_id;
+int device_id;
+int control = 0;
+const char *device="handset_tx";
+#define DIR_TX 2
+#endif
+
+#define AACHDR_LAYER_SIZE             2
+#define AACHDR_CRC_SIZE               1
+#define AAC_PROFILE_SIZE              2
+#define AAC_SAMPLING_FREQ_INDEX_SIZE  4
+#define AAC_ORIGINAL_COPY_SIZE        1
+#define AAC_HOME_SIZE                 1
+
+#define MIN(A,B)    (((A) < (B))?(A):(B))
+
+uint8   audaac_header[AUDAAC_MAX_ADTS_HEADER_LENGTH];
+unsigned int audaac_hdr_bit_index;
+
+
+FILE *F1 = NULL;
+
+uint32_t aac_samplerate = 0;
+uint32_t pcm_samplerate = 0;
+uint32_t aac_channels = 0;
+uint32_t pcm_channels = 0;
+uint32_t bitrate = 128000;
+uint32_t pcmplayback = 0;
+uint32_t tunnel      = 0;
+uint32_t rectime     = 0;
+uint32_t format = 1;
+uint32_t profile = OMX_AUDIO_AACObjectLC;
+#define DEBUG_PRINT printf
+unsigned to_idle_transition = 0;
+
+typedef enum adts_sample_index__ {
+
+ADTS_SAMPLE_INDEX_96000=0x0,
+ADTS_SAMPLE_INDEX_88200,
+ADTS_SAMPLE_INDEX_64000,
+ADTS_SAMPLE_INDEX_48000,
+ADTS_SAMPLE_INDEX_44100,
+ADTS_SAMPLE_INDEX_32000,
+ADTS_SAMPLE_INDEX_24000,
+ADTS_SAMPLE_INDEX_22050,
+ADTS_SAMPLE_INDEX_16000,
+ADTS_SAMPLE_INDEX_12000,
+ADTS_SAMPLE_INDEX_11025,
+ADTS_SAMPLE_INDEX_8000,
+ADTS_SAMPLE_INDEX_7350,
+ADTS_SAMPLE_INDEX_MAX
+
+}adts_sample_index;
+/************************************************************************/
+/*                #DEFINES                            */
+/************************************************************************/
+#define false 0
+#define true 1
+
+#define CONFIG_VERSION_SIZE(param) \
+    param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\
+    param.nSize = sizeof(param);
+
+#define FAILED(result) (result != OMX_ErrorNone)
+
+#define SUCCEEDED(result) (result == OMX_ErrorNone)
+
+/************************************************************************/
+/*                GLOBAL DECLARATIONS                     */
+/************************************************************************/
+
+pthread_mutex_t lock;
+pthread_cond_t cond;
+pthread_mutex_t elock;
+pthread_cond_t econd;
+pthread_cond_t fcond;
+pthread_mutex_t etb_lock;
+pthread_mutex_t etb_lock1;
+pthread_cond_t etb_cond;
+FILE * inputBufferFile;
+FILE * outputBufferFile;
+OMX_PARAM_PORTDEFINITIONTYPE inputportFmt;
+OMX_PARAM_PORTDEFINITIONTYPE outputportFmt;
+OMX_AUDIO_PARAM_AACPROFILETYPE aacparam;
+OMX_AUDIO_PARAM_PCMMODETYPE    pcmparam;
+OMX_PORT_PARAM_TYPE portParam;
+OMX_ERRORTYPE error;
+
+
+
+
+#define ID_RIFF 0x46464952
+#define ID_WAVE 0x45564157
+#define ID_FMT  0x20746d66
+#define ID_DATA 0x61746164
+
+#define FORMAT_PCM 1
+
+struct wav_header {
+  uint32_t riff_id;
+  uint32_t riff_sz;
+  uint32_t riff_fmt;
+  uint32_t fmt_id;
+  uint32_t fmt_sz;
+  uint16_t audio_format;
+  uint16_t num_channels;
+  uint32_t sample_rate;
+  uint32_t byte_rate;       /* sample_rate * num_channels * bps / 8 */
+  uint16_t block_align;     /* num_channels * bps / 8 */
+  uint16_t bits_per_sample;
+  uint32_t data_id;
+  uint32_t data_sz;
+};
+struct enc_meta_out{
+        unsigned int offset_to_frame;
+        unsigned int frame_size;
+        unsigned int encoded_pcm_samples;
+        unsigned int msw_ts;
+        unsigned int lsw_ts;
+        unsigned int nflags;
+} __attribute__ ((packed));
+
+static int totaldatalen = 0;
+/************************************************************************/
+/*                GLOBAL INIT                    */
+/************************************************************************/
+
+unsigned int input_buf_cnt = 0;
+unsigned int output_buf_cnt = 0;
+int used_ip_buf_cnt = 0;
+volatile int event_is_done = 0;
+volatile int ebd_event_is_done = 0;
+volatile int fbd_event_is_done = 0;
+volatile int etb_event_is_done = 0;
+int ebd_cnt;
+int bInputEosReached = 0;
+int bOutputEosReached = 0;
+int bInputEosReached_tunnel = 0;
+static int etb_done = 0;
+int bFlushing = false;
+int bPause    = false;
+const char *in_filename;
+const char *out_filename;
+
+int timeStampLfile = 0;
+int timestampInterval = 100;
+
+//* OMX Spec Version supported by the wrappers. Version = 1.1 */
+const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101;
+OMX_COMPONENTTYPE* aac_enc_handle = 0;
+
+OMX_BUFFERHEADERTYPE  **pInputBufHdrs = NULL;
+OMX_BUFFERHEADERTYPE  **pOutputBufHdrs = NULL;
+
+/************************************************************************/
+/*                GLOBAL FUNC DECL                        */
+/************************************************************************/
+int Init_Encoder(char*);
+int Play_Encoder();
+OMX_STRING aud_comp;
+/**************************************************************************/
+/*                STATIC DECLARATIONS                       */
+/**************************************************************************/
+
+static int open_audio_file ();
+static int Read_Buffer(OMX_BUFFERHEADERTYPE  *pBufHdr );
+static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *aac_enc_handle,
+                                       OMX_BUFFERHEADERTYPE  ***pBufHdrs,
+                                       OMX_U32 nPortIndex,
+                                       unsigned int bufCntMin, unsigned int bufSize);
+
+
+static OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                                  OMX_IN OMX_PTR pAppData,
+                                  OMX_IN OMX_EVENTTYPE eEvent,
+                                  OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
+                                  OMX_IN OMX_PTR pEventData);
+static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                     OMX_IN OMX_PTR pAppData,
+                                     OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+static OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                     OMX_IN OMX_PTR pAppData,
+                                     OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+static OMX_ERRORTYPE  parse_pcm_header();
+
+typedef enum {
+    UINTMAX = 1,
+    UCHARMAX,
+    USHRTMAX
+}datatype;
+
+int get_input_and_validate(char *input, datatype type)
+{
+    unsigned long int value = 0;
+    char *ptr = NULL;
+    int status = 0;
+
+    errno = 0;
+    ptr = (char *)malloc(strlen(input) + 1);
+    if (ptr == NULL) {
+        DEBUG_PRINT("Low memory\n");
+        status = -1;
+        goto exit;
+    }
+    if (input == NULL){
+        DEBUG_PRINT("No input is given\n");
+        status = -1;
+        goto exit;
+    }
+    /* Check for negative input */
+    if (*input == '-') {
+        DEBUG_PRINT("Negative Number is not allowed\n");
+        status = -1;
+        goto exit;
+    }
+    /* Convert string to unsigned long int */
+    value = strtoul(input, &ptr, 10);
+    if (errno != 0){
+        perror("strtoul");
+        status = errno;
+        goto exit;
+    }
+    /* check if number input is zero or string or string##number or viceversa */
+    if (value == 0 || *ptr != '\0'){
+        DEBUG_PRINT("Input is string+number or Zero or string = %s\n", input);
+        status = -1;
+        goto exit;
+    }
+    /* check for out of range */
+    switch(type) {
+    case 1 :if (value > UINT_MAX) {
+                DEBUG_PRINT("Input is Out of range\n");
+                status = -1;
+            }
+            break;
+    case 2 :if (value > UCHAR_MAX) {
+                DEBUG_PRINT("Input is Out of range\n");
+                status = -1;
+            }
+            break;
+    case 3 :if (value > USHRT_MAX) {
+                DEBUG_PRINT("Input is Out of range\n");
+                status = -1;
+            }
+            break;
+    }
+exit:
+    if (status != 0)
+        exit(0);
+    return value;
+}
+
+void wait_for_event(void)
+{
+    pthread_mutex_lock(&lock);
+    DEBUG_PRINT("%s: event_is_done=%d", __FUNCTION__, event_is_done);
+    while (event_is_done == 0) {
+        pthread_cond_wait(&cond, &lock);
+    }
+    event_is_done = 0;
+    pthread_mutex_unlock(&lock);
+}
+
+void event_complete(void )
+{
+    pthread_mutex_lock(&lock);
+    if (event_is_done == 0) {
+        event_is_done = 1;
+        pthread_cond_broadcast(&cond);
+    }
+    pthread_mutex_unlock(&lock);
+}
+
+void etb_wait_for_event(void)
+{
+    pthread_mutex_lock(&etb_lock1);
+    DEBUG_PRINT("%s: etb_event_is_done=%d", __FUNCTION__, etb_event_is_done);
+    while (etb_event_is_done == 0) {
+        pthread_cond_wait(&etb_cond, &etb_lock1);
+    }
+    etb_event_is_done = 0;
+    pthread_mutex_unlock(&etb_lock1);
+}
+
+void etb_event_complete(void )
+{
+    pthread_mutex_lock(&etb_lock1);
+    if (etb_event_is_done == 0) {
+        etb_event_is_done = 1;
+        pthread_cond_broadcast(&etb_cond);
+    }
+    pthread_mutex_unlock(&etb_lock1);
+}
+
+
+OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                           OMX_IN OMX_PTR pAppData,
+                           OMX_IN OMX_EVENTTYPE eEvent,
+                           OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
+                           OMX_IN OMX_PTR pEventData)
+{
+    DEBUG_PRINT("Function %s \n", __FUNCTION__);
+    /* To remove warning for unused variable to keep prototype same */
+    (void)hComponent;
+    (void)pAppData;
+    (void)pEventData;
+
+    switch(eEvent) {
+        case OMX_EventCmdComplete:
+        DEBUG_PRINT("\n OMX_EventCmdComplete event=%d data1=%u data2=%u\n",(OMX_EVENTTYPE)eEvent,
+                                                                               nData1,nData2);
+            event_complete();
+        break;
+        case OMX_EventError:
+        DEBUG_PRINT("\n OMX_EventError \n");
+        break;
+         case OMX_EventBufferFlag:
+             DEBUG_PRINT("\n OMX_EventBufferFlag \n");
+             bOutputEosReached = true;
+             event_complete();
+             break;
+        case OMX_EventPortSettingsChanged:
+        DEBUG_PRINT("\n OMX_EventPortSettingsChanged \n");
+        break;
+        default:
+        DEBUG_PRINT("\n Unknown Event \n");
+        break;
+    }
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                              OMX_IN OMX_PTR pAppData,
+                              OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    size_t bytes_writen = 0;
+    size_t total_bytes_writen = 0;
+    size_t len = 0;
+    struct enc_meta_out *meta = NULL;
+    OMX_U8 *src = pBuffer->pBuffer;
+    unsigned int num_of_frames = 1;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)pAppData;
+
+        if(((pBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+            DEBUG_PRINT("FBD::EOS on output port\n ");
+            bOutputEosReached = true;
+            return OMX_ErrorNone;
+        }
+        if(bInputEosReached_tunnel || bOutputEosReached)
+        {
+            DEBUG_PRINT("EOS REACHED NO MORE PROCESSING OF BUFFERS\n");
+            return OMX_ErrorNone;
+        }
+        if(num_of_frames != src[0]){
+
+            printf("Data corrupt\n");
+            return OMX_ErrorNone;
+        }
+        /* Skip the first bytes */
+
+
+
+        src += sizeof(unsigned char);
+        meta = (struct enc_meta_out *)src;
+        while (num_of_frames > 0) {
+            meta = (struct enc_meta_out *)src;
+            /*printf("offset=%d framesize=%d encoded_pcm[%d] msw_ts[%d]lsw_ts[%d] nflags[%d]\n",
+                                                                       meta->offset_to_frame,
+                                                                       meta->frame_size,
+                          meta->encoded_pcm_samples, meta->msw_ts, meta->lsw_ts, meta->nflags);*/
+            len = meta->frame_size;
+
+            if(format == 6)
+            {
+                audaac_rec_install_adts_header_variable((uint16_t)(len + AUDAAC_MAX_ADTS_HEADER_LENGTH));
+                bytes_writen = fwrite(audaac_header,1,AUDAAC_MAX_ADTS_HEADER_LENGTH,outputBufferFile);
+                if(bytes_writen < AUDAAC_MAX_ADTS_HEADER_LENGTH)
+                {
+                    DEBUG_PRINT("error: invalid adts header length\n");
+                    return OMX_ErrorNone;
+                }
+            }
+            bytes_writen = fwrite(pBuffer->pBuffer + sizeof(unsigned char) + meta->offset_to_frame,1,len,outputBufferFile);
+            if(bytes_writen < len)
+            {
+                DEBUG_PRINT("error: invalid AAC encoded data \n");
+                return OMX_ErrorNone;
+            }
+            src += sizeof(struct enc_meta_out);
+            num_of_frames--;
+            total_bytes_writen += len;
+        }
+        DEBUG_PRINT(" FillBufferDone size writen to file  %zu\n",total_bytes_writen);
+        totaldatalen = totaldatalen + (int)total_bytes_writen;
+
+        DEBUG_PRINT(" FBD calling FTB\n");
+        OMX_FillThisBuffer(hComponent,pBuffer);
+
+        return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                              OMX_IN OMX_PTR pAppData,
+                              OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    int readBytes =0;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)pAppData;
+
+    ebd_cnt++;
+    used_ip_buf_cnt--;
+    pthread_mutex_lock(&etb_lock);
+    if(!etb_done)
+    {
+        DEBUG_PRINT("\n*********************************************\n");
+        DEBUG_PRINT("Wait till first set of buffers are given to component\n");
+        DEBUG_PRINT("\n*********************************************\n");
+        etb_done++;
+        pthread_mutex_unlock(&etb_lock);
+        etb_wait_for_event();
+    }
+    else
+    {
+        pthread_mutex_unlock(&etb_lock);
+    }
+
+
+    if(bInputEosReached)
+    {
+        DEBUG_PRINT("\n*********************************************\n");
+        DEBUG_PRINT("   EBD::EOS on input port\n ");
+        DEBUG_PRINT("*********************************************\n");
+        return OMX_ErrorNone;
+    }else if (bFlushing == true) {
+      DEBUG_PRINT("omx_aac_adec_test: bFlushing is set to TRUE used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
+      if (used_ip_buf_cnt == 0) {
+        bFlushing = false;
+      } else {
+        DEBUG_PRINT("omx_aac_adec_test: more buffer to come back used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
+        return OMX_ErrorNone;
+      }
+    }
+
+    if((readBytes = Read_Buffer(pBuffer)) > 0) {
+        pBuffer->nFilledLen = (OMX_U32)readBytes;
+        used_ip_buf_cnt++;
+        OMX_EmptyThisBuffer(hComponent,pBuffer);
+    }
+    else{
+        pBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
+        used_ip_buf_cnt++;
+        bInputEosReached = true;
+        pBuffer->nFilledLen = 0;
+        OMX_EmptyThisBuffer(hComponent,pBuffer);
+        DEBUG_PRINT("EBD..Either EOS or Some Error while reading file\n");
+    }
+    return OMX_ErrorNone;
+}
+
+void signal_handler(int sig_id) {
+
+  /* Flush */
+  if (sig_id == SIGUSR1) {
+    DEBUG_PRINT("%s Initiate flushing\n", __FUNCTION__);
+    bFlushing = true;
+    OMX_SendCommand(aac_enc_handle, OMX_CommandFlush, OMX_ALL, NULL);
+  } else if (sig_id == SIGUSR2) {
+    if (bPause == true) {
+      DEBUG_PRINT("%s resume playback\n", __FUNCTION__);
+      bPause = false;
+      OMX_SendCommand(aac_enc_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
+    } else {
+      DEBUG_PRINT("%s pause playback\n", __FUNCTION__);
+      bPause = true;
+      OMX_SendCommand(aac_enc_handle, OMX_CommandStateSet, OMX_StatePause, NULL);
+    }
+  }
+}
+
+int main(int argc, char **argv)
+{
+     unsigned int bufCnt=0;
+     OMX_ERRORTYPE result;
+
+    struct sigaction sa;
+
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_handler = &signal_handler;
+    sigaction(SIGABRT, &sa, NULL);
+    sigaction(SIGUSR1, &sa, NULL);
+    sigaction(SIGUSR2, &sa, NULL);
+
+   (void) signal(SIGINT, Release_Encoder);
+
+    pthread_cond_init(&cond, 0);
+    pthread_mutex_init(&lock, 0);
+    pthread_cond_init(&etb_cond, 0);
+    pthread_mutex_init(&etb_lock, 0);
+    pthread_mutex_init(&etb_lock1, 0);
+
+    if (argc >= 9) {
+      in_filename = argv[1];
+      out_filename = argv[2];
+      if (in_filename == NULL || out_filename == NULL) {
+                DEBUG_PRINT("Invalid %s filename\n", in_filename ? "Output":"Input");
+                return 0;
+      }
+      aac_samplerate = (uint32_t)atoi(argv[3]);
+      aac_channels = (uint32_t)atoi(argv[4]);
+      tunnel  = (uint32_t)atoi(argv[5]);
+      rectime = (uint32_t)get_input_and_validate(argv[6], UINTMAX);
+      bitrate = (uint32_t)atoi(argv[7]);
+      format =  (uint32_t)atoi(argv[8]);
+      profile = (uint32_t)atoi(argv[9]);
+
+	  DEBUG_PRINT("Input parameters: aac_samplerate = %d, channels = %d, tunnel = %d,"
+				  " rectime = %d, bitrate = %d, format = %d, profile = %d\n",
+				  aac_samplerate, aac_channels, tunnel, rectime, bitrate, format, profile);
+
+	  if (!((profile == 2) || (profile == 5) || (profile == 29))) {
+		  DEBUG_PRINT("profile = %d, not supported. Supported "
+					  "profile values are AAC_LC(2), AAC+(5), EAAC+(29)\n", profile);
+		  return 0;
+	  }
+	  if (!((format == 1) || (format == 6)))  {
+		  DEBUG_PRINT("format = %d, not supported. Supported "
+					  "formats are ADTS(1), RAW(6)\n", format);
+		  return 0;
+	  }
+	  if ((aac_channels > 2) || (aac_channels <= 0)) {
+		  DEBUG_PRINT("channels = %d, not supported. Supported "
+					  "number of channels are 1 and 2\n", aac_channels);
+		  return 0;
+	  }
+	  if ((aac_samplerate < 8000) && (aac_samplerate > 48000)) {
+		  DEBUG_PRINT("samplerate = %d, not supported, Supported "
+					  "samplerates are 8000, 11025, 12000, 16000, 22050, "
+					  "24000, 32000, 44100, 48000\n", aac_samplerate);
+		  return 0;
+	  } else {
+		  if ((profile == 5) || (profile == 29)) {
+			  if (aac_samplerate < 24000) {
+				  DEBUG_PRINT("samplerate = %d, not supported for AAC+/EAAC+."
+							  " Supported samplerates are 24000, 32000,"
+							  " 44100, 48000\n", aac_samplerate);
+				  return 0;
+			  }
+		  }
+	  }
+    } else {
+        DEBUG_PRINT(" invalid format: \n");
+        DEBUG_PRINT("ex: ./mm-aenc-omxaac INPUTFILE AAC_OUTPUTFILE SAMPFREQ CHANNEL TUNNEL RECORDTIME BITRATE FORMAT PROFILE\n");
+        DEBUG_PRINT("FOR TUNNEL MOD PASS INPUT FILE AS ZERO\n");
+        DEBUG_PRINT("RECORDTIME in seconds for AST Automation ...TUNNEL MODE ONLY\n");
+        DEBUG_PRINT("FORMAT::ADTS(1), RAW(6)\n");
+        DEBUG_PRINT("BITRATE in bits/sec \n");
+        DEBUG_PRINT("PROFILE::AAC_LC(2), AAC+(5), EAAC+(29)\n");
+        return 0;
+    }
+    if(tunnel == 0)
+        aud_comp = "OMX.qcom.audio.encoder.aac";
+    else
+        aud_comp = "OMX.qcom.audio.encoder.tunneled.aac";
+    if(Init_Encoder(aud_comp)!= 0x00)
+    {
+        DEBUG_PRINT("Decoder Init failed\n");
+        return -1;
+    }
+
+    fcntl(0, F_SETFL, O_NONBLOCK);
+
+    if(Play_Encoder() != 0x00)
+    {
+        DEBUG_PRINT("Play_Decoder failed\n");
+        return -1;
+    }
+
+    // Wait till EOS is reached...
+        if(rectime && tunnel)
+        {
+            sleep(rectime);
+            rectime = 0;
+            bInputEosReached_tunnel = 1;
+            DEBUG_PRINT("\EOS ON INPUT PORT\n");
+        }
+        else
+        {
+            wait_for_event();
+        }
+
+        if((bInputEosReached_tunnel) || ((bOutputEosReached) && !tunnel))
+        {
+
+            DEBUG_PRINT("\nMoving the decoder to idle state \n");
+            OMX_SendCommand(aac_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
+            wait_for_event();
+            DEBUG_PRINT("\nMoving the encoder to loaded state \n");
+            OMX_SendCommand(aac_enc_handle, OMX_CommandStateSet, OMX_StateLoaded,0);
+            sleep(1);
+            if (!tunnel)
+            {
+                DEBUG_PRINT("\nFillBufferDone: Deallocating i/p buffers \n");
+                for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt) {
+                    OMX_FreeBuffer(aac_enc_handle, 0, pInputBufHdrs[bufCnt]);
+                }
+            }
+
+            DEBUG_PRINT ("\nFillBufferDone: Deallocating o/p buffers \n");
+            for(bufCnt=0; bufCnt < output_buf_cnt; ++bufCnt) {
+                OMX_FreeBuffer(aac_enc_handle, 1, pOutputBufHdrs[bufCnt]);
+            }
+            wait_for_event();
+
+            result = OMX_FreeHandle(aac_enc_handle);
+            if (result != OMX_ErrorNone) {
+                DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
+            }
+            /* Deinit OpenMAX */
+            if(tunnel)
+            {
+                #ifdef AUDIOV2
+                if (msm_route_stream(DIR_TX,session_id,device_id, 0))
+                {
+                    DEBUG_PRINT("\ncould not set stream routing\n");
+                    return -1;
+                }
+                if (msm_en_device(device_id, 0))
+                {
+                    DEBUG_PRINT("\ncould not enable device\n");
+                    return -1;
+                }
+                msm_mixer_close();
+                #endif
+            }
+            OMX_Deinit();
+            ebd_cnt=0;
+            bOutputEosReached = false;
+            bInputEosReached_tunnel = false;
+            bInputEosReached = 0;
+            aac_enc_handle = NULL;
+            pthread_cond_destroy(&cond);
+            pthread_mutex_destroy(&lock);
+            fclose(outputBufferFile);
+            DEBUG_PRINT("*****************************************\n");
+            DEBUG_PRINT("******...AAC ENC TEST COMPLETED...***************\n");
+            DEBUG_PRINT("*****************************************\n");
+        }
+        return 0;
+}
+
+void Release_Encoder()
+{
+    static int cnt=0;
+    OMX_ERRORTYPE result;
+
+    DEBUG_PRINT("END OF AAC ENCODING: EXITING PLEASE WAIT\n");
+    bInputEosReached_tunnel = 1;
+    event_complete();
+    cnt++;
+    if(cnt > 1)
+    {
+        /* FORCE RESET  */
+        aac_enc_handle = NULL;
+        ebd_cnt=0;
+        bInputEosReached_tunnel = false;
+
+        result = OMX_FreeHandle(aac_enc_handle);
+        if (result != OMX_ErrorNone) {
+            DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
+        }
+
+        /* Deinit OpenMAX */
+
+        OMX_Deinit();
+
+        pthread_cond_destroy(&cond);
+        pthread_mutex_destroy(&lock);
+            DEBUG_PRINT("*****************************************\n");
+            DEBUG_PRINT("******...AAC ENC TEST COMPLETED...***************\n");
+            DEBUG_PRINT("*****************************************\n");
+        exit(0);
+    }
+}
+
+int Init_Encoder(OMX_STRING audio_component)
+{
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE omxresult;
+    OMX_U32 total = 0;
+    typedef OMX_U8* OMX_U8_PTR;
+    char *role ="audio_encoder";
+
+    static OMX_CALLBACKTYPE call_back = {
+        &EventHandler,&EmptyBufferDone,&FillBufferDone
+    };
+
+    /* Init. the OpenMAX Core */
+    DEBUG_PRINT("\nInitializing OpenMAX Core....\n");
+    omxresult = OMX_Init();
+
+    if(OMX_ErrorNone != omxresult) {
+        DEBUG_PRINT("\n Failed to Init OpenMAX core");
+          return -1;
+    }
+    else {
+        DEBUG_PRINT("\nOpenMAX Core Init Done\n");
+    }
+
+    /* Query for audio decoders*/
+    DEBUG_PRINT("Aac_test: Before entering OMX_GetComponentOfRole");
+    OMX_GetComponentsOfRole(role, &total, 0);
+    DEBUG_PRINT ("\nTotal components of role=%s :%u", role, total);
+
+
+    omxresult = OMX_GetHandle((OMX_HANDLETYPE*)(&aac_enc_handle),
+                        (OMX_STRING)audio_component, NULL, &call_back);
+    if (FAILED(omxresult)) {
+        DEBUG_PRINT("\nFailed to Load the component:%s\n", audio_component);
+    return -1;
+    }
+    else
+    {
+        DEBUG_PRINT("\nComponent %s is in LOADED state\n", audio_component);
+    }
+
+    /* Get the port information */
+    CONFIG_VERSION_SIZE(portParam);
+    omxresult = OMX_GetParameter(aac_enc_handle, OMX_IndexParamAudioInit,
+                                (OMX_PTR)&portParam);
+
+    if(FAILED(omxresult)) {
+        DEBUG_PRINT("\nFailed to get Port Param\n");
+    return -1;
+    }
+    else
+    {
+        DEBUG_PRINT("\nportParam.nPorts:%u\n", portParam.nPorts);
+    DEBUG_PRINT("\nportParam.nStartPortNumber:%u\n",
+                                             portParam.nStartPortNumber);
+    }
+    return 0;
+}
+
+int Play_Encoder()
+{
+    unsigned int i;
+    int Size=0;
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE ret;
+    OMX_INDEXTYPE index;
+#ifdef __LP64__
+    DEBUG_PRINT("sizeof[%ld]\n", sizeof(OMX_BUFFERHEADERTYPE));
+#else
+    DEBUG_PRINT("sizeof[%d]\n", sizeof(OMX_BUFFERHEADERTYPE));
+#endif
+
+    /* open the i/p and o/p files based on the video file format passed */
+    if(open_audio_file()) {
+        DEBUG_PRINT("\n Returning -1");
+    return -1;
+    }
+
+    /* Query the encoder input min buf requirements */
+    CONFIG_VERSION_SIZE(inputportFmt);
+
+    /* Port for which the Client needs to obtain info */
+    inputportFmt.nPortIndex = portParam.nStartPortNumber;
+
+    OMX_GetParameter(aac_enc_handle,OMX_IndexParamPortDefinition,&inputportFmt);
+    DEBUG_PRINT ("\nEnc Input Buffer Count %u\n", inputportFmt.nBufferCountMin);
+    DEBUG_PRINT ("\nEnc: Input Buffer Size %u\n", inputportFmt.nBufferSize);
+
+    if(OMX_DirInput != inputportFmt.eDir) {
+        DEBUG_PRINT ("\nEnc: Expect Input Port\n");
+    return -1;
+    }
+
+    pcmparam.nPortIndex   = 0;
+    pcmparam.nChannels    =  pcm_channels;
+    pcmparam.nSamplingRate = pcm_samplerate;
+    OMX_SetParameter(aac_enc_handle,OMX_IndexParamAudioPcm,&pcmparam);
+
+
+    /* Query the encoder outport's min buf requirements */
+    CONFIG_VERSION_SIZE(outputportFmt);
+    /* Port for which the Client needs to obtain info */
+    outputportFmt.nPortIndex = portParam.nStartPortNumber + 1;
+
+    OMX_GetParameter(aac_enc_handle,OMX_IndexParamPortDefinition,&outputportFmt);
+    DEBUG_PRINT ("\nEnc: Output Buffer Count %u\n", outputportFmt.nBufferCountMin);
+    DEBUG_PRINT ("\nEnc: Output Buffer Size %u\n", outputportFmt.nBufferSize);
+
+    if(OMX_DirOutput != outputportFmt.eDir) {
+        DEBUG_PRINT ("\nEnc: Expect Output Port\n");
+    return -1;
+    }
+
+
+    CONFIG_VERSION_SIZE(aacparam);
+
+
+    aacparam.nPortIndex   =  1;
+    aacparam.nChannels    =  aac_channels; //2 ; /* 1-> mono 2-> stereo*/
+    aacparam.nBitRate     =  bitrate;
+    aacparam.nSampleRate  =  aac_samplerate;
+    aacparam.eChannelMode =  OMX_AUDIO_ChannelModeStereo;
+    aacparam.eAACStreamFormat    =  (OMX_AUDIO_AACSTREAMFORMATTYPE)format;
+    aacparam.eAACProfile = (OMX_AUDIO_AACPROFILETYPE)profile;
+    OMX_SetParameter(aac_enc_handle,OMX_IndexParamAudioAac,&aacparam);
+    OMX_GetExtensionIndex(aac_enc_handle,"OMX.Qualcomm.index.audio.sessionId",&index);
+    OMX_GetParameter(aac_enc_handle,index,&streaminfoparam);
+    if(tunnel)
+    {
+    #ifdef AUDIOV2
+    session_id = streaminfoparam.sessionId;
+    control = msm_mixer_open("/dev/snd/controlC0", 0);
+    if(control < 0)
+    printf("ERROR opening the device\n");
+    device_id = msm_get_device(device);
+    DEBUG_PRINT ("\ndevice_id = %d\n",device_id);
+    DEBUG_PRINT("\nsession_id = %d\n",session_id);
+    if (msm_en_device(device_id, 1))
+    {
+        perror("could not enable device\n");
+        return -1;
+    }
+
+    if (msm_route_stream(DIR_TX,session_id,device_id, 1))
+    {
+        perror("could not set stream routing\n");
+        return -1;
+    }
+    #endif
+    }
+    DEBUG_PRINT ("\nOMX_SendCommand Encoder -> IDLE\n");
+    OMX_SendCommand(aac_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
+    /* wait_for_event(); should not wait here event complete status will
+       not come until enough buffer are allocated */
+    if (tunnel == 0)
+    {
+        input_buf_cnt = inputportFmt.nBufferCountActual; //  inputportFmt.nBufferCountMin + 5;
+        DEBUG_PRINT("Transition to Idle State succesful...\n");
+        /* Allocate buffer on decoder's i/p port */
+        error = Allocate_Buffer(aac_enc_handle, &pInputBufHdrs, inputportFmt.nPortIndex,
+                            input_buf_cnt, inputportFmt.nBufferSize);
+        if (error != OMX_ErrorNone || pInputBufHdrs == NULL) {
+            DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer error\n");
+        return -1;
+    }
+    else {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer success\n");
+    }
+    }
+    output_buf_cnt = outputportFmt.nBufferCountMin ;
+
+    /* Allocate buffer on encoder's O/Pp port */
+    error = Allocate_Buffer(aac_enc_handle, &pOutputBufHdrs, outputportFmt.nPortIndex,
+                            output_buf_cnt, outputportFmt.nBufferSize);
+    if (error != OMX_ErrorNone || pOutputBufHdrs == NULL) {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer error\n");
+    return -1;
+    }
+    else {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer success\n");
+    }
+
+    wait_for_event();
+
+
+    if (tunnel == 1)
+    {
+        DEBUG_PRINT ("\nOMX_SendCommand to enable TUNNEL MODE during IDLE\n");
+        OMX_SendCommand(aac_enc_handle, OMX_CommandPortDisable,0,0); // disable input port
+        wait_for_event();
+    }
+
+    DEBUG_PRINT ("\nOMX_SendCommand encoder -> Executing\n");
+    OMX_SendCommand(aac_enc_handle, OMX_CommandStateSet, OMX_StateExecuting,0);
+    wait_for_event();
+
+    DEBUG_PRINT(" Start sending OMX_FILLthisbuffer\n");
+
+    for(i=0; i < output_buf_cnt; i++) {
+        DEBUG_PRINT ("\nOMX_FillThisBuffer on output buf no.%d\n",i);
+        pOutputBufHdrs[i]->nOutputPortIndex = 1;
+        pOutputBufHdrs[i]->nFlags = pOutputBufHdrs[i]->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
+        ret = OMX_FillThisBuffer(aac_enc_handle, pOutputBufHdrs[i]);
+        if (OMX_ErrorNone != ret) {
+            DEBUG_PRINT("OMX_FillThisBuffer failed with result %d\n", ret);
+    }
+        else {
+            DEBUG_PRINT("OMX_FillThisBuffer success!\n");
+    }
+    }
+
+if(tunnel == 0)
+{
+    DEBUG_PRINT(" Start sending OMX_emptythisbuffer\n");
+    for (i = 0;i < input_buf_cnt;i++) {
+        DEBUG_PRINT ("\nOMX_EmptyThisBuffer on Input buf no.%d\n",i);
+        pInputBufHdrs[i]->nInputPortIndex = 0;
+        Size = Read_Buffer(pInputBufHdrs[i]);
+        if(Size <=0 ){
+          DEBUG_PRINT("NO DATA READ\n");
+          bInputEosReached = true;
+          pInputBufHdrs[i]->nFlags= OMX_BUFFERFLAG_EOS;
+        }
+        pInputBufHdrs[i]->nFilledLen = (OMX_U32)Size;
+        pInputBufHdrs[i]->nInputPortIndex = 0;
+        used_ip_buf_cnt++;
+        ret = OMX_EmptyThisBuffer(aac_enc_handle, pInputBufHdrs[i]);
+        if (OMX_ErrorNone != ret) {
+            DEBUG_PRINT("OMX_EmptyThisBuffer failed with result %d\n", ret);
+        }
+        else {
+            DEBUG_PRINT("OMX_EmptyThisBuffer success!\n");
+        }
+        if(Size <=0 ){
+            break;//eos reached
+        }
+    }
+    pthread_mutex_lock(&etb_lock);
+    if(etb_done)
+{
+        DEBUG_PRINT("Component is waiting for EBD to be released.\n");
+        etb_event_complete();
+    }
+    else
+    {
+        DEBUG_PRINT("\n****************************\n");
+        DEBUG_PRINT("EBD not yet happened ...\n");
+        DEBUG_PRINT("\n****************************\n");
+        etb_done++;
+    }
+    pthread_mutex_unlock(&etb_lock);
+}
+
+    return 0;
+}
+
+
+
+static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *avc_enc_handle,
+                                       OMX_BUFFERHEADERTYPE  ***pBufHdrs,
+                                       OMX_U32 nPortIndex,
+                                       unsigned int bufCntMin, unsigned int bufSize)
+{
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE error=OMX_ErrorNone;
+    unsigned int bufCnt=0;
+    /* To remove warning for unused variable to keep prototype same */
+    (void)avc_enc_handle;
+
+    *pBufHdrs= (OMX_BUFFERHEADERTYPE **)
+                   malloc(sizeof(OMX_BUFFERHEADERTYPE*)*bufCntMin);
+
+    for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
+        DEBUG_PRINT("\n OMX_AllocateBuffer No %d \n", bufCnt);
+        error = OMX_AllocateBuffer(aac_enc_handle, &((*pBufHdrs)[bufCnt]),
+                                   nPortIndex, NULL, bufSize);
+    }
+
+    return error;
+}
+
+
+
+
+static int Read_Buffer (OMX_BUFFERHEADERTYPE  *pBufHdr )
+{
+
+    size_t bytes_read=0;
+
+
+    pBufHdr->nFilledLen = 0;
+    pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
+
+     bytes_read = fread(pBufHdr->pBuffer, 1, pBufHdr->nAllocLen , inputBufferFile);
+
+      pBufHdr->nFilledLen = (OMX_U32)bytes_read;
+        if(bytes_read == 0)
+        {
+
+          pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
+          DEBUG_PRINT ("\nBytes read zero\n");
+        }
+        else
+        {
+            pBufHdr->nFlags = pBufHdr->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
+        }
+
+    return (int)bytes_read;
+}
+
+
+
+//In Encoder this Should Open a PCM or WAV file for input.
+
+static int open_audio_file ()
+{
+    int error_code = 0;
+
+    if (!tunnel)
+    {
+        DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, in_filename);
+        inputBufferFile = fopen (in_filename, "rb");
+        if (inputBufferFile == NULL) {
+            DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
+                                         in_filename);
+            return -1;
+        }
+        if(parse_pcm_header() != 0x00)
+        {
+            DEBUG_PRINT("PCM parser failed \n");
+            return -1;
+        }
+    }
+
+    DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, out_filename);
+    outputBufferFile = fopen (out_filename, "wb");
+    if (outputBufferFile == NULL) {
+        DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
+                                         out_filename);
+    error_code = -1;
+    }
+    return error_code;
+}
+
+
+void audaac_rec_install_bits
+(
+  uint8   *input,
+  byte    num_bits_reqd,
+  uint32  value,
+  uint16  *hdr_bit_index
+)
+{
+  uint32 byte_index;
+  byte   bit_index;
+  byte   bits_avail_in_byte;
+  byte   num_to_copy;
+  byte   byte_to_copy;
+
+  byte   num_remaining = num_bits_reqd;
+  uint8  bit_mask;
+
+  bit_mask = 0xFF;
+
+  while (num_remaining) {
+
+    byte_index = (*hdr_bit_index) >> 3;
+    bit_index  = (*hdr_bit_index) &  0x07;
+
+    bits_avail_in_byte = (uint8)(8 - bit_index);
+
+    num_to_copy = MIN(bits_avail_in_byte, num_remaining);
+
+    byte_to_copy = (uint8)(((value >> (num_remaining - num_to_copy)) & 0xFF) <<
+                    (bits_avail_in_byte - num_to_copy));
+
+    input[byte_index] &= ((uint8)(bit_mask << bits_avail_in_byte));
+    input[byte_index] |= byte_to_copy;
+
+    *hdr_bit_index += num_to_copy;
+
+    num_remaining = (uint8)(num_remaining - num_to_copy);
+  } /* while (num_remaining) */
+} /* audaac_rec_install_bits */
+
+adts_sample_index  map_adts_sample_index(uint32 srate)
+{
+  adts_sample_index ret;
+
+  switch(srate){
+
+     case 96000:
+     ret= ADTS_SAMPLE_INDEX_96000;
+     break;
+     case 88200:
+     ret= ADTS_SAMPLE_INDEX_88200;
+     break;
+     case 64000:
+     ret= ADTS_SAMPLE_INDEX_64000;
+     break;
+     case 48000:
+     ret=ADTS_SAMPLE_INDEX_48000;
+     break;
+     case 44100:
+     ret=ADTS_SAMPLE_INDEX_44100;
+     break;
+     case 32000:
+     ret=ADTS_SAMPLE_INDEX_32000;
+     break;
+     case 24000:
+     ret=ADTS_SAMPLE_INDEX_24000;
+     break;
+     case 22050:
+     ret=ADTS_SAMPLE_INDEX_22050;
+     break;
+     case 16000:
+     ret=ADTS_SAMPLE_INDEX_16000;
+     break;
+     case 12000:
+     ret=ADTS_SAMPLE_INDEX_12000;
+     break;
+     case 11025:
+     ret=ADTS_SAMPLE_INDEX_11025;
+     break;
+     case 8000:
+     ret=ADTS_SAMPLE_INDEX_8000;
+     break;
+     case 7350:
+     ret=ADTS_SAMPLE_INDEX_7350;
+     break;
+     default:
+     ret=ADTS_SAMPLE_INDEX_44100;
+     break;
+    }
+  return ret;
+}
+
+void audaac_rec_install_adts_header_variable (uint16  byte_num)
+{
+  //uint16  bit_index=0;
+
+  adts_sample_index srate_enum;
+  uint32  value;
+
+  uint32   sample_index = (uint32)aac_samplerate;
+  uint8   channel_config = (uint8)aac_channels;
+
+  /* Store Sync word first */
+  audaac_header[0] = 0xFF;
+  audaac_header[1] = 0xF0;
+
+  audaac_hdr_bit_index = 12;
+
+  if ((format == OMX_AUDIO_AACStreamFormatRAW) &&
+      ((profile == OMX_AUDIO_AACObjectHE) ||
+       (profile == OMX_AUDIO_AACObjectHE_PS))){
+      if (aac_samplerate >= 24000)
+          sample_index = aac_samplerate/2;
+  }
+
+  /* ID field, 1 bit */
+  value = 1;
+  audaac_rec_install_bits(audaac_header,
+                          1,
+                          value,
+                          &(audaac_hdr_bit_index));
+
+  /* Layer field, 2 bits */
+  value = 0;
+  audaac_rec_install_bits(audaac_header,
+                          AACHDR_LAYER_SIZE,
+                          value,
+                          &(audaac_hdr_bit_index));
+
+  /* Protection_absent field, 1 bit */
+  value = 1;
+  audaac_rec_install_bits(audaac_header,
+                          AACHDR_CRC_SIZE,
+                          value,
+                          &(audaac_hdr_bit_index));
+
+  /* profile_ObjectType field, 2 bit */
+  value = 1;
+  audaac_rec_install_bits(audaac_header,
+                          AAC_PROFILE_SIZE,
+                          value,
+                          &(audaac_hdr_bit_index));
+
+  /* sampling_frequency_index field, 4 bits */
+  srate_enum = map_adts_sample_index(sample_index);
+  audaac_rec_install_bits(audaac_header,
+                          AAC_SAMPLING_FREQ_INDEX_SIZE,
+                          (uint32)srate_enum,
+                          &(audaac_hdr_bit_index));
+
+  DEBUG_PRINT("%s: sample_index=%d; srate_enum = %d \n",
+			  __FUNCTION__, sample_index, srate_enum);
+
+  /* pravate_bit field, 1 bits */
+  audaac_rec_install_bits(audaac_header,
+                          1,
+                          0,
+                          &(audaac_hdr_bit_index));
+
+  /* channel_configuration field, 3 bits */
+  audaac_rec_install_bits(audaac_header,
+                          3,
+                          channel_config,
+                          &(audaac_hdr_bit_index));
+
+
+  /* original/copy field, 1 bits */
+  audaac_rec_install_bits(audaac_header,
+                          AAC_ORIGINAL_COPY_SIZE,
+                          0,
+                          &(audaac_hdr_bit_index));
+
+
+  /* home field, 1 bits */
+  audaac_rec_install_bits(audaac_header,
+                          AAC_HOME_SIZE,
+                          0,
+                          &(audaac_hdr_bit_index));
+
+ // bit_index = audaac_hdr_bit_index;
+ // bit_index += 2;
+
+    /* copyr. id. bit, 1 bits */
+  audaac_rec_install_bits(audaac_header,
+                          1,
+                          0,
+                          &(audaac_hdr_bit_index));
+
+    /* copyr. id. start, 1 bits */
+  audaac_rec_install_bits(audaac_header,
+                          1,
+                          0,
+                          &(audaac_hdr_bit_index));
+
+  /* aac_frame_length field, 13 bits */
+  audaac_rec_install_bits(audaac_header,
+                          AUDAAC_ADTS_FRAME_LENGTH_SIZE,
+                          byte_num,
+                          &audaac_hdr_bit_index);
+
+  /* adts_buffer_fullness field, 11 bits */
+  audaac_rec_install_bits(audaac_header,
+                          11,
+                          0x660,/*0x660 = CBR,0x7FF = VBR*/
+                          &audaac_hdr_bit_index);
+
+  /* number_of_raw_data_blocks_in_frame, 2 bits */
+  audaac_rec_install_bits(audaac_header,
+                          2,
+                          0,
+                          &audaac_hdr_bit_index);
+
+} /* audaac_rec_install_adts_header_variable */
+
+static OMX_ERRORTYPE parse_pcm_header()
+{
+    struct wav_header hdr;
+
+    DEBUG_PRINT("\n***************************************************************\n");
+    if(fread(&hdr, 1, sizeof(hdr),inputBufferFile)!=sizeof(hdr))
+    {
+        DEBUG_PRINT("Wav file cannot read header\n");
+        return -1;
+    }
+
+    if ((hdr.riff_id != ID_RIFF) ||
+        (hdr.riff_fmt != ID_WAVE)||
+        (hdr.fmt_id != ID_FMT))
+    {
+        DEBUG_PRINT("Wav file is not a riff/wave file\n");
+        return -1;
+    }
+
+    if (hdr.audio_format != FORMAT_PCM)
+    {
+        DEBUG_PRINT("Wav file is not adpcm format %d and fmt size is %d\n",
+                      hdr.audio_format, hdr.fmt_sz);
+        return -1;
+    }
+
+    DEBUG_PRINT("Samplerate is %d\n", hdr.sample_rate);
+    DEBUG_PRINT("Channel Count is %d\n", hdr.num_channels);
+    DEBUG_PRINT("\n***************************************************************\n");
+
+    pcm_samplerate = hdr.sample_rate;
+    pcm_channels = hdr.num_channels;
+
+    return OMX_ErrorNone;
+}
diff --git a/mm-audio/aenc-amrnb/qdsp6/Android.mk b/mm-audio/aenc-amrnb/qdsp6/Android.mk
index 2e7453c..62124e9 100644
--- a/mm-audio/aenc-amrnb/qdsp6/Android.mk
+++ b/mm-audio/aenc-amrnb/qdsp6/Android.mk
@@ -42,6 +42,29 @@
 
 include $(BUILD_SHARED_LIBRARY)
 
+# ---------------------------------------------------------------------------------
+#             Make the apps-test (mm-aenc-omxamr-test)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+mm-amr-enc-test-inc    := $(LOCAL_PATH)/inc
+mm-amr-enc-test-inc    += $(LOCAL_PATH)/test
+
+mm-amr-enc-test-inc    += $(TARGET_OUT_HEADERS)/mm-core/omxcore
+mm-amr-enc-test-inc    += $(TARGET_OUT_HEADERS)/mm-audio/audio-alsa
+LOCAL_MODULE            := mm-aenc-omxamr-test
+LOCAL_MODULE_TAGS       := optional
+LOCAL_CFLAGS            := $(libOmxAmrEnc-def)
+LOCAL_C_INCLUDES        := $(mm-amr-enc-test-inc)
+LOCAL_PRELINK_MODULE    := false
+LOCAL_SHARED_LIBRARIES  := libmm-omxcore
+LOCAL_SHARED_LIBRARIES  += libOmxAmrEnc
+LOCAL_SHARED_LIBRARIES  += libaudioalsa
+LOCAL_SRC_FILES         := test/omx_amr_enc_test.c
+
+include $(BUILD_EXECUTABLE)
+
 endif
 
 # ---------------------------------------------------------------------------------
diff --git a/mm-audio/aenc-amrnb/qdsp6/Makefile b/mm-audio/aenc-amrnb/qdsp6/Makefile
index 4ea0849..0abd31c 100644
--- a/mm-audio/aenc-amrnb/qdsp6/Makefile
+++ b/mm-audio/aenc-amrnb/qdsp6/Makefile
@@ -39,7 +39,7 @@
 # ---------------------------------------------------------------------------------
 #					BUILD
 # ---------------------------------------------------------------------------------
-all: libOmxAmrEnc.so.$(LIBVER)
+all: libOmxAmrEnc.so.$(LIBVER) mm-aenc-omxamr-test
 
 install:
 	echo "intalling aenc-amr in $(DESTDIR)"
@@ -49,7 +49,8 @@
 	install -m 555 libOmxAmrEnc.so.$(LIBVER) $(LIBINSTALLDIR)
 	cd $(LIBINSTALLDIR) && ln -s libOmxAmrEnc.so.$(LIBVER) libOmxAmrEnc.so.$(LIBMAJOR)
 	cd $(LIBINSTALLDIR) && ln -s libOmxAmrEnc.so.$(LIBMAJOR) libOmxAmrEnc.so
-
+	install -m 555 mm-aenc-omxamr-test $(BININSTALLDIR)
+	
 # ---------------------------------------------------------------------------------
 #				COMPILE LIBRARY
 # ---------------------------------------------------------------------------------
@@ -64,5 +65,17 @@
 	$(CC) $(CPPFLAGS) $(CFLAGS_SO) $(LDFLAGS_SO) -Wl,-soname,libOmxAmrEnc.so.$(LIBMAJOR) -o $@ $^ $(LDFLAGS) $(LDLIBS)
 
 # ---------------------------------------------------------------------------------
+#				COMPILE TEST APP
+# ---------------------------------------------------------------------------------
+TEST_LDLIBS := -lpthread
+TEST_LDLIBS += -ldl
+TEST_LDLIBS += -lOmxCore
+
+TEST_SRCS := test/omx_amr_enc_test.c
+
+mm-aenc-omxamr-test: libOmxAmrEnc.so.$(LIBVER) $(TEST_SRCS)
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $^ $(TEST_LDLIBS)
+
+# ---------------------------------------------------------------------------------
 #					END
 # ---------------------------------------------------------------------------------
diff --git a/mm-audio/aenc-amrnb/qdsp6/Makefile.am b/mm-audio/aenc-amrnb/qdsp6/Makefile.am
index fc19f87..13379a3 100644
--- a/mm-audio/aenc-amrnb/qdsp6/Makefile.am
+++ b/mm-audio/aenc-amrnb/qdsp6/Makefile.am
@@ -32,3 +32,11 @@
 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 -avoid-version
+
+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/test/omx_amr_enc_test.c b/mm-audio/aenc-amrnb/qdsp6/test/omx_amr_enc_test.c
new file mode 100644
index 0000000..58215c4
--- /dev/null
+++ b/mm-audio/aenc-amrnb/qdsp6/test/omx_amr_enc_test.c
@@ -0,0 +1,1097 @@
+
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2014, 2017 The Linux Foundation. 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.
+    * Neither the name of The Linux Foundation nor
+      the names of its contributors may be used to endorse or promote
+      products derived from this software without specific prior written
+      permission.
+
+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, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT 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.
+--------------------------------------------------------------------------*/
+
+
+/*
+    An Open max test application ....
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include "OMX_Core.h"
+#include "OMX_Component.h"
+#include "pthread.h"
+#include <signal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include<unistd.h>
+#include<string.h>
+#include <pthread.h>
+#include "QOMX_AudioExtensions.h"
+#include "QOMX_AudioIndexExtensions.h"
+#ifdef AUDIOV2
+#include "control.h"
+#endif
+
+
+#include <linux/ioctl.h>
+
+typedef unsigned char uint8;
+typedef unsigned char byte;
+typedef unsigned int  uint32;
+typedef unsigned int  uint16;
+QOMX_AUDIO_STREAM_INFO_DATA streaminfoparam;
+/* maximum ADTS frame header length                */
+void Release_Encoder();
+
+#ifdef AUDIOV2
+unsigned short session_id;
+int device_id;
+int control = 0;
+const char *device="handset_tx";
+#define DIR_TX 2
+#endif
+
+uint32_t samplerate = 8000;
+uint32_t channels = 1;
+uint32_t bandmode = 7;
+uint32_t dtxenable = 0;
+uint32_t rectime = 0;
+uint32_t recpath = 0;
+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;
+
+/************************************************************************/
+/*                GLOBAL INIT                    */
+/************************************************************************/
+
+/************************************************************************/
+/*                #DEFINES                            */
+/************************************************************************/
+#define false 0
+#define true 1
+
+#define CONFIG_VERSION_SIZE(param) \
+    param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\
+    param.nSize = sizeof(param);
+
+#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)
+
+/************************************************************************/
+/*                GLOBAL DECLARATIONS                     */
+/************************************************************************/
+
+pthread_mutex_t lock;
+pthread_cond_t cond;
+pthread_mutex_t elock;
+pthread_cond_t econd;
+pthread_cond_t fcond;
+pthread_mutex_t etb_lock;
+pthread_mutex_t etb_lock1;
+pthread_cond_t etb_cond;
+FILE * inputBufferFile;
+FILE * outputBufferFile;
+OMX_PARAM_PORTDEFINITIONTYPE inputportFmt;
+OMX_PARAM_PORTDEFINITIONTYPE outputportFmt;
+OMX_AUDIO_PARAM_AMRTYPE amrparam;
+OMX_AUDIO_PARAM_PCMMODETYPE    pcmparam;
+OMX_PORT_PARAM_TYPE portParam;
+OMX_PORT_PARAM_TYPE portFmt;
+OMX_ERRORTYPE error;
+
+
+
+
+#define ID_RIFF 0x46464952
+#define ID_WAVE 0x45564157
+#define ID_FMT  0x20746d66
+#define ID_DATA 0x61746164
+
+#define FORMAT_PCM 1
+
+struct wav_header {
+  uint32_t riff_id;
+  uint32_t riff_sz;
+  uint32_t riff_fmt;
+  uint32_t fmt_id;
+  uint32_t fmt_sz;
+  uint16_t audio_format;
+  uint16_t num_channels;
+  uint32_t sample_rate;
+  uint32_t byte_rate;       /* sample_rate * num_channels * bps / 8 */
+  uint16_t block_align;     /* num_channels * bps / 8 */
+  uint16_t bits_per_sample;
+  uint32_t data_id;
+  uint32_t data_sz;
+};
+struct enc_meta_out{
+        unsigned int offset_to_frame;
+        unsigned int frame_size;
+        unsigned int encoded_pcm_samples;
+        unsigned int msw_ts;
+        unsigned int lsw_ts;
+        unsigned int nflags;
+} __attribute__ ((packed));
+
+struct qcp_header {
+        /* RIFF Section */
+        char riff[4];
+        unsigned int s_riff;
+        char qlcm[4];
+
+        /* Format chunk */
+        char fmt[4];
+        unsigned int s_fmt;
+        char mjr;
+        char mnr;
+        unsigned int data1;         /* UNIQUE ID of the codec */
+        unsigned short data2;
+        unsigned short data3;
+        char data4[8];
+        unsigned short ver;         /* Codec Info */
+        char name[80];
+        unsigned short abps;    /* average bits per sec of the codec */
+        unsigned short bytes_per_pkt;
+        unsigned short samp_per_block;
+        unsigned short samp_per_sec;
+        unsigned short bits_per_samp;
+        unsigned char vr_num_of_rates;         /* Rate Header fmt info */
+        unsigned char rvd1[3];
+        unsigned short vr_bytes_per_pkt[8];
+        unsigned int rvd2[5];
+
+        /* Vrat chunk */
+        unsigned char vrat[4];
+        unsigned int s_vrat;
+        unsigned int v_rate;
+        unsigned int size_in_pkts;
+
+        /* Data chunk */
+        unsigned char data[4];
+        unsigned int s_data;
+} __attribute__ ((packed));
+
+static int totaldatalen = 0;
+static int framecnt = 0;
+/************************************************************************/
+/*                GLOBAL INIT                    */
+/************************************************************************/
+
+unsigned int input_buf_cnt = 0;
+unsigned int output_buf_cnt = 0;
+int used_ip_buf_cnt = 0;
+volatile int event_is_done = 0;
+volatile int ebd_event_is_done = 0;
+volatile int fbd_event_is_done = 0;
+volatile int etb_event_is_done = 0;
+int ebd_cnt;
+int bInputEosReached = 0;
+int bOutputEosReached = 0;
+int bInputEosReached_tunnel = 0;
+static int etb_done = 0;
+int bFlushing = false;
+int bPause    = false;
+const char *in_filename;
+const char *out_filename;
+
+int timeStampLfile = 0;
+int timestampInterval = 100;
+
+//* OMX Spec Version supported by the wrappers. Version = 1.1 */
+const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101;
+OMX_COMPONENTTYPE* amr_enc_handle = 0;
+
+OMX_BUFFERHEADERTYPE  **pInputBufHdrs = NULL;
+OMX_BUFFERHEADERTYPE  **pOutputBufHdrs = NULL;
+
+/************************************************************************/
+/*                GLOBAL FUNC DECL                        */
+/************************************************************************/
+int Init_Encoder(char*);
+int Play_Encoder();
+OMX_STRING aud_comp;
+/**************************************************************************/
+/*                STATIC DECLARATIONS                       */
+/**************************************************************************/
+
+static int open_audio_file ();
+static int Read_Buffer(OMX_BUFFERHEADERTYPE  *pBufHdr );
+static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *amr_enc_handle,
+                                       OMX_BUFFERHEADERTYPE  ***pBufHdrs,
+                                       OMX_U32 nPortIndex,
+                                       unsigned int bufCntMin, unsigned int bufSize);
+
+
+static OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                                  OMX_IN OMX_PTR pAppData,
+                                  OMX_IN OMX_EVENTTYPE eEvent,
+                                  OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
+                                  OMX_IN OMX_PTR pEventData);
+static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                     OMX_IN OMX_PTR pAppData,
+                                     OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+static OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                     OMX_IN OMX_PTR pAppData,
+                                     OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+static OMX_ERRORTYPE  parse_pcm_header();
+void wait_for_event(void)
+{
+    pthread_mutex_lock(&lock);
+    DEBUG_PRINT("%s: event_is_done=%d", __FUNCTION__, event_is_done);
+    while (event_is_done == 0) {
+        pthread_cond_wait(&cond, &lock);
+    }
+    event_is_done = 0;
+    pthread_mutex_unlock(&lock);
+}
+
+void event_complete(void )
+{
+    pthread_mutex_lock(&lock);
+    if (event_is_done == 0) {
+        event_is_done = 1;
+        pthread_cond_broadcast(&cond);
+    }
+    pthread_mutex_unlock(&lock);
+}
+
+void etb_wait_for_event(void)
+{
+    pthread_mutex_lock(&etb_lock1);
+    DEBUG_PRINT("%s: etb_event_is_done=%d", __FUNCTION__, etb_event_is_done);
+    while (etb_event_is_done == 0) {
+        pthread_cond_wait(&etb_cond, &etb_lock1);
+    }
+    etb_event_is_done = 0;
+    pthread_mutex_unlock(&etb_lock1);
+}
+
+void etb_event_complete(void )
+{
+    pthread_mutex_lock(&etb_lock1);
+    if (etb_event_is_done == 0) {
+        etb_event_is_done = 1;
+        pthread_cond_broadcast(&etb_cond);
+    }
+    pthread_mutex_unlock(&etb_lock1);
+}
+
+
+OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                           OMX_IN OMX_PTR pAppData,
+                           OMX_IN OMX_EVENTTYPE eEvent,
+                           OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
+                           OMX_IN OMX_PTR pEventData)
+{
+    DEBUG_PRINT("Function %s \n", __FUNCTION__);
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)hComponent;
+    (void)pAppData;
+    (void)pEventData;
+    switch(eEvent) {
+        case OMX_EventCmdComplete:
+        DEBUG_PRINT("\n OMX_EventCmdComplete event=%d data1=%u data2=%u\n",(OMX_EVENTTYPE)eEvent,
+                                                                               nData1,nData2);
+            event_complete();
+        break;
+        case OMX_EventError:
+        DEBUG_PRINT("\n OMX_EventError \n");
+        break;
+         case OMX_EventBufferFlag:
+             DEBUG_PRINT("\n OMX_EventBufferFlag \n");
+             bOutputEosReached = true;
+             event_complete();
+             break;
+        case OMX_EventPortSettingsChanged:
+        DEBUG_PRINT("\n OMX_EventPortSettingsChanged \n");
+        break;
+        default:
+        DEBUG_PRINT("\n Unknown Event \n");
+        break;
+    }
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                              OMX_IN OMX_PTR pAppData,
+                              OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    size_t bytes_writen = 0;
+    size_t total_bytes_writen = 0;
+    size_t len = 0;
+    struct enc_meta_out *meta = NULL;
+    OMX_U8 *src = pBuffer->pBuffer;
+    unsigned int num_of_frames = 1;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)pAppData;
+
+        if(((pBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+            DEBUG_PRINT("FBD::EOS on output port\n ");
+            bOutputEosReached = true;
+            return OMX_ErrorNone;
+        }
+        if(bInputEosReached_tunnel || bOutputEosReached)
+        {
+            DEBUG_PRINT("EOS REACHED NO MORE PROCESSING OF BUFFERS\n");
+            return OMX_ErrorNone;
+        }
+        if(num_of_frames != src[0]){
+
+            printf("Data corrupt\n");
+            return OMX_ErrorNone;
+        }
+        /* Skip the first bytes */
+
+
+
+        src += sizeof(unsigned char);
+        meta = (struct enc_meta_out *)src;
+        while (num_of_frames > 0) {
+            meta = (struct enc_meta_out *)src;
+            /*printf("offset=%d framesize=%d encoded_pcm[%d] msw_ts[%d]lsw_ts[%d] nflags[%d]\n",
+                                                                       meta->offset_to_frame,
+                                                                       meta->frame_size,
+                          meta->encoded_pcm_samples, meta->msw_ts, meta->lsw_ts, meta->nflags);*/
+            len = meta->frame_size;
+
+            bytes_writen = fwrite(pBuffer->pBuffer + sizeof(unsigned char) + meta->offset_to_frame,1,len,outputBufferFile);
+            if(bytes_writen < len)
+            {
+                DEBUG_PRINT("error: invalid AMR encoded data \n");
+                return OMX_ErrorNone;
+            }
+            src += sizeof(struct enc_meta_out);
+            num_of_frames--;
+            total_bytes_writen += len;
+        }
+        DEBUG_PRINT(" FillBufferDone size writen to file  %zu count %d\n",total_bytes_writen, framecnt);
+        totaldatalen = totaldatalen + (int)total_bytes_writen;
+    framecnt++;
+
+        DEBUG_PRINT(" FBD calling FTB\n");
+        OMX_FillThisBuffer(hComponent,pBuffer);
+
+        return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                              OMX_IN OMX_PTR pAppData,
+                              OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    int readBytes =0;
+    /* To remove warning for unused variable to keep prototype same */
+    (void)pAppData;
+
+    ebd_cnt++;
+    used_ip_buf_cnt--;
+    pthread_mutex_lock(&etb_lock);
+    if(!etb_done)
+    {
+        DEBUG_PRINT("\n*********************************************\n");
+        DEBUG_PRINT("Wait till first set of buffers are given to component\n");
+        DEBUG_PRINT("\n*********************************************\n");
+        etb_done++;
+        pthread_mutex_unlock(&etb_lock);
+        etb_wait_for_event();
+    }
+    else
+    {
+        pthread_mutex_unlock(&etb_lock);
+    }
+
+
+    if(bInputEosReached)
+    {
+        DEBUG_PRINT("\n*********************************************\n");
+        DEBUG_PRINT("   EBD::EOS on input port\n ");
+        DEBUG_PRINT("*********************************************\n");
+        return OMX_ErrorNone;
+    }else if (bFlushing == true) {
+      DEBUG_PRINT("omx_amr_adec_test: bFlushing is set to TRUE used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
+      if (used_ip_buf_cnt == 0) {
+        bFlushing = false;
+      } else {
+        DEBUG_PRINT("omx_amr_adec_test: more buffer to come back used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
+        return OMX_ErrorNone;
+      }
+    }
+
+    if((readBytes = Read_Buffer(pBuffer)) > 0) {
+        pBuffer->nFilledLen = (OMX_U32)readBytes;
+        used_ip_buf_cnt++;
+        OMX_EmptyThisBuffer(hComponent,pBuffer);
+    }
+    else{
+        pBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
+        used_ip_buf_cnt++;
+        bInputEosReached = true;
+        pBuffer->nFilledLen = 0;
+        OMX_EmptyThisBuffer(hComponent,pBuffer);
+        DEBUG_PRINT("EBD..Either EOS or Some Error while reading file\n");
+    }
+    return OMX_ErrorNone;
+}
+
+void signal_handler(int sig_id) {
+
+  /* Flush */
+  if (sig_id == SIGUSR1) {
+    DEBUG_PRINT("%s Initiate flushing\n", __FUNCTION__);
+    bFlushing = true;
+    OMX_SendCommand(amr_enc_handle, OMX_CommandFlush, OMX_ALL, NULL);
+  } else if (sig_id == SIGUSR2) {
+    if (bPause == true) {
+      DEBUG_PRINT("%s resume record\n", __FUNCTION__);
+      bPause = false;
+      OMX_SendCommand(amr_enc_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
+    } else {
+      DEBUG_PRINT("%s pause record\n", __FUNCTION__);
+      bPause = true;
+      OMX_SendCommand(amr_enc_handle, OMX_CommandStateSet, OMX_StatePause, NULL);
+    }
+  }
+}
+
+int main(int argc, char **argv)
+{
+     unsigned int bufCnt=0;
+     OMX_ERRORTYPE result;
+
+    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);
+    sigaction(SIGUSR1, &sa, NULL);
+    sigaction(SIGUSR2, &sa, NULL);
+
+   (void) signal(SIGINT, Release_Encoder);
+
+    pthread_cond_init(&cond, 0);
+    pthread_mutex_init(&lock, 0);
+    pthread_cond_init(&etb_cond, 0);
+    pthread_mutex_init(&etb_lock, 0);
+    pthread_mutex_init(&etb_lock1, 0);
+
+    if (argc >= 9) {
+        in_filename = argv[1];
+        out_filename = argv[2];
+	if (in_filename == NULL || out_filename == NULL) {
+                DEBUG_PRINT("Invalid %s filename\n", in_filename ? "Output":"Input");
+                return 0;
+        }
+	tunnel =  (uint32_t)atoi(argv[3]);
+        bandmode  = (uint32_t)atoi(argv[4]);
+        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 amrwb_enable \n");
+          DEBUG_PRINT("amrnb:Bandmode 1-8 amrwb:Bandmode 0-8, 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 (!amrwb_enable && (bandmode < 1 || bandmode > 8)) {
+          DEBUG_PRINT("%d Bandmode is not supported for amrnb:supported Bandmodes are 1-8\n",bandmode);
+          return 0;
+    }
+
+    if (amrwb_enable && (bandmode < 0 || bandmode > 8)) {
+          DEBUG_PRINT("%d Bandmode not supported for amrwb:supported Bandmodes are 0-8\n",bandmode);
+          return 0;
+    }
+
+    if (dtxenable != 0 && dtxenable != 1) {
+          DEBUG_PRINT("dtxenable not supported:dtxenable should be 0-1\n");
+          return 0;
+    }
+
+    if(recpath != 3) {
+          DEBUG_PRINT("For RECORDPATH Only MIC supported\n");
+          return 0;
+    }
+    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");
+        return -1;
+    }
+
+    fcntl(0, F_SETFL, O_NONBLOCK);
+
+    if(Play_Encoder() != 0x00)
+    {
+        DEBUG_PRINT("Play_Decoder failed\n");
+        return -1;
+    }
+
+    // Wait till EOS is reached...
+        if(rectime && tunnel)
+        {
+            sleep(rectime);
+            rectime = 0;
+            bInputEosReached_tunnel = 1;
+            DEBUG_PRINT("\EOS ON INPUT PORT\n");
+        }
+        else
+        {
+            wait_for_event();
+        }
+
+        if((bInputEosReached_tunnel) || ((bOutputEosReached) && !tunnel))
+        {
+
+            DEBUG_PRINT("\nMoving the decoder to idle state \n");
+            OMX_SendCommand(amr_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
+            wait_for_event();
+
+            DEBUG_PRINT("\nMoving the encoder to loaded state \n");
+            OMX_SendCommand(amr_enc_handle, OMX_CommandStateSet, OMX_StateLoaded,0);
+            sleep(1);
+            if (!tunnel)
+            {
+                DEBUG_PRINT("\nFillBufferDone: Deallocating i/p buffers \n");
+                for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt) {
+                    OMX_FreeBuffer(amr_enc_handle, 0, pInputBufHdrs[bufCnt]);
+                }
+            }
+
+            DEBUG_PRINT ("\nFillBufferDone: Deallocating o/p buffers \n");
+            for(bufCnt=0; bufCnt < output_buf_cnt; ++bufCnt) {
+                OMX_FreeBuffer(amr_enc_handle, 1, pOutputBufHdrs[bufCnt]);
+            }
+            wait_for_event();
+            fseek(outputBufferFile, 0,SEEK_SET);
+            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) {
+                DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
+            }
+
+            /* Deinit OpenMAX */
+        if(tunnel)
+        {
+            #ifdef AUDIOV2
+            if (msm_route_stream(DIR_TX,session_id,device_id, 0))
+            {
+                DEBUG_PRINT("\ncould not set stream routing\n");
+                return -1;
+            }
+            if (msm_en_device(device_id, 0))
+            {
+                DEBUG_PRINT("\ncould not enable device\n");
+                return -1;
+            }
+            msm_mixer_close();
+            #endif
+        }
+            OMX_Deinit();
+            ebd_cnt=0;
+            bOutputEosReached = false;
+            bInputEosReached_tunnel = false;
+            bInputEosReached = 0;
+            amr_enc_handle = NULL;
+            pthread_cond_destroy(&cond);
+            pthread_mutex_destroy(&lock);
+            fclose(outputBufferFile);
+            DEBUG_PRINT("*****************************************\n");
+            DEBUG_PRINT("******...AMR ENC TEST COMPLETED...***************\n");
+            DEBUG_PRINT("*****************************************\n");
+        }
+        return 0;
+}
+
+void Release_Encoder()
+{
+    static int cnt=0;
+    OMX_ERRORTYPE result;
+
+    DEBUG_PRINT("END OF AMR ENCODING: EXITING PLEASE WAIT\n");
+    bInputEosReached_tunnel = 1;
+    event_complete();
+    cnt++;
+    if(cnt > 1)
+    {
+        /* FORCE RESET  */
+        amr_enc_handle = NULL;
+        ebd_cnt=0;
+        bInputEosReached_tunnel = false;
+
+        result = OMX_FreeHandle(amr_enc_handle);
+        if (result != OMX_ErrorNone) {
+            DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
+        }
+
+        /* Deinit OpenMAX */
+
+        OMX_Deinit();
+
+        pthread_cond_destroy(&cond);
+        pthread_mutex_destroy(&lock);
+            DEBUG_PRINT("*****************************************\n");
+            DEBUG_PRINT("******...AMR ENC TEST COMPLETED...***************\n");
+            DEBUG_PRINT("*****************************************\n");
+        exit(0);
+    }
+}
+
+int Init_Encoder(OMX_STRING audio_component)
+{
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE omxresult;
+    OMX_U32 total = 0;
+    typedef OMX_U8* OMX_U8_PTR;
+    char *role ="audio_encoder";
+
+    static OMX_CALLBACKTYPE call_back = {
+        &EventHandler,&EmptyBufferDone,&FillBufferDone
+    };
+
+    /* Init. the OpenMAX Core */
+    DEBUG_PRINT("\nInitializing OpenMAX Core....\n");
+    omxresult = OMX_Init();
+
+    if(OMX_ErrorNone != omxresult) {
+        DEBUG_PRINT("\n Failed to Init OpenMAX core");
+          return -1;
+    }
+    else {
+        DEBUG_PRINT("\nOpenMAX Core Init Done\n");
+    }
+
+    /* Query for audio decoders*/
+    DEBUG_PRINT("Amr_test: Before entering OMX_GetComponentOfRole");
+    OMX_GetComponentsOfRole(role, &total, 0);
+    DEBUG_PRINT ("\nTotal components of role=%s :%u", role, total);
+
+
+    omxresult = OMX_GetHandle((OMX_HANDLETYPE*)(&amr_enc_handle),
+                        (OMX_STRING)audio_component, NULL, &call_back);
+    if (FAILED(omxresult)) {
+        DEBUG_PRINT("\nFailed to Load the component:%s\n", audio_component);
+    return -1;
+    }
+    else
+    {
+        DEBUG_PRINT("\nComponent %s is in LOADED state\n", audio_component);
+    }
+
+    /* Get the port information */
+    CONFIG_VERSION_SIZE(portParam);
+    omxresult = OMX_GetParameter(amr_enc_handle, OMX_IndexParamAudioInit,
+                                (OMX_PTR)&portParam);
+
+    if(FAILED(omxresult)) {
+        DEBUG_PRINT("\nFailed to get Port Param\n");
+    return -1;
+    }
+    else
+    {
+        DEBUG_PRINT("\nportParam.nPorts:%u\n", portParam.nPorts);
+    DEBUG_PRINT("\nportParam.nStartPortNumber:%u\n",
+                                             portParam.nStartPortNumber);
+    }
+
+    if(OMX_ErrorNone != omxresult)
+    {
+        DEBUG_PRINT("Set parameter failed");
+    }
+
+    return 0;
+}
+
+int Play_Encoder()
+{
+    unsigned int i;
+    int Size=0;
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE ret;
+    OMX_INDEXTYPE index;
+#ifdef __LP64__
+    DEBUG_PRINT("sizeof[%ld]\n", sizeof(OMX_BUFFERHEADERTYPE));
+#else
+    DEBUG_PRINT("sizeof[%d]\n", sizeof(OMX_BUFFERHEADERTYPE));
+#endif
+
+    /* open the i/p and o/p files based on the video file format passed */
+    if(open_audio_file()) {
+        DEBUG_PRINT("\n Returning -1");
+    return -1;
+    }
+
+    /* Query the encoder input min buf requirements */
+    CONFIG_VERSION_SIZE(inputportFmt);
+
+    /* Port for which the Client needs to obtain info */
+    inputportFmt.nPortIndex = portParam.nStartPortNumber;
+
+    OMX_GetParameter(amr_enc_handle,OMX_IndexParamPortDefinition,&inputportFmt);
+    DEBUG_PRINT ("\nEnc Input Buffer Count %u\n", inputportFmt.nBufferCountMin);
+    DEBUG_PRINT ("\nEnc: Input Buffer Size %u\n", inputportFmt.nBufferSize);
+
+    if(OMX_DirInput != inputportFmt.eDir) {
+        DEBUG_PRINT ("\nEnc: Expect Input Port\n");
+    return -1;
+    }
+
+    pcmparam.nPortIndex   = 0;
+    pcmparam.nChannels    =  channels;
+    pcmparam.nSamplingRate = samplerate;
+    OMX_SetParameter(amr_enc_handle,OMX_IndexParamAudioPcm,&pcmparam);
+
+
+    /* Query the encoder outport's min buf requirements */
+    CONFIG_VERSION_SIZE(outputportFmt);
+    /* Port for which the Client needs to obtain info */
+    outputportFmt.nPortIndex = portParam.nStartPortNumber + 1;
+
+    OMX_GetParameter(amr_enc_handle,OMX_IndexParamPortDefinition,&outputportFmt);
+    DEBUG_PRINT ("\nEnc: Output Buffer Count %u\n", outputportFmt.nBufferCountMin);
+    DEBUG_PRINT ("\nEnc: Output Buffer Size %u\n", outputportFmt.nBufferSize);
+
+    if(OMX_DirOutput != outputportFmt.eDir) {
+        DEBUG_PRINT ("\nEnc: Expect Output Port\n");
+    return -1;
+    }
+
+
+    CONFIG_VERSION_SIZE(amrparam);
+
+    amrparam.nPortIndex   =  1;
+    amrparam.nChannels    =  channels; //2 ; /* 1-> mono 2-> stereo*/
+    amrparam.eAMRBandMode = bandmode;
+    amrparam.eAMRDTXMode = dtxenable;
+    OMX_SetParameter(amr_enc_handle,OMX_IndexParamAudioAmr,&amrparam);
+    OMX_GetExtensionIndex(amr_enc_handle,"OMX.Qualcomm.index.audio.sessionId",&index);
+    OMX_GetParameter(amr_enc_handle,index,&streaminfoparam);
+    if(tunnel) {
+    #ifdef AUDIOV2
+    session_id = streaminfoparam.sessionId;
+    control = msm_mixer_open("/dev/snd/controlC0", 0);
+    if(control < 0)
+    printf("ERROR opening the device\n");
+    device_id = msm_get_device(device);
+    DEBUG_PRINT ("\ndevice_id = %d\n",device_id);
+    DEBUG_PRINT("\nsession_id = %d\n",session_id);
+    if (msm_en_device(device_id, 1))
+    {
+        perror("could not enable device\n");
+        return -1;
+    }
+    if (msm_route_stream(DIR_TX,session_id,device_id, 1))
+    {
+        perror("could not set stream routing\n");
+        return -1;
+    }
+    #endif
+    }
+
+    DEBUG_PRINT ("\nOMX_SendCommand Encoder -> IDLE\n");
+    OMX_SendCommand(amr_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
+    /* wait_for_event(); should not wait here event complete status will
+       not come until enough buffer are allocated */
+    if (tunnel == 0)
+    {
+        input_buf_cnt = inputportFmt.nBufferCountActual; //  inputportFmt.nBufferCountMin + 5;
+        DEBUG_PRINT("Transition to Idle State succesful...\n");
+        /* Allocate buffer on decoder's i/p port */
+        error = Allocate_Buffer(amr_enc_handle, &pInputBufHdrs, inputportFmt.nPortIndex,
+                            input_buf_cnt, inputportFmt.nBufferSize);
+        if (error != OMX_ErrorNone || pInputBufHdrs == NULL ) {
+            DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer error\n");
+        return -1;
+    }
+    else {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer success\n");
+    }
+    }
+    output_buf_cnt = outputportFmt.nBufferCountMin ;
+
+    /* Allocate buffer on encoder's O/Pp port */
+    error = Allocate_Buffer(amr_enc_handle, &pOutputBufHdrs, outputportFmt.nPortIndex,
+                            output_buf_cnt, outputportFmt.nBufferSize);
+    if (error != OMX_ErrorNone || pOutputBufHdrs == NULL ) {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer error\n");
+    return -1;
+    }
+    else {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer success\n");
+    }
+
+    wait_for_event();
+
+
+    if (tunnel == 1)
+    {
+        DEBUG_PRINT ("\nOMX_SendCommand to enable TUNNEL MODE during IDLE\n");
+        OMX_SendCommand(amr_enc_handle, OMX_CommandPortDisable,0,0); // disable input port
+        wait_for_event();
+    }
+
+    DEBUG_PRINT ("\nOMX_SendCommand encoder -> Executing\n");
+    OMX_SendCommand(amr_enc_handle, OMX_CommandStateSet, OMX_StateExecuting,0);
+    wait_for_event();
+
+    DEBUG_PRINT(" Start sending OMX_FILLthisbuffer\n");
+
+    for(i=0; i < output_buf_cnt; i++) {
+        DEBUG_PRINT ("\nOMX_FillThisBuffer on output buf no.%d\n",i);
+        pOutputBufHdrs[i]->nOutputPortIndex = 1;
+        pOutputBufHdrs[i]->nFlags = pOutputBufHdrs[i]->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
+        ret = OMX_FillThisBuffer(amr_enc_handle, pOutputBufHdrs[i]);
+        if (OMX_ErrorNone != ret) {
+            DEBUG_PRINT("OMX_FillThisBuffer failed with result %d\n", ret);
+    }
+        else {
+            DEBUG_PRINT("OMX_FillThisBuffer success!\n");
+    }
+    }
+
+if(tunnel == 0)
+{
+    DEBUG_PRINT(" Start sending OMX_emptythisbuffer\n");
+    for (i = 0;i < input_buf_cnt;i++) {
+        DEBUG_PRINT ("\nOMX_EmptyThisBuffer on Input buf no.%d\n",i);
+        pInputBufHdrs[i]->nInputPortIndex = 0;
+        Size = Read_Buffer(pInputBufHdrs[i]);
+        if(Size <=0 ){
+          DEBUG_PRINT("NO DATA READ\n");
+          bInputEosReached = true;
+          pInputBufHdrs[i]->nFlags= OMX_BUFFERFLAG_EOS;
+        }
+        pInputBufHdrs[i]->nFilledLen = (OMX_U32)Size;
+        pInputBufHdrs[i]->nInputPortIndex = 0;
+        used_ip_buf_cnt++;
+        ret = OMX_EmptyThisBuffer(amr_enc_handle, pInputBufHdrs[i]);
+        if (OMX_ErrorNone != ret) {
+            DEBUG_PRINT("OMX_EmptyThisBuffer failed with result %d\n", ret);
+        }
+        else {
+            DEBUG_PRINT("OMX_EmptyThisBuffer success!\n");
+        }
+        if(Size <=0 ){
+            break;//eos reached
+        }
+    }
+    pthread_mutex_lock(&etb_lock);
+    if(etb_done)
+{
+        DEBUG_PRINT("Component is waiting for EBD to be released.\n");
+        etb_event_complete();
+    }
+    else
+    {
+        DEBUG_PRINT("\n****************************\n");
+        DEBUG_PRINT("EBD not yet happened ...\n");
+        DEBUG_PRINT("\n****************************\n");
+        etb_done++;
+    }
+    pthread_mutex_unlock(&etb_lock);
+}
+
+    return 0;
+}
+
+
+
+static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *avc_enc_handle,
+                                       OMX_BUFFERHEADERTYPE  ***pBufHdrs,
+                                       OMX_U32 nPortIndex,
+                                       unsigned int bufCntMin, unsigned int bufSize)
+{
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE error=OMX_ErrorNone;
+    unsigned int bufCnt=0;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)avc_enc_handle;
+    *pBufHdrs= (OMX_BUFFERHEADERTYPE **)
+                   malloc(sizeof(OMX_BUFFERHEADERTYPE*)*bufCntMin);
+
+    for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
+        DEBUG_PRINT("\n OMX_AllocateBuffer No %d \n", bufCnt);
+        error = OMX_AllocateBuffer(amr_enc_handle, &((*pBufHdrs)[bufCnt]),
+                                   nPortIndex, NULL, bufSize);
+    }
+
+    return error;
+}
+
+
+
+
+static int Read_Buffer (OMX_BUFFERHEADERTYPE  *pBufHdr )
+{
+
+    size_t bytes_read=0;
+
+
+    pBufHdr->nFilledLen = 0;
+    pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
+
+     bytes_read = fread(pBufHdr->pBuffer, 1, pBufHdr->nAllocLen , inputBufferFile);
+
+      pBufHdr->nFilledLen = (OMX_U32)bytes_read;
+      // Time stamp logic
+    ((OMX_BUFFERHEADERTYPE *)pBufHdr)->nTimeStamp = \
+
+    (OMX_TICKS) ((total_pcm_bytes * 1000)/(samplerate * channels *2));
+
+       DEBUG_PRINT ("\n--time stamp -- %ld\n",  (unsigned long)((OMX_BUFFERHEADERTYPE *)pBufHdr)->nTimeStamp);
+        if(bytes_read == 0)
+        {
+          pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
+          DEBUG_PRINT ("\nBytes read zero\n");
+        }
+        else
+        {
+            pBufHdr->nFlags = pBufHdr->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
+
+            total_pcm_bytes = (unsigned)(total_pcm_bytes + bytes_read);
+        }
+
+    return (int)bytes_read;;
+}
+
+
+
+//In Encoder this Should Open a PCM or WAV file for input.
+
+static int open_audio_file ()
+{
+    int error_code = 0;
+
+    if (!tunnel)
+    {
+        DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, in_filename);
+        inputBufferFile = fopen (in_filename, "rb");
+        if (inputBufferFile == NULL) {
+            DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
+                                         in_filename);
+            return -1;
+        }
+        if(parse_pcm_header() != 0x00)
+        {
+            DEBUG_PRINT("PCM parser failed \n");
+            return -1;
+        }
+    }
+
+    DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, out_filename);
+    outputBufferFile = fopen (out_filename, "wb");
+    if (outputBufferFile == NULL) {
+        DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
+                                         out_filename);
+    error_code = -1;
+    return error_code;
+    }
+    if(!amrwb_enable) {
+        fseek(outputBufferFile, AMR_HEADER_SIZE, SEEK_SET);
+    } else {
+        fseek(outputBufferFile, AMRWB_HEADER_SIZE, SEEK_SET);
+    }
+    return error_code;
+}
+
+static OMX_ERRORTYPE parse_pcm_header()
+{
+    struct wav_header hdr;
+
+    DEBUG_PRINT("\n***************************************************************\n");
+    if(fread(&hdr, 1, sizeof(hdr),inputBufferFile)!=sizeof(hdr))
+    {
+        DEBUG_PRINT("Wav file cannot read header\n");
+        return -1;
+    }
+
+    if ((hdr.riff_id != ID_RIFF) ||
+        (hdr.riff_fmt != ID_WAVE)||
+        (hdr.fmt_id != ID_FMT))
+    {
+        DEBUG_PRINT("Wav file is not a riff/wave file\n");
+        return -1;
+    }
+
+    if (hdr.audio_format != FORMAT_PCM)
+    {
+        DEBUG_PRINT("Wav file is not adpcm format %d and fmt size is %d\n",
+                      hdr.audio_format, hdr.fmt_sz);
+        return -1;
+    }
+
+    DEBUG_PRINT("Samplerate is %d\n", hdr.sample_rate);
+    DEBUG_PRINT("Channel Count is %d\n", hdr.num_channels);
+    DEBUG_PRINT("\n***************************************************************\n");
+
+    samplerate = hdr.sample_rate;
+    channels = hdr.num_channels;
+    total_pcm_bytes = 0;
+
+    return OMX_ErrorNone;
+}
diff --git a/mm-audio/aenc-evrc/qdsp6/Android.mk b/mm-audio/aenc-evrc/qdsp6/Android.mk
index 9d8d0b7..7d56f5c 100644
--- a/mm-audio/aenc-evrc/qdsp6/Android.mk
+++ b/mm-audio/aenc-evrc/qdsp6/Android.mk
@@ -42,6 +42,28 @@
 
 include $(BUILD_SHARED_LIBRARY)
 
+# ---------------------------------------------------------------------------------
+#             Make the apps-test (mm-aenc-omxevrc-test)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+mm-evrc-enc-test-inc    := $(LOCAL_PATH)/inc
+mm-evrc-enc-test-inc    += $(LOCAL_PATH)/test
+mm-evrc-enc-test-inc    += $(TARGET_OUT_HEADERS)/mm-core/omxcore
+mm-evrc-enc-test-inc     += $(TARGET_OUT_HEADERS)/mm-audio/audio-alsa
+LOCAL_MODULE            := mm-aenc-omxevrc-test
+LOCAL_MODULE_TAGS       := optional
+LOCAL_CFLAGS            := $(libOmxEvrcEnc-def)
+LOCAL_C_INCLUDES        := $(mm-evrc-enc-test-inc)
+LOCAL_PRELINK_MODULE    := false
+LOCAL_SHARED_LIBRARIES  := libmm-omxcore
+LOCAL_SHARED_LIBRARIES  += libOmxEvrcEnc
+LOCAL_SHARED_LIBRARIES  += libaudioalsa
+LOCAL_SRC_FILES         := test/omx_evrc_enc_test.c
+
+include $(BUILD_EXECUTABLE)
+
 endif
 
 # ---------------------------------------------------------------------------------
diff --git a/mm-audio/aenc-evrc/qdsp6/Makefile b/mm-audio/aenc-evrc/qdsp6/Makefile
index 2c9c7bb..d0871de 100644
--- a/mm-audio/aenc-evrc/qdsp6/Makefile
+++ b/mm-audio/aenc-evrc/qdsp6/Makefile
@@ -39,7 +39,7 @@
 # ---------------------------------------------------------------------------------
 #					BUILD
 # ---------------------------------------------------------------------------------
-all: libOmxEvrcEnc.so.$(LIBVER)
+all: libOmxEvrcEnc.so.$(LIBVER) mm-aenc-omxevrc-test
 
 install:
 	echo "intalling aenc-evrc in $(DESTDIR)"
@@ -49,7 +49,8 @@
 	install -m 555 libOmxEvrcEnc.so.$(LIBVER) $(LIBINSTALLDIR)
 	cd $(LIBINSTALLDIR) && ln -s libOmxEvrcEnc.so.$(LIBVER) libOmxEvrcEnc.so.$(LIBMAJOR)
 	cd $(LIBINSTALLDIR) && ln -s libOmxEvrcEnc.so.$(LIBMAJOR) libOmxEvrcEnc.so
-
+	install -m 555 mm-aenc-omxevrc-test $(BININSTALLDIR)
+	
 # ---------------------------------------------------------------------------------
 #				COMPILE LIBRARY
 # ---------------------------------------------------------------------------------
@@ -64,5 +65,17 @@
 	$(CC) $(CPPFLAGS) $(CFLAGS_SO) $(LDFLAGS_SO) -Wl,-soname,libOmxEvrcEnc.so.$(LIBMAJOR) -o $@ $^ $(LDFLAGS) $(LDLIBS)
 
 # ---------------------------------------------------------------------------------
+#				COMPILE TEST APP
+# ---------------------------------------------------------------------------------
+TEST_LDLIBS := -lpthread
+TEST_LDLIBS += -ldl
+TEST_LDLIBS += -lOmxCore
+
+TEST_SRCS := test/omx_evrc_enc_test.c
+
+mm-aenc-omxevrc-test: libOmxEvrcEnc.so.$(LIBVER) $(TEST_SRCS)
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $^ $(TEST_LDLIBS)
+
+# ---------------------------------------------------------------------------------
 #					END
 # ---------------------------------------------------------------------------------
diff --git a/mm-audio/aenc-evrc/qdsp6/test/omx_evrc_enc_test.c b/mm-audio/aenc-evrc/qdsp6/test/omx_evrc_enc_test.c
new file mode 100644
index 0000000..e5f72cc
--- /dev/null
+++ b/mm-audio/aenc-evrc/qdsp6/test/omx_evrc_enc_test.c
@@ -0,0 +1,1171 @@
+
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2014, 2017 The Linux Foundation. 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.
+    * Neither the name of The Linux Foundation nor
+      the names of its contributors may be used to endorse or promote
+      products derived from this software without specific prior written
+      permission.
+
+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, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT 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.
+--------------------------------------------------------------------------*/
+
+
+/*
+    An Open max test application ....
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include "OMX_Core.h"
+#include "OMX_Component.h"
+#include "pthread.h"
+#include <signal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include<unistd.h>
+#include<string.h>
+#include <pthread.h>
+#include "QOMX_AudioExtensions.h"
+#include "QOMX_AudioIndexExtensions.h"
+#ifdef AUDIOV2
+#include "control.h"
+#endif
+
+
+#include <linux/ioctl.h>
+
+typedef unsigned char uint8;
+typedef unsigned char byte;
+typedef unsigned int  uint32;
+typedef unsigned int  uint16;
+QOMX_AUDIO_STREAM_INFO_DATA streaminfoparam;
+/* maximum ADTS frame header length                */
+void Release_Encoder();
+
+#ifdef AUDIOV2
+unsigned short session_id;
+int device_id;
+int control = 0;
+const char *device="handset_tx";
+#define DIR_TX 2
+#endif
+
+uint32_t samplerate = 8000;
+uint32_t channels = 1;
+uint32_t min_bitrate = 0;
+uint32_t max_bitrate = 0;
+uint32_t cdmarate = 0;
+uint32_t rectime = 0;
+uint32_t recpath = 0;
+int32_t pcmplayback = 0;
+uint32_t tunnel      = 0;
+uint32_t format = 1;
+#define DEBUG_PRINT printf
+unsigned to_idle_transition = 0;
+unsigned long total_pcm_bytes;
+
+/************************************************************************/
+/*                GLOBAL INIT                    */
+/************************************************************************/
+
+/************************************************************************/
+/*                #DEFINES                            */
+/************************************************************************/
+#define false 0
+#define true 1
+
+#define CONFIG_VERSION_SIZE(param) \
+    param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\
+    param.nSize = sizeof(param);
+
+#define QCP_HEADER_SIZE sizeof(struct qcp_header)
+#define MIN_BITRATE 4 /* Bit rate 1 - 13.6 , 2 - 6.2 , 3 - 2.7 , 4 - 1.0 kbps*/
+#define MAX_BITRATE 4
+
+#define FAILED(result) (result != OMX_ErrorNone)
+
+#define SUCCEEDED(result) (result == OMX_ErrorNone)
+
+/************************************************************************/
+/*                GLOBAL DECLARATIONS                     */
+/************************************************************************/
+
+pthread_mutex_t lock;
+pthread_cond_t cond;
+pthread_mutex_t elock;
+pthread_cond_t econd;
+pthread_cond_t fcond;
+pthread_mutex_t etb_lock;
+pthread_mutex_t etb_lock1;
+pthread_cond_t etb_cond;
+FILE * inputBufferFile;
+FILE * outputBufferFile;
+OMX_PARAM_PORTDEFINITIONTYPE inputportFmt;
+OMX_PARAM_PORTDEFINITIONTYPE outputportFmt;
+OMX_AUDIO_PARAM_EVRCTYPE evrcparam;
+OMX_AUDIO_PARAM_PCMMODETYPE    pcmparam;
+OMX_PORT_PARAM_TYPE portParam;
+OMX_PORT_PARAM_TYPE portFmt;
+OMX_ERRORTYPE error;
+
+
+
+
+#define ID_RIFF 0x46464952
+#define ID_WAVE 0x45564157
+#define ID_FMT  0x20746d66
+#define ID_DATA 0x61746164
+
+#define FORMAT_PCM 1
+
+struct wav_header {
+  uint32_t riff_id;
+  uint32_t riff_sz;
+  uint32_t riff_fmt;
+  uint32_t fmt_id;
+  uint32_t fmt_sz;
+  uint16_t audio_format;
+  uint16_t num_channels;
+  uint32_t sample_rate;
+  uint32_t byte_rate;       /* sample_rate * num_channels * bps / 8 */
+  uint16_t block_align;     /* num_channels * bps / 8 */
+  uint16_t bits_per_sample;
+  uint32_t data_id;
+  uint32_t data_sz;
+};
+struct enc_meta_out{
+        unsigned int offset_to_frame;
+        unsigned int frame_size;
+        unsigned int encoded_pcm_samples;
+        unsigned int msw_ts;
+        unsigned int lsw_ts;
+        unsigned int nflags;
+} __attribute__ ((packed));
+
+struct qcp_header {
+        /* RIFF Section */
+        char riff[4];
+        unsigned int s_riff;
+        char qlcm[4];
+
+        /* Format chunk */
+        char fmt[4];
+        unsigned int s_fmt;
+        char mjr;
+        char mnr;
+        unsigned int data1;         /* UNIQUE ID of the codec */
+        unsigned short data2;
+        unsigned short data3;
+        char data4[8];
+        unsigned short ver;         /* Codec Info */
+        char name[80];
+        unsigned short abps;    /* average bits per sec of the codec */
+        unsigned short bytes_per_pkt;
+        unsigned short samp_per_block;
+        unsigned short samp_per_sec;
+        unsigned short bits_per_samp;
+        unsigned char vr_num_of_rates;         /* Rate Header fmt info */
+        unsigned char rvd1[3];
+        unsigned short vr_bytes_per_pkt[8];
+        unsigned int rvd2[5];
+
+        /* Vrat chunk */
+        unsigned char vrat[4];
+        unsigned int s_vrat;
+        unsigned int v_rate;
+        unsigned int size_in_pkts;
+
+        /* Data chunk */
+        unsigned char data[4];
+        unsigned int s_data;
+} __attribute__ ((packed));
+
+ /* Common part */
+ static struct qcp_header append_header = {
+         {'R', 'I', 'F', 'F'}, 0, {'Q', 'L', 'C', 'M'},
+         {'f', 'm', 't', ' '}, 150, 1, 0, 0, 0, 0,{0}, 0, {0},0,0,160,8000,16,0,{0},{0},{0},
+         {'v','r','a','t'},0, 0, 0,{'d','a','t','a'},0
+ };
+
+static int totaldatalen = 0;
+static int framecnt = 0;
+/************************************************************************/
+/*                GLOBAL INIT                    */
+/************************************************************************/
+
+unsigned int input_buf_cnt = 0;
+unsigned int output_buf_cnt = 0;
+int used_ip_buf_cnt = 0;
+volatile int event_is_done = 0;
+volatile int ebd_event_is_done = 0;
+volatile int fbd_event_is_done = 0;
+volatile int etb_event_is_done = 0;
+int ebd_cnt;
+int bInputEosReached = 0;
+int bOutputEosReached = 0;
+int bInputEosReached_tunnel = 0;
+static int etb_done = 0;
+int bFlushing = false;
+int bPause    = false;
+const char *in_filename;
+const char *out_filename;
+
+int timeStampLfile = 0;
+int timestampInterval = 100;
+
+//* OMX Spec Version supported by the wrappers. Version = 1.1 */
+const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101;
+OMX_COMPONENTTYPE* evrc_enc_handle = 0;
+
+OMX_BUFFERHEADERTYPE  **pInputBufHdrs = NULL;
+OMX_BUFFERHEADERTYPE  **pOutputBufHdrs = NULL;
+
+/************************************************************************/
+/*                GLOBAL FUNC DECL                        */
+/************************************************************************/
+int Init_Encoder(char*);
+int Play_Encoder();
+OMX_STRING aud_comp;
+
+typedef enum {
+    UINTMAX = 1,
+    UCHARMAX,
+    USHRTMAX
+}datatype;
+
+/**************************************************************************/
+/*                STATIC DECLARATIONS                       */
+/**************************************************************************/
+
+static int open_audio_file ();
+static int Read_Buffer(OMX_BUFFERHEADERTYPE  *pBufHdr );
+static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *evrc_enc_handle,
+                                       OMX_BUFFERHEADERTYPE  ***pBufHdrs,
+                                       OMX_U32 nPortIndex,
+                                       unsigned int bufCntMin, unsigned int bufSize);
+
+
+static OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                                  OMX_IN OMX_PTR pAppData,
+                                  OMX_IN OMX_EVENTTYPE eEvent,
+                                  OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
+                                  OMX_IN OMX_PTR pEventData);
+static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                     OMX_IN OMX_PTR pAppData,
+                                     OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+static OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                     OMX_IN OMX_PTR pAppData,
+                                     OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+static OMX_ERRORTYPE  parse_pcm_header();
+
+int get_input_and_validate(char *input, datatype type)
+{
+    unsigned long int value = 0;
+    char *ptr = NULL;
+    int status = 0;
+
+    errno = 0;
+    ptr = (char *)malloc(strlen(input) + 1);
+    if (ptr == NULL) {
+        DEBUG_PRINT("Low memory\n");
+        status = -1;
+        goto exit;
+    }
+    if (input == NULL){
+        DEBUG_PRINT("No input is given\n");
+        status = -1;
+        goto exit;
+    }
+    /* Check for negative input */
+    if (*input == '-') {
+        DEBUG_PRINT("Negative Number is not allowed\n");
+        status = -1;
+        goto exit;
+    }
+    /* Convert string to unsigned long int */
+    value = strtoul(input, &ptr, 10);
+    if (errno != 0){
+        perror("strtoul");
+        status = errno;
+        goto exit;
+    }
+    /* check if number input is zero or string or string##number or viceversa */
+    if (value == 0 || *ptr != '\0'){
+        DEBUG_PRINT("Input is string+number or Zero or string = %s\n", input);
+        status = -1;
+        goto exit;
+    }
+    /* check for out of range */
+    switch(type) {
+    case 1 :if (value > UINT_MAX) {
+                DEBUG_PRINT("Input is Out of range\n");
+                status = -1;
+            }
+            break;
+    case 2 :if (value > UCHAR_MAX) {
+                DEBUG_PRINT("Input is Out of range\n");
+                status = -1;
+                }
+            break;
+    case 3 :if (value > USHRT_MAX) {
+                DEBUG_PRINT("Input is Out of range\n");
+                status = -1;
+            }
+            break;
+    }
+exit:
+    if (status != 0)
+        exit(0);
+    return value;
+}
+
+void wait_for_event(void)
+{
+    pthread_mutex_lock(&lock);
+    DEBUG_PRINT("%s: event_is_done=%d", __FUNCTION__, event_is_done);
+    while (event_is_done == 0) {
+        pthread_cond_wait(&cond, &lock);
+    }
+    event_is_done = 0;
+    pthread_mutex_unlock(&lock);
+}
+
+void event_complete(void )
+{
+    pthread_mutex_lock(&lock);
+    if (event_is_done == 0) {
+        event_is_done = 1;
+        pthread_cond_broadcast(&cond);
+    }
+    pthread_mutex_unlock(&lock);
+}
+
+void etb_wait_for_event(void)
+{
+    pthread_mutex_lock(&etb_lock1);
+    DEBUG_PRINT("%s: etb_event_is_done=%d", __FUNCTION__, etb_event_is_done);
+    while (etb_event_is_done == 0) {
+        pthread_cond_wait(&etb_cond, &etb_lock1);
+    }
+    etb_event_is_done = 0;
+    pthread_mutex_unlock(&etb_lock1);
+}
+
+void etb_event_complete(void )
+{
+    pthread_mutex_lock(&etb_lock1);
+    if (etb_event_is_done == 0) {
+        etb_event_is_done = 1;
+        pthread_cond_broadcast(&etb_cond);
+    }
+    pthread_mutex_unlock(&etb_lock1);
+}
+
+static void create_qcp_header(int Datasize, int Frames)
+{
+        append_header.s_riff = (unsigned)(Datasize + (int)QCP_HEADER_SIZE - 8);
+        /* exclude riff id and size field */
+    append_header.data1 = 0xe689d48d;
+    append_header.data2 = 0x9076;
+    append_header.data3 = 0x46b5;
+    append_header.data4[0] = 0x91;
+    append_header.data4[1] = 0xef;
+    append_header.data4[2] = 0x73;
+    append_header.data4[3] = 0x6a;
+    append_header.data4[4] = 0x51;
+    append_header.data4[5] = 0x00;
+    append_header.data4[6] = 0xce;
+    append_header.data4[7] = 0xb4;
+    append_header.ver = 0x0001;
+    memcpy(append_header.name, "TIA IS-127 Enhanced Variable Rate Codec, Speech Service Option 3", 64);
+    append_header.abps = 9600;
+    append_header.bytes_per_pkt = 23;
+    append_header.vr_num_of_rates = 4;
+    append_header.vr_bytes_per_pkt[0] = 0x0416;
+    append_header.vr_bytes_per_pkt[1] = 0x030a;
+    append_header.vr_bytes_per_pkt[2] = 0x0200;
+    append_header.vr_bytes_per_pkt[3] = 0x0102;
+    append_header.s_vrat = 0x00000008;
+    append_header.v_rate = 0x00000001;
+        append_header.size_in_pkts = (unsigned)Frames;
+        append_header.s_data = (unsigned)Datasize;
+        return;
+}
+
+OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                           OMX_IN OMX_PTR pAppData,
+                           OMX_IN OMX_EVENTTYPE eEvent,
+                           OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
+                           OMX_IN OMX_PTR pEventData)
+{
+    DEBUG_PRINT("Function %s \n", __FUNCTION__);
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)hComponent;
+    (void)pAppData;
+    (void)pEventData;
+    switch(eEvent) {
+        case OMX_EventCmdComplete:
+        DEBUG_PRINT("\n OMX_EventCmdComplete event=%d data1=%u data2=%u\n",(OMX_EVENTTYPE)eEvent,
+                                                                               nData1,nData2);
+            event_complete();
+        break;
+        case OMX_EventError:
+        DEBUG_PRINT("\n OMX_EventError \n");
+        break;
+         case OMX_EventBufferFlag:
+             DEBUG_PRINT("\n OMX_EventBufferFlag \n");
+             bOutputEosReached = true;
+             event_complete();
+             break;
+        case OMX_EventPortSettingsChanged:
+        DEBUG_PRINT("\n OMX_EventPortSettingsChanged \n");
+        break;
+        default:
+        DEBUG_PRINT("\n Unknown Event \n");
+        break;
+    }
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                              OMX_IN OMX_PTR pAppData,
+                              OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    size_t bytes_writen = 0;
+    size_t total_bytes_writen = 0;
+    size_t len = 0;
+    struct enc_meta_out *meta = NULL;
+    OMX_U8 *src = pBuffer->pBuffer;
+    unsigned int num_of_frames = 1;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)pAppData;
+
+        if(((pBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+            DEBUG_PRINT("FBD::EOS on output port\n ");
+            bOutputEosReached = true;
+            return OMX_ErrorNone;
+        }
+        if(bInputEosReached_tunnel || bOutputEosReached)
+        {
+            DEBUG_PRINT("EOS REACHED NO MORE PROCESSING OF BUFFERS\n");
+            return OMX_ErrorNone;
+        }
+        if(num_of_frames != src[0]){
+
+            printf("Data corrupt\n");
+            return OMX_ErrorNone;
+        }
+        /* Skip the first bytes */
+
+
+
+        src += sizeof(unsigned char);
+        meta = (struct enc_meta_out *)src;
+        while (num_of_frames > 0) {
+            meta = (struct enc_meta_out *)src;
+            /*printf("offset=%d framesize=%d encoded_pcm[%d] msw_ts[%d]lsw_ts[%d] nflags[%d]\n",
+                                                                       meta->offset_to_frame,
+                                                                       meta->frame_size,
+                          meta->encoded_pcm_samples, meta->msw_ts, meta->lsw_ts, meta->nflags);*/
+            len = meta->frame_size;
+
+            bytes_writen = fwrite(pBuffer->pBuffer + sizeof(unsigned char) + meta->offset_to_frame,1,len,outputBufferFile);
+            if(bytes_writen < len)
+            {
+                DEBUG_PRINT("error: invalid EVRC encoded data \n");
+                return OMX_ErrorNone;
+            }
+            src += sizeof(struct enc_meta_out);
+            num_of_frames--;
+            total_bytes_writen += len;
+        }
+        DEBUG_PRINT(" FillBufferDone size writen to file  %zu count %d\n",total_bytes_writen, framecnt);
+        totaldatalen = totaldatalen + (int)total_bytes_writen;
+    framecnt++;
+
+        DEBUG_PRINT(" FBD calling FTB\n");
+        OMX_FillThisBuffer(hComponent,pBuffer);
+
+        return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                              OMX_IN OMX_PTR pAppData,
+                              OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    int readBytes =0;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)pAppData;
+
+    ebd_cnt++;
+    used_ip_buf_cnt--;
+    pthread_mutex_lock(&etb_lock);
+    if(!etb_done)
+    {
+        DEBUG_PRINT("\n*********************************************\n");
+        DEBUG_PRINT("Wait till first set of buffers are given to component\n");
+        DEBUG_PRINT("\n*********************************************\n");
+        etb_done++;
+        pthread_mutex_unlock(&etb_lock);
+        etb_wait_for_event();
+    }
+    else
+    {
+        pthread_mutex_unlock(&etb_lock);
+    }
+
+
+    if(bInputEosReached)
+    {
+        DEBUG_PRINT("\n*********************************************\n");
+        DEBUG_PRINT("   EBD::EOS on input port\n ");
+        DEBUG_PRINT("*********************************************\n");
+        return OMX_ErrorNone;
+    }else if (bFlushing == true) {
+      DEBUG_PRINT("omx_evrc13_adec_test: bFlushing is set to TRUE used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
+      if (used_ip_buf_cnt == 0) {
+        bFlushing = false;
+      } else {
+        DEBUG_PRINT("omx_evrc13_adec_test: more buffer to come back used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
+        return OMX_ErrorNone;
+      }
+    }
+
+    if((readBytes = Read_Buffer(pBuffer)) > 0) {
+        pBuffer->nFilledLen = (OMX_U32)readBytes;
+        used_ip_buf_cnt++;
+        OMX_EmptyThisBuffer(hComponent,pBuffer);
+    }
+    else{
+        pBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
+        used_ip_buf_cnt++;
+        bInputEosReached = true;
+        pBuffer->nFilledLen = 0;
+        OMX_EmptyThisBuffer(hComponent,pBuffer);
+        DEBUG_PRINT("EBD..Either EOS or Some Error while reading file\n");
+    }
+    return OMX_ErrorNone;
+}
+
+void signal_handler(int sig_id) {
+
+  /* Flush */
+  if (sig_id == SIGUSR1) {
+    DEBUG_PRINT("%s Initiate flushing\n", __FUNCTION__);
+    bFlushing = true;
+    OMX_SendCommand(evrc_enc_handle, OMX_CommandFlush, OMX_ALL, NULL);
+  } else if (sig_id == SIGUSR2) {
+    if (bPause == true) {
+      DEBUG_PRINT("%s resume record\n", __FUNCTION__);
+      bPause = false;
+      OMX_SendCommand(evrc_enc_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
+    } else {
+      DEBUG_PRINT("%s pause record\n", __FUNCTION__);
+      bPause = true;
+      OMX_SendCommand(evrc_enc_handle, OMX_CommandStateSet, OMX_StatePause, NULL);
+    }
+  }
+}
+
+int main(int argc, char **argv)
+{
+     unsigned int bufCnt=0;
+     OMX_ERRORTYPE result;
+
+    struct sigaction sa;
+
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_handler = &signal_handler;
+    sigaction(SIGABRT, &sa, NULL);
+    sigaction(SIGUSR1, &sa, NULL);
+    sigaction(SIGUSR2, &sa, NULL);
+
+   (void) signal(SIGINT, Release_Encoder);
+
+    pthread_cond_init(&cond, 0);
+    pthread_mutex_init(&lock, 0);
+    pthread_cond_init(&etb_cond, 0);
+    pthread_mutex_init(&etb_lock, 0);
+    pthread_mutex_init(&etb_lock1, 0);
+
+    if (argc >= 9) {
+        in_filename = argv[1];
+        out_filename = argv[2];
+	if (in_filename == NULL || out_filename == NULL) {
+		DEBUG_PRINT("Invalid %s filename\n", in_filename ? "Output":"Input");
+		return 0;
+	}
+	tunnel =  (uint32_t)atoi(argv[3]);
+        min_bitrate  = (uint32_t)atoi(argv[4]);
+        max_bitrate  = (uint32_t)atoi(argv[5]);
+        cdmarate     = (uint32_t)atoi(argv[6]);
+        recpath      = (uint32_t)atoi(argv[7]); // No configuration support yet..
+        rectime      = (uint32_t)get_input_and_validate(argv[8], UINTMAX);
+
+    } else {
+          DEBUG_PRINT(" invalid format: \n");
+          DEBUG_PRINT("ex: ./mm-aenc-omxevrc-test INPUTFILE OUTPUTFILE Tunnel MINRATE MAXRATE CDMARATE RECORDPATH RECORDTIME\n");
+          DEBUG_PRINT("MINRATE MAXRATE and CDMARATE 1 to 4\n");
+          DEBUG_PRINT("RECORDPATH 0(TX),1(RX),2(BOTH),3(MIC)\n");
+          DEBUG_PRINT("RECORDTIME in seconds for AST Automation\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.evrc";
+    else
+        aud_comp = "OMX.qcom.audio.encoder.tunneled.evrc";
+    if(Init_Encoder(aud_comp)!= 0x00)
+    {
+        DEBUG_PRINT("Decoder Init failed\n");
+        return -1;
+    }
+
+    fcntl(0, F_SETFL, O_NONBLOCK);
+
+    if(Play_Encoder() != 0x00)
+    {
+        DEBUG_PRINT("Play_Decoder failed\n");
+        return -1;
+    }
+
+    // Wait till EOS is reached...
+        if(rectime && tunnel)
+        {
+            sleep(rectime);
+            rectime = 0;
+            bInputEosReached_tunnel = 1;
+            DEBUG_PRINT("\EOS ON INPUT PORT\n");
+        }
+        else
+        {
+            wait_for_event();
+        }
+
+        if((bInputEosReached_tunnel) || ((bOutputEosReached) && !tunnel))
+        {
+
+            DEBUG_PRINT("\nMoving the decoder to idle state \n");
+            OMX_SendCommand(evrc_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
+            wait_for_event();
+
+            DEBUG_PRINT("\nMoving the encoder to loaded state \n");
+            OMX_SendCommand(evrc_enc_handle, OMX_CommandStateSet, OMX_StateLoaded,0);
+            sleep(1);
+            if (!tunnel)
+            {
+                DEBUG_PRINT("\nFillBufferDone: Deallocating i/p buffers \n");
+                for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt) {
+                    OMX_FreeBuffer(evrc_enc_handle, 0, pInputBufHdrs[bufCnt]);
+                }
+            }
+
+            DEBUG_PRINT ("\nFillBufferDone: Deallocating o/p buffers \n");
+            for(bufCnt=0; bufCnt < output_buf_cnt; ++bufCnt) {
+                OMX_FreeBuffer(evrc_enc_handle, 1, pOutputBufHdrs[bufCnt]);
+            }
+            wait_for_event();
+            create_qcp_header(totaldatalen, framecnt);
+        fseek(outputBufferFile, 0,SEEK_SET);
+            fwrite(&append_header,1,QCP_HEADER_SIZE,outputBufferFile);
+
+
+            result = OMX_FreeHandle(evrc_enc_handle);
+            if (result != OMX_ErrorNone) {
+                DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
+            }
+
+            /* Deinit OpenMAX */
+        if(tunnel)
+        {
+            #ifdef AUDIOV2
+            if (msm_route_stream(DIR_TX,session_id,device_id, 0))
+            {
+                DEBUG_PRINT("\ncould not set stream routing\n");
+                return -1;
+            }
+            if (msm_en_device(device_id, 0))
+            {
+                DEBUG_PRINT("\ncould not enable device\n");
+                return -1;
+            }
+            msm_mixer_close();
+            #endif
+        }
+            OMX_Deinit();
+            ebd_cnt=0;
+            bOutputEosReached = false;
+            bInputEosReached_tunnel = false;
+            bInputEosReached = 0;
+            evrc_enc_handle = NULL;
+            pthread_cond_destroy(&cond);
+            pthread_mutex_destroy(&lock);
+            fclose(outputBufferFile);
+            DEBUG_PRINT("*****************************************\n");
+            DEBUG_PRINT("******...EVRC ENC TEST COMPLETED...***************\n");
+            DEBUG_PRINT("*****************************************\n");
+        }
+        return 0;
+}
+
+void Release_Encoder()
+{
+    static int cnt=0;
+    OMX_ERRORTYPE result;
+
+    DEBUG_PRINT("END OF EVRC ENCODING: EXITING PLEASE WAIT\n");
+    bInputEosReached_tunnel = 1;
+    event_complete();
+    cnt++;
+    if(cnt > 1)
+    {
+        /* FORCE RESET  */
+        evrc_enc_handle = NULL;
+        ebd_cnt=0;
+        bInputEosReached_tunnel = false;
+
+        result = OMX_FreeHandle(evrc_enc_handle);
+        if (result != OMX_ErrorNone) {
+            DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
+        }
+
+        /* Deinit OpenMAX */
+
+        OMX_Deinit();
+
+        pthread_cond_destroy(&cond);
+        pthread_mutex_destroy(&lock);
+            DEBUG_PRINT("*****************************************\n");
+            DEBUG_PRINT("******...EVRC ENC TEST COMPLETED...***************\n");
+            DEBUG_PRINT("*****************************************\n");
+        exit(0);
+    }
+}
+
+int Init_Encoder(OMX_STRING audio_component)
+{
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE omxresult;
+    OMX_U32 total = 0;
+    typedef OMX_U8* OMX_U8_PTR;
+    char *role ="audio_encoder";
+
+    static OMX_CALLBACKTYPE call_back = {
+        &EventHandler,&EmptyBufferDone,&FillBufferDone
+    };
+
+    /* Init. the OpenMAX Core */
+    DEBUG_PRINT("\nInitializing OpenMAX Core....\n");
+    omxresult = OMX_Init();
+
+    if(OMX_ErrorNone != omxresult) {
+        DEBUG_PRINT("\n Failed to Init OpenMAX core");
+          return -1;
+    }
+    else {
+        DEBUG_PRINT("\nOpenMAX Core Init Done\n");
+    }
+
+    /* Query for audio decoders*/
+    DEBUG_PRINT("Evrc_test: Before entering OMX_GetComponentOfRole");
+    OMX_GetComponentsOfRole(role, &total, 0);
+    DEBUG_PRINT ("\nTotal components of role=%s :%u", role, total);
+
+
+    omxresult = OMX_GetHandle((OMX_HANDLETYPE*)(&evrc_enc_handle),
+                        (OMX_STRING)audio_component, NULL, &call_back);
+    if (FAILED(omxresult)) {
+        DEBUG_PRINT("\nFailed to Load the component:%s\n", audio_component);
+    return -1;
+    }
+    else
+    {
+        DEBUG_PRINT("\nComponent %s is in LOADED state\n", audio_component);
+    }
+
+    /* Get the port information */
+    CONFIG_VERSION_SIZE(portParam);
+    omxresult = OMX_GetParameter(evrc_enc_handle, OMX_IndexParamAudioInit,
+                                (OMX_PTR)&portParam);
+
+    if(FAILED(omxresult)) {
+        DEBUG_PRINT("\nFailed to get Port Param\n");
+    return -1;
+    }
+    else
+    {
+        DEBUG_PRINT("\nportParam.nPorts:%u\n", portParam.nPorts);
+    DEBUG_PRINT("\nportParam.nStartPortNumber:%u\n",
+                                             portParam.nStartPortNumber);
+    }
+
+    if(OMX_ErrorNone != omxresult)
+    {
+        DEBUG_PRINT("Set parameter failed");
+    }
+
+    return 0;
+}
+
+int Play_Encoder()
+{
+    unsigned int i;
+    int Size=0;
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE ret;
+    OMX_INDEXTYPE index;
+#ifdef __LP64__
+    DEBUG_PRINT("sizeof[%ld]\n", sizeof(OMX_BUFFERHEADERTYPE));
+#else
+    DEBUG_PRINT("sizeof[%d]\n", sizeof(OMX_BUFFERHEADERTYPE));
+#endif
+
+    /* open the i/p and o/p files based on the video file format passed */
+    if(open_audio_file()) {
+        DEBUG_PRINT("\n Returning -1");
+    return -1;
+    }
+
+    /* Query the encoder input min buf requirements */
+    CONFIG_VERSION_SIZE(inputportFmt);
+
+    /* Port for which the Client needs to obtain info */
+    inputportFmt.nPortIndex = portParam.nStartPortNumber;
+
+    OMX_GetParameter(evrc_enc_handle,OMX_IndexParamPortDefinition,&inputportFmt);
+    DEBUG_PRINT ("\nEnc Input Buffer Count %u\n", inputportFmt.nBufferCountMin);
+    DEBUG_PRINT ("\nEnc: Input Buffer Size %u\n", inputportFmt.nBufferSize);
+
+    if(OMX_DirInput != inputportFmt.eDir) {
+        DEBUG_PRINT ("\nEnc: Expect Input Port\n");
+    return -1;
+    }
+
+    pcmparam.nPortIndex   = 0;
+    pcmparam.nChannels    =  channels;
+    pcmparam.nSamplingRate = samplerate;
+    OMX_SetParameter(evrc_enc_handle,OMX_IndexParamAudioPcm,&pcmparam);
+
+
+    /* Query the encoder outport's min buf requirements */
+    CONFIG_VERSION_SIZE(outputportFmt);
+    /* Port for which the Client needs to obtain info */
+    outputportFmt.nPortIndex = portParam.nStartPortNumber + 1;
+
+    OMX_GetParameter(evrc_enc_handle,OMX_IndexParamPortDefinition,&outputportFmt);
+    DEBUG_PRINT ("\nEnc: Output Buffer Count %u\n", outputportFmt.nBufferCountMin);
+    DEBUG_PRINT ("\nEnc: Output Buffer Size %u\n", outputportFmt.nBufferSize);
+
+    if(OMX_DirOutput != outputportFmt.eDir) {
+        DEBUG_PRINT ("\nEnc: Expect Output Port\n");
+    return -1;
+    }
+
+
+    CONFIG_VERSION_SIZE(evrcparam);
+
+    evrcparam.nPortIndex   =  1;
+    evrcparam.nChannels    =  channels; //2 ; /* 1-> mono 2-> stereo*/
+    evrcparam.nMinBitRate = min_bitrate;
+    evrcparam.nMaxBitRate = max_bitrate;
+    OMX_SetParameter(evrc_enc_handle,OMX_IndexParamAudioEvrc,&evrcparam);
+    OMX_GetExtensionIndex(evrc_enc_handle,"OMX.Qualcomm.index.audio.sessionId",&index);
+    OMX_GetParameter(evrc_enc_handle,index,&streaminfoparam);
+    if(tunnel) {
+    #ifdef AUDIOV2
+    session_id = streaminfoparam.sessionId;
+    control = msm_mixer_open("/dev/snd/controlC0", 0);
+    if(control < 0)
+    printf("ERROR opening the device\n");
+    device_id = msm_get_device(device);
+    DEBUG_PRINT ("\ndevice_id = %d\n",device_id);
+    DEBUG_PRINT("\nsession_id = %d\n",session_id);
+    if (msm_en_device(device_id, 1))
+    {
+        perror("could not enable device\n");
+        return -1;
+    }
+    if (msm_route_stream(DIR_TX,session_id,device_id, 1))
+    {
+        perror("could not set stream routing\n");
+        return -1;
+    }
+    #endif
+    }
+
+    DEBUG_PRINT ("\nOMX_SendCommand Encoder -> IDLE\n");
+    OMX_SendCommand(evrc_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
+    /* wait_for_event(); should not wait here event complete status will
+       not come until enough buffer are allocated */
+    if (tunnel == 0)
+    {
+        input_buf_cnt = inputportFmt.nBufferCountActual; //  inputportFmt.nBufferCountMin + 5;
+        DEBUG_PRINT("Transition to Idle State succesful...\n");
+        /* Allocate buffer on decoder's i/p port */
+        error = Allocate_Buffer(evrc_enc_handle, &pInputBufHdrs, inputportFmt.nPortIndex,
+                            input_buf_cnt, inputportFmt.nBufferSize);
+        if (error != OMX_ErrorNone || pInputBufHdrs == NULL) {
+            DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer error\n");
+        return -1;
+    }
+    else {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer success\n");
+    }
+    }
+    output_buf_cnt = outputportFmt.nBufferCountMin ;
+
+    /* Allocate buffer on encoder's O/Pp port */
+    error = Allocate_Buffer(evrc_enc_handle, &pOutputBufHdrs, outputportFmt.nPortIndex,
+                            output_buf_cnt, outputportFmt.nBufferSize);
+    if (error != OMX_ErrorNone || pOutputBufHdrs == NULL) {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer error\n");
+    return -1;
+    }
+    else {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer success\n");
+    }
+
+    wait_for_event();
+
+
+    if (tunnel == 1)
+    {
+        DEBUG_PRINT ("\nOMX_SendCommand to enable TUNNEL MODE during IDLE\n");
+        OMX_SendCommand(evrc_enc_handle, OMX_CommandPortDisable,0,0); // disable input port
+        wait_for_event();
+    }
+
+    DEBUG_PRINT ("\nOMX_SendCommand encoder -> Executing\n");
+    OMX_SendCommand(evrc_enc_handle, OMX_CommandStateSet, OMX_StateExecuting,0);
+    wait_for_event();
+
+    DEBUG_PRINT(" Start sending OMX_FILLthisbuffer\n");
+
+    for(i=0; i < output_buf_cnt; i++) {
+        DEBUG_PRINT ("\nOMX_FillThisBuffer on output buf no.%d\n",i);
+        pOutputBufHdrs[i]->nOutputPortIndex = 1;
+        pOutputBufHdrs[i]->nFlags = pOutputBufHdrs[i]->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
+        ret = OMX_FillThisBuffer(evrc_enc_handle, pOutputBufHdrs[i]);
+        if (OMX_ErrorNone != ret) {
+            DEBUG_PRINT("OMX_FillThisBuffer failed with result %d\n", ret);
+    }
+        else {
+            DEBUG_PRINT("OMX_FillThisBuffer success!\n");
+    }
+    }
+
+if(tunnel == 0)
+{
+    DEBUG_PRINT(" Start sending OMX_emptythisbuffer\n");
+    for (i = 0;i < input_buf_cnt;i++) {
+        DEBUG_PRINT ("\nOMX_EmptyThisBuffer on Input buf no.%d\n",i);
+        pInputBufHdrs[i]->nInputPortIndex = 0;
+        Size = Read_Buffer(pInputBufHdrs[i]);
+        if(Size <=0 ){
+          DEBUG_PRINT("NO DATA READ\n");
+          bInputEosReached = true;
+          pInputBufHdrs[i]->nFlags= OMX_BUFFERFLAG_EOS;
+        }
+        pInputBufHdrs[i]->nFilledLen = (OMX_U32)Size;
+        pInputBufHdrs[i]->nInputPortIndex = 0;
+        used_ip_buf_cnt++;
+        ret = OMX_EmptyThisBuffer(evrc_enc_handle, pInputBufHdrs[i]);
+        if (OMX_ErrorNone != ret) {
+            DEBUG_PRINT("OMX_EmptyThisBuffer failed with result %d\n", ret);
+        }
+        else {
+            DEBUG_PRINT("OMX_EmptyThisBuffer success!\n");
+        }
+        if(Size <=0 ){
+            break;//eos reached
+        }
+    }
+    pthread_mutex_lock(&etb_lock);
+    if(etb_done)
+{
+        DEBUG_PRINT("Component is waiting for EBD to be released.\n");
+        etb_event_complete();
+    }
+    else
+    {
+        DEBUG_PRINT("\n****************************\n");
+        DEBUG_PRINT("EBD not yet happened ...\n");
+        DEBUG_PRINT("\n****************************\n");
+        etb_done++;
+    }
+    pthread_mutex_unlock(&etb_lock);
+}
+
+    return 0;
+}
+
+
+
+static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *avc_enc_handle,
+                                       OMX_BUFFERHEADERTYPE  ***pBufHdrs,
+                                       OMX_U32 nPortIndex,
+                                       unsigned int bufCntMin, unsigned int bufSize)
+{
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE error=OMX_ErrorNone;
+    unsigned int bufCnt=0;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)avc_enc_handle;
+    *pBufHdrs= (OMX_BUFFERHEADERTYPE **)
+                   malloc(sizeof(OMX_BUFFERHEADERTYPE*)*bufCntMin);
+
+    for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
+        DEBUG_PRINT("\n OMX_AllocateBuffer No %d \n", bufCnt);
+        error = OMX_AllocateBuffer(evrc_enc_handle, &((*pBufHdrs)[bufCnt]),
+                                   nPortIndex, NULL, bufSize);
+    }
+
+    return error;
+}
+
+
+
+
+static int Read_Buffer (OMX_BUFFERHEADERTYPE  *pBufHdr )
+{
+
+    size_t bytes_read=0;
+
+
+    pBufHdr->nFilledLen = 0;
+    pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
+
+     bytes_read = fread(pBufHdr->pBuffer, 1, pBufHdr->nAllocLen , inputBufferFile);
+
+      pBufHdr->nFilledLen = (OMX_U32)bytes_read;
+      // Time stamp logic
+    ((OMX_BUFFERHEADERTYPE *)pBufHdr)->nTimeStamp = \
+
+    (OMX_TICKS) ((total_pcm_bytes * 1000)/(samplerate * channels *2));
+
+       DEBUG_PRINT ("\n--time stamp -- %ld\n",  (unsigned long)((OMX_BUFFERHEADERTYPE *)pBufHdr)->nTimeStamp);
+        if(bytes_read == 0)
+        {
+          pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
+          DEBUG_PRINT ("\nBytes read zero\n");
+        }
+        else
+        {
+            pBufHdr->nFlags = pBufHdr->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
+
+            total_pcm_bytes = (unsigned)(total_pcm_bytes + bytes_read);
+        }
+
+    return (int)bytes_read;;
+}
+
+
+
+//In Encoder this Should Open a PCM or WAV file for input.
+
+static int open_audio_file ()
+{
+    int error_code = 0;
+
+    if (!tunnel)
+    {
+        DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, in_filename);
+        inputBufferFile = fopen (in_filename, "rb");
+        if (inputBufferFile == NULL) {
+            DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
+                                         in_filename);
+            return -1;
+        }
+        if(parse_pcm_header() != 0x00)
+        {
+            DEBUG_PRINT("PCM parser failed \n");
+            return -1;
+        }
+    }
+
+    DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, out_filename);
+    outputBufferFile = fopen (out_filename, "wb");
+    if (outputBufferFile == NULL) {
+        DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
+                                         out_filename);
+    error_code = -1;
+    return error_code;
+    }
+    fseek(outputBufferFile, QCP_HEADER_SIZE, SEEK_SET);
+    return error_code;
+}
+
+static OMX_ERRORTYPE parse_pcm_header()
+{
+    struct wav_header hdr;
+
+    DEBUG_PRINT("\n***************************************************************\n");
+    if(fread(&hdr, 1, sizeof(hdr),inputBufferFile)!=sizeof(hdr))
+    {
+        DEBUG_PRINT("Wav file cannot read header\n");
+        return -1;
+    }
+
+    if ((hdr.riff_id != ID_RIFF) ||
+        (hdr.riff_fmt != ID_WAVE)||
+        (hdr.fmt_id != ID_FMT))
+    {
+        DEBUG_PRINT("Wav file is not a riff/wave file\n");
+        return -1;
+    }
+
+    if (hdr.audio_format != FORMAT_PCM)
+    {
+        DEBUG_PRINT("Wav file is not adpcm format %d and fmt size is %d\n",
+                      hdr.audio_format, hdr.fmt_sz);
+        return -1;
+    }
+
+    DEBUG_PRINT("Samplerate is %d\n", hdr.sample_rate);
+    DEBUG_PRINT("Channel Count is %d\n", hdr.num_channels);
+    DEBUG_PRINT("\n***************************************************************\n");
+
+    samplerate = hdr.sample_rate;
+    channels = hdr.num_channels;
+    total_pcm_bytes = 0;
+
+    return OMX_ErrorNone;
+}
diff --git a/mm-audio/aenc-g711/qdsp6/Android.mk b/mm-audio/aenc-g711/qdsp6/Android.mk
index 4a6cc03..62dc09a 100644
--- a/mm-audio/aenc-g711/qdsp6/Android.mk
+++ b/mm-audio/aenc-g711/qdsp6/Android.mk
@@ -44,6 +44,28 @@
 
 include $(BUILD_SHARED_LIBRARY)
 
+
+# ---------------------------------------------------------------------------------
+#             Make the apps-test (mm-aenc-omxg711-test)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+mm-g711-enc-test-inc   := $(LOCAL_PATH)/inc
+mm-g711-enc-test-inc   += $(LOCAL_PATH)/test
+mm-g711-enc-test-inc   += $(TARGET_OUT_HEADERS)/mm-core/omxcore
+
+LOCAL_MODULE            := mm-aenc-omxg711-test
+LOCAL_MODULE_TAGS       := optional
+LOCAL_CFLAGS            := $(libOmxG711Enc-def)
+LOCAL_C_INCLUDES        := $(mm-g711-enc-test-inc)
+LOCAL_PRELINK_MODULE    := false
+LOCAL_SHARED_LIBRARIES  := libmm-omxcore
+LOCAL_SHARED_LIBRARIES  += libOmxG711Enc
+LOCAL_SRC_FILES         := test/omx_g711_enc_test.c
+
+include $(BUILD_EXECUTABLE)
+
 endif
 
 # ---------------------------------------------------------------------------------
diff --git a/mm-audio/aenc-g711/qdsp6/Makefile b/mm-audio/aenc-g711/qdsp6/Makefile
index f6bd921..80dd4e5 100644
--- a/mm-audio/aenc-g711/qdsp6/Makefile
+++ b/mm-audio/aenc-g711/qdsp6/Makefile
@@ -39,7 +39,7 @@
 # ---------------------------------------------------------------------------------
 #					BUILD
 # ---------------------------------------------------------------------------------
-all: libOmxG711Enc.so.$(LIBVER)
+all: libOmxG711Enc.so.$(LIBVER) mm-aenc-omxg711-test
 
 install:
 	echo "intalling aenc-g711 in $(DESTDIR)"
@@ -49,6 +49,7 @@
 	install -m 555 libOmxG711Enc.so.$(LIBVER) $(LIBINSTALLDIR)
 	cd $(LIBINSTALLDIR) && ln -s libOmxG711Enc.so.$(LIBVER) libOmxG711Enc.so.$(LIBMAJOR)
 	cd $(LIBINSTALLDIR) && ln -s libOmxG711Enc.so.$(LIBMAJOR) libOmxG711Enc.so
+	install -m 555 mm-aenc-omxg711-test $(BININSTALLDIR)
 
 # ---------------------------------------------------------------------------------
 #				COMPILE LIBRARY
@@ -64,5 +65,17 @@
 	$(CC) $(CPPFLAGS) $(CFLAGS_SO) $(LDFLAGS_SO) -Wl,-soname,libOmxG711Enc.so.$(LIBMAJOR) -o $@ $^ $(LDFLAGS) $(LDLIBS)
 
 # ---------------------------------------------------------------------------------
+#				COMPILE TEST APP
+# ---------------------------------------------------------------------------------
+TEST_LDLIBS := -lpthread
+TEST_LDLIBS += -ldl
+TEST_LDLIBS += -lOmxCore
+
+#TEST_SRCS := test/omx_g711_enc_test.c
+
+mm-aenc-omxg711-test: libOmxG711Enc.so.$(LIBVER) $(TEST_SRCS)
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $^ $(TEST_LDLIBS)
+
+# ---------------------------------------------------------------------------------
 #					END
 # ---------------------------------------------------------------------------------
diff --git a/mm-audio/aenc-g711/qdsp6/Makefile.am b/mm-audio/aenc-g711/qdsp6/Makefile.am
index 688bae8..f5ccca8 100644
--- a/mm-audio/aenc-g711/qdsp6/Makefile.am
+++ b/mm-audio/aenc-g711/qdsp6/Makefile.am
@@ -23,3 +23,8 @@
 libOmxG711Enc_la_CPPFLAGS = $(AM_CFLAGS) -Dstrlcpy=g_strlcpy $(GLIB_CFLAGS) -include glib.h
 libOmxG711Enc_la_LIBADD = $(GLIB_LIBS) -lcutils -llog -lstdc++
 libOmxG711Enc_la_LDFLAGS = -shared -avoid-version
+
+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/aenc-g711/qdsp6/test/omx_g711_enc_test.c b/mm-audio/aenc-g711/qdsp6/test/omx_g711_enc_test.c
new file mode 100644
index 0000000..8815818
--- /dev/null
+++ b/mm-audio/aenc-g711/qdsp6/test/omx_g711_enc_test.c
@@ -0,0 +1,1030 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010, 2014, 2016-2017 The Linux Foundation. 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.
+    * Neither the name of The Linux Foundation nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+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.
+--------------------------------------------------------------------------*/
+
+
+/*
+    An Open max test application ....
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include "OMX_Core.h"
+#include "OMX_Component.h"
+#include "pthread.h"
+#include <signal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include<unistd.h>
+#include<string.h>
+#include <pthread.h>
+#include "QOMX_AudioExtensions.h"
+#include "QOMX_AudioIndexExtensions.h"
+#include <linux/ioctl.h>
+
+typedef unsigned char uint8;
+typedef unsigned char byte;
+typedef unsigned int  uint32;
+typedef unsigned int  uint16;
+
+QOMX_AUDIO_STREAM_INFO_DATA streaminfoparam;
+
+void Release_Encoder();
+
+#ifdef AUDIOV2
+unsigned short session_id;
+int device_id;
+int control = 0;
+const char *device="handset_tx";
+#define DIR_TX 2
+#endif
+
+#define MIN(A,B)    (((A) < (B))?(A):(B))
+
+FILE *F1 = NULL;
+
+uint32_t channels    = 1;
+uint32_t samplerate  = 8000;
+uint32_t pcmplayback = 0;
+uint32_t tunnel      = 0;
+uint32_t rectime     = 0;
+uint32_t encode_format        = 0;
+#define DEBUG_PRINT printf
+unsigned to_idle_transition = 0;
+
+
+/************************************************************************/
+/*                #DEFINES                            */
+/************************************************************************/
+#define false 0
+#define true 1
+
+#define CONFIG_VERSION_SIZE(param) \
+    param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\
+    param.nSize = sizeof(param);
+
+#define FAILED(result) (result != OMX_ErrorNone)
+
+#define SUCCEEDED(result) (result == OMX_ErrorNone)
+
+/************************************************************************/
+/*                GLOBAL DECLARATIONS                     */
+/************************************************************************/
+
+pthread_mutex_t lock;
+pthread_cond_t cond;
+pthread_mutex_t elock;
+pthread_cond_t econd;
+pthread_cond_t fcond;
+pthread_mutex_t etb_lock;
+pthread_mutex_t etb_lock1;
+pthread_cond_t etb_cond;
+FILE * inputBufferFile;
+FILE * outputBufferFile;
+OMX_PARAM_PORTDEFINITIONTYPE inputportFmt;
+OMX_PARAM_PORTDEFINITIONTYPE outputportFmt;
+OMX_AUDIO_PARAM_PCMMODETYPE pcmParams;
+OMX_PORT_PARAM_TYPE portParam;
+OMX_ERRORTYPE error;
+
+
+
+
+#define ID_RIFF 0x46464952
+#define ID_WAVE 0x45564157
+#define ID_FMT  0x20746d66
+#define ID_DATA 0x61746164
+#define ID_FACT 0x74636166
+
+#define FORMAT_PCM   0x0001
+#define FORMAT_ALAW  0x0006
+#define FORMAT_MULAW 0x0007
+
+struct wav_header {
+  uint32_t riff_id;
+  uint32_t riff_sz;
+  uint32_t riff_fmt;
+  uint32_t fmt_id;
+  uint32_t fmt_sz;
+  uint16_t audio_format;
+  uint16_t num_channels;
+  uint32_t sample_rate;
+  uint32_t byte_rate;       /* sample_rate * num_channels * bps / 8 */
+  uint16_t block_align;     /* num_channels * bps / 8 */
+  uint16_t bits_per_sample;
+  uint32_t data_id;
+  uint32_t data_sz;
+};
+
+struct __attribute__((__packed__)) g711_header {
+  uint32_t riff_id;
+  uint32_t riff_sz;
+  uint32_t riff_fmt;
+  uint32_t fmt_id;
+  uint32_t fmt_sz;
+  uint16_t audio_format;
+  uint16_t num_channels;
+  uint32_t sample_rate;
+  uint32_t byte_rate;       /* sample_rate * num_channels * bps / 8 */
+  uint16_t block_align;     /* num_channels * bps / 8 */
+  uint16_t bits_per_sample;
+  uint16_t extension_size;
+  uint32_t fact_id;
+  uint32_t fact_sz;
+  uint32_t sample_length;
+  uint32_t data_id;
+  uint32_t data_sz;
+};
+
+struct enc_meta_out{
+        unsigned int offset_to_frame;
+        unsigned int frame_size;
+        unsigned int encoded_pcm_samples;
+        unsigned int msw_ts;
+        unsigned int lsw_ts;
+        unsigned int nflags;
+} __attribute__ ((packed));
+
+static int totaldatalen = 0;
+
+static struct wav_header hdr;
+static struct g711_header g711hdr;
+/************************************************************************/
+/*                GLOBAL INIT                    */
+/************************************************************************/
+
+unsigned int input_buf_cnt = 0;
+unsigned int output_buf_cnt = 0;
+int used_ip_buf_cnt = 0;
+volatile int event_is_done = 0;
+volatile int ebd_event_is_done = 0;
+volatile int fbd_event_is_done = 0;
+volatile int etb_event_is_done = 0;
+int ebd_cnt;
+int bInputEosReached = 0;
+int bOutputEosReached = 0;
+int bInputEosReached_tunnel = 0;
+static int etb_done = 0;
+int bFlushing = false;
+int bPause    = false;
+const char *in_filename;
+const char *out_filename;
+
+int timeStampLfile = 0;
+int timestampInterval = 100;
+
+//* OMX Spec Version supported by the wrappers. Version = 1.1 */
+const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101;
+OMX_COMPONENTTYPE* g711_enc_handle = 0;
+
+OMX_BUFFERHEADERTYPE  **pInputBufHdrs = NULL;
+OMX_BUFFERHEADERTYPE  **pOutputBufHdrs = NULL;
+
+/************************************************************************/
+/*                GLOBAL FUNC DECL                        */
+/************************************************************************/
+int Init_Encoder(char*);
+int Play_Encoder();
+OMX_STRING aud_comp;
+/**************************************************************************/
+/*                STATIC DECLARATIONS                       */
+/**************************************************************************/
+
+static int open_audio_file ();
+static int Read_Buffer(OMX_BUFFERHEADERTYPE  *pBufHdr );
+static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *g711_enc_handle,
+                                       OMX_BUFFERHEADERTYPE  ***pBufHdrs,
+                                       OMX_U32 nPortIndex,
+                                       unsigned int bufCntMin, unsigned int bufSize);
+
+
+static OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                                  OMX_IN OMX_PTR pAppData,
+                                  OMX_IN OMX_EVENTTYPE eEvent,
+                                  OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
+                                  OMX_IN OMX_PTR pEventData);
+static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                     OMX_IN OMX_PTR pAppData,
+                                     OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+static OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                     OMX_IN OMX_PTR pAppData,
+                                     OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+static OMX_ERRORTYPE  parse_pcm_header();
+static OMX_ERRORTYPE  attach_g711_header();
+void wait_for_event(void)
+{
+    pthread_mutex_lock(&lock);
+    DEBUG_PRINT("%s: event_is_done=%d", __FUNCTION__, event_is_done);
+    while (event_is_done == 0) {
+        pthread_cond_wait(&cond, &lock);
+    }
+    event_is_done = 0;
+    pthread_mutex_unlock(&lock);
+}
+
+void event_complete(void )
+{
+    pthread_mutex_lock(&lock);
+    if (event_is_done == 0) {
+        event_is_done = 1;
+        pthread_cond_broadcast(&cond);
+    }
+    pthread_mutex_unlock(&lock);
+}
+
+void etb_wait_for_event(void)
+{
+    pthread_mutex_lock(&etb_lock1);
+    DEBUG_PRINT("%s: etb_event_is_done=%d", __FUNCTION__, etb_event_is_done);
+    while (etb_event_is_done == 0) {
+        pthread_cond_wait(&etb_cond, &etb_lock1);
+    }
+    etb_event_is_done = 0;
+    pthread_mutex_unlock(&etb_lock1);
+}
+
+void etb_event_complete(void )
+{
+    pthread_mutex_lock(&etb_lock1);
+    if (etb_event_is_done == 0) {
+        etb_event_is_done = 1;
+        pthread_cond_broadcast(&etb_cond);
+    }
+    pthread_mutex_unlock(&etb_lock1);
+}
+
+
+OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                           OMX_IN OMX_PTR pAppData,
+                           OMX_IN OMX_EVENTTYPE eEvent,
+                           OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
+                           OMX_IN OMX_PTR pEventData)
+{
+    DEBUG_PRINT("Function %s \n", __FUNCTION__);
+    /* To remove warning for unused variable to keep prototype same */
+    (void)hComponent;
+    (void)pAppData;
+    (void)pEventData;
+
+    switch(eEvent) {
+        case OMX_EventCmdComplete:
+        DEBUG_PRINT("\n OMX_EventCmdComplete event=%d data1=%u data2=%u\n",(OMX_EVENTTYPE)eEvent,
+                                                                               nData1,nData2);
+            event_complete();
+        break;
+        case OMX_EventError:
+        DEBUG_PRINT("\n OMX_EventError \n");
+        break;
+         case OMX_EventBufferFlag:
+             DEBUG_PRINT("\n OMX_EventBufferFlag \n");
+             bOutputEosReached = true;
+             event_complete();
+             break;
+        case OMX_EventPortSettingsChanged:
+        DEBUG_PRINT("\n OMX_EventPortSettingsChanged \n");
+        break;
+        default:
+        DEBUG_PRINT("\n Unknown Event \n");
+        break;
+    }
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                              OMX_IN OMX_PTR pAppData,
+                              OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    size_t bytes_writen = 0;
+    size_t total_bytes_writen = 0;
+    size_t len = 0;
+    struct enc_meta_out *meta = NULL;
+    OMX_U8 *src = pBuffer->pBuffer;
+    unsigned int num_of_frames = 1;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)pAppData;
+
+        if(((pBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+            DEBUG_PRINT("FBD::EOS on output port totaldatalen %d\n ", totaldatalen);
+            bOutputEosReached = true;
+            g711hdr.data_sz = (uint32_t)totaldatalen;
+            g711hdr.sample_length = (uint32_t)totaldatalen;
+            g711hdr.riff_sz = g711hdr.data_sz + sizeof(g711hdr) - 8;
+            fseek(outputBufferFile, 0, SEEK_SET);
+            fwrite(&g711hdr,1, sizeof(g711hdr), outputBufferFile);
+            fseek(outputBufferFile, 0, SEEK_END);
+            return OMX_ErrorNone;
+        }
+        if(bInputEosReached_tunnel || bOutputEosReached)
+        {
+            DEBUG_PRINT("EOS REACHED NO MORE PROCESSING OF BUFFERS\n");
+            return OMX_ErrorNone;
+        }
+        if(num_of_frames != src[0]){
+
+            printf("Data corrupt\n");
+            return OMX_ErrorNone;
+        }
+        /* Skip the first bytes */
+
+
+
+        src += sizeof(unsigned char);
+        meta = (struct enc_meta_out *)src;
+        while (num_of_frames > 0) {
+            meta = (struct enc_meta_out *)src;
+            len = meta->frame_size;
+            bytes_writen = fwrite(pBuffer->pBuffer + sizeof(unsigned char) + meta->offset_to_frame,1,len,outputBufferFile);
+            if(bytes_writen < len)
+            {
+                DEBUG_PRINT("error: invalid g711 encoded data \n");
+                return OMX_ErrorNone;
+            }
+            src += sizeof(struct enc_meta_out);
+            num_of_frames--;
+            total_bytes_writen += len;
+        }
+        DEBUG_PRINT(" FillBufferDone size writen to file  %zu\n",total_bytes_writen);
+        totaldatalen = totaldatalen + (int)total_bytes_writen;
+
+        DEBUG_PRINT(" FBD calling FTB\n");
+        OMX_FillThisBuffer(hComponent,pBuffer);
+        return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                              OMX_IN OMX_PTR pAppData,
+                              OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    int readBytes =0;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)pAppData;
+
+    ebd_cnt++;
+    used_ip_buf_cnt--;
+    pthread_mutex_lock(&etb_lock);
+    if(!etb_done)
+    {
+        DEBUG_PRINT("\n*********************************************\n");
+        DEBUG_PRINT("Wait till first set of buffers are given to component\n");
+        DEBUG_PRINT("\n*********************************************\n");
+        etb_done++;
+        pthread_mutex_unlock(&etb_lock);
+        etb_wait_for_event();
+    }
+    else
+    {
+        pthread_mutex_unlock(&etb_lock);
+    }
+
+
+    if(bInputEosReached)
+    {
+        DEBUG_PRINT("\n*********************************************\n");
+        DEBUG_PRINT("   EBD::EOS on input port\n ");
+        DEBUG_PRINT("*********************************************\n");
+        return OMX_ErrorNone;
+    }else if (bFlushing == true) {
+      DEBUG_PRINT("omx_g711_aenc_test: bFlushing is set to TRUE used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
+      if (used_ip_buf_cnt == 0) {
+        bFlushing = false;
+      } else {
+        DEBUG_PRINT("omx_g711_aenc_test: more buffer to come back used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
+        return OMX_ErrorNone;
+      }
+    }
+
+    if((readBytes = Read_Buffer(pBuffer)) > 0) {
+        pBuffer->nFilledLen = (OMX_U32)readBytes;
+        used_ip_buf_cnt++;
+        OMX_EmptyThisBuffer(hComponent,pBuffer);
+    }
+    else{
+        pBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
+        used_ip_buf_cnt++;
+        bInputEosReached = true;
+        pBuffer->nFilledLen = 0;
+        OMX_EmptyThisBuffer(hComponent,pBuffer);
+        DEBUG_PRINT("EBD..Either EOS or Some Error while reading file\n");
+    }
+    return OMX_ErrorNone;
+}
+
+void signal_handler(int sig_id) {
+
+  /* Flush */
+  if (sig_id == SIGUSR1) {
+    DEBUG_PRINT("%s Initiate flushing\n", __FUNCTION__);
+    bFlushing = true;
+    OMX_SendCommand(g711_enc_handle, OMX_CommandFlush, OMX_ALL, NULL);
+  } else if (sig_id == SIGUSR2) {
+    if (bPause == true) {
+      DEBUG_PRINT("%s resume playback\n", __FUNCTION__);
+      bPause = false;
+      OMX_SendCommand(g711_enc_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
+    } else {
+      DEBUG_PRINT("%s pause playback\n", __FUNCTION__);
+      bPause = true;
+      OMX_SendCommand(g711_enc_handle, OMX_CommandStateSet, OMX_StatePause, NULL);
+    }
+  }
+}
+
+int main(int argc, char **argv)
+{
+    unsigned int bufCnt=0;
+    OMX_ERRORTYPE result;
+
+    struct sigaction sa;
+
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_handler = &signal_handler;
+    sigaction(SIGABRT, &sa, NULL);
+    sigaction(SIGUSR1, &sa, NULL);
+    sigaction(SIGUSR2, &sa, NULL);
+
+   (void) signal(SIGINT, Release_Encoder);
+
+    pthread_cond_init(&cond, 0);
+    pthread_mutex_init(&lock, 0);
+    pthread_cond_init(&etb_cond, 0);
+    pthread_mutex_init(&etb_lock, 0);
+    pthread_mutex_init(&etb_lock1, 0);
+
+    if (argc >= 5) {
+      in_filename = argv[1];
+      out_filename = argv[2];
+      if (in_filename == NULL || out_filename == NULL) {
+                DEBUG_PRINT("Invalid %s filename\n", in_filename ? "Output":"Input");
+                return 0;
+      }
+      encode_format = (uint32_t)atoi(argv[3]);
+      tunnel  = (uint32_t)atoi(argv[4]);
+      rectime = (uint32_t)atoi(argv[5]);
+
+
+      DEBUG_PRINT("Input parameters: enocder format= %d, tunnel %d, rectime = %d\n",
+                encode_format, tunnel, rectime);
+
+    } else {
+        DEBUG_PRINT(" invalid format: \n");
+        DEBUG_PRINT("ex: ./mm-aenc-omxg711 INPUTFILE G711_OUTPUTFILE   ENCODE_FORMAT TUNNEL RECORDTIME \n");
+        DEBUG_PRINT("ENCODE formats are : G711MLAW :0 , G711ALAW: 1");
+        DEBUG_PRINT("FOR TUNNEL MOD PASS INPUT FILE AS ZERO\n");
+        DEBUG_PRINT("RECORDTIME in seconds for AST Automation ...TUNNEL MODE ONLY\n");
+        return 0;
+    }
+    if(tunnel == 0) {
+        if(encode_format == 0) {
+            aud_comp = "OMX.qcom.audio.encoder.g711mlaw";
+        }
+        else {
+            aud_comp = "OMX.qcom.audio.encoder.g711alaw";
+        }
+    } else {
+        if(encode_format == 0) {
+            aud_comp = "OMX.qcom.audio.encoder.tunneled.g711mlaw";
+        }
+        else {
+            aud_comp = "OMX.qcom.audio.encoder.tunneled.g711alaw";
+        }
+    }
+    if(Init_Encoder(aud_comp)!= 0x00)
+    {
+        DEBUG_PRINT("Decoder Init failed\n");
+        return -1;
+    }
+
+    fcntl(0, F_SETFL, O_NONBLOCK);
+
+    if(Play_Encoder() != 0x00)
+    {
+        DEBUG_PRINT("Play_Decoder failed\n");
+        return -1;
+    }
+
+    // Wait till EOS is reached...
+        if(rectime && tunnel)
+        {
+            sleep(rectime);
+            rectime = 0;
+            bInputEosReached_tunnel = 1;
+            DEBUG_PRINT("\EOS ON INPUT PORT\n");
+        }
+        else
+        {
+            wait_for_event();
+        }
+
+        if((bInputEosReached_tunnel) || ((bOutputEosReached) && !tunnel))
+        {
+
+            DEBUG_PRINT("\nMoving the decoder to idle state \n");
+            OMX_SendCommand(g711_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
+            wait_for_event();
+            DEBUG_PRINT("\nMoving the encoder to loaded state \n");
+            OMX_SendCommand(g711_enc_handle, OMX_CommandStateSet, OMX_StateLoaded,0);
+            sleep(1);
+            if (!tunnel)
+            {
+                DEBUG_PRINT("\nFillBufferDone: Deallocating i/p buffers \n");
+                for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt) {
+                    OMX_FreeBuffer(g711_enc_handle, 0, pInputBufHdrs[bufCnt]);
+                }
+            }
+
+            DEBUG_PRINT ("\nFillBufferDone: Deallocating o/p buffers \n");
+            for(bufCnt=0; bufCnt < output_buf_cnt; ++bufCnt) {
+                OMX_FreeBuffer(g711_enc_handle, 1, pOutputBufHdrs[bufCnt]);
+            }
+            wait_for_event();
+
+            result = OMX_FreeHandle(g711_enc_handle);
+            if (result != OMX_ErrorNone) {
+                DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
+            }
+            OMX_Deinit();
+            ebd_cnt=0;
+            bOutputEosReached = false;
+            bInputEosReached_tunnel = false;
+            bInputEosReached = 0;
+            g711_enc_handle = NULL;
+            pthread_cond_destroy(&cond);
+            pthread_mutex_destroy(&lock);
+            fclose(outputBufferFile);
+            DEBUG_PRINT("*****************************************\n");
+            DEBUG_PRINT("******...G711 ENC TEST COMPLETED...***************\n");
+            DEBUG_PRINT("*****************************************\n");
+        }
+        return 0;
+}
+
+void Release_Encoder()
+{
+    static int cnt=0;
+    OMX_ERRORTYPE result;
+
+    DEBUG_PRINT("END OF G711 ENCODING: EXITING PLEASE WAIT\n");
+    bInputEosReached_tunnel = 1;
+    event_complete();
+    cnt++;
+    if(cnt > 1)
+    {
+        /* FORCE RESET  */
+        g711_enc_handle = NULL;
+        ebd_cnt=0;
+        bInputEosReached_tunnel = false;
+
+        result = OMX_FreeHandle(g711_enc_handle);
+        if (result != OMX_ErrorNone) {
+            DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
+        }
+
+        /* Deinit OpenMAX */
+
+        OMX_Deinit();
+
+        pthread_cond_destroy(&cond);
+        pthread_mutex_destroy(&lock);
+            DEBUG_PRINT("*****************************************\n");
+            DEBUG_PRINT("******...G711 ENC TEST COMPLETED...***************\n");
+            DEBUG_PRINT("*****************************************\n");
+        exit(0);
+    }
+}
+
+int Init_Encoder(OMX_STRING audio_component)
+{
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE omxresult;
+    OMX_U32 total = 0;
+    typedef OMX_U8* OMX_U8_PTR;
+    char *role ="audio_encoder";
+
+    static OMX_CALLBACKTYPE call_back = {
+        &EventHandler,&EmptyBufferDone,&FillBufferDone
+    };
+
+    /* Init. the OpenMAX Core */
+    DEBUG_PRINT("\nInitializing OpenMAX Core....\n");
+    omxresult = OMX_Init();
+
+    if(OMX_ErrorNone != omxresult) {
+        DEBUG_PRINT("\n Failed to Init OpenMAX core");
+          return -1;
+    }
+    else {
+        DEBUG_PRINT("\nOpenMAX Core Init Done\n");
+    }
+
+    /* Query for audio decoders*/
+    DEBUG_PRINT("G711_test: Before entering OMX_GetComponentOfRole");
+    OMX_GetComponentsOfRole(role, &total, 0);
+    DEBUG_PRINT ("\nTotal components of role=%s :%u", role, total);
+
+
+    omxresult = OMX_GetHandle((OMX_HANDLETYPE*)(&g711_enc_handle),
+                        (OMX_STRING)audio_component, NULL, &call_back);
+    if (FAILED(omxresult)) {
+        DEBUG_PRINT("\nFailed to Load the component:%s\n", audio_component);
+    return -1;
+    }
+    else
+    {
+        DEBUG_PRINT("\nComponent %s is in LOADED state\n", audio_component);
+    }
+
+    /* Get the port information */
+    CONFIG_VERSION_SIZE(portParam);
+    omxresult = OMX_GetParameter(g711_enc_handle, OMX_IndexParamAudioInit,
+                                (OMX_PTR)&portParam);
+
+    if(FAILED(omxresult)) {
+        DEBUG_PRINT("\nFailed to get Port Param\n");
+    return -1;
+    }
+    else
+    {
+        DEBUG_PRINT("\nportParam.nPorts:%u\n", portParam.nPorts);
+    DEBUG_PRINT("\nportParam.nStartPortNumber:%u\n",
+                                             portParam.nStartPortNumber);
+    }
+    return 0;
+}
+
+int Play_Encoder()
+{
+    unsigned int i;
+    int Size=0;
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE ret;
+    OMX_INDEXTYPE index;
+#ifdef __LP64__
+    DEBUG_PRINT("sizeof[%ld]\n", sizeof(OMX_BUFFERHEADERTYPE));
+#else
+    DEBUG_PRINT("sizeof[%d]\n", sizeof(OMX_BUFFERHEADERTYPE));
+#endif
+
+    /* open the i/p and o/p files based on the video file format passed */
+    if(open_audio_file()) {
+        DEBUG_PRINT("\n Returning -1");
+        return -1;
+    }
+
+    /* Query the encoder input min buf requirements */
+    CONFIG_VERSION_SIZE(inputportFmt);
+
+    /* Port for which the Client needs to obtain info */
+    inputportFmt.nPortIndex = portParam.nStartPortNumber;
+
+    OMX_GetParameter(g711_enc_handle,OMX_IndexParamPortDefinition,&inputportFmt);
+    DEBUG_PRINT ("\nEnc Input Buffer Count %u\n", inputportFmt.nBufferCountMin);
+    DEBUG_PRINT ("\nEnc: Input Buffer Size %u\n", inputportFmt.nBufferSize);
+
+    if(OMX_DirInput != inputportFmt.eDir) {
+        DEBUG_PRINT ("\nEnc: Expect Input Port\n");
+        return -1;
+    }
+
+    pcmParams.nPortIndex   = 0;
+    pcmParams.nChannels    =  channels;
+    pcmParams.bInterleaved = OMX_TRUE;
+    pcmParams.nSamplingRate = samplerate;
+    OMX_SetParameter(g711_enc_handle,OMX_IndexParamAudioPcm,&pcmParams);
+
+
+    /* Query the encoder outport's min buf requirements */
+    CONFIG_VERSION_SIZE(outputportFmt);
+    /* Port for which the Client needs to obtain info */
+    outputportFmt.nPortIndex = portParam.nStartPortNumber + 1;
+
+    OMX_GetParameter(g711_enc_handle,OMX_IndexParamPortDefinition,&outputportFmt);
+    DEBUG_PRINT ("\nEnc: Output Buffer Count %u\n", outputportFmt.nBufferCountMin);
+    DEBUG_PRINT ("\nEnc: Output Buffer Size %u\n", outputportFmt.nBufferSize);
+
+    if(OMX_DirOutput != outputportFmt.eDir) {
+        DEBUG_PRINT ("\nEnc: Expect Output Port\n");
+        return -1;
+    }
+
+
+    CONFIG_VERSION_SIZE(pcmParams);
+
+
+    pcmParams.nPortIndex   =  1;
+    pcmParams.nChannels    =  channels; //Only mono is supported
+    pcmParams.nSamplingRate  =  samplerate;
+    OMX_SetParameter(g711_enc_handle,OMX_IndexParamAudioPcm,&pcmParams);
+    OMX_GetExtensionIndex(g711_enc_handle,"OMX.Qualcomm.index.audio.sessionId",&index);
+    OMX_GetParameter(g711_enc_handle,index,&streaminfoparam);
+    DEBUG_PRINT ("\nOMX_SendCommand Encoder -> IDLE\n");
+    OMX_SendCommand(g711_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
+    /* wait_for_event(); should not wait here event complete status will
+       not come until enough buffer are allocated */
+    if (tunnel == 0)
+    {
+        input_buf_cnt = inputportFmt.nBufferCountActual; //  inputportFmt.nBufferCountMin + 5;
+        DEBUG_PRINT("Transition to Idle State succesful...\n");
+        /* Allocate buffer on decoder's i/p port */
+        error = Allocate_Buffer(g711_enc_handle, &pInputBufHdrs, inputportFmt.nPortIndex,
+                            input_buf_cnt, inputportFmt.nBufferSize);
+        if (error != OMX_ErrorNone || pInputBufHdrs == NULL) {
+            DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer error\n");
+            return -1;
+        }
+        else {
+            DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer success\n");
+        }
+    }
+    output_buf_cnt = outputportFmt.nBufferCountMin ;
+
+    /* Allocate buffer on encoder's O/Pp port */
+    error = Allocate_Buffer(g711_enc_handle, &pOutputBufHdrs, outputportFmt.nPortIndex,
+                            output_buf_cnt, outputportFmt.nBufferSize);
+    if (error != OMX_ErrorNone || pOutputBufHdrs == NULL) {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer error\n");
+        return -1;
+    }
+    else {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer success\n");
+    }
+
+    wait_for_event();
+
+    if (tunnel == 1)
+    {
+        DEBUG_PRINT ("\nOMX_SendCommand to enable TUNNEL MODE during IDLE\n");
+        OMX_SendCommand(g711_enc_handle, OMX_CommandPortDisable,0,0); // disable input port
+        wait_for_event();
+    }
+
+    DEBUG_PRINT ("\nOMX_SendCommand encoder -> Executing\n");
+    OMX_SendCommand(g711_enc_handle, OMX_CommandStateSet, OMX_StateExecuting,0);
+    wait_for_event();
+
+    DEBUG_PRINT(" Start sending OMX_FILLthisbuffer\n");
+
+    attach_g711_header();
+
+    for(i=0; i < output_buf_cnt; i++) {
+        DEBUG_PRINT ("\nOMX_FillThisBuffer on output buf no.%d\n",i);
+        pOutputBufHdrs[i]->nOutputPortIndex = 1;
+        pOutputBufHdrs[i]->nFlags = pOutputBufHdrs[i]->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
+        ret = OMX_FillThisBuffer(g711_enc_handle, pOutputBufHdrs[i]);
+        if (OMX_ErrorNone != ret) {
+            DEBUG_PRINT("OMX_FillThisBuffer failed with result %d\n", ret);
+        }
+        else {
+            DEBUG_PRINT("OMX_FillThisBuffer success!\n");
+        }
+    }
+
+    if(tunnel == 0)
+    {
+        DEBUG_PRINT(" Start sending OMX_emptythisbuffer\n");
+        for (i = 0;i < input_buf_cnt;i++) {
+            DEBUG_PRINT ("\nOMX_EmptyThisBuffer on Input buf no.%d\n",i);
+            pInputBufHdrs[i]->nInputPortIndex = 0;
+            Size = Read_Buffer(pInputBufHdrs[i]);
+            if(Size <=0 ){
+              DEBUG_PRINT("NO DATA READ\n");
+              bInputEosReached = true;
+              pInputBufHdrs[i]->nFlags= OMX_BUFFERFLAG_EOS;
+            }
+            pInputBufHdrs[i]->nFilledLen = (OMX_U32)Size;
+            pInputBufHdrs[i]->nInputPortIndex = 0;
+            used_ip_buf_cnt++;
+            ret = OMX_EmptyThisBuffer(g711_enc_handle, pInputBufHdrs[i]);
+            if (OMX_ErrorNone != ret) {
+                DEBUG_PRINT("OMX_EmptyThisBuffer failed with result %d\n", ret);
+            }
+            else {
+                DEBUG_PRINT("OMX_EmptyThisBuffer success!\n");
+            }
+            if(Size <=0 ){
+                break;//eos reached
+            }
+        }
+        pthread_mutex_lock(&etb_lock);
+        if(etb_done)
+        {
+            DEBUG_PRINT("Component is waiting for EBD to be released.\n");
+            etb_event_complete();
+        }
+        else
+        {
+            DEBUG_PRINT("\n****************************\n");
+            DEBUG_PRINT("EBD not yet happened ...\n");
+            DEBUG_PRINT("\n****************************\n");
+            etb_done++;
+        }
+        pthread_mutex_unlock(&etb_lock);
+    }
+    return 0;
+}
+
+
+
+static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *avc_enc_handle,
+                                       OMX_BUFFERHEADERTYPE  ***pBufHdrs,
+                                       OMX_U32 nPortIndex,
+                                       unsigned int bufCntMin, unsigned int bufSize)
+{
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE error=OMX_ErrorNone;
+    unsigned int bufCnt=0;
+    /* To remove warning for unused variable to keep prototype same */
+    (void)avc_enc_handle;
+
+    *pBufHdrs= (OMX_BUFFERHEADERTYPE **)
+                   malloc(sizeof(OMX_BUFFERHEADERTYPE*)*bufCntMin);
+
+    for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
+        DEBUG_PRINT("\n OMX_AllocateBuffer No %d \n", bufCnt);
+        error = OMX_AllocateBuffer(g711_enc_handle, &((*pBufHdrs)[bufCnt]),
+                                   nPortIndex, NULL, bufSize);
+    }
+    return error;
+}
+
+
+
+
+static int Read_Buffer (OMX_BUFFERHEADERTYPE  *pBufHdr )
+{
+    size_t bytes_read=0;
+    pBufHdr->nFilledLen = 0;
+    pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
+
+     bytes_read = fread(pBufHdr->pBuffer, 1, pBufHdr->nAllocLen , inputBufferFile);
+
+      pBufHdr->nFilledLen = (OMX_U32)bytes_read;
+        if(bytes_read == 0)
+        {
+
+          pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
+          DEBUG_PRINT ("\nBytes read zero\n");
+        }
+        else
+        {
+            pBufHdr->nFlags = pBufHdr->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
+        }
+
+    return (int)bytes_read;
+}
+
+
+
+//In Encoder this Should Open a PCM or WAV file for input.
+
+static int open_audio_file ()
+{
+    int error_code = 0;
+
+    if (!tunnel)
+    {
+        DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, in_filename);
+        inputBufferFile = fopen (in_filename, "rb");
+        if (inputBufferFile == NULL) {
+            DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
+                                         in_filename);
+            return -1;
+        }
+        if(parse_pcm_header() != 0x00)
+        {
+            DEBUG_PRINT("PCM parser failed \n");
+            return -1;
+        }
+    }
+
+    DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, out_filename);
+    outputBufferFile = fopen (out_filename, "wb");
+    if (outputBufferFile == NULL) {
+        DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
+                                         out_filename);
+        error_code = -1;
+    }
+    return error_code;
+}
+
+static OMX_ERRORTYPE attach_g711_header()
+{
+
+    memset(&g711hdr, 0, sizeof(struct g711_header));
+
+    g711hdr.riff_id = ID_RIFF;
+    g711hdr.riff_fmt = ID_WAVE;
+    g711hdr.fmt_id = ID_FMT;
+    g711hdr.fmt_sz = 18;
+
+    //change format type from wav to g711
+    if(encode_format == 0) {
+        g711hdr.audio_format = FORMAT_MULAW;
+    }
+    else {
+        g711hdr.audio_format = FORMAT_ALAW;
+    }
+
+    g711hdr.num_channels = hdr.num_channels;
+    g711hdr.sample_rate = hdr.sample_rate;
+    g711hdr.bits_per_sample = 8;
+    g711hdr.byte_rate = g711hdr.sample_rate * g711hdr.num_channels * (g711hdr.bits_per_sample / 8);
+    g711hdr.block_align = (uint16_t)((g711hdr.bits_per_sample / 8) * g711hdr.num_channels);
+    g711hdr.extension_size = 0;
+    g711hdr.fact_id = ID_FACT;
+    g711hdr.fact_sz = 4;
+    g711hdr.data_id = ID_DATA;
+    g711hdr.data_sz = 0;
+    g711hdr.riff_sz = g711hdr.data_sz + sizeof(g711hdr) - 8;
+
+    fwrite(&g711hdr,1, sizeof(g711hdr), outputBufferFile);
+
+    /*To Do : Attach Fact chunk for Non -PCM format */
+    return OMX_ErrorNone;
+}
+
+static OMX_ERRORTYPE parse_pcm_header()
+{
+
+    DEBUG_PRINT("\n***************************************************************\n");
+    if(fread(&hdr, 1, sizeof(hdr),inputBufferFile)!=sizeof(hdr))
+    {
+        DEBUG_PRINT("Wav file cannot read header\n");
+        return -1;
+    }
+
+    if ((hdr.riff_id != ID_RIFF) ||
+        (hdr.riff_fmt != ID_WAVE)||
+        (hdr.fmt_id != ID_FMT))
+    {
+        DEBUG_PRINT("Wav file is not a riff/wave file\n");
+        return -1;
+    }
+
+    if (hdr.audio_format != FORMAT_PCM)
+    {
+        DEBUG_PRINT("Wav file is not pcm format %d and fmt size is %d\n",
+                      hdr.audio_format, hdr.fmt_sz);
+        return -1;
+    }
+
+    if ((hdr.sample_rate != 8000) && (hdr.sample_rate != 16000)) {
+          DEBUG_PRINT("samplerate = %d, not supported, Supported "
+                      "samplerates are 8000, 16000", samplerate);
+        return -1;
+    }
+
+    if (hdr.num_channels != 1) {
+          DEBUG_PRINT("stereo and multi channel are not supported, channels %d"
+                      , hdr.num_channels);
+        return -1;
+    }
+
+    DEBUG_PRINT("Samplerate is %d\n", hdr.sample_rate);
+    DEBUG_PRINT("Channel Count is %d\n", hdr.num_channels);
+    DEBUG_PRINT("\n***************************************************************\n");
+
+    samplerate = hdr.sample_rate;
+    channels = hdr.num_channels;
+
+    return OMX_ErrorNone;
+}
diff --git a/mm-audio/aenc-qcelp13/qdsp6/Android.mk b/mm-audio/aenc-qcelp13/qdsp6/Android.mk
index 5ce66ab..2664db5 100644
--- a/mm-audio/aenc-qcelp13/qdsp6/Android.mk
+++ b/mm-audio/aenc-qcelp13/qdsp6/Android.mk
@@ -43,6 +43,30 @@
 
 include $(BUILD_SHARED_LIBRARY)
 
+
+# ---------------------------------------------------------------------------------
+#             Make the apps-test (mm-aenc-omxqcelp13-test)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+mm-qcelp13-enc-test-inc    := $(LOCAL_PATH)/inc
+mm-qcelp13-enc-test-inc    += $(LOCAL_PATH)/test
+
+mm-qcelp13-enc-test-inc    += $(TARGET_OUT_HEADERS)/mm-core/omxcore
+mm-qcelp13-enc-test-inc    += $(TARGET_OUT_HEADERS)/mm-audio/audio-alsa
+LOCAL_MODULE            := mm-aenc-omxqcelp13-test
+LOCAL_MODULE_TAGS       := optional
+LOCAL_CFLAGS            := $(libOmxQcelp13Enc-def)
+LOCAL_C_INCLUDES        := $(mm-qcelp13-enc-test-inc)
+LOCAL_PRELINK_MODULE    := false
+LOCAL_SHARED_LIBRARIES  := libmm-omxcore
+LOCAL_SHARED_LIBRARIES  += libOmxQcelp13Enc
+LOCAL_SHARED_LIBRARIES  += libaudioalsa
+LOCAL_SRC_FILES         := test/omx_qcelp13_enc_test.c
+
+include $(BUILD_EXECUTABLE)
+
 endif
 
 # ---------------------------------------------------------------------------------
diff --git a/mm-audio/aenc-qcelp13/qdsp6/Makefile b/mm-audio/aenc-qcelp13/qdsp6/Makefile
index 9bbc4ab..b14655b 100644
--- a/mm-audio/aenc-qcelp13/qdsp6/Makefile
+++ b/mm-audio/aenc-qcelp13/qdsp6/Makefile
@@ -39,7 +39,7 @@
 # ---------------------------------------------------------------------------------
 #					BUILD
 # ---------------------------------------------------------------------------------
-all: libOmxQcelp13Enc.so.$(LIBVER)
+all: libOmxQcelp13Enc.so.$(LIBVER) mm-aenc-omxqcelp13-test
 
 install:
 	echo "intalling aenc-qcelp13 in $(DESTDIR)"
@@ -49,7 +49,8 @@
 	install -m 555 libOmxQcelp13Enc.so.$(LIBVER) $(LIBINSTALLDIR)
 	cd $(LIBINSTALLDIR) && ln -s libOmxQcelp13Enc.so.$(LIBVER) libOmxQcelp13Enc.so.$(LIBMAJOR)
 	cd $(LIBINSTALLDIR) && ln -s libOmxQcelp13Enc.so.$(LIBMAJOR) libOmxQcelp13Enc.so
-
+	install -m 555 mm-aenc-omxqcelp13-test $(BININSTALLDIR)
+	
 # ---------------------------------------------------------------------------------
 #				COMPILE LIBRARY
 # ---------------------------------------------------------------------------------
@@ -64,5 +65,17 @@
 	$(CC) $(CPPFLAGS) $(CFLAGS_SO) $(LDFLAGS_SO) -Wl,-soname,libOmxQcelp13Enc.so.$(LIBMAJOR) -o $@ $^ $(LDFLAGS) $(LDLIBS)
 
 # ---------------------------------------------------------------------------------
+#				COMPILE TEST APP
+# ---------------------------------------------------------------------------------
+TEST_LDLIBS := -lpthread
+TEST_LDLIBS += -ldl
+TEST_LDLIBS += -lOmxCore
+
+TEST_SRCS := test/omx_qcelp13_enc_test.c
+
+mm-aenc-omxqcelp13-test: libOmxQcelp13Enc.so.$(LIBVER) $(TEST_SRCS)
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $^ $(TEST_LDLIBS)
+
+# ---------------------------------------------------------------------------------
 #					END
 # ---------------------------------------------------------------------------------
diff --git a/mm-audio/aenc-qcelp13/qdsp6/test/omx_qcelp13_enc_test.c b/mm-audio/aenc-qcelp13/qdsp6/test/omx_qcelp13_enc_test.c
new file mode 100644
index 0000000..a0b39c2
--- /dev/null
+++ b/mm-audio/aenc-qcelp13/qdsp6/test/omx_qcelp13_enc_test.c
@@ -0,0 +1,1173 @@
+
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2014, 2017 The Linux Foundation. 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.
+    * Neither the name of The Linux Foundation nor
+      the names of its contributors may be used to endorse or promote
+      products derived from this software without specific prior written
+      permission.
+
+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, FITNESS FOR A PARTICULAR PURPOSE AND
+NON-INFRINGEMENT 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.
+--------------------------------------------------------------------------*/
+
+
+/*
+    An Open max test application ....
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <time.h>
+#include <sys/ioctl.h>
+#include "OMX_Core.h"
+#include "OMX_Component.h"
+#include "pthread.h"
+#include <signal.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <sys/mman.h>
+#include <sys/ioctl.h>
+#include<unistd.h>
+#include<string.h>
+#include <pthread.h>
+#include "QOMX_AudioExtensions.h"
+#include "QOMX_AudioIndexExtensions.h"
+#ifdef AUDIOV2
+#include "control.h"
+#endif
+
+
+#include <linux/ioctl.h>
+
+typedef unsigned char uint8;
+typedef unsigned char byte;
+typedef unsigned int  uint32;
+typedef unsigned int  uint16;
+QOMX_AUDIO_STREAM_INFO_DATA streaminfoparam;
+/* maximum ADTS frame header length                */
+void Release_Encoder();
+
+#ifdef AUDIOV2
+unsigned short session_id;
+int device_id;
+int control = 0;
+const char *device="handset_tx";
+#define DIR_TX 2
+#endif
+
+uint32_t samplerate = 8000;
+uint32_t channels = 1;
+uint32_t min_bitrate = 0;
+uint32_t max_bitrate = 0;
+uint32_t cdmarate = 0;
+uint32_t rectime = 0;
+uint32_t recpath = 0;
+uint32_t pcmplayback = 0;
+uint32_t tunnel      = 0;
+uint32_t format = 1;
+#define DEBUG_PRINT printf
+unsigned to_idle_transition = 0;
+unsigned long total_pcm_bytes;
+
+/************************************************************************/
+/*                GLOBAL INIT                    */
+/************************************************************************/
+
+/************************************************************************/
+/*                #DEFINES                            */
+/************************************************************************/
+#define false 0
+#define true 1
+
+#define CONFIG_VERSION_SIZE(param) \
+    param.nVersion.nVersion = CURRENT_OMX_SPEC_VERSION;\
+    param.nSize = sizeof(param);
+
+#define QCP_HEADER_SIZE sizeof(struct qcp_header)
+#define MIN_BITRATE 4 /* Bit rate 1 - 13.6 , 2 - 6.2 , 3 - 2.7 , 4 - 1.0 kbps*/
+#define MAX_BITRATE 4
+
+#define FAILED(result) (result != OMX_ErrorNone)
+
+#define SUCCEEDED(result) (result == OMX_ErrorNone)
+
+/************************************************************************/
+/*                GLOBAL DECLARATIONS                     */
+/************************************************************************/
+
+pthread_mutex_t lock;
+pthread_cond_t cond;
+pthread_mutex_t elock;
+pthread_cond_t econd;
+pthread_cond_t fcond;
+pthread_mutex_t etb_lock;
+pthread_mutex_t etb_lock1;
+pthread_cond_t etb_cond;
+FILE * inputBufferFile;
+FILE * outputBufferFile;
+OMX_PARAM_PORTDEFINITIONTYPE inputportFmt;
+OMX_PARAM_PORTDEFINITIONTYPE outputportFmt;
+OMX_AUDIO_PARAM_QCELP13TYPE qcelp13param;
+OMX_AUDIO_PARAM_PCMMODETYPE    pcmparam;
+OMX_PORT_PARAM_TYPE portParam;
+OMX_PORT_PARAM_TYPE portFmt;
+OMX_ERRORTYPE error;
+
+
+
+
+#define ID_RIFF 0x46464952
+#define ID_WAVE 0x45564157
+#define ID_FMT  0x20746d66
+#define ID_DATA 0x61746164
+
+#define FORMAT_PCM 1
+
+struct wav_header {
+  uint32_t riff_id;
+  uint32_t riff_sz;
+  uint32_t riff_fmt;
+  uint32_t fmt_id;
+  uint32_t fmt_sz;
+  uint16_t audio_format;
+  uint16_t num_channels;
+  uint32_t sample_rate;
+  uint32_t byte_rate;       /* sample_rate * num_channels * bps / 8 */
+  uint16_t block_align;     /* num_channels * bps / 8 */
+  uint16_t bits_per_sample;
+  uint32_t data_id;
+  uint32_t data_sz;
+};
+struct enc_meta_out{
+        unsigned int offset_to_frame;
+        unsigned int frame_size;
+        unsigned int encoded_pcm_samples;
+        unsigned int msw_ts;
+        unsigned int lsw_ts;
+        unsigned int nflags;
+} __attribute__ ((packed));
+
+struct qcp_header {
+        /* RIFF Section */
+        char riff[4];
+        unsigned int s_riff;
+        char qlcm[4];
+
+        /* Format chunk */
+        char fmt[4];
+        unsigned int s_fmt;
+        char mjr;
+        char mnr;
+        unsigned int data1;         /* UNIQUE ID of the codec */
+        unsigned short data2;
+        unsigned short data3;
+        char data4[8];
+        unsigned short ver;         /* Codec Info */
+        char name[80];
+        unsigned short abps;    /* average bits per sec of the codec */
+        unsigned short bytes_per_pkt;
+        unsigned short samp_per_block;
+        unsigned short samp_per_sec;
+        unsigned short bits_per_samp;
+        unsigned char vr_num_of_rates;         /* Rate Header fmt info */
+        unsigned char rvd1[3];
+        unsigned short vr_bytes_per_pkt[8];
+        unsigned int rvd2[5];
+
+        /* Vrat chunk */
+        unsigned char vrat[4];
+        unsigned int s_vrat;
+        unsigned int v_rate;
+        unsigned int size_in_pkts;
+
+        /* Data chunk */
+        unsigned char data[4];
+        unsigned int s_data;
+} __attribute__ ((packed));
+
+ /* Common part */
+ static struct qcp_header append_header = {
+         {'R', 'I', 'F', 'F'}, 0, {'Q', 'L', 'C', 'M'},
+         {'f', 'm', 't', ' '}, 150, 1, 0, 0, 0, 0,{0}, 0, {0},0,0,160,8000,16,0,{0},{0},{0},
+         {'v','r','a','t'},0, 0, 0,{'d','a','t','a'},0
+ };
+
+static int totaldatalen = 0;
+static int framecnt = 0;
+/************************************************************************/
+/*                GLOBAL INIT                    */
+/************************************************************************/
+
+unsigned int input_buf_cnt = 0;
+unsigned int output_buf_cnt = 0;
+int used_ip_buf_cnt = 0;
+volatile int event_is_done = 0;
+volatile int ebd_event_is_done = 0;
+volatile int fbd_event_is_done = 0;
+volatile int etb_event_is_done = 0;
+int ebd_cnt;
+int bInputEosReached = 0;
+int bOutputEosReached = 0;
+int bInputEosReached_tunnel = 0;
+static int etb_done = 0;
+int bFlushing = false;
+int bPause    = false;
+const char *in_filename;
+const char *out_filename;
+
+int timeStampLfile = 0;
+int timestampInterval = 100;
+
+//* OMX Spec Version supported by the wrappers. Version = 1.1 */
+const OMX_U32 CURRENT_OMX_SPEC_VERSION = 0x00000101;
+OMX_COMPONENTTYPE* qcelp13_enc_handle = 0;
+
+OMX_BUFFERHEADERTYPE  **pInputBufHdrs = NULL;
+OMX_BUFFERHEADERTYPE  **pOutputBufHdrs = NULL;
+
+typedef enum {
+    UINTMAX = 1,
+    UCHARMAX,
+    USHRTMAX
+}datatype;
+
+/************************************************************************/
+/*                GLOBAL FUNC DECL                        */
+/************************************************************************/
+int Init_Encoder(char*);
+int Play_Encoder();
+OMX_STRING aud_comp;
+/**************************************************************************/
+/*                STATIC DECLARATIONS                       */
+/**************************************************************************/
+
+static int open_audio_file ();
+static int Read_Buffer(OMX_BUFFERHEADERTYPE  *pBufHdr );
+static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *qcelp13_enc_handle,
+                                       OMX_BUFFERHEADERTYPE  ***pBufHdrs,
+                                       OMX_U32 nPortIndex,
+                                       unsigned int bufCntMin, unsigned int bufSize);
+
+
+static OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                                  OMX_IN OMX_PTR pAppData,
+                                  OMX_IN OMX_EVENTTYPE eEvent,
+                                  OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
+                                  OMX_IN OMX_PTR pEventData);
+static OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                     OMX_IN OMX_PTR pAppData,
+                                     OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+
+static OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                                     OMX_IN OMX_PTR pAppData,
+                                     OMX_IN OMX_BUFFERHEADERTYPE* pBuffer);
+static OMX_ERRORTYPE  parse_pcm_header();
+
+int get_input_and_validate(char *input, datatype type)
+{
+    unsigned long int value = 0;
+    char *ptr = NULL;
+    int status = 0;
+
+    errno = 0;
+    ptr = (char *)malloc(strlen(input) + 1);
+    if (ptr == NULL) {
+        DEBUG_PRINT("Low memory\n");
+        status = -1;
+        goto exit;
+    }
+    if (input == NULL){
+        DEBUG_PRINT("No input is given\n");
+        status = -1;
+        goto exit;
+    }
+    /* Check for negative input */
+    if (*input == '-') {
+        DEBUG_PRINT("Negative Number is not allowed\n");
+        status = -1;
+        goto exit;
+    }
+    /* Convert string to unsigned long int */
+    value = strtoul(input, &ptr, 10);
+    if (errno != 0){
+        perror("strtoul");
+        status = errno;
+        goto exit;
+    }
+    /* check if number input is zero or string or string##number or viceversa */
+    if (value == 0 || *ptr != '\0'){
+        DEBUG_PRINT("Input is string+number or Zero or string = %s\n", input);
+        status = -1;
+        goto exit;
+    }
+    /* check for out of range */
+    switch(type) {
+    case 1 :if (value > UINT_MAX) {
+                DEBUG_PRINT("Input is Out of range\n");
+                status = -1;
+            }
+            break;
+    case 2 :if (value > UCHAR_MAX) {
+                DEBUG_PRINT("Input is Out of range\n");
+                status = -1;
+            }
+            break;
+    case 3 :if (value > USHRT_MAX) {
+                DEBUG_PRINT("Input is Out of range\n");
+                status = -1;
+            }
+            break;
+    }
+exit:
+    if (status != 0)
+        exit(0);
+    return value;
+}
+
+void wait_for_event(void)
+{
+    pthread_mutex_lock(&lock);
+    DEBUG_PRINT("%s: event_is_done=%d", __FUNCTION__, event_is_done);
+    while (event_is_done == 0) {
+        pthread_cond_wait(&cond, &lock);
+    }
+    event_is_done = 0;
+    pthread_mutex_unlock(&lock);
+}
+
+void event_complete(void )
+{
+    pthread_mutex_lock(&lock);
+    if (event_is_done == 0) {
+        event_is_done = 1;
+        pthread_cond_broadcast(&cond);
+    }
+    pthread_mutex_unlock(&lock);
+}
+
+void etb_wait_for_event(void)
+{
+    pthread_mutex_lock(&etb_lock1);
+    DEBUG_PRINT("%s: etb_event_is_done=%d", __FUNCTION__, etb_event_is_done);
+    while (etb_event_is_done == 0) {
+        pthread_cond_wait(&etb_cond, &etb_lock1);
+    }
+    etb_event_is_done = 0;
+    pthread_mutex_unlock(&etb_lock1);
+}
+
+void etb_event_complete(void )
+{
+    pthread_mutex_lock(&etb_lock1);
+    if (etb_event_is_done == 0) {
+        etb_event_is_done = 1;
+        pthread_cond_broadcast(&etb_cond);
+    }
+    pthread_mutex_unlock(&etb_lock1);
+}
+
+static void create_qcp_header(int Datasize, int Frames)
+{
+        append_header.s_riff = (unsigned)(Datasize + (int)QCP_HEADER_SIZE - 8);
+        /* exclude riff id and size field */
+        append_header.data1 = 0x5E7F6D41;
+        append_header.data2 = 0xB115;
+        append_header.data3 = 0x11D0;
+        append_header.data4[0] = 0xBA;
+        append_header.data4[1] = 0x91;
+        append_header.data4[2] = 0x00;
+        append_header.data4[3] = 0x80;
+        append_header.data4[4] = 0x5F;
+        append_header.data4[5] = 0xB4;
+        append_header.data4[6] = 0xB9;
+        append_header.data4[7] = 0x7E;
+        append_header.ver = 0x0002;
+        memcpy(append_header.name, "Qcelp 13K", 9);
+        append_header.abps = 13000;
+        append_header.bytes_per_pkt = 35;
+        append_header.vr_num_of_rates = 5;
+        append_header.vr_bytes_per_pkt[0] = 0x0422;
+        append_header.vr_bytes_per_pkt[1] = 0x0310;
+        append_header.vr_bytes_per_pkt[2] = 0x0207;
+        append_header.vr_bytes_per_pkt[3] = 0x0103;
+        append_header.s_vrat = 0x00000008;
+        append_header.v_rate = 0x00000001;
+        append_header.size_in_pkts = (unsigned)Frames;
+        append_header.s_data = (unsigned)Datasize;
+        return;
+}
+
+OMX_ERRORTYPE EventHandler(OMX_IN OMX_HANDLETYPE hComponent,
+                           OMX_IN OMX_PTR pAppData,
+                           OMX_IN OMX_EVENTTYPE eEvent,
+                           OMX_IN OMX_U32 nData1, OMX_IN OMX_U32 nData2,
+                           OMX_IN OMX_PTR pEventData)
+{
+    DEBUG_PRINT("Function %s \n", __FUNCTION__);
+
+    /* To remove warning for unused variable to keep prototype same */
+   (void)hComponent;
+   (void)pAppData;
+   (void)pEventData;
+
+    switch(eEvent) {
+        case OMX_EventCmdComplete:
+        DEBUG_PRINT("\n OMX_EventCmdComplete event=%d data1=%u data2=%u\n",(OMX_EVENTTYPE)eEvent,
+                                                                               nData1,nData2);
+            event_complete();
+        break;
+        case OMX_EventError:
+        DEBUG_PRINT("\n OMX_EventError \n");
+        break;
+         case OMX_EventBufferFlag:
+             DEBUG_PRINT("\n OMX_EventBufferFlag \n");
+             bOutputEosReached = true;
+             event_complete();
+             break;
+        case OMX_EventPortSettingsChanged:
+        DEBUG_PRINT("\n OMX_EventPortSettingsChanged \n");
+        break;
+        default:
+        DEBUG_PRINT("\n Unknown Event \n");
+        break;
+    }
+    return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE FillBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                              OMX_IN OMX_PTR pAppData,
+                              OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    size_t bytes_writen = 0;
+    size_t total_bytes_writen = 0;
+    size_t len = 0;
+    struct enc_meta_out *meta = NULL;
+    OMX_U8 *src = pBuffer->pBuffer;
+    unsigned int num_of_frames = 1;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)pAppData;
+
+        if(((pBuffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS)) {
+            DEBUG_PRINT("FBD::EOS on output port\n ");
+            bOutputEosReached = true;
+            return OMX_ErrorNone;
+        }
+        if(bInputEosReached_tunnel || bOutputEosReached)
+        {
+            DEBUG_PRINT("EOS REACHED NO MORE PROCESSING OF BUFFERS\n");
+            return OMX_ErrorNone;
+        }
+        if(num_of_frames != src[0]){
+
+            printf("Data corrupt\n");
+            return OMX_ErrorNone;
+        }
+        /* Skip the first bytes */
+
+
+
+        src += sizeof(unsigned char);
+        meta = (struct enc_meta_out *)src;
+        while (num_of_frames > 0) {
+            meta = (struct enc_meta_out *)src;
+            /*printf("offset=%d framesize=%d encoded_pcm[%d] msw_ts[%d]lsw_ts[%d] nflags[%d]\n",
+                                                                       meta->offset_to_frame,
+                                                                       meta->frame_size,
+                          meta->encoded_pcm_samples, meta->msw_ts, meta->lsw_ts, meta->nflags);*/
+            len = meta->frame_size;
+
+            bytes_writen = fwrite(pBuffer->pBuffer + sizeof(unsigned char) + meta->offset_to_frame,1,len,outputBufferFile);
+            if(bytes_writen < len)
+            {
+                DEBUG_PRINT("error: invalid QCELP13 encoded data \n");
+                return OMX_ErrorNone;
+            }
+            src += sizeof(struct enc_meta_out);
+            num_of_frames--;
+            total_bytes_writen += len;
+        }
+        DEBUG_PRINT(" FillBufferDone size writen to file  %zu count %d\n",total_bytes_writen, framecnt);
+        totaldatalen = totaldatalen + (int)total_bytes_writen;
+    framecnt++;
+
+        DEBUG_PRINT(" FBD calling FTB\n");
+        OMX_FillThisBuffer(hComponent,pBuffer);
+
+        return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE EmptyBufferDone(OMX_IN OMX_HANDLETYPE hComponent,
+                              OMX_IN OMX_PTR pAppData,
+                              OMX_IN OMX_BUFFERHEADERTYPE* pBuffer)
+{
+    int readBytes =0;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)pAppData;
+
+    ebd_cnt++;
+    used_ip_buf_cnt--;
+    pthread_mutex_lock(&etb_lock);
+    if(!etb_done)
+    {
+        DEBUG_PRINT("\n*********************************************\n");
+        DEBUG_PRINT("Wait till first set of buffers are given to component\n");
+        DEBUG_PRINT("\n*********************************************\n");
+        etb_done++;
+        pthread_mutex_unlock(&etb_lock);
+        etb_wait_for_event();
+    }
+    else
+    {
+        pthread_mutex_unlock(&etb_lock);
+    }
+
+
+    if(bInputEosReached)
+    {
+        DEBUG_PRINT("\n*********************************************\n");
+        DEBUG_PRINT("   EBD::EOS on input port\n ");
+        DEBUG_PRINT("*********************************************\n");
+        return OMX_ErrorNone;
+    }else if (bFlushing == true) {
+      DEBUG_PRINT("omx_qcelp13_adec_test: bFlushing is set to TRUE used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
+      if (used_ip_buf_cnt == 0) {
+        bFlushing = false;
+      } else {
+        DEBUG_PRINT("omx_qcelp13_adec_test: more buffer to come back used_ip_buf_cnt=%d\n",used_ip_buf_cnt);
+        return OMX_ErrorNone;
+      }
+    }
+
+    if((readBytes = Read_Buffer(pBuffer)) > 0) {
+        pBuffer->nFilledLen = (OMX_U32)readBytes;
+        used_ip_buf_cnt++;
+        OMX_EmptyThisBuffer(hComponent,pBuffer);
+    }
+    else{
+        pBuffer->nFlags |= OMX_BUFFERFLAG_EOS;
+        used_ip_buf_cnt++;
+        bInputEosReached = true;
+        pBuffer->nFilledLen = 0;
+        OMX_EmptyThisBuffer(hComponent,pBuffer);
+        DEBUG_PRINT("EBD..Either EOS or Some Error while reading file\n");
+    }
+    return OMX_ErrorNone;
+}
+
+void signal_handler(int sig_id) {
+
+  /* Flush */
+  if (sig_id == SIGUSR1) {
+    DEBUG_PRINT("%s Initiate flushing\n", __FUNCTION__);
+    bFlushing = true;
+    OMX_SendCommand(qcelp13_enc_handle, OMX_CommandFlush, OMX_ALL, NULL);
+  } else if (sig_id == SIGUSR2) {
+    if (bPause == true) {
+      DEBUG_PRINT("%s resume record\n", __FUNCTION__);
+      bPause = false;
+      OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
+    } else {
+      DEBUG_PRINT("%s pause record\n", __FUNCTION__);
+      bPause = true;
+      OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StatePause, NULL);
+    }
+  }
+}
+
+int main(int argc, char **argv)
+{
+     unsigned int bufCnt=0;
+     OMX_ERRORTYPE result;
+
+    struct sigaction sa;
+
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_handler = &signal_handler;
+    sigaction(SIGABRT, &sa, NULL);
+    sigaction(SIGUSR1, &sa, NULL);
+    sigaction(SIGUSR2, &sa, NULL);
+
+   (void) signal(SIGINT, Release_Encoder);
+
+    pthread_cond_init(&cond, 0);
+    pthread_mutex_init(&lock, 0);
+    pthread_cond_init(&etb_cond, 0);
+    pthread_mutex_init(&etb_lock, 0);
+    pthread_mutex_init(&etb_lock1, 0);
+
+    if (argc >= 9) {
+        in_filename = argv[1];
+        out_filename = argv[2];
+	if (in_filename == NULL || out_filename == NULL) {
+                DEBUG_PRINT("Invalid %s filename\n", in_filename ? "Output":"Input");
+                return 0;
+        }
+	tunnel =  (uint32_t)atoi(argv[3]);
+        min_bitrate  = (uint32_t)atoi(argv[4]);
+        max_bitrate  = (uint32_t)atoi(argv[5]);
+        cdmarate     = (uint32_t)atoi(argv[6]);
+        recpath      = (uint32_t)atoi(argv[7]); // No configuration support yet..
+        rectime      = (uint32_t)get_input_and_validate(argv[8], UINTMAX);
+
+    } else {
+          DEBUG_PRINT(" invalid format: \n");
+          DEBUG_PRINT("ex: ./mm-aenc-omxqcelp13-test INPUTFILE OUTPUTFILE Tunnel MINRATE MAXRATE CDMARATE RECORDPATH RECORDTIME\n");
+          DEBUG_PRINT("MINRATE, MAXRATE and CDMARATE 1 to 4\n");
+          DEBUG_PRINT("RECORDPATH 0(TX),1(RX),2(BOTH),3(MIC)\n");
+          DEBUG_PRINT("RECORDTIME in seconds for AST Automation\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.qcelp13";
+    else
+        aud_comp = "OMX.qcom.audio.encoder.tunneled.qcelp13";
+    if(Init_Encoder(aud_comp)!= 0x00)
+    {
+        DEBUG_PRINT("Decoder Init failed\n");
+        return -1;
+    }
+
+    fcntl(0, F_SETFL, O_NONBLOCK);
+
+    if(Play_Encoder() != 0x00)
+    {
+        DEBUG_PRINT("Play_Decoder failed\n");
+        return -1;
+    }
+
+    // Wait till EOS is reached...
+        if(rectime && tunnel)
+        {
+            sleep(rectime);
+            rectime = 0;
+            bInputEosReached_tunnel = 1;
+            DEBUG_PRINT("\EOS ON INPUT PORT\n");
+        }
+        else
+        {
+            wait_for_event();
+        }
+
+        if((bInputEosReached_tunnel) || ((bOutputEosReached) && !tunnel))
+        {
+
+            DEBUG_PRINT("\nMoving the decoder to idle state \n");
+            OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
+            wait_for_event();
+
+            DEBUG_PRINT("\nMoving the encoder to loaded state \n");
+            OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StateLoaded,0);
+            sleep(1);
+            if (!tunnel)
+            {
+                DEBUG_PRINT("\nFillBufferDone: Deallocating i/p buffers \n");
+                for(bufCnt=0; bufCnt < input_buf_cnt; ++bufCnt) {
+                    OMX_FreeBuffer(qcelp13_enc_handle, 0, pInputBufHdrs[bufCnt]);
+                }
+            }
+
+            DEBUG_PRINT ("\nFillBufferDone: Deallocating o/p buffers \n");
+            for(bufCnt=0; bufCnt < output_buf_cnt; ++bufCnt) {
+                OMX_FreeBuffer(qcelp13_enc_handle, 1, pOutputBufHdrs[bufCnt]);
+            }
+            wait_for_event();
+            create_qcp_header(totaldatalen, framecnt);
+        fseek(outputBufferFile, 0,SEEK_SET);
+            fwrite(&append_header,1,QCP_HEADER_SIZE,outputBufferFile);
+
+
+            result = OMX_FreeHandle(qcelp13_enc_handle);
+            if (result != OMX_ErrorNone) {
+                DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
+            }
+
+            /* Deinit OpenMAX */
+        if(tunnel)
+        {
+            #ifdef AUDIOV2
+            if (msm_route_stream(DIR_TX,session_id,device_id, 0))
+            {
+                DEBUG_PRINT("\ncould not set stream routing\n");
+                return -1;
+            }
+            if (msm_en_device(device_id, 0))
+            {
+                DEBUG_PRINT("\ncould not enable device\n");
+                return -1;
+            }
+            msm_mixer_close();
+            #endif
+        }
+            OMX_Deinit();
+            ebd_cnt=0;
+            bOutputEosReached = false;
+            bInputEosReached_tunnel = false;
+            bInputEosReached = 0;
+            qcelp13_enc_handle = NULL;
+            pthread_cond_destroy(&cond);
+            pthread_mutex_destroy(&lock);
+            fclose(outputBufferFile);
+            DEBUG_PRINT("*****************************************\n");
+            DEBUG_PRINT("******...QCELP13 ENC TEST COMPLETED...***************\n");
+            DEBUG_PRINT("*****************************************\n");
+        }
+        return 0;
+}
+
+void Release_Encoder()
+{
+    static int cnt=0;
+    OMX_ERRORTYPE result;
+
+    DEBUG_PRINT("END OF QCELP13 ENCODING: EXITING PLEASE WAIT\n");
+    bInputEosReached_tunnel = 1;
+    event_complete();
+    cnt++;
+    if(cnt > 1)
+    {
+        /* FORCE RESET  */
+        qcelp13_enc_handle = NULL;
+        ebd_cnt=0;
+        bInputEosReached_tunnel = false;
+
+        result = OMX_FreeHandle(qcelp13_enc_handle);
+        if (result != OMX_ErrorNone) {
+            DEBUG_PRINT ("\nOMX_FreeHandle error. Error code: %d\n", result);
+        }
+
+        /* Deinit OpenMAX */
+
+        OMX_Deinit();
+
+        pthread_cond_destroy(&cond);
+        pthread_mutex_destroy(&lock);
+            DEBUG_PRINT("*****************************************\n");
+            DEBUG_PRINT("******...QCELP13 ENC TEST COMPLETED...***************\n");
+            DEBUG_PRINT("*****************************************\n");
+        exit(0);
+    }
+}
+
+int Init_Encoder(OMX_STRING audio_component)
+{
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE omxresult;
+    OMX_U32 total = 0;
+    typedef OMX_U8* OMX_U8_PTR;
+    char *role ="audio_encoder";
+
+    static OMX_CALLBACKTYPE call_back = {
+        &EventHandler,&EmptyBufferDone,&FillBufferDone
+    };
+
+    /* Init. the OpenMAX Core */
+    DEBUG_PRINT("\nInitializing OpenMAX Core....\n");
+    omxresult = OMX_Init();
+
+    if(OMX_ErrorNone != omxresult) {
+        DEBUG_PRINT("\n Failed to Init OpenMAX core");
+          return -1;
+    }
+    else {
+        DEBUG_PRINT("\nOpenMAX Core Init Done\n");
+    }
+
+    /* Query for audio decoders*/
+    DEBUG_PRINT("Qcelp13_test: Before entering OMX_GetComponentOfRole");
+    OMX_GetComponentsOfRole(role, &total, 0);
+    DEBUG_PRINT ("\nTotal components of role=%s :%u", role, total);
+
+
+    omxresult = OMX_GetHandle((OMX_HANDLETYPE*)(&qcelp13_enc_handle),
+                        (OMX_STRING)audio_component, NULL, &call_back);
+    if (FAILED(omxresult)) {
+        DEBUG_PRINT("\nFailed to Load the component:%s\n", audio_component);
+    return -1;
+    }
+    else
+    {
+        DEBUG_PRINT("\nComponent %s is in LOADED state\n", audio_component);
+    }
+
+    /* Get the port information */
+    CONFIG_VERSION_SIZE(portParam);
+    omxresult = OMX_GetParameter(qcelp13_enc_handle, OMX_IndexParamAudioInit,
+                                (OMX_PTR)&portParam);
+
+    if(FAILED(omxresult)) {
+        DEBUG_PRINT("\nFailed to get Port Param\n");
+    return -1;
+    }
+    else
+    {
+        DEBUG_PRINT("\nportParam.nPorts:%u\n", portParam.nPorts);
+    DEBUG_PRINT("\nportParam.nStartPortNumber:%u\n",
+                                             portParam.nStartPortNumber);
+    }
+
+    if(OMX_ErrorNone != omxresult)
+    {
+        DEBUG_PRINT("Set parameter failed");
+    }
+
+    return 0;
+}
+
+int Play_Encoder()
+{
+    unsigned int i;
+    int Size=0;
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE ret;
+    OMX_INDEXTYPE index;
+#ifdef __LP64__
+    DEBUG_PRINT("sizeof[%ld]\n", sizeof(OMX_BUFFERHEADERTYPE));
+#else
+    DEBUG_PRINT("sizeof[%d]\n", sizeof(OMX_BUFFERHEADERTYPE));
+#endif
+
+    /* open the i/p and o/p files based on the video file format passed */
+    if(open_audio_file()) {
+        DEBUG_PRINT("\n Returning -1");
+    return -1;
+    }
+
+    /* Query the encoder input min buf requirements */
+    CONFIG_VERSION_SIZE(inputportFmt);
+
+    /* Port for which the Client needs to obtain info */
+    inputportFmt.nPortIndex = portParam.nStartPortNumber;
+
+    OMX_GetParameter(qcelp13_enc_handle,OMX_IndexParamPortDefinition,&inputportFmt);
+    DEBUG_PRINT ("\nEnc Input Buffer Count %u\n", inputportFmt.nBufferCountMin);
+    DEBUG_PRINT ("\nEnc: Input Buffer Size %u\n", inputportFmt.nBufferSize);
+
+    if(OMX_DirInput != inputportFmt.eDir) {
+        DEBUG_PRINT ("\nEnc: Expect Input Port\n");
+    return -1;
+    }
+
+    pcmparam.nPortIndex   = 0;
+    pcmparam.nChannels    =  channels;
+    pcmparam.nSamplingRate = samplerate;
+    OMX_SetParameter(qcelp13_enc_handle,OMX_IndexParamAudioPcm,&pcmparam);
+
+
+    /* Query the encoder outport's min buf requirements */
+    CONFIG_VERSION_SIZE(outputportFmt);
+    /* Port for which the Client needs to obtain info */
+    outputportFmt.nPortIndex = portParam.nStartPortNumber + 1;
+
+    OMX_GetParameter(qcelp13_enc_handle,OMX_IndexParamPortDefinition,&outputportFmt);
+    DEBUG_PRINT ("\nEnc: Output Buffer Count %u\n", outputportFmt.nBufferCountMin);
+    DEBUG_PRINT ("\nEnc: Output Buffer Size %u\n", outputportFmt.nBufferSize);
+
+    if(OMX_DirOutput != outputportFmt.eDir) {
+        DEBUG_PRINT ("\nEnc: Expect Output Port\n");
+    return -1;
+    }
+
+
+    CONFIG_VERSION_SIZE(qcelp13param);
+
+    qcelp13param.nPortIndex   =  1;
+    qcelp13param.nChannels    =  channels; //2 ; /* 1-> mono 2-> stereo*/
+    qcelp13param.nMinBitRate = min_bitrate;
+    qcelp13param.nMaxBitRate = max_bitrate;
+    OMX_SetParameter(qcelp13_enc_handle,OMX_IndexParamAudioQcelp13,&qcelp13param);
+    OMX_GetExtensionIndex(qcelp13_enc_handle,"OMX.Qualcomm.index.audio.sessionId",&index);
+    OMX_GetParameter(qcelp13_enc_handle,index,&streaminfoparam);
+    if(tunnel) {
+    #ifdef AUDIOV2
+    session_id = streaminfoparam.sessionId;
+    control = msm_mixer_open("/dev/snd/controlC0", 0);
+    if(control < 0)
+    printf("ERROR opening the device\n");
+    device_id = msm_get_device(device);
+    DEBUG_PRINT ("\ndevice_id = %d\n",device_id);
+    DEBUG_PRINT("\nsession_id = %d\n",session_id);
+    if (msm_en_device(device_id, 1))
+    {
+        perror("could not enable device\n");
+        return -1;
+    }
+    if (msm_route_stream(DIR_TX,session_id,device_id, 1))
+    {
+        perror("could not set stream routing\n");
+        return -1;
+    }
+    #endif
+    }
+
+    DEBUG_PRINT ("\nOMX_SendCommand Encoder -> IDLE\n");
+    OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StateIdle,0);
+    /* wait_for_event(); should not wait here event complete status will
+       not come until enough buffer are allocated */
+    if (tunnel == 0)
+    {
+        input_buf_cnt = inputportFmt.nBufferCountActual; //  inputportFmt.nBufferCountMin + 5;
+        DEBUG_PRINT("Transition to Idle State succesful...\n");
+        /* Allocate buffer on decoder's i/p port */
+        error = Allocate_Buffer(qcelp13_enc_handle, &pInputBufHdrs, inputportFmt.nPortIndex,
+                            input_buf_cnt, inputportFmt.nBufferSize);
+        if (error != OMX_ErrorNone || pInputBufHdrs == NULL) {
+            DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer error\n");
+        return -1;
+    }
+    else {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Input buffer success\n");
+    }
+    }
+    output_buf_cnt = outputportFmt.nBufferCountMin ;
+
+    /* Allocate buffer on encoder's O/Pp port */
+    error = Allocate_Buffer(qcelp13_enc_handle, &pOutputBufHdrs, outputportFmt.nPortIndex,
+                            output_buf_cnt, outputportFmt.nBufferSize);
+    if (error != OMX_ErrorNone || pOutputBufHdrs == NULL ) {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer error\n");
+    return -1;
+    }
+    else {
+        DEBUG_PRINT ("\nOMX_AllocateBuffer Output buffer success\n");
+    }
+
+    wait_for_event();
+
+
+    if (tunnel == 1)
+    {
+        DEBUG_PRINT ("\nOMX_SendCommand to enable TUNNEL MODE during IDLE\n");
+        OMX_SendCommand(qcelp13_enc_handle, OMX_CommandPortDisable,0,0); // disable input port
+        wait_for_event();
+    }
+
+    DEBUG_PRINT ("\nOMX_SendCommand encoder -> Executing\n");
+    OMX_SendCommand(qcelp13_enc_handle, OMX_CommandStateSet, OMX_StateExecuting,0);
+    wait_for_event();
+
+    DEBUG_PRINT(" Start sending OMX_FILLthisbuffer\n");
+
+    for(i=0; i < output_buf_cnt; i++) {
+        DEBUG_PRINT ("\nOMX_FillThisBuffer on output buf no.%d\n",i);
+        pOutputBufHdrs[i]->nOutputPortIndex = 1;
+        pOutputBufHdrs[i]->nFlags = pOutputBufHdrs[i]->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
+        ret = OMX_FillThisBuffer(qcelp13_enc_handle, pOutputBufHdrs[i]);
+        if (OMX_ErrorNone != ret) {
+            DEBUG_PRINT("OMX_FillThisBuffer failed with result %d\n", ret);
+    }
+        else {
+            DEBUG_PRINT("OMX_FillThisBuffer success!\n");
+    }
+    }
+
+if(tunnel == 0)
+{
+    DEBUG_PRINT(" Start sending OMX_emptythisbuffer\n");
+    for (i = 0;i < input_buf_cnt;i++) {
+        DEBUG_PRINT ("\nOMX_EmptyThisBuffer on Input buf no.%d\n",i);
+        pInputBufHdrs[i]->nInputPortIndex = 0;
+        Size = Read_Buffer(pInputBufHdrs[i]);
+        if(Size <=0 ){
+          DEBUG_PRINT("NO DATA READ\n");
+          bInputEosReached = true;
+          pInputBufHdrs[i]->nFlags= OMX_BUFFERFLAG_EOS;
+        }
+        pInputBufHdrs[i]->nFilledLen = (OMX_U32)Size;
+        pInputBufHdrs[i]->nInputPortIndex = 0;
+        used_ip_buf_cnt++;
+        ret = OMX_EmptyThisBuffer(qcelp13_enc_handle, pInputBufHdrs[i]);
+        if (OMX_ErrorNone != ret) {
+            DEBUG_PRINT("OMX_EmptyThisBuffer failed with result %d\n", ret);
+        }
+        else {
+            DEBUG_PRINT("OMX_EmptyThisBuffer success!\n");
+        }
+        if(Size <=0 ){
+            break;//eos reached
+        }
+    }
+    pthread_mutex_lock(&etb_lock);
+    if(etb_done)
+{
+        DEBUG_PRINT("Component is waiting for EBD to be released.\n");
+        etb_event_complete();
+    }
+    else
+    {
+        DEBUG_PRINT("\n****************************\n");
+        DEBUG_PRINT("EBD not yet happened ...\n");
+        DEBUG_PRINT("\n****************************\n");
+        etb_done++;
+    }
+    pthread_mutex_unlock(&etb_lock);
+}
+
+    return 0;
+}
+
+
+
+static OMX_ERRORTYPE Allocate_Buffer ( OMX_COMPONENTTYPE *avc_enc_handle,
+                                       OMX_BUFFERHEADERTYPE  ***pBufHdrs,
+                                       OMX_U32 nPortIndex,
+                                       unsigned int bufCntMin, unsigned int bufSize)
+{
+    DEBUG_PRINT("Inside %s \n", __FUNCTION__);
+    OMX_ERRORTYPE error=OMX_ErrorNone;
+    unsigned int bufCnt=0;
+
+    /* To remove warning for unused variable to keep prototype same */
+    (void)avc_enc_handle;
+
+    *pBufHdrs= (OMX_BUFFERHEADERTYPE **)
+                   malloc(sizeof(OMX_BUFFERHEADERTYPE*)*bufCntMin);
+
+    for(bufCnt=0; bufCnt < bufCntMin; ++bufCnt) {
+        DEBUG_PRINT("\n OMX_AllocateBuffer No %d \n", bufCnt);
+        error = OMX_AllocateBuffer(qcelp13_enc_handle, &((*pBufHdrs)[bufCnt]),
+                                   nPortIndex, NULL, bufSize);
+    }
+
+    return error;
+}
+
+
+
+
+static int Read_Buffer (OMX_BUFFERHEADERTYPE  *pBufHdr )
+{
+
+    size_t bytes_read=0;
+
+
+    pBufHdr->nFilledLen = 0;
+    pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
+
+     bytes_read = fread(pBufHdr->pBuffer, 1, pBufHdr->nAllocLen , inputBufferFile);
+
+      pBufHdr->nFilledLen = (OMX_U32)bytes_read;
+      // Time stamp logic
+    ((OMX_BUFFERHEADERTYPE *)pBufHdr)->nTimeStamp = \
+
+    (OMX_TICKS) ((total_pcm_bytes * 1000)/(samplerate * channels *2));
+
+       DEBUG_PRINT ("\n--time stamp -- %ld\n",  (unsigned long)((OMX_BUFFERHEADERTYPE *)pBufHdr)->nTimeStamp);
+        if(bytes_read == 0)
+        {
+          pBufHdr->nFlags |= OMX_BUFFERFLAG_EOS;
+          DEBUG_PRINT ("\nBytes read zero\n");
+        }
+        else
+        {
+            pBufHdr->nFlags = pBufHdr->nFlags & (unsigned)~OMX_BUFFERFLAG_EOS;
+
+            total_pcm_bytes = (unsigned)(total_pcm_bytes + bytes_read);
+        }
+
+    return (int)bytes_read;;
+}
+
+
+
+//In Encoder this Should Open a PCM or WAV file for input.
+
+static int open_audio_file ()
+{
+    int error_code = 0;
+
+    if (!tunnel)
+    {
+        DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, in_filename);
+        inputBufferFile = fopen (in_filename, "rb");
+        if (inputBufferFile == NULL) {
+            DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
+                                         in_filename);
+            return -1;
+        }
+        if(parse_pcm_header() != 0x00)
+        {
+            DEBUG_PRINT("PCM parser failed \n");
+            return -1;
+        }
+    }
+
+    DEBUG_PRINT("Inside %s filename=%s\n", __FUNCTION__, out_filename);
+    outputBufferFile = fopen (out_filename, "wb");
+    if (outputBufferFile == NULL) {
+        DEBUG_PRINT("\ni/p file %s could NOT be opened\n",
+                                         out_filename);
+    error_code = -1;
+    return error_code;
+    }
+    fseek(outputBufferFile, QCP_HEADER_SIZE, SEEK_SET);
+    return error_code;
+}
+
+static OMX_ERRORTYPE parse_pcm_header()
+{
+    struct wav_header hdr;
+
+    DEBUG_PRINT("\n***************************************************************\n");
+    if(fread(&hdr, 1, sizeof(hdr),inputBufferFile)!=sizeof(hdr))
+    {
+        DEBUG_PRINT("Wav file cannot read header\n");
+        return -1;
+    }
+
+    if ((hdr.riff_id != ID_RIFF) ||
+        (hdr.riff_fmt != ID_WAVE)||
+        (hdr.fmt_id != ID_FMT))
+    {
+        DEBUG_PRINT("Wav file is not a riff/wave file\n");
+        return -1;
+    }
+
+    if (hdr.audio_format != FORMAT_PCM)
+    {
+        DEBUG_PRINT("Wav file is not adpcm format %d and fmt size is %d\n",
+                      hdr.audio_format, hdr.fmt_sz);
+        return -1;
+    }
+
+    DEBUG_PRINT("Samplerate is %d\n", hdr.sample_rate);
+    DEBUG_PRINT("Channel Count is %d\n", hdr.num_channels);
+    DEBUG_PRINT("\n***************************************************************\n");
+
+    samplerate = hdr.sample_rate;
+    channels = hdr.num_channels;
+    total_pcm_bytes = 0;
+
+    return OMX_ErrorNone;
+}
diff --git a/post_proc/Android.mk b/post_proc/Android.mk
index 13ee389..cbc5f8e 100644
--- a/post_proc/Android.mk
+++ b/post_proc/Android.mk
@@ -84,7 +84,7 @@
 
 ################################################################################
 
-ifneq ($(filter msm8992 msm8994 msm8996 msm8998 sdm660 sdm845 apq8098_latv msmpeafowl,$(TARGET_BOARD_PLATFORM)),)
+ifneq ($(filter msm8992 msm8994 msm8996 msm8998 sdm660 sdm845 apq8098_latv sdm670,$(TARGET_BOARD_PLATFORM)),)
 
 include $(CLEAR_VARS)
 
diff --git a/qahw_api/Makefile.am b/qahw_api/Makefile.am
index ca1839a..7c74d25 100644
--- a/qahw_api/Makefile.am
+++ b/qahw_api/Makefile.am
@@ -20,5 +20,6 @@
 libqahw_la_CFLAGS = -Dstrlcpy=g_strlcpy $(GLIB_CFLAGS) -include glib.h $(AM_CFLAGS) -include stddef.h
 libqahw_la_CFLAGS += -D__unused=__attribute__\(\(__unused__\)\)
 libqahw_la_CFLAGS += -Wno-sign-compare -Werror
-libqahw_la_LIBADD = $(GLIB_LIBS) -llog -lcutils -lhardware
+libqahw_la_CFLAGS += -Dstrlcat=g_strlcat -Dstrlcpy=g_strlcpy -include glib.h $(GLIB_CFLAGS)
+libqahw_la_LIBADD = $(GLIB_LIBS) -llog -lcutils -lhardware -ldl
 libqahw_la_LDFLAGS = -module -shared -avoid-version
diff --git a/qahw_api/test/qahw_multi_record_test.c b/qahw_api/test/qahw_multi_record_test.c
index f0720f2..23acdeb 100644
--- a/qahw_api/test/qahw_multi_record_test.c
+++ b/qahw_api/test/qahw_multi_record_test.c
@@ -73,6 +73,7 @@
     double record_delay;
     double record_length;
     char profile[50];
+    char kvpairs[256];
 };
 
 struct timed_params {
@@ -279,6 +280,14 @@
       pthread_exit(0);
   }
 
+  /* Turn BT_SCO on if bt_sco recording */
+  if(audio_is_bluetooth_sco_device(params->input_device)) {
+      int ret = -1;
+      const char * bt_sco_on = "BT_SCO=on";
+      ret = qahw_set_parameters(qahw_mod_handle, bt_sco_on);
+      fprintf(log_file, " param %s set to hal with return value %d\n", bt_sco_on, ret);
+  }
+
   /* setup debug node if in kpi mode */
   if (kpi_mode) {
       fdLatencyNode = fopen(LATENCY_NODE,"r+");
@@ -565,6 +574,7 @@
     printf(" -i  --interactive-mode                    - Use this flag if prefer configuring streams using interactive mode\n");
     printf("                                             All other flags passed would be ignore if this flag is used\n\n");
     printf(" -S  --source-tracking                     - Use this flag to show capture source tracking params for recordings\n\n");
+    printf(" -k --kvpairs                              - kvpairs to be set globally\n");
     printf(" -h  --help                                - Show this help\n\n");
     printf(" \n Examples \n");
     printf(" hal_rec_test     -> start a recording stream with default configurations\n\n");
@@ -576,6 +586,8 @@
     printf(" hal_rec_test -S -c 1 -r 48000 -t 30 -> Enable Sourcetracking\n");
     printf("                                      For mono channel 48kHz rate for 30seconds\n\n");
     printf(" hal_rec_test -F 1 --kpi-mode -> start a recording with low latency input flag and calculate latency KPIs\n\n");
+    printf(" hal_rec_test -c 1 -r 16000 -t 30 -k ffvOn=true;ffv_ec_ref_ch_cnt=2 -> Enable FFV with stereo ec ref\n");
+    printf("                                               For mono channel 16kHz rate for 30seconds\n\n");
 }
 
 int main(int argc, char* argv[]) {
@@ -607,6 +619,7 @@
         {"kpi-mode",        no_argument,          0, 'K'},
         {"interactive",     no_argument,          0, 'i'},
         {"source-tracking", no_argument,          0, 'S'},
+        {"kvpairs",         required_argument,    0, 'k'},
         {"help",            no_argument,          0, 'h'},
         {0, 0, 0, 0}
     };
@@ -615,7 +628,7 @@
     int option_index = 0;
     while ((opt = getopt_long(argc,
                               argv,
-                              "-d:f:F:r:c:s:p:t:D:l:KiSh",
+                              "-d:f:F:r:c:s:p:t:D:l:k:KiSh",
                               long_options,
                               &option_index)) != -1) {
             switch (opt) {
@@ -658,6 +671,9 @@
             case 'S':
                 source_tracking = true;
                 break;
+            case 'k':
+                snprintf(params[0].kvpairs, sizeof(params[0].kvpairs), "%s", optarg);
+                break;
             case 'h':
                 usage();
                 return 0;
@@ -768,6 +784,20 @@
         }
     }
 
+    /* set global setparams entered by user.
+     * Also other global setparams can be concatenated if required.
+     */
+    if (params[0].kvpairs != NULL) {
+        size_t len;
+        len = strcspn(params[0].kvpairs, ",");
+        while (len < strlen(params[0].kvpairs)) {
+            params[0].kvpairs[len] = ';';
+            len = strcspn(params[0].kvpairs, ",");
+        }
+        printf("param %s set to hal\n", params[0].kvpairs);
+        qahw_set_parameters(qahw_mod_handle, params[0].kvpairs);
+    }
+
     pthread_t tid[4];
     pthread_t sourcetrack_thread;
     int ret = -1;
diff --git a/qahw_api/test/qahw_playback_test.c b/qahw_api/test/qahw_playback_test.c
index fb69d93..1338591 100644
--- a/qahw_api/test/qahw_playback_test.c
+++ b/qahw_api/test/qahw_playback_test.c
@@ -172,6 +172,7 @@
    if (enable) {
        if (!wakelock_acquired) {
            system_ret = system("echo audio_services > /sys/power/wake_lock");
+           if (system_ret < 0) {
                fprintf(stderr, "%s.Failed to acquire audio_service lock\n", __func__);
                fprintf(log_file, "%s.Failed to acquire audio_service lock\n", __func__);
            } else {
@@ -322,6 +323,7 @@
     case QAHW_STREAM_CBK_EVENT_DRAIN_READY:
         fprintf(log_file, "stream %d: received event - QAHW_STREAM_CBK_EVENT_DRAIN_READY\n", params->stream_index);
         pthread_mutex_lock(&params->drain_lock);
+        params->drain_received = true;
         pthread_cond_signal(&params->drain_cond);
         pthread_mutex_unlock(&params->drain_lock);
         break;
@@ -738,6 +740,21 @@
         fprintf(stderr, "stream %d: unable to set volume\n", params->stream_index);
     }
 
+    if (params->pan_scale_ctrl == QAHW_PARAM_OUT_MIX_MATRIX_PARAMS) {
+        rc = qahw_out_set_param_data(params->out_handle, QAHW_PARAM_OUT_MIX_MATRIX_PARAMS,
+                                     (qahw_param_payload *) &params->mm_params_pan_scale);
+        if (rc != 0) {
+            fprintf(log_file, "QAHW_PARAM_OUT_MIX_MATRIX_PARAMS could not be sent!\n");
+        }
+    }
+    if (params->mix_ctrl == QAHW_PARAM_CH_MIX_MATRIX_PARAMS) {
+        rc = qahw_out_set_param_data(params->out_handle, QAHW_PARAM_CH_MIX_MATRIX_PARAMS,
+                                     (qahw_param_payload *) &params->mm_params_downmix);
+        if (rc != 0) {
+            fprintf(log_file, "QAHW_PARAM_CH_MIX_MATRIX_PARAMS could not be sent!\n");
+        }
+    }
+
     bytes_wanted = qahw_out_get_buffer_size(params->out_handle);
     data_ptr = (char *) malloc (bytes_wanted);
     if (data_ptr == NULL) {
@@ -765,11 +782,14 @@
             if ((!read_complete_file && (bytes_to_read <= 0)) || (bytes_read <= 0)) {
                 fprintf(log_file, "stream %d: end of file\n", params->stream_index);
                 if (is_offload) {
-                    pthread_mutex_lock(&params->drain_lock);
+                    params->drain_received = false;
                     qahw_out_drain(params->out_handle, QAHW_DRAIN_ALL);
-                    pthread_cond_wait(&params->drain_cond, &params->drain_lock);
+                    if(!params->drain_received) {
+                        pthread_mutex_lock(&params->drain_lock);
+                        pthread_cond_wait(&params->drain_cond, &params->drain_lock);
+                        pthread_mutex_unlock(&params->drain_lock);
+                    }
                     fprintf(log_file, "stream %d: out of compress drain\n", params->stream_index);
-                    pthread_mutex_unlock(&params->drain_lock);
                 }
                 /*
                  * Caution: Below ADL log shouldnt be altered without notifying
@@ -1010,7 +1030,7 @@
             else
                 stream_info->config.offload_info.format = AUDIO_FORMAT_PCM_16_BIT;
             if (!(stream_info->flags_set))
-                stream_info->flags = AUDIO_OUTPUT_FLAG_DIRECT_PCM|AUDIO_OUTPUT_FLAG_DIRECT;
+                stream_info->flags = AUDIO_OUTPUT_FLAG_DIRECT;
             break;
 
         case FILE_MP3:
@@ -2337,7 +2357,6 @@
 
     if (is_qap_session_active(argc, argv, kvp_string)) {
         char *file_name = NULL;
-        char *file_name_tmp = NULL;
         char *cmd_kvp_str[100] = {NULL};
         char *play_list_kvp_str[100] = {NULL};
         int i = 0, j = 0;
@@ -2508,23 +2527,6 @@
         }
 
         thread_active[i] = true;
-        usleep(500000); //Wait until stream is created
-        if(stream_param[i].pan_scale_ctrl == QAHW_PARAM_OUT_MIX_MATRIX_PARAMS) {
-            payload = (qahw_param_payload) stream_param[i].mm_params_pan_scale;
-            param_id = QAHW_PARAM_OUT_MIX_MATRIX_PARAMS;
-            rc = qahw_out_set_param_data(stream->out_handle, param_id, &payload);
-            if (rc != 0) {
-                fprintf(log_file, "QAHW_PARAM_OUT_MIX_MATRIX_PARAMS could not be sent!\n");
-            }
-        }
-        if(stream_param[i].mix_ctrl == QAHW_PARAM_CH_MIX_MATRIX_PARAMS) {
-            payload = (qahw_param_payload) stream_param[i].mm_params_downmix;
-            param_id = QAHW_PARAM_CH_MIX_MATRIX_PARAMS;
-            rc = qahw_out_set_param_data(stream->out_handle, param_id, &payload);
-            if (rc != 0) {
-                fprintf(log_file, "QAHW_PARAM_CH_MIX_MATRIX_PARAMS could not be sent!\n");
-            }
-        }
 
     }
 
diff --git a/qahw_api/test/qahw_playback_test.h b/qahw_api/test/qahw_playback_test.h
index 1f524b9..3ec8f25 100644
--- a/qahw_api/test/qahw_playback_test.h
+++ b/qahw_api/test/qahw_playback_test.h
@@ -134,6 +134,7 @@
     pthread_mutex_t write_lock;
     pthread_cond_t drain_cond;
     pthread_mutex_t drain_lock;
+    bool drain_received;
     bool interactive_strm;
     qahw_mix_matrix_params_t mm_params_pan_scale;
     qahw_mix_matrix_params_t mm_params_downmix;
diff --git a/qahw_api/test/qap_wrapper_extn.c b/qahw_api/test/qap_wrapper_extn.c
index 5c76d40..4c35711 100644
--- a/qahw_api/test/qap_wrapper_extn.c
+++ b/qahw_api/test/qap_wrapper_extn.c
@@ -57,10 +57,11 @@
 #define DOLBY 1
 #define DTS   2
 #define FRAME_SIZE_FOR_2CH_PCM 6144 /* For 48k samplerate, 2 ch, 2 bytes */
-
+#define PCM_16_BITWIDTH 16
+#define PCM_24_BITWIDTH 24
+#define DEFAULT_SAMPLE_RATE 48000
 #define MAX_QAP_MODULE_OUT 3
 
-qap_output_config_t qap_out_configs[MAX_QAP_MODULE_OUT];
 bool is_media_fmt_changed[MAX_QAP_MODULE_OUT];
 int new_output_conf_index = 0;
 
@@ -114,20 +115,36 @@
 double data_callback_st_arr[TIMESTAMP_ARRAY_SIZE];
 bool has_system_input = false;
 char session_kv_pairs[256];
-bool stream_close = false;
+bool primary_stream_close = false;
+int8_t stream_cnt = 0;
 uint32_t dsp_latency = 0;
 
-static int get_qap_out_config_index_for_id(int32_t out_id)
+static int get_qap_session_out_config_index_for_id(uint32_t out_id)
 {
     int index = -1, i;
 
     for (i = 0; i < MAX_QAP_MODULE_OUT; i++)
-        if (qap_out_configs[i].id == out_id)
+        if (session_output_config.output_config[i].id == out_id)
             index = i;
 
     return index;
 }
 
+static void set_qahw_stream_channel_map(qahw_stream_handle_t *out_handle, qap_output_config_t *qap_config)
+{
+    struct qahw_out_channel_map_param chmap_param = {0};
+    int i = 0;
+    if (qap_config == NULL || out_handle == NULL) {
+        return;
+    }
+    chmap_param.channels = qap_config->channels;
+    for (i = 0; i < chmap_param.channels && i < AUDIO_CHANNEL_COUNT_MAX && i < QAP_AUDIO_MAX_CHANNELS;
+            i++) {
+        chmap_param.channel_map[i] = qap_config->ch_map[i];
+    }
+    qahw_out_set_param_data(out_handle, QAHW_PARAM_OUT_CHANNEL_MAP, (qahw_param_payload *) &chmap_param);
+}
+
 static void update_combo_dev_kvpairs()
 {
     bool enable_spk = false;
@@ -170,6 +187,79 @@
     ALOGV("%s:%d session set param %s and combo_enabled %d", __func__, __LINE__, session_kv_pairs, combo_enabled);
     return;
 }
+static void update_session_outputs_config(int hdmi_render_format, int in_channels, int bitwidth, int smpl_rate)
+{
+    bool enable_spk = false;
+    bool enable_hp = false;
+    bool enable_hdmi = false;
+    bool combo_enabled = false;
+    char dev_kv_pair[16] = {0};
+
+    ALOGV("%s:%d output device id %d render format = %d", __func__, __LINE__, output_device_id, hdmi_render_format);
+
+    if (output_device_id & AUDIO_DEVICE_OUT_HDMI)
+        enable_hdmi = true;
+    if (output_device_id & AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+        output_device_id & AUDIO_DEVICE_OUT_LINE)
+        enable_hp = true;
+    if (output_device_id & AUDIO_DEVICE_OUT_SPEAKER)
+        enable_spk = true;
+
+    if (enable_hdmi) {
+        session_output_config.output_config[session_output_config.num_output].id = AUDIO_DEVICE_OUT_HDMI;
+        if (hdmi_render_format == 1) {
+            session_output_config.output_config[session_output_config.num_output].id = AUDIO_DEVICE_OUT_HDMI|AUDIO_FORMAT_AC3;
+            session_output_config.output_config[session_output_config.num_output].format = QAP_AUDIO_FORMAT_AC3;
+        } else if (hdmi_render_format == 2) {
+            session_output_config.output_config[session_output_config.num_output].id = AUDIO_DEVICE_OUT_HDMI|AUDIO_FORMAT_E_AC3;
+            session_output_config.output_config[session_output_config.num_output].format = QAP_AUDIO_FORMAT_EAC3;
+        } else if (hdmi_render_format == 3) {
+            session_output_config.output_config[session_output_config.num_output].id = AUDIO_DEVICE_OUT_HDMI|AUDIO_FORMAT_DTS;
+            session_output_config.output_config[session_output_config.num_output].format = QAP_AUDIO_FORMAT_DTS;
+        } else {
+            if (bitwidth == PCM_24_BITWIDTH) {
+                session_output_config.output_config[session_output_config.num_output].format = QAP_AUDIO_FORMAT_PCM_24_BIT_PACKED;
+                session_output_config.output_config[session_output_config.num_output].bit_width = PCM_24_BITWIDTH;
+            } else {
+                session_output_config.output_config[session_output_config.num_output].format = QAP_AUDIO_FORMAT_PCM_16_BIT;
+                session_output_config.output_config[session_output_config.num_output].bit_width = PCM_16_BITWIDTH;
+            }
+        }
+        session_output_config.output_config[session_output_config.num_output].channels = in_channels;
+        session_output_config.output_config[session_output_config.num_output].sample_rate = smpl_rate;
+        session_output_config.num_output++;
+    }
+
+    if (enable_hp) {
+        session_output_config.output_config[session_output_config.num_output].id = AUDIO_DEVICE_OUT_LINE;
+        session_output_config.output_config[session_output_config.num_output].channels = popcount(AUDIO_CHANNEL_OUT_STEREO);
+        session_output_config.output_config[session_output_config.num_output].sample_rate = smpl_rate;
+        if (bitwidth == PCM_24_BITWIDTH) {
+            session_output_config.output_config[session_output_config.num_output].format = QAP_AUDIO_FORMAT_PCM_24_BIT_PACKED;
+            session_output_config.output_config[session_output_config.num_output].bit_width = PCM_24_BITWIDTH;
+        } else {
+            session_output_config.output_config[session_output_config.num_output].format = QAP_AUDIO_FORMAT_PCM_16_BIT;
+            session_output_config.output_config[session_output_config.num_output].bit_width = PCM_16_BITWIDTH;
+        }
+        session_output_config.num_output++;
+    }
+    if (enable_spk) {
+        session_output_config.output_config[session_output_config.num_output].channels = popcount(AUDIO_CHANNEL_OUT_STEREO);
+        session_output_config.output_config[session_output_config.num_output].id = AUDIO_DEVICE_OUT_SPEAKER;
+        session_output_config.output_config[session_output_config.num_output].sample_rate = smpl_rate;
+        if (bitwidth == PCM_24_BITWIDTH) {
+            session_output_config.output_config[session_output_config.num_output].format = QAP_AUDIO_FORMAT_PCM_24_BIT_PACKED;
+            session_output_config.output_config[session_output_config.num_output].bit_width = PCM_24_BITWIDTH;
+        } else {
+            session_output_config.output_config[session_output_config.num_output].format = QAP_AUDIO_FORMAT_PCM_16_BIT;
+            session_output_config.output_config[session_output_config.num_output].bit_width = PCM_16_BITWIDTH;
+        }
+        session_output_config.num_output++;
+    }
+
+    ALOGV("%s:%d num_output = %d", __func__, __LINE__, session_output_config.num_output);
+    return;
+}
 
 static void update_kvpairs_for_encode(int out_device_id) {
     uint8_t device_id;
@@ -320,8 +410,7 @@
     if (tmp_str != NULL) {
         file_str = strstr(kvp_string, ".txt");
         len = file_str - tmp_str;
-        play_list = (char*) malloc(sizeof(char) * (len+4));
-        memset(play_list, '\0', len+4);
+        play_list = (char*) calloc(1, sizeof(char) * (len+4));
         strncpy(play_list, tmp_str+2, len+2);
     }
     return play_list;
@@ -392,13 +481,13 @@
             }
         }
         i++;
-        while (!stream_close) {
+        while (!primary_stream_close) {
             usleep(50000);
             fprintf(stderr, "QAP Stream not closed\n");
         }
         fprintf(stderr, "QAP Stream closed\n");
     } while (i <num_of_streams);
-    if (broad_cast && qap_wrapper_session_active) {
+    if (qap_wrapper_session_active) {
         qap_wrapper_session_close();
         qap_wrapper_session_active = false;
     }
@@ -427,8 +516,7 @@
         if (temp_kvp != NULL) {
             temp_key = strtok_r(temp_kvp, "=", &context2);
             if (!strncmp(key, temp_key, strlen(key))) {
-                kvp = malloc((strlen(token) + 1) * sizeof(char));
-                memset(kvp, 0, strlen(token) + 1);
+                kvp = calloc(1, (strlen(token) + 1) * sizeof(char));
                 strncat(kvp, token, strlen(token));
                 return kvp;
             }
@@ -441,8 +529,7 @@
                 if (temp_kvp != NULL) {
                     temp_key = strtok_r(temp_kvp, "=", &context2);
                     if (!strncmp(key, temp_key, strlen(key))) {
-                        kvp = malloc((strlen(token) + 1) * sizeof(char));
-                        memset(kvp, 0, strlen(token) + 1);
+                        kvp = calloc(1, (strlen(token) + 1) * sizeof(char));
                         strncat(kvp, token, strlen(token));
                         return kvp;
                     }
@@ -488,7 +575,7 @@
             for (i=0; s[i]; s[i]==',' ? i++ : *s++);
 
             temp = i;
-            val = malloc((i + 1)*sizeof(int));
+            val = calloc(1, (i + 1)*sizeof(int));
             i = 0;
             val[i++] = strtol(tempstr2, &endstr, 0);
 
@@ -690,7 +777,7 @@
             fprintf(stderr, "%s::%d: could not close output stream, error - %d\n", __func__, __LINE__, ret);
         qap_out_hdmi_handle = NULL;
     }
-    stream_close = true;
+    primary_stream_close = true;
 }
 
 void qap_wrapper_session_callback(qap_session_handle_t session_handle __unused, void* priv_data __unused, qap_callback_event_t event_id, int size __unused, void *data)
@@ -707,13 +794,15 @@
     switch (event_id) {
         case QAP_CALLBACK_EVENT_EOS:
             ALOGV("%s %d Received Main Input EOS", __func__, __LINE__);
+            if (stream_cnt > 0)
+                stream_cnt--;
             pthread_mutex_lock(&main_eos_lock);
             pthread_cond_signal(&main_eos_cond);
             pthread_mutex_unlock(&main_eos_lock);
 
             ALOGE("%s %d Received Main Input EOS ", __func__, __LINE__);
-            if (!stream_close)
-            close_output_streams();
+            if (!stream_cnt)
+                close_output_streams();
             if (play_list_cnt && input_streams_count) {
                 play_list_cnt--;
                 input_streams_count = 0;
@@ -721,12 +810,16 @@
             break;
         case QAP_CALLBACK_EVENT_EOS_ASSOC:
         case QAP_CALLBACK_EVENT_MAIN_2_EOS:
+            if (stream_cnt > 0)
+                stream_cnt--;
             if (!has_system_input){
                 ALOGV("%s %d Received Secondary Input EOS", __func__, __LINE__);
                 pthread_mutex_lock(&sec_eos_lock);
                 pthread_cond_signal(&sec_eos_cond);
                 pthread_mutex_unlock(&sec_eos_lock);
             }
+            if (!stream_cnt)
+                close_output_streams();
             break;
         case QAP_CALLBACK_EVENT_ERROR:
             break;
@@ -743,17 +836,13 @@
 
                 ALOGV("%s %d Received Output cfg change", __func__, __LINE__);
                 if (buffer) {
-                    index = get_qap_out_config_index_for_id(
+                    index = get_qap_session_out_config_index_for_id(
                               buffer->buffer_parms.output_buf_params.output_id);
-                    if (index < 0 && new_output_conf_index < MAX_QAP_MODULE_OUT) {
-                        index = new_output_conf_index;
-                        cached_conf = &qap_out_configs[index];
-                        new_output_conf_index++;
-                    }
+                    if (index >= 0)
+                        cached_conf = &session_output_config.output_config[index];
                 }
-
                 if (cached_conf == NULL) {
-                    ALOGE("Maximum output from QAP is reached");
+                    ALOGE("Invalid output config from QAP is reached");
                     return;
                 }
                 if (memcmp(cached_conf, new_conf, sizeof(qap_output_config_t)) != 0) {
@@ -802,17 +891,18 @@
                 if (buffer && buffer->common_params.data) {
                     int index = -1;
                     bool is_reopen_stream = false;
-                    index = get_qap_out_config_index_for_id(buffer->buffer_parms.output_buf_params.output_id);
+                    index = get_qap_session_out_config_index_for_id(buffer->buffer_parms.output_buf_params.output_id);
                     if (index > -1 && is_media_fmt_changed[index]) {
-                        session_output_config.output_config->sample_rate = qap_out_configs[index].sample_rate;
-                        session_output_config.output_config->bit_width = qap_out_configs[index].bit_width;
-                        session_output_config.output_config->channels = qap_out_configs[index].channels;
                         is_reopen_stream = true;
                         is_media_fmt_changed[index] = false;
+                    } else if (index < 0) {
+                        ALOGE("%s: No Valid Output Config found for id = %d",
+                                     __func__, buffer->buffer_parms.output_buf_params.output_id);
+                        break;
                     }
 
-                    if (buffer->buffer_parms.output_buf_params.output_id &
-                            AUDIO_DEVICE_OUT_HDMI) {
+                    if ((buffer->buffer_parms.output_buf_params.output_id &
+                            AUDIO_DEVICE_OUT_HDMI) == AUDIO_DEVICE_OUT_HDMI) {
                         if (!hdmi_connected) {
                             char param[100] = {0};
                             snprintf(param, sizeof(param), "%s=%d", "connect", AUDIO_DEVICE_OUT_HDMI);
@@ -852,35 +942,32 @@
 
                             config.offload_info.version = AUDIO_INFO_INITIALIZER.version;
                             config.offload_info.size = AUDIO_INFO_INITIALIZER.size;
-                            config.sample_rate = config.offload_info.sample_rate =
-                                                        session_output_config.output_config->sample_rate;
-                            if (session_output_config.output_config->bit_width == 24) {
-                                config.format = config.offload_info.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
-                                config.offload_info.bit_width = 24;
-                            } else {
-                                config.format = config.offload_info.format = AUDIO_FORMAT_PCM_16_BIT;
-                                config.offload_info.bit_width = 16;
+                            config.sample_rate = config.offload_info.sample_rate = DEFAULT_SAMPLE_RATE;
+
+                            if (index > -1) {
+                                if (session_output_config.output_config[index].sample_rate > 0)
+                                    config.sample_rate = config.offload_info.sample_rate = session_output_config.output_config[index].sample_rate;
+                                config.offload_info.channel_mask = config.channel_mask =
+                                                   audio_channel_out_mask_from_count(session_output_config.output_config[index].channels);
+                                if (session_output_config.output_config[index].bit_width == 24) {
+                                    config.format = config.offload_info.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+                                    config.offload_info.bit_width = 24;
+                                } else {
+                                    config.format = config.offload_info.format = AUDIO_FORMAT_PCM_16_BIT;
+                                    config.offload_info.bit_width = 16;
+                                }
+                                if (session_output_config.output_config[index].format == QAP_AUDIO_FORMAT_AC3)
+                                    config.format = config.offload_info.format = AUDIO_FORMAT_AC3;
+                                else if (session_output_config.output_config[index].format == QAP_AUDIO_FORMAT_EAC3)
+                                    config.format = config.offload_info.format = AUDIO_FORMAT_E_AC3;
+                                else if (session_output_config.output_config[index].format == QAP_AUDIO_FORMAT_DTS)
+                                    config.format = config.offload_info.format = AUDIO_FORMAT_DTS;
                             }
 
-                            if (session_output_config.output_config->channels == 2) {
-                                config.offload_info.channel_mask = config.channel_mask =
-                                    AUDIO_CHANNEL_OUT_STEREO;
-                            } else {
-                                config.offload_info.channel_mask = config.channel_mask =
-                                    audio_channel_out_mask_from_count(MAX_OUTPUT_CHANNELS);
-                            }
                             devices = AUDIO_DEVICE_OUT_HDMI;
                             if (timestamp_mode)
                                 flags |= AUDIO_OUTPUT_FLAG_TIMESTAMP;
                             if (encode) {
-                                if (buffer->buffer_parms.output_buf_params.output_id ==
-                                       (AUDIO_FORMAT_AC3|AUDIO_DEVICE_OUT_HDMI))
-                                    config.format = config.offload_info.format = AUDIO_FORMAT_AC3;
-                                else if (buffer->buffer_parms.output_buf_params.output_id ==
-                                            (AUDIO_FORMAT_E_AC3|AUDIO_DEVICE_OUT_HDMI))
-                                    config.format = config.offload_info.format = AUDIO_FORMAT_E_AC3;
-                                else
-                                    config.format = config.offload_info.format = AUDIO_FORMAT_DTS;
                                 ALOGV("%s:%d output format %x", __func__, __LINE__,
                                         config.format, config.offload_info.format);
                                 ret = qahw_open_output_stream(qap_out_hal_handle, qap_stream_out_cmpr_handle, devices,
@@ -888,6 +975,8 @@
                             } else {
                                 ret = qahw_open_output_stream(qap_out_hal_handle, qap_stream_out_hdmi_handle, devices,
                                                               flags, &config, &qap_out_hdmi_handle, "stream");
+                                if (index > -1)
+                                    set_qahw_stream_channel_map(qap_out_hdmi_handle, &session_output_config.output_config[index]);
                             }
 
                             ret = qahw_out_set_volume(qap_out_hdmi_handle, vol_level, vol_level);
@@ -909,7 +998,8 @@
                              ALOGD("%s::%d Measuring Kpi cold stop %lf", __func__, __LINE__, cold_stop);
                         }
                     }
-                    if (buffer->buffer_parms.output_buf_params.output_id & AUDIO_DEVICE_OUT_WIRED_HEADPHONE) {
+                    if (buffer->buffer_parms.output_buf_params.output_id == AUDIO_DEVICE_OUT_WIRED_HEADPHONE ||
+                        buffer->buffer_parms.output_buf_params.output_id == AUDIO_DEVICE_OUT_LINE) {
                         if (enable_dump && fp_output_writer_hp == NULL) {
                             fp_output_writer_hp =
                                          fopen("/sdcard/output_hp.dump","wb");
@@ -937,18 +1027,21 @@
                             audio_devices_t devices;
                             config.offload_info.version = AUDIO_INFO_INITIALIZER.version;
                             config.offload_info.size = AUDIO_INFO_INITIALIZER.size;
-                            config.sample_rate = config.offload_info.sample_rate =
-                                                        session_output_config.output_config->sample_rate;
-                            if (session_output_config.output_config->bit_width == 24) {
-                                config.format = config.offload_info.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
-                                config.offload_info.bit_width = 24;
-                            } else {
-                                config.format = config.offload_info.format = AUDIO_FORMAT_PCM_16_BIT;
-                                config.offload_info.bit_width = 16;
+                            config.sample_rate = config.offload_info.sample_rate = DEFAULT_SAMPLE_RATE;
+                            config.format = config.offload_info.format = AUDIO_FORMAT_PCM_16_BIT;
+                            config.offload_info.bit_width = 16;
+                            config.offload_info.channel_mask = config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+
+                           if (index > -1) {
+                                config.sample_rate = config.offload_info.sample_rate = session_output_config.output_config[index].sample_rate;
+                                config.offload_info.channel_mask = config.channel_mask =
+                                                   audio_channel_out_mask_from_count(session_output_config.output_config[index].channels);
+                                if (session_output_config.output_config[index].bit_width == 24) {
+                                    config.format = config.offload_info.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+                                    config.offload_info.bit_width = 24;
+                                }
                             }
 
-                            config.offload_info.channel_mask = config.channel_mask =
-                                    AUDIO_CHANNEL_OUT_STEREO;
                             devices = AUDIO_DEVICE_OUT_LINE;//ToDO - Need to change to AUDIO_DEVICE_OUT_WIRED_HEADPHONE
 
                             if (timestamp_mode)
@@ -960,6 +1053,8 @@
                                 ALOGE("%s:%d could not open output stream, error - %d", __func__, __LINE__, ret);
                                 return;
                             }
+                            if (index > -1)
+                                set_qahw_stream_channel_map(qap_out_hp_handle, &session_output_config.output_config[index]);
                             ret = qahw_out_set_volume(qap_out_hp_handle, vol_level, vol_level);
                             if (ret < 0)
                                  ALOGE("unable to set volume");
@@ -979,7 +1074,7 @@
                              ALOGD("%s::%d Measuring Kpi cold stop %lf", __func__, __LINE__, cold_stop);
                         }
                     }
-                    if (buffer->buffer_parms.output_buf_params.output_id & AUDIO_DEVICE_OUT_SPEAKER) {
+                    if (buffer->buffer_parms.output_buf_params.output_id == AUDIO_DEVICE_OUT_SPEAKER) {
                         if (enable_dump && fp_output_writer_spk == NULL) {
                             char ch[4] = {0};
                             fp_output_writer_spk =
@@ -1009,20 +1104,24 @@
                         if (qap_out_spk_handle == NULL) {
                             struct audio_config config;
                             audio_devices_t devices;
+
                             config.offload_info.version = AUDIO_INFO_INITIALIZER.version;
                             config.offload_info.size = AUDIO_INFO_INITIALIZER.size;
-                            config.sample_rate = config.offload_info.sample_rate =
-                                                        session_output_config.output_config->sample_rate;
-                            if (session_output_config.output_config->bit_width == 24) {
-                                config.format = config.offload_info.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
-                                config.offload_info.bit_width = 24;
-                            } else {
-                                config.format = config.offload_info.format = AUDIO_FORMAT_PCM_16_BIT;
-                                config.offload_info.bit_width = 16;
+                            config.sample_rate = config.offload_info.sample_rate = DEFAULT_SAMPLE_RATE;
+                            config.format = config.offload_info.format = AUDIO_FORMAT_PCM_16_BIT;
+                            config.offload_info.bit_width = 16;
+                            config.offload_info.channel_mask = config.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+
+                           if (index > -1) {
+                                 config.sample_rate = config.offload_info.sample_rate = session_output_config.output_config[index].sample_rate;
+                                 config.offload_info.channel_mask = config.channel_mask =
+                                 audio_channel_out_mask_from_count(session_output_config.output_config[index].channels);
+                                 if (session_output_config.output_config[index].bit_width == 24) {
+                                     config.format = config.offload_info.format = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+                                     config.offload_info.bit_width = 24;
+                                 }
                             }
 
-                            config.offload_info.channel_mask = config.channel_mask =
-                                    AUDIO_CHANNEL_OUT_STEREO;
                             if (play_through_bt) {
                                 fprintf(stderr, "%s::%d: connecting BT\n", __func__, __LINE__);
                                 char param[100] = {0};
@@ -1042,6 +1141,8 @@
                                 ALOGE("%s:%d could not open output stream, error - %d", __func__, __LINE__, ret);
                                 return;
                             }
+                            if (index > -1)
+                                set_qahw_stream_channel_map(qap_out_spk_handle, &session_output_config.output_config[index]);
                             ret = qahw_out_set_volume(qap_out_spk_handle, vol_level, vol_level);
                             if (ret < 0)
                                  ALOGE("unable to set volume");
@@ -1121,6 +1222,8 @@
     char *encode_kvp = NULL;
     int *temp_val = NULL;
     char *bitwidth_kvp = NULL;
+    int out_bitwidth = PCM_16_BITWIDTH;
+    int out_sample_rate = DEFAULT_SAMPLE_RATE;
 
     qap_out_hal_handle = hal_handle;
     if (kpi_mode) {
@@ -1137,7 +1240,7 @@
 
     memset(&session_output_config, 0, sizeof(session_output_config));
     strcpy(session_kv_pairs, kv_pairs);
-
+    ALOGV("%s session_kv_pairs = %s", __func__, session_kv_pairs);
     if (NULL != (session_type_kvp = qap_wrapper_get_single_kvp("broadcast", kv_pairs, &status))) {
         session_type = SESSION_BROADCAST;
         fprintf(stdout, "Session Type is Broadcast\n");
@@ -1162,7 +1265,7 @@
         }
     }
 
-    if (stream->filetype == FILE_DTS) {
+    if (stream->filetype == FILE_DTS && (NULL == m8_lib_handle)) {
         m8_lib_handle = (qap_session_handle_t) qap_load_library(QAC_LIB_M8);
         if (m8_lib_handle == NULL) {
             fprintf(stdout, "Failed to load M8 library\n");
@@ -1176,7 +1279,7 @@
                 (stream->filetype == FILE_WAV) ||
                 (stream->filetype == FILE_AAC) ||
                 (stream->filetype == FILE_AAC_ADTS) ||
-                (stream->filetype == FILE_AAC_LATM)) {
+                (stream->filetype == FILE_AAC_LATM) && (NULL == ms12_lib_handle)) {
         ms12_lib_handle = (qap_session_handle_t) qap_load_library(QAC_LIB_MS12);
         if (ms12_lib_handle == NULL) {
             fprintf(stderr, "Failed to load MS12 library\n");
@@ -1189,18 +1292,13 @@
 
     // To-Do - Need to check SPDIF out also when SPDIF out is supported
     ALOGD("%s::%d output device %d", __func__, __LINE__, stream->output_device);
-    if (stream->output_device & AUDIO_DEVICE_OUT_HDMI)
-        update_kvpairs_for_encode(AUDIO_DEVICE_OUT_HDMI);
-
-    if (stream->filetype == FILE_DTS)
-        session_output_config.output_config->bit_width = 24;
 
     bitwidth_kvp = qap_wrapper_get_single_kvp("bitwidth", kv_pairs, &status);
     if (bitwidth_kvp != NULL) {
         temp_val = qap_wrapper_get_int_value_array(bitwidth_kvp, &temp, &status);
         if (temp_val != NULL) {
             if (stream->filetype == FILE_DTS)
-                session_output_config.output_config->bit_width = temp_val[0];
+                out_bitwidth = temp_val[0];
             free(temp_val);
             temp_val = NULL;
         }
@@ -1250,44 +1348,26 @@
     }
 
     if (!session_output_configured) {
-        session_output_config.output_config->channels = stream->channels;
-        session_output_config.output_config->sample_rate = stream->config.sample_rate;
-        if (session_type == SESSION_BROADCAST)
-            session_output_config.output_config->sample_rate = 48000;
+        if (session_type != SESSION_BROADCAST)
+            out_sample_rate = stream->config.sample_rate;;
 
         output_device_id = stream->output_device;
         if (output_device_id & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) {
             output_device_id |= AUDIO_DEVICE_OUT_SPEAKER;
             play_through_bt = true;
         }
-        if (output_device_id & AUDIO_DEVICE_OUT_LINE) {
-            output_device_id |= AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
-        }
-        if (encode) {
-            if (render_format == 1)
-                output_device_id |= AUDIO_FORMAT_AC3;
-            else if (render_format == 2)
-                output_device_id |= AUDIO_FORMAT_E_AC3;
-            else if (render_format == 3)
-                output_device_id |= AUDIO_FORMAT_DTS;
-        }
-        session_output_config.output_config->id = output_device_id;
-        update_combo_dev_kvpairs();
-        if (stream->filetype != FILE_DTS)
-            session_output_config.output_config->bit_width = stream->config.offload_info.bit_width;
-        session_output_config.num_output = 1;
-
+        update_session_outputs_config(render_format, stream->channels, out_bitwidth, out_sample_rate);
         ret = qap_session_cmd(qap_session_handle, QAP_SESSION_CMD_SET_OUTPUTS, sizeof(session_output_config), &session_output_config, NULL, NULL);
         if (ret != QAP_STATUS_OK) {
             fprintf(stderr, "Output config failed\n");
             return -EINVAL;
         }
 
-        ALOGV("Session set params %s", session_kv_pairs);
-        ret = qap_session_cmd(qap_session_handle, QAP_SESSION_CMD_SET_KVPAIRS, sizeof(session_kv_pairs), session_kv_pairs, NULL, NULL);
-        if (ret != QAP_STATUS_OK) {
-            fprintf(stderr, "Session set params failed\n");
-            return -EINVAL;
+        bitwidth_kvp = qap_wrapper_get_single_kvp("k", kv_pairs, &status);
+        if (bitwidth_kvp && strncmp(bitwidth_kvp, "k=", 2) == 0) {
+            ret = qap_session_cmd(qap_session_handle, QAP_SESSION_CMD_SET_KVPAIRS, (sizeof(bitwidth_kvp) - 2), &bitwidth_kvp[2], NULL, NULL);
+            if (ret != QAP_STATUS_OK)
+                fprintf(stderr, "Session set params failed\n");
         }
         usleep(2000);
         session_output_configured = true;
@@ -1307,6 +1387,16 @@
     session_output_configured = false;
     qap_session_close(qap_session_handle);
     qap_session_handle = NULL;
+    if (stream_cnt == 0) {
+        if (NULL != m8_lib_handle) {
+            qap_unload_library(m8_lib_handle);
+            m8_lib_handle = NULL;
+        }
+        if (NULL != ms12_lib_handle) {
+            qap_unload_library(ms12_lib_handle);
+            ms12_lib_handle = NULL;
+        }
+    }
 }
 
 void *qap_wrapper_start_stream (void* stream_data)
@@ -1488,16 +1578,14 @@
         free( buffer);
         buffer = NULL;
     }
+    qap_module_deinit(qap_module_handle);
     if ((true == play_list) && (0 == play_list_cnt) && qap_out_hal_handle) {
-         ALOGV("%s %d QAP_CALLBACK_EVENT_EOS for play list received and unload_hals", __func__, __LINE__);
-         unload_hals();
+         ALOGV("%s %d QAP_CALLBACK_EVENT_EOS for play list received", __func__, __LINE__);
          qap_out_hal_handle = NULL;
     } else if (!play_list && qap_out_hal_handle) {
-         ALOGV("%s %d QAP_CALLBACK_EVENT_EOS and unload_hals", __func__, __LINE__);
-         unload_hals();
+         ALOGV("%s %d QAP_CALLBACK_EVENT_EOS received", __func__, __LINE__);
          qap_out_hal_handle = NULL;
     }
-    qap_module_deinit(qap_module_handle);
     if (kpi_mode) {
         qap_wrapper_measure_kpi_values(cold_start, cold_stop);
     }
@@ -1572,7 +1660,8 @@
         return NULL;
     }
 
-    stream_close = false;
+    primary_stream_close = false;
+    stream_cnt++;
     return qap_module_handle;
 
 }
@@ -1580,33 +1669,27 @@
 {
     char *token = NULL;
     char *strings[100] = {NULL};
-    char cmd_str[500] = {0};
+    char cmd_str[1024] = {0};
     char *tmp_str = NULL;
     int i = 0;
 
     do {
-        int j = 0, cnt = 1, status = 0;
+        int j = 0, cnt = 0, status = 0;
 
         if (fgets(cmd_str, sizeof(cmd_str), fp) != NULL)
             tmp_str = strdup(cmd_str);
         else
             break;
-        fprintf(stdout, "%s %d\n", __FUNCTION__, __LINE__);
+        fprintf(stdout, "%s %d tmp_str is %s", __FUNCTION__, __LINE__, tmp_str);
         token = strtok(tmp_str, " ");
         if (NULL != token) {
-            strings[cnt] = (char*)calloc(1, (strlen(token) +1));
-            memset(strings[cnt], '\0', strlen(token) +1);
-            strncpy(strings[cnt], token, strlen(token));
-            cnt++;
+            strings[cnt++] = strdup("playlist");
+            strings[cnt++] = strdup(token);
             while (NULL != (token = strtok(NULL, " "))) {
-                strings[cnt] = (char*)calloc(1, (strlen(token) +1));
-                memset(strings[cnt], '\0', strlen(token) +1);
-                strncpy(strings[cnt], token, strlen(token));
+                strings[cnt] = strdup(token);
+                ALOGV("%s %d strings[%d] is %s", __FUNCTION__, __LINE__, cnt, strings[cnt]);
                 cnt++;
             }
-            strings[0] = calloc(1, 4);
-            memset(strings[0], '\0', 4);
-            strncpy(strings[0], "play_list", 3);
             for (j = 0;j< cnt;j++) {
                 if (!strncmp(strings[j], "-f", 2)) {
                    (*stream_param)[i].filename = strdup(strings[j+1]);
@@ -1626,15 +1709,21 @@
                     (*stream_param)[i].aac_fmt_type = atoi(strings[j+1]);
                 }
             }
+            free(tmp_str);
+            tmp_str = NULL;
         }
         if(NULL != (*stream_param)[i].filename) {
             *num_of_streams = i+1;
             play_list = true;
-            kvp_str[i] = (char *)qap_wrapper_get_cmd_string_from_arg_array(cnt, (char**)strings, &status);
+            kvp_str[i] = (char *)qap_wrapper_get_cmd_string_from_arg_array(cnt, strings, &status);
+            ALOGV("%s %d kvp_str[%d] is %s", __FUNCTION__, __LINE__, i, kvp_str[i]);
         }
-        free(tmp_str);
-        for (j=0; j < cnt; j++)
-           free(strings[j]);
+        for (j=0; j < cnt; j++) {
+           if (NULL != strings[j]){
+               free(strings[j]);
+               strings[j] = NULL;
+           }
+        }
         i++;
     }while(NULL != cmd_str);
 
diff --git a/qahw_api/test/trans_loopback_test.c b/qahw_api/test/trans_loopback_test.c
index 1ba2c55..f81cef7 100644
--- a/qahw_api/test/trans_loopback_test.c
+++ b/qahw_api/test/trans_loopback_test.c
@@ -103,6 +103,7 @@
 
 /* Function declarations */
 void usage();
+int poll_data_event_init();
 
 typedef enum source_port_type {
     SOURCE_PORT_NONE,