summaryrefslogtreecommitdiffstats
path: root/msm8909/mm-audio/aenc-evrc/qdsp6
diff options
context:
space:
mode:
Diffstat (limited to 'msm8909/mm-audio/aenc-evrc/qdsp6')
-rw-r--r--msm8909/mm-audio/aenc-evrc/qdsp6/Android.mk67
-rw-r--r--msm8909/mm-audio/aenc-evrc/qdsp6/Makefile81
-rw-r--r--msm8909/mm-audio/aenc-evrc/qdsp6/inc/Map.h244
-rw-r--r--msm8909/mm-audio/aenc-evrc/qdsp6/inc/aenc_svr.h122
-rw-r--r--msm8909/mm-audio/aenc-evrc/qdsp6/inc/omx_evrc_aenc.h539
-rw-r--r--msm8909/mm-audio/aenc-evrc/qdsp6/src/aenc_svr.c205
-rw-r--r--msm8909/mm-audio/aenc-evrc/qdsp6/src/omx_evrc_aenc.cpp4531
-rw-r--r--msm8909/mm-audio/aenc-evrc/qdsp6/test/omx_evrc_enc_test.c1098
8 files changed, 6887 insertions, 0 deletions
diff --git a/msm8909/mm-audio/aenc-evrc/qdsp6/Android.mk b/msm8909/mm-audio/aenc-evrc/qdsp6/Android.mk
new file mode 100644
index 00000000..a9f556dc
--- /dev/null
+++ b/msm8909/mm-audio/aenc-evrc/qdsp6/Android.mk
@@ -0,0 +1,67 @@
+ifneq ($(BUILD_TINY_ANDROID),true)
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# ---------------------------------------------------------------------------------
+# Common definitons
+# ---------------------------------------------------------------------------------
+
+libOmxEvrcEnc-def := -g -O3
+libOmxEvrcEnc-def += -DQC_MODIFIED
+libOmxEvrcEnc-def += -D_ANDROID_
+libOmxEvrcEnc-def += -D_ENABLE_QC_MSG_LOG_
+libOmxEvrcEnc-def += -DVERBOSE
+libOmxEvrcEnc-def += -D_DEBUG
+libOmxEvrcEnc-def += -Wconversion
+libOmxEvrcEnc-def += -DAUDIOV2
+
+# ---------------------------------------------------------------------------------
+# Make the Shared library (libOmxEvrcEnc)
+# ---------------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+
+libOmxEvrcEnc-inc := $(LOCAL_PATH)/inc
+libOmxEvrcEnc-inc += $(TARGET_OUT_HEADERS)/mm-core/omxcore
+
+LOCAL_MODULE := libOmxEvrcEnc
+LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := $(libOmxEvrcEnc-def)
+LOCAL_C_INCLUDES := $(libOmxEvrcEnc-inc)
+LOCAL_PRELINK_MODULE := false
+LOCAL_SHARED_LIBRARIES := libutils liblog
+
+LOCAL_SRC_FILES := src/aenc_svr.c
+LOCAL_SRC_FILES += src/omx_evrc_aenc.cpp
+
+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
+
+# ---------------------------------------------------------------------------------
+# END
+# ---------------------------------------------------------------------------------
+
diff --git a/msm8909/mm-audio/aenc-evrc/qdsp6/Makefile b/msm8909/mm-audio/aenc-evrc/qdsp6/Makefile
new file mode 100644
index 00000000..d0871dea
--- /dev/null
+++ b/msm8909/mm-audio/aenc-evrc/qdsp6/Makefile
@@ -0,0 +1,81 @@
+# ---------------------------------------------------------------------------------
+# MM-AUDIO-OSS-8K-AENC-EVRC
+# ---------------------------------------------------------------------------------
+
+# cross-compiler flags
+CFLAGS += -Wall
+CFLAGS += -Wundef
+CFLAGS += -Wstrict-prototypes
+CFLAGS += -Wno-trigraphs
+
+# cross-compile flags specific to shared objects
+CFLAGS_SO += -fpic
+
+# required pre-processor flags
+CPPFLAGS := -D__packed__=
+CPPFLAGS += -DIMAGE_APPS_PROC
+CPPFLAGS += -DFEATURE_Q_SINGLE_LINK
+CPPFLAGS += -DFEATURE_Q_NO_SELF_QPTR
+CPPFLAGS += -DFEATURE_LINUX
+CPPFLAGS += -DFEATURE_NATIVELINUX
+CPPFLAGS += -DFEATURE_DSM_DUP_ITEMS
+
+CPPFLAGS += -g
+CPPFALGS += -D_DEBUG
+CPPFLAGS += -Iinc
+
+# linker flags
+LDFLAGS += -L$(SYSROOT)/usr/lib
+
+# linker flags for shared objects
+LDFLAGS_SO := -shared
+
+# defintions
+LIBMAJOR := $(basename $(basename $(LIBVER)))
+LIBINSTALLDIR := $(DESTDIR)usr/lib
+INCINSTALLDIR := $(DESTDIR)usr/include
+BININSTALLDIR := $(DESTDIR)usr/bin
+
+# ---------------------------------------------------------------------------------
+# BUILD
+# ---------------------------------------------------------------------------------
+all: libOmxEvrcEnc.so.$(LIBVER) mm-aenc-omxevrc-test
+
+install:
+ echo "intalling aenc-evrc in $(DESTDIR)"
+ if [ ! -d $(LIBINSTALLDIR) ]; then mkdir -p $(LIBINSTALLDIR); fi
+ if [ ! -d $(INCINSTALLDIR) ]; then mkdir -p $(INCINSTALLDIR); fi
+ if [ ! -d $(BININSTALLDIR) ]; then mkdir -p $(BININSTALLDIR); fi
+ 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
+# ---------------------------------------------------------------------------------
+LDLIBS := -lpthread
+LDLIBS += -lstdc++
+LDLIBS += -lOmxCore
+
+SRCS := src/omx_evrc_aenc.cpp
+SRCS += src/aenc_svr.c
+
+libOmxEvrcEnc.so.$(LIBVER): $(SRCS)
+ $(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/msm8909/mm-audio/aenc-evrc/qdsp6/inc/Map.h b/msm8909/mm-audio/aenc-evrc/qdsp6/inc/Map.h
new file mode 100644
index 00000000..aac96fd1
--- /dev/null
+++ b/msm8909/mm-audio/aenc-evrc/qdsp6/inc/Map.h
@@ -0,0 +1,244 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010, 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.
+--------------------------------------------------------------------------*/
+#ifndef _MAP_H_
+#define _MAP_H_
+
+#include <stdio.h>
+using namespace std;
+
+template <typename T,typename T2>
+class Map
+{
+ struct node
+ {
+ T data;
+ T2 data2;
+ node* prev;
+ node* next;
+ node(T t, T2 t2,node* p, node* n) :
+ data(t), data2(t2), prev(p), next(n) {}
+ };
+ node* head;
+ node* tail;
+ node* tmp;
+ unsigned size_of_list;
+ static Map<T,T2> *m_self;
+public:
+ Map() : head( NULL ), tail ( NULL ),tmp(head),size_of_list(0) {}
+ bool empty() const { return ( !head || !tail ); }
+ operator bool() const { return !empty(); }
+ void insert(T,T2);
+ void show();
+ int size();
+ T2 find(T); // Return VALUE
+ T find_ele(T);// Check if the KEY is present or not
+ T2 begin(); //give the first ele
+ bool erase(T);
+ bool eraseall();
+ bool isempty();
+ ~Map()
+ {
+ while(head)
+ {
+ node* temp(head);
+ head=head->next;
+ size_of_list--;
+ delete temp;
+ }
+ }
+};
+
+template <typename T,typename T2>
+T2 Map<T,T2>::find(T d1)
+{
+ tmp = head;
+ while(tmp)
+ {
+ if(tmp->data == d1)
+ {
+ return tmp->data2;
+ }
+ tmp = tmp->next;
+ }
+ return 0;
+}
+
+template <typename T,typename T2>
+T Map<T,T2>::find_ele(T d1)
+{
+ tmp = head;
+ while(tmp)
+ {
+ if(tmp->data == d1)
+ {
+ return tmp->data;
+ }
+ tmp = tmp->next;
+ }
+ return 0;
+}
+
+template <typename T,typename T2>
+T2 Map<T,T2>::begin()
+{
+ tmp = head;
+ if(tmp)
+ {
+ return (tmp->data2);
+ }
+ return 0;
+}
+
+template <typename T,typename T2>
+void Map<T,T2>::show()
+{
+ tmp = head;
+ while(tmp)
+ {
+ printf("%d-->%d\n",tmp->data,tmp->data2);
+ tmp = tmp->next;
+ }
+}
+
+template <typename T,typename T2>
+int Map<T,T2>::size()
+{
+ int count =0;
+ tmp = head;
+ while(tmp)
+ {
+ tmp = tmp->next;
+ count++;
+ }
+ return count;
+}
+
+template <typename T,typename T2>
+void Map<T,T2>::insert(T data, T2 data2)
+{
+ tail = new node(data, data2,tail, NULL);
+ if( tail->prev )
+ tail->prev->next = tail;
+
+ if( empty() )
+ {
+ head = tail;
+ tmp=head;
+ }
+ tmp = head;
+ size_of_list++;
+}
+
+template <typename T,typename T2>
+bool Map<T,T2>::erase(T d)
+{
+ bool found = false;
+ tmp = head;
+ node* prevnode = tmp;
+ node *tempnode;
+
+ while(tmp)
+ {
+ if((head == tail) && (head->data == d))
+ {
+ found = true;
+ tempnode = head;
+ head = tail = NULL;
+ delete tempnode;
+ break;
+ }
+ if((tmp ==head) && (tmp->data ==d))
+ {
+ found = true;
+ tempnode = tmp;
+ tmp = tmp->next;
+ tmp->prev = NULL;
+ head = tmp;
+ tempnode->next = NULL;
+ delete tempnode;
+ break;
+ }
+ if((tmp == tail) && (tmp->data ==d))
+ {
+ found = true;
+ tempnode = tmp;
+ prevnode->next = NULL;
+ tmp->prev = NULL;
+ tail = prevnode;
+ delete tempnode;
+ break;
+ }
+ if(tmp->data == d)
+ {
+ found = true;
+ prevnode->next = tmp->next;
+ tmp->next->prev = prevnode->next;
+ tempnode = tmp;
+ //tmp = tmp->next;
+ delete tempnode;
+ break;
+ }
+ prevnode = tmp;
+ tmp = tmp->next;
+ }
+ if(found)size_of_list--;
+ return found;
+}
+
+template <typename T,typename T2>
+bool Map<T,T2>::eraseall()
+{
+ // Be careful while using this method
+ // it not only removes the node but FREES(not delete) the allocated
+ // memory.
+ node *tempnode;
+ tmp = head;
+ while(head)
+ {
+ tempnode = head;
+ head = head->next;
+ tempnode->next = NULL;
+ if(tempnode->data)
+ free(tempnode->data);
+ if(tempnode->data2)
+ free(tempnode->data2);
+ delete tempnode;
+ }
+ tail = head = NULL;
+ return true;
+}
+
+
+template <typename T,typename T2>
+bool Map<T,T2>::isempty()
+{
+ if(!size_of_list) return true;
+ else return false;
+}
+
+#endif // _MAP_H_
diff --git a/msm8909/mm-audio/aenc-evrc/qdsp6/inc/aenc_svr.h b/msm8909/mm-audio/aenc-evrc/qdsp6/inc/aenc_svr.h
new file mode 100644
index 00000000..46f40ee3
--- /dev/null
+++ b/msm8909/mm-audio/aenc-evrc/qdsp6/inc/aenc_svr.h
@@ -0,0 +1,122 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010, 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.
+--------------------------------------------------------------------------*/
+#ifndef AENC_SVR_H
+#define AENC_SVR_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <pthread.h>
+#include <sched.h>
+#include <utils/Log.h>
+
+#ifdef _ANDROID_
+#define LOG_TAG "QC_EVRCENC"
+#endif
+
+#ifndef LOGE
+#define LOGE ALOGE
+#endif
+
+#ifndef LOGW
+#define LOGW ALOGW
+#endif
+
+#ifndef LOGD
+#define LOGD ALOGD
+#endif
+
+#ifndef LOGV
+#define LOGV ALOGV
+#endif
+
+#ifndef LOGI
+#define LOGI ALOGI
+#endif
+
+#define DEBUG_PRINT_ERROR LOGE
+#define DEBUG_PRINT LOGI
+#define DEBUG_DETAIL LOGV
+
+typedef void (*message_func)(void* client_data, unsigned char id);
+
+/**
+ @brief audio encoder ipc info structure
+
+ */
+struct evrc_ipc_info
+{
+ pthread_t thr;
+ int pipe_in;
+ int pipe_out;
+ int dead;
+ message_func process_msg_cb;
+ void *client_data;
+ char thread_name[128];
+};
+
+/**
+ @brief This function starts command server
+
+ @param cb pointer to callback function from the client
+ @param client_data reference client wants to get back
+ through callback
+ @return handle to command server
+ */
+struct evrc_ipc_info *omx_evrc_thread_create(message_func cb,
+ void* client_data,
+ char *th_name);
+
+struct evrc_ipc_info *omx_evrc_event_thread_create(message_func cb,
+ void* client_data,
+ char *th_name);
+/**
+ @brief This function stop command server
+
+ @param svr handle to command server
+ @return none
+ */
+void omx_evrc_thread_stop(struct evrc_ipc_info *evrc_ipc);
+
+
+/**
+ @brief This function post message in the command server
+
+ @param svr handle to command server
+ @return none
+ */
+void omx_evrc_post_msg(struct evrc_ipc_info *evrc_ipc,
+ unsigned char id);
+
+void* omx_evrc_comp_timer_handler(void *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* AENC_SVR */
diff --git a/msm8909/mm-audio/aenc-evrc/qdsp6/inc/omx_evrc_aenc.h b/msm8909/mm-audio/aenc-evrc/qdsp6/inc/omx_evrc_aenc.h
new file mode 100644
index 00000000..09ffb2d7
--- /dev/null
+++ b/msm8909/mm-audio/aenc-evrc/qdsp6/inc/omx_evrc_aenc.h
@@ -0,0 +1,539 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010,2014 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.
+--------------------------------------------------------------------------*/
+#ifndef _EVRC_ENC_H_
+#define _EVRC_ENC_H_
+/*============================================================================
+ Audio Encoder
+
+@file omx_evrc_aenc.h
+This module contains the class definition for openMAX encoder component.
+
+
+
+============================================================================*/
+
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+
+/* Uncomment out below line #define LOG_NDEBUG 0 if we want to see
+ * all DEBUG_PRINT or LOGV messaging */
+#include<stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <time.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include "QOMX_AudioExtensions.h"
+#include "QOMX_AudioIndexExtensions.h"
+#include "OMX_Core.h"
+#include "OMX_Audio.h"
+#include "aenc_svr.h"
+#include "qc_omx_component.h"
+#include "Map.h"
+#include <semaphore.h>
+#include <linux/msm_audio.h>
+#include <linux/msm_audio_qcp.h>
+extern "C" {
+ void * get_omx_component_factory_fn(void);
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+// Module specific globals
+//////////////////////////////////////////////////////////////////////////////
+
+
+
+#define OMX_SPEC_VERSION 0x00000101
+#define MIN(x,y) (((x) < (y)) ? (x) : (y))
+#define MAX(x,y) (x >= y?x:y)
+
+//////////////////////////////////////////////////////////////////////////////
+// Macros
+//////////////////////////////////////////////////////////////////////////////
+//
+
+
+#define PrintFrameHdr(i,bufHdr) \
+ DEBUG_PRINT("i=%d OMX bufHdr[%p]buf[%p]size[%d]TS[%lld]nFlags[0x%x]\n",\
+ i,\
+ bufHdr, \
+ ((OMX_BUFFERHEADERTYPE *)bufHdr)->pBuffer, \
+ (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nFilledLen,\
+ ((OMX_BUFFERHEADERTYPE *)bufHdr)->nTimeStamp, \
+ (unsigned)((OMX_BUFFERHEADERTYPE *)bufHdr)->nFlags)
+
+
+// BitMask Management logic
+#define BITS_PER_BYTE 8
+#define BITMASK_SIZE(mIndex) \
+ (((mIndex) + BITS_PER_BYTE - 1)/BITS_PER_BYTE)
+#define BITMASK_OFFSET(mIndex)\
+ ((mIndex)/BITS_PER_BYTE)
+#define BITMASK_FLAG(mIndex) \
+ (1 << ((mIndex) % BITS_PER_BYTE))
+#define BITMASK_CLEAR(mArray,mIndex)\
+ (mArray)[BITMASK_OFFSET(mIndex)] &= ~(BITMASK_FLAG(mIndex))
+#define BITMASK_SET(mArray,mIndex)\
+ (mArray)[BITMASK_OFFSET(mIndex)] |= BITMASK_FLAG(mIndex)
+#define BITMASK_PRESENT(mArray,mIndex)\
+ ((mArray)[BITMASK_OFFSET(mIndex)] & BITMASK_FLAG(mIndex))
+#define BITMASK_ABSENT(mArray,mIndex)\
+ (((mArray)[BITMASK_OFFSET(mIndex)] & \
+ BITMASK_FLAG(mIndex)) == 0x0)
+
+#define OMX_CORE_NUM_INPUT_BUFFERS 2
+#define OMX_CORE_NUM_OUTPUT_BUFFERS 16
+
+#define OMX_CORE_INPUT_BUFFER_SIZE 8160 // Multiple of 160
+#define OMX_CORE_CONTROL_CMDQ_SIZE 100
+#define OMX_AENC_VOLUME_STEP 0x147
+#define OMX_AENC_MIN 0
+#define OMX_AENC_MAX 100
+#define NON_TUNNEL 1
+#define TUNNEL 0
+#define IP_PORT_BITMASK 0x02
+#define OP_PORT_BITMASK 0x01
+#define IP_OP_PORT_BITMASK 0x03
+
+#define OMX_EVRC_DEFAULT_SF 8000
+#define OMX_EVRC_DEFAULT_CH_CFG 1
+#define OMX_EVRC_DEFAULT_VOL 25
+// 14 bytes for input meta data
+#define OMX_AENC_SIZEOF_META_BUF (OMX_CORE_INPUT_BUFFER_SIZE+14)
+
+#define TRUE 1
+#define FALSE 0
+
+#define NUMOFFRAMES 1
+#define MAXFRAMELENGTH 25
+#define OMX_EVRC_OUTPUT_BUFFER_SIZE ((NUMOFFRAMES * (sizeof(ENC_META_OUT) + MAXFRAMELENGTH) \
+ + 1))
+
+#define OMX_EVRC_DEFAULT_MINRATE 4
+#define OMX_EVRC_DEFAULT_MAXRATE 4
+
+class omx_evrc_aenc;
+
+// OMX EVRC audio encoder class
+class omx_evrc_aenc: public qc_omx_component
+{
+public:
+ omx_evrc_aenc(); // constructor
+ virtual ~omx_evrc_aenc(); // destructor
+
+ OMX_ERRORTYPE allocate_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,
+ OMX_PTR appData,
+ OMX_U32 bytes);
+
+
+ OMX_ERRORTYPE component_deinit(OMX_HANDLETYPE hComp);
+
+ OMX_ERRORTYPE component_init(OMX_STRING role);
+
+ OMX_ERRORTYPE component_role_enum(OMX_HANDLETYPE hComp,
+ OMX_U8 *role,
+ OMX_U32 index);
+
+ OMX_ERRORTYPE component_tunnel_request(OMX_HANDLETYPE hComp,
+ OMX_U32 port,
+ OMX_HANDLETYPE peerComponent,
+ OMX_U32 peerPort,
+ OMX_TUNNELSETUPTYPE *tunnelSetup);
+
+ OMX_ERRORTYPE empty_this_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+
+ OMX_ERRORTYPE empty_this_buffer_proxy(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+
+ OMX_ERRORTYPE fill_this_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+
+ OMX_ERRORTYPE free_buffer(OMX_HANDLETYPE hComp,
+ OMX_U32 port,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ OMX_ERRORTYPE get_component_version(OMX_HANDLETYPE hComp,
+ OMX_STRING componentName,
+ OMX_VERSIONTYPE *componentVersion,
+ OMX_VERSIONTYPE * specVersion,
+ OMX_UUIDTYPE *componentUUID);
+
+ OMX_ERRORTYPE get_config(OMX_HANDLETYPE hComp,
+ OMX_INDEXTYPE configIndex,
+ OMX_PTR configData);
+
+ OMX_ERRORTYPE get_extension_index(OMX_HANDLETYPE hComp,
+ OMX_STRING paramName,
+ OMX_INDEXTYPE *indexType);
+
+ OMX_ERRORTYPE get_parameter(OMX_HANDLETYPE hComp,
+ OMX_INDEXTYPE paramIndex,
+ OMX_PTR paramData);
+
+ OMX_ERRORTYPE get_state(OMX_HANDLETYPE hComp,
+ OMX_STATETYPE *state);
+
+ static void process_in_port_msg(void *client_data,
+ unsigned char id);
+
+ static void process_out_port_msg(void *client_data,
+ unsigned char id);
+
+ static void process_command_msg(void *client_data,
+ unsigned char id);
+
+ static void process_event_cb(void *client_data,
+ unsigned char id);
+
+
+ OMX_ERRORTYPE set_callbacks(OMX_HANDLETYPE hComp,
+ OMX_CALLBACKTYPE *callbacks,
+ OMX_PTR appData);
+
+ OMX_ERRORTYPE set_config(OMX_HANDLETYPE hComp,
+ OMX_INDEXTYPE configIndex,
+ OMX_PTR configData);
+
+ OMX_ERRORTYPE set_parameter(OMX_HANDLETYPE hComp,
+ OMX_INDEXTYPE paramIndex,
+ OMX_PTR paramData);
+
+ OMX_ERRORTYPE use_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,
+ OMX_PTR appData,
+ OMX_U32 bytes,
+ OMX_U8 *buffer);
+
+ OMX_ERRORTYPE use_EGL_image(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,
+ OMX_PTR appData,
+ void * eglImage);
+
+ bool post_command(unsigned int p1, unsigned int p2,
+ unsigned char id);
+
+ // Deferred callback identifiers
+ enum
+ {
+ //Event Callbacks from the component thread context
+ OMX_COMPONENT_GENERATE_EVENT = 0x1,
+ //Buffer Done callbacks from component thread context
+ OMX_COMPONENT_GENERATE_BUFFER_DONE = 0x2,
+ OMX_COMPONENT_GENERATE_ETB = 0x3,
+ //Command
+ OMX_COMPONENT_GENERATE_COMMAND = 0x4,
+ OMX_COMPONENT_GENERATE_FRAME_DONE = 0x05,
+ OMX_COMPONENT_GENERATE_FTB = 0x06,
+ OMX_COMPONENT_GENERATE_EOS = 0x07,
+ OMX_COMPONENT_PORTSETTINGS_CHANGED = 0x08,
+ OMX_COMPONENT_SUSPEND = 0x09,
+ OMX_COMPONENT_RESUME = 0x0a
+ };
+private:
+
+ ///////////////////////////////////////////////////////////
+ // Type definitions
+ ///////////////////////////////////////////////////////////
+ // Bit Positions
+ enum flags_bit_positions
+ {
+ // Defer transition to IDLE
+ OMX_COMPONENT_IDLE_PENDING =0x1,
+ // Defer transition to LOADING
+ OMX_COMPONENT_LOADING_PENDING =0x2,
+
+ OMX_COMPONENT_MUTED =0x3,
+
+ // Defer transition to Enable
+ OMX_COMPONENT_INPUT_ENABLE_PENDING =0x4,
+ // Defer transition to Enable
+ OMX_COMPONENT_OUTPUT_ENABLE_PENDING =0x5,
+ // Defer transition to Disable
+ OMX_COMPONENT_INPUT_DISABLE_PENDING =0x6,
+ // Defer transition to Disable
+ OMX_COMPONENT_OUTPUT_DISABLE_PENDING =0x7
+ };
+
+
+ typedef Map<OMX_BUFFERHEADERTYPE*, OMX_BUFFERHEADERTYPE*>
+ input_buffer_map;
+
+ typedef Map<OMX_BUFFERHEADERTYPE*, OMX_BUFFERHEADERTYPE*>
+ output_buffer_map;
+
+ enum port_indexes
+ {
+ OMX_CORE_INPUT_PORT_INDEX =0,
+ OMX_CORE_OUTPUT_PORT_INDEX =1
+ };
+
+ struct omx_event
+ {
+ unsigned long param1;
+ unsigned long param2;
+ unsigned char id;
+ };
+
+ struct omx_cmd_queue
+ {
+ omx_event m_q[OMX_CORE_CONTROL_CMDQ_SIZE];
+ unsigned m_read;
+ unsigned m_write;
+ unsigned m_size;
+
+ omx_cmd_queue();
+ ~omx_cmd_queue();
+ bool insert_entry(unsigned long p1, unsigned long p2, unsigned char id);
+ bool pop_entry(unsigned long *p1,unsigned long *p2, unsigned char *id);
+ bool get_msg_id(unsigned char *id);
+ bool get_msg_with_id(unsigned *p1,unsigned *p2, unsigned char id);
+ };
+
+ typedef struct TIMESTAMP
+ {
+ unsigned int LowPart;
+ unsigned int HighPart;
+ }__attribute__((packed)) TIMESTAMP;
+
+ typedef struct metadata_input
+ {
+ unsigned short offsetVal;
+ TIMESTAMP nTimeStamp;
+ unsigned int nFlags;
+ }__attribute__((packed)) META_IN;
+
+ typedef 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))ENC_META_OUT;
+
+ typedef struct
+ {
+ OMX_U32 tot_in_buf_len;
+ OMX_U32 tot_out_buf_len;
+ OMX_TICKS tot_pb_time;
+ OMX_U32 fbd_cnt;
+ OMX_U32 ftb_cnt;
+ OMX_U32 etb_cnt;
+ OMX_U32 ebd_cnt;
+ }EVRC_PB_STATS;
+
+ ///////////////////////////////////////////////////////////
+ // Member variables
+ ///////////////////////////////////////////////////////////
+ OMX_U8 *m_tmp_meta_buf;
+ OMX_U8 *m_tmp_out_meta_buf;
+ OMX_U8 m_flush_cnt ;
+ OMX_U8 m_comp_deinit;
+
+ // the below var doesnt hold good if combo of use and alloc bufs are used
+ OMX_S32 m_volume;//Unit to be determined
+ OMX_PTR m_app_data;// Application data
+ int nNumInputBuf;
+ int nNumOutputBuf;
+ int m_drv_fd; // Kernel device node file handle
+ bool bFlushinprogress;
+ bool is_in_th_sleep;
+ bool is_out_th_sleep;
+ unsigned int m_flags; //encapsulate the waiting states.
+ OMX_TICKS nTimestamp;
+ unsigned int pcm_input; //tunnel or non-tunnel
+ unsigned int m_inp_act_buf_count; // Num of Input Buffers
+ unsigned int m_out_act_buf_count; // Numb of Output Buffers
+ unsigned int m_inp_current_buf_count; // Num of Input Buffers
+ unsigned int m_out_current_buf_count; // Numb of Output Buffers
+ unsigned int output_buffer_size;
+ unsigned int input_buffer_size;
+ unsigned short m_session_id;
+ // store I/P PORT state
+ OMX_BOOL m_inp_bEnabled;
+ // store O/P PORT state
+ OMX_BOOL m_out_bEnabled;
+ //Input port Populated
+ OMX_BOOL m_inp_bPopulated;
+ //Output port Populated
+ OMX_BOOL m_out_bPopulated;
+ sem_t sem_States;
+ sem_t sem_read_msg;
+ sem_t sem_write_msg;
+
+ volatile int m_is_event_done;
+ volatile int m_is_in_th_sleep;
+ volatile int m_is_out_th_sleep;
+ input_buffer_map m_input_buf_hdrs;
+ output_buffer_map m_output_buf_hdrs;
+ omx_cmd_queue m_input_q;
+ omx_cmd_queue m_input_ctrl_cmd_q;
+ omx_cmd_queue m_input_ctrl_ebd_q;
+ omx_cmd_queue m_command_q;
+ omx_cmd_queue m_output_q;
+ omx_cmd_queue m_output_ctrl_cmd_q;
+ omx_cmd_queue m_output_ctrl_fbd_q;
+ pthread_mutexattr_t m_outputlock_attr;
+ pthread_mutexattr_t m_commandlock_attr;
+ pthread_mutexattr_t m_lock_attr;
+ pthread_mutexattr_t m_state_attr;
+ pthread_mutexattr_t m_flush_attr;
+ pthread_mutexattr_t m_in_th_attr_1;
+ pthread_mutexattr_t m_out_th_attr_1;
+ pthread_mutexattr_t m_event_attr;
+ pthread_mutexattr_t m_in_th_attr;
+ pthread_mutexattr_t m_out_th_attr;
+ pthread_mutexattr_t out_buf_count_lock_attr;
+ pthread_mutexattr_t in_buf_count_lock_attr;
+ pthread_cond_t cond;
+ pthread_cond_t in_cond;
+ pthread_cond_t out_cond;
+ pthread_mutex_t m_lock;
+ pthread_mutex_t m_commandlock;
+ pthread_mutex_t m_outputlock;
+ // Mutexes for state change
+ pthread_mutex_t m_state_lock;
+ // Mutexes for flush acks from input and output threads
+ pthread_mutex_t m_flush_lock;
+ pthread_mutex_t m_event_lock;
+ pthread_mutex_t m_in_th_lock;
+ pthread_mutex_t m_out_th_lock;
+ pthread_mutex_t m_in_th_lock_1;
+ pthread_mutex_t m_out_th_lock_1;
+ pthread_mutex_t out_buf_count_lock;
+ pthread_mutex_t in_buf_count_lock;
+
+ OMX_STATETYPE m_state; // OMX State
+ OMX_STATETYPE nState;
+ OMX_CALLBACKTYPE m_cb; // Application callbacks
+ EVRC_PB_STATS m_evrc_pb_stats;
+ struct evrc_ipc_info *m_ipc_to_in_th; // for input thread
+ struct evrc_ipc_info *m_ipc_to_out_th; // for output thread
+ struct evrc_ipc_info *m_ipc_to_cmd_th; // for command thread
+ struct evrc_ipc_info *m_ipc_to_event_th; //for txco event thread
+ OMX_PRIORITYMGMTTYPE m_priority_mgm ;
+ OMX_AUDIO_PARAM_EVRCTYPE m_evrc_param; // Cache EVRC encoder parameter
+ OMX_AUDIO_PARAM_PCMMODETYPE m_pcm_param; // Cache pcm parameter
+ OMX_PARAM_COMPONENTROLETYPE component_Role;
+ OMX_PARAM_BUFFERSUPPLIERTYPE m_buffer_supplier;
+
+ ///////////////////////////////////////////////////////////
+ // Private methods
+ ///////////////////////////////////////////////////////////
+ OMX_ERRORTYPE allocate_output_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,OMX_PTR appData,
+ OMX_U32 bytes);
+
+ OMX_ERRORTYPE allocate_input_buffer(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE **bufferHdr,
+ OMX_U32 port,
+ OMX_PTR appData,
+ OMX_U32 bytes);
+
+ OMX_ERRORTYPE use_input_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE **bufHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes,
+ OMX_IN OMX_U8* buffer);
+
+ OMX_ERRORTYPE use_output_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE **bufHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes,
+ OMX_IN OMX_U8* buffer);
+
+ OMX_ERRORTYPE fill_this_buffer_proxy(OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE *buffer);
+
+ OMX_ERRORTYPE send_command_proxy(OMX_HANDLETYPE hComp,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param1,
+ OMX_PTR cmdData);
+
+ OMX_ERRORTYPE send_command(OMX_HANDLETYPE hComp,
+ OMX_COMMANDTYPE cmd,
+ OMX_U32 param1,
+ OMX_PTR cmdData);
+
+ bool allocate_done(void);
+
+ bool release_done(OMX_U32 param1);
+
+ bool execute_omx_flush(OMX_IN OMX_U32 param1, bool cmd_cmpl=true);
+
+ bool execute_input_omx_flush(void);
+
+ bool execute_output_omx_flush(void);
+
+ bool search_input_bufhdr(OMX_BUFFERHEADERTYPE *buffer);
+
+ bool search_output_bufhdr(OMX_BUFFERHEADERTYPE *buffer);
+
+ bool post_input(unsigned long p1, unsigned long p2,
+ unsigned char id);
+
+ bool post_output(unsigned long p1, unsigned long p2,
+ unsigned char id);
+
+ void process_events(omx_evrc_aenc *client_data);
+
+ void buffer_done_cb(OMX_BUFFERHEADERTYPE *bufHdr);
+
+ void frame_done_cb(OMX_BUFFERHEADERTYPE *bufHdr);
+
+ void wait_for_event();
+
+ void event_complete();
+
+ void in_th_goto_sleep();
+
+ void in_th_wakeup();
+
+ void out_th_goto_sleep();
+
+ void out_th_wakeup();
+
+ void flush_ack();
+ void deinit_encoder();
+
+};
+#endif
diff --git a/msm8909/mm-audio/aenc-evrc/qdsp6/src/aenc_svr.c b/msm8909/mm-audio/aenc-evrc/qdsp6/src/aenc_svr.c
new file mode 100644
index 00000000..4f828fcf
--- /dev/null
+++ b/msm8909/mm-audio/aenc-evrc/qdsp6/src/aenc_svr.c
@@ -0,0 +1,205 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010, 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.
+--------------------------------------------------------------------------*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <fcntl.h>
+#include <errno.h>
+
+#include <aenc_svr.h>
+
+/**
+ @brief This function processes posted messages
+
+ Once thread is being spawned, this function is run to
+ start processing commands posted by client
+
+ @param info pointer to context
+
+ */
+void *omx_evrc_msg(void *info)
+{
+ struct evrc_ipc_info *evrc_info = (struct evrc_ipc_info*)info;
+ unsigned char id;
+ ssize_t n;
+
+ DEBUG_DETAIL("\n%s: message thread start\n", __FUNCTION__);
+ while (!evrc_info->dead)
+ {
+ n = read(evrc_info->pipe_in, &id, 1);
+ if (0 == n) break;
+ if (1 == n)
+ {
+ DEBUG_DETAIL("\n%s-->pipe_in=%d pipe_out=%d\n",
+ evrc_info->thread_name,
+ evrc_info->pipe_in,
+ evrc_info->pipe_out);
+
+ evrc_info->process_msg_cb(evrc_info->client_data, id);
+ }
+ if ((n < 0) && (errno != EINTR)) break;
+ }
+ DEBUG_DETAIL("%s: message thread stop\n", __FUNCTION__);
+
+ return 0;
+}
+
+void *omx_evrc_events(void *info)
+{
+ struct evrc_ipc_info *evrc_info = (struct evrc_ipc_info*)info;
+ unsigned char id = 0;
+
+ DEBUG_DETAIL("%s: message thread start\n", evrc_info->thread_name);
+ evrc_info->process_msg_cb(evrc_info->client_data, id);
+ DEBUG_DETAIL("%s: message thread stop\n", evrc_info->thread_name);
+ return 0;
+}
+
+/**
+ @brief This function starts command server
+
+ @param cb pointer to callback function from the client
+ @param client_data reference client wants to get back
+ through callback
+ @return handle to msging thread
+ */
+struct evrc_ipc_info *omx_evrc_thread_create(
+ message_func cb,
+ void* client_data,
+ char* th_name)
+{
+ int r;
+ int fds[2];
+ struct evrc_ipc_info *evrc_info;
+
+ evrc_info = calloc(1, sizeof(struct evrc_ipc_info));
+ if (!evrc_info)
+ {
+ return 0;
+ }
+
+ evrc_info->client_data = client_data;
+ evrc_info->process_msg_cb = cb;
+ strlcpy(evrc_info->thread_name, th_name, sizeof(evrc_info->thread_name));
+
+ if (pipe(fds))
+ {
+ DEBUG_PRINT_ERROR("\n%s: pipe creation failed\n", __FUNCTION__);
+ goto fail_pipe;
+ }
+
+ evrc_info->pipe_in = fds[0];
+ evrc_info->pipe_out = fds[1];
+
+ r = pthread_create(&evrc_info->thr, 0, omx_evrc_msg, evrc_info);
+ if (r < 0) goto fail_thread;
+
+ DEBUG_DETAIL("Created thread for %s \n", evrc_info->thread_name);
+ return evrc_info;
+
+
+fail_thread:
+ close(evrc_info->pipe_in);
+ close(evrc_info->pipe_out);
+
+fail_pipe:
+ free(evrc_info);
+
+ return 0;
+}
+
+/**
+ * @brief This function starts command server
+ *
+ * @param cb pointer to callback function from the client
+ * @param client_data reference client wants to get back
+ * through callback
+ * @return handle to msging thread
+ * */
+struct evrc_ipc_info *omx_evrc_event_thread_create(
+ message_func cb,
+ void* client_data,
+ char* th_name)
+{
+ int r;
+ int fds[2];
+ struct evrc_ipc_info *evrc_info;
+
+ evrc_info = calloc(1, sizeof(struct evrc_ipc_info));
+ if (!evrc_info)
+ {
+ return 0;
+ }
+
+ evrc_info->client_data = client_data;
+ evrc_info->process_msg_cb = cb;
+ strlcpy(evrc_info->thread_name, th_name, sizeof(evrc_info->thread_name));
+
+ if (pipe(fds))
+ {
+ DEBUG_PRINT("\n%s: pipe creation failed\n", __FUNCTION__);
+ goto fail_pipe;
+ }
+
+ evrc_info->pipe_in = fds[0];
+ evrc_info->pipe_out = fds[1];
+
+ r = pthread_create(&evrc_info->thr, 0, omx_evrc_events, evrc_info);
+ if (r < 0) goto fail_thread;
+
+ DEBUG_DETAIL("Created thread for %s \n", evrc_info->thread_name);
+ return evrc_info;
+
+
+fail_thread:
+ close(evrc_info->pipe_in);
+ close(evrc_info->pipe_out);
+
+fail_pipe:
+ free(evrc_info);
+
+ return 0;
+}
+
+void omx_evrc_thread_stop(struct evrc_ipc_info *evrc_info) {
+ DEBUG_DETAIL("%s stop server\n", __FUNCTION__);
+ close(evrc_info->pipe_in);
+ close(evrc_info->pipe_out);
+ pthread_join(evrc_info->thr,NULL);
+ evrc_info->pipe_out = -1;
+ evrc_info->pipe_in = -1;
+ DEBUG_DETAIL("%s: message thread close fds%d %d\n", evrc_info->thread_name,
+ evrc_info->pipe_in,evrc_info->pipe_out);
+ free(evrc_info);
+}
+
+void omx_evrc_post_msg(struct evrc_ipc_info *evrc_info, unsigned char id) {
+ DEBUG_DETAIL("\n%s id=%d\n", __FUNCTION__,id);
+ write(evrc_info->pipe_out, &id, 1);
+}
diff --git a/msm8909/mm-audio/aenc-evrc/qdsp6/src/omx_evrc_aenc.cpp b/msm8909/mm-audio/aenc-evrc/qdsp6/src/omx_evrc_aenc.cpp
new file mode 100644
index 00000000..8200365f
--- /dev/null
+++ b/msm8909/mm-audio/aenc-evrc/qdsp6/src/omx_evrc_aenc.cpp
@@ -0,0 +1,4531 @@
+/*--------------------------------------------------------------------------
+Copyright (c) 2010, 2014 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.
+--------------------------------------------------------------------------*/
+/*============================================================================
+@file omx_aenc_evrc.c
+ This module contains the implementation of the OpenMAX core & component.
+
+*//*========================================================================*/
+//////////////////////////////////////////////////////////////////////////////
+// Include Files
+//////////////////////////////////////////////////////////////////////////////
+
+
+#include<string.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "omx_evrc_aenc.h"
+#include <errno.h>
+
+using namespace std;
+#define SLEEP_MS 100
+
+// omx_cmd_queue destructor
+omx_evrc_aenc::omx_cmd_queue::~omx_cmd_queue()
+{
+ // Nothing to do
+}
+
+// omx cmd queue constructor
+omx_evrc_aenc::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
+{
+ memset(m_q, 0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
+}
+
+// omx cmd queue insert
+bool omx_evrc_aenc::omx_cmd_queue::insert_entry(unsigned long p1,
+ unsigned long p2,
+ unsigned char id)
+{
+ bool ret = true;
+ if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
+ {
+ m_q[m_write].id = id;
+ m_q[m_write].param1 = p1;
+ m_q[m_write].param2 = p2;
+ m_write++;
+ m_size ++;
+ if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
+ {
+ m_write = 0;
+ }
+ } else
+ {
+ ret = false;
+ DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full");
+ }
+ return ret;
+}
+
+bool omx_evrc_aenc::omx_cmd_queue::pop_entry(unsigned long *p1,
+ unsigned long *p2, unsigned char *id)
+{
+ bool ret = true;
+ if (m_size > 0)
+ {
+ *id = m_q[m_read].id;
+ *p1 = m_q[m_read].param1;
+ *p2 = m_q[m_read].param2;
+ // Move the read pointer ahead
+ ++m_read;
+ --m_size;
+ if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
+ {
+ m_read = 0;
+
+ }
+ } else
+ {
+ ret = false;
+ DEBUG_PRINT_ERROR("ERROR Delete!!! Command Queue Empty");
+ }
+ return ret;
+}
+
+// factory function executed by the core to create instances
+void *get_omx_component_factory_fn(void)
+{
+ return(new omx_evrc_aenc);
+}
+bool omx_evrc_aenc::omx_cmd_queue::get_msg_id(unsigned char *id)
+{
+ if(m_size > 0)
+ {
+ *id = m_q[m_read].id;
+ DEBUG_PRINT("get_msg_id=%d\n",*id);
+ }
+ else{
+ return false;
+ }
+ return true;
+}
+/*=============================================================================
+FUNCTION:
+ wait_for_event
+
+DESCRIPTION:
+ waits for a particular event
+
+INPUT/OUTPUT PARAMETERS:
+ None
+
+RETURN VALUE:
+ None
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+void omx_evrc_aenc::wait_for_event()
+{
+ int rc;
+ struct timespec ts;
+ pthread_mutex_lock(&m_event_lock);
+ while (0 == m_is_event_done)
+ {
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_sec += (SLEEP_MS/1000);
+ ts.tv_nsec += ((SLEEP_MS%1000) * 1000000);
+ rc = pthread_cond_timedwait(&cond, &m_event_lock, &ts);
+ if (rc == ETIMEDOUT && !m_is_event_done) {
+ DEBUG_PRINT("Timed out waiting for flush");
+ if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) == -1)
+ DEBUG_PRINT_ERROR("Flush:Input port, ioctl flush failed %d\n",
+ errno);
+ }
+ }
+ m_is_event_done = 0;
+ pthread_mutex_unlock(&m_event_lock);
+}
+
+/*=============================================================================
+FUNCTION:
+ event_complete
+
+DESCRIPTION:
+ informs about the occurance of an event
+
+INPUT/OUTPUT PARAMETERS:
+ None
+
+RETURN VALUE:
+ None
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+void omx_evrc_aenc::event_complete()
+{
+ pthread_mutex_lock(&m_event_lock);
+ if (0 == m_is_event_done)
+ {
+ m_is_event_done = 1;
+ pthread_cond_signal(&cond);
+ }
+ pthread_mutex_unlock(&m_event_lock);
+}
+
+// All this non-sense because of a single evrc object
+void omx_evrc_aenc::in_th_goto_sleep()
+{
+ pthread_mutex_lock(&m_in_th_lock);
+ while (0 == m_is_in_th_sleep)
+ {
+ pthread_cond_wait(&in_cond, &m_in_th_lock);
+ }
+ m_is_in_th_sleep = 0;
+ pthread_mutex_unlock(&m_in_th_lock);
+}
+
+void omx_evrc_aenc::in_th_wakeup()
+{
+ pthread_mutex_lock(&m_in_th_lock);
+ if (0 == m_is_in_th_sleep)
+ {
+ m_is_in_th_sleep = 1;
+ pthread_cond_signal(&in_cond);
+ }
+ pthread_mutex_unlock(&m_in_th_lock);
+}
+
+void omx_evrc_aenc::out_th_goto_sleep()
+{
+
+ pthread_mutex_lock(&m_out_th_lock);
+ while (0 == m_is_out_th_sleep)
+ {
+ pthread_cond_wait(&out_cond, &m_out_th_lock);
+ }
+ m_is_out_th_sleep = 0;
+ pthread_mutex_unlock(&m_out_th_lock);
+}
+
+void omx_evrc_aenc::out_th_wakeup()
+{
+ pthread_mutex_lock(&m_out_th_lock);
+ if (0 == m_is_out_th_sleep)
+ {
+ m_is_out_th_sleep = 1;
+ pthread_cond_signal(&out_cond);
+ }
+ pthread_mutex_unlock(&m_out_th_lock);
+}
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::omx_evrc_aenc
+
+DESCRIPTION
+ Constructor
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+omx_evrc_aenc::omx_evrc_aenc(): m_tmp_meta_buf(NULL),
+ m_tmp_out_meta_buf(NULL),
+ m_flush_cnt(255),
+ m_comp_deinit(0),
+ m_volume(25),
+ m_app_data(NULL),
+ nNumInputBuf(0),
+ nNumOutputBuf(0),
+ m_drv_fd(-1),
+ bFlushinprogress(0),
+ is_in_th_sleep(false),
+ is_out_th_sleep(false),
+ m_flags(0),
+ nTimestamp(0),
+ m_inp_act_buf_count (OMX_CORE_NUM_INPUT_BUFFERS),
+ m_out_act_buf_count (OMX_CORE_NUM_OUTPUT_BUFFERS),
+ m_inp_current_buf_count(0),
+ m_out_current_buf_count(0),
+ output_buffer_size((OMX_U32)OMX_EVRC_OUTPUT_BUFFER_SIZE),
+ input_buffer_size(OMX_CORE_INPUT_BUFFER_SIZE),
+ m_inp_bEnabled(OMX_TRUE),
+ m_out_bEnabled(OMX_TRUE),
+ m_inp_bPopulated(OMX_FALSE),
+ m_out_bPopulated(OMX_FALSE),
+ m_is_event_done(0),
+ m_state(OMX_StateInvalid),
+ m_ipc_to_in_th(NULL),
+ m_ipc_to_out_th(NULL),
+ m_ipc_to_cmd_th(NULL)
+{
+ int cond_ret = 0;
+ memset(&m_cmp, 0, sizeof(m_cmp));
+ memset(&m_cb, 0, sizeof(m_cb));
+ memset(&m_evrc_param, 0, sizeof(m_evrc_param));
+ memset(&m_buffer_supplier, 0, sizeof(m_buffer_supplier));
+ memset(&m_evrc_pb_stats, 0, sizeof(m_evrc_pb_stats));
+ memset(&m_pcm_param, 0, sizeof(m_pcm_param));
+ memset(&m_priority_mgm, 0, sizeof(m_priority_mgm));
+
+ pthread_mutexattr_init(&m_lock_attr);
+ pthread_mutex_init(&m_lock, &m_lock_attr);
+ pthread_mutexattr_init(&m_commandlock_attr);
+ pthread_mutex_init(&m_commandlock, &m_commandlock_attr);
+
+ pthread_mutexattr_init(&m_outputlock_attr);
+ pthread_mutex_init(&m_outputlock, &m_outputlock_attr);
+
+ pthread_mutexattr_init(&m_state_attr);
+ pthread_mutex_init(&m_state_lock, &m_state_attr);
+
+ pthread_mutexattr_init(&m_event_attr);
+ pthread_mutex_init(&m_event_lock, &m_event_attr);
+
+ pthread_mutexattr_init(&m_flush_attr);
+ pthread_mutex_init(&m_flush_lock, &m_flush_attr);
+
+ pthread_mutexattr_init(&m_event_attr);
+ pthread_mutex_init(&m_event_lock, &m_event_attr);
+
+ pthread_mutexattr_init(&m_in_th_attr);
+ pthread_mutex_init(&m_in_th_lock, &m_in_th_attr);
+
+ pthread_mutexattr_init(&m_out_th_attr);
+ pthread_mutex_init(&m_out_th_lock, &m_out_th_attr);
+
+ pthread_mutexattr_init(&m_in_th_attr_1);
+ pthread_mutex_init(&m_in_th_lock_1, &m_in_th_attr_1);
+
+ pthread_mutexattr_init(&m_out_th_attr_1);
+ pthread_mutex_init(&m_out_th_lock_1, &m_out_th_attr_1);
+
+ pthread_mutexattr_init(&out_buf_count_lock_attr);
+ pthread_mutex_init(&out_buf_count_lock, &out_buf_count_lock_attr);
+
+ pthread_mutexattr_init(&in_buf_count_lock_attr);
+ pthread_mutex_init(&in_buf_count_lock, &in_buf_count_lock_attr);
+ if ((cond_ret = pthread_cond_init (&cond, NULL)) != 0)
+ {
+ DEBUG_PRINT_ERROR("pthread_cond_init returns non zero for cond\n");
+ if (cond_ret == EAGAIN)
+ DEBUG_PRINT_ERROR("The system lacked necessary \
+ resources(other than mem)\n");
+ else if (cond_ret == ENOMEM)
+ DEBUG_PRINT_ERROR("Insufficient memory to initialise \
+ condition variable\n");
+ }
+ if ((cond_ret = pthread_cond_init (&in_cond, NULL)) != 0)
+ {
+ DEBUG_PRINT_ERROR("pthread_cond_init returns non zero for in_cond\n");
+ if (cond_ret == EAGAIN)
+ DEBUG_PRINT_ERROR("The system lacked necessary \
+ resources(other than mem)\n");
+ else if (cond_ret == ENOMEM)
+ DEBUG_PRINT_ERROR("Insufficient memory to initialise \
+ condition variable\n");
+ }
+ if ((cond_ret = pthread_cond_init (&out_cond, NULL)) != 0)
+ {
+ DEBUG_PRINT_ERROR("pthread_cond_init returns non zero for out_cond\n");
+ if (cond_ret == EAGAIN)
+ DEBUG_PRINT_ERROR("The system lacked necessary \
+ resources(other than mem)\n");
+ else if (cond_ret == ENOMEM)
+ DEBUG_PRINT_ERROR("Insufficient memory to initialise \
+ condition variable\n");
+ }
+
+ sem_init(&sem_read_msg,0, 0);
+ sem_init(&sem_write_msg,0, 0);
+ sem_init(&sem_States,0, 0);
+ return;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::~omx_evrc_aenc
+
+DESCRIPTION
+ Destructor
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+omx_evrc_aenc::~omx_evrc_aenc()
+{
+ DEBUG_PRINT_ERROR("EVRC Object getting destroyed comp-deinit=%d\n",
+ m_comp_deinit);
+ if ( !m_comp_deinit )
+ {
+ deinit_encoder();
+ }
+ pthread_mutexattr_destroy(&m_lock_attr);
+ pthread_mutex_destroy(&m_lock);
+
+ pthread_mutexattr_destroy(&m_commandlock_attr);
+ pthread_mutex_destroy(&m_commandlock);
+
+ pthread_mutexattr_destroy(&m_outputlock_attr);
+ pthread_mutex_destroy(&m_outputlock);
+
+ pthread_mutexattr_destroy(&m_state_attr);
+ pthread_mutex_destroy(&m_state_lock);
+
+ pthread_mutexattr_destroy(&m_event_attr);
+ pthread_mutex_destroy(&m_event_lock);
+
+ pthread_mutexattr_destroy(&m_flush_attr);
+ pthread_mutex_destroy(&m_flush_lock);
+
+ pthread_mutexattr_destroy(&m_in_th_attr);
+ pthread_mutex_destroy(&m_in_th_lock);
+
+ pthread_mutexattr_destroy(&m_out_th_attr);
+ pthread_mutex_destroy(&m_out_th_lock);
+
+ pthread_mutexattr_destroy(&out_buf_count_lock_attr);
+ pthread_mutex_destroy(&out_buf_count_lock);
+
+ pthread_mutexattr_destroy(&in_buf_count_lock_attr);
+ pthread_mutex_destroy(&in_buf_count_lock);
+
+ pthread_mutexattr_destroy(&m_in_th_attr_1);
+ pthread_mutex_destroy(&m_in_th_lock_1);
+
+ pthread_mutexattr_destroy(&m_out_th_attr_1);
+ pthread_mutex_destroy(&m_out_th_lock_1);
+ pthread_mutex_destroy(&out_buf_count_lock);
+ pthread_mutex_destroy(&in_buf_count_lock);
+ pthread_cond_destroy(&cond);
+ pthread_cond_destroy(&in_cond);
+ pthread_cond_destroy(&out_cond);
+ sem_destroy (&sem_read_msg);
+ sem_destroy (&sem_write_msg);
+ sem_destroy (&sem_States);
+ DEBUG_PRINT_ERROR("OMX EVRC component destroyed\n");
+ return;
+}
+
+/**
+ @brief memory function for sending EmptyBufferDone event
+ back to IL client
+
+ @param bufHdr OMX buffer header to be passed back to IL client
+ @return none
+ */
+void omx_evrc_aenc::buffer_done_cb(OMX_BUFFERHEADERTYPE *bufHdr)
+{
+ if (m_cb.EmptyBufferDone)
+ {
+ PrintFrameHdr(OMX_COMPONENT_GENERATE_BUFFER_DONE,bufHdr);
+ bufHdr->nFilledLen = 0;
+
+ m_cb.EmptyBufferDone(&m_cmp, m_app_data, bufHdr);
+ pthread_mutex_lock(&in_buf_count_lock);
+ m_evrc_pb_stats.ebd_cnt++;
+ nNumInputBuf--;
+ DEBUG_DETAIL("EBD CB:: in_buf_len=%d nNumInputBuf=%d %d ebd_cnt %d \n",\
+ m_evrc_pb_stats.tot_in_buf_len,
+ nNumInputBuf, m_evrc_pb_stats.ebd_cnt);
+ pthread_mutex_unlock(&in_buf_count_lock);
+ }
+
+ return;
+}
+
+/*=============================================================================
+FUNCTION:
+ flush_ack
+
+DESCRIPTION:
+
+
+INPUT/OUTPUT PARAMETERS:
+ None
+
+RETURN VALUE:
+ None
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+void omx_evrc_aenc::flush_ack()
+{
+ // Decrement the FLUSH ACK count and notify the waiting recepients
+ pthread_mutex_lock(&m_flush_lock);
+ --m_flush_cnt;
+ if (0 == m_flush_cnt)
+ {
+ event_complete();
+ }
+ DEBUG_PRINT("Rxed FLUSH ACK cnt=%d\n",m_flush_cnt);
+ pthread_mutex_unlock(&m_flush_lock);
+}
+void omx_evrc_aenc::frame_done_cb(OMX_BUFFERHEADERTYPE *bufHdr)
+{
+ if (m_cb.FillBufferDone)
+ {
+ PrintFrameHdr(OMX_COMPONENT_GENERATE_FRAME_DONE,bufHdr);
+ m_evrc_pb_stats.fbd_cnt++;
+ pthread_mutex_lock(&out_buf_count_lock);
+ nNumOutputBuf--;
+ DEBUG_PRINT("FBD CB:: nNumOutputBuf=%d out_buf_len=%u fbd_cnt=%u\n",\
+ nNumOutputBuf,
+ m_evrc_pb_stats.tot_out_buf_len,
+ m_evrc_pb_stats.fbd_cnt);
+ m_evrc_pb_stats.tot_out_buf_len += bufHdr->nFilledLen;
+ m_evrc_pb_stats.tot_pb_time = bufHdr->nTimeStamp;
+ DEBUG_PRINT("FBD:in_buf_len=%u out_buf_len=%u\n",
+ m_evrc_pb_stats.tot_in_buf_len,
+ m_evrc_pb_stats.tot_out_buf_len);
+
+ pthread_mutex_unlock(&out_buf_count_lock);
+ m_cb.FillBufferDone(&m_cmp, m_app_data, bufHdr);
+ }
+ return;
+}
+
+/*=============================================================================
+FUNCTION:
+ process_out_port_msg
+
+DESCRIPTION:
+ Function for handling all commands from IL client
+IL client commands are processed and callbacks are generated through
+this routine Audio Command Server provides the thread context for this routine
+
+INPUT/OUTPUT PARAMETERS:
+ [INOUT] client_data
+ [IN] id
+
+RETURN VALUE:
+ None
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+void omx_evrc_aenc::process_out_port_msg(void *client_data, unsigned char id)
+{
+ unsigned long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned char ident = 0;
+ unsigned qsize = 0; // qsize
+ unsigned tot_qsize = 0;
+ omx_evrc_aenc *pThis = (omx_evrc_aenc *) client_data;
+ OMX_STATETYPE state;
+
+loopback_out:
+ pthread_mutex_lock(&pThis->m_state_lock);
+ pThis->get_state(&pThis->m_cmp, &state);
+ pthread_mutex_unlock(&pThis->m_state_lock);
+ if ( state == OMX_StateLoaded )
+ {
+ DEBUG_PRINT(" OUT: IN LOADED STATE RETURN\n");
+ return;
+ }
+ pthread_mutex_lock(&pThis->m_outputlock);
+
+ qsize = pThis->m_output_ctrl_cmd_q.m_size;
+ tot_qsize = pThis->m_output_ctrl_cmd_q.m_size;
+ tot_qsize += pThis->m_output_ctrl_fbd_q.m_size;
+ tot_qsize += pThis->m_output_q.m_size;
+
+ if ( 0 == tot_qsize )
+ {
+ pthread_mutex_unlock(&pThis->m_outputlock);
+ DEBUG_DETAIL("OUT-->BREAK FROM LOOP...%d\n",tot_qsize);
+ return;
+ }
+ if ( (state != OMX_StateExecuting) && !qsize )
+ {
+ pthread_mutex_unlock(&pThis->m_outputlock);
+ pthread_mutex_lock(&pThis->m_state_lock);
+ pThis->get_state(&pThis->m_cmp, &state);
+ pthread_mutex_unlock(&pThis->m_state_lock);
+ if ( state == OMX_StateLoaded )
+ return;
+
+ DEBUG_DETAIL("OUT:1.SLEEPING OUT THREAD\n");
+ pthread_mutex_lock(&pThis->m_out_th_lock_1);
+ pThis->is_out_th_sleep = true;
+ pthread_mutex_unlock(&pThis->m_out_th_lock_1);
+ pThis->out_th_goto_sleep();
+
+ /* Get the updated state */
+ pthread_mutex_lock(&pThis->m_state_lock);
+ pThis->get_state(&pThis->m_cmp, &state);
+ pthread_mutex_unlock(&pThis->m_state_lock);
+ }
+
+ if ( ((!pThis->m_output_ctrl_cmd_q.m_size) && !pThis->m_out_bEnabled) )
+ {
+ // case where no port reconfig and nothing in the flush q
+ DEBUG_DETAIL("No flush/port reconfig qsize=%d tot_qsize=%d",\
+ qsize,tot_qsize);
+ pthread_mutex_unlock(&pThis->m_outputlock);
+ pthread_mutex_lock(&pThis->m_state_lock);
+ pThis->get_state(&pThis->m_cmp, &state);
+ pthread_mutex_unlock(&pThis->m_state_lock);
+ if ( state == OMX_StateLoaded )
+ return;
+
+ if(pThis->m_output_ctrl_cmd_q.m_size || !(pThis->bFlushinprogress))
+ {
+ DEBUG_PRINT("OUT:2. SLEEPING OUT THREAD \n");
+ pthread_mutex_lock(&pThis->m_out_th_lock_1);
+ pThis->is_out_th_sleep = true;
+ pthread_mutex_unlock(&pThis->m_out_th_lock_1);
+ pThis->out_th_goto_sleep();
+ }
+ /* Get the updated state */
+ pthread_mutex_lock(&pThis->m_state_lock);
+ pThis->get_state(&pThis->m_cmp, &state);
+ pthread_mutex_unlock(&pThis->m_state_lock);
+ }
+ qsize = pThis->m_output_ctrl_cmd_q.m_size;
+ tot_qsize = pThis->m_output_ctrl_cmd_q.m_size;
+ tot_qsize += pThis->m_output_ctrl_fbd_q.m_size;
+ tot_qsize += pThis->m_output_q.m_size;
+ pthread_mutex_lock(&pThis->m_state_lock);
+ pThis->get_state(&pThis->m_cmp, &state);
+ pthread_mutex_unlock(&pThis->m_state_lock);
+ DEBUG_DETAIL("OUT-->QSIZE-flush=%d,fbd=%d QSIZE=%d state=%d\n",\
+ pThis->m_output_ctrl_cmd_q.m_size,
+ pThis->m_output_ctrl_fbd_q.m_size,
+ pThis->m_output_q.m_size,state);
+
+
+ if (qsize)
+ {
+ // process FLUSH message
+ pThis->m_output_ctrl_cmd_q.pop_entry(&p1,&p2,&ident);
+ } else if ( (qsize = pThis->m_output_ctrl_fbd_q.m_size) &&
+ (pThis->m_out_bEnabled) && (state == OMX_StateExecuting) )
+ {
+ // then process EBD's
+ pThis->m_output_ctrl_fbd_q.pop_entry(&p1,&p2,&ident);
+ } else if ( (qsize = pThis->m_output_q.m_size) &&
+ (pThis->m_out_bEnabled) && (state == OMX_StateExecuting) )
+ {
+ // if no FLUSH and FBD's then process FTB's
+ pThis->m_output_q.pop_entry(&p1,&p2,&ident);
+ } else if ( state == OMX_StateLoaded )
+ {
+ pthread_mutex_unlock(&pThis->m_outputlock);
+ DEBUG_PRINT("IN: ***in OMX_StateLoaded so exiting\n");
+ return ;
+ } else
+ {
+ qsize = 0;
+ DEBUG_PRINT("OUT--> Empty Queue state=%d %d %d %d\n",state,
+ pThis->m_output_ctrl_cmd_q.m_size,
+ pThis->m_output_ctrl_fbd_q.m_size,
+ pThis->m_output_q.m_size);
+
+ if(state == OMX_StatePause)
+ {
+ DEBUG_DETAIL("OUT: SLEEPING AGAIN OUT THREAD\n");
+ pthread_mutex_lock(&pThis->m_out_th_lock_1);
+ pThis->is_out_th_sleep = true;
+ pthread_mutex_unlock(&pThis->m_out_th_lock_1);
+ pthread_mutex_unlock(&pThis->m_outputlock);
+ pThis->out_th_goto_sleep();
+ goto loopback_out;
+ }
+ }
+ pthread_mutex_unlock(&pThis->m_outputlock);
+
+ if ( qsize > 0 )
+ {
+ id = ident;
+ ident = 0;
+ DEBUG_DETAIL("OUT->state[%d]ident[%d]flushq[%d]fbd[%d]dataq[%d]\n",\
+ pThis->m_state,
+ ident,
+ pThis->m_output_ctrl_cmd_q.m_size,
+ pThis->m_output_ctrl_fbd_q.m_size,
+ pThis->m_output_q.m_size);
+
+ if ( OMX_COMPONENT_GENERATE_FRAME_DONE == id )
+ {
+ pThis->frame_done_cb((OMX_BUFFERHEADERTYPE *)p2);
+ } else if ( OMX_COMPONENT_GENERATE_FTB == id )
+ {
+ pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,
+ (OMX_BUFFERHEADERTYPE *)p2);
+ } else if ( OMX_COMPONENT_GENERATE_EOS == id )
+ {
+ pThis->m_cb.EventHandler(&pThis->m_cmp,
+ pThis->m_app_data,
+ OMX_EventBufferFlag,
+ 1, 1, NULL );
+
+ }
+ else if(id == OMX_COMPONENT_RESUME)
+ {
+ DEBUG_PRINT("RESUMED...\n");
+ }
+ else if(id == OMX_COMPONENT_GENERATE_COMMAND)
+ {
+ // Execute FLUSH command
+ if ( OMX_CommandFlush == p1 )
+ {
+ DEBUG_DETAIL("Executing FLUSH command on Output port\n");
+ pThis->execute_output_omx_flush();
+ } else
+ {
+ DEBUG_DETAIL("Invalid command[%lu]\n",p1);
+ }
+ } else
+ {
+ DEBUG_PRINT_ERROR("ERROR:OUT-->Invalid Id[%d]\n",id);
+ }
+ } else
+ {
+ DEBUG_DETAIL("ERROR: OUT--> Empty OUTPUTQ\n");
+ }
+
+ return;
+}
+
+/*=============================================================================
+FUNCTION:
+ process_command_msg
+
+DESCRIPTION:
+
+
+INPUT/OUTPUT PARAMETERS:
+ [INOUT] client_data
+ [IN] id
+
+RETURN VALUE:
+ None
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+void omx_evrc_aenc::process_command_msg(void *client_data, unsigned char id)
+{
+ unsigned long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned char ident = 0;
+ unsigned qsize = 0;
+ omx_evrc_aenc *pThis = (omx_evrc_aenc*)client_data;
+ pthread_mutex_lock(&pThis->m_commandlock);
+
+ qsize = pThis->m_command_q.m_size;
+ DEBUG_DETAIL("CMD-->QSIZE=%d state=%d\n",pThis->m_command_q.m_size,
+ pThis->m_state);
+
+ if (!qsize)
+ {
+ DEBUG_DETAIL("CMD-->BREAKING FROM LOOP\n");
+ pthread_mutex_unlock(&pThis->m_commandlock);
+ return;
+ } else
+ {
+ pThis->m_command_q.pop_entry(&p1,&p2,&ident);
+ }
+ pthread_mutex_unlock(&pThis->m_commandlock);
+
+ id = ident;
+ DEBUG_DETAIL("CMD->state[%d]id[%d]cmdq[%d]n",\
+ pThis->m_state,ident, \
+ pThis->m_command_q.m_size);
+
+ if (OMX_COMPONENT_GENERATE_EVENT == id)
+ {
+ if (pThis->m_cb.EventHandler)
+ {
+ if (OMX_CommandStateSet == p1)
+ {
+ pthread_mutex_lock(&pThis->m_state_lock);
+ pThis->m_state = (OMX_STATETYPE) p2;
+ pthread_mutex_unlock(&pThis->m_state_lock);
+ DEBUG_PRINT("CMD:Process->state set to %d \n", \
+ pThis->m_state);
+
+ if (pThis->m_state == OMX_StateExecuting ||
+ pThis->m_state == OMX_StateLoaded)
+ {
+
+ pthread_mutex_lock(&pThis->m_in_th_lock_1);
+ if (pThis->is_in_th_sleep)
+ {
+ pThis->is_in_th_sleep = false;
+ DEBUG_DETAIL("CMD:WAKING UP IN THREADS\n");
+ pThis->in_th_wakeup();
+ }
+ pthread_mutex_unlock(&pThis->m_in_th_lock_1);
+
+ pthread_mutex_lock(&pThis->m_out_th_lock_1);
+ if (pThis->is_out_th_sleep)
+ {
+ DEBUG_DETAIL("CMD:WAKING UP OUT THREADS\n");
+ pThis->is_out_th_sleep = false;
+ pThis->out_th_wakeup();
+ }
+ pthread_mutex_unlock(&pThis->m_out_th_lock_1);
+ }
+ }
+ if (OMX_StateInvalid == pThis->m_state)
+ {
+ pThis->m_cb.EventHandler(&pThis->m_cmp,
+ pThis->m_app_data,
+ OMX_EventError,
+ OMX_ErrorInvalidState,
+ 0, NULL );
+ } else if ((signed)p2 == OMX_ErrorPortUnpopulated)
+ {
+ pThis->m_cb.EventHandler(&pThis->m_cmp,
+ pThis->m_app_data,
+ OMX_EventError,
+ (OMX_U32)p2,
+ 0,
+ 0 );
+ } else
+ {
+ pThis->m_cb.EventHandler(&pThis->m_cmp,
+ pThis->m_app_data,
+ OMX_EventCmdComplete,
+ (OMX_U32)p1, (OMX_U32)p2, NULL );
+ }
+ } else
+ {
+ DEBUG_PRINT_ERROR("ERROR:CMD-->EventHandler NULL \n");
+ }
+ } else if (OMX_COMPONENT_GENERATE_COMMAND == id)
+ {
+ pThis->send_command_proxy(&pThis->m_cmp,
+ (OMX_COMMANDTYPE)p1,
+ (OMX_U32)p2,(OMX_PTR)NULL);
+ } else if (OMX_COMPONENT_PORTSETTINGS_CHANGED == id)
+ {
+ DEBUG_DETAIL("CMD-->RXED PORTSETTINGS_CHANGED");
+ pThis->m_cb.EventHandler(&pThis->m_cmp,
+ pThis->m_app_data,
+ OMX_EventPortSettingsChanged,
+ 1, 1, NULL );
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("CMD->state[%d]id[%d]\n",pThis->m_state,ident);
+ }
+ return;
+}
+
+/*=============================================================================
+FUNCTION:
+ process_in_port_msg
+
+DESCRIPTION:
+
+
+INPUT/OUTPUT PARAMETERS:
+ [INOUT] client_data
+ [IN] id
+
+RETURN VALUE:
+ None
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+void omx_evrc_aenc::process_in_port_msg(void *client_data, unsigned char id)
+{
+ unsigned long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned char ident = 0;
+ unsigned qsize = 0;
+ unsigned tot_qsize = 0;
+ omx_evrc_aenc *pThis = (omx_evrc_aenc *) client_data;
+ OMX_STATETYPE state;
+
+ if (!pThis)
+ {
+ DEBUG_PRINT_ERROR("ERROR:IN--> Invalid Obj \n");
+ return;
+ }
+loopback_in:
+ pthread_mutex_lock(&pThis->m_state_lock);
+ pThis->get_state(&pThis->m_cmp, &state);
+ pthread_mutex_unlock(&pThis->m_state_lock);
+ if ( state == OMX_StateLoaded )
+ {
+ DEBUG_PRINT(" IN: IN LOADED STATE RETURN\n");
+ return;
+ }
+ // Protect the shared queue data structure
+ pthread_mutex_lock(&pThis->m_lock);
+
+ qsize = pThis->m_input_ctrl_cmd_q.m_size;
+ tot_qsize = qsize;
+ tot_qsize += pThis->m_input_ctrl_ebd_q.m_size;
+ tot_qsize += pThis->m_input_q.m_size;
+
+ if ( 0 == tot_qsize )
+ {
+ DEBUG_DETAIL("IN-->BREAKING FROM IN LOOP");
+ pthread_mutex_unlock(&pThis->m_lock);
+ return;
+ }
+
+ if ( (state != OMX_StateExecuting) && ! (pThis->m_input_ctrl_cmd_q.m_size))
+ {
+ pthread_mutex_unlock(&pThis->m_lock);
+ DEBUG_DETAIL("SLEEPING IN THREAD\n");
+ pthread_mutex_lock(&pThis->m_in_th_lock_1);
+ pThis->is_in_th_sleep = true;
+ pthread_mutex_unlock(&pThis->m_in_th_lock_1);
+ pThis->in_th_goto_sleep();
+
+ /* Get the updated state */
+ pthread_mutex_lock(&pThis->m_state_lock);
+ pThis->get_state(&pThis->m_cmp, &state);
+ pthread_mutex_unlock(&pThis->m_state_lock);
+ }
+ else if ((state == OMX_StatePause))
+ {
+ if(!(pThis->m_input_ctrl_cmd_q.m_size))
+ {
+ pthread_mutex_unlock(&pThis->m_lock);
+
+ DEBUG_DETAIL("IN: SLEEPING IN THREAD\n");
+ pthread_mutex_lock(&pThis->m_in_th_lock_1);
+ pThis->is_in_th_sleep = true;
+ pthread_mutex_unlock(&pThis->m_in_th_lock_1);
+ pThis->in_th_goto_sleep();
+
+ pthread_mutex_lock(&pThis->m_state_lock);
+ pThis->get_state(&pThis->m_cmp, &state);
+ pthread_mutex_unlock(&pThis->m_state_lock);
+ }
+ }
+
+ qsize = pThis->m_input_ctrl_cmd_q.m_size;
+ tot_qsize = qsize;
+ tot_qsize += pThis->m_input_ctrl_ebd_q.m_size;
+ tot_qsize += pThis->m_input_q.m_size;
+
+ DEBUG_DETAIL("Input-->QSIZE-flush=%d,ebd=%d QSIZE=%d state=%d\n",\
+ pThis->m_input_ctrl_cmd_q.m_size,
+ pThis->m_input_ctrl_ebd_q.m_size,
+ pThis->m_input_q.m_size, state);
+
+
+ if ( qsize )
+ {
+ // process FLUSH message
+ pThis->m_input_ctrl_cmd_q.pop_entry(&p1,&p2,&ident);
+ } else if ( (qsize = pThis->m_input_ctrl_ebd_q.m_size) &&
+ (state == OMX_StateExecuting) )
+ {
+ // then process EBD's
+ pThis->m_input_ctrl_ebd_q.pop_entry(&p1,&p2,&ident);
+ } else if ((qsize = pThis->m_input_q.m_size) &&
+ (state == OMX_StateExecuting))
+ {
+ // if no FLUSH and EBD's then process ETB's
+ pThis->m_input_q.pop_entry(&p1, &p2, &ident);
+ } else if ( state == OMX_StateLoaded )
+ {
+ pthread_mutex_unlock(&pThis->m_lock);
+ DEBUG_PRINT("IN: ***in OMX_StateLoaded so exiting\n");
+ return ;
+ } else
+ {
+ qsize = 0;
+ DEBUG_PRINT("IN-->state[%d]cmdq[%d]ebdq[%d]in[%d]\n",\
+ state,pThis->m_input_ctrl_cmd_q.m_size,
+ pThis->m_input_ctrl_ebd_q.m_size,
+ pThis->m_input_q.m_size);
+
+ if(state == OMX_StatePause)
+ {
+ DEBUG_DETAIL("IN: SLEEPING AGAIN IN THREAD\n");
+ pthread_mutex_lock(&pThis->m_in_th_lock_1);
+ pThis->is_in_th_sleep = true;
+ pthread_mutex_unlock(&pThis->m_in_th_lock_1);
+ pthread_mutex_unlock(&pThis->m_lock);
+ pThis->in_th_goto_sleep();
+ goto loopback_in;
+ }
+ }
+ pthread_mutex_unlock(&pThis->m_lock);
+
+ if ( qsize > 0 )
+ {
+ id = ident;
+ DEBUG_DETAIL("Input->state[%d]id[%d]flushq[%d]ebdq[%d]dataq[%d]\n",\
+ pThis->m_state,
+ ident,
+ pThis->m_input_ctrl_cmd_q.m_size,
+ pThis->m_input_ctrl_ebd_q.m_size,
+ pThis->m_input_q.m_size);
+ if ( OMX_COMPONENT_GENERATE_BUFFER_DONE == id )
+ {
+ pThis->buffer_done_cb((OMX_BUFFERHEADERTYPE *)p2);
+ }
+ else if(id == OMX_COMPONENT_GENERATE_EOS)
+ {
+ pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
+ OMX_EventBufferFlag, 0, 1, NULL );
+ } else if ( OMX_COMPONENT_GENERATE_ETB == id )
+ {
+ pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,
+ (OMX_BUFFERHEADERTYPE *)p2);
+ } else if ( OMX_COMPONENT_GENERATE_COMMAND == id )
+ {
+ // Execute FLUSH command
+ if ( OMX_CommandFlush == p1 )
+ {
+ DEBUG_DETAIL(" Executing FLUSH command on Input port\n");
+ pThis->execute_input_omx_flush();
+ } else
+ {
+ DEBUG_DETAIL("Invalid command[%lu]\n",p1);
+ }
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR("ERROR:IN-->Invalid Id[%u]\n",id);
+ }
+ } else
+ {
+ DEBUG_DETAIL("ERROR:IN-->Empty INPUT Q\n");
+ }
+ return;
+}
+
+/**
+ @brief member function for performing component initialization
+
+ @param role C string mandating role of this component
+ @return Error status
+ */
+OMX_ERRORTYPE omx_evrc_aenc::component_init(OMX_STRING role)
+{
+
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ m_state = OMX_StateLoaded;
+
+ /* DSP does not give information about the bitstream
+ randomly assign the value right now. Query will result in
+ incorrect param */
+ memset(&m_evrc_param, 0, sizeof(m_evrc_param));
+ m_evrc_param.nSize = (OMX_U32)sizeof(m_evrc_param);
+ m_evrc_param.nChannels = OMX_EVRC_DEFAULT_CH_CFG;
+ //Current DSP does not have config
+ m_evrc_param.eCDMARate = OMX_AUDIO_CDMARateFull;
+ m_evrc_param.nMinBitRate = OMX_EVRC_DEFAULT_MINRATE;
+ m_evrc_param.nMaxBitRate = OMX_EVRC_DEFAULT_MAXRATE;
+ m_volume = OMX_EVRC_DEFAULT_VOL; /* Close to unity gain */
+ memset(&m_evrc_pb_stats,0,sizeof(EVRC_PB_STATS));
+ memset(&m_pcm_param, 0, sizeof(m_pcm_param));
+ m_pcm_param.nSize = (OMX_U32)sizeof(m_pcm_param);
+ m_pcm_param.nChannels = OMX_EVRC_DEFAULT_CH_CFG;
+ m_pcm_param.nSamplingRate = OMX_EVRC_DEFAULT_SF;
+ nTimestamp = 0;
+
+
+ nNumInputBuf = 0;
+ nNumOutputBuf = 0;
+ m_ipc_to_in_th = NULL; // Command server instance
+ m_ipc_to_out_th = NULL; // Client server instance
+ m_ipc_to_cmd_th = NULL; // command instance
+ m_is_out_th_sleep = 0;
+ m_is_in_th_sleep = 0;
+ is_out_th_sleep= false;
+
+ is_in_th_sleep=false;
+
+ memset(&m_priority_mgm, 0, sizeof(m_priority_mgm));
+ m_priority_mgm.nGroupID =0;
+ m_priority_mgm.nGroupPriority=0;
+
+ memset(&m_buffer_supplier, 0, sizeof(m_buffer_supplier));
+ m_buffer_supplier.nPortIndex=OMX_BufferSupplyUnspecified;
+
+ DEBUG_PRINT_ERROR(" component init: role = %s\n",role);
+
+ DEBUG_PRINT(" component init: role = %s\n",role);
+ component_Role.nVersion.nVersion = OMX_SPEC_VERSION;
+ if (!strcmp(role,"OMX.qcom.audio.encoder.evrc"))
+ {
+ pcm_input = 1;
+ component_Role.nSize = (OMX_U32)sizeof(role);
+ strlcpy((char *)component_Role.cRole,
+ (const char*)role, sizeof(component_Role.cRole));
+ DEBUG_PRINT("\ncomponent_init: Component %s LOADED \n", role);
+ } else if (!strcmp(role,"OMX.qcom.audio.encoder.tunneled.evrc"))
+ {
+ pcm_input = 0;
+ component_Role.nSize = (OMX_U32)sizeof(role);
+ strlcpy((char *)component_Role.cRole,
+ (const char*)role, sizeof(component_Role.cRole));
+ DEBUG_PRINT("\ncomponent_init: Component %s LOADED \n", role);
+ } else
+ {
+ component_Role.nSize = (OMX_U32)sizeof("\0");
+ strlcpy((char *)component_Role.cRole,
+ (const char*)"\0",sizeof(component_Role.cRole));
+ DEBUG_PRINT("\ncomponent_init: Component %s LOADED is invalid\n", role);
+ }
+ if(pcm_input)
+ {
+
+
+ m_tmp_meta_buf = (OMX_U8*) malloc(sizeof(OMX_U8) *
+ (OMX_CORE_INPUT_BUFFER_SIZE + sizeof(META_IN)));
+
+ if (m_tmp_meta_buf == NULL){
+ DEBUG_PRINT_ERROR("Mem alloc failed for in meta buf\n");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ m_tmp_out_meta_buf =
+ (OMX_U8*)malloc(sizeof(OMX_U8)*OMX_EVRC_OUTPUT_BUFFER_SIZE);
+ if ( m_tmp_out_meta_buf == NULL ) {
+ DEBUG_PRINT_ERROR("Mem alloc failed for out meta buf\n");
+ return OMX_ErrorInsufficientResources;
+ }
+
+ if(0 == pcm_input)
+ {
+ m_drv_fd = open("/dev/msm_evrc_in",O_RDONLY);
+ DEBUG_PRINT("Driver in Tunnel mode open\n");
+ }
+ else
+ {
+ m_drv_fd = open("/dev/msm_evrc_in",O_RDWR);
+ DEBUG_PRINT("Driver in Non Tunnel mode open\n");
+ }
+ if (m_drv_fd < 0)
+ {
+ DEBUG_PRINT_ERROR("Component_init Open Failed[%d] errno[%d]",\
+ m_drv_fd,errno);
+
+ return OMX_ErrorInsufficientResources;
+ }
+ if(ioctl(m_drv_fd, AUDIO_GET_SESSION_ID,&m_session_id) == -1)
+ {
+ DEBUG_PRINT_ERROR("AUDIO_GET_SESSION_ID FAILED\n");
+ }
+ if(pcm_input)
+ {
+ if (!m_ipc_to_in_th)
+ {
+ m_ipc_to_in_th = omx_evrc_thread_create(process_in_port_msg,
+ this, (char *)"INPUT_THREAD");
+ if (!m_ipc_to_in_th)
+ {
+ DEBUG_PRINT_ERROR("ERROR!!! Failed to start \
+ Input port thread\n");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ }
+
+ if (!m_ipc_to_cmd_th)
+ {
+ m_ipc_to_cmd_th = omx_evrc_thread_create(process_command_msg,
+ this, (char *)"CMD_THREAD");
+ if (!m_ipc_to_cmd_th)
+ {
+ DEBUG_PRINT_ERROR("ERROR!!!Failed to start "
+ "command message thread\n");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+
+ if (!m_ipc_to_out_th)
+ {
+ m_ipc_to_out_th = omx_evrc_thread_create(process_out_port_msg,
+ this, (char *)"OUTPUT_THREAD");
+ if (!m_ipc_to_out_th)
+ {
+ DEBUG_PRINT_ERROR("ERROR!!! Failed to start output "
+ "port thread\n");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ return eRet;
+}
+
+/**
+
+ @brief member function to retrieve version of component
+
+
+
+ @param hComp handle to this component instance
+ @param componentName name of component
+ @param componentVersion pointer to memory space which stores the
+ version number
+ @param specVersion pointer to memory sapce which stores version of
+ openMax specification
+ @param componentUUID
+ @return Error status
+ */
+OMX_ERRORTYPE omx_evrc_aenc::get_component_version
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_STRING componentName,
+ OMX_OUT OMX_VERSIONTYPE* componentVersion,
+ OMX_OUT OMX_VERSIONTYPE* specVersion,
+ OMX_OUT OMX_UUIDTYPE* componentUUID)
+{
+ if((hComp == NULL) || (componentName == NULL) ||
+ (specVersion == NULL) || (componentUUID == NULL))
+ {
+ componentVersion = NULL;
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+ componentVersion->nVersion = OMX_SPEC_VERSION;
+ specVersion->nVersion = OMX_SPEC_VERSION;
+ return OMX_ErrorNone;
+}
+/**
+ @brief member function handles command from IL client
+
+ This function simply queue up commands from IL client.
+ Commands will be processed in command server thread context later
+
+ @param hComp handle to component instance
+ @param cmd type of command
+ @param param1 parameters associated with the command type
+ @param cmdData
+ @return Error status
+*/
+OMX_ERRORTYPE omx_evrc_aenc::send_command(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_COMMANDTYPE cmd,
+ OMX_IN OMX_U32 param1,
+ OMX_IN OMX_PTR cmdData)
+{
+ int portIndex = (int)param1;
+
+ if(hComp == NULL)
+ {
+ cmdData = cmdData;
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (OMX_StateInvalid == m_state)
+ {
+ return OMX_ErrorInvalidState;
+ }
+ if ( (cmd == OMX_CommandFlush) && (portIndex > 1) )
+ {
+ return OMX_ErrorBadPortIndex;
+ }
+ post_command((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
+ DEBUG_PRINT("Send Command : returns with OMX_ErrorNone \n");
+ DEBUG_PRINT("send_command : recieved state before semwait= %u\n",param1);
+ sem_wait (&sem_States);
+ DEBUG_PRINT("send_command : recieved state after semwait\n");
+ return OMX_ErrorNone;
+}
+
+/**
+ @brief member function performs actual processing of commands excluding
+ empty buffer call
+
+ @param hComp handle to component
+ @param cmd command type
+ @param param1 parameter associated with the command
+ @param cmdData
+
+ @return error status
+*/
+OMX_ERRORTYPE omx_evrc_aenc::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_COMMANDTYPE cmd,
+ OMX_IN OMX_U32 param1,
+ OMX_IN OMX_PTR cmdData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ // Handle only IDLE and executing
+ OMX_STATETYPE eState = (OMX_STATETYPE) param1;
+ int bFlag = 1;
+ nState = eState;
+
+ if(hComp == NULL)
+ {
+ cmdData = cmdData;
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (OMX_CommandStateSet == cmd)
+ {
+ /***************************/
+ /* Current State is Loaded */
+ /***************************/
+ if (OMX_StateLoaded == m_state)
+ {
+ if (OMX_StateIdle == eState)
+ {
+
+ if (allocate_done() ||
+ (m_inp_bEnabled == OMX_FALSE
+ && m_out_bEnabled == OMX_FALSE))
+ {
+ DEBUG_PRINT("SCP-->Allocate Done Complete\n");
+ }
+ else
+ {
+ DEBUG_PRINT("SCP-->Loaded to Idle-Pending\n");
+ BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
+ bFlag = 0;
+ }
+
+ } else if (eState == OMX_StateLoaded)
+ {
+ DEBUG_PRINT("OMXCORE-SM: Loaded-->Loaded\n");
+ m_cb.EventHandler(&this->m_cmp,
+ this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorSameState,
+ 0, NULL );
+ eRet = OMX_ErrorSameState;
+ }
+
+ else if (eState == OMX_StateWaitForResources)
+ {
+ DEBUG_PRINT("OMXCORE-SM: Loaded-->WaitForResources\n");
+ eRet = OMX_ErrorNone;
+ }
+
+ else if (eState == OMX_StateExecuting)
+ {
+ DEBUG_PRINT("OMXCORE-SM: Loaded-->Executing\n");
+ m_cb.EventHandler(&this->m_cmp,
+ this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorIncorrectStateTransition,
+ 0, NULL );
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+
+ else if (eState == OMX_StatePause)
+ {
+ DEBUG_PRINT("OMXCORE-SM: Loaded-->Pause\n");
+ m_cb.EventHandler(&this->m_cmp,
+ this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorIncorrectStateTransition,
+ 0, NULL );
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+
+ else if (eState == OMX_StateInvalid)
+ {
+ DEBUG_PRINT("OMXCORE-SM: Loaded-->Invalid\n");
+ m_cb.EventHandler(&this->m_cmp,
+ this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorInvalidState,
+ 0, NULL );
+ m_state = OMX_StateInvalid;
+ eRet = OMX_ErrorInvalidState;
+ } else
+ {
+ DEBUG_PRINT_ERROR("SCP-->Loaded to Invalid(%d))\n",eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+
+ /***************************/
+ /* Current State is IDLE */
+ /***************************/
+ else if (OMX_StateIdle == m_state)
+ {
+ if (OMX_StateLoaded == eState)
+ {
+ if (release_done(-1))
+ {
+ if (ioctl(m_drv_fd, AUDIO_STOP, 0) == -1)
+ {
+ DEBUG_PRINT_ERROR("SCP:Idle->Loaded,\
+ ioctl stop failed %d\n", errno);
+ }
+
+ nTimestamp=0;
+
+ DEBUG_PRINT("SCP-->Idle to Loaded\n");
+ } else
+ {
+ DEBUG_PRINT("SCP--> Idle to Loaded-Pending\n");
+ BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
+ // Skip the event notification
+ bFlag = 0;
+ }
+ }
+ else if (OMX_StateExecuting == eState)
+ {
+
+ struct msm_audio_evrc_enc_config drv_evrc_enc_config;
+ struct msm_audio_stream_config drv_stream_config;
+ struct msm_audio_buf_cfg buf_cfg;
+ struct msm_audio_config pcm_cfg;
+
+ if(ioctl(m_drv_fd, AUDIO_GET_STREAM_CONFIG, &drv_stream_config)
+ == -1)
+ {
+ DEBUG_PRINT_ERROR("ioctl AUDIO_GET_STREAM_CONFIG failed, \
+ errno[%d]\n", errno);
+ }
+ if(ioctl(m_drv_fd, AUDIO_SET_STREAM_CONFIG, &drv_stream_config)
+ == -1)
+ {
+ DEBUG_PRINT_ERROR("ioctl AUDIO_SET_STREAM_CONFIG failed, \
+ errno[%d]\n", errno);
+ }
+
+ if(ioctl(m_drv_fd, AUDIO_GET_EVRC_ENC_CONFIG,
+ &drv_evrc_enc_config) == -1)
+ {
+ DEBUG_PRINT_ERROR("ioctl AUDIO_GET_EVRC_ENC_CONFIG failed,\
+ errno[%d]\n", errno);
+ }
+ drv_evrc_enc_config.min_bit_rate = m_evrc_param.nMinBitRate;
+ drv_evrc_enc_config.max_bit_rate = m_evrc_param.nMaxBitRate;
+ if(ioctl(m_drv_fd, AUDIO_SET_EVRC_ENC_CONFIG, &drv_evrc_enc_config)
+ == -1)
+ {
+ DEBUG_PRINT_ERROR("ioctl AUDIO_SET_EVRC_ENC_CONFIG failed,\
+ errno[%d]\n", errno);
+ }
+ if (ioctl(m_drv_fd, AUDIO_GET_BUF_CFG, &buf_cfg) == -1)
+ {
+ DEBUG_PRINT_ERROR("ioctl AUDIO_GET_BUF_CFG, errno[%d]\n",
+ errno);
+ }
+ buf_cfg.meta_info_enable = 1;
+ buf_cfg.frames_per_buf = NUMOFFRAMES;
+ if (ioctl(m_drv_fd, AUDIO_SET_BUF_CFG, &buf_cfg) == -1)
+ {
+ DEBUG_PRINT_ERROR("ioctl AUDIO_SET_BUF_CFG, errno[%d]\n",
+ errno);
+ }
+ if(pcm_input)
+ {
+ if (ioctl(m_drv_fd, AUDIO_GET_CONFIG, &pcm_cfg) == -1)
+ {
+ DEBUG_PRINT_ERROR("ioctl AUDIO_GET_CONFIG, errno[%d]\n",
+ errno);
+ }
+ pcm_cfg.channel_count = m_pcm_param.nChannels;
+ pcm_cfg.sample_rate = m_pcm_param.nSamplingRate;
+ DEBUG_PRINT("pcm config %u %u\n",m_pcm_param.nChannels,
+ m_pcm_param.nSamplingRate);
+
+ if (ioctl(m_drv_fd, AUDIO_SET_CONFIG, &pcm_cfg) == -1)
+ {
+ DEBUG_PRINT_ERROR("ioctl AUDIO_SET_CONFIG, errno[%d]\n",
+ errno);
+ }
+ }
+ if(ioctl(m_drv_fd, AUDIO_START, 0) == -1)
+ {
+ DEBUG_PRINT_ERROR("ioctl AUDIO_START failed, errno[%d]\n",
+ errno);
+ m_state = OMX_StateInvalid;
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError, OMX_ErrorInvalidState,
+ 0, NULL );
+ eRet = OMX_ErrorInvalidState;
+
+ }
+ DEBUG_PRINT("SCP-->Idle to Executing\n");
+ nState = eState;
+ } else if (eState == OMX_StateIdle)
+ {
+ DEBUG_PRINT("OMXCORE-SM: Idle-->Idle\n");
+ m_cb.EventHandler(&this->m_cmp,
+ this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorSameState,
+ 0, NULL );
+ eRet = OMX_ErrorSameState;
+ } else if (eState == OMX_StateWaitForResources)
+ {
+ DEBUG_PRINT("OMXCORE-SM: Idle-->WaitForResources\n");
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorIncorrectStateTransition,
+ 0, NULL );
+ eRet = OMX_ErrorIncorrectStateTransition;
+ }
+
+ else if (eState == OMX_StatePause)
+ {
+ DEBUG_PRINT("OMXCORE-SM: Idle-->Pause\n");
+ }
+
+ else if (eState == OMX_StateInvalid)
+ {
+ DEBUG_PRINT("OMXCORE-SM: Idle-->Invalid\n");
+ m_state = OMX_StateInvalid;
+ this->m_cb.EventHandler(&this->m_cmp,
+ this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorInvalidState,
+ 0, NULL );
+ eRet = OMX_ErrorInvalidState;
+ } else
+ {
+ DEBUG_PRINT_ERROR("SCP--> Idle to %d Not Handled\n",eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+
+ /******************************/
+ /* Current State is Executing */
+ /******************************/
+ else if (OMX_StateExecuting == m_state)
+ {
+ if (OMX_StateIdle == eState)
+ {
+ DEBUG_PRINT("SCP-->Executing to Idle \n");
+ if(pcm_input)
+ execute_omx_flush(-1,false);
+ else
+ execute_omx_flush(1,false);
+
+
+ } else if (OMX_StatePause == eState)
+ {
+ DEBUG_DETAIL("*************************\n");
+ DEBUG_PRINT("SCP-->RXED PAUSE STATE\n");
+ DEBUG_DETAIL("*************************\n");
+ //ioctl(m_drv_fd, AUDIO_PAUSE, 0);
+ } else if (eState == OMX_StateLoaded)
+ {
+ DEBUG_PRINT("\n OMXCORE-SM: Executing --> Loaded \n");
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorIncorrectStateTransition,
+ 0, NULL );
+ eRet = OMX_ErrorIncorrectStateTransition;
+ } else if (eState == OMX_StateWaitForResources)
+ {
+ DEBUG_PRINT("\n OMXCORE-SM: Executing --> WaitForResources \n");
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorIncorrectStateTransition,
+ 0, NULL );
+ eRet = OMX_ErrorIncorrectStateTransition;
+ } else if (eState == OMX_StateExecuting)
+ {
+ DEBUG_PRINT("\n OMXCORE-SM: Executing --> Executing \n");
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError, OMX_ErrorSameState,
+ 0, NULL );
+ eRet = OMX_ErrorSameState;
+ } else if (eState == OMX_StateInvalid)
+ {
+ DEBUG_PRINT("\n OMXCORE-SM: Executing --> Invalid \n");
+ m_state = OMX_StateInvalid;
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError, OMX_ErrorInvalidState,
+ 0, NULL );
+ eRet = OMX_ErrorInvalidState;
+ } else
+ {
+ DEBUG_PRINT_ERROR("SCP--> Executing to %d Not Handled\n",
+ eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ /***************************/
+ /* Current State is Pause */
+ /***************************/
+ else if (OMX_StatePause == m_state)
+ {
+ if( (eState == OMX_StateExecuting || eState == OMX_StateIdle) )
+ {
+ pthread_mutex_lock(&m_out_th_lock_1);
+ if(is_out_th_sleep)
+ {
+ DEBUG_DETAIL("PE: WAKING UP OUT THREAD\n");
+ is_out_th_sleep = false;
+ out_th_wakeup();
+ }
+ pthread_mutex_unlock(&m_out_th_lock_1);
+ }
+ if ( OMX_StateExecuting == eState )
+ {
+ nState = eState;
+ } else if ( OMX_StateIdle == eState )
+ {
+ DEBUG_PRINT("SCP-->Paused to Idle \n");
+ DEBUG_PRINT ("\n Internal flush issued");
+ pthread_mutex_lock(&m_flush_lock);
+ m_flush_cnt = 2;
+ pthread_mutex_unlock(&m_flush_lock);
+ if(pcm_input)
+ execute_omx_flush(-1,false);
+ else
+ execute_omx_flush(1,false);
+
+ } else if ( eState == OMX_StateLoaded )
+ {
+ DEBUG_PRINT("\n Pause --> loaded \n");
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorIncorrectStateTransition,
+ 0, NULL );
+ eRet = OMX_ErrorIncorrectStateTransition;
+ } else if (eState == OMX_StateWaitForResources)
+ {
+ DEBUG_PRINT("\n Pause --> WaitForResources \n");
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorIncorrectStateTransition,
+ 0, NULL );
+ eRet = OMX_ErrorIncorrectStateTransition;
+ } else if (eState == OMX_StatePause)
+ {
+ DEBUG_PRINT("\n Pause --> Pause \n");
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError, OMX_ErrorSameState,
+ 0, NULL );
+ eRet = OMX_ErrorSameState;
+ } else if (eState == OMX_StateInvalid)
+ {
+ DEBUG_PRINT("\n Pause --> Invalid \n");
+ m_state = OMX_StateInvalid;
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError, OMX_ErrorInvalidState,
+ 0, NULL );
+ eRet = OMX_ErrorInvalidState;
+ } else
+ {
+ DEBUG_PRINT("SCP-->Paused to %d Not Handled\n",eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ /**************************************/
+ /* Current State is WaitForResources */
+ /**************************************/
+ else if (m_state == OMX_StateWaitForResources)
+ {
+ if (eState == OMX_StateLoaded)
+ {
+ DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Loaded\n");
+ } else if (eState == OMX_StateWaitForResources)
+ {
+ DEBUG_PRINT("OMXCORE-SM: \
+ WaitForResources-->WaitForResources\n");
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError, OMX_ErrorSameState,
+ 0, NULL );
+ eRet = OMX_ErrorSameState;
+ } else if (eState == OMX_StateExecuting)
+ {
+ DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Executing\n");
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorIncorrectStateTransition,
+ 0, NULL );
+ eRet = OMX_ErrorIncorrectStateTransition;
+ } else if (eState == OMX_StatePause)
+ {
+ DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Pause\n");
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorIncorrectStateTransition,
+ 0, NULL );
+ eRet = OMX_ErrorIncorrectStateTransition;
+ } else if (eState == OMX_StateInvalid)
+ {
+ DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Invalid\n");
+ m_state = OMX_StateInvalid;
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError,
+ OMX_ErrorInvalidState,
+ 0, NULL );
+ eRet = OMX_ErrorInvalidState;
+ } else
+ {
+ DEBUG_PRINT_ERROR("SCP--> %d to %d(Not Handled)\n",
+ m_state,eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ /****************************/
+ /* Current State is Invalid */
+ /****************************/
+ else if (m_state == OMX_StateInvalid)
+ {
+ if (OMX_StateLoaded == eState || OMX_StateWaitForResources == eState
+ || OMX_StateIdle == eState || OMX_StateExecuting == eState
+ || OMX_StatePause == eState || OMX_StateInvalid == eState)
+ {
+ DEBUG_PRINT("OMXCORE-SM: Invalid-->Loaded/Idle/Executing"
+ "/Pause/Invalid/WaitForResources\n");
+ m_state = OMX_StateInvalid;
+ this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
+ OMX_EventError, OMX_ErrorInvalidState,
+ 0, NULL );
+ eRet = OMX_ErrorInvalidState;
+ }
+ } else
+ {
+ DEBUG_PRINT_ERROR("OMXCORE-SM: %d --> %d(Not Handled)\n",\
+ m_state,eState);
+ eRet = OMX_ErrorBadParameter;
+ }
+ } else if (OMX_CommandFlush == cmd)
+ {
+ DEBUG_DETAIL("*************************\n");
+ DEBUG_PRINT("SCP-->RXED FLUSH COMMAND port=%u\n",param1);
+ DEBUG_DETAIL("*************************\n");
+ bFlag = 0;
+ if ( param1 == OMX_CORE_INPUT_PORT_INDEX ||
+ param1 == OMX_CORE_OUTPUT_PORT_INDEX ||
+ (signed)param1 == -1 )
+ {
+ execute_omx_flush(param1);
+ } else
+ {
+ eRet = OMX_ErrorBadPortIndex;
+ m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventError,
+ OMX_CommandFlush, OMX_ErrorBadPortIndex, NULL );
+ }
+ } else if ( cmd == OMX_CommandPortDisable )
+ {
+ bFlag = 0;
+ if ( param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL )
+ {
+ DEBUG_PRINT("SCP: Disabling Input port Indx\n");
+ m_inp_bEnabled = OMX_FALSE;
+ if ( (m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
+ && release_done(0) )
+ {
+ DEBUG_PRINT("send_command_proxy:OMX_CommandPortDisable:\
+ OMX_CORE_INPUT_PORT_INDEX:release_done \n");
+ DEBUG_PRINT("************* OMX_CommandPortDisable:\
+ m_inp_bEnabled = %d********\n",m_inp_bEnabled);
+
+ post_command(OMX_CommandPortDisable,
+ OMX_CORE_INPUT_PORT_INDEX,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+
+ else
+ {
+ if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
+ {
+ DEBUG_PRINT("SCP: execute_omx_flush in Disable in "\
+ " param1=%u m_state=%d \n",param1, m_state);
+ execute_omx_flush(param1);
+ }
+ DEBUG_PRINT("send_command_proxy:OMX_CommandPortDisable:\
+ OMX_CORE_INPUT_PORT_INDEX \n");
+ BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
+ // Skip the event notification
+
+ }
+
+ }
+ if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
+ {
+
+ DEBUG_PRINT("SCP: Disabling Output port Indx\n");
+ m_out_bEnabled = OMX_FALSE;
+ if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
+ && release_done(1))
+ {
+ DEBUG_PRINT("send_command_proxy:OMX_CommandPortDisable:\
+ OMX_CORE_OUTPUT_PORT_INDEX:release_done \n");
+ DEBUG_PRINT("************* OMX_CommandPortDisable:\
+ m_out_bEnabled = %d********\n",m_inp_bEnabled);
+
+ post_command(OMX_CommandPortDisable,
+ OMX_CORE_OUTPUT_PORT_INDEX,
+ OMX_COMPONENT_GENERATE_EVENT);
+ } else
+ {
+ if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
+ {
+ DEBUG_PRINT("SCP: execute_omx_flush in Disable out "\
+ "param1=%u m_state=%d \n",param1, m_state);
+ execute_omx_flush(param1);
+ }
+ BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
+ // Skip the event notification
+
+ }
+ } else
+ {
+ DEBUG_PRINT_ERROR("OMX_CommandPortDisable: disable wrong port ID");
+ }
+
+ } else if (cmd == OMX_CommandPortEnable)
+ {
+ bFlag = 0;
+ if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
+ {
+ m_inp_bEnabled = OMX_TRUE;
+ DEBUG_PRINT("SCP: Enabling Input port Indx\n");
+ if ((m_state == OMX_StateLoaded
+ && !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
+ || (m_state == OMX_StateWaitForResources)
+ || (m_inp_bPopulated == OMX_TRUE))
+ {
+ post_command(OMX_CommandPortEnable,
+ OMX_CORE_INPUT_PORT_INDEX,
+ OMX_COMPONENT_GENERATE_EVENT);
+
+
+ } else
+ {
+ BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
+ // Skip the event notification
+
+ }
+ }
+
+ if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
+ {
+ DEBUG_PRINT("SCP: Enabling Output port Indx\n");
+ m_out_bEnabled = OMX_TRUE;
+ if ((m_state == OMX_StateLoaded
+ && !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
+ || (m_state == OMX_StateWaitForResources)
+ || (m_out_bPopulated == OMX_TRUE))
+ {
+ post_command(OMX_CommandPortEnable,
+ OMX_CORE_OUTPUT_PORT_INDEX,
+ OMX_COMPONENT_GENERATE_EVENT);
+ } else
+ {
+ DEBUG_PRINT("send_command_proxy:OMX_CommandPortEnable:\
+ OMX_CORE_OUTPUT_PORT_INDEX:release_done \n");
+ BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
+ // Skip the event notification
+
+ }
+ pthread_mutex_lock(&m_in_th_lock_1);
+ if(is_in_th_sleep)
+ {
+ is_in_th_sleep = false;
+ DEBUG_DETAIL("SCP:WAKING UP IN THREADS\n");
+ in_th_wakeup();
+ }
+ pthread_mutex_unlock(&m_in_th_lock_1);
+ pthread_mutex_lock(&m_out_th_lock_1);
+ if (is_out_th_sleep)
+ {
+ is_out_th_sleep = false;
+ DEBUG_PRINT("SCP:WAKING OUT THR, OMX_CommandPortEnable\n");
+ out_th_wakeup();
+ }
+ pthread_mutex_unlock(&m_out_th_lock_1);
+ } else
+ {
+ DEBUG_PRINT_ERROR("OMX_CommandPortEnable: disable wrong port ID");
+ }
+
+ } else
+ {
+ DEBUG_PRINT_ERROR("SCP-->ERROR: Invali Command [%d]\n",cmd);
+ eRet = OMX_ErrorNotImplemented;
+ }
+ DEBUG_PRINT("posting sem_States\n");
+ sem_post (&sem_States);
+ if (eRet == OMX_ErrorNone && bFlag)
+ {
+ post_command(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
+ }
+ return eRet;
+}
+
+/*=============================================================================
+FUNCTION:
+ execute_omx_flush
+
+DESCRIPTION:
+ Function that flushes buffers that are pending to be written to driver
+
+INPUT/OUTPUT PARAMETERS:
+ [IN] param1
+ [IN] cmd_cmpl
+
+RETURN VALUE:
+ true
+ false
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+bool omx_evrc_aenc::execute_omx_flush(OMX_IN OMX_U32 param1, bool cmd_cmpl)
+{
+ bool bRet = true;
+
+ DEBUG_PRINT("Execute_omx_flush Port[%u]", param1);
+ struct timespec abs_timeout;
+ abs_timeout.tv_sec = 1;
+ abs_timeout.tv_nsec = 0;
+
+ if ((signed)param1 == -1)
+ {
+ bFlushinprogress = true;
+ DEBUG_PRINT("Execute flush for both I/p O/p port\n");
+ pthread_mutex_lock(&m_flush_lock);
+ m_flush_cnt = 2;
+ pthread_mutex_unlock(&m_flush_lock);
+
+ // Send Flush commands to input and output threads
+ post_input(OMX_CommandFlush,
+ OMX_CORE_INPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND);
+ post_output(OMX_CommandFlush,
+ OMX_CORE_OUTPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND);
+ // Send Flush to the kernel so that the in and out buffers are released
+ if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) == -1)
+ DEBUG_PRINT_ERROR("FLush:ioctl flush failed errno=%d\n",errno);
+ DEBUG_DETAIL("****************************************");
+ DEBUG_DETAIL("is_in_th_sleep=%d is_out_th_sleep=%d\n",\
+ is_in_th_sleep,is_out_th_sleep);
+ DEBUG_DETAIL("****************************************");
+
+ pthread_mutex_lock(&m_in_th_lock_1);
+ if (is_in_th_sleep)
+ {
+ is_in_th_sleep = false;
+ DEBUG_DETAIL("For FLUSH-->WAKING UP IN THREADS\n");
+ in_th_wakeup();
+ }
+ pthread_mutex_unlock(&m_in_th_lock_1);
+
+ pthread_mutex_lock(&m_out_th_lock_1);
+ if (is_out_th_sleep)
+ {
+ is_out_th_sleep = false;
+ DEBUG_DETAIL("For FLUSH-->WAKING UP OUT THREADS\n");
+ out_th_wakeup();
+ }
+ pthread_mutex_unlock(&m_out_th_lock_1);
+
+
+ // sleep till the FLUSH ACK are done by both the input and
+ // output threads
+ DEBUG_DETAIL("WAITING FOR FLUSH ACK's param1=%d",param1);
+ wait_for_event();
+
+ DEBUG_PRINT("RECIEVED BOTH FLUSH ACK's param1=%u cmd_cmpl=%d",\
+ param1,cmd_cmpl);
+
+ // If not going to idle state, Send FLUSH complete message
+ // to the Client, now that FLUSH ACK's have been recieved.
+ if (cmd_cmpl)
+ {
+ m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete,
+ OMX_CommandFlush, OMX_CORE_INPUT_PORT_INDEX,
+ NULL );
+ m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete,
+ OMX_CommandFlush, OMX_CORE_OUTPUT_PORT_INDEX,
+ NULL );
+ DEBUG_PRINT("Inside FLUSH.. sending FLUSH CMPL\n");
+ }
+ bFlushinprogress = false;
+ }
+ else if (param1 == OMX_CORE_INPUT_PORT_INDEX)
+ {
+ DEBUG_PRINT("Execute FLUSH for I/p port\n");
+ pthread_mutex_lock(&m_flush_lock);
+ m_flush_cnt = 1;
+ pthread_mutex_unlock(&m_flush_lock);
+ post_input(OMX_CommandFlush,
+ OMX_CORE_INPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND);
+ if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) == -1)
+ DEBUG_PRINT_ERROR("Flush:Input port, ioctl flush failed %d\n",
+ errno);
+ DEBUG_DETAIL("****************************************");
+ DEBUG_DETAIL("is_in_th_sleep=%d is_out_th_sleep=%d\n",\
+ is_in_th_sleep,is_out_th_sleep);
+ DEBUG_DETAIL("****************************************");
+
+ if (is_in_th_sleep)
+ {
+ pthread_mutex_lock(&m_in_th_lock_1);
+ is_in_th_sleep = false;
+ pthread_mutex_unlock(&m_in_th_lock_1);
+ DEBUG_DETAIL("For FLUSH-->WAKING UP IN THREADS\n");
+ in_th_wakeup();
+ }
+
+ if (is_out_th_sleep)
+ {
+ pthread_mutex_lock(&m_out_th_lock_1);
+ is_out_th_sleep = false;
+ pthread_mutex_unlock(&m_out_th_lock_1);
+ DEBUG_DETAIL("For FLUSH-->WAKING UP OUT THREADS\n");
+ out_th_wakeup();
+ }
+
+ //sleep till the FLUSH ACK are done by both the input and output threads
+ DEBUG_DETAIL("Executing FLUSH for I/p port\n");
+ DEBUG_DETAIL("WAITING FOR FLUSH ACK's param1=%d",param1);
+ wait_for_event();
+ DEBUG_DETAIL(" RECIEVED FLUSH ACK FOR I/P PORT param1=%d",param1);
+
+ // Send FLUSH complete message to the Client,
+ // now that FLUSH ACK's have been recieved.
+ if (cmd_cmpl)
+ {
+ m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete,
+ OMX_CommandFlush, OMX_CORE_INPUT_PORT_INDEX,
+ NULL );
+ }
+ } else if (OMX_CORE_OUTPUT_PORT_INDEX == param1)
+ {
+ DEBUG_PRINT("Executing FLUSH for O/p port\n");
+ pthread_mutex_lock(&m_flush_lock);
+ m_flush_cnt = 1;
+ pthread_mutex_unlock(&m_flush_lock);
+ DEBUG_DETAIL("Executing FLUSH for O/p port\n");
+ DEBUG_DETAIL("WAITING FOR FLUSH ACK's param1=%d",param1);
+ post_output(OMX_CommandFlush,
+ OMX_CORE_OUTPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND);
+ if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) ==-1)
+ DEBUG_PRINT_ERROR("Flush:Output port, ioctl flush failed %d\n",
+ errno);
+ DEBUG_DETAIL("****************************************");
+ DEBUG_DETAIL("is_in_th_sleep=%d is_out_th_sleep=%d\n",\
+ is_in_th_sleep,is_out_th_sleep);
+ DEBUG_DETAIL("****************************************");
+ if (is_in_th_sleep)
+ {
+ pthread_mutex_lock(&m_in_th_lock_1);
+ is_in_th_sleep = false;
+ pthread_mutex_unlock(&m_in_th_lock_1);
+ DEBUG_DETAIL("For FLUSH-->WAKING UP IN THREADS\n");
+ in_th_wakeup();
+ }
+
+ if (is_out_th_sleep)
+ {
+ pthread_mutex_lock(&m_out_th_lock_1);
+ is_out_th_sleep = false;
+ pthread_mutex_unlock(&m_out_th_lock_1);
+ DEBUG_DETAIL("For FLUSH-->WAKING UP OUT THREADS\n");
+ out_th_wakeup();
+ }
+
+ // sleep till the FLUSH ACK are done by both the input and
+ // output threads
+ wait_for_event();
+ // Send FLUSH complete message to the Client,
+ // now that FLUSH ACK's have been recieved.
+ if (cmd_cmpl)
+ {
+ m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete,
+ OMX_CommandFlush, OMX_CORE_OUTPUT_PORT_INDEX,
+ NULL );
+ }
+ DEBUG_DETAIL("RECIEVED FLUSH ACK FOR O/P PORT param1=%d",param1);
+ } else
+ {
+ DEBUG_PRINT("Invalid Port ID[%u]",param1);
+ }
+ return bRet;
+}
+
+/*=============================================================================
+FUNCTION:
+ execute_input_omx_flush
+
+DESCRIPTION:
+ Function that flushes buffers that are pending to be written to driver
+
+INPUT/OUTPUT PARAMETERS:
+ None
+
+RETURN VALUE:
+ true
+ false
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+bool omx_evrc_aenc::execute_input_omx_flush()
+{
+ OMX_BUFFERHEADERTYPE *omx_buf;
+ unsigned long p1 = 0; // Parameter - 1
+ unsigned long p2 = 0; // Parameter - 2
+ unsigned char ident = 0;
+ unsigned qsize=0; // qsize
+ unsigned tot_qsize=0; // qsize
+
+ DEBUG_PRINT("Execute_omx_flush on input port");
+
+ pthread_mutex_lock(&m_lock);
+ do
+ {
+ qsize = m_input_q.m_size;
+ tot_qsize = qsize;
+ tot_qsize += m_input_ctrl_ebd_q.m_size;
+
+ DEBUG_DETAIL("Input FLUSH-->flushq[%d] ebd[%d]dataq[%d]",\
+ m_input_ctrl_cmd_q.m_size,
+ m_input_ctrl_ebd_q.m_size,qsize);
+ if (!tot_qsize)
+ {
+ DEBUG_DETAIL("Input-->BREAKING FROM execute_input_flush LOOP");
+ pthread_mutex_unlock(&m_lock);
+ break;
+ }
+ if (qsize)
+ {
+ m_input_q.pop_entry(&p1, &p2, &ident);
+ if ((ident == OMX_COMPONENT_GENERATE_ETB) ||
+ (ident == OMX_COMPONENT_GENERATE_BUFFER_DONE))
+ {
+ omx_buf = (OMX_BUFFERHEADERTYPE *) p2;
+ DEBUG_DETAIL("Flush:Input dataq=%p \n", omx_buf);
+ omx_buf->nFilledLen = 0;
+ buffer_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf);
+ }
+ } else if (m_input_ctrl_ebd_q.m_size)
+ {
+ m_input_ctrl_ebd_q.pop_entry(&p1, &p2, &ident);
+ if (ident == OMX_COMPONENT_GENERATE_BUFFER_DONE)
+ {
+ omx_buf = (OMX_BUFFERHEADERTYPE *) p2;
+ omx_buf->nFilledLen = 0;
+ DEBUG_DETAIL("Flush:ctrl dataq=%p \n", omx_buf);
+ buffer_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf);
+ }
+ } else
+ {
+ }
+ }while (tot_qsize>0);
+ DEBUG_DETAIL("*************************\n");
+ DEBUG_DETAIL("IN-->FLUSHING DONE\n");
+ DEBUG_DETAIL("*************************\n");
+ flush_ack();
+ pthread_mutex_unlock(&m_lock);
+ return true;
+}
+
+/*=============================================================================
+FUNCTION:
+ execute_output_omx_flush
+
+DESCRIPTION:
+ Function that flushes buffers that are pending to be written to driver
+
+INPUT/OUTPUT PARAMETERS:
+ None
+
+RETURN VALUE:
+ true
+ false
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+bool omx_evrc_aenc::execute_output_omx_flush()
+{
+ OMX_BUFFERHEADERTYPE *omx_buf;
+ unsigned long p1; // Parameter - 1
+ unsigned long p2; // Parameter - 2
+ unsigned char ident = 0;
+ unsigned qsize=0; // qsize
+ unsigned tot_qsize=0; // qsize
+
+ DEBUG_PRINT("Execute_omx_flush on output port");
+
+ pthread_mutex_lock(&m_outputlock);
+ do
+ {
+ qsize = m_output_q.m_size;
+ DEBUG_DETAIL("OUT FLUSH-->flushq[%d] fbd[%d]dataq[%d]",\
+ m_output_ctrl_cmd_q.m_size,
+ m_output_ctrl_fbd_q.m_size,qsize);
+ tot_qsize = qsize;
+ tot_qsize += m_output_ctrl_fbd_q.m_size;
+ if (!tot_qsize)
+ {
+ DEBUG_DETAIL("OUT-->BREAKING FROM execute_input_flush LOOP");
+ pthread_mutex_unlock(&m_outputlock);
+ break;
+ }
+ if (qsize)
+ {
+ m_output_q.pop_entry(&p1,&p2,&ident);
+ if ( (OMX_COMPONENT_GENERATE_FTB == ident) ||
+ (OMX_COMPONENT_GENERATE_FRAME_DONE == ident))
+ {
+ omx_buf = (OMX_BUFFERHEADERTYPE *) p2;
+ DEBUG_DETAIL("Ouput Buf_Addr=%p TS[0x%x] \n",\
+ omx_buf,nTimestamp);
+ omx_buf->nTimeStamp = nTimestamp;
+ omx_buf->nFilledLen = 0;
+ frame_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf);
+ DEBUG_DETAIL("CALLING FBD FROM FLUSH");
+ }
+ } else if ((qsize = m_output_ctrl_fbd_q.m_size))
+ {
+ m_output_ctrl_fbd_q.pop_entry(&p1, &p2, &ident);
+ if (OMX_COMPONENT_GENERATE_FRAME_DONE == ident)
+ {
+ omx_buf = (OMX_BUFFERHEADERTYPE *) p2;
+ DEBUG_DETAIL("Ouput Buf_Addr=%p TS[0x%x] \n", \
+ omx_buf,nTimestamp);
+ omx_buf->nTimeStamp = nTimestamp;
+ omx_buf->nFilledLen = 0;
+ frame_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf);
+ DEBUG_DETAIL("CALLING FROM CTRL-FBDQ FROM FLUSH");
+ }
+ }
+ }while (qsize>0);
+ DEBUG_DETAIL("*************************\n");
+ DEBUG_DETAIL("OUT-->FLUSHING DONE\n");
+ DEBUG_DETAIL("*************************\n");
+ flush_ack();
+ pthread_mutex_unlock(&m_outputlock);
+ return true;
+}
+
+/*=============================================================================
+FUNCTION:
+ post_input
+
+DESCRIPTION:
+ Function that posts command in the command queue
+
+INPUT/OUTPUT PARAMETERS:
+ [IN] p1
+ [IN] p2
+ [IN] id - command ID
+ [IN] lock - self-locking mode
+
+RETURN VALUE:
+ true
+ false
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+bool omx_evrc_aenc::post_input(unsigned long p1,
+ unsigned long p2,
+ unsigned char id)
+{
+ bool bRet = false;
+ pthread_mutex_lock(&m_lock);
+
+ if((OMX_COMPONENT_GENERATE_COMMAND == id) || (id == OMX_COMPONENT_SUSPEND))
+ {
+ // insert flush message and ebd
+ m_input_ctrl_cmd_q.insert_entry(p1,p2,id);
+ } else if ((OMX_COMPONENT_GENERATE_BUFFER_DONE == id))
+ {
+ // insert ebd
+ m_input_ctrl_ebd_q.insert_entry(p1,p2,id);
+ } else
+ {
+ // ETBS in this queue
+ m_input_q.insert_entry(p1,p2,id);
+ }
+
+ if (m_ipc_to_in_th)
+ {
+ bRet = true;
+ omx_evrc_post_msg(m_ipc_to_in_th, id);
+ }
+
+ DEBUG_DETAIL("PostInput-->state[%d]id[%d]flushq[%d]ebdq[%d]dataq[%d] \n",\
+ m_state,
+ id,
+ m_input_ctrl_cmd_q.m_size,
+ m_input_ctrl_ebd_q.m_size,
+ m_input_q.m_size);
+
+ pthread_mutex_unlock(&m_lock);
+ return bRet;
+}
+
+/*=============================================================================
+FUNCTION:
+ post_command
+
+DESCRIPTION:
+ Function that posts command in the command queue
+
+INPUT/OUTPUT PARAMETERS:
+ [IN] p1
+ [IN] p2
+ [IN] id - command ID
+ [IN] lock - self-locking mode
+
+RETURN VALUE:
+ true
+ false
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+bool omx_evrc_aenc::post_command(unsigned int p1,
+ unsigned int p2,
+ unsigned char id)
+{
+ bool bRet = false;
+
+ pthread_mutex_lock(&m_commandlock);
+
+ m_command_q.insert_entry(p1,p2,id);
+
+ if (m_ipc_to_cmd_th)
+ {
+ bRet = true;
+ omx_evrc_post_msg(m_ipc_to_cmd_th, id);
+ }
+
+ DEBUG_DETAIL("PostCmd-->state[%d]id[%d]cmdq[%d]flags[%x]\n",\
+ m_state,
+ id,
+ m_command_q.m_size,
+ m_flags >> 3);
+
+ pthread_mutex_unlock(&m_commandlock);
+ return bRet;
+}
+
+/*=============================================================================
+FUNCTION:
+ post_output
+
+DESCRIPTION:
+ Function that posts command in the command queue
+
+INPUT/OUTPUT PARAMETERS:
+ [IN] p1
+ [IN] p2
+ [IN] id - command ID
+ [IN] lock - self-locking mode
+
+RETURN VALUE:
+ true
+ false
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+bool omx_evrc_aenc::post_output(unsigned long p1,
+ unsigned long p2,
+ unsigned char id)
+{
+ bool bRet = false;
+
+ pthread_mutex_lock(&m_outputlock);
+ if((OMX_COMPONENT_GENERATE_COMMAND == id) || (id == OMX_COMPONENT_SUSPEND)
+ || (id == OMX_COMPONENT_RESUME))
+ {
+ // insert flush message and fbd
+ m_output_ctrl_cmd_q.insert_entry(p1,p2,id);
+ } else if ( (OMX_COMPONENT_GENERATE_FRAME_DONE == id) )
+ {
+ // insert flush message and fbd
+ m_output_ctrl_fbd_q.insert_entry(p1,p2,id);
+ } else
+ {
+ m_output_q.insert_entry(p1,p2,id);
+ }
+ if ( m_ipc_to_out_th )
+ {
+ bRet = true;
+ omx_evrc_post_msg(m_ipc_to_out_th, id);
+ }
+ DEBUG_DETAIL("PostOutput-->state[%d]id[%d]flushq[%d]ebdq[%d]dataq[%d]\n",\
+ m_state,
+ id,
+ m_output_ctrl_cmd_q.m_size,
+ m_output_ctrl_fbd_q.m_size,
+ m_output_q.m_size);
+
+ pthread_mutex_unlock(&m_outputlock);
+ return bRet;
+}
+/**
+ @brief member function that return parameters to IL client
+
+ @param hComp handle to component instance
+ @param paramIndex Parameter type
+ @param paramData pointer to memory space which would hold the
+ paramter
+ @return error status
+*/
+OMX_ERRORTYPE omx_evrc_aenc::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_INOUT OMX_PTR paramData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ if(hComp == NULL)
+ {
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+ if (paramData == NULL)
+ {
+ DEBUG_PRINT("get_parameter: paramData is NULL\n");
+ return OMX_ErrorBadParameter;
+ }
+
+ switch ((int)paramIndex)
+ {
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+
+ DEBUG_PRINT("OMX_IndexParamPortDefinition " \
+ "portDefn->nPortIndex = %u\n",
+ portDefn->nPortIndex);
+
+ portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
+ portDefn->nSize = (OMX_U32)sizeof(portDefn);
+ portDefn->eDomain = OMX_PortDomainAudio;
+
+ if (0 == portDefn->nPortIndex)
+ {
+ portDefn->eDir = OMX_DirInput;
+ portDefn->bEnabled = m_inp_bEnabled;
+ portDefn->bPopulated = m_inp_bPopulated;
+ portDefn->nBufferCountActual = m_inp_act_buf_count;
+ portDefn->nBufferCountMin = OMX_CORE_NUM_INPUT_BUFFERS;
+ portDefn->nBufferSize = input_buffer_size;
+ portDefn->format.audio.bFlagErrorConcealment = OMX_TRUE;
+ portDefn->format.audio.eEncoding = OMX_AUDIO_CodingPCM;
+ portDefn->format.audio.pNativeRender = 0;
+ } else if (1 == portDefn->nPortIndex)
+ {
+ portDefn->eDir = OMX_DirOutput;
+ portDefn->bEnabled = m_out_bEnabled;
+ portDefn->bPopulated = m_out_bPopulated;
+ portDefn->nBufferCountActual = m_out_act_buf_count;
+ portDefn->nBufferCountMin = OMX_CORE_NUM_OUTPUT_BUFFERS;
+ portDefn->nBufferSize = output_buffer_size;
+ portDefn->format.audio.bFlagErrorConcealment = OMX_TRUE;
+ portDefn->format.audio.eEncoding = OMX_AUDIO_CodingEVRC;
+ portDefn->format.audio.pNativeRender = 0;
+ } else
+ {
+ portDefn->eDir = OMX_DirMax;
+ DEBUG_PRINT_ERROR("Bad Port idx %d\n",\
+ (int)portDefn->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_IndexParamAudioInit:
+ {
+ OMX_PORT_PARAM_TYPE *portParamType =
+ (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT("OMX_IndexParamAudioInit\n");
+
+ portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
+ portParamType->nSize = (OMX_U32)sizeof(portParamType);
+ portParamType->nPorts = 2;
+ portParamType->nStartPortNumber = 0;
+ break;
+ }
+
+ case OMX_IndexParamAudioPortFormat:
+ {
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormatType =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *) paramData;
+ DEBUG_PRINT("OMX_IndexParamAudioPortFormat\n");
+ portFormatType->nVersion.nVersion = OMX_SPEC_VERSION;
+ portFormatType->nSize = (OMX_U32)sizeof(portFormatType);
+
+ if (OMX_CORE_INPUT_PORT_INDEX == portFormatType->nPortIndex)
+ {
+
+ portFormatType->eEncoding = OMX_AUDIO_CodingPCM;
+ } else if (OMX_CORE_OUTPUT_PORT_INDEX==
+ portFormatType->nPortIndex)
+ {
+ DEBUG_PRINT("get_parameter: OMX_IndexParamAudioFormat: "\
+ "%u\n", portFormatType->nIndex);
+
+ portFormatType->eEncoding = OMX_AUDIO_CodingEVRC;
+ } else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
+ (int)portFormatType->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_IndexParamAudioEvrc:
+ {
+ OMX_AUDIO_PARAM_EVRCTYPE *evrcParam =
+ (OMX_AUDIO_PARAM_EVRCTYPE *) paramData;
+ DEBUG_PRINT("OMX_IndexParamAudioEvrc\n");
+ if (OMX_CORE_OUTPUT_PORT_INDEX== evrcParam->nPortIndex)
+ {
+ memcpy(evrcParam,&m_evrc_param,
+ sizeof(OMX_AUDIO_PARAM_EVRCTYPE));
+ } else
+ {
+ DEBUG_PRINT_ERROR("get_parameter:OMX_IndexParamAudioEvrc "\
+ "OMX_ErrorBadPortIndex %d\n", \
+ (int)evrcParam->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case QOMX_IndexParamAudioSessionId:
+ {
+ QOMX_AUDIO_STREAM_INFO_DATA *streaminfoparam =
+ (QOMX_AUDIO_STREAM_INFO_DATA *) paramData;
+ streaminfoparam->sessionId = (OMX_U8)m_session_id;
+ break;
+ }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmparam =
+ (OMX_AUDIO_PARAM_PCMMODETYPE *) paramData;
+
+ if (OMX_CORE_INPUT_PORT_INDEX== pcmparam->nPortIndex)
+ {
+ memcpy(pcmparam,&m_pcm_param,\
+ sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ DEBUG_PRINT("get_parameter: Sampling rate %u",\
+ pcmparam->nSamplingRate);
+ DEBUG_PRINT("get_parameter: Number of channels %u",\
+ pcmparam->nChannels);
+ } else
+ {
+ DEBUG_PRINT_ERROR("get_parameter:OMX_IndexParamAudioPcm "\
+ "OMX_ErrorBadPortIndex %d\n", \
+ (int)pcmparam->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case OMX_IndexParamComponentSuspended:
+ {
+ OMX_PARAM_SUSPENSIONTYPE *suspend =
+ (OMX_PARAM_SUSPENSIONTYPE *) paramData;
+ DEBUG_PRINT("get_parameter: OMX_IndexParamComponentSuspended %p\n",
+ suspend);
+ break;
+ }
+ case OMX_IndexParamVideoInit:
+ {
+ OMX_PORT_PARAM_TYPE *portParamType =
+ (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT("get_parameter: OMX_IndexParamVideoInit\n");
+ portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
+ portParamType->nSize = (OMX_U32)sizeof(portParamType);
+ portParamType->nPorts = 0;
+ portParamType->nStartPortNumber = 0;
+ break;
+ }
+ case OMX_IndexParamPriorityMgmt:
+ {
+ OMX_PRIORITYMGMTTYPE *priorityMgmtType =
+ (OMX_PRIORITYMGMTTYPE*)paramData;
+ DEBUG_PRINT("get_parameter: OMX_IndexParamPriorityMgmt\n");
+ priorityMgmtType->nSize = (OMX_U32)sizeof(priorityMgmtType);
+ priorityMgmtType->nVersion.nVersion = OMX_SPEC_VERSION;
+ priorityMgmtType->nGroupID = m_priority_mgm.nGroupID;
+ priorityMgmtType->nGroupPriority =
+ m_priority_mgm.nGroupPriority;
+ break;
+ }
+ case OMX_IndexParamImageInit:
+ {
+ OMX_PORT_PARAM_TYPE *portParamType =
+ (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT("get_parameter: OMX_IndexParamImageInit\n");
+ portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
+ portParamType->nSize = (OMX_U32)sizeof(portParamType);
+ portParamType->nPorts = 0;
+ portParamType->nStartPortNumber = 0;
+ break;
+ }
+
+ case OMX_IndexParamCompBufferSupplier:
+ {
+ DEBUG_PRINT("get_parameter: \
+ OMX_IndexParamCompBufferSupplier\n");
+ OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType
+ = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
+ DEBUG_PRINT("get_parameter: \
+ OMX_IndexParamCompBufferSupplier\n");
+
+ bufferSupplierType->nSize = (OMX_U32)sizeof(bufferSupplierType);
+ bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
+ if (OMX_CORE_INPUT_PORT_INDEX ==
+ bufferSupplierType->nPortIndex)
+ {
+ bufferSupplierType->nPortIndex =
+ OMX_BufferSupplyUnspecified;
+ } else if (OMX_CORE_OUTPUT_PORT_INDEX ==
+ bufferSupplierType->nPortIndex)
+ {
+ bufferSupplierType->nPortIndex =
+ OMX_BufferSupplyUnspecified;
+ } else
+ {
+ DEBUG_PRINT_ERROR("get_parameter:"\
+ "OMX_IndexParamCompBufferSupplier eRet"\
+ "%08x\n", eRet);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ /*Component should support this port definition*/
+ case OMX_IndexParamOtherInit:
+ {
+ OMX_PORT_PARAM_TYPE *portParamType =
+ (OMX_PORT_PARAM_TYPE *) paramData;
+ DEBUG_PRINT("get_parameter: OMX_IndexParamOtherInit\n");
+ portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
+ portParamType->nSize = (OMX_U32)sizeof(portParamType);
+ portParamType->nPorts = 0;
+ portParamType->nStartPortNumber = 0;
+ break;
+ }
+ case OMX_IndexParamStandardComponentRole:
+ {
+ OMX_PARAM_COMPONENTROLETYPE *componentRole;
+ componentRole = (OMX_PARAM_COMPONENTROLETYPE*)paramData;
+ componentRole->nSize = component_Role.nSize;
+ componentRole->nVersion = component_Role.nVersion;
+ strlcpy((char *)componentRole->cRole,
+ (const char*)component_Role.cRole,
+ sizeof(componentRole->cRole));
+ DEBUG_PRINT_ERROR("nSize = %d , nVersion = %d, cRole = %s\n",
+ component_Role.nSize,
+ component_Role.nVersion,
+ component_Role.cRole);
+ break;
+
+ }
+ default:
+ {
+ DEBUG_PRINT_ERROR("unknown param %08x\n", paramIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ }
+ return eRet;
+
+}
+
+/**
+ @brief member function that set paramter from IL client
+
+ @param hComp handle to component instance
+ @param paramIndex parameter type
+ @param paramData pointer to memory space which holds the paramter
+ @return error status
+ */
+OMX_ERRORTYPE omx_evrc_aenc::set_parameter(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE paramIndex,
+ OMX_IN OMX_PTR paramData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ if(hComp == NULL)
+ {
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (m_state != OMX_StateLoaded)
+ {
+ DEBUG_PRINT_ERROR("set_parameter is not in proper state\n");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ if (paramData == NULL)
+ {
+ DEBUG_PRINT("param data is NULL");
+ return OMX_ErrorBadParameter;
+ }
+
+ switch (paramIndex)
+ {
+ case OMX_IndexParamAudioEvrc:
+ {
+ DEBUG_PRINT("OMX_IndexParamAudioEvrc");
+ OMX_AUDIO_PARAM_AMRTYPE *evrcparam
+ = (OMX_AUDIO_PARAM_AMRTYPE *) paramData;
+ memcpy(&m_evrc_param,evrcparam,
+ sizeof(OMX_AUDIO_PARAM_EVRCTYPE));
+ break;
+ }
+ case OMX_IndexParamPortDefinition:
+ {
+ OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
+ portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
+
+ if (((m_state == OMX_StateLoaded)&&
+ !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
+ || (m_state == OMX_StateWaitForResources &&
+ ((OMX_DirInput == portDefn->eDir &&
+ m_inp_bEnabled == true)||
+ (OMX_DirInput == portDefn->eDir &&
+ m_out_bEnabled == true)))
+ ||(((OMX_DirInput == portDefn->eDir &&
+ m_inp_bEnabled == false)||
+ (OMX_DirInput == portDefn->eDir &&
+ m_out_bEnabled == false)) &&
+ (m_state != OMX_StateWaitForResources)))
+ {
+ DEBUG_PRINT("Set Parameter called in valid state\n");
+ } else
+ {
+ DEBUG_PRINT_ERROR("Set Parameter called in \
+ Invalid State\n");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ DEBUG_PRINT("OMX_IndexParamPortDefinition portDefn->nPortIndex "
+ "= %u\n",portDefn->nPortIndex);
+ if (OMX_CORE_INPUT_PORT_INDEX == portDefn->nPortIndex)
+ {
+ if ( portDefn->nBufferCountActual >
+ OMX_CORE_NUM_INPUT_BUFFERS )
+ {
+ m_inp_act_buf_count = portDefn->nBufferCountActual;
+ } else
+ {
+ m_inp_act_buf_count =OMX_CORE_NUM_INPUT_BUFFERS;
+ }
+ input_buffer_size = portDefn->nBufferSize;
+
+ } else if (OMX_CORE_OUTPUT_PORT_INDEX == portDefn->nPortIndex)
+ {
+ if ( portDefn->nBufferCountActual >
+ OMX_CORE_NUM_OUTPUT_BUFFERS )
+ {
+ m_out_act_buf_count = portDefn->nBufferCountActual;
+ } else
+ {
+ m_out_act_buf_count =OMX_CORE_NUM_OUTPUT_BUFFERS;
+ }
+ output_buffer_size = portDefn->nBufferSize;
+ } else
+ {
+ DEBUG_PRINT(" set_parameter: Bad Port idx %d",\
+ (int)portDefn->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case OMX_IndexParamPriorityMgmt:
+ {
+ DEBUG_PRINT("set_parameter: OMX_IndexParamPriorityMgmt\n");
+
+ if (m_state != OMX_StateLoaded)
+ {
+ DEBUG_PRINT_ERROR("Set Parameter called in \
+ Invalid State\n");
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ OMX_PRIORITYMGMTTYPE *priorityMgmtype
+ = (OMX_PRIORITYMGMTTYPE*) paramData;
+ DEBUG_PRINT("set_parameter: OMX_IndexParamPriorityMgmt %u\n",
+ priorityMgmtype->nGroupID);
+
+ DEBUG_PRINT("set_parameter: priorityMgmtype %u\n",
+ priorityMgmtype->nGroupPriority);
+
+ m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
+ m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
+
+ break;
+ }
+ case OMX_IndexParamAudioPortFormat:
+ {
+
+ OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormatType =
+ (OMX_AUDIO_PARAM_PORTFORMATTYPE *) paramData;
+ DEBUG_PRINT("set_parameter: OMX_IndexParamAudioPortFormat\n");
+
+ if (OMX_CORE_INPUT_PORT_INDEX== portFormatType->nPortIndex)
+ {
+ portFormatType->eEncoding = OMX_AUDIO_CodingPCM;
+ } else if (OMX_CORE_OUTPUT_PORT_INDEX ==
+ portFormatType->nPortIndex)
+ {
+ DEBUG_PRINT("set_parameter: OMX_IndexParamAudioFormat:"\
+ " %u\n", portFormatType->nIndex);
+ portFormatType->eEncoding = OMX_AUDIO_CodingEVRC;
+ } else
+ {
+ DEBUG_PRINT_ERROR("set_parameter: Bad port index %d\n", \
+ (int)portFormatType->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+
+ case OMX_IndexParamCompBufferSupplier:
+ {
+ DEBUG_PRINT("set_parameter: \
+ OMX_IndexParamCompBufferSupplier\n");
+ OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType
+ = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
+ DEBUG_PRINT("set_param: OMX_IndexParamCompBufferSupplier %d",\
+ bufferSupplierType->eBufferSupplier);
+
+ if (bufferSupplierType->nPortIndex == OMX_CORE_INPUT_PORT_INDEX
+ || bufferSupplierType->nPortIndex ==
+ OMX_CORE_OUTPUT_PORT_INDEX)
+ {
+ DEBUG_PRINT("set_parameter:\
+ OMX_IndexParamCompBufferSupplier\n");
+ m_buffer_supplier.eBufferSupplier =
+ bufferSupplierType->eBufferSupplier;
+ } else
+ {
+ DEBUG_PRINT_ERROR("set_param:\
+ IndexParamCompBufferSup %08x\n", eRet);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+
+ break; }
+
+ case OMX_IndexParamAudioPcm:
+ {
+ DEBUG_PRINT("set_parameter: OMX_IndexParamAudioPcm\n");
+ OMX_AUDIO_PARAM_PCMMODETYPE *pcmparam
+ = (OMX_AUDIO_PARAM_PCMMODETYPE *) paramData;
+
+ if (OMX_CORE_INPUT_PORT_INDEX== pcmparam->nPortIndex)
+ {
+ memcpy(&m_pcm_param,pcmparam,\
+ sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
+ DEBUG_PRINT("set_pcm_parameter: %u %u",\
+ m_pcm_param.nChannels,
+ m_pcm_param.nSamplingRate);
+ } else
+ {
+ DEBUG_PRINT_ERROR("Set_parameter:OMX_IndexParamAudioPcm "
+ "OMX_ErrorBadPortIndex %d\n",
+ (int)pcmparam->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+ case OMX_IndexParamSuspensionPolicy:
+ {
+ eRet = OMX_ErrorNotImplemented;
+ break;
+ }
+ case OMX_IndexParamStandardComponentRole:
+ {
+ OMX_PARAM_COMPONENTROLETYPE *componentRole;
+ componentRole = (OMX_PARAM_COMPONENTROLETYPE*)paramData;
+ component_Role.nSize = componentRole->nSize;
+ component_Role.nVersion = componentRole->nVersion;
+ strlcpy((char *)component_Role.cRole,
+ (const char*)componentRole->cRole,
+ sizeof(component_Role.cRole));
+ break;
+ }
+
+ default:
+ {
+ DEBUG_PRINT_ERROR("unknown param %d\n", paramIndex);
+ eRet = OMX_ErrorUnsupportedIndex;
+ }
+ }
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::GetConfig
+
+DESCRIPTION
+ OMX Get Config Method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::get_config(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_INOUT OMX_PTR configData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ if(hComp == NULL)
+ {
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+
+ switch (configIndex)
+ {
+ case OMX_IndexConfigAudioVolume:
+ {
+ OMX_AUDIO_CONFIG_VOLUMETYPE *volume =
+ (OMX_AUDIO_CONFIG_VOLUMETYPE*) configData;
+
+ if (OMX_CORE_INPUT_PORT_INDEX == volume->nPortIndex)
+ {
+ volume->nSize = (OMX_U32)sizeof(volume);
+ volume->nVersion.nVersion = OMX_SPEC_VERSION;
+ volume->bLinear = OMX_TRUE;
+ volume->sVolume.nValue = m_volume;
+ volume->sVolume.nMax = OMX_AENC_MAX;
+ volume->sVolume.nMin = OMX_AENC_MIN;
+ } else
+ {
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ }
+ break;
+
+ case OMX_IndexConfigAudioMute:
+ {
+ OMX_AUDIO_CONFIG_MUTETYPE *mute =
+ (OMX_AUDIO_CONFIG_MUTETYPE*) configData;
+
+ if (OMX_CORE_INPUT_PORT_INDEX == mute->nPortIndex)
+ {
+ mute->nSize = (OMX_U32)sizeof(mute);
+ mute->nVersion.nVersion = OMX_SPEC_VERSION;
+ mute->bMute = (BITMASK_PRESENT(&m_flags,
+ OMX_COMPONENT_MUTED)?OMX_TRUE:OMX_FALSE);
+ } else
+ {
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ }
+ break;
+
+ default:
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::SetConfig
+
+DESCRIPTION
+ OMX Set Config method implementation
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if successful.
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::set_config(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_INDEXTYPE configIndex,
+ OMX_IN OMX_PTR configData)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ if(hComp == NULL)
+ {
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Set Config in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+ if ( m_state == OMX_StateExecuting)
+ {
+ DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
+ return OMX_ErrorInvalidState;
+ }
+
+ switch (configIndex)
+ {
+ case OMX_IndexConfigAudioVolume:
+ {
+ OMX_AUDIO_CONFIG_VOLUMETYPE *vol =
+ (OMX_AUDIO_CONFIG_VOLUMETYPE*)configData;
+ if (vol->nPortIndex == OMX_CORE_INPUT_PORT_INDEX)
+ {
+ if ((vol->sVolume.nValue <= OMX_AENC_MAX) &&
+ (vol->sVolume.nValue >= OMX_AENC_MIN))
+ {
+ m_volume = vol->sVolume.nValue;
+ if (BITMASK_ABSENT(&m_flags, OMX_COMPONENT_MUTED))
+ {
+ /* ioctl(m_drv_fd, AUDIO_VOLUME,
+ m_volume * OMX_AENC_VOLUME_STEP); */
+ }
+
+ } else
+ {
+ eRet = OMX_ErrorBadParameter;
+ }
+ } else
+ {
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ }
+ break;
+
+ case OMX_IndexConfigAudioMute:
+ {
+ OMX_AUDIO_CONFIG_MUTETYPE *mute = (OMX_AUDIO_CONFIG_MUTETYPE*)
+ configData;
+ if (mute->nPortIndex == OMX_CORE_INPUT_PORT_INDEX)
+ {
+ if (mute->bMute == OMX_TRUE)
+ {
+ BITMASK_SET(&m_flags, OMX_COMPONENT_MUTED);
+ /* ioctl(m_drv_fd, AUDIO_VOLUME, 0); */
+ } else
+ {
+ BITMASK_CLEAR(&m_flags, OMX_COMPONENT_MUTED);
+ /* ioctl(m_drv_fd, AUDIO_VOLUME,
+ m_volume * OMX_AENC_VOLUME_STEP); */
+ }
+ } else
+ {
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ }
+ break;
+
+ default:
+ eRet = OMX_ErrorUnsupportedIndex;
+ break;
+ }
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::GetExtensionIndex
+
+DESCRIPTION
+ OMX GetExtensionIndex method implementaion. <TBD>
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::get_extension_index(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_STRING paramName,
+ OMX_OUT OMX_INDEXTYPE* indexType)
+{
+ if((hComp == NULL) || (paramName == NULL) || (indexType == NULL))
+ {
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+ if(strncmp(paramName,"OMX.Qualcomm.index.audio.sessionId",
+ strlen("OMX.Qualcomm.index.audio.sessionId")) == 0)
+ {
+ *indexType =(OMX_INDEXTYPE)QOMX_IndexParamAudioSessionId;
+ DEBUG_PRINT("Extension index type - %d\n", *indexType);
+
+ }
+ else
+ {
+ return OMX_ErrorBadParameter;
+
+ }
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::GetState
+
+DESCRIPTION
+ Returns the state information back to the caller.<TBD>
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ Error None if everything is successful.
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::get_state(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_STATETYPE* state)
+{
+ if(hComp == NULL)
+ {
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ *state = m_state;
+ DEBUG_PRINT("Returning the state %d\n",*state);
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::ComponentTunnelRequest
+
+DESCRIPTION
+ OMX Component Tunnel Request method implementation. <TBD>
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::component_tunnel_request
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_HANDLETYPE peerComponent,
+ OMX_IN OMX_U32 peerPort,
+ OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
+{
+ DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
+
+ if((hComp == NULL) || (peerComponent == NULL) || (tunnelSetup == NULL))
+ {
+ port = port;
+ peerPort = peerPort;
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ return OMX_ErrorNotImplemented;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::AllocateInputBuffer
+
+DESCRIPTION
+ Helper function for allocate buffer in the input pin
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::allocate_input_buffer
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ OMX_BUFFERHEADERTYPE *bufHdr;
+ unsigned nBufSize = MAX(bytes, input_buffer_size);
+ char *buf_ptr;
+ if(m_inp_current_buf_count < m_inp_act_buf_count)
+ {
+ buf_ptr = (char *) calloc((nBufSize + \
+ sizeof(OMX_BUFFERHEADERTYPE)+sizeof(META_IN)) , 1);
+
+ if(hComp == NULL)
+ {
+ port = port;
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ free(buf_ptr);
+ return OMX_ErrorBadParameter;
+ }
+ if (buf_ptr != NULL)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr;
+ *bufferHdr = bufHdr;
+ memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE));
+
+ bufHdr->pBuffer = (OMX_U8 *)((buf_ptr) + sizeof(META_IN)+
+ sizeof(OMX_BUFFERHEADERTYPE));
+ bufHdr->nSize = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE);
+ bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
+ bufHdr->nAllocLen = nBufSize;
+ bufHdr->pAppPrivate = appData;
+ bufHdr->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
+ m_input_buf_hdrs.insert(bufHdr, NULL);
+
+ m_inp_current_buf_count++;
+ DEBUG_PRINT("AIB:bufHdr %p bufHdr->pBuffer %p m_inp_buf_cnt=%u \
+ bytes=%u", bufHdr, bufHdr->pBuffer,
+ m_inp_current_buf_count, bytes);
+
+ } else
+ {
+ DEBUG_PRINT("Input buffer memory allocation failed 1 \n");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ }
+ else
+ {
+ DEBUG_PRINT("Input buffer memory allocation failed 2\n");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ return eRet;
+}
+
+OMX_ERRORTYPE omx_evrc_aenc::allocate_output_buffer
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ OMX_BUFFERHEADERTYPE *bufHdr;
+ unsigned nBufSize = MAX(bytes,output_buffer_size);
+ char *buf_ptr;
+
+ if(hComp == NULL)
+ {
+ port = port;
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (m_out_current_buf_count < m_out_act_buf_count)
+ {
+ buf_ptr = (char *) calloc( (nBufSize + sizeof(OMX_BUFFERHEADERTYPE)),1);
+
+ if (buf_ptr != NULL)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr;
+ *bufferHdr = bufHdr;
+ memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE));
+
+ bufHdr->pBuffer = (OMX_U8 *)((buf_ptr) +
+ sizeof(OMX_BUFFERHEADERTYPE));
+ bufHdr->nSize = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE);
+ bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
+ bufHdr->nAllocLen = nBufSize;
+ bufHdr->pAppPrivate = appData;
+ bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+ m_output_buf_hdrs.insert(bufHdr, NULL);
+ m_out_current_buf_count++;
+ DEBUG_PRINT("AOB::bufHdr %p bufHdr->pBuffer %p m_out_buf_cnt=%d "\
+ "bytes=%u",bufHdr, bufHdr->pBuffer,\
+ m_out_current_buf_count, bytes);
+ } else
+ {
+ DEBUG_PRINT("Output buffer memory allocation failed 1 \n");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ } else
+ {
+ DEBUG_PRINT("Output buffer memory allocation failed\n");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ return eRet;
+}
+
+
+// AllocateBuffer -- API Call
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::AllocateBuffer
+
+DESCRIPTION
+ Returns zero if all the buffers released..
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::allocate_buffer
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes)
+{
+
+ OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
+
+ if (m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+ // What if the client calls again.
+ if (OMX_CORE_INPUT_PORT_INDEX == port)
+ {
+ eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
+ } else if (OMX_CORE_OUTPUT_PORT_INDEX == port)
+ {
+ eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
+ } else
+ {
+ DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",
+ (int)port);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+
+ if (eRet == OMX_ErrorNone)
+ {
+ DEBUG_PRINT("allocate_buffer: before allocate_done \n");
+ if (allocate_done())
+ {
+ DEBUG_PRINT("allocate_buffer: after allocate_done \n");
+ if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
+ {
+ BITMASK_CLEAR(&m_flags, OMX_COMPONENT_IDLE_PENDING);
+ post_command(OMX_CommandStateSet,OMX_StateIdle,
+ OMX_COMPONENT_GENERATE_EVENT);
+ DEBUG_PRINT("allocate_buffer: post idle transition event \n");
+ }
+ DEBUG_PRINT("allocate_buffer: complete \n");
+ }
+ if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
+ {
+ if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
+ {
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
+ post_command(OMX_CommandPortEnable, OMX_CORE_INPUT_PORT_INDEX,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ }
+ if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
+ {
+ if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
+ {
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
+ m_out_bEnabled = OMX_TRUE;
+
+ DEBUG_PRINT("AllocBuf-->is_out_th_sleep=%d\n",is_out_th_sleep);
+ pthread_mutex_lock(&m_out_th_lock_1);
+ if (is_out_th_sleep)
+ {
+ is_out_th_sleep = false;
+ DEBUG_DETAIL("AllocBuf:WAKING UP OUT THREADS\n");
+ out_th_wakeup();
+ }
+ pthread_mutex_unlock(&m_out_th_lock_1);
+ pthread_mutex_lock(&m_in_th_lock_1);
+ if(is_in_th_sleep)
+ {
+ is_in_th_sleep = false;
+ DEBUG_DETAIL("AB:WAKING UP IN THREADS\n");
+ in_th_wakeup();
+ }
+ pthread_mutex_unlock(&m_in_th_lock_1);
+ post_command(OMX_CommandPortEnable, OMX_CORE_OUTPUT_PORT_INDEX,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ }
+ }
+ DEBUG_PRINT("Allocate Buffer exit with ret Code %d\n", eRet);
+ return eRet;
+}
+
+/*=============================================================================
+FUNCTION:
+ use_buffer
+
+DESCRIPTION:
+ OMX Use Buffer method implementation.
+
+INPUT/OUTPUT PARAMETERS:
+ [INOUT] bufferHdr
+ [IN] hComp
+ [IN] port
+ [IN] appData
+ [IN] bytes
+ [IN] buffer
+
+RETURN VALUE:
+ OMX_ERRORTYPE
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+OMX_ERRORTYPE omx_evrc_aenc::use_buffer
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes,
+ OMX_IN OMX_U8* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ if (OMX_CORE_INPUT_PORT_INDEX == port)
+ {
+ eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
+
+ } else if (OMX_CORE_OUTPUT_PORT_INDEX == port)
+ {
+ eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
+ } else
+ {
+ DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+
+ if (eRet == OMX_ErrorNone)
+ {
+ DEBUG_PRINT("Checking for Output Allocate buffer Done");
+ if (allocate_done())
+ {
+ if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
+ {
+ BITMASK_CLEAR(&m_flags, OMX_COMPONENT_IDLE_PENDING);
+ post_command(OMX_CommandStateSet,OMX_StateIdle,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ }
+ if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
+ {
+ if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
+ {
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
+ post_command(OMX_CommandPortEnable, OMX_CORE_INPUT_PORT_INDEX,
+ OMX_COMPONENT_GENERATE_EVENT);
+
+ }
+ }
+ if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
+ {
+ if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
+ {
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
+ post_command(OMX_CommandPortEnable, OMX_CORE_OUTPUT_PORT_INDEX,
+ OMX_COMPONENT_GENERATE_EVENT);
+ pthread_mutex_lock(&m_out_th_lock_1);
+ if (is_out_th_sleep)
+ {
+ is_out_th_sleep = false;
+ DEBUG_DETAIL("UseBuf:WAKING UP OUT THREADS\n");
+ out_th_wakeup();
+ }
+ pthread_mutex_unlock(&m_out_th_lock_1);
+ pthread_mutex_lock(&m_in_th_lock_1);
+ if(is_in_th_sleep)
+ {
+ is_in_th_sleep = false;
+ DEBUG_DETAIL("UB:WAKING UP IN THREADS\n");
+ in_th_wakeup();
+ }
+ pthread_mutex_unlock(&m_in_th_lock_1);
+ }
+ }
+ }
+ DEBUG_PRINT("Use Buffer for port[%u] eRet[%d]\n", port,eRet);
+ return eRet;
+}
+/*=============================================================================
+FUNCTION:
+ use_input_buffer
+
+DESCRIPTION:
+ Helper function for Use buffer in the input pin
+
+INPUT/OUTPUT PARAMETERS:
+ [INOUT] bufferHdr
+ [IN] hComp
+ [IN] port
+ [IN] appData
+ [IN] bytes
+ [IN] buffer
+
+RETURN VALUE:
+ OMX_ERRORTYPE
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+OMX_ERRORTYPE omx_evrc_aenc::use_input_buffer
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes,
+ OMX_IN OMX_U8* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ OMX_BUFFERHEADERTYPE *bufHdr;
+ unsigned nBufSize = MAX(bytes, input_buffer_size);
+ char *buf_ptr;
+
+ if(hComp == NULL)
+ {
+ port = port;
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if(bytes < input_buffer_size)
+ {
+ /* return if i\p buffer size provided by client
+ is less than min i\p buffer size supported by omx component*/
+ return OMX_ErrorInsufficientResources;
+ }
+ if (m_inp_current_buf_count < m_inp_act_buf_count)
+ {
+ buf_ptr = (char *) calloc(sizeof(OMX_BUFFERHEADERTYPE), 1);
+
+ if (buf_ptr != NULL)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr;
+ *bufferHdr = bufHdr;
+ memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE));
+
+ bufHdr->pBuffer = (OMX_U8 *)(buffer);
+ DEBUG_PRINT("use_input_buffer:bufHdr %p bufHdr->pBuffer %p \
+ bytes=%u", bufHdr, bufHdr->pBuffer,bytes);
+ bufHdr->nSize = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE);
+ bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
+ bufHdr->nAllocLen = nBufSize;
+ input_buffer_size = nBufSize;
+ bufHdr->pAppPrivate = appData;
+ bufHdr->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX;
+ bufHdr->nOffset = 0;
+ m_input_buf_hdrs.insert(bufHdr, NULL);
+ m_inp_current_buf_count++;
+ } else
+ {
+ DEBUG_PRINT("Input buffer memory allocation failed 1 \n");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ } else
+ {
+ DEBUG_PRINT("Input buffer memory allocation failed\n");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ return eRet;
+}
+
+/*=============================================================================
+FUNCTION:
+ use_output_buffer
+
+DESCRIPTION:
+ Helper function for Use buffer in the output pin
+
+INPUT/OUTPUT PARAMETERS:
+ [INOUT] bufferHdr
+ [IN] hComp
+ [IN] port
+ [IN] appData
+ [IN] bytes
+ [IN] buffer
+
+RETURN VALUE:
+ OMX_ERRORTYPE
+
+Dependency:
+ None
+
+SIDE EFFECTS:
+ None
+=============================================================================*/
+OMX_ERRORTYPE omx_evrc_aenc::use_output_buffer
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN OMX_U32 bytes,
+ OMX_IN OMX_U8* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ OMX_BUFFERHEADERTYPE *bufHdr;
+ unsigned nBufSize = MAX(bytes,output_buffer_size);
+ char *buf_ptr;
+
+ if(hComp == NULL)
+ {
+ port = port;
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (bytes < output_buffer_size)
+ {
+ /* return if o\p buffer size provided by client
+ is less than min o\p buffer size supported by omx component*/
+ return OMX_ErrorInsufficientResources;
+ }
+
+ DEBUG_PRINT("Inside omx_evrc_aenc::use_output_buffer");
+ if (m_out_current_buf_count < m_out_act_buf_count)
+ {
+
+ buf_ptr = (char *) calloc(sizeof(OMX_BUFFERHEADERTYPE), 1);
+
+ if (buf_ptr != NULL)
+ {
+ bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr;
+ DEBUG_PRINT("BufHdr=%p buffer=%p\n",bufHdr,buffer);
+ *bufferHdr = bufHdr;
+ memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE));
+
+ bufHdr->pBuffer = (OMX_U8 *)(buffer);
+ DEBUG_PRINT("use_output_buffer:bufHdr %p bufHdr->pBuffer %p \
+ len=%u\n", bufHdr, bufHdr->pBuffer,bytes);
+ bufHdr->nSize = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE);
+ bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
+ bufHdr->nAllocLen = nBufSize;
+ output_buffer_size = nBufSize;
+ bufHdr->pAppPrivate = appData;
+ bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
+ bufHdr->nOffset = 0;
+ m_output_buf_hdrs.insert(bufHdr, NULL);
+ m_out_current_buf_count++;
+
+ } else
+ {
+ DEBUG_PRINT("Output buffer memory allocation failed\n");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ } else
+ {
+ DEBUG_PRINT("Output buffer memory allocation failed 2\n");
+ eRet = OMX_ErrorInsufficientResources;
+ }
+ return eRet;
+}
+/**
+ @brief member function that searches for caller buffer
+
+ @param buffer pointer to buffer header
+ @return bool value indicating whether buffer is found
+ */
+bool omx_evrc_aenc::search_input_bufhdr(OMX_BUFFERHEADERTYPE *buffer)
+{
+
+ bool eRet = false;
+ OMX_BUFFERHEADERTYPE *temp = NULL;
+
+ //access only in IL client context
+ temp = m_input_buf_hdrs.find_ele(buffer);
+ if (buffer && temp)
+ {
+ DEBUG_DETAIL("search_input_bufhdr %p \n", buffer);
+ eRet = true;
+ }
+ return eRet;
+}
+
+/**
+ @brief member function that searches for caller buffer
+
+ @param buffer pointer to buffer header
+ @return bool value indicating whether buffer is found
+ */
+bool omx_evrc_aenc::search_output_bufhdr(OMX_BUFFERHEADERTYPE *buffer)
+{
+
+ bool eRet = false;
+ OMX_BUFFERHEADERTYPE *temp = NULL;
+
+ //access only in IL client context
+ temp = m_output_buf_hdrs.find_ele(buffer);
+ if (buffer && temp)
+ {
+ DEBUG_DETAIL("search_output_bufhdr %p \n", buffer);
+ eRet = true;
+ }
+ return eRet;
+}
+
+// Free Buffer - API call
+/**
+ @brief member function that handles free buffer command from IL client
+
+ This function is a block-call function that handles IL client request to
+ freeing the buffer
+
+ @param hComp handle to component instance
+ @param port id of port which holds the buffer
+ @param buffer buffer header
+ @return Error status
+*/
+OMX_ERRORTYPE omx_evrc_aenc::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ DEBUG_PRINT("Free_Buffer buf %p\n", buffer);
+ if(hComp == NULL)
+ {
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (m_state == OMX_StateIdle &&
+ (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
+ {
+ DEBUG_PRINT(" free buffer while Component in Loading pending\n");
+ } else if ((m_inp_bEnabled == OMX_FALSE &&
+ port == OMX_CORE_INPUT_PORT_INDEX)||
+ (m_out_bEnabled == OMX_FALSE &&
+ port == OMX_CORE_OUTPUT_PORT_INDEX))
+ {
+ DEBUG_PRINT("Free Buffer while port %u disabled\n", port);
+ } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause)
+ {
+ DEBUG_PRINT("Invalid state to free buffer,ports need to be disabled:\
+ OMX_ErrorPortUnpopulated\n");
+ post_command(OMX_EventError,
+ OMX_ErrorPortUnpopulated,
+ OMX_COMPONENT_GENERATE_EVENT);
+
+ return eRet;
+ } else
+ {
+ DEBUG_PRINT("free_buffer: Invalid state to free buffer,ports need to be\
+ disabled:OMX_ErrorPortUnpopulated\n");
+ post_command(OMX_EventError,
+ OMX_ErrorPortUnpopulated,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ if (OMX_CORE_INPUT_PORT_INDEX == port)
+ {
+ if (m_inp_current_buf_count != 0)
+ {
+ m_inp_bPopulated = OMX_FALSE;
+ if (true == search_input_bufhdr(buffer))
+ {
+ /* Buffer exist */
+ //access only in IL client context
+ DEBUG_PRINT("Free_Buf:in_buffer[%p]\n",buffer);
+ m_input_buf_hdrs.erase(buffer);
+ free(buffer);
+ m_inp_current_buf_count--;
+ } else
+ {
+ DEBUG_PRINT_ERROR("Free_Buf:Error-->free_buffer, \
+ Invalid Input buffer header\n");
+ eRet = OMX_ErrorBadParameter;
+ }
+ } else
+ {
+ DEBUG_PRINT_ERROR("Error: free_buffer,Port Index calculation \
+ came out Invalid\n");
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
+ && release_done(0))
+ {
+ DEBUG_PRINT("INPUT PORT MOVING TO DISABLED STATE \n");
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
+ post_command(OMX_CommandPortDisable,
+ OMX_CORE_INPUT_PORT_INDEX,
+ OMX_COMPONENT_GENERATE_EVENT);
+ }
+ } else if (OMX_CORE_OUTPUT_PORT_INDEX == port)
+ {
+ if (m_out_current_buf_count != 0)
+ {
+ m_out_bPopulated = OMX_FALSE;
+ if (true == search_output_bufhdr(buffer))
+ {
+ /* Buffer exist */
+ //access only in IL client context
+ DEBUG_PRINT("Free_Buf:out_buffer[%p]\n",buffer);
+ m_output_buf_hdrs.erase(buffer);
+ free(buffer);
+ m_out_current_buf_count--;
+ } else
+ {
+ DEBUG_PRINT("Free_Buf:Error-->free_buffer , \
+ Invalid Output buffer header\n");
+ eRet = OMX_ErrorBadParameter;
+ }
+ } else
+ {
+ eRet = OMX_ErrorBadPortIndex;
+ }
+
+ if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
+ && release_done(1))
+ {
+ DEBUG_PRINT("OUTPUT PORT MOVING TO DISABLED STATE \n");
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
+ post_command(OMX_CommandPortDisable,
+ OMX_CORE_OUTPUT_PORT_INDEX,
+ OMX_COMPONENT_GENERATE_EVENT);
+
+ }
+ } else
+ {
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ if ((OMX_ErrorNone == eRet) &&
+ (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
+ {
+ if (release_done(-1))
+ {
+ if(ioctl(m_drv_fd, AUDIO_STOP, 0) < 0)
+ DEBUG_PRINT_ERROR("AUDIO STOP in free buffer failed\n");
+ else
+ DEBUG_PRINT("AUDIO STOP in free buffer passed\n");
+
+
+ DEBUG_PRINT("Free_Buf: Free buffer\n");
+
+
+ // Send the callback now
+ BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
+ DEBUG_PRINT("Before OMX_StateLoaded \
+ OMX_COMPONENT_GENERATE_EVENT\n");
+ post_command(OMX_CommandStateSet,
+ OMX_StateLoaded,OMX_COMPONENT_GENERATE_EVENT);
+ DEBUG_PRINT("After OMX_StateLoaded OMX_COMPONENT_GENERATE_EVENT\n");
+
+ }
+ }
+ return eRet;
+}
+
+
+/**
+ @brief member function that that handles empty this buffer command
+
+ This function meremly queue up the command and data would be consumed
+ in command server thread context
+
+ @param hComp handle to component instance
+ @param buffer pointer to buffer header
+ @return error status
+ */
+OMX_ERRORTYPE omx_evrc_aenc::empty_this_buffer(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+
+ DEBUG_PRINT("ETB:Buf:%p Len %u TS %lld numInBuf=%d\n", \
+ buffer, buffer->nFilledLen, buffer->nTimeStamp, (nNumInputBuf));
+ if (m_state == OMX_StateInvalid)
+ {
+ DEBUG_PRINT("Empty this buffer in Invalid State\n");
+ return OMX_ErrorInvalidState;
+ }
+ if (!m_inp_bEnabled)
+ {
+ DEBUG_PRINT("empty_this_buffer OMX_ErrorIncorrectStateOperation "\
+ "Port Status %d \n", m_inp_bEnabled);
+ return OMX_ErrorIncorrectStateOperation;
+ }
+ if (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))
+ {
+ DEBUG_PRINT("omx_evrc_aenc::etb--> Buffer Size Invalid\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (buffer->nVersion.nVersion != OMX_SPEC_VERSION)
+ {
+ DEBUG_PRINT("omx_evrc_aenc::etb--> OMX Version Invalid\n");
+ return OMX_ErrorVersionMismatch;
+ }
+
+ if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
+ {
+ return OMX_ErrorBadPortIndex;
+ }
+ if ((m_state != OMX_StateExecuting) &&
+ (m_state != OMX_StatePause))
+ {
+ DEBUG_PRINT_ERROR("Invalid state\n");
+ eRet = OMX_ErrorInvalidState;
+ }
+ if (OMX_ErrorNone == eRet)
+ {
+ if (search_input_bufhdr(buffer) == true)
+ {
+ post_input((unsigned long)hComp,
+ (unsigned long) buffer,OMX_COMPONENT_GENERATE_ETB);
+ } else
+ {
+ DEBUG_PRINT_ERROR("Bad header %p \n", buffer);
+ eRet = OMX_ErrorBadParameter;
+ }
+ }
+ pthread_mutex_lock(&in_buf_count_lock);
+ nNumInputBuf++;
+ m_evrc_pb_stats.etb_cnt++;
+ pthread_mutex_unlock(&in_buf_count_lock);
+ return eRet;
+}
+/**
+ @brief member function that writes data to kernel driver
+
+ @param hComp handle to component instance
+ @param buffer pointer to buffer header
+ @return error status
+ */
+OMX_ERRORTYPE omx_evrc_aenc::empty_this_buffer_proxy
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE* buffer)
+{
+ OMX_STATETYPE state;
+ META_IN meta_in;
+ //Pointer to the starting location of the data to be transcoded
+ OMX_U8 *srcStart;
+ //The total length of the data to be transcoded
+ srcStart = buffer->pBuffer;
+ OMX_U8 *data = NULL;
+ PrintFrameHdr(OMX_COMPONENT_GENERATE_ETB,buffer);
+ memset(&meta_in,0,sizeof(meta_in));
+ if ( search_input_bufhdr(buffer) == false )
+ {
+ DEBUG_PRINT("ETBP: INVALID BUF HDR\n");
+ buffer_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
+ return OMX_ErrorBadParameter;
+ }
+ if (m_tmp_meta_buf)
+ {
+ data = m_tmp_meta_buf;
+
+ // copy the metadata info from the BufHdr and insert to payload
+ meta_in.offsetVal = (OMX_U16)sizeof(META_IN);
+ meta_in.nTimeStamp.LowPart =
+ (unsigned int) ((((OMX_BUFFERHEADERTYPE*)buffer)->nTimeStamp) & 0xFFFFFFFF);
+ meta_in.nTimeStamp.HighPart =
+ (unsigned int) (((((OMX_BUFFERHEADERTYPE*)buffer)->nTimeStamp) >> 32) & 0xFFFFFFFF);
+ meta_in.nFlags &= ~OMX_BUFFERFLAG_EOS;
+ if(buffer->nFlags & OMX_BUFFERFLAG_EOS)
+ {
+ DEBUG_PRINT("EOS OCCURED \n");
+ meta_in.nFlags |= OMX_BUFFERFLAG_EOS;
+ }
+ memcpy(data,&meta_in, meta_in.offsetVal);
+ DEBUG_PRINT("meta_in.nFlags = %d\n",meta_in.nFlags);
+ }
+
+ memcpy(&data[sizeof(META_IN)],buffer->pBuffer,buffer->nFilledLen);
+ write(m_drv_fd, data, buffer->nFilledLen+sizeof(META_IN));
+
+ pthread_mutex_lock(&m_state_lock);
+ get_state(&m_cmp, &state);
+ pthread_mutex_unlock(&m_state_lock);
+
+ if (OMX_StateExecuting == state)
+ {
+ DEBUG_DETAIL("In Exe state, EBD CB");
+ buffer_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
+ } else
+ {
+ /* Assume empty this buffer function has already checked
+ validity of buffer */
+ DEBUG_PRINT("Empty buffer %p to kernel driver\n", buffer);
+ post_input((unsigned long) & hComp,(unsigned long) buffer,
+ OMX_COMPONENT_GENERATE_BUFFER_DONE);
+ }
+ return OMX_ErrorNone;
+}
+
+OMX_ERRORTYPE omx_evrc_aenc::fill_this_buffer_proxy
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_BUFFERHEADERTYPE* buffer)
+{
+ OMX_STATETYPE state;
+ ENC_META_OUT *meta_out = NULL;
+ ssize_t nReadbytes = 0;
+
+ pthread_mutex_lock(&m_state_lock);
+ get_state(&m_cmp, &state);
+ pthread_mutex_unlock(&m_state_lock);
+
+ if (true == search_output_bufhdr(buffer))
+ {
+ DEBUG_PRINT("\nBefore Read..m_drv_fd = %d,\n",m_drv_fd);
+ nReadbytes = read(m_drv_fd,buffer->pBuffer,output_buffer_size );
+ DEBUG_DETAIL("FTBP->Al_len[%lu]buf[%p]size[%d]numOutBuf[%d]\n",\
+ buffer->nAllocLen,buffer->pBuffer,
+ nReadbytes,nNumOutputBuf);
+ if (nReadbytes <= 0) {
+ buffer->nFilledLen = 0;
+ buffer->nOffset = 0;
+ buffer->nTimeStamp = nTimestamp;
+ frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
+ return OMX_ErrorNone;
+ } else
+ DEBUG_PRINT("Read bytes %d\n",nReadbytes);
+ // Buffer from Driver will have
+ // 1 byte => Nr of frame field
+ // (sizeof(ENC_META_OUT) * Nr of frame) bytes => meta_out->offset_to_frame
+ // Frame Size * Nr of frame =>
+
+ meta_out = (ENC_META_OUT *)(buffer->pBuffer + sizeof(unsigned char));
+ buffer->nTimeStamp = (((OMX_TICKS) meta_out->msw_ts << 32)+
+ meta_out->lsw_ts);
+ buffer->nFlags |= meta_out->nflags;
+ buffer->nOffset = (OMX_U32)(meta_out->offset_to_frame +
+ sizeof(unsigned char));
+ buffer->nFilledLen = (OMX_U32)(nReadbytes - buffer->nOffset);
+ nTimestamp = buffer->nTimeStamp;
+ DEBUG_PRINT("nflags %d frame_size %d offset_to_frame %d \
+ timestamp %lld\n", meta_out->nflags,
+ meta_out->frame_size, meta_out->offset_to_frame,
+ buffer->nTimeStamp);
+
+ if ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS )
+ {
+ buffer->nFilledLen = 0;
+ buffer->nOffset = 0;
+ buffer->nTimeStamp = nTimestamp;
+ frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
+ if ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS )
+ {
+ DEBUG_PRINT("FTBP: Now, Send EOS flag to Client \n");
+ m_cb.EventHandler(&m_cmp,
+ m_app_data,
+ OMX_EventBufferFlag,
+ 1, 1, NULL );
+ }
+
+ return OMX_ErrorNone;
+ }
+ DEBUG_PRINT("nState %d \n",nState );
+
+ pthread_mutex_lock(&m_state_lock);
+ get_state(&m_cmp, &state);
+ pthread_mutex_unlock(&m_state_lock);
+
+ if (state == OMX_StatePause)
+ {
+ DEBUG_PRINT("FTBP:Post the FBD to event thread currstate=%d\n",\
+ state);
+ post_output((unsigned long) & hComp,(unsigned long) buffer,
+ OMX_COMPONENT_GENERATE_FRAME_DONE);
+ }
+ else
+ {
+ frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
+
+ }
+
+ }
+ else
+ DEBUG_PRINT("\n FTBP-->Invalid buffer in FTB \n");
+
+
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::FillThisBuffer
+
+DESCRIPTION
+ IL client uses this method to release the frame buffer
+ after displaying them.
+
+
+
+PARAMETERS
+
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::fill_this_buffer
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_BUFFERHEADERTYPE* buffer)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ if (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))
+ {
+ DEBUG_PRINT("omx_evrc_aenc::ftb--> Buffer Size Invalid\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (m_out_bEnabled == OMX_FALSE)
+ {
+ return OMX_ErrorIncorrectStateOperation;
+ }
+
+ if (buffer->nVersion.nVersion != OMX_SPEC_VERSION)
+ {
+ DEBUG_PRINT("omx_evrc_aenc::ftb--> OMX Version Invalid\n");
+ return OMX_ErrorVersionMismatch;
+ }
+ if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
+ {
+ return OMX_ErrorBadPortIndex;
+ }
+ pthread_mutex_lock(&out_buf_count_lock);
+ nNumOutputBuf++;
+ m_evrc_pb_stats.ftb_cnt++;
+ DEBUG_DETAIL("FTB:nNumOutputBuf is %d", nNumOutputBuf);
+ pthread_mutex_unlock(&out_buf_count_lock);
+ post_output((unsigned long)hComp,
+ (unsigned long) buffer,OMX_COMPONENT_GENERATE_FTB);
+ return eRet;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::SetCallbacks
+
+DESCRIPTION
+ Set the callbacks.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_IN OMX_CALLBACKTYPE* callbacks,
+ OMX_IN OMX_PTR appData)
+{
+ if(hComp == NULL)
+ {
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ m_cb = *callbacks;
+ m_app_data = appData;
+
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::ComponentDeInit
+
+DESCRIPTION
+ Destroys the component and release memory allocated to the heap.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
+{
+ if(hComp == NULL)
+ {
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (OMX_StateLoaded != m_state && OMX_StateInvalid != m_state)
+ {
+ DEBUG_PRINT_ERROR("Warning: Rxed DeInit when not in LOADED state %d\n",
+ m_state);
+ }
+ deinit_encoder();
+
+DEBUG_PRINT_ERROR("%s:COMPONENT DEINIT...\n", __FUNCTION__);
+ return OMX_ErrorNone;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::deinit_encoder
+
+DESCRIPTION
+ Closes all the threads and release memory allocated to the heap.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ None.
+
+========================================================================== */
+void omx_evrc_aenc::deinit_encoder()
+{
+ DEBUG_PRINT("Component-deinit being processed\n");
+ DEBUG_PRINT("********************************\n");
+ DEBUG_PRINT("STATS: in-buf-len[%u]out-buf-len[%u] tot-pb-time[%lld]",\
+ m_evrc_pb_stats.tot_in_buf_len,
+ m_evrc_pb_stats.tot_out_buf_len,
+ m_evrc_pb_stats.tot_pb_time);
+ DEBUG_PRINT("STATS: fbd-cnt[%u]ftb-cnt[%u]etb-cnt[%u]ebd-cnt[%u]",\
+ m_evrc_pb_stats.fbd_cnt,m_evrc_pb_stats.ftb_cnt,
+ m_evrc_pb_stats.etb_cnt,
+ m_evrc_pb_stats.ebd_cnt);
+ memset(&m_evrc_pb_stats,0,sizeof(EVRC_PB_STATS));
+
+ if((OMX_StateLoaded != m_state) && (OMX_StateInvalid != m_state))
+ {
+ DEBUG_PRINT_ERROR("%s,Deinit called in state[%d]\n",__FUNCTION__,\
+ m_state);
+ // Get back any buffers from driver
+ if(pcm_input)
+ execute_omx_flush(-1,false);
+ else
+ execute_omx_flush(1,false);
+ // force state change to loaded so that all threads can be exited
+ pthread_mutex_lock(&m_state_lock);
+ m_state = OMX_StateLoaded;
+ pthread_mutex_unlock(&m_state_lock);
+ DEBUG_PRINT_ERROR("Freeing Buf:inp_current_buf_count[%d][%d]\n",\
+ m_inp_current_buf_count,
+ m_input_buf_hdrs.size());
+ m_input_buf_hdrs.eraseall();
+ DEBUG_PRINT_ERROR("Freeing Buf:out_current_buf_count[%d][%d]\n",\
+ m_out_current_buf_count,
+ m_output_buf_hdrs.size());
+ m_output_buf_hdrs.eraseall();
+
+ }
+ if(pcm_input)
+ {
+ pthread_mutex_lock(&m_in_th_lock_1);
+ if (is_in_th_sleep)
+ {
+ is_in_th_sleep = false;
+ DEBUG_DETAIL("Deinit:WAKING UP IN THREADS\n");
+ in_th_wakeup();
+ }
+ pthread_mutex_unlock(&m_in_th_lock_1);
+ }
+ pthread_mutex_lock(&m_out_th_lock_1);
+ if (is_out_th_sleep)
+ {
+ is_out_th_sleep = false;
+ DEBUG_DETAIL("SCP:WAKING UP OUT THREADS\n");
+ out_th_wakeup();
+ }
+ pthread_mutex_unlock(&m_out_th_lock_1);
+ if(pcm_input)
+ {
+ if (m_ipc_to_in_th != NULL)
+ {
+ omx_evrc_thread_stop(m_ipc_to_in_th);
+ m_ipc_to_in_th = NULL;
+ }
+ }
+
+ if (m_ipc_to_cmd_th != NULL)
+ {
+ omx_evrc_thread_stop(m_ipc_to_cmd_th);
+ m_ipc_to_cmd_th = NULL;
+ }
+ if (m_ipc_to_out_th != NULL)
+ {
+ DEBUG_DETAIL("Inside omx_evrc_thread_stop\n");
+ omx_evrc_thread_stop(m_ipc_to_out_th);
+ m_ipc_to_out_th = NULL;
+ }
+
+
+ if(ioctl(m_drv_fd, AUDIO_STOP, 0) <0)
+ DEBUG_PRINT_ERROR("De-init: AUDIO_STOP FAILED\n");
+
+ if(pcm_input && m_tmp_meta_buf )
+ {
+ free(m_tmp_meta_buf);
+ }
+
+ if(m_tmp_out_meta_buf)
+ {
+ free(m_tmp_out_meta_buf);
+ }
+ nNumInputBuf = 0;
+ nNumOutputBuf = 0;
+ bFlushinprogress = 0;
+
+ m_inp_current_buf_count=0;
+ m_out_current_buf_count=0;
+ m_out_act_buf_count = 0;
+ m_inp_act_buf_count = 0;
+ m_inp_bEnabled = OMX_FALSE;
+ m_out_bEnabled = OMX_FALSE;
+ m_inp_bPopulated = OMX_FALSE;
+ m_out_bPopulated = OMX_FALSE;
+
+ if ( m_drv_fd >= 0 )
+ {
+ if(close(m_drv_fd) < 0)
+ DEBUG_PRINT("De-init: Driver Close Failed \n");
+ m_drv_fd = -1;
+ }
+ else
+ {
+ DEBUG_PRINT_ERROR(" EVRC device already closed\n");
+ }
+ m_comp_deinit=1;
+ m_is_out_th_sleep = 1;
+ m_is_in_th_sleep = 1;
+ DEBUG_PRINT("************************************\n");
+ DEBUG_PRINT(" DEINIT COMPLETED");
+ DEBUG_PRINT("************************************\n");
+
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::UseEGLImage
+
+DESCRIPTION
+ OMX Use EGL Image method implementation <TBD>.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ Not Implemented error.
+
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::use_EGL_image
+(
+ OMX_IN OMX_HANDLETYPE hComp,
+ OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
+ OMX_IN OMX_U32 port,
+ OMX_IN OMX_PTR appData,
+ OMX_IN void* eglImage)
+{
+ DEBUG_PRINT_ERROR("Error : use_EGL_image: Not Implemented \n");
+
+ if((hComp == NULL) || (appData == NULL) || (eglImage == NULL))
+ {
+ bufferHdr = bufferHdr;
+ port = port;
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ return OMX_ErrorNotImplemented;
+}
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::ComponentRoleEnum
+
+DESCRIPTION
+ OMX Component Role Enum method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything is successful.
+========================================================================== */
+OMX_ERRORTYPE omx_evrc_aenc::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
+ OMX_OUT OMX_U8* role,
+ OMX_IN OMX_U32 index)
+{
+ OMX_ERRORTYPE eRet = OMX_ErrorNone;
+ const char *cmp_role = "audio_encoder.evrc";
+
+ if(hComp == NULL)
+ {
+ DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (index == 0 && role)
+ {
+ memcpy(role, cmp_role, strlen(cmp_role));
+ *(((char *) role) + strlen(cmp_role) + 1) = '\0';
+ } else
+ {
+ eRet = OMX_ErrorNoMore;
+ }
+ return eRet;
+}
+
+
+
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::AllocateDone
+
+DESCRIPTION
+ Checks if entire buffer pool is allocated by IL Client or not.
+ Need this to move to IDLE state.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false.
+
+========================================================================== */
+bool omx_evrc_aenc::allocate_done(void)
+{
+ OMX_BOOL bRet = OMX_FALSE;
+ if (pcm_input==1)
+ {
+ if ((m_inp_act_buf_count == m_inp_current_buf_count)
+ &&(m_out_act_buf_count == m_out_current_buf_count))
+ {
+ bRet=OMX_TRUE;
+
+ }
+ if ((m_inp_act_buf_count == m_inp_current_buf_count) && m_inp_bEnabled )
+ {
+ m_inp_bPopulated = OMX_TRUE;
+ }
+
+ if ((m_out_act_buf_count == m_out_current_buf_count) && m_out_bEnabled )
+ {
+ m_out_bPopulated = OMX_TRUE;
+ }
+ } else if (pcm_input==0)
+ {
+ if (m_out_act_buf_count == m_out_current_buf_count)
+ {
+ bRet=OMX_TRUE;
+
+ }
+ if ((m_out_act_buf_count == m_out_current_buf_count) && m_out_bEnabled )
+ {
+ m_out_bPopulated = OMX_TRUE;
+ }
+
+ }
+ return bRet;
+}
+
+
+/* ======================================================================
+FUNCTION
+ omx_evrc_aenc::ReleaseDone
+
+DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_evrc_aenc::release_done(OMX_U32 param1)
+{
+ DEBUG_PRINT("Inside omx_evrc_aenc::release_done");
+ OMX_BOOL bRet = OMX_FALSE;
+
+ if (param1 == OMX_ALL)
+ {
+ if ((0 == m_inp_current_buf_count)&&(0 == m_out_current_buf_count))
+ {
+ bRet=OMX_TRUE;
+ }
+ } else if (param1 == OMX_CORE_INPUT_PORT_INDEX )
+ {
+ if ((0 == m_inp_current_buf_count))
+ {
+ bRet=OMX_TRUE;
+ }
+ } else if (param1 == OMX_CORE_OUTPUT_PORT_INDEX)
+ {
+ if ((0 == m_out_current_buf_count))
+ {
+ bRet=OMX_TRUE;
+ }
+ }
+ return bRet;
+}
diff --git a/msm8909/mm-audio/aenc-evrc/qdsp6/test/omx_evrc_enc_test.c b/msm8909/mm-audio/aenc-evrc/qdsp6/test/omx_evrc_enc_test.c
new file mode 100644
index 00000000..63d953bd
--- /dev/null
+++ b/msm8909/mm-audio/aenc-evrc/qdsp6/test/omx_evrc_enc_test.c
@@ -0,0 +1,1098 @@
+
+/*--------------------------------------------------------------------------
+Copyright (c) 2010-2014, 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;
+/**************************************************************************/
+/* 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();
+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];
+ 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)atoi(argv[8]);
+
+ } 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);
+ error_code = -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;
+}