Merge "audio: Dynamic USB profile changes"
diff --git a/configs/sdm845/mixer_paths_skuk.xml b/configs/sdm845/mixer_paths_skuk.xml
index 08f6d2c..242fa57 100644
--- a/configs/sdm845/mixer_paths_skuk.xml
+++ b/configs/sdm845/mixer_paths_skuk.xml
@@ -1419,6 +1419,11 @@
<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" />
diff --git a/configs/sdm845/mixer_paths_tavil.xml b/configs/sdm845/mixer_paths_tavil.xml
index f20566d..7b2e638 100644
--- a/configs/sdm845/mixer_paths_tavil.xml
+++ b/configs/sdm845/mixer_paths_tavil.xml
@@ -467,27 +467,27 @@
<ctl name="ASRC1 Output Mode" value="INT" />
<!-- IIR/voice anc -->
- <ctl name="IIR0 Band1" id ="0" value="0" />
+ <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="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="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="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="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" />
@@ -1550,6 +1550,11 @@
<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" />
@@ -1845,31 +1850,6 @@
</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" />
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_hw.c b/hal/audio_hw.c
index 4ca649b..6cf2231 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -4529,10 +4529,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;
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/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/inc/omx_aac_aenc.h b/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
index 374611a..6041ffe 100644
--- a/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
+++ b/mm-audio/aenc-aac/qdsp6/inc/omx_aac_aenc.h
@@ -53,6 +53,7 @@
#include "QOMX_AudioIndexExtensions.h"
#include "OMX_Core.h"
#include "OMX_Audio.h"
+#include "OMX_IndexExt.h"
#include "aenc_svr.h"
#include "qc_omx_component.h"
#include "Map.h"
diff --git a/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp b/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
index ca6bb6e..51b2056 100644
--- a/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
+++ b/mm-audio/aenc-aac/qdsp6/src/omx_aac_aenc.cpp
@@ -45,6 +45,14 @@
#define SLEEP_MS 100
+static const OMX_U32 supported_profiles[] = {
+ OMX_AUDIO_AACObjectLC,
+ OMX_AUDIO_AACObjectHE,
+ OMX_AUDIO_AACObjectHE_PS,
+};
+
+static const int num_profiles = sizeof(supported_profiles) / sizeof(supported_profiles[0]);
+
// omx_cmd_queue destructor
omx_aac_aenc::omx_cmd_queue::~omx_cmd_queue()
{
@@ -2777,6 +2785,25 @@
break;
}
+ case OMX_IndexParamAudioProfileQuerySupported:
+ {
+ DEBUG_PRINT("OMX_IndexParamAudioProfileQuerySupported");
+ OMX_AUDIO_PARAM_ANDROID_PROFILETYPE *profileParams =
+ (OMX_AUDIO_PARAM_ANDROID_PROFILETYPE *)paramData;
+
+ if (profileParams->nPortIndex != 1) {
+ return OMX_ErrorUndefined;
+ }
+
+ if (profileParams->nProfileIndex >= num_profiles) {
+ return OMX_ErrorNoMore;
+ }
+
+ profileParams->eProfile =
+ supported_profiles[profileParams->nProfileIndex];
+
+ return OMX_ErrorNone;
+ }
default:
{
DEBUG_PRINT_ERROR("unknown param %08x\n", paramIndex);
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/qahw_api/test/qahw_playback_test.c b/qahw_api/test/qahw_playback_test.c
index f7f9e34..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 {
@@ -1029,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: