summaryrefslogtreecommitdiff
path: root/audio/mm-audio/aenc-amrnb/qdsp6/src/omx_amr_aenc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'audio/mm-audio/aenc-amrnb/qdsp6/src/omx_amr_aenc.cpp')
-rw-r--r--audio/mm-audio/aenc-amrnb/qdsp6/src/omx_amr_aenc.cpp4532
1 files changed, 4532 insertions, 0 deletions
diff --git a/audio/mm-audio/aenc-amrnb/qdsp6/src/omx_amr_aenc.cpp b/audio/mm-audio/aenc-amrnb/qdsp6/src/omx_amr_aenc.cpp
new file mode 100644
index 0000000..5e9ee4e
--- /dev/null
+++ b/audio/mm-audio/aenc-amrnb/qdsp6/src/omx_amr_aenc.cpp
@@ -0,0 +1,4532 @@
+/*--------------------------------------------------------------------------
+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_amr.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_amr_aenc.h"
+#include <errno.h>
+
+using namespace std;
+#define SLEEP_MS 100
+
+// omx_cmd_queue destructor
+omx_amr_aenc::omx_cmd_queue::~omx_cmd_queue()
+{
+ // Nothing to do
+}
+
+// omx cmd queue constructor
+omx_amr_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_amr_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_amr_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_amr_aenc);
+}
+bool omx_amr_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_amr_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_amr_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 amr object
+void omx_amr_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_amr_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_amr_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_amr_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_amr_aenc::omx_amr_aenc
+
+DESCRIPTION
+ Constructor
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+omx_amr_aenc::omx_amr_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),
+ ts(0),
+ pcm_input(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_AMR_OUTPUT_BUFFER_SIZE),
+ input_buffer_size(OMX_CORE_INPUT_BUFFER_SIZE),
+ m_session_id(0),
+ 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;
+ component_Role.nSize = 0;
+ memset(&m_cmp, 0, sizeof(m_cmp));
+ memset(&m_cb, 0, sizeof(m_cb));
+ memset(&m_pcm_param, 0, sizeof(m_pcm_param));
+ memset(&m_amr_param, 0, sizeof(m_amr_param));
+ memset(&m_amr_pb_stats, 0, sizeof(m_amr_pb_stats));
+ memset(&m_buffer_supplier, 0, sizeof(m_buffer_supplier));
+ 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_amr_aenc::~omx_amr_aenc
+
+DESCRIPTION
+ Destructor
+
+PARAMETERS
+ None
+
+RETURN VALUE
+ None.
+========================================================================== */
+omx_amr_aenc::~omx_amr_aenc()
+{
+ DEBUG_PRINT_ERROR("AMR 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 AMR 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_amr_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_amr_pb_stats.ebd_cnt++;
+ nNumInputBuf--;
+ DEBUG_DETAIL("EBD CB:: in_buf_len=%d nNumInputBuf=%d ebd_cnt=%d\n",\
+ m_amr_pb_stats.tot_in_buf_len,
+ nNumInputBuf, m_amr_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_amr_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_amr_aenc::frame_done_cb(OMX_BUFFERHEADERTYPE *bufHdr)
+{
+ if (m_cb.FillBufferDone)
+ {
+ PrintFrameHdr(OMX_COMPONENT_GENERATE_FRAME_DONE,bufHdr);
+ m_amr_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_amr_pb_stats.tot_out_buf_len,
+ m_amr_pb_stats.fbd_cnt);
+ m_amr_pb_stats.tot_out_buf_len += bufHdr->nFilledLen;
+ m_amr_pb_stats.tot_pb_time = bufHdr->nTimeStamp;
+ DEBUG_PRINT("FBD:in_buf_len=%u out_buf_len=%u\n",
+ m_amr_pb_stats.tot_in_buf_len,
+ m_amr_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_amr_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_amr_aenc *pThis = (omx_amr_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_amr_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_amr_aenc *pThis = (omx_amr_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_amr_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_amr_aenc *pThis = (omx_amr_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[%d]\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_amr_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_amr_param, 0, sizeof(m_amr_param));
+ m_amr_param.nSize = (OMX_U32)sizeof(m_amr_param);
+ m_amr_param.nChannels = OMX_AMR_DEFAULT_CH_CFG;
+ m_volume = OMX_AMR_DEFAULT_VOL; /* Close to unity gain */
+ memset(&m_amr_pb_stats,0,sizeof(AMR_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_AMR_DEFAULT_CH_CFG;
+ m_pcm_param.nSamplingRate = OMX_AMR_DEFAULT_SF;
+ nTimestamp = 0;
+ ts = 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.amrnb"))
+ {
+ 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.amrnb"))
+ {
+ 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 tmp meta buf\n");
+ return OMX_ErrorInsufficientResources;
+ }
+ }
+ m_tmp_out_meta_buf =
+ (OMX_U8*)malloc(sizeof(OMX_U8)*OMX_AMR_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_amrnb_in",O_RDONLY);
+ DEBUG_PRINT("Driver in Tunnel mode open\n");
+ }
+ else
+ {
+ m_drv_fd = open("/dev/msm_amrnb_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_amr_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_amr_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_amr_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_amr_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_amr_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_amr_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;
+ ts = 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_amrnb_enc_config_v2 drv_amr_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_AMRNB_ENC_CONFIG_V2,
+ &drv_amr_enc_config) == -1)
+ {
+ DEBUG_PRINT_ERROR("ioctl AUDIO_GET_AMRNB_ENC_CONFIG_V2 \
+ failed, errno[%d]\n", errno);
+ }
+ drv_amr_enc_config.band_mode = m_amr_param.eAMRBandMode;
+ drv_amr_enc_config.dtx_enable = m_amr_param.eAMRDTXMode;
+ drv_amr_enc_config.frame_format = m_amr_param.eAMRFrameFormat;
+ if(ioctl(m_drv_fd, AUDIO_SET_AMRNB_ENC_CONFIG_V2, &drv_amr_enc_config)
+ == -1)
+ {
+ DEBUG_PRINT_ERROR("ioctl AUDIO_SET_AMRNB_ENC_CONFIG_V2 \
+ 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_amr_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_amr_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_amr_aenc::execute_output_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 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_amr_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_amr_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_amr_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_amr_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_amr_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_amr_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_amr_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_CodingAMR;
+ 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_CodingAMR;
+ } else
+ {
+ DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
+ (int)portFormatType->nPortIndex);
+ eRet = OMX_ErrorBadPortIndex;
+ }
+ break;
+ }
+
+ case OMX_IndexParamAudioAmr:
+ {
+ OMX_AUDIO_PARAM_AMRTYPE *amrParam =
+ (OMX_AUDIO_PARAM_AMRTYPE *) paramData;
+ DEBUG_PRINT("OMX_IndexParamAudioAmr\n");
+ if (OMX_CORE_OUTPUT_PORT_INDEX== amrParam->nPortIndex)
+ {
+ memcpy(amrParam,&m_amr_param,
+ sizeof(OMX_AUDIO_PARAM_AMRTYPE));
+ } else
+ {
+ DEBUG_PRINT_ERROR("get_parameter:OMX_IndexParamAudioAmr "\
+ "OMX_ErrorBadPortIndex %d\n", \
+ (int)amrParam->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_amr_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_IndexParamAudioAmr:
+ {
+ DEBUG_PRINT("OMX_IndexParamAudioAmr");
+ OMX_AUDIO_PARAM_AMRTYPE *amrparam
+ = (OMX_AUDIO_PARAM_AMRTYPE *) paramData;
+ memcpy(&m_amr_param,amrparam,
+ sizeof(OMX_AUDIO_PARAM_AMRTYPE));
+ 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_CodingAMR;
+ } 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_amr_aenc::GetConfig
+
+DESCRIPTION
+ OMX Get Config Method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_amr_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_amr_aenc::SetConfig
+
+DESCRIPTION
+ OMX Set Config method implementation
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if successful.
+========================================================================== */
+OMX_ERRORTYPE omx_amr_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_amr_aenc::GetExtensionIndex
+
+DESCRIPTION
+ OMX GetExtensionIndex method implementaion. <TBD>
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_amr_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_amr_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_amr_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_amr_aenc::ComponentTunnelRequest
+
+DESCRIPTION
+ OMX Component Tunnel Request method implementation. <TBD>
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_amr_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_amr_aenc::AllocateInputBuffer
+
+DESCRIPTION
+ Helper function for allocate buffer in the input pin
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_amr_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=%d \
+ 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_amr_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_amr_aenc::AllocateBuffer
+
+DESCRIPTION
+ Returns zero if all the buffers released..
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+OMX_ERRORTYPE omx_amr_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_amr_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_amr_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_amr_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_amr_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", 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_amr_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_amr_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_amr_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_amr_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_amr_aenc::etb--> Buffer Size Invalid\n");
+ return OMX_ErrorBadParameter;
+ }
+ if (buffer->nVersion.nVersion != OMX_SPEC_VERSION)
+ {
+ DEBUG_PRINT("omx_amr_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_amr_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_amr_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_amr_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);
+ ts += FRAMEDURATION;
+ buffer->nTimeStamp = ts;
+ 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_amr_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_amr_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_amr_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_amr_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_amr_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_amr_aenc::SetCallbacks
+
+DESCRIPTION
+ Set the callbacks.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ OMX Error None if everything successful.
+
+========================================================================== */
+OMX_ERRORTYPE omx_amr_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_amr_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_amr_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_amr_aenc::deinit_encoder
+
+DESCRIPTION
+ Closes all the threads and release memory allocated to the heap.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ None.
+
+========================================================================== */
+void omx_amr_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_amr_pb_stats.tot_in_buf_len,
+ m_amr_pb_stats.tot_out_buf_len,
+ m_amr_pb_stats.tot_pb_time);
+ DEBUG_PRINT("STATS: fbd-cnt[%u]ftb-cnt[%u]etb-cnt[%u]ebd-cnt[%u]",\
+ m_amr_pb_stats.fbd_cnt,m_amr_pb_stats.ftb_cnt,
+ m_amr_pb_stats.etb_cnt,
+ m_amr_pb_stats.ebd_cnt);
+ memset(&m_amr_pb_stats,0,sizeof(AMR_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_amr_thread_stop(m_ipc_to_in_th);
+ m_ipc_to_in_th = NULL;
+ }
+ }
+
+ if (m_ipc_to_cmd_th != NULL)
+ {
+ omx_amr_thread_stop(m_ipc_to_cmd_th);
+ m_ipc_to_cmd_th = NULL;
+ }
+ if (m_ipc_to_out_th != NULL)
+ {
+ DEBUG_DETAIL("Inside omx_amr_thread_stop\n");
+ omx_amr_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;
+ nTimestamp = 0;
+ ts = 0;
+
+ 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(" AMR 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_amr_aenc::UseEGLImage
+
+DESCRIPTION
+ OMX Use EGL Image method implementation <TBD>.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ Not Implemented error.
+
+========================================================================== */
+OMX_ERRORTYPE omx_amr_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_amr_aenc::ComponentRoleEnum
+
+DESCRIPTION
+ OMX Component Role Enum method implementation.
+
+PARAMETERS
+ <TBD>.
+
+RETURN VALUE
+ OMX Error None if everything is successful.
+========================================================================== */
+OMX_ERRORTYPE omx_amr_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.amr";
+
+ 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_amr_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_amr_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_amr_aenc::ReleaseDone
+
+DESCRIPTION
+ Checks if IL client has released all the buffers.
+
+PARAMETERS
+ None.
+
+RETURN VALUE
+ true/false
+
+========================================================================== */
+bool omx_amr_aenc::release_done(OMX_U32 param1)
+{
+ DEBUG_PRINT("Inside omx_amr_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;
+}