audio : Add g711 omx component for encoding

-Add G711 omx component and omx test app
  for encoding

Change-Id: Idcef6db3af50195c7c701219d38b4032e0347627
This commit is contained in:
Arun Kumar Dasari 2016-03-10 17:59:29 +05:30 committed by Gerrit - the friendly Code Review server
parent 2bc67c81f3
commit 882636a0f7
12 changed files with 6986 additions and 0 deletions

View File

@ -0,0 +1,7 @@
ifneq ($(filter arm aarch64 arm64, $(TARGET_ARCH)),)
AENC_G7111_PATH:= $(call my-dir)
include $(AENC_G7111_PATH)/qdsp6/Android.mk
endif

View File

@ -0,0 +1,6 @@
all:
@echo "invoking omxaudio make"
$(MAKE) -C qdsp6
install:
$(MAKE) -C qdsp6 install

View File

@ -0,0 +1,72 @@
ifneq ($(BUILD_TINY_ANDROID),true)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
# ---------------------------------------------------------------------------------
# Common definitons
# ---------------------------------------------------------------------------------
libOmxG711Enc-def := -g -O3
libOmxG711Enc-def += -DQC_MODIFIED
libOmxG711Enc-def += -D_ANDROID_
libOmxG711Enc-def += -D_ENABLE_QC_MSG_LOG_
libOmxG711Enc-def += -DVERBOSE
libOmxG711Enc-def += -D_DEBUG
libOmxG711Enc-def += -Wconversion
libOmxG711Enc-def += -DAUDIOV2
# ---------------------------------------------------------------------------------
# Make the Shared library (libOmxG711Enc)
# ---------------------------------------------------------------------------------
include $(CLEAR_VARS)
libOmxG711Enc-inc := $(LOCAL_PATH)/inc
libOmxG711Enc-inc += $(TARGET_OUT_HEADERS)/mm-core/omxcore
LOCAL_MODULE := libOmxG711Enc
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := $(libOmxG711Enc-def)
LOCAL_C_INCLUDES := $(libOmxG711Enc-inc)
LOCAL_PRELINK_MODULE := false
LOCAL_SHARED_LIBRARIES := libutils liblog libcutils
LOCAL_SRC_FILES := src/aenc_svr.c
LOCAL_SRC_FILES += src/omx_g711_aenc.cpp
LOCAL_SRC_FILES += src/omx_log.cpp
LOCAL_C_INCLUDES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
LOCAL_ADDITIONAL_DEPENDENCIES += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
include $(BUILD_SHARED_LIBRARY)
# ---------------------------------------------------------------------------------
# Make the apps-test (mm-aenc-omxg711-test)
# ---------------------------------------------------------------------------------
include $(CLEAR_VARS)
mm-g711-enc-test-inc := $(LOCAL_PATH)/inc
mm-g711-enc-test-inc += $(LOCAL_PATH)/test
mm-g711-enc-test-inc += $(TARGET_OUT_HEADERS)/mm-core/omxcore
LOCAL_MODULE := mm-aenc-omxg711-test
LOCAL_MODULE_TAGS := optional
LOCAL_CFLAGS := $(libOmxG711Enc-def)
LOCAL_C_INCLUDES := $(mm-g711-enc-test-inc)
LOCAL_PRELINK_MODULE := false
LOCAL_SHARED_LIBRARIES := libmm-omxcore
LOCAL_SHARED_LIBRARIES += libOmxG711Enc
LOCAL_SRC_FILES := test/omx_g711_enc_test.c
include $(BUILD_EXECUTABLE)
endif
# ---------------------------------------------------------------------------------
# END
# ---------------------------------------------------------------------------------

View File

@ -0,0 +1,81 @@
# ---------------------------------------------------------------------------------
# MM-AUDIO-OSS-8K-AENC-G7111
# ---------------------------------------------------------------------------------
# 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: libOmxG711Enc.so.$(LIBVER) mm-aenc-omxg711-test
install:
echo "intalling aenc-g711 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 libOmxG711Enc.so.$(LIBVER) $(LIBINSTALLDIR)
cd $(LIBINSTALLDIR) && ln -s libOmxG711Enc.so.$(LIBVER) libOmxG711Enc.so.$(LIBMAJOR)
cd $(LIBINSTALLDIR) && ln -s libOmxG711Enc.so.$(LIBMAJOR) libOmxG711Enc.so
install -m 555 mm-aenc-omxg711-test $(BININSTALLDIR)
# ---------------------------------------------------------------------------------
# COMPILE LIBRARY
# ---------------------------------------------------------------------------------
LDLIBS := -lpthread
LDLIBS += -lstdc++
LDLIBS += -lOmxCore
SRCS := src/omx_g711_aenc.cpp
SRCS += src/aenc_svr.c
libOmxG711Enc.so.$(LIBVER): $(SRCS)
$(CC) $(CPPFLAGS) $(CFLAGS_SO) $(LDFLAGS_SO) -Wl,-soname,libOmxG711Enc.so.$(LIBMAJOR) -o $@ $^ $(LDFLAGS) $(LDLIBS)
# ---------------------------------------------------------------------------------
# COMPILE TEST APP
# ---------------------------------------------------------------------------------
TEST_LDLIBS := -lpthread
TEST_LDLIBS += -ldl
TEST_LDLIBS += -lOmxCore
#TEST_SRCS := test/omx_g711_enc_test.c
mm-aenc-omxg711-test: libOmxG711Enc.so.$(LIBVER) $(TEST_SRCS)
$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) -o $@ $^ $(TEST_LDLIBS)
# ---------------------------------------------------------------------------------
# END
# ---------------------------------------------------------------------------------

View File

@ -0,0 +1,245 @@
/*--------------------------------------------------------------------------
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 "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_

View File

@ -0,0 +1,121 @@
/*--------------------------------------------------------------------------
Copyright (c) 2010, 2016, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/
#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_G711ENC"
#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 g711_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 g711_ipc_info *omx_g711_thread_create(message_func cb,
void* client_data,
char *th_name);
struct g711_ipc_info *omx_g711_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_g711_thread_stop(struct g711_ipc_info *g711_ipc);
/**
@brief This function post message in the command server
@param svr handle to command server
@return none
*/
void omx_g711_post_msg(struct g711_ipc_info *g711_ipc,
unsigned char id);
#ifdef __cplusplus
}
#endif
#endif /* AENC_SVR */

View File

@ -0,0 +1,539 @@
/*--------------------------------------------------------------------------
Copyright (c) 2010, 2014, 2016 The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/
#ifndef _G711_ENC_H_
#define _G711_ENC_H_
/*============================================================================
Audio Encoder
@file omx_g711_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_g711.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 4
#define OMX_CORE_NUM_OUTPUT_BUFFERS 8
#define OMX_CORE_INPUT_BUFFER_SIZE 4096 // 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_G711_DEFAULT_SF 8000
#define OMX_G711_DEFAULT_CH_CFG 1
#define OMX_G711_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 360
#define OMX_G711_OUTPUT_BUFFER_SIZE ((NUMOFFRAMES * (sizeof(ENC_META_OUT) + MAXFRAMELENGTH) \
+ 1))
class omx_g711_aenc;
// OMX mo3 audio encoder class
class omx_g711_aenc: public qc_omx_component
{
public:
omx_g711_aenc(); // constructor
virtual ~omx_g711_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 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 lsw_ts;
unsigned int msw_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;
}G711_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;
bool is_mlaw;
// 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
G711_PB_STATS m_g711_pb_stats;
struct g711_ipc_info *m_ipc_to_in_th; // for input thread
struct g711_ipc_info *m_ipc_to_out_th; // for output thread
struct g711_ipc_info *m_ipc_to_cmd_th; // for command thread
struct g711_ipc_info *m_ipc_to_event_th; //for txco event thread
OMX_PRIORITYMGMTTYPE m_priority_mgm ;
OMX_AUDIO_PARAM_PCMMODETYPE m_g711_param; // Cache G711 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_g711_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

View File

@ -0,0 +1,61 @@
/*--------------------------------------------------------------------------
Copyright (c) 2016, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/
#ifndef OMX_LOGS_H
#define OMX_LOGS_H
#include <inttypes.h>
using namespace std;
/*
* Change logging-level at runtime with "persist.debug.omx.logs.level"
*
* level OMX_LOGV OMX_LOGD
* ----------------------------------
* 0 silent silent
* 1 silent printed
* 2 printed printed
*
* AVLOGI/W/E are printed always
*/
extern uint32_t gOmxLogLevel;
#define OMX_LOGV(format, args...) ALOGD_IF((gOmxLogLevel > 1), format, ##args)
#define OMX_LOGD(format, args...) ALOGD_IF((gOmxLogLevel > 0), format, ##args)
#define OMX_LOGI(format, args...) ALOGI(format, ##args)
#define OMX_LOGW(format, args...) ALOGW(format, ##args)
#define OMX_LOGE(format, args...) ALOGE(format, ##args)
void updateLogLevel();
#endif // OMX_LOGS_H

View File

@ -0,0 +1,206 @@
/*--------------------------------------------------------------------------
Copyright (c) 2010, 2016 The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/
#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_g711_msg(void *info)
{
struct g711_ipc_info *g711_info = (struct g711_ipc_info*)info;
unsigned char id;
ssize_t n;
DEBUG_DETAIL("\n%s: message thread start\n", __FUNCTION__);
while (!g711_info->dead)
{
n = read(g711_info->pipe_in, &id, 1);
if (0 == n) break;
if (1 == n)
{
DEBUG_DETAIL("\n%s-->pipe_in=%d pipe_out=%d\n",
g711_info->thread_name,
g711_info->pipe_in,
g711_info->pipe_out);
g711_info->process_msg_cb(g711_info->client_data, id);
}
if ((n < 0) && (errno != EINTR)) break;
}
DEBUG_DETAIL("%s: message thread stop\n", __FUNCTION__);
return 0;
}
void *omx_g711_events(void *info)
{
struct g711_ipc_info *g711_info = (struct g711_ipc_info*)info;
unsigned char id = 0;
DEBUG_DETAIL("%s: message thread start\n", g711_info->thread_name);
g711_info->process_msg_cb(g711_info->client_data, id);
DEBUG_DETAIL("%s: message thread stop\n", g711_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 g711_ipc_info *omx_g711_thread_create(
message_func cb,
void* client_data,
char* th_name)
{
int r;
int fds[2];
struct g711_ipc_info *g711_info;
g711_info = calloc(1, sizeof(struct g711_ipc_info));
if (!g711_info)
{
return 0;
}
g711_info->client_data = client_data;
g711_info->process_msg_cb = cb;
strlcpy(g711_info->thread_name, th_name, sizeof(g711_info->thread_name));
if (pipe(fds))
{
DEBUG_PRINT_ERROR("\n%s: pipe creation failed\n", __FUNCTION__);
goto fail_pipe;
}
g711_info->pipe_in = fds[0];
g711_info->pipe_out = fds[1];
r = pthread_create(&g711_info->thr, 0, omx_g711_msg, g711_info);
if (r < 0) goto fail_thread;
DEBUG_DETAIL("Created thread for %s \n", g711_info->thread_name);
return g711_info;
fail_thread:
close(g711_info->pipe_in);
close(g711_info->pipe_out);
fail_pipe:
free(g711_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 g711_ipc_info *omx_g711_event_thread_create(
message_func cb,
void* client_data,
char* th_name)
{
int r;
int fds[2];
struct g711_ipc_info *g711_info;
g711_info = calloc(1, sizeof(struct g711_ipc_info));
if (!g711_info)
{
return 0;
}
g711_info->client_data = client_data;
g711_info->process_msg_cb = cb;
strlcpy(g711_info->thread_name, th_name, sizeof(g711_info->thread_name));
if (pipe(fds))
{
DEBUG_PRINT("\n%s: pipe creation failed\n", __FUNCTION__);
goto fail_pipe;
}
g711_info->pipe_in = fds[0];
g711_info->pipe_out = fds[1];
r = pthread_create(&g711_info->thr, 0, omx_g711_events, g711_info);
if (r < 0) goto fail_thread;
DEBUG_DETAIL("Created thread for %s \n", g711_info->thread_name);
return g711_info;
fail_thread:
close(g711_info->pipe_in);
close(g711_info->pipe_out);
fail_pipe:
free(g711_info);
return 0;
}
void omx_g711_thread_stop(struct g711_ipc_info *g711_info) {
DEBUG_DETAIL("%s stop server\n", __FUNCTION__);
close(g711_info->pipe_in);
close(g711_info->pipe_out);
pthread_join(g711_info->thr,NULL);
g711_info->pipe_out = -1;
g711_info->pipe_in = -1;
DEBUG_DETAIL("%s: message thread close fds%d %d\n", g711_info->thread_name,
g711_info->pipe_in,g711_info->pipe_out);
free(g711_info);
}
void omx_g711_post_msg(struct g711_ipc_info *g711_info, unsigned char id) {
DEBUG_DETAIL("\n%s id=%d\n", __FUNCTION__,id);
write(g711_info->pipe_out, &id, 1);
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
/*--------------------------------------------------------------------------
Copyright (c) 2016 The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------*/
#include <stdlib.h>
#include <utils/Log.h>
#include <cutils/properties.h>
#include "omx_log.h"
using namespace std;
uint32_t gOmxLogLevel;
void updateLogLevel() {
char level[PROPERTY_VALUE_MAX];
#ifdef ANDROID
property_get("persist.debug.omx.logs.level", level, "0");
gOmxLogLevel = atoi(level);
#else
gOmxLogLevel = atoi("0");
#endif
}

File diff suppressed because it is too large Load Diff