| /*-------------------------------------------------------------------------- |
| Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved. |
| |
| Redistribution and use in source and binary forms, with or without |
| modification, are permitted provided that the following conditions are met: |
| * Redistributions of source code must retain the above copyright |
| notice, this list of conditions and the following disclaimer. |
| * Redistributions in binary form must reproduce the above copyright |
| notice, this list of conditions and the following disclaimer in the |
| documentation and/or other materials provided with the distribution. |
| * Neither the name of The Linux Foundation nor |
| the names of its contributors may be used to endorse or promote |
| products derived from this software without specific prior written |
| permission. |
| |
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
| NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
| CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
| OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
| WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
| ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| --------------------------------------------------------------------------*/ |
| /*============================================================================ |
| @file omx_aenc_evrc.c |
| This module contains the implementation of the OpenMAX core & component. |
| |
| *//*========================================================================*/ |
| ////////////////////////////////////////////////////////////////////////////// |
| // Include Files |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| |
| #include<string.h> |
| #include <fcntl.h> |
| #include <sys/ioctl.h> |
| #include "omx_evrc_aenc.h" |
| #include <errno.h> |
| |
| using namespace std; |
| #define SLEEP_MS 100 |
| |
| // omx_cmd_queue destructor |
| omx_evrc_aenc::omx_cmd_queue::~omx_cmd_queue() |
| { |
| // Nothing to do |
| } |
| |
| // omx cmd queue constructor |
| omx_evrc_aenc::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) |
| { |
| memset(m_q, 0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); |
| } |
| |
| // omx cmd queue insert |
| bool omx_evrc_aenc::omx_cmd_queue::insert_entry(unsigned long p1, |
| unsigned long p2, |
| unsigned char id) |
| { |
| bool ret = true; |
| if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) |
| { |
| m_q[m_write].id = id; |
| m_q[m_write].param1 = p1; |
| m_q[m_write].param2 = p2; |
| m_write++; |
| m_size ++; |
| if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) |
| { |
| m_write = 0; |
| } |
| } else |
| { |
| ret = false; |
| DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full"); |
| } |
| return ret; |
| } |
| |
| bool omx_evrc_aenc::omx_cmd_queue::pop_entry(unsigned long *p1, |
| unsigned long *p2, unsigned char *id) |
| { |
| bool ret = true; |
| if (m_size > 0) |
| { |
| *id = m_q[m_read].id; |
| *p1 = m_q[m_read].param1; |
| *p2 = m_q[m_read].param2; |
| // Move the read pointer ahead |
| ++m_read; |
| --m_size; |
| if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) |
| { |
| m_read = 0; |
| |
| } |
| } else |
| { |
| ret = false; |
| DEBUG_PRINT_ERROR("ERROR Delete!!! Command Queue Empty"); |
| } |
| return ret; |
| } |
| |
| // factory function executed by the core to create instances |
| void *get_omx_component_factory_fn(void) |
| { |
| return(new omx_evrc_aenc); |
| } |
| bool omx_evrc_aenc::omx_cmd_queue::get_msg_id(unsigned char *id) |
| { |
| if(m_size > 0) |
| { |
| *id = m_q[m_read].id; |
| DEBUG_PRINT("get_msg_id=%d\n",*id); |
| } |
| else{ |
| return false; |
| } |
| return true; |
| } |
| /*============================================================================= |
| FUNCTION: |
| wait_for_event |
| |
| DESCRIPTION: |
| waits for a particular event |
| |
| INPUT/OUTPUT PARAMETERS: |
| None |
| |
| RETURN VALUE: |
| None |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| void omx_evrc_aenc::wait_for_event() |
| { |
| int rc; |
| struct timespec ts; |
| pthread_mutex_lock(&m_event_lock); |
| while (0 == m_is_event_done) |
| { |
| clock_gettime(CLOCK_REALTIME, &ts); |
| ts.tv_sec += (SLEEP_MS/1000); |
| ts.tv_nsec += ((SLEEP_MS%1000) * 1000000); |
| rc = pthread_cond_timedwait(&cond, &m_event_lock, &ts); |
| if (rc == ETIMEDOUT && !m_is_event_done) { |
| DEBUG_PRINT("Timed out waiting for flush"); |
| if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) == -1) |
| DEBUG_PRINT_ERROR("Flush:Input port, ioctl flush failed %d\n", |
| errno); |
| } |
| } |
| m_is_event_done = 0; |
| pthread_mutex_unlock(&m_event_lock); |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| event_complete |
| |
| DESCRIPTION: |
| informs about the occurance of an event |
| |
| INPUT/OUTPUT PARAMETERS: |
| None |
| |
| RETURN VALUE: |
| None |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| void omx_evrc_aenc::event_complete() |
| { |
| pthread_mutex_lock(&m_event_lock); |
| if (0 == m_is_event_done) |
| { |
| m_is_event_done = 1; |
| pthread_cond_signal(&cond); |
| } |
| pthread_mutex_unlock(&m_event_lock); |
| } |
| |
| // All this non-sense because of a single evrc object |
| void omx_evrc_aenc::in_th_goto_sleep() |
| { |
| pthread_mutex_lock(&m_in_th_lock); |
| while (0 == m_is_in_th_sleep) |
| { |
| pthread_cond_wait(&in_cond, &m_in_th_lock); |
| } |
| m_is_in_th_sleep = 0; |
| pthread_mutex_unlock(&m_in_th_lock); |
| } |
| |
| void omx_evrc_aenc::in_th_wakeup() |
| { |
| pthread_mutex_lock(&m_in_th_lock); |
| if (0 == m_is_in_th_sleep) |
| { |
| m_is_in_th_sleep = 1; |
| pthread_cond_signal(&in_cond); |
| } |
| pthread_mutex_unlock(&m_in_th_lock); |
| } |
| |
| void omx_evrc_aenc::out_th_goto_sleep() |
| { |
| |
| pthread_mutex_lock(&m_out_th_lock); |
| while (0 == m_is_out_th_sleep) |
| { |
| pthread_cond_wait(&out_cond, &m_out_th_lock); |
| } |
| m_is_out_th_sleep = 0; |
| pthread_mutex_unlock(&m_out_th_lock); |
| } |
| |
| void omx_evrc_aenc::out_th_wakeup() |
| { |
| pthread_mutex_lock(&m_out_th_lock); |
| if (0 == m_is_out_th_sleep) |
| { |
| m_is_out_th_sleep = 1; |
| pthread_cond_signal(&out_cond); |
| } |
| pthread_mutex_unlock(&m_out_th_lock); |
| } |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::omx_evrc_aenc |
| |
| DESCRIPTION |
| Constructor |
| |
| PARAMETERS |
| None |
| |
| RETURN VALUE |
| None. |
| ========================================================================== */ |
| omx_evrc_aenc::omx_evrc_aenc(): m_tmp_meta_buf(NULL), |
| m_tmp_out_meta_buf(NULL), |
| m_flush_cnt(255), |
| m_comp_deinit(0), |
| m_volume(25), |
| m_app_data(NULL), |
| nNumInputBuf(0), |
| nNumOutputBuf(0), |
| m_drv_fd(-1), |
| bFlushinprogress(0), |
| is_in_th_sleep(false), |
| is_out_th_sleep(false), |
| m_flags(0), |
| nTimestamp(0), |
| m_inp_act_buf_count (OMX_CORE_NUM_INPUT_BUFFERS), |
| m_out_act_buf_count (OMX_CORE_NUM_OUTPUT_BUFFERS), |
| m_inp_current_buf_count(0), |
| m_out_current_buf_count(0), |
| output_buffer_size((OMX_U32)OMX_EVRC_OUTPUT_BUFFER_SIZE), |
| input_buffer_size(OMX_CORE_INPUT_BUFFER_SIZE), |
| m_inp_bEnabled(OMX_TRUE), |
| m_out_bEnabled(OMX_TRUE), |
| m_inp_bPopulated(OMX_FALSE), |
| m_out_bPopulated(OMX_FALSE), |
| m_is_event_done(0), |
| m_state(OMX_StateInvalid), |
| m_ipc_to_in_th(NULL), |
| m_ipc_to_out_th(NULL), |
| m_ipc_to_cmd_th(NULL) |
| { |
| int cond_ret = 0; |
| memset(&m_cmp, 0, sizeof(m_cmp)); |
| memset(&m_cb, 0, sizeof(m_cb)); |
| memset(&m_evrc_param, 0, sizeof(m_evrc_param)); |
| memset(&m_buffer_supplier, 0, sizeof(m_buffer_supplier)); |
| memset(&m_evrc_pb_stats, 0, sizeof(m_evrc_pb_stats)); |
| memset(&m_pcm_param, 0, sizeof(m_pcm_param)); |
| memset(&m_priority_mgm, 0, sizeof(m_priority_mgm)); |
| |
| pthread_mutexattr_init(&m_lock_attr); |
| pthread_mutex_init(&m_lock, &m_lock_attr); |
| pthread_mutexattr_init(&m_commandlock_attr); |
| pthread_mutex_init(&m_commandlock, &m_commandlock_attr); |
| |
| pthread_mutexattr_init(&m_outputlock_attr); |
| pthread_mutex_init(&m_outputlock, &m_outputlock_attr); |
| |
| pthread_mutexattr_init(&m_state_attr); |
| pthread_mutex_init(&m_state_lock, &m_state_attr); |
| |
| pthread_mutexattr_init(&m_event_attr); |
| pthread_mutex_init(&m_event_lock, &m_event_attr); |
| |
| pthread_mutexattr_init(&m_flush_attr); |
| pthread_mutex_init(&m_flush_lock, &m_flush_attr); |
| |
| pthread_mutexattr_init(&m_event_attr); |
| pthread_mutex_init(&m_event_lock, &m_event_attr); |
| |
| pthread_mutexattr_init(&m_in_th_attr); |
| pthread_mutex_init(&m_in_th_lock, &m_in_th_attr); |
| |
| pthread_mutexattr_init(&m_out_th_attr); |
| pthread_mutex_init(&m_out_th_lock, &m_out_th_attr); |
| |
| pthread_mutexattr_init(&m_in_th_attr_1); |
| pthread_mutex_init(&m_in_th_lock_1, &m_in_th_attr_1); |
| |
| pthread_mutexattr_init(&m_out_th_attr_1); |
| pthread_mutex_init(&m_out_th_lock_1, &m_out_th_attr_1); |
| |
| pthread_mutexattr_init(&out_buf_count_lock_attr); |
| pthread_mutex_init(&out_buf_count_lock, &out_buf_count_lock_attr); |
| |
| pthread_mutexattr_init(&in_buf_count_lock_attr); |
| pthread_mutex_init(&in_buf_count_lock, &in_buf_count_lock_attr); |
| if ((cond_ret = pthread_cond_init (&cond, NULL)) != 0) |
| { |
| DEBUG_PRINT_ERROR("pthread_cond_init returns non zero for cond\n"); |
| if (cond_ret == EAGAIN) |
| DEBUG_PRINT_ERROR("The system lacked necessary \ |
| resources(other than mem)\n"); |
| else if (cond_ret == ENOMEM) |
| DEBUG_PRINT_ERROR("Insufficient memory to initialise \ |
| condition variable\n"); |
| } |
| if ((cond_ret = pthread_cond_init (&in_cond, NULL)) != 0) |
| { |
| DEBUG_PRINT_ERROR("pthread_cond_init returns non zero for in_cond\n"); |
| if (cond_ret == EAGAIN) |
| DEBUG_PRINT_ERROR("The system lacked necessary \ |
| resources(other than mem)\n"); |
| else if (cond_ret == ENOMEM) |
| DEBUG_PRINT_ERROR("Insufficient memory to initialise \ |
| condition variable\n"); |
| } |
| if ((cond_ret = pthread_cond_init (&out_cond, NULL)) != 0) |
| { |
| DEBUG_PRINT_ERROR("pthread_cond_init returns non zero for out_cond\n"); |
| if (cond_ret == EAGAIN) |
| DEBUG_PRINT_ERROR("The system lacked necessary \ |
| resources(other than mem)\n"); |
| else if (cond_ret == ENOMEM) |
| DEBUG_PRINT_ERROR("Insufficient memory to initialise \ |
| condition variable\n"); |
| } |
| |
| sem_init(&sem_read_msg,0, 0); |
| sem_init(&sem_write_msg,0, 0); |
| sem_init(&sem_States,0, 0); |
| return; |
| } |
| |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::~omx_evrc_aenc |
| |
| DESCRIPTION |
| Destructor |
| |
| PARAMETERS |
| None |
| |
| RETURN VALUE |
| None. |
| ========================================================================== */ |
| omx_evrc_aenc::~omx_evrc_aenc() |
| { |
| DEBUG_PRINT_ERROR("EVRC Object getting destroyed comp-deinit=%d\n", |
| m_comp_deinit); |
| if ( !m_comp_deinit ) |
| { |
| deinit_encoder(); |
| } |
| pthread_mutexattr_destroy(&m_lock_attr); |
| pthread_mutex_destroy(&m_lock); |
| |
| pthread_mutexattr_destroy(&m_commandlock_attr); |
| pthread_mutex_destroy(&m_commandlock); |
| |
| pthread_mutexattr_destroy(&m_outputlock_attr); |
| pthread_mutex_destroy(&m_outputlock); |
| |
| pthread_mutexattr_destroy(&m_state_attr); |
| pthread_mutex_destroy(&m_state_lock); |
| |
| pthread_mutexattr_destroy(&m_event_attr); |
| pthread_mutex_destroy(&m_event_lock); |
| |
| pthread_mutexattr_destroy(&m_flush_attr); |
| pthread_mutex_destroy(&m_flush_lock); |
| |
| pthread_mutexattr_destroy(&m_in_th_attr); |
| pthread_mutex_destroy(&m_in_th_lock); |
| |
| pthread_mutexattr_destroy(&m_out_th_attr); |
| pthread_mutex_destroy(&m_out_th_lock); |
| |
| pthread_mutexattr_destroy(&out_buf_count_lock_attr); |
| pthread_mutex_destroy(&out_buf_count_lock); |
| |
| pthread_mutexattr_destroy(&in_buf_count_lock_attr); |
| pthread_mutex_destroy(&in_buf_count_lock); |
| |
| pthread_mutexattr_destroy(&m_in_th_attr_1); |
| pthread_mutex_destroy(&m_in_th_lock_1); |
| |
| pthread_mutexattr_destroy(&m_out_th_attr_1); |
| pthread_mutex_destroy(&m_out_th_lock_1); |
| pthread_mutex_destroy(&out_buf_count_lock); |
| pthread_mutex_destroy(&in_buf_count_lock); |
| pthread_cond_destroy(&cond); |
| pthread_cond_destroy(&in_cond); |
| pthread_cond_destroy(&out_cond); |
| sem_destroy (&sem_read_msg); |
| sem_destroy (&sem_write_msg); |
| sem_destroy (&sem_States); |
| DEBUG_PRINT_ERROR("OMX EVRC component destroyed\n"); |
| return; |
| } |
| |
| /** |
| @brief memory function for sending EmptyBufferDone event |
| back to IL client |
| |
| @param bufHdr OMX buffer header to be passed back to IL client |
| @return none |
| */ |
| void omx_evrc_aenc::buffer_done_cb(OMX_BUFFERHEADERTYPE *bufHdr) |
| { |
| if (m_cb.EmptyBufferDone) |
| { |
| PrintFrameHdr(OMX_COMPONENT_GENERATE_BUFFER_DONE,bufHdr); |
| bufHdr->nFilledLen = 0; |
| |
| m_cb.EmptyBufferDone(&m_cmp, m_app_data, bufHdr); |
| pthread_mutex_lock(&in_buf_count_lock); |
| m_evrc_pb_stats.ebd_cnt++; |
| nNumInputBuf--; |
| DEBUG_DETAIL("EBD CB:: in_buf_len=%d nNumInputBuf=%d %d ebd_cnt %d \n",\ |
| m_evrc_pb_stats.tot_in_buf_len, |
| nNumInputBuf, m_evrc_pb_stats.ebd_cnt); |
| pthread_mutex_unlock(&in_buf_count_lock); |
| } |
| |
| return; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| flush_ack |
| |
| DESCRIPTION: |
| |
| |
| INPUT/OUTPUT PARAMETERS: |
| None |
| |
| RETURN VALUE: |
| None |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| void omx_evrc_aenc::flush_ack() |
| { |
| // Decrement the FLUSH ACK count and notify the waiting recepients |
| pthread_mutex_lock(&m_flush_lock); |
| --m_flush_cnt; |
| if (0 == m_flush_cnt) |
| { |
| event_complete(); |
| } |
| DEBUG_PRINT("Rxed FLUSH ACK cnt=%d\n",m_flush_cnt); |
| pthread_mutex_unlock(&m_flush_lock); |
| } |
| void omx_evrc_aenc::frame_done_cb(OMX_BUFFERHEADERTYPE *bufHdr) |
| { |
| if (m_cb.FillBufferDone) |
| { |
| PrintFrameHdr(OMX_COMPONENT_GENERATE_FRAME_DONE,bufHdr); |
| m_evrc_pb_stats.fbd_cnt++; |
| pthread_mutex_lock(&out_buf_count_lock); |
| nNumOutputBuf--; |
| DEBUG_PRINT("FBD CB:: nNumOutputBuf=%d out_buf_len=%u fbd_cnt=%u\n",\ |
| nNumOutputBuf, |
| m_evrc_pb_stats.tot_out_buf_len, |
| m_evrc_pb_stats.fbd_cnt); |
| m_evrc_pb_stats.tot_out_buf_len += bufHdr->nFilledLen; |
| m_evrc_pb_stats.tot_pb_time = bufHdr->nTimeStamp; |
| DEBUG_PRINT("FBD:in_buf_len=%u out_buf_len=%u\n", |
| m_evrc_pb_stats.tot_in_buf_len, |
| m_evrc_pb_stats.tot_out_buf_len); |
| |
| pthread_mutex_unlock(&out_buf_count_lock); |
| m_cb.FillBufferDone(&m_cmp, m_app_data, bufHdr); |
| } |
| return; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| process_out_port_msg |
| |
| DESCRIPTION: |
| Function for handling all commands from IL client |
| IL client commands are processed and callbacks are generated through |
| this routine Audio Command Server provides the thread context for this routine |
| |
| INPUT/OUTPUT PARAMETERS: |
| [INOUT] client_data |
| [IN] id |
| |
| RETURN VALUE: |
| None |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| void omx_evrc_aenc::process_out_port_msg(void *client_data, unsigned char id) |
| { |
| unsigned long p1 = 0; // Parameter - 1 |
| unsigned long p2 = 0; // Parameter - 2 |
| unsigned char ident = 0; |
| unsigned qsize = 0; // qsize |
| unsigned tot_qsize = 0; |
| omx_evrc_aenc *pThis = (omx_evrc_aenc *) client_data; |
| OMX_STATETYPE state; |
| |
| loopback_out: |
| pthread_mutex_lock(&pThis->m_state_lock); |
| pThis->get_state(&pThis->m_cmp, &state); |
| pthread_mutex_unlock(&pThis->m_state_lock); |
| if ( state == OMX_StateLoaded ) |
| { |
| DEBUG_PRINT(" OUT: IN LOADED STATE RETURN\n"); |
| return; |
| } |
| pthread_mutex_lock(&pThis->m_outputlock); |
| |
| qsize = pThis->m_output_ctrl_cmd_q.m_size; |
| tot_qsize = pThis->m_output_ctrl_cmd_q.m_size; |
| tot_qsize += pThis->m_output_ctrl_fbd_q.m_size; |
| tot_qsize += pThis->m_output_q.m_size; |
| |
| if ( 0 == tot_qsize ) |
| { |
| pthread_mutex_unlock(&pThis->m_outputlock); |
| DEBUG_DETAIL("OUT-->BREAK FROM LOOP...%d\n",tot_qsize); |
| return; |
| } |
| if ( (state != OMX_StateExecuting) && !qsize ) |
| { |
| pthread_mutex_unlock(&pThis->m_outputlock); |
| pthread_mutex_lock(&pThis->m_state_lock); |
| pThis->get_state(&pThis->m_cmp, &state); |
| pthread_mutex_unlock(&pThis->m_state_lock); |
| if ( state == OMX_StateLoaded ) |
| return; |
| |
| DEBUG_DETAIL("OUT:1.SLEEPING OUT THREAD\n"); |
| pthread_mutex_lock(&pThis->m_out_th_lock_1); |
| pThis->is_out_th_sleep = true; |
| pthread_mutex_unlock(&pThis->m_out_th_lock_1); |
| pThis->out_th_goto_sleep(); |
| |
| /* Get the updated state */ |
| pthread_mutex_lock(&pThis->m_state_lock); |
| pThis->get_state(&pThis->m_cmp, &state); |
| pthread_mutex_unlock(&pThis->m_state_lock); |
| } |
| |
| if ( ((!pThis->m_output_ctrl_cmd_q.m_size) && !pThis->m_out_bEnabled) ) |
| { |
| // case where no port reconfig and nothing in the flush q |
| DEBUG_DETAIL("No flush/port reconfig qsize=%d tot_qsize=%d",\ |
| qsize,tot_qsize); |
| pthread_mutex_unlock(&pThis->m_outputlock); |
| pthread_mutex_lock(&pThis->m_state_lock); |
| pThis->get_state(&pThis->m_cmp, &state); |
| pthread_mutex_unlock(&pThis->m_state_lock); |
| if ( state == OMX_StateLoaded ) |
| return; |
| |
| if(pThis->m_output_ctrl_cmd_q.m_size || !(pThis->bFlushinprogress)) |
| { |
| DEBUG_PRINT("OUT:2. SLEEPING OUT THREAD \n"); |
| pthread_mutex_lock(&pThis->m_out_th_lock_1); |
| pThis->is_out_th_sleep = true; |
| pthread_mutex_unlock(&pThis->m_out_th_lock_1); |
| pThis->out_th_goto_sleep(); |
| } |
| /* Get the updated state */ |
| pthread_mutex_lock(&pThis->m_state_lock); |
| pThis->get_state(&pThis->m_cmp, &state); |
| pthread_mutex_unlock(&pThis->m_state_lock); |
| } |
| qsize = pThis->m_output_ctrl_cmd_q.m_size; |
| tot_qsize = pThis->m_output_ctrl_cmd_q.m_size; |
| tot_qsize += pThis->m_output_ctrl_fbd_q.m_size; |
| tot_qsize += pThis->m_output_q.m_size; |
| pthread_mutex_lock(&pThis->m_state_lock); |
| pThis->get_state(&pThis->m_cmp, &state); |
| pthread_mutex_unlock(&pThis->m_state_lock); |
| DEBUG_DETAIL("OUT-->QSIZE-flush=%d,fbd=%d QSIZE=%d state=%d\n",\ |
| pThis->m_output_ctrl_cmd_q.m_size, |
| pThis->m_output_ctrl_fbd_q.m_size, |
| pThis->m_output_q.m_size,state); |
| |
| |
| if (qsize) |
| { |
| // process FLUSH message |
| pThis->m_output_ctrl_cmd_q.pop_entry(&p1,&p2,&ident); |
| } else if ( (qsize = pThis->m_output_ctrl_fbd_q.m_size) && |
| (pThis->m_out_bEnabled) && (state == OMX_StateExecuting) ) |
| { |
| // then process EBD's |
| pThis->m_output_ctrl_fbd_q.pop_entry(&p1,&p2,&ident); |
| } else if ( (qsize = pThis->m_output_q.m_size) && |
| (pThis->m_out_bEnabled) && (state == OMX_StateExecuting) ) |
| { |
| // if no FLUSH and FBD's then process FTB's |
| pThis->m_output_q.pop_entry(&p1,&p2,&ident); |
| } else if ( state == OMX_StateLoaded ) |
| { |
| pthread_mutex_unlock(&pThis->m_outputlock); |
| DEBUG_PRINT("IN: ***in OMX_StateLoaded so exiting\n"); |
| return ; |
| } else |
| { |
| qsize = 0; |
| DEBUG_PRINT("OUT--> Empty Queue state=%d %d %d %d\n",state, |
| pThis->m_output_ctrl_cmd_q.m_size, |
| pThis->m_output_ctrl_fbd_q.m_size, |
| pThis->m_output_q.m_size); |
| |
| if(state == OMX_StatePause) |
| { |
| DEBUG_DETAIL("OUT: SLEEPING AGAIN OUT THREAD\n"); |
| pthread_mutex_lock(&pThis->m_out_th_lock_1); |
| pThis->is_out_th_sleep = true; |
| pthread_mutex_unlock(&pThis->m_out_th_lock_1); |
| pthread_mutex_unlock(&pThis->m_outputlock); |
| pThis->out_th_goto_sleep(); |
| goto loopback_out; |
| } |
| } |
| pthread_mutex_unlock(&pThis->m_outputlock); |
| |
| if ( qsize > 0 ) |
| { |
| id = ident; |
| ident = 0; |
| DEBUG_DETAIL("OUT->state[%d]ident[%d]flushq[%d]fbd[%d]dataq[%d]\n",\ |
| pThis->m_state, |
| ident, |
| pThis->m_output_ctrl_cmd_q.m_size, |
| pThis->m_output_ctrl_fbd_q.m_size, |
| pThis->m_output_q.m_size); |
| |
| if ( OMX_COMPONENT_GENERATE_FRAME_DONE == id ) |
| { |
| pThis->frame_done_cb((OMX_BUFFERHEADERTYPE *)p2); |
| } else if ( OMX_COMPONENT_GENERATE_FTB == id ) |
| { |
| pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1, |
| (OMX_BUFFERHEADERTYPE *)p2); |
| } else if ( OMX_COMPONENT_GENERATE_EOS == id ) |
| { |
| pThis->m_cb.EventHandler(&pThis->m_cmp, |
| pThis->m_app_data, |
| OMX_EventBufferFlag, |
| 1, 1, NULL ); |
| |
| } |
| else if(id == OMX_COMPONENT_RESUME) |
| { |
| DEBUG_PRINT("RESUMED...\n"); |
| } |
| else if(id == OMX_COMPONENT_GENERATE_COMMAND) |
| { |
| // Execute FLUSH command |
| if ( OMX_CommandFlush == p1 ) |
| { |
| DEBUG_DETAIL("Executing FLUSH command on Output port\n"); |
| pThis->execute_output_omx_flush(); |
| } else |
| { |
| DEBUG_DETAIL("Invalid command[%lu]\n",p1); |
| } |
| } else |
| { |
| DEBUG_PRINT_ERROR("ERROR:OUT-->Invalid Id[%d]\n",id); |
| } |
| } else |
| { |
| DEBUG_DETAIL("ERROR: OUT--> Empty OUTPUTQ\n"); |
| } |
| |
| return; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| process_command_msg |
| |
| DESCRIPTION: |
| |
| |
| INPUT/OUTPUT PARAMETERS: |
| [INOUT] client_data |
| [IN] id |
| |
| RETURN VALUE: |
| None |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| void omx_evrc_aenc::process_command_msg(void *client_data, unsigned char id) |
| { |
| unsigned long p1 = 0; // Parameter - 1 |
| unsigned long p2 = 0; // Parameter - 2 |
| unsigned char ident = 0; |
| unsigned qsize = 0; |
| omx_evrc_aenc *pThis = (omx_evrc_aenc*)client_data; |
| pthread_mutex_lock(&pThis->m_commandlock); |
| |
| qsize = pThis->m_command_q.m_size; |
| DEBUG_DETAIL("CMD-->QSIZE=%d state=%d\n",pThis->m_command_q.m_size, |
| pThis->m_state); |
| |
| if (!qsize) |
| { |
| DEBUG_DETAIL("CMD-->BREAKING FROM LOOP\n"); |
| pthread_mutex_unlock(&pThis->m_commandlock); |
| return; |
| } else |
| { |
| pThis->m_command_q.pop_entry(&p1,&p2,&ident); |
| } |
| pthread_mutex_unlock(&pThis->m_commandlock); |
| |
| id = ident; |
| DEBUG_DETAIL("CMD->state[%d]id[%d]cmdq[%d]n",\ |
| pThis->m_state,ident, \ |
| pThis->m_command_q.m_size); |
| |
| if (OMX_COMPONENT_GENERATE_EVENT == id) |
| { |
| if (pThis->m_cb.EventHandler) |
| { |
| if (OMX_CommandStateSet == p1) |
| { |
| pthread_mutex_lock(&pThis->m_state_lock); |
| pThis->m_state = (OMX_STATETYPE) p2; |
| pthread_mutex_unlock(&pThis->m_state_lock); |
| DEBUG_PRINT("CMD:Process->state set to %d \n", \ |
| pThis->m_state); |
| |
| if (pThis->m_state == OMX_StateExecuting || |
| pThis->m_state == OMX_StateLoaded) |
| { |
| |
| pthread_mutex_lock(&pThis->m_in_th_lock_1); |
| if (pThis->is_in_th_sleep) |
| { |
| pThis->is_in_th_sleep = false; |
| DEBUG_DETAIL("CMD:WAKING UP IN THREADS\n"); |
| pThis->in_th_wakeup(); |
| } |
| pthread_mutex_unlock(&pThis->m_in_th_lock_1); |
| |
| pthread_mutex_lock(&pThis->m_out_th_lock_1); |
| if (pThis->is_out_th_sleep) |
| { |
| DEBUG_DETAIL("CMD:WAKING UP OUT THREADS\n"); |
| pThis->is_out_th_sleep = false; |
| pThis->out_th_wakeup(); |
| } |
| pthread_mutex_unlock(&pThis->m_out_th_lock_1); |
| } |
| } |
| if (OMX_StateInvalid == pThis->m_state) |
| { |
| pThis->m_cb.EventHandler(&pThis->m_cmp, |
| pThis->m_app_data, |
| OMX_EventError, |
| OMX_ErrorInvalidState, |
| 0, NULL ); |
| } else if ((signed)p2 == OMX_ErrorPortUnpopulated) |
| { |
| pThis->m_cb.EventHandler(&pThis->m_cmp, |
| pThis->m_app_data, |
| OMX_EventError, |
| (OMX_U32)p2, |
| 0, |
| 0 ); |
| } else |
| { |
| pThis->m_cb.EventHandler(&pThis->m_cmp, |
| pThis->m_app_data, |
| OMX_EventCmdComplete, |
| (OMX_U32)p1, (OMX_U32)p2, NULL ); |
| } |
| } else |
| { |
| DEBUG_PRINT_ERROR("ERROR:CMD-->EventHandler NULL \n"); |
| } |
| } else if (OMX_COMPONENT_GENERATE_COMMAND == id) |
| { |
| pThis->send_command_proxy(&pThis->m_cmp, |
| (OMX_COMMANDTYPE)p1, |
| (OMX_U32)p2,(OMX_PTR)NULL); |
| } else if (OMX_COMPONENT_PORTSETTINGS_CHANGED == id) |
| { |
| DEBUG_DETAIL("CMD-->RXED PORTSETTINGS_CHANGED"); |
| pThis->m_cb.EventHandler(&pThis->m_cmp, |
| pThis->m_app_data, |
| OMX_EventPortSettingsChanged, |
| 1, 1, NULL ); |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("CMD->state[%d]id[%d]\n",pThis->m_state,ident); |
| } |
| return; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| process_in_port_msg |
| |
| DESCRIPTION: |
| |
| |
| INPUT/OUTPUT PARAMETERS: |
| [INOUT] client_data |
| [IN] id |
| |
| RETURN VALUE: |
| None |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| void omx_evrc_aenc::process_in_port_msg(void *client_data, unsigned char id) |
| { |
| unsigned long p1 = 0; // Parameter - 1 |
| unsigned long p2 = 0; // Parameter - 2 |
| unsigned char ident = 0; |
| unsigned qsize = 0; |
| unsigned tot_qsize = 0; |
| omx_evrc_aenc *pThis = (omx_evrc_aenc *) client_data; |
| OMX_STATETYPE state; |
| |
| if (!pThis) |
| { |
| DEBUG_PRINT_ERROR("ERROR:IN--> Invalid Obj \n"); |
| return; |
| } |
| loopback_in: |
| pthread_mutex_lock(&pThis->m_state_lock); |
| pThis->get_state(&pThis->m_cmp, &state); |
| pthread_mutex_unlock(&pThis->m_state_lock); |
| if ( state == OMX_StateLoaded ) |
| { |
| DEBUG_PRINT(" IN: IN LOADED STATE RETURN\n"); |
| return; |
| } |
| // Protect the shared queue data structure |
| pthread_mutex_lock(&pThis->m_lock); |
| |
| qsize = pThis->m_input_ctrl_cmd_q.m_size; |
| tot_qsize = qsize; |
| tot_qsize += pThis->m_input_ctrl_ebd_q.m_size; |
| tot_qsize += pThis->m_input_q.m_size; |
| |
| if ( 0 == tot_qsize ) |
| { |
| DEBUG_DETAIL("IN-->BREAKING FROM IN LOOP"); |
| pthread_mutex_unlock(&pThis->m_lock); |
| return; |
| } |
| |
| if ( (state != OMX_StateExecuting) && ! (pThis->m_input_ctrl_cmd_q.m_size)) |
| { |
| pthread_mutex_unlock(&pThis->m_lock); |
| DEBUG_DETAIL("SLEEPING IN THREAD\n"); |
| pthread_mutex_lock(&pThis->m_in_th_lock_1); |
| pThis->is_in_th_sleep = true; |
| pthread_mutex_unlock(&pThis->m_in_th_lock_1); |
| pThis->in_th_goto_sleep(); |
| |
| /* Get the updated state */ |
| pthread_mutex_lock(&pThis->m_state_lock); |
| pThis->get_state(&pThis->m_cmp, &state); |
| pthread_mutex_unlock(&pThis->m_state_lock); |
| } |
| else if ((state == OMX_StatePause)) |
| { |
| if(!(pThis->m_input_ctrl_cmd_q.m_size)) |
| { |
| pthread_mutex_unlock(&pThis->m_lock); |
| |
| DEBUG_DETAIL("IN: SLEEPING IN THREAD\n"); |
| pthread_mutex_lock(&pThis->m_in_th_lock_1); |
| pThis->is_in_th_sleep = true; |
| pthread_mutex_unlock(&pThis->m_in_th_lock_1); |
| pThis->in_th_goto_sleep(); |
| |
| pthread_mutex_lock(&pThis->m_state_lock); |
| pThis->get_state(&pThis->m_cmp, &state); |
| pthread_mutex_unlock(&pThis->m_state_lock); |
| } |
| } |
| |
| qsize = pThis->m_input_ctrl_cmd_q.m_size; |
| tot_qsize = qsize; |
| tot_qsize += pThis->m_input_ctrl_ebd_q.m_size; |
| tot_qsize += pThis->m_input_q.m_size; |
| |
| DEBUG_DETAIL("Input-->QSIZE-flush=%d,ebd=%d QSIZE=%d state=%d\n",\ |
| pThis->m_input_ctrl_cmd_q.m_size, |
| pThis->m_input_ctrl_ebd_q.m_size, |
| pThis->m_input_q.m_size, state); |
| |
| |
| if ( qsize ) |
| { |
| // process FLUSH message |
| pThis->m_input_ctrl_cmd_q.pop_entry(&p1,&p2,&ident); |
| } else if ( (qsize = pThis->m_input_ctrl_ebd_q.m_size) && |
| (state == OMX_StateExecuting) ) |
| { |
| // then process EBD's |
| pThis->m_input_ctrl_ebd_q.pop_entry(&p1,&p2,&ident); |
| } else if ((qsize = pThis->m_input_q.m_size) && |
| (state == OMX_StateExecuting)) |
| { |
| // if no FLUSH and EBD's then process ETB's |
| pThis->m_input_q.pop_entry(&p1, &p2, &ident); |
| } else if ( state == OMX_StateLoaded ) |
| { |
| pthread_mutex_unlock(&pThis->m_lock); |
| DEBUG_PRINT("IN: ***in OMX_StateLoaded so exiting\n"); |
| return ; |
| } else |
| { |
| qsize = 0; |
| DEBUG_PRINT("IN-->state[%d]cmdq[%d]ebdq[%d]in[%d]\n",\ |
| state,pThis->m_input_ctrl_cmd_q.m_size, |
| pThis->m_input_ctrl_ebd_q.m_size, |
| pThis->m_input_q.m_size); |
| |
| if(state == OMX_StatePause) |
| { |
| DEBUG_DETAIL("IN: SLEEPING AGAIN IN THREAD\n"); |
| pthread_mutex_lock(&pThis->m_in_th_lock_1); |
| pThis->is_in_th_sleep = true; |
| pthread_mutex_unlock(&pThis->m_in_th_lock_1); |
| pthread_mutex_unlock(&pThis->m_lock); |
| pThis->in_th_goto_sleep(); |
| goto loopback_in; |
| } |
| } |
| pthread_mutex_unlock(&pThis->m_lock); |
| |
| if ( qsize > 0 ) |
| { |
| id = ident; |
| DEBUG_DETAIL("Input->state[%d]id[%d]flushq[%d]ebdq[%d]dataq[%d]\n",\ |
| pThis->m_state, |
| ident, |
| pThis->m_input_ctrl_cmd_q.m_size, |
| pThis->m_input_ctrl_ebd_q.m_size, |
| pThis->m_input_q.m_size); |
| if ( OMX_COMPONENT_GENERATE_BUFFER_DONE == id ) |
| { |
| pThis->buffer_done_cb((OMX_BUFFERHEADERTYPE *)p2); |
| } |
| else if(id == OMX_COMPONENT_GENERATE_EOS) |
| { |
| pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, |
| OMX_EventBufferFlag, 0, 1, NULL ); |
| } else if ( OMX_COMPONENT_GENERATE_ETB == id ) |
| { |
| pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, |
| (OMX_BUFFERHEADERTYPE *)p2); |
| } else if ( OMX_COMPONENT_GENERATE_COMMAND == id ) |
| { |
| // Execute FLUSH command |
| if ( OMX_CommandFlush == p1 ) |
| { |
| DEBUG_DETAIL(" Executing FLUSH command on Input port\n"); |
| pThis->execute_input_omx_flush(); |
| } else |
| { |
| DEBUG_DETAIL("Invalid command[%lu]\n",p1); |
| } |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR("ERROR:IN-->Invalid Id[%u]\n",id); |
| } |
| } else |
| { |
| DEBUG_DETAIL("ERROR:IN-->Empty INPUT Q\n"); |
| } |
| return; |
| } |
| |
| /** |
| @brief member function for performing component initialization |
| |
| @param role C string mandating role of this component |
| @return Error status |
| */ |
| OMX_ERRORTYPE omx_evrc_aenc::component_init(OMX_STRING role) |
| { |
| |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| m_state = OMX_StateLoaded; |
| |
| /* DSP does not give information about the bitstream |
| randomly assign the value right now. Query will result in |
| incorrect param */ |
| memset(&m_evrc_param, 0, sizeof(m_evrc_param)); |
| m_evrc_param.nSize = (OMX_U32)sizeof(m_evrc_param); |
| m_evrc_param.nChannels = OMX_EVRC_DEFAULT_CH_CFG; |
| //Current DSP does not have config |
| m_evrc_param.eCDMARate = OMX_AUDIO_CDMARateFull; |
| m_evrc_param.nMinBitRate = OMX_EVRC_DEFAULT_MINRATE; |
| m_evrc_param.nMaxBitRate = OMX_EVRC_DEFAULT_MAXRATE; |
| m_volume = OMX_EVRC_DEFAULT_VOL; /* Close to unity gain */ |
| memset(&m_evrc_pb_stats,0,sizeof(EVRC_PB_STATS)); |
| memset(&m_pcm_param, 0, sizeof(m_pcm_param)); |
| m_pcm_param.nSize = (OMX_U32)sizeof(m_pcm_param); |
| m_pcm_param.nChannels = OMX_EVRC_DEFAULT_CH_CFG; |
| m_pcm_param.nSamplingRate = OMX_EVRC_DEFAULT_SF; |
| nTimestamp = 0; |
| |
| |
| nNumInputBuf = 0; |
| nNumOutputBuf = 0; |
| m_ipc_to_in_th = NULL; // Command server instance |
| m_ipc_to_out_th = NULL; // Client server instance |
| m_ipc_to_cmd_th = NULL; // command instance |
| m_is_out_th_sleep = 0; |
| m_is_in_th_sleep = 0; |
| is_out_th_sleep= false; |
| |
| is_in_th_sleep=false; |
| |
| memset(&m_priority_mgm, 0, sizeof(m_priority_mgm)); |
| m_priority_mgm.nGroupID =0; |
| m_priority_mgm.nGroupPriority=0; |
| |
| memset(&m_buffer_supplier, 0, sizeof(m_buffer_supplier)); |
| m_buffer_supplier.nPortIndex=OMX_BufferSupplyUnspecified; |
| |
| DEBUG_PRINT_ERROR(" component init: role = %s\n",role); |
| |
| DEBUG_PRINT(" component init: role = %s\n",role); |
| component_Role.nVersion.nVersion = OMX_SPEC_VERSION; |
| if (!strcmp(role,"OMX.qcom.audio.encoder.evrc")) |
| { |
| pcm_input = 1; |
| component_Role.nSize = (OMX_U32)sizeof(role); |
| strlcpy((char *)component_Role.cRole, |
| (const char*)role, sizeof(component_Role.cRole)); |
| DEBUG_PRINT("\ncomponent_init: Component %s LOADED \n", role); |
| } else if (!strcmp(role,"OMX.qcom.audio.encoder.tunneled.evrc")) |
| { |
| pcm_input = 0; |
| component_Role.nSize = (OMX_U32)sizeof(role); |
| strlcpy((char *)component_Role.cRole, |
| (const char*)role, sizeof(component_Role.cRole)); |
| DEBUG_PRINT("\ncomponent_init: Component %s LOADED \n", role); |
| } else |
| { |
| component_Role.nSize = (OMX_U32)sizeof("\0"); |
| strlcpy((char *)component_Role.cRole, |
| (const char*)"\0",sizeof(component_Role.cRole)); |
| DEBUG_PRINT("\ncomponent_init: Component %s LOADED is invalid\n", role); |
| } |
| if(pcm_input) |
| { |
| |
| |
| m_tmp_meta_buf = (OMX_U8*) malloc(sizeof(OMX_U8) * |
| (OMX_CORE_INPUT_BUFFER_SIZE + sizeof(META_IN))); |
| |
| if (m_tmp_meta_buf == NULL){ |
| DEBUG_PRINT_ERROR("Mem alloc failed for in meta buf\n"); |
| return OMX_ErrorInsufficientResources; |
| } |
| } |
| m_tmp_out_meta_buf = |
| (OMX_U8*)malloc(sizeof(OMX_U8)*OMX_EVRC_OUTPUT_BUFFER_SIZE); |
| if ( m_tmp_out_meta_buf == NULL ) { |
| DEBUG_PRINT_ERROR("Mem alloc failed for out meta buf\n"); |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| if(0 == pcm_input) |
| { |
| m_drv_fd = open("/dev/msm_evrc_in",O_RDONLY); |
| DEBUG_PRINT("Driver in Tunnel mode open\n"); |
| } |
| else |
| { |
| m_drv_fd = open("/dev/msm_evrc_in",O_RDWR); |
| DEBUG_PRINT("Driver in Non Tunnel mode open\n"); |
| } |
| if (m_drv_fd < 0) |
| { |
| DEBUG_PRINT_ERROR("Component_init Open Failed[%d] errno[%d]",\ |
| m_drv_fd,errno); |
| |
| return OMX_ErrorInsufficientResources; |
| } |
| if(ioctl(m_drv_fd, AUDIO_GET_SESSION_ID,&m_session_id) == -1) |
| { |
| DEBUG_PRINT_ERROR("AUDIO_GET_SESSION_ID FAILED\n"); |
| } |
| if(pcm_input) |
| { |
| if (!m_ipc_to_in_th) |
| { |
| m_ipc_to_in_th = omx_evrc_thread_create(process_in_port_msg, |
| this, (char *)"INPUT_THREAD"); |
| if (!m_ipc_to_in_th) |
| { |
| DEBUG_PRINT_ERROR("ERROR!!! Failed to start \ |
| Input port thread\n"); |
| return OMX_ErrorInsufficientResources; |
| } |
| } |
| } |
| |
| if (!m_ipc_to_cmd_th) |
| { |
| m_ipc_to_cmd_th = omx_evrc_thread_create(process_command_msg, |
| this, (char *)"CMD_THREAD"); |
| if (!m_ipc_to_cmd_th) |
| { |
| DEBUG_PRINT_ERROR("ERROR!!!Failed to start " |
| "command message thread\n"); |
| return OMX_ErrorInsufficientResources; |
| } |
| } |
| |
| if (!m_ipc_to_out_th) |
| { |
| m_ipc_to_out_th = omx_evrc_thread_create(process_out_port_msg, |
| this, (char *)"OUTPUT_THREAD"); |
| if (!m_ipc_to_out_th) |
| { |
| DEBUG_PRINT_ERROR("ERROR!!! Failed to start output " |
| "port thread\n"); |
| return OMX_ErrorInsufficientResources; |
| } |
| } |
| return eRet; |
| } |
| |
| /** |
| |
| @brief member function to retrieve version of component |
| |
| |
| |
| @param hComp handle to this component instance |
| @param componentName name of component |
| @param componentVersion pointer to memory space which stores the |
| version number |
| @param specVersion pointer to memory sapce which stores version of |
| openMax specification |
| @param componentUUID |
| @return Error status |
| */ |
| OMX_ERRORTYPE omx_evrc_aenc::get_component_version |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_OUT OMX_STRING componentName, |
| OMX_OUT OMX_VERSIONTYPE* componentVersion, |
| OMX_OUT OMX_VERSIONTYPE* specVersion, |
| OMX_OUT OMX_UUIDTYPE* componentUUID) |
| { |
| if((hComp == NULL) || (componentName == NULL) || |
| (specVersion == NULL) || (componentUUID == NULL)) |
| { |
| componentVersion = NULL; |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (m_state == OMX_StateInvalid) |
| { |
| DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n"); |
| return OMX_ErrorInvalidState; |
| } |
| componentVersion->nVersion = OMX_SPEC_VERSION; |
| specVersion->nVersion = OMX_SPEC_VERSION; |
| return OMX_ErrorNone; |
| } |
| /** |
| @brief member function handles command from IL client |
| |
| This function simply queue up commands from IL client. |
| Commands will be processed in command server thread context later |
| |
| @param hComp handle to component instance |
| @param cmd type of command |
| @param param1 parameters associated with the command type |
| @param cmdData |
| @return Error status |
| */ |
| OMX_ERRORTYPE omx_evrc_aenc::send_command(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_COMMANDTYPE cmd, |
| OMX_IN OMX_U32 param1, |
| OMX_IN OMX_PTR cmdData) |
| { |
| int portIndex = (int)param1; |
| |
| if(hComp == NULL) |
| { |
| cmdData = cmdData; |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (OMX_StateInvalid == m_state) |
| { |
| return OMX_ErrorInvalidState; |
| } |
| if ( (cmd == OMX_CommandFlush) && (portIndex > 1) ) |
| { |
| return OMX_ErrorBadPortIndex; |
| } |
| post_command((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); |
| DEBUG_PRINT("Send Command : returns with OMX_ErrorNone \n"); |
| DEBUG_PRINT("send_command : recieved state before semwait= %u\n",param1); |
| sem_wait (&sem_States); |
| DEBUG_PRINT("send_command : recieved state after semwait\n"); |
| return OMX_ErrorNone; |
| } |
| |
| /** |
| @brief member function performs actual processing of commands excluding |
| empty buffer call |
| |
| @param hComp handle to component |
| @param cmd command type |
| @param param1 parameter associated with the command |
| @param cmdData |
| |
| @return error status |
| */ |
| OMX_ERRORTYPE omx_evrc_aenc::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_COMMANDTYPE cmd, |
| OMX_IN OMX_U32 param1, |
| OMX_IN OMX_PTR cmdData) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| // Handle only IDLE and executing |
| OMX_STATETYPE eState = (OMX_STATETYPE) param1; |
| int bFlag = 1; |
| nState = eState; |
| |
| if(hComp == NULL) |
| { |
| cmdData = cmdData; |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (OMX_CommandStateSet == cmd) |
| { |
| /***************************/ |
| /* Current State is Loaded */ |
| /***************************/ |
| if (OMX_StateLoaded == m_state) |
| { |
| if (OMX_StateIdle == eState) |
| { |
| |
| if (allocate_done() || |
| (m_inp_bEnabled == OMX_FALSE |
| && m_out_bEnabled == OMX_FALSE)) |
| { |
| DEBUG_PRINT("SCP-->Allocate Done Complete\n"); |
| } |
| else |
| { |
| DEBUG_PRINT("SCP-->Loaded to Idle-Pending\n"); |
| BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); |
| bFlag = 0; |
| } |
| |
| } else if (eState == OMX_StateLoaded) |
| { |
| DEBUG_PRINT("OMXCORE-SM: Loaded-->Loaded\n"); |
| m_cb.EventHandler(&this->m_cmp, |
| this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorSameState, |
| 0, NULL ); |
| eRet = OMX_ErrorSameState; |
| } |
| |
| else if (eState == OMX_StateWaitForResources) |
| { |
| DEBUG_PRINT("OMXCORE-SM: Loaded-->WaitForResources\n"); |
| eRet = OMX_ErrorNone; |
| } |
| |
| else if (eState == OMX_StateExecuting) |
| { |
| DEBUG_PRINT("OMXCORE-SM: Loaded-->Executing\n"); |
| m_cb.EventHandler(&this->m_cmp, |
| this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| 0, NULL ); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| |
| else if (eState == OMX_StatePause) |
| { |
| DEBUG_PRINT("OMXCORE-SM: Loaded-->Pause\n"); |
| m_cb.EventHandler(&this->m_cmp, |
| this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| 0, NULL ); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| |
| else if (eState == OMX_StateInvalid) |
| { |
| DEBUG_PRINT("OMXCORE-SM: Loaded-->Invalid\n"); |
| m_cb.EventHandler(&this->m_cmp, |
| this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorInvalidState, |
| 0, NULL ); |
| m_state = OMX_StateInvalid; |
| eRet = OMX_ErrorInvalidState; |
| } else |
| { |
| DEBUG_PRINT_ERROR("SCP-->Loaded to Invalid(%d))\n",eState); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } |
| |
| /***************************/ |
| /* Current State is IDLE */ |
| /***************************/ |
| else if (OMX_StateIdle == m_state) |
| { |
| if (OMX_StateLoaded == eState) |
| { |
| if (release_done(-1)) |
| { |
| if (ioctl(m_drv_fd, AUDIO_STOP, 0) == -1) |
| { |
| DEBUG_PRINT_ERROR("SCP:Idle->Loaded,\ |
| ioctl stop failed %d\n", errno); |
| } |
| |
| nTimestamp=0; |
| |
| DEBUG_PRINT("SCP-->Idle to Loaded\n"); |
| } else |
| { |
| DEBUG_PRINT("SCP--> Idle to Loaded-Pending\n"); |
| BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); |
| // Skip the event notification |
| bFlag = 0; |
| } |
| } |
| else if (OMX_StateExecuting == eState) |
| { |
| |
| struct msm_audio_evrc_enc_config drv_evrc_enc_config; |
| struct msm_audio_stream_config drv_stream_config; |
| struct msm_audio_buf_cfg buf_cfg; |
| struct msm_audio_config pcm_cfg; |
| |
| if(ioctl(m_drv_fd, AUDIO_GET_STREAM_CONFIG, &drv_stream_config) |
| == -1) |
| { |
| DEBUG_PRINT_ERROR("ioctl AUDIO_GET_STREAM_CONFIG failed, \ |
| errno[%d]\n", errno); |
| } |
| if(ioctl(m_drv_fd, AUDIO_SET_STREAM_CONFIG, &drv_stream_config) |
| == -1) |
| { |
| DEBUG_PRINT_ERROR("ioctl AUDIO_SET_STREAM_CONFIG failed, \ |
| errno[%d]\n", errno); |
| } |
| |
| if(ioctl(m_drv_fd, AUDIO_GET_EVRC_ENC_CONFIG, |
| &drv_evrc_enc_config) == -1) |
| { |
| DEBUG_PRINT_ERROR("ioctl AUDIO_GET_EVRC_ENC_CONFIG failed,\ |
| errno[%d]\n", errno); |
| } |
| drv_evrc_enc_config.min_bit_rate = m_evrc_param.nMinBitRate; |
| drv_evrc_enc_config.max_bit_rate = m_evrc_param.nMaxBitRate; |
| if(ioctl(m_drv_fd, AUDIO_SET_EVRC_ENC_CONFIG, &drv_evrc_enc_config) |
| == -1) |
| { |
| DEBUG_PRINT_ERROR("ioctl AUDIO_SET_EVRC_ENC_CONFIG failed,\ |
| errno[%d]\n", errno); |
| } |
| if (ioctl(m_drv_fd, AUDIO_GET_BUF_CFG, &buf_cfg) == -1) |
| { |
| DEBUG_PRINT_ERROR("ioctl AUDIO_GET_BUF_CFG, errno[%d]\n", |
| errno); |
| } |
| buf_cfg.meta_info_enable = 1; |
| buf_cfg.frames_per_buf = NUMOFFRAMES; |
| if (ioctl(m_drv_fd, AUDIO_SET_BUF_CFG, &buf_cfg) == -1) |
| { |
| DEBUG_PRINT_ERROR("ioctl AUDIO_SET_BUF_CFG, errno[%d]\n", |
| errno); |
| } |
| if(pcm_input) |
| { |
| if (ioctl(m_drv_fd, AUDIO_GET_CONFIG, &pcm_cfg) == -1) |
| { |
| DEBUG_PRINT_ERROR("ioctl AUDIO_GET_CONFIG, errno[%d]\n", |
| errno); |
| } |
| pcm_cfg.channel_count = m_pcm_param.nChannels; |
| pcm_cfg.sample_rate = m_pcm_param.nSamplingRate; |
| DEBUG_PRINT("pcm config %u %u\n",m_pcm_param.nChannels, |
| m_pcm_param.nSamplingRate); |
| |
| if (ioctl(m_drv_fd, AUDIO_SET_CONFIG, &pcm_cfg) == -1) |
| { |
| DEBUG_PRINT_ERROR("ioctl AUDIO_SET_CONFIG, errno[%d]\n", |
| errno); |
| } |
| } |
| if(ioctl(m_drv_fd, AUDIO_START, 0) == -1) |
| { |
| DEBUG_PRINT_ERROR("ioctl AUDIO_START failed, errno[%d]\n", |
| errno); |
| m_state = OMX_StateInvalid; |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, OMX_ErrorInvalidState, |
| 0, NULL ); |
| eRet = OMX_ErrorInvalidState; |
| |
| } |
| DEBUG_PRINT("SCP-->Idle to Executing\n"); |
| nState = eState; |
| } else if (eState == OMX_StateIdle) |
| { |
| DEBUG_PRINT("OMXCORE-SM: Idle-->Idle\n"); |
| m_cb.EventHandler(&this->m_cmp, |
| this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorSameState, |
| 0, NULL ); |
| eRet = OMX_ErrorSameState; |
| } else if (eState == OMX_StateWaitForResources) |
| { |
| DEBUG_PRINT("OMXCORE-SM: Idle-->WaitForResources\n"); |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| 0, NULL ); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } |
| |
| else if (eState == OMX_StatePause) |
| { |
| DEBUG_PRINT("OMXCORE-SM: Idle-->Pause\n"); |
| } |
| |
| else if (eState == OMX_StateInvalid) |
| { |
| DEBUG_PRINT("OMXCORE-SM: Idle-->Invalid\n"); |
| m_state = OMX_StateInvalid; |
| this->m_cb.EventHandler(&this->m_cmp, |
| this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorInvalidState, |
| 0, NULL ); |
| eRet = OMX_ErrorInvalidState; |
| } else |
| { |
| DEBUG_PRINT_ERROR("SCP--> Idle to %d Not Handled\n",eState); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } |
| |
| /******************************/ |
| /* Current State is Executing */ |
| /******************************/ |
| else if (OMX_StateExecuting == m_state) |
| { |
| if (OMX_StateIdle == eState) |
| { |
| DEBUG_PRINT("SCP-->Executing to Idle \n"); |
| if(pcm_input) |
| execute_omx_flush(-1,false); |
| else |
| execute_omx_flush(1,false); |
| |
| |
| } else if (OMX_StatePause == eState) |
| { |
| DEBUG_DETAIL("*************************\n"); |
| DEBUG_PRINT("SCP-->RXED PAUSE STATE\n"); |
| DEBUG_DETAIL("*************************\n"); |
| //ioctl(m_drv_fd, AUDIO_PAUSE, 0); |
| } else if (eState == OMX_StateLoaded) |
| { |
| DEBUG_PRINT("\n OMXCORE-SM: Executing --> Loaded \n"); |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| 0, NULL ); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } else if (eState == OMX_StateWaitForResources) |
| { |
| DEBUG_PRINT("\n OMXCORE-SM: Executing --> WaitForResources \n"); |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| 0, NULL ); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } else if (eState == OMX_StateExecuting) |
| { |
| DEBUG_PRINT("\n OMXCORE-SM: Executing --> Executing \n"); |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, OMX_ErrorSameState, |
| 0, NULL ); |
| eRet = OMX_ErrorSameState; |
| } else if (eState == OMX_StateInvalid) |
| { |
| DEBUG_PRINT("\n OMXCORE-SM: Executing --> Invalid \n"); |
| m_state = OMX_StateInvalid; |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, OMX_ErrorInvalidState, |
| 0, NULL ); |
| eRet = OMX_ErrorInvalidState; |
| } else |
| { |
| DEBUG_PRINT_ERROR("SCP--> Executing to %d Not Handled\n", |
| eState); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } |
| /***************************/ |
| /* Current State is Pause */ |
| /***************************/ |
| else if (OMX_StatePause == m_state) |
| { |
| if( (eState == OMX_StateExecuting || eState == OMX_StateIdle) ) |
| { |
| pthread_mutex_lock(&m_out_th_lock_1); |
| if(is_out_th_sleep) |
| { |
| DEBUG_DETAIL("PE: WAKING UP OUT THREAD\n"); |
| is_out_th_sleep = false; |
| out_th_wakeup(); |
| } |
| pthread_mutex_unlock(&m_out_th_lock_1); |
| } |
| if ( OMX_StateExecuting == eState ) |
| { |
| nState = eState; |
| } else if ( OMX_StateIdle == eState ) |
| { |
| DEBUG_PRINT("SCP-->Paused to Idle \n"); |
| DEBUG_PRINT ("\n Internal flush issued"); |
| pthread_mutex_lock(&m_flush_lock); |
| m_flush_cnt = 2; |
| pthread_mutex_unlock(&m_flush_lock); |
| if(pcm_input) |
| execute_omx_flush(-1,false); |
| else |
| execute_omx_flush(1,false); |
| |
| } else if ( eState == OMX_StateLoaded ) |
| { |
| DEBUG_PRINT("\n Pause --> loaded \n"); |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| 0, NULL ); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } else if (eState == OMX_StateWaitForResources) |
| { |
| DEBUG_PRINT("\n Pause --> WaitForResources \n"); |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| 0, NULL ); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } else if (eState == OMX_StatePause) |
| { |
| DEBUG_PRINT("\n Pause --> Pause \n"); |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, OMX_ErrorSameState, |
| 0, NULL ); |
| eRet = OMX_ErrorSameState; |
| } else if (eState == OMX_StateInvalid) |
| { |
| DEBUG_PRINT("\n Pause --> Invalid \n"); |
| m_state = OMX_StateInvalid; |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, OMX_ErrorInvalidState, |
| 0, NULL ); |
| eRet = OMX_ErrorInvalidState; |
| } else |
| { |
| DEBUG_PRINT("SCP-->Paused to %d Not Handled\n",eState); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } |
| /**************************************/ |
| /* Current State is WaitForResources */ |
| /**************************************/ |
| else if (m_state == OMX_StateWaitForResources) |
| { |
| if (eState == OMX_StateLoaded) |
| { |
| DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Loaded\n"); |
| } else if (eState == OMX_StateWaitForResources) |
| { |
| DEBUG_PRINT("OMXCORE-SM: \ |
| WaitForResources-->WaitForResources\n"); |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, OMX_ErrorSameState, |
| 0, NULL ); |
| eRet = OMX_ErrorSameState; |
| } else if (eState == OMX_StateExecuting) |
| { |
| DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Executing\n"); |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| 0, NULL ); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } else if (eState == OMX_StatePause) |
| { |
| DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Pause\n"); |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorIncorrectStateTransition, |
| 0, NULL ); |
| eRet = OMX_ErrorIncorrectStateTransition; |
| } else if (eState == OMX_StateInvalid) |
| { |
| DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Invalid\n"); |
| m_state = OMX_StateInvalid; |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, |
| OMX_ErrorInvalidState, |
| 0, NULL ); |
| eRet = OMX_ErrorInvalidState; |
| } else |
| { |
| DEBUG_PRINT_ERROR("SCP--> %d to %d(Not Handled)\n", |
| m_state,eState); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } |
| /****************************/ |
| /* Current State is Invalid */ |
| /****************************/ |
| else if (m_state == OMX_StateInvalid) |
| { |
| if (OMX_StateLoaded == eState || OMX_StateWaitForResources == eState |
| || OMX_StateIdle == eState || OMX_StateExecuting == eState |
| || OMX_StatePause == eState || OMX_StateInvalid == eState) |
| { |
| DEBUG_PRINT("OMXCORE-SM: Invalid-->Loaded/Idle/Executing" |
| "/Pause/Invalid/WaitForResources\n"); |
| m_state = OMX_StateInvalid; |
| this->m_cb.EventHandler(&this->m_cmp, this->m_app_data, |
| OMX_EventError, OMX_ErrorInvalidState, |
| 0, NULL ); |
| eRet = OMX_ErrorInvalidState; |
| } |
| } else |
| { |
| DEBUG_PRINT_ERROR("OMXCORE-SM: %d --> %d(Not Handled)\n",\ |
| m_state,eState); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } else if (OMX_CommandFlush == cmd) |
| { |
| DEBUG_DETAIL("*************************\n"); |
| DEBUG_PRINT("SCP-->RXED FLUSH COMMAND port=%u\n",param1); |
| DEBUG_DETAIL("*************************\n"); |
| bFlag = 0; |
| if ( param1 == OMX_CORE_INPUT_PORT_INDEX || |
| param1 == OMX_CORE_OUTPUT_PORT_INDEX || |
| (signed)param1 == -1 ) |
| { |
| execute_omx_flush(param1); |
| } else |
| { |
| eRet = OMX_ErrorBadPortIndex; |
| m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventError, |
| OMX_CommandFlush, OMX_ErrorBadPortIndex, NULL ); |
| } |
| } else if ( cmd == OMX_CommandPortDisable ) |
| { |
| bFlag = 0; |
| if ( param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL ) |
| { |
| DEBUG_PRINT("SCP: Disabling Input port Indx\n"); |
| m_inp_bEnabled = OMX_FALSE; |
| if ( (m_state == OMX_StateLoaded || m_state == OMX_StateIdle) |
| && release_done(0) ) |
| { |
| DEBUG_PRINT("send_command_proxy:OMX_CommandPortDisable:\ |
| OMX_CORE_INPUT_PORT_INDEX:release_done \n"); |
| DEBUG_PRINT("************* OMX_CommandPortDisable:\ |
| m_inp_bEnabled = %d********\n",m_inp_bEnabled); |
| |
| post_command(OMX_CommandPortDisable, |
| OMX_CORE_INPUT_PORT_INDEX, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } |
| |
| else |
| { |
| if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) |
| { |
| DEBUG_PRINT("SCP: execute_omx_flush in Disable in "\ |
| " param1=%u m_state=%d \n",param1, m_state); |
| execute_omx_flush(param1); |
| } |
| DEBUG_PRINT("send_command_proxy:OMX_CommandPortDisable:\ |
| OMX_CORE_INPUT_PORT_INDEX \n"); |
| BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); |
| // Skip the event notification |
| |
| } |
| |
| } |
| if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) |
| { |
| |
| DEBUG_PRINT("SCP: Disabling Output port Indx\n"); |
| m_out_bEnabled = OMX_FALSE; |
| if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) |
| && release_done(1)) |
| { |
| DEBUG_PRINT("send_command_proxy:OMX_CommandPortDisable:\ |
| OMX_CORE_OUTPUT_PORT_INDEX:release_done \n"); |
| DEBUG_PRINT("************* OMX_CommandPortDisable:\ |
| m_out_bEnabled = %d********\n",m_inp_bEnabled); |
| |
| post_command(OMX_CommandPortDisable, |
| OMX_CORE_OUTPUT_PORT_INDEX, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } else |
| { |
| if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) |
| { |
| DEBUG_PRINT("SCP: execute_omx_flush in Disable out "\ |
| "param1=%u m_state=%d \n",param1, m_state); |
| execute_omx_flush(param1); |
| } |
| BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); |
| // Skip the event notification |
| |
| } |
| } else |
| { |
| DEBUG_PRINT_ERROR("OMX_CommandPortDisable: disable wrong port ID"); |
| } |
| |
| } else if (cmd == OMX_CommandPortEnable) |
| { |
| bFlag = 0; |
| if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) |
| { |
| m_inp_bEnabled = OMX_TRUE; |
| DEBUG_PRINT("SCP: Enabling Input port Indx\n"); |
| if ((m_state == OMX_StateLoaded |
| && !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) |
| || (m_state == OMX_StateWaitForResources) |
| || (m_inp_bPopulated == OMX_TRUE)) |
| { |
| post_command(OMX_CommandPortEnable, |
| OMX_CORE_INPUT_PORT_INDEX, |
| OMX_COMPONENT_GENERATE_EVENT); |
| |
| |
| } else |
| { |
| BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); |
| // Skip the event notification |
| |
| } |
| } |
| |
| if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) |
| { |
| DEBUG_PRINT("SCP: Enabling Output port Indx\n"); |
| m_out_bEnabled = OMX_TRUE; |
| if ((m_state == OMX_StateLoaded |
| && !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) |
| || (m_state == OMX_StateWaitForResources) |
| || (m_out_bPopulated == OMX_TRUE)) |
| { |
| post_command(OMX_CommandPortEnable, |
| OMX_CORE_OUTPUT_PORT_INDEX, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } else |
| { |
| DEBUG_PRINT("send_command_proxy:OMX_CommandPortEnable:\ |
| OMX_CORE_OUTPUT_PORT_INDEX:release_done \n"); |
| BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); |
| // Skip the event notification |
| |
| } |
| pthread_mutex_lock(&m_in_th_lock_1); |
| if(is_in_th_sleep) |
| { |
| is_in_th_sleep = false; |
| DEBUG_DETAIL("SCP:WAKING UP IN THREADS\n"); |
| in_th_wakeup(); |
| } |
| pthread_mutex_unlock(&m_in_th_lock_1); |
| pthread_mutex_lock(&m_out_th_lock_1); |
| if (is_out_th_sleep) |
| { |
| is_out_th_sleep = false; |
| DEBUG_PRINT("SCP:WAKING OUT THR, OMX_CommandPortEnable\n"); |
| out_th_wakeup(); |
| } |
| pthread_mutex_unlock(&m_out_th_lock_1); |
| } else |
| { |
| DEBUG_PRINT_ERROR("OMX_CommandPortEnable: disable wrong port ID"); |
| } |
| |
| } else |
| { |
| DEBUG_PRINT_ERROR("SCP-->ERROR: Invali Command [%d]\n",cmd); |
| eRet = OMX_ErrorNotImplemented; |
| } |
| DEBUG_PRINT("posting sem_States\n"); |
| sem_post (&sem_States); |
| if (eRet == OMX_ErrorNone && bFlag) |
| { |
| post_command(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); |
| } |
| return eRet; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| execute_omx_flush |
| |
| DESCRIPTION: |
| Function that flushes buffers that are pending to be written to driver |
| |
| INPUT/OUTPUT PARAMETERS: |
| [IN] param1 |
| [IN] cmd_cmpl |
| |
| RETURN VALUE: |
| true |
| false |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| bool omx_evrc_aenc::execute_omx_flush(OMX_IN OMX_U32 param1, bool cmd_cmpl) |
| { |
| bool bRet = true; |
| |
| DEBUG_PRINT("Execute_omx_flush Port[%u]", param1); |
| struct timespec abs_timeout; |
| abs_timeout.tv_sec = 1; |
| abs_timeout.tv_nsec = 0; |
| |
| if ((signed)param1 == -1) |
| { |
| bFlushinprogress = true; |
| DEBUG_PRINT("Execute flush for both I/p O/p port\n"); |
| pthread_mutex_lock(&m_flush_lock); |
| m_flush_cnt = 2; |
| pthread_mutex_unlock(&m_flush_lock); |
| |
| // Send Flush commands to input and output threads |
| post_input(OMX_CommandFlush, |
| OMX_CORE_INPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND); |
| post_output(OMX_CommandFlush, |
| OMX_CORE_OUTPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND); |
| // Send Flush to the kernel so that the in and out buffers are released |
| if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) == -1) |
| DEBUG_PRINT_ERROR("FLush:ioctl flush failed errno=%d\n",errno); |
| DEBUG_DETAIL("****************************************"); |
| DEBUG_DETAIL("is_in_th_sleep=%d is_out_th_sleep=%d\n",\ |
| is_in_th_sleep,is_out_th_sleep); |
| DEBUG_DETAIL("****************************************"); |
| |
| pthread_mutex_lock(&m_in_th_lock_1); |
| if (is_in_th_sleep) |
| { |
| is_in_th_sleep = false; |
| DEBUG_DETAIL("For FLUSH-->WAKING UP IN THREADS\n"); |
| in_th_wakeup(); |
| } |
| pthread_mutex_unlock(&m_in_th_lock_1); |
| |
| pthread_mutex_lock(&m_out_th_lock_1); |
| if (is_out_th_sleep) |
| { |
| is_out_th_sleep = false; |
| DEBUG_DETAIL("For FLUSH-->WAKING UP OUT THREADS\n"); |
| out_th_wakeup(); |
| } |
| pthread_mutex_unlock(&m_out_th_lock_1); |
| |
| |
| // sleep till the FLUSH ACK are done by both the input and |
| // output threads |
| DEBUG_DETAIL("WAITING FOR FLUSH ACK's param1=%d",param1); |
| wait_for_event(); |
| |
| DEBUG_PRINT("RECIEVED BOTH FLUSH ACK's param1=%u cmd_cmpl=%d",\ |
| param1,cmd_cmpl); |
| |
| // If not going to idle state, Send FLUSH complete message |
| // to the Client, now that FLUSH ACK's have been recieved. |
| if (cmd_cmpl) |
| { |
| m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete, |
| OMX_CommandFlush, OMX_CORE_INPUT_PORT_INDEX, |
| NULL ); |
| m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete, |
| OMX_CommandFlush, OMX_CORE_OUTPUT_PORT_INDEX, |
| NULL ); |
| DEBUG_PRINT("Inside FLUSH.. sending FLUSH CMPL\n"); |
| } |
| bFlushinprogress = false; |
| } |
| else if (param1 == OMX_CORE_INPUT_PORT_INDEX) |
| { |
| DEBUG_PRINT("Execute FLUSH for I/p port\n"); |
| pthread_mutex_lock(&m_flush_lock); |
| m_flush_cnt = 1; |
| pthread_mutex_unlock(&m_flush_lock); |
| post_input(OMX_CommandFlush, |
| OMX_CORE_INPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND); |
| if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) == -1) |
| DEBUG_PRINT_ERROR("Flush:Input port, ioctl flush failed %d\n", |
| errno); |
| DEBUG_DETAIL("****************************************"); |
| DEBUG_DETAIL("is_in_th_sleep=%d is_out_th_sleep=%d\n",\ |
| is_in_th_sleep,is_out_th_sleep); |
| DEBUG_DETAIL("****************************************"); |
| |
| if (is_in_th_sleep) |
| { |
| pthread_mutex_lock(&m_in_th_lock_1); |
| is_in_th_sleep = false; |
| pthread_mutex_unlock(&m_in_th_lock_1); |
| DEBUG_DETAIL("For FLUSH-->WAKING UP IN THREADS\n"); |
| in_th_wakeup(); |
| } |
| |
| if (is_out_th_sleep) |
| { |
| pthread_mutex_lock(&m_out_th_lock_1); |
| is_out_th_sleep = false; |
| pthread_mutex_unlock(&m_out_th_lock_1); |
| DEBUG_DETAIL("For FLUSH-->WAKING UP OUT THREADS\n"); |
| out_th_wakeup(); |
| } |
| |
| //sleep till the FLUSH ACK are done by both the input and output threads |
| DEBUG_DETAIL("Executing FLUSH for I/p port\n"); |
| DEBUG_DETAIL("WAITING FOR FLUSH ACK's param1=%d",param1); |
| wait_for_event(); |
| DEBUG_DETAIL(" RECIEVED FLUSH ACK FOR I/P PORT param1=%d",param1); |
| |
| // Send FLUSH complete message to the Client, |
| // now that FLUSH ACK's have been recieved. |
| if (cmd_cmpl) |
| { |
| m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete, |
| OMX_CommandFlush, OMX_CORE_INPUT_PORT_INDEX, |
| NULL ); |
| } |
| } else if (OMX_CORE_OUTPUT_PORT_INDEX == param1) |
| { |
| DEBUG_PRINT("Executing FLUSH for O/p port\n"); |
| pthread_mutex_lock(&m_flush_lock); |
| m_flush_cnt = 1; |
| pthread_mutex_unlock(&m_flush_lock); |
| DEBUG_DETAIL("Executing FLUSH for O/p port\n"); |
| DEBUG_DETAIL("WAITING FOR FLUSH ACK's param1=%d",param1); |
| post_output(OMX_CommandFlush, |
| OMX_CORE_OUTPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND); |
| if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) ==-1) |
| DEBUG_PRINT_ERROR("Flush:Output port, ioctl flush failed %d\n", |
| errno); |
| DEBUG_DETAIL("****************************************"); |
| DEBUG_DETAIL("is_in_th_sleep=%d is_out_th_sleep=%d\n",\ |
| is_in_th_sleep,is_out_th_sleep); |
| DEBUG_DETAIL("****************************************"); |
| if (is_in_th_sleep) |
| { |
| pthread_mutex_lock(&m_in_th_lock_1); |
| is_in_th_sleep = false; |
| pthread_mutex_unlock(&m_in_th_lock_1); |
| DEBUG_DETAIL("For FLUSH-->WAKING UP IN THREADS\n"); |
| in_th_wakeup(); |
| } |
| |
| if (is_out_th_sleep) |
| { |
| pthread_mutex_lock(&m_out_th_lock_1); |
| is_out_th_sleep = false; |
| pthread_mutex_unlock(&m_out_th_lock_1); |
| DEBUG_DETAIL("For FLUSH-->WAKING UP OUT THREADS\n"); |
| out_th_wakeup(); |
| } |
| |
| // sleep till the FLUSH ACK are done by both the input and |
| // output threads |
| wait_for_event(); |
| // Send FLUSH complete message to the Client, |
| // now that FLUSH ACK's have been recieved. |
| if (cmd_cmpl) |
| { |
| m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete, |
| OMX_CommandFlush, OMX_CORE_OUTPUT_PORT_INDEX, |
| NULL ); |
| } |
| DEBUG_DETAIL("RECIEVED FLUSH ACK FOR O/P PORT param1=%d",param1); |
| } else |
| { |
| DEBUG_PRINT("Invalid Port ID[%u]",param1); |
| } |
| return bRet; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| execute_input_omx_flush |
| |
| DESCRIPTION: |
| Function that flushes buffers that are pending to be written to driver |
| |
| INPUT/OUTPUT PARAMETERS: |
| None |
| |
| RETURN VALUE: |
| true |
| false |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| bool omx_evrc_aenc::execute_input_omx_flush() |
| { |
| OMX_BUFFERHEADERTYPE *omx_buf; |
| unsigned long p1 = 0; // Parameter - 1 |
| unsigned long p2 = 0; // Parameter - 2 |
| unsigned char ident = 0; |
| unsigned qsize=0; // qsize |
| unsigned tot_qsize=0; // qsize |
| |
| DEBUG_PRINT("Execute_omx_flush on input port"); |
| |
| pthread_mutex_lock(&m_lock); |
| do |
| { |
| qsize = m_input_q.m_size; |
| tot_qsize = qsize; |
| tot_qsize += m_input_ctrl_ebd_q.m_size; |
| |
| DEBUG_DETAIL("Input FLUSH-->flushq[%d] ebd[%d]dataq[%d]",\ |
| m_input_ctrl_cmd_q.m_size, |
| m_input_ctrl_ebd_q.m_size,qsize); |
| if (!tot_qsize) |
| { |
| DEBUG_DETAIL("Input-->BREAKING FROM execute_input_flush LOOP"); |
| pthread_mutex_unlock(&m_lock); |
| break; |
| } |
| if (qsize) |
| { |
| m_input_q.pop_entry(&p1, &p2, &ident); |
| if ((ident == OMX_COMPONENT_GENERATE_ETB) || |
| (ident == OMX_COMPONENT_GENERATE_BUFFER_DONE)) |
| { |
| omx_buf = (OMX_BUFFERHEADERTYPE *) p2; |
| DEBUG_DETAIL("Flush:Input dataq=%p \n", omx_buf); |
| omx_buf->nFilledLen = 0; |
| buffer_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf); |
| } |
| } else if (m_input_ctrl_ebd_q.m_size) |
| { |
| m_input_ctrl_ebd_q.pop_entry(&p1, &p2, &ident); |
| if (ident == OMX_COMPONENT_GENERATE_BUFFER_DONE) |
| { |
| omx_buf = (OMX_BUFFERHEADERTYPE *) p2; |
| omx_buf->nFilledLen = 0; |
| DEBUG_DETAIL("Flush:ctrl dataq=%p \n", omx_buf); |
| buffer_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf); |
| } |
| } else |
| { |
| } |
| }while (tot_qsize>0); |
| DEBUG_DETAIL("*************************\n"); |
| DEBUG_DETAIL("IN-->FLUSHING DONE\n"); |
| DEBUG_DETAIL("*************************\n"); |
| flush_ack(); |
| pthread_mutex_unlock(&m_lock); |
| return true; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| execute_output_omx_flush |
| |
| DESCRIPTION: |
| Function that flushes buffers that are pending to be written to driver |
| |
| INPUT/OUTPUT PARAMETERS: |
| None |
| |
| RETURN VALUE: |
| true |
| false |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| bool omx_evrc_aenc::execute_output_omx_flush() |
| { |
| OMX_BUFFERHEADERTYPE *omx_buf; |
| unsigned long p1; // Parameter - 1 |
| unsigned long p2; // Parameter - 2 |
| unsigned char ident = 0; |
| unsigned qsize=0; // qsize |
| unsigned tot_qsize=0; // qsize |
| |
| DEBUG_PRINT("Execute_omx_flush on output port"); |
| |
| pthread_mutex_lock(&m_outputlock); |
| do |
| { |
| qsize = m_output_q.m_size; |
| DEBUG_DETAIL("OUT FLUSH-->flushq[%d] fbd[%d]dataq[%d]",\ |
| m_output_ctrl_cmd_q.m_size, |
| m_output_ctrl_fbd_q.m_size,qsize); |
| tot_qsize = qsize; |
| tot_qsize += m_output_ctrl_fbd_q.m_size; |
| if (!tot_qsize) |
| { |
| DEBUG_DETAIL("OUT-->BREAKING FROM execute_input_flush LOOP"); |
| pthread_mutex_unlock(&m_outputlock); |
| break; |
| } |
| if (qsize) |
| { |
| m_output_q.pop_entry(&p1,&p2,&ident); |
| if ( (OMX_COMPONENT_GENERATE_FTB == ident) || |
| (OMX_COMPONENT_GENERATE_FRAME_DONE == ident)) |
| { |
| omx_buf = (OMX_BUFFERHEADERTYPE *) p2; |
| DEBUG_DETAIL("Ouput Buf_Addr=%p TS[0x%x] \n",\ |
| omx_buf,nTimestamp); |
| omx_buf->nTimeStamp = nTimestamp; |
| omx_buf->nFilledLen = 0; |
| frame_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf); |
| DEBUG_DETAIL("CALLING FBD FROM FLUSH"); |
| } |
| } else if ((qsize = m_output_ctrl_fbd_q.m_size)) |
| { |
| m_output_ctrl_fbd_q.pop_entry(&p1, &p2, &ident); |
| if (OMX_COMPONENT_GENERATE_FRAME_DONE == ident) |
| { |
| omx_buf = (OMX_BUFFERHEADERTYPE *) p2; |
| DEBUG_DETAIL("Ouput Buf_Addr=%p TS[0x%x] \n", \ |
| omx_buf,nTimestamp); |
| omx_buf->nTimeStamp = nTimestamp; |
| omx_buf->nFilledLen = 0; |
| frame_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf); |
| DEBUG_DETAIL("CALLING FROM CTRL-FBDQ FROM FLUSH"); |
| } |
| } |
| }while (qsize>0); |
| DEBUG_DETAIL("*************************\n"); |
| DEBUG_DETAIL("OUT-->FLUSHING DONE\n"); |
| DEBUG_DETAIL("*************************\n"); |
| flush_ack(); |
| pthread_mutex_unlock(&m_outputlock); |
| return true; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| post_input |
| |
| DESCRIPTION: |
| Function that posts command in the command queue |
| |
| INPUT/OUTPUT PARAMETERS: |
| [IN] p1 |
| [IN] p2 |
| [IN] id - command ID |
| [IN] lock - self-locking mode |
| |
| RETURN VALUE: |
| true |
| false |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| bool omx_evrc_aenc::post_input(unsigned long p1, |
| unsigned long p2, |
| unsigned char id) |
| { |
| bool bRet = false; |
| pthread_mutex_lock(&m_lock); |
| |
| if((OMX_COMPONENT_GENERATE_COMMAND == id) || (id == OMX_COMPONENT_SUSPEND)) |
| { |
| // insert flush message and ebd |
| m_input_ctrl_cmd_q.insert_entry(p1,p2,id); |
| } else if ((OMX_COMPONENT_GENERATE_BUFFER_DONE == id)) |
| { |
| // insert ebd |
| m_input_ctrl_ebd_q.insert_entry(p1,p2,id); |
| } else |
| { |
| // ETBS in this queue |
| m_input_q.insert_entry(p1,p2,id); |
| } |
| |
| if (m_ipc_to_in_th) |
| { |
| bRet = true; |
| omx_evrc_post_msg(m_ipc_to_in_th, id); |
| } |
| |
| DEBUG_DETAIL("PostInput-->state[%d]id[%d]flushq[%d]ebdq[%d]dataq[%d] \n",\ |
| m_state, |
| id, |
| m_input_ctrl_cmd_q.m_size, |
| m_input_ctrl_ebd_q.m_size, |
| m_input_q.m_size); |
| |
| pthread_mutex_unlock(&m_lock); |
| return bRet; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| post_command |
| |
| DESCRIPTION: |
| Function that posts command in the command queue |
| |
| INPUT/OUTPUT PARAMETERS: |
| [IN] p1 |
| [IN] p2 |
| [IN] id - command ID |
| [IN] lock - self-locking mode |
| |
| RETURN VALUE: |
| true |
| false |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| bool omx_evrc_aenc::post_command(unsigned int p1, |
| unsigned int p2, |
| unsigned char id) |
| { |
| bool bRet = false; |
| |
| pthread_mutex_lock(&m_commandlock); |
| |
| m_command_q.insert_entry(p1,p2,id); |
| |
| if (m_ipc_to_cmd_th) |
| { |
| bRet = true; |
| omx_evrc_post_msg(m_ipc_to_cmd_th, id); |
| } |
| |
| DEBUG_DETAIL("PostCmd-->state[%d]id[%d]cmdq[%d]flags[%x]\n",\ |
| m_state, |
| id, |
| m_command_q.m_size, |
| m_flags >> 3); |
| |
| pthread_mutex_unlock(&m_commandlock); |
| return bRet; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| post_output |
| |
| DESCRIPTION: |
| Function that posts command in the command queue |
| |
| INPUT/OUTPUT PARAMETERS: |
| [IN] p1 |
| [IN] p2 |
| [IN] id - command ID |
| [IN] lock - self-locking mode |
| |
| RETURN VALUE: |
| true |
| false |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| bool omx_evrc_aenc::post_output(unsigned long p1, |
| unsigned long p2, |
| unsigned char id) |
| { |
| bool bRet = false; |
| |
| pthread_mutex_lock(&m_outputlock); |
| if((OMX_COMPONENT_GENERATE_COMMAND == id) || (id == OMX_COMPONENT_SUSPEND) |
| || (id == OMX_COMPONENT_RESUME)) |
| { |
| // insert flush message and fbd |
| m_output_ctrl_cmd_q.insert_entry(p1,p2,id); |
| } else if ( (OMX_COMPONENT_GENERATE_FRAME_DONE == id) ) |
| { |
| // insert flush message and fbd |
| m_output_ctrl_fbd_q.insert_entry(p1,p2,id); |
| } else |
| { |
| m_output_q.insert_entry(p1,p2,id); |
| } |
| if ( m_ipc_to_out_th ) |
| { |
| bRet = true; |
| omx_evrc_post_msg(m_ipc_to_out_th, id); |
| } |
| DEBUG_DETAIL("PostOutput-->state[%d]id[%d]flushq[%d]ebdq[%d]dataq[%d]\n",\ |
| m_state, |
| id, |
| m_output_ctrl_cmd_q.m_size, |
| m_output_ctrl_fbd_q.m_size, |
| m_output_q.m_size); |
| |
| pthread_mutex_unlock(&m_outputlock); |
| return bRet; |
| } |
| /** |
| @brief member function that return parameters to IL client |
| |
| @param hComp handle to component instance |
| @param paramIndex Parameter type |
| @param paramData pointer to memory space which would hold the |
| paramter |
| @return error status |
| */ |
| OMX_ERRORTYPE omx_evrc_aenc::get_parameter(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_INDEXTYPE paramIndex, |
| OMX_INOUT OMX_PTR paramData) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| |
| if(hComp == NULL) |
| { |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (m_state == OMX_StateInvalid) |
| { |
| DEBUG_PRINT_ERROR("Get Param in Invalid State\n"); |
| return OMX_ErrorInvalidState; |
| } |
| if (paramData == NULL) |
| { |
| DEBUG_PRINT("get_parameter: paramData is NULL\n"); |
| return OMX_ErrorBadParameter; |
| } |
| |
| switch ((int)paramIndex) |
| { |
| case OMX_IndexParamPortDefinition: |
| { |
| OMX_PARAM_PORTDEFINITIONTYPE *portDefn; |
| portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; |
| |
| DEBUG_PRINT("OMX_IndexParamPortDefinition " \ |
| "portDefn->nPortIndex = %u\n", |
| portDefn->nPortIndex); |
| |
| portDefn->nVersion.nVersion = OMX_SPEC_VERSION; |
| portDefn->nSize = (OMX_U32)sizeof(portDefn); |
| portDefn->eDomain = OMX_PortDomainAudio; |
| |
| if (0 == portDefn->nPortIndex) |
| { |
| portDefn->eDir = OMX_DirInput; |
| portDefn->bEnabled = m_inp_bEnabled; |
| portDefn->bPopulated = m_inp_bPopulated; |
| portDefn->nBufferCountActual = m_inp_act_buf_count; |
| portDefn->nBufferCountMin = OMX_CORE_NUM_INPUT_BUFFERS; |
| portDefn->nBufferSize = input_buffer_size; |
| portDefn->format.audio.bFlagErrorConcealment = OMX_TRUE; |
| portDefn->format.audio.eEncoding = OMX_AUDIO_CodingPCM; |
| portDefn->format.audio.pNativeRender = 0; |
| } else if (1 == portDefn->nPortIndex) |
| { |
| portDefn->eDir = OMX_DirOutput; |
| portDefn->bEnabled = m_out_bEnabled; |
| portDefn->bPopulated = m_out_bPopulated; |
| portDefn->nBufferCountActual = m_out_act_buf_count; |
| portDefn->nBufferCountMin = OMX_CORE_NUM_OUTPUT_BUFFERS; |
| portDefn->nBufferSize = output_buffer_size; |
| portDefn->format.audio.bFlagErrorConcealment = OMX_TRUE; |
| portDefn->format.audio.eEncoding = OMX_AUDIO_CodingEVRC; |
| portDefn->format.audio.pNativeRender = 0; |
| } else |
| { |
| portDefn->eDir = OMX_DirMax; |
| DEBUG_PRINT_ERROR("Bad Port idx %d\n",\ |
| (int)portDefn->nPortIndex); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| |
| case OMX_IndexParamAudioInit: |
| { |
| OMX_PORT_PARAM_TYPE *portParamType = |
| (OMX_PORT_PARAM_TYPE *) paramData; |
| DEBUG_PRINT("OMX_IndexParamAudioInit\n"); |
| |
| portParamType->nVersion.nVersion = OMX_SPEC_VERSION; |
| portParamType->nSize = (OMX_U32)sizeof(portParamType); |
| portParamType->nPorts = 2; |
| portParamType->nStartPortNumber = 0; |
| break; |
| } |
| |
| case OMX_IndexParamAudioPortFormat: |
| { |
| OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormatType = |
| (OMX_AUDIO_PARAM_PORTFORMATTYPE *) paramData; |
| DEBUG_PRINT("OMX_IndexParamAudioPortFormat\n"); |
| portFormatType->nVersion.nVersion = OMX_SPEC_VERSION; |
| portFormatType->nSize = (OMX_U32)sizeof(portFormatType); |
| |
| if (OMX_CORE_INPUT_PORT_INDEX == portFormatType->nPortIndex) |
| { |
| |
| portFormatType->eEncoding = OMX_AUDIO_CodingPCM; |
| } else if (OMX_CORE_OUTPUT_PORT_INDEX== |
| portFormatType->nPortIndex) |
| { |
| DEBUG_PRINT("get_parameter: OMX_IndexParamAudioFormat: "\ |
| "%u\n", portFormatType->nIndex); |
| |
| portFormatType->eEncoding = OMX_AUDIO_CodingEVRC; |
| } else |
| { |
| DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n", |
| (int)portFormatType->nPortIndex); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| |
| case OMX_IndexParamAudioEvrc: |
| { |
| OMX_AUDIO_PARAM_EVRCTYPE *evrcParam = |
| (OMX_AUDIO_PARAM_EVRCTYPE *) paramData; |
| DEBUG_PRINT("OMX_IndexParamAudioEvrc\n"); |
| if (OMX_CORE_OUTPUT_PORT_INDEX== evrcParam->nPortIndex) |
| { |
| memcpy(evrcParam,&m_evrc_param, |
| sizeof(OMX_AUDIO_PARAM_EVRCTYPE)); |
| } else |
| { |
| DEBUG_PRINT_ERROR("get_parameter:OMX_IndexParamAudioEvrc "\ |
| "OMX_ErrorBadPortIndex %d\n", \ |
| (int)evrcParam->nPortIndex); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| case QOMX_IndexParamAudioSessionId: |
| { |
| QOMX_AUDIO_STREAM_INFO_DATA *streaminfoparam = |
| (QOMX_AUDIO_STREAM_INFO_DATA *) paramData; |
| streaminfoparam->sessionId = (OMX_U8)m_session_id; |
| break; |
| } |
| |
| case OMX_IndexParamAudioPcm: |
| { |
| OMX_AUDIO_PARAM_PCMMODETYPE *pcmparam = |
| (OMX_AUDIO_PARAM_PCMMODETYPE *) paramData; |
| |
| if (OMX_CORE_INPUT_PORT_INDEX== pcmparam->nPortIndex) |
| { |
| memcpy(pcmparam,&m_pcm_param,\ |
| sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); |
| DEBUG_PRINT("get_parameter: Sampling rate %u",\ |
| pcmparam->nSamplingRate); |
| DEBUG_PRINT("get_parameter: Number of channels %u",\ |
| pcmparam->nChannels); |
| } else |
| { |
| DEBUG_PRINT_ERROR("get_parameter:OMX_IndexParamAudioPcm "\ |
| "OMX_ErrorBadPortIndex %d\n", \ |
| (int)pcmparam->nPortIndex); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| case OMX_IndexParamComponentSuspended: |
| { |
| OMX_PARAM_SUSPENSIONTYPE *suspend = |
| (OMX_PARAM_SUSPENSIONTYPE *) paramData; |
| DEBUG_PRINT("get_parameter: OMX_IndexParamComponentSuspended %p\n", |
| suspend); |
| break; |
| } |
| case OMX_IndexParamVideoInit: |
| { |
| OMX_PORT_PARAM_TYPE *portParamType = |
| (OMX_PORT_PARAM_TYPE *) paramData; |
| DEBUG_PRINT("get_parameter: OMX_IndexParamVideoInit\n"); |
| portParamType->nVersion.nVersion = OMX_SPEC_VERSION; |
| portParamType->nSize = (OMX_U32)sizeof(portParamType); |
| portParamType->nPorts = 0; |
| portParamType->nStartPortNumber = 0; |
| break; |
| } |
| case OMX_IndexParamPriorityMgmt: |
| { |
| OMX_PRIORITYMGMTTYPE *priorityMgmtType = |
| (OMX_PRIORITYMGMTTYPE*)paramData; |
| DEBUG_PRINT("get_parameter: OMX_IndexParamPriorityMgmt\n"); |
| priorityMgmtType->nSize = (OMX_U32)sizeof(priorityMgmtType); |
| priorityMgmtType->nVersion.nVersion = OMX_SPEC_VERSION; |
| priorityMgmtType->nGroupID = m_priority_mgm.nGroupID; |
| priorityMgmtType->nGroupPriority = |
| m_priority_mgm.nGroupPriority; |
| break; |
| } |
| case OMX_IndexParamImageInit: |
| { |
| OMX_PORT_PARAM_TYPE *portParamType = |
| (OMX_PORT_PARAM_TYPE *) paramData; |
| DEBUG_PRINT("get_parameter: OMX_IndexParamImageInit\n"); |
| portParamType->nVersion.nVersion = OMX_SPEC_VERSION; |
| portParamType->nSize = (OMX_U32)sizeof(portParamType); |
| portParamType->nPorts = 0; |
| portParamType->nStartPortNumber = 0; |
| break; |
| } |
| |
| case OMX_IndexParamCompBufferSupplier: |
| { |
| DEBUG_PRINT("get_parameter: \ |
| OMX_IndexParamCompBufferSupplier\n"); |
| OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType |
| = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; |
| DEBUG_PRINT("get_parameter: \ |
| OMX_IndexParamCompBufferSupplier\n"); |
| |
| bufferSupplierType->nSize = (OMX_U32)sizeof(bufferSupplierType); |
| bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION; |
| if (OMX_CORE_INPUT_PORT_INDEX == |
| bufferSupplierType->nPortIndex) |
| { |
| bufferSupplierType->nPortIndex = |
| OMX_BufferSupplyUnspecified; |
| } else if (OMX_CORE_OUTPUT_PORT_INDEX == |
| bufferSupplierType->nPortIndex) |
| { |
| bufferSupplierType->nPortIndex = |
| OMX_BufferSupplyUnspecified; |
| } else |
| { |
| DEBUG_PRINT_ERROR("get_parameter:"\ |
| "OMX_IndexParamCompBufferSupplier eRet"\ |
| "%08x\n", eRet); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| |
| /*Component should support this port definition*/ |
| case OMX_IndexParamOtherInit: |
| { |
| OMX_PORT_PARAM_TYPE *portParamType = |
| (OMX_PORT_PARAM_TYPE *) paramData; |
| DEBUG_PRINT("get_parameter: OMX_IndexParamOtherInit\n"); |
| portParamType->nVersion.nVersion = OMX_SPEC_VERSION; |
| portParamType->nSize = (OMX_U32)sizeof(portParamType); |
| portParamType->nPorts = 0; |
| portParamType->nStartPortNumber = 0; |
| break; |
| } |
| case OMX_IndexParamStandardComponentRole: |
| { |
| OMX_PARAM_COMPONENTROLETYPE *componentRole; |
| componentRole = (OMX_PARAM_COMPONENTROLETYPE*)paramData; |
| componentRole->nSize = component_Role.nSize; |
| componentRole->nVersion = component_Role.nVersion; |
| strlcpy((char *)componentRole->cRole, |
| (const char*)component_Role.cRole, |
| sizeof(componentRole->cRole)); |
| DEBUG_PRINT_ERROR("nSize = %d , nVersion = %d, cRole = %s\n", |
| component_Role.nSize, |
| component_Role.nVersion, |
| component_Role.cRole); |
| break; |
| |
| } |
| default: |
| { |
| DEBUG_PRINT_ERROR("unknown param %08x\n", paramIndex); |
| eRet = OMX_ErrorUnsupportedIndex; |
| } |
| } |
| return eRet; |
| |
| } |
| |
| /** |
| @brief member function that set paramter from IL client |
| |
| @param hComp handle to component instance |
| @param paramIndex parameter type |
| @param paramData pointer to memory space which holds the paramter |
| @return error status |
| */ |
| OMX_ERRORTYPE omx_evrc_aenc::set_parameter(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_INDEXTYPE paramIndex, |
| OMX_IN OMX_PTR paramData) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| |
| if(hComp == NULL) |
| { |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (m_state != OMX_StateLoaded) |
| { |
| DEBUG_PRINT_ERROR("set_parameter is not in proper state\n"); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| if (paramData == NULL) |
| { |
| DEBUG_PRINT("param data is NULL"); |
| return OMX_ErrorBadParameter; |
| } |
| |
| switch (paramIndex) |
| { |
| case OMX_IndexParamAudioEvrc: |
| { |
| DEBUG_PRINT("OMX_IndexParamAudioEvrc"); |
| OMX_AUDIO_PARAM_AMRTYPE *evrcparam |
| = (OMX_AUDIO_PARAM_AMRTYPE *) paramData; |
| memcpy(&m_evrc_param,evrcparam, |
| sizeof(OMX_AUDIO_PARAM_EVRCTYPE)); |
| break; |
| } |
| case OMX_IndexParamPortDefinition: |
| { |
| OMX_PARAM_PORTDEFINITIONTYPE *portDefn; |
| portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; |
| |
| if (((m_state == OMX_StateLoaded)&& |
| !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) |
| || (m_state == OMX_StateWaitForResources && |
| ((OMX_DirInput == portDefn->eDir && |
| m_inp_bEnabled == true)|| |
| (OMX_DirInput == portDefn->eDir && |
| m_out_bEnabled == true))) |
| ||(((OMX_DirInput == portDefn->eDir && |
| m_inp_bEnabled == false)|| |
| (OMX_DirInput == portDefn->eDir && |
| m_out_bEnabled == false)) && |
| (m_state != OMX_StateWaitForResources))) |
| { |
| DEBUG_PRINT("Set Parameter called in valid state\n"); |
| } else |
| { |
| DEBUG_PRINT_ERROR("Set Parameter called in \ |
| Invalid State\n"); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| DEBUG_PRINT("OMX_IndexParamPortDefinition portDefn->nPortIndex " |
| "= %u\n",portDefn->nPortIndex); |
| if (OMX_CORE_INPUT_PORT_INDEX == portDefn->nPortIndex) |
| { |
| if ( portDefn->nBufferCountActual > |
| OMX_CORE_NUM_INPUT_BUFFERS ) |
| { |
| m_inp_act_buf_count = portDefn->nBufferCountActual; |
| } else |
| { |
| m_inp_act_buf_count =OMX_CORE_NUM_INPUT_BUFFERS; |
| } |
| input_buffer_size = portDefn->nBufferSize; |
| |
| } else if (OMX_CORE_OUTPUT_PORT_INDEX == portDefn->nPortIndex) |
| { |
| if ( portDefn->nBufferCountActual > |
| OMX_CORE_NUM_OUTPUT_BUFFERS ) |
| { |
| m_out_act_buf_count = portDefn->nBufferCountActual; |
| } else |
| { |
| m_out_act_buf_count =OMX_CORE_NUM_OUTPUT_BUFFERS; |
| } |
| output_buffer_size = portDefn->nBufferSize; |
| } else |
| { |
| DEBUG_PRINT(" set_parameter: Bad Port idx %d",\ |
| (int)portDefn->nPortIndex); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| case OMX_IndexParamPriorityMgmt: |
| { |
| DEBUG_PRINT("set_parameter: OMX_IndexParamPriorityMgmt\n"); |
| |
| if (m_state != OMX_StateLoaded) |
| { |
| DEBUG_PRINT_ERROR("Set Parameter called in \ |
| Invalid State\n"); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| OMX_PRIORITYMGMTTYPE *priorityMgmtype |
| = (OMX_PRIORITYMGMTTYPE*) paramData; |
| DEBUG_PRINT("set_parameter: OMX_IndexParamPriorityMgmt %u\n", |
| priorityMgmtype->nGroupID); |
| |
| DEBUG_PRINT("set_parameter: priorityMgmtype %u\n", |
| priorityMgmtype->nGroupPriority); |
| |
| m_priority_mgm.nGroupID = priorityMgmtype->nGroupID; |
| m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority; |
| |
| break; |
| } |
| case OMX_IndexParamAudioPortFormat: |
| { |
| |
| OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormatType = |
| (OMX_AUDIO_PARAM_PORTFORMATTYPE *) paramData; |
| DEBUG_PRINT("set_parameter: OMX_IndexParamAudioPortFormat\n"); |
| |
| if (OMX_CORE_INPUT_PORT_INDEX== portFormatType->nPortIndex) |
| { |
| portFormatType->eEncoding = OMX_AUDIO_CodingPCM; |
| } else if (OMX_CORE_OUTPUT_PORT_INDEX == |
| portFormatType->nPortIndex) |
| { |
| DEBUG_PRINT("set_parameter: OMX_IndexParamAudioFormat:"\ |
| " %u\n", portFormatType->nIndex); |
| portFormatType->eEncoding = OMX_AUDIO_CodingEVRC; |
| } else |
| { |
| DEBUG_PRINT_ERROR("set_parameter: Bad port index %d\n", \ |
| (int)portFormatType->nPortIndex); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| |
| |
| case OMX_IndexParamCompBufferSupplier: |
| { |
| DEBUG_PRINT("set_parameter: \ |
| OMX_IndexParamCompBufferSupplier\n"); |
| OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType |
| = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; |
| DEBUG_PRINT("set_param: OMX_IndexParamCompBufferSupplier %d",\ |
| bufferSupplierType->eBufferSupplier); |
| |
| if (bufferSupplierType->nPortIndex == OMX_CORE_INPUT_PORT_INDEX |
| || bufferSupplierType->nPortIndex == |
| OMX_CORE_OUTPUT_PORT_INDEX) |
| { |
| DEBUG_PRINT("set_parameter:\ |
| OMX_IndexParamCompBufferSupplier\n"); |
| m_buffer_supplier.eBufferSupplier = |
| bufferSupplierType->eBufferSupplier; |
| } else |
| { |
| DEBUG_PRINT_ERROR("set_param:\ |
| IndexParamCompBufferSup %08x\n", eRet); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| |
| break; } |
| |
| case OMX_IndexParamAudioPcm: |
| { |
| DEBUG_PRINT("set_parameter: OMX_IndexParamAudioPcm\n"); |
| OMX_AUDIO_PARAM_PCMMODETYPE *pcmparam |
| = (OMX_AUDIO_PARAM_PCMMODETYPE *) paramData; |
| |
| if (OMX_CORE_INPUT_PORT_INDEX== pcmparam->nPortIndex) |
| { |
| memcpy(&m_pcm_param,pcmparam,\ |
| sizeof(OMX_AUDIO_PARAM_PCMMODETYPE)); |
| DEBUG_PRINT("set_pcm_parameter: %u %u",\ |
| m_pcm_param.nChannels, |
| m_pcm_param.nSamplingRate); |
| } else |
| { |
| DEBUG_PRINT_ERROR("Set_parameter:OMX_IndexParamAudioPcm " |
| "OMX_ErrorBadPortIndex %d\n", |
| (int)pcmparam->nPortIndex); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| break; |
| } |
| case OMX_IndexParamSuspensionPolicy: |
| { |
| eRet = OMX_ErrorNotImplemented; |
| break; |
| } |
| case OMX_IndexParamStandardComponentRole: |
| { |
| OMX_PARAM_COMPONENTROLETYPE *componentRole; |
| componentRole = (OMX_PARAM_COMPONENTROLETYPE*)paramData; |
| component_Role.nSize = componentRole->nSize; |
| component_Role.nVersion = componentRole->nVersion; |
| strlcpy((char *)component_Role.cRole, |
| (const char*)componentRole->cRole, |
| sizeof(component_Role.cRole)); |
| break; |
| } |
| |
| default: |
| { |
| DEBUG_PRINT_ERROR("unknown param %d\n", paramIndex); |
| eRet = OMX_ErrorUnsupportedIndex; |
| } |
| } |
| return eRet; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::GetConfig |
| |
| DESCRIPTION |
| OMX Get Config Method implementation. |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| OMX Error None if successful. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::get_config(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_INDEXTYPE configIndex, |
| OMX_INOUT OMX_PTR configData) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| |
| if(hComp == NULL) |
| { |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (m_state == OMX_StateInvalid) |
| { |
| DEBUG_PRINT_ERROR("Get Config in Invalid State\n"); |
| return OMX_ErrorInvalidState; |
| } |
| |
| switch (configIndex) |
| { |
| case OMX_IndexConfigAudioVolume: |
| { |
| OMX_AUDIO_CONFIG_VOLUMETYPE *volume = |
| (OMX_AUDIO_CONFIG_VOLUMETYPE*) configData; |
| |
| if (OMX_CORE_INPUT_PORT_INDEX == volume->nPortIndex) |
| { |
| volume->nSize = (OMX_U32)sizeof(volume); |
| volume->nVersion.nVersion = OMX_SPEC_VERSION; |
| volume->bLinear = OMX_TRUE; |
| volume->sVolume.nValue = m_volume; |
| volume->sVolume.nMax = OMX_AENC_MAX; |
| volume->sVolume.nMin = OMX_AENC_MIN; |
| } else |
| { |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| } |
| break; |
| |
| case OMX_IndexConfigAudioMute: |
| { |
| OMX_AUDIO_CONFIG_MUTETYPE *mute = |
| (OMX_AUDIO_CONFIG_MUTETYPE*) configData; |
| |
| if (OMX_CORE_INPUT_PORT_INDEX == mute->nPortIndex) |
| { |
| mute->nSize = (OMX_U32)sizeof(mute); |
| mute->nVersion.nVersion = OMX_SPEC_VERSION; |
| mute->bMute = (BITMASK_PRESENT(&m_flags, |
| OMX_COMPONENT_MUTED)?OMX_TRUE:OMX_FALSE); |
| } else |
| { |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| } |
| break; |
| |
| default: |
| eRet = OMX_ErrorUnsupportedIndex; |
| break; |
| } |
| return eRet; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::SetConfig |
| |
| DESCRIPTION |
| OMX Set Config method implementation |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| OMX Error None if successful. |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::set_config(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_INDEXTYPE configIndex, |
| OMX_IN OMX_PTR configData) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| |
| if(hComp == NULL) |
| { |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (m_state == OMX_StateInvalid) |
| { |
| DEBUG_PRINT_ERROR("Set Config in Invalid State\n"); |
| return OMX_ErrorInvalidState; |
| } |
| if ( m_state == OMX_StateExecuting) |
| { |
| DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n"); |
| return OMX_ErrorInvalidState; |
| } |
| |
| switch (configIndex) |
| { |
| case OMX_IndexConfigAudioVolume: |
| { |
| OMX_AUDIO_CONFIG_VOLUMETYPE *vol = |
| (OMX_AUDIO_CONFIG_VOLUMETYPE*)configData; |
| if (vol->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) |
| { |
| if ((vol->sVolume.nValue <= OMX_AENC_MAX) && |
| (vol->sVolume.nValue >= OMX_AENC_MIN)) |
| { |
| m_volume = vol->sVolume.nValue; |
| if (BITMASK_ABSENT(&m_flags, OMX_COMPONENT_MUTED)) |
| { |
| /* ioctl(m_drv_fd, AUDIO_VOLUME, |
| m_volume * OMX_AENC_VOLUME_STEP); */ |
| } |
| |
| } else |
| { |
| eRet = OMX_ErrorBadParameter; |
| } |
| } else |
| { |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| } |
| break; |
| |
| case OMX_IndexConfigAudioMute: |
| { |
| OMX_AUDIO_CONFIG_MUTETYPE *mute = (OMX_AUDIO_CONFIG_MUTETYPE*) |
| configData; |
| if (mute->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) |
| { |
| if (mute->bMute == OMX_TRUE) |
| { |
| BITMASK_SET(&m_flags, OMX_COMPONENT_MUTED); |
| /* ioctl(m_drv_fd, AUDIO_VOLUME, 0); */ |
| } else |
| { |
| BITMASK_CLEAR(&m_flags, OMX_COMPONENT_MUTED); |
| /* ioctl(m_drv_fd, AUDIO_VOLUME, |
| m_volume * OMX_AENC_VOLUME_STEP); */ |
| } |
| } else |
| { |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| } |
| break; |
| |
| default: |
| eRet = OMX_ErrorUnsupportedIndex; |
| break; |
| } |
| return eRet; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::GetExtensionIndex |
| |
| DESCRIPTION |
| OMX GetExtensionIndex method implementaion. <TBD> |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| OMX Error None if everything successful. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::get_extension_index( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_STRING paramName, |
| OMX_OUT OMX_INDEXTYPE* indexType) |
| { |
| if((hComp == NULL) || (paramName == NULL) || (indexType == NULL)) |
| { |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (m_state == OMX_StateInvalid) |
| { |
| DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n"); |
| return OMX_ErrorInvalidState; |
| } |
| if(strncmp(paramName,"OMX.Qualcomm.index.audio.sessionId", |
| strlen("OMX.Qualcomm.index.audio.sessionId")) == 0) |
| { |
| *indexType =(OMX_INDEXTYPE)QOMX_IndexParamAudioSessionId; |
| DEBUG_PRINT("Extension index type - %d\n", *indexType); |
| |
| } |
| else |
| { |
| return OMX_ErrorBadParameter; |
| |
| } |
| return OMX_ErrorNone; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::GetState |
| |
| DESCRIPTION |
| Returns the state information back to the caller.<TBD> |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| Error None if everything is successful. |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::get_state(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_OUT OMX_STATETYPE* state) |
| { |
| if(hComp == NULL) |
| { |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| *state = m_state; |
| DEBUG_PRINT("Returning the state %d\n",*state); |
| return OMX_ErrorNone; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::ComponentTunnelRequest |
| |
| DESCRIPTION |
| OMX Component Tunnel Request method implementation. <TBD> |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| OMX Error None if everything successful. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::component_tunnel_request |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_HANDLETYPE peerComponent, |
| OMX_IN OMX_U32 peerPort, |
| OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) |
| { |
| DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n"); |
| |
| if((hComp == NULL) || (peerComponent == NULL) || (tunnelSetup == NULL)) |
| { |
| port = port; |
| peerPort = peerPort; |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| return OMX_ErrorNotImplemented; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::AllocateInputBuffer |
| |
| DESCRIPTION |
| Helper function for allocate buffer in the input pin |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::allocate_input_buffer |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_PTR appData, |
| OMX_IN OMX_U32 bytes) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| OMX_BUFFERHEADERTYPE *bufHdr; |
| unsigned nBufSize = MAX(bytes, input_buffer_size); |
| char *buf_ptr; |
| if(m_inp_current_buf_count < m_inp_act_buf_count) |
| { |
| buf_ptr = (char *) calloc((nBufSize + \ |
| sizeof(OMX_BUFFERHEADERTYPE)+sizeof(META_IN)) , 1); |
| |
| if(hComp == NULL) |
| { |
| port = port; |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| free(buf_ptr); |
| return OMX_ErrorBadParameter; |
| } |
| if (buf_ptr != NULL) |
| { |
| bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr; |
| *bufferHdr = bufHdr; |
| memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE)); |
| |
| bufHdr->pBuffer = (OMX_U8 *)((buf_ptr) + sizeof(META_IN)+ |
| sizeof(OMX_BUFFERHEADERTYPE)); |
| bufHdr->nSize = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE); |
| bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; |
| bufHdr->nAllocLen = nBufSize; |
| bufHdr->pAppPrivate = appData; |
| bufHdr->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; |
| m_input_buf_hdrs.insert(bufHdr, NULL); |
| |
| m_inp_current_buf_count++; |
| DEBUG_PRINT("AIB:bufHdr %p bufHdr->pBuffer %p m_inp_buf_cnt=%u \ |
| bytes=%u", bufHdr, bufHdr->pBuffer, |
| m_inp_current_buf_count, bytes); |
| |
| } else |
| { |
| DEBUG_PRINT("Input buffer memory allocation failed 1 \n"); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| } |
| else |
| { |
| DEBUG_PRINT("Input buffer memory allocation failed 2\n"); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| return eRet; |
| } |
| |
| OMX_ERRORTYPE omx_evrc_aenc::allocate_output_buffer |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_PTR appData, |
| OMX_IN OMX_U32 bytes) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| OMX_BUFFERHEADERTYPE *bufHdr; |
| unsigned nBufSize = MAX(bytes,output_buffer_size); |
| char *buf_ptr; |
| |
| if(hComp == NULL) |
| { |
| port = port; |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (m_out_current_buf_count < m_out_act_buf_count) |
| { |
| buf_ptr = (char *) calloc( (nBufSize + sizeof(OMX_BUFFERHEADERTYPE)),1); |
| |
| if (buf_ptr != NULL) |
| { |
| bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr; |
| *bufferHdr = bufHdr; |
| memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE)); |
| |
| bufHdr->pBuffer = (OMX_U8 *)((buf_ptr) + |
| sizeof(OMX_BUFFERHEADERTYPE)); |
| bufHdr->nSize = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE); |
| bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; |
| bufHdr->nAllocLen = nBufSize; |
| bufHdr->pAppPrivate = appData; |
| bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; |
| m_output_buf_hdrs.insert(bufHdr, NULL); |
| m_out_current_buf_count++; |
| DEBUG_PRINT("AOB::bufHdr %p bufHdr->pBuffer %p m_out_buf_cnt=%d "\ |
| "bytes=%u",bufHdr, bufHdr->pBuffer,\ |
| m_out_current_buf_count, bytes); |
| } else |
| { |
| DEBUG_PRINT("Output buffer memory allocation failed 1 \n"); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| } else |
| { |
| DEBUG_PRINT("Output buffer memory allocation failed\n"); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| return eRet; |
| } |
| |
| |
| // AllocateBuffer -- API Call |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::AllocateBuffer |
| |
| DESCRIPTION |
| Returns zero if all the buffers released.. |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::allocate_buffer |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_PTR appData, |
| OMX_IN OMX_U32 bytes) |
| { |
| |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type |
| |
| if (m_state == OMX_StateInvalid) |
| { |
| DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n"); |
| return OMX_ErrorInvalidState; |
| } |
| // What if the client calls again. |
| if (OMX_CORE_INPUT_PORT_INDEX == port) |
| { |
| eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); |
| } else if (OMX_CORE_OUTPUT_PORT_INDEX == port) |
| { |
| eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); |
| } else |
| { |
| DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n", |
| (int)port); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| |
| if (eRet == OMX_ErrorNone) |
| { |
| DEBUG_PRINT("allocate_buffer: before allocate_done \n"); |
| if (allocate_done()) |
| { |
| DEBUG_PRINT("allocate_buffer: after allocate_done \n"); |
| if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) |
| { |
| BITMASK_CLEAR(&m_flags, OMX_COMPONENT_IDLE_PENDING); |
| post_command(OMX_CommandStateSet,OMX_StateIdle, |
| OMX_COMPONENT_GENERATE_EVENT); |
| DEBUG_PRINT("allocate_buffer: post idle transition event \n"); |
| } |
| DEBUG_PRINT("allocate_buffer: complete \n"); |
| } |
| if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) |
| { |
| if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) |
| { |
| BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); |
| post_command(OMX_CommandPortEnable, OMX_CORE_INPUT_PORT_INDEX, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } |
| } |
| if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) |
| { |
| if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) |
| { |
| BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); |
| m_out_bEnabled = OMX_TRUE; |
| |
| DEBUG_PRINT("AllocBuf-->is_out_th_sleep=%d\n",is_out_th_sleep); |
| pthread_mutex_lock(&m_out_th_lock_1); |
| if (is_out_th_sleep) |
| { |
| is_out_th_sleep = false; |
| DEBUG_DETAIL("AllocBuf:WAKING UP OUT THREADS\n"); |
| out_th_wakeup(); |
| } |
| pthread_mutex_unlock(&m_out_th_lock_1); |
| pthread_mutex_lock(&m_in_th_lock_1); |
| if(is_in_th_sleep) |
| { |
| is_in_th_sleep = false; |
| DEBUG_DETAIL("AB:WAKING UP IN THREADS\n"); |
| in_th_wakeup(); |
| } |
| pthread_mutex_unlock(&m_in_th_lock_1); |
| post_command(OMX_CommandPortEnable, OMX_CORE_OUTPUT_PORT_INDEX, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } |
| } |
| } |
| DEBUG_PRINT("Allocate Buffer exit with ret Code %d\n", eRet); |
| return eRet; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| use_buffer |
| |
| DESCRIPTION: |
| OMX Use Buffer method implementation. |
| |
| INPUT/OUTPUT PARAMETERS: |
| [INOUT] bufferHdr |
| [IN] hComp |
| [IN] port |
| [IN] appData |
| [IN] bytes |
| [IN] buffer |
| |
| RETURN VALUE: |
| OMX_ERRORTYPE |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| OMX_ERRORTYPE omx_evrc_aenc::use_buffer |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_PTR appData, |
| OMX_IN OMX_U32 bytes, |
| OMX_IN OMX_U8* buffer) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| |
| if (OMX_CORE_INPUT_PORT_INDEX == port) |
| { |
| eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer); |
| |
| } else if (OMX_CORE_OUTPUT_PORT_INDEX == port) |
| { |
| eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); |
| } else |
| { |
| DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| |
| if (eRet == OMX_ErrorNone) |
| { |
| DEBUG_PRINT("Checking for Output Allocate buffer Done"); |
| if (allocate_done()) |
| { |
| if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) |
| { |
| BITMASK_CLEAR(&m_flags, OMX_COMPONENT_IDLE_PENDING); |
| post_command(OMX_CommandStateSet,OMX_StateIdle, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } |
| } |
| if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) |
| { |
| if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) |
| { |
| BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); |
| post_command(OMX_CommandPortEnable, OMX_CORE_INPUT_PORT_INDEX, |
| OMX_COMPONENT_GENERATE_EVENT); |
| |
| } |
| } |
| if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) |
| { |
| if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) |
| { |
| BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); |
| post_command(OMX_CommandPortEnable, OMX_CORE_OUTPUT_PORT_INDEX, |
| OMX_COMPONENT_GENERATE_EVENT); |
| pthread_mutex_lock(&m_out_th_lock_1); |
| if (is_out_th_sleep) |
| { |
| is_out_th_sleep = false; |
| DEBUG_DETAIL("UseBuf:WAKING UP OUT THREADS\n"); |
| out_th_wakeup(); |
| } |
| pthread_mutex_unlock(&m_out_th_lock_1); |
| pthread_mutex_lock(&m_in_th_lock_1); |
| if(is_in_th_sleep) |
| { |
| is_in_th_sleep = false; |
| DEBUG_DETAIL("UB:WAKING UP IN THREADS\n"); |
| in_th_wakeup(); |
| } |
| pthread_mutex_unlock(&m_in_th_lock_1); |
| } |
| } |
| } |
| DEBUG_PRINT("Use Buffer for port[%u] eRet[%d]\n", port,eRet); |
| return eRet; |
| } |
| /*============================================================================= |
| FUNCTION: |
| use_input_buffer |
| |
| DESCRIPTION: |
| Helper function for Use buffer in the input pin |
| |
| INPUT/OUTPUT PARAMETERS: |
| [INOUT] bufferHdr |
| [IN] hComp |
| [IN] port |
| [IN] appData |
| [IN] bytes |
| [IN] buffer |
| |
| RETURN VALUE: |
| OMX_ERRORTYPE |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| OMX_ERRORTYPE omx_evrc_aenc::use_input_buffer |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_PTR appData, |
| OMX_IN OMX_U32 bytes, |
| OMX_IN OMX_U8* buffer) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| OMX_BUFFERHEADERTYPE *bufHdr; |
| unsigned nBufSize = MAX(bytes, input_buffer_size); |
| char *buf_ptr; |
| |
| if(hComp == NULL) |
| { |
| port = port; |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if(bytes < input_buffer_size) |
| { |
| /* return if i\p buffer size provided by client |
| is less than min i\p buffer size supported by omx component*/ |
| return OMX_ErrorInsufficientResources; |
| } |
| if (m_inp_current_buf_count < m_inp_act_buf_count) |
| { |
| buf_ptr = (char *) calloc(sizeof(OMX_BUFFERHEADERTYPE), 1); |
| |
| if (buf_ptr != NULL) |
| { |
| bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr; |
| *bufferHdr = bufHdr; |
| memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE)); |
| |
| bufHdr->pBuffer = (OMX_U8 *)(buffer); |
| DEBUG_PRINT("use_input_buffer:bufHdr %p bufHdr->pBuffer %p \ |
| bytes=%u", bufHdr, bufHdr->pBuffer,bytes); |
| bufHdr->nSize = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE); |
| bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; |
| bufHdr->nAllocLen = nBufSize; |
| input_buffer_size = nBufSize; |
| bufHdr->pAppPrivate = appData; |
| bufHdr->nInputPortIndex = OMX_CORE_INPUT_PORT_INDEX; |
| bufHdr->nOffset = 0; |
| m_input_buf_hdrs.insert(bufHdr, NULL); |
| m_inp_current_buf_count++; |
| } else |
| { |
| DEBUG_PRINT("Input buffer memory allocation failed 1 \n"); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| } else |
| { |
| DEBUG_PRINT("Input buffer memory allocation failed\n"); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| return eRet; |
| } |
| |
| /*============================================================================= |
| FUNCTION: |
| use_output_buffer |
| |
| DESCRIPTION: |
| Helper function for Use buffer in the output pin |
| |
| INPUT/OUTPUT PARAMETERS: |
| [INOUT] bufferHdr |
| [IN] hComp |
| [IN] port |
| [IN] appData |
| [IN] bytes |
| [IN] buffer |
| |
| RETURN VALUE: |
| OMX_ERRORTYPE |
| |
| Dependency: |
| None |
| |
| SIDE EFFECTS: |
| None |
| =============================================================================*/ |
| OMX_ERRORTYPE omx_evrc_aenc::use_output_buffer |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_PTR appData, |
| OMX_IN OMX_U32 bytes, |
| OMX_IN OMX_U8* buffer) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| OMX_BUFFERHEADERTYPE *bufHdr; |
| unsigned nBufSize = MAX(bytes,output_buffer_size); |
| char *buf_ptr; |
| |
| if(hComp == NULL) |
| { |
| port = port; |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (bytes < output_buffer_size) |
| { |
| /* return if o\p buffer size provided by client |
| is less than min o\p buffer size supported by omx component*/ |
| return OMX_ErrorInsufficientResources; |
| } |
| |
| DEBUG_PRINT("Inside omx_evrc_aenc::use_output_buffer"); |
| if (m_out_current_buf_count < m_out_act_buf_count) |
| { |
| |
| buf_ptr = (char *) calloc(sizeof(OMX_BUFFERHEADERTYPE), 1); |
| |
| if (buf_ptr != NULL) |
| { |
| bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr; |
| DEBUG_PRINT("BufHdr=%p buffer=%p\n",bufHdr,buffer); |
| *bufferHdr = bufHdr; |
| memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE)); |
| |
| bufHdr->pBuffer = (OMX_U8 *)(buffer); |
| DEBUG_PRINT("use_output_buffer:bufHdr %p bufHdr->pBuffer %p \ |
| len=%u\n", bufHdr, bufHdr->pBuffer,bytes); |
| bufHdr->nSize = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE); |
| bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; |
| bufHdr->nAllocLen = nBufSize; |
| output_buffer_size = nBufSize; |
| bufHdr->pAppPrivate = appData; |
| bufHdr->nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX; |
| bufHdr->nOffset = 0; |
| m_output_buf_hdrs.insert(bufHdr, NULL); |
| m_out_current_buf_count++; |
| |
| } else |
| { |
| DEBUG_PRINT("Output buffer memory allocation failed\n"); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| } else |
| { |
| DEBUG_PRINT("Output buffer memory allocation failed 2\n"); |
| eRet = OMX_ErrorInsufficientResources; |
| } |
| return eRet; |
| } |
| /** |
| @brief member function that searches for caller buffer |
| |
| @param buffer pointer to buffer header |
| @return bool value indicating whether buffer is found |
| */ |
| bool omx_evrc_aenc::search_input_bufhdr(OMX_BUFFERHEADERTYPE *buffer) |
| { |
| |
| bool eRet = false; |
| OMX_BUFFERHEADERTYPE *temp = NULL; |
| |
| //access only in IL client context |
| temp = m_input_buf_hdrs.find_ele(buffer); |
| if (buffer && temp) |
| { |
| DEBUG_DETAIL("search_input_bufhdr %p \n", buffer); |
| eRet = true; |
| } |
| return eRet; |
| } |
| |
| /** |
| @brief member function that searches for caller buffer |
| |
| @param buffer pointer to buffer header |
| @return bool value indicating whether buffer is found |
| */ |
| bool omx_evrc_aenc::search_output_bufhdr(OMX_BUFFERHEADERTYPE *buffer) |
| { |
| |
| bool eRet = false; |
| OMX_BUFFERHEADERTYPE *temp = NULL; |
| |
| //access only in IL client context |
| temp = m_output_buf_hdrs.find_ele(buffer); |
| if (buffer && temp) |
| { |
| DEBUG_DETAIL("search_output_bufhdr %p \n", buffer); |
| eRet = true; |
| } |
| return eRet; |
| } |
| |
| // Free Buffer - API call |
| /** |
| @brief member function that handles free buffer command from IL client |
| |
| This function is a block-call function that handles IL client request to |
| freeing the buffer |
| |
| @param hComp handle to component instance |
| @param port id of port which holds the buffer |
| @param buffer buffer header |
| @return Error status |
| */ |
| OMX_ERRORTYPE omx_evrc_aenc::free_buffer(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_BUFFERHEADERTYPE* buffer) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| |
| DEBUG_PRINT("Free_Buffer buf %p\n", buffer); |
| if(hComp == NULL) |
| { |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (m_state == OMX_StateIdle && |
| (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) |
| { |
| DEBUG_PRINT(" free buffer while Component in Loading pending\n"); |
| } else if ((m_inp_bEnabled == OMX_FALSE && |
| port == OMX_CORE_INPUT_PORT_INDEX)|| |
| (m_out_bEnabled == OMX_FALSE && |
| port == OMX_CORE_OUTPUT_PORT_INDEX)) |
| { |
| DEBUG_PRINT("Free Buffer while port %u disabled\n", port); |
| } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) |
| { |
| DEBUG_PRINT("Invalid state to free buffer,ports need to be disabled:\ |
| OMX_ErrorPortUnpopulated\n"); |
| post_command(OMX_EventError, |
| OMX_ErrorPortUnpopulated, |
| OMX_COMPONENT_GENERATE_EVENT); |
| |
| return eRet; |
| } else |
| { |
| DEBUG_PRINT("free_buffer: Invalid state to free buffer,ports need to be\ |
| disabled:OMX_ErrorPortUnpopulated\n"); |
| post_command(OMX_EventError, |
| OMX_ErrorPortUnpopulated, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } |
| if (OMX_CORE_INPUT_PORT_INDEX == port) |
| { |
| if (m_inp_current_buf_count != 0) |
| { |
| m_inp_bPopulated = OMX_FALSE; |
| if (true == search_input_bufhdr(buffer)) |
| { |
| /* Buffer exist */ |
| //access only in IL client context |
| DEBUG_PRINT("Free_Buf:in_buffer[%p]\n",buffer); |
| m_input_buf_hdrs.erase(buffer); |
| free(buffer); |
| m_inp_current_buf_count--; |
| } else |
| { |
| DEBUG_PRINT_ERROR("Free_Buf:Error-->free_buffer, \ |
| Invalid Input buffer header\n"); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } else |
| { |
| DEBUG_PRINT_ERROR("Error: free_buffer,Port Index calculation \ |
| came out Invalid\n"); |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) |
| && release_done(0)) |
| { |
| DEBUG_PRINT("INPUT PORT MOVING TO DISABLED STATE \n"); |
| BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); |
| post_command(OMX_CommandPortDisable, |
| OMX_CORE_INPUT_PORT_INDEX, |
| OMX_COMPONENT_GENERATE_EVENT); |
| } |
| } else if (OMX_CORE_OUTPUT_PORT_INDEX == port) |
| { |
| if (m_out_current_buf_count != 0) |
| { |
| m_out_bPopulated = OMX_FALSE; |
| if (true == search_output_bufhdr(buffer)) |
| { |
| /* Buffer exist */ |
| //access only in IL client context |
| DEBUG_PRINT("Free_Buf:out_buffer[%p]\n",buffer); |
| m_output_buf_hdrs.erase(buffer); |
| free(buffer); |
| m_out_current_buf_count--; |
| } else |
| { |
| DEBUG_PRINT("Free_Buf:Error-->free_buffer , \ |
| Invalid Output buffer header\n"); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } else |
| { |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| |
| if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) |
| && release_done(1)) |
| { |
| DEBUG_PRINT("OUTPUT PORT MOVING TO DISABLED STATE \n"); |
| BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); |
| post_command(OMX_CommandPortDisable, |
| OMX_CORE_OUTPUT_PORT_INDEX, |
| OMX_COMPONENT_GENERATE_EVENT); |
| |
| } |
| } else |
| { |
| eRet = OMX_ErrorBadPortIndex; |
| } |
| if ((OMX_ErrorNone == eRet) && |
| (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) |
| { |
| if (release_done(-1)) |
| { |
| if(ioctl(m_drv_fd, AUDIO_STOP, 0) < 0) |
| DEBUG_PRINT_ERROR("AUDIO STOP in free buffer failed\n"); |
| else |
| DEBUG_PRINT("AUDIO STOP in free buffer passed\n"); |
| |
| |
| DEBUG_PRINT("Free_Buf: Free buffer\n"); |
| |
| |
| // Send the callback now |
| BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); |
| DEBUG_PRINT("Before OMX_StateLoaded \ |
| OMX_COMPONENT_GENERATE_EVENT\n"); |
| post_command(OMX_CommandStateSet, |
| OMX_StateLoaded,OMX_COMPONENT_GENERATE_EVENT); |
| DEBUG_PRINT("After OMX_StateLoaded OMX_COMPONENT_GENERATE_EVENT\n"); |
| |
| } |
| } |
| return eRet; |
| } |
| |
| |
| /** |
| @brief member function that that handles empty this buffer command |
| |
| This function meremly queue up the command and data would be consumed |
| in command server thread context |
| |
| @param hComp handle to component instance |
| @param buffer pointer to buffer header |
| @return error status |
| */ |
| OMX_ERRORTYPE omx_evrc_aenc::empty_this_buffer( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_BUFFERHEADERTYPE* buffer) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| |
| DEBUG_PRINT("ETB:Buf:%p Len %u TS %lld numInBuf=%d\n", \ |
| buffer, buffer->nFilledLen, buffer->nTimeStamp, (nNumInputBuf)); |
| if (m_state == OMX_StateInvalid) |
| { |
| DEBUG_PRINT("Empty this buffer in Invalid State\n"); |
| return OMX_ErrorInvalidState; |
| } |
| if (!m_inp_bEnabled) |
| { |
| DEBUG_PRINT("empty_this_buffer OMX_ErrorIncorrectStateOperation "\ |
| "Port Status %d \n", m_inp_bEnabled); |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| if (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE)) |
| { |
| DEBUG_PRINT("omx_evrc_aenc::etb--> Buffer Size Invalid\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) |
| { |
| DEBUG_PRINT("omx_evrc_aenc::etb--> OMX Version Invalid\n"); |
| return OMX_ErrorVersionMismatch; |
| } |
| |
| if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) |
| { |
| return OMX_ErrorBadPortIndex; |
| } |
| if ((m_state != OMX_StateExecuting) && |
| (m_state != OMX_StatePause)) |
| { |
| DEBUG_PRINT_ERROR("Invalid state\n"); |
| eRet = OMX_ErrorInvalidState; |
| } |
| if (OMX_ErrorNone == eRet) |
| { |
| if (search_input_bufhdr(buffer) == true) |
| { |
| post_input((unsigned long)hComp, |
| (unsigned long) buffer,OMX_COMPONENT_GENERATE_ETB); |
| } else |
| { |
| DEBUG_PRINT_ERROR("Bad header %p \n", buffer); |
| eRet = OMX_ErrorBadParameter; |
| } |
| } |
| pthread_mutex_lock(&in_buf_count_lock); |
| nNumInputBuf++; |
| m_evrc_pb_stats.etb_cnt++; |
| pthread_mutex_unlock(&in_buf_count_lock); |
| return eRet; |
| } |
| /** |
| @brief member function that writes data to kernel driver |
| |
| @param hComp handle to component instance |
| @param buffer pointer to buffer header |
| @return error status |
| */ |
| OMX_ERRORTYPE omx_evrc_aenc::empty_this_buffer_proxy |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_BUFFERHEADERTYPE* buffer) |
| { |
| OMX_STATETYPE state; |
| META_IN meta_in; |
| //Pointer to the starting location of the data to be transcoded |
| OMX_U8 *srcStart; |
| //The total length of the data to be transcoded |
| srcStart = buffer->pBuffer; |
| OMX_U8 *data = NULL; |
| PrintFrameHdr(OMX_COMPONENT_GENERATE_ETB,buffer); |
| memset(&meta_in,0,sizeof(meta_in)); |
| if ( search_input_bufhdr(buffer) == false ) |
| { |
| DEBUG_PRINT("ETBP: INVALID BUF HDR\n"); |
| buffer_done_cb((OMX_BUFFERHEADERTYPE *)buffer); |
| return OMX_ErrorBadParameter; |
| } |
| if (m_tmp_meta_buf) |
| { |
| data = m_tmp_meta_buf; |
| |
| // copy the metadata info from the BufHdr and insert to payload |
| meta_in.offsetVal = (OMX_U16)sizeof(META_IN); |
| meta_in.nTimeStamp.LowPart = |
| (unsigned int) ((((OMX_BUFFERHEADERTYPE*)buffer)->nTimeStamp) & 0xFFFFFFFF); |
| meta_in.nTimeStamp.HighPart = |
| (unsigned int) (((((OMX_BUFFERHEADERTYPE*)buffer)->nTimeStamp) >> 32) & 0xFFFFFFFF); |
| meta_in.nFlags &= ~OMX_BUFFERFLAG_EOS; |
| if(buffer->nFlags & OMX_BUFFERFLAG_EOS) |
| { |
| DEBUG_PRINT("EOS OCCURED \n"); |
| meta_in.nFlags |= OMX_BUFFERFLAG_EOS; |
| } |
| memcpy(data,&meta_in, meta_in.offsetVal); |
| DEBUG_PRINT("meta_in.nFlags = %d\n",meta_in.nFlags); |
| } |
| |
| memcpy(&data[sizeof(META_IN)],buffer->pBuffer,buffer->nFilledLen); |
| write(m_drv_fd, data, buffer->nFilledLen+sizeof(META_IN)); |
| |
| pthread_mutex_lock(&m_state_lock); |
| get_state(&m_cmp, &state); |
| pthread_mutex_unlock(&m_state_lock); |
| |
| if (OMX_StateExecuting == state) |
| { |
| DEBUG_DETAIL("In Exe state, EBD CB"); |
| buffer_done_cb((OMX_BUFFERHEADERTYPE *)buffer); |
| } else |
| { |
| /* Assume empty this buffer function has already checked |
| validity of buffer */ |
| DEBUG_PRINT("Empty buffer %p to kernel driver\n", buffer); |
| post_input((unsigned long) & hComp,(unsigned long) buffer, |
| OMX_COMPONENT_GENERATE_BUFFER_DONE); |
| } |
| return OMX_ErrorNone; |
| } |
| |
| OMX_ERRORTYPE omx_evrc_aenc::fill_this_buffer_proxy |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_BUFFERHEADERTYPE* buffer) |
| { |
| OMX_STATETYPE state; |
| ENC_META_OUT *meta_out = NULL; |
| ssize_t nReadbytes = 0; |
| |
| pthread_mutex_lock(&m_state_lock); |
| get_state(&m_cmp, &state); |
| pthread_mutex_unlock(&m_state_lock); |
| |
| if (true == search_output_bufhdr(buffer)) |
| { |
| DEBUG_PRINT("\nBefore Read..m_drv_fd = %d,\n",m_drv_fd); |
| nReadbytes = read(m_drv_fd,buffer->pBuffer,output_buffer_size ); |
| DEBUG_DETAIL("FTBP->Al_len[%lu]buf[%p]size[%d]numOutBuf[%d]\n",\ |
| buffer->nAllocLen,buffer->pBuffer, |
| nReadbytes,nNumOutputBuf); |
| if (nReadbytes <= 0) { |
| buffer->nFilledLen = 0; |
| buffer->nOffset = 0; |
| buffer->nTimeStamp = nTimestamp; |
| frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer); |
| return OMX_ErrorNone; |
| } else |
| DEBUG_PRINT("Read bytes %d\n",nReadbytes); |
| // Buffer from Driver will have |
| // 1 byte => Nr of frame field |
| // (sizeof(ENC_META_OUT) * Nr of frame) bytes => meta_out->offset_to_frame |
| // Frame Size * Nr of frame => |
| |
| meta_out = (ENC_META_OUT *)(buffer->pBuffer + sizeof(unsigned char)); |
| buffer->nTimeStamp = (((OMX_TICKS) meta_out->msw_ts << 32)+ |
| meta_out->lsw_ts); |
| buffer->nFlags |= meta_out->nflags; |
| buffer->nOffset = (OMX_U32)(meta_out->offset_to_frame + |
| sizeof(unsigned char)); |
| buffer->nFilledLen = (OMX_U32)(nReadbytes - buffer->nOffset); |
| nTimestamp = buffer->nTimeStamp; |
| DEBUG_PRINT("nflags %d frame_size %d offset_to_frame %d \ |
| timestamp %lld\n", meta_out->nflags, |
| meta_out->frame_size, meta_out->offset_to_frame, |
| buffer->nTimeStamp); |
| |
| if ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS ) |
| { |
| buffer->nFilledLen = 0; |
| buffer->nOffset = 0; |
| buffer->nTimeStamp = nTimestamp; |
| frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer); |
| if ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS ) |
| { |
| DEBUG_PRINT("FTBP: Now, Send EOS flag to Client \n"); |
| m_cb.EventHandler(&m_cmp, |
| m_app_data, |
| OMX_EventBufferFlag, |
| 1, 1, NULL ); |
| } |
| |
| return OMX_ErrorNone; |
| } |
| DEBUG_PRINT("nState %d \n",nState ); |
| |
| pthread_mutex_lock(&m_state_lock); |
| get_state(&m_cmp, &state); |
| pthread_mutex_unlock(&m_state_lock); |
| |
| if (state == OMX_StatePause) |
| { |
| DEBUG_PRINT("FTBP:Post the FBD to event thread currstate=%d\n",\ |
| state); |
| post_output((unsigned long) & hComp,(unsigned long) buffer, |
| OMX_COMPONENT_GENERATE_FRAME_DONE); |
| } |
| else |
| { |
| frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer); |
| |
| } |
| |
| } |
| else |
| DEBUG_PRINT("\n FTBP-->Invalid buffer in FTB \n"); |
| |
| |
| return OMX_ErrorNone; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::FillThisBuffer |
| |
| DESCRIPTION |
| IL client uses this method to release the frame buffer |
| after displaying them. |
| |
| |
| |
| PARAMETERS |
| |
| None. |
| |
| RETURN VALUE |
| true/false |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::fill_this_buffer |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_BUFFERHEADERTYPE* buffer) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| if (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE)) |
| { |
| DEBUG_PRINT("omx_evrc_aenc::ftb--> Buffer Size Invalid\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (m_out_bEnabled == OMX_FALSE) |
| { |
| return OMX_ErrorIncorrectStateOperation; |
| } |
| |
| if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) |
| { |
| DEBUG_PRINT("omx_evrc_aenc::ftb--> OMX Version Invalid\n"); |
| return OMX_ErrorVersionMismatch; |
| } |
| if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) |
| { |
| return OMX_ErrorBadPortIndex; |
| } |
| pthread_mutex_lock(&out_buf_count_lock); |
| nNumOutputBuf++; |
| m_evrc_pb_stats.ftb_cnt++; |
| DEBUG_DETAIL("FTB:nNumOutputBuf is %d", nNumOutputBuf); |
| pthread_mutex_unlock(&out_buf_count_lock); |
| post_output((unsigned long)hComp, |
| (unsigned long) buffer,OMX_COMPONENT_GENERATE_FTB); |
| return eRet; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::SetCallbacks |
| |
| DESCRIPTION |
| Set the callbacks. |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| OMX Error None if everything successful. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_IN OMX_CALLBACKTYPE* callbacks, |
| OMX_IN OMX_PTR appData) |
| { |
| if(hComp == NULL) |
| { |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| m_cb = *callbacks; |
| m_app_data = appData; |
| |
| return OMX_ErrorNone; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::ComponentDeInit |
| |
| DESCRIPTION |
| Destroys the component and release memory allocated to the heap. |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| OMX Error None if everything successful. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::component_deinit(OMX_IN OMX_HANDLETYPE hComp) |
| { |
| if(hComp == NULL) |
| { |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (OMX_StateLoaded != m_state && OMX_StateInvalid != m_state) |
| { |
| DEBUG_PRINT_ERROR("Warning: Rxed DeInit when not in LOADED state %d\n", |
| m_state); |
| } |
| deinit_encoder(); |
| |
| DEBUG_PRINT_ERROR("%s:COMPONENT DEINIT...\n", __FUNCTION__); |
| return OMX_ErrorNone; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::deinit_encoder |
| |
| DESCRIPTION |
| Closes all the threads and release memory allocated to the heap. |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| None. |
| |
| ========================================================================== */ |
| void omx_evrc_aenc::deinit_encoder() |
| { |
| DEBUG_PRINT("Component-deinit being processed\n"); |
| DEBUG_PRINT("********************************\n"); |
| DEBUG_PRINT("STATS: in-buf-len[%u]out-buf-len[%u] tot-pb-time[%lld]",\ |
| m_evrc_pb_stats.tot_in_buf_len, |
| m_evrc_pb_stats.tot_out_buf_len, |
| m_evrc_pb_stats.tot_pb_time); |
| DEBUG_PRINT("STATS: fbd-cnt[%u]ftb-cnt[%u]etb-cnt[%u]ebd-cnt[%u]",\ |
| m_evrc_pb_stats.fbd_cnt,m_evrc_pb_stats.ftb_cnt, |
| m_evrc_pb_stats.etb_cnt, |
| m_evrc_pb_stats.ebd_cnt); |
| memset(&m_evrc_pb_stats,0,sizeof(EVRC_PB_STATS)); |
| |
| if((OMX_StateLoaded != m_state) && (OMX_StateInvalid != m_state)) |
| { |
| DEBUG_PRINT_ERROR("%s,Deinit called in state[%d]\n",__FUNCTION__,\ |
| m_state); |
| // Get back any buffers from driver |
| if(pcm_input) |
| execute_omx_flush(-1,false); |
| else |
| execute_omx_flush(1,false); |
| // force state change to loaded so that all threads can be exited |
| pthread_mutex_lock(&m_state_lock); |
| m_state = OMX_StateLoaded; |
| pthread_mutex_unlock(&m_state_lock); |
| DEBUG_PRINT_ERROR("Freeing Buf:inp_current_buf_count[%d][%d]\n",\ |
| m_inp_current_buf_count, |
| m_input_buf_hdrs.size()); |
| m_input_buf_hdrs.eraseall(); |
| DEBUG_PRINT_ERROR("Freeing Buf:out_current_buf_count[%d][%d]\n",\ |
| m_out_current_buf_count, |
| m_output_buf_hdrs.size()); |
| m_output_buf_hdrs.eraseall(); |
| |
| } |
| if(pcm_input) |
| { |
| pthread_mutex_lock(&m_in_th_lock_1); |
| if (is_in_th_sleep) |
| { |
| is_in_th_sleep = false; |
| DEBUG_DETAIL("Deinit:WAKING UP IN THREADS\n"); |
| in_th_wakeup(); |
| } |
| pthread_mutex_unlock(&m_in_th_lock_1); |
| } |
| pthread_mutex_lock(&m_out_th_lock_1); |
| if (is_out_th_sleep) |
| { |
| is_out_th_sleep = false; |
| DEBUG_DETAIL("SCP:WAKING UP OUT THREADS\n"); |
| out_th_wakeup(); |
| } |
| pthread_mutex_unlock(&m_out_th_lock_1); |
| if(pcm_input) |
| { |
| if (m_ipc_to_in_th != NULL) |
| { |
| omx_evrc_thread_stop(m_ipc_to_in_th); |
| m_ipc_to_in_th = NULL; |
| } |
| } |
| |
| if (m_ipc_to_cmd_th != NULL) |
| { |
| omx_evrc_thread_stop(m_ipc_to_cmd_th); |
| m_ipc_to_cmd_th = NULL; |
| } |
| if (m_ipc_to_out_th != NULL) |
| { |
| DEBUG_DETAIL("Inside omx_evrc_thread_stop\n"); |
| omx_evrc_thread_stop(m_ipc_to_out_th); |
| m_ipc_to_out_th = NULL; |
| } |
| |
| |
| if(ioctl(m_drv_fd, AUDIO_STOP, 0) <0) |
| DEBUG_PRINT_ERROR("De-init: AUDIO_STOP FAILED\n"); |
| |
| if(pcm_input && m_tmp_meta_buf ) |
| { |
| free(m_tmp_meta_buf); |
| } |
| |
| if(m_tmp_out_meta_buf) |
| { |
| free(m_tmp_out_meta_buf); |
| } |
| nNumInputBuf = 0; |
| nNumOutputBuf = 0; |
| bFlushinprogress = 0; |
| |
| m_inp_current_buf_count=0; |
| m_out_current_buf_count=0; |
| m_out_act_buf_count = 0; |
| m_inp_act_buf_count = 0; |
| m_inp_bEnabled = OMX_FALSE; |
| m_out_bEnabled = OMX_FALSE; |
| m_inp_bPopulated = OMX_FALSE; |
| m_out_bPopulated = OMX_FALSE; |
| |
| if ( m_drv_fd >= 0 ) |
| { |
| if(close(m_drv_fd) < 0) |
| DEBUG_PRINT("De-init: Driver Close Failed \n"); |
| m_drv_fd = -1; |
| } |
| else |
| { |
| DEBUG_PRINT_ERROR(" EVRC device already closed\n"); |
| } |
| m_comp_deinit=1; |
| m_is_out_th_sleep = 1; |
| m_is_in_th_sleep = 1; |
| DEBUG_PRINT("************************************\n"); |
| DEBUG_PRINT(" DEINIT COMPLETED"); |
| DEBUG_PRINT("************************************\n"); |
| |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::UseEGLImage |
| |
| DESCRIPTION |
| OMX Use EGL Image method implementation <TBD>. |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| Not Implemented error. |
| |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::use_EGL_image |
| ( |
| OMX_IN OMX_HANDLETYPE hComp, |
| OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, |
| OMX_IN OMX_U32 port, |
| OMX_IN OMX_PTR appData, |
| OMX_IN void* eglImage) |
| { |
| DEBUG_PRINT_ERROR("Error : use_EGL_image: Not Implemented \n"); |
| |
| if((hComp == NULL) || (appData == NULL) || (eglImage == NULL)) |
| { |
| bufferHdr = bufferHdr; |
| port = port; |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| return OMX_ErrorNotImplemented; |
| } |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::ComponentRoleEnum |
| |
| DESCRIPTION |
| OMX Component Role Enum method implementation. |
| |
| PARAMETERS |
| <TBD>. |
| |
| RETURN VALUE |
| OMX Error None if everything is successful. |
| ========================================================================== */ |
| OMX_ERRORTYPE omx_evrc_aenc::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, |
| OMX_OUT OMX_U8* role, |
| OMX_IN OMX_U32 index) |
| { |
| OMX_ERRORTYPE eRet = OMX_ErrorNone; |
| const char *cmp_role = "audio_encoder.evrc"; |
| |
| if(hComp == NULL) |
| { |
| DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n"); |
| return OMX_ErrorBadParameter; |
| } |
| if (index == 0 && role) |
| { |
| memcpy(role, cmp_role, strlen(cmp_role)); |
| *(((char *) role) + strlen(cmp_role) + 1) = '\0'; |
| } else |
| { |
| eRet = OMX_ErrorNoMore; |
| } |
| return eRet; |
| } |
| |
| |
| |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::AllocateDone |
| |
| DESCRIPTION |
| Checks if entire buffer pool is allocated by IL Client or not. |
| Need this to move to IDLE state. |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false. |
| |
| ========================================================================== */ |
| bool omx_evrc_aenc::allocate_done(void) |
| { |
| OMX_BOOL bRet = OMX_FALSE; |
| if (pcm_input==1) |
| { |
| if ((m_inp_act_buf_count == m_inp_current_buf_count) |
| &&(m_out_act_buf_count == m_out_current_buf_count)) |
| { |
| bRet=OMX_TRUE; |
| |
| } |
| if ((m_inp_act_buf_count == m_inp_current_buf_count) && m_inp_bEnabled ) |
| { |
| m_inp_bPopulated = OMX_TRUE; |
| } |
| |
| if ((m_out_act_buf_count == m_out_current_buf_count) && m_out_bEnabled ) |
| { |
| m_out_bPopulated = OMX_TRUE; |
| } |
| } else if (pcm_input==0) |
| { |
| if (m_out_act_buf_count == m_out_current_buf_count) |
| { |
| bRet=OMX_TRUE; |
| |
| } |
| if ((m_out_act_buf_count == m_out_current_buf_count) && m_out_bEnabled ) |
| { |
| m_out_bPopulated = OMX_TRUE; |
| } |
| |
| } |
| return bRet; |
| } |
| |
| |
| /* ====================================================================== |
| FUNCTION |
| omx_evrc_aenc::ReleaseDone |
| |
| DESCRIPTION |
| Checks if IL client has released all the buffers. |
| |
| PARAMETERS |
| None. |
| |
| RETURN VALUE |
| true/false |
| |
| ========================================================================== */ |
| bool omx_evrc_aenc::release_done(OMX_U32 param1) |
| { |
| DEBUG_PRINT("Inside omx_evrc_aenc::release_done"); |
| OMX_BOOL bRet = OMX_FALSE; |
| |
| if (param1 == OMX_ALL) |
| { |
| if ((0 == m_inp_current_buf_count)&&(0 == m_out_current_buf_count)) |
| { |
| bRet=OMX_TRUE; |
| } |
| } else if (param1 == OMX_CORE_INPUT_PORT_INDEX ) |
| { |
| if ((0 == m_inp_current_buf_count)) |
| { |
| bRet=OMX_TRUE; |
| } |
| } else if (param1 == OMX_CORE_OUTPUT_PORT_INDEX) |
| { |
| if ((0 == m_out_current_buf_count)) |
| { |
| bRet=OMX_TRUE; |
| } |
| } |
| return bRet; |
| } |