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(¶ms->drain_lock);
+ params->drain_received = true;
pthread_cond_signal(¶ms->drain_cond);
pthread_mutex_unlock(¶ms->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 *) ¶ms->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 *) ¶ms->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(¶ms->drain_lock);
+ params->drain_received = false;
qahw_out_drain(params->out_handle, QAHW_DRAIN_ALL);
- pthread_cond_wait(¶ms->drain_cond, ¶ms->drain_lock);
+ if(!params->drain_received) {
+ pthread_mutex_lock(¶ms->drain_lock);
+ pthread_cond_wait(¶ms->drain_cond, ¶ms->drain_lock);
+ pthread_mutex_unlock(¶ms->drain_lock);
+ }
fprintf(log_file, "stream %d: out of compress drain\n", params->stream_index);
- pthread_mutex_unlock(¶ms->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,