1/*--------------------------------------------------------------------------
2Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are met:
6    * Redistributions of source code must retain the above copyright
7      notice, this list of conditions and the following disclaimer.
8    * Redistributions in binary form must reproduce the above copyright
9      notice, this list of conditions and the following disclaimer in the
10      documentation and/or other materials provided with the distribution.
11    * Neither the name of The Linux Foundation nor
12      the names of its contributors may be used to endorse or promote
13      products derived from this software without specific prior written
14      permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27--------------------------------------------------------------------------*/
28/*============================================================================
29@file omx_aenc_amr.c
30  This module contains the implementation of the OpenMAX core & component.
31
32*//*========================================================================*/
33//////////////////////////////////////////////////////////////////////////////
34//                             Include Files
35//////////////////////////////////////////////////////////////////////////////
36
37
38#include<string.h>
39#include <fcntl.h>
40#include <sys/ioctl.h>
41#include "omx_amr_aenc.h"
42#include <errno.h>
43
44using namespace std;
45#define SLEEP_MS 100
46
47// omx_cmd_queue destructor
48omx_amr_aenc::omx_cmd_queue::~omx_cmd_queue()
49{
50    // Nothing to do
51}
52
53// omx cmd queue constructor
54omx_amr_aenc::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
55{
56    memset(m_q,      0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
57}
58
59// omx cmd queue insert
60bool omx_amr_aenc::omx_cmd_queue::insert_entry(unsigned long p1,
61                                                unsigned long p2,
62                                                unsigned char id)
63{
64    bool ret = true;
65    if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
66    {
67        m_q[m_write].id       = id;
68        m_q[m_write].param1   = p1;
69        m_q[m_write].param2   = p2;
70        m_write++;
71        m_size ++;
72        if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
73        {
74            m_write = 0;
75        }
76    } else
77    {
78        ret = false;
79        DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full");
80    }
81    return ret;
82}
83
84bool omx_amr_aenc::omx_cmd_queue::pop_entry(unsigned long *p1,
85                                             unsigned long *p2, unsigned char *id)
86{
87    bool ret = true;
88    if (m_size > 0)
89    {
90        *id = m_q[m_read].id;
91        *p1 = m_q[m_read].param1;
92        *p2 = m_q[m_read].param2;
93        // Move the read pointer ahead
94        ++m_read;
95        --m_size;
96        if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
97        {
98            m_read = 0;
99
100        }
101    } else
102    {
103        ret = false;
104        DEBUG_PRINT_ERROR("ERROR Delete!!! Command Queue Empty");
105    }
106    return ret;
107}
108
109// factory function executed by the core to create instances
110void *get_omx_component_factory_fn(void)
111{
112    return(new omx_amr_aenc);
113}
114bool omx_amr_aenc::omx_cmd_queue::get_msg_id(unsigned char *id)
115{
116   if(m_size > 0)
117   {
118       *id = m_q[m_read].id;
119       DEBUG_PRINT("get_msg_id=%d\n",*id);
120   }
121   else{
122       return false;
123   }
124   return true;
125}
126/*=============================================================================
127FUNCTION:
128  wait_for_event
129
130DESCRIPTION:
131  waits for a particular event
132
133INPUT/OUTPUT PARAMETERS:
134  None
135
136RETURN VALUE:
137  None
138
139Dependency:
140  None
141
142SIDE EFFECTS:
143   None
144=============================================================================*/
145void omx_amr_aenc::wait_for_event()
146{
147    int               rc;
148    struct timespec   ts;
149    pthread_mutex_lock(&m_event_lock);
150    while (0 == m_is_event_done)
151    {
152       clock_gettime(CLOCK_REALTIME, &ts);
153       ts.tv_sec += (SLEEP_MS/1000);
154       ts.tv_nsec += ((SLEEP_MS%1000) * 1000000);
155       rc = pthread_cond_timedwait(&cond, &m_event_lock, &ts);
156       if (rc == ETIMEDOUT && !m_is_event_done) {
157            DEBUG_PRINT("Timed out waiting for flush");
158            if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) == -1)
159                DEBUG_PRINT_ERROR("Flush:Input port, ioctl flush failed %d\n",
160                    errno);
161       }
162    }
163    m_is_event_done = 0;
164    pthread_mutex_unlock(&m_event_lock);
165}
166
167/*=============================================================================
168FUNCTION:
169  event_complete
170
171DESCRIPTION:
172  informs about the occurance of an event
173
174INPUT/OUTPUT PARAMETERS:
175  None
176
177RETURN VALUE:
178  None
179
180Dependency:
181  None
182
183SIDE EFFECTS:
184   None
185=============================================================================*/
186void omx_amr_aenc::event_complete()
187{
188    pthread_mutex_lock(&m_event_lock);
189    if (0 == m_is_event_done)
190    {
191        m_is_event_done = 1;
192        pthread_cond_signal(&cond);
193    }
194    pthread_mutex_unlock(&m_event_lock);
195}
196
197// All this non-sense because of a single amr object
198void omx_amr_aenc::in_th_goto_sleep()
199{
200    pthread_mutex_lock(&m_in_th_lock);
201    while (0 == m_is_in_th_sleep)
202    {
203        pthread_cond_wait(&in_cond, &m_in_th_lock);
204    }
205    m_is_in_th_sleep = 0;
206    pthread_mutex_unlock(&m_in_th_lock);
207}
208
209void omx_amr_aenc::in_th_wakeup()
210{
211    pthread_mutex_lock(&m_in_th_lock);
212    if (0 == m_is_in_th_sleep)
213    {
214        m_is_in_th_sleep = 1;
215        pthread_cond_signal(&in_cond);
216    }
217    pthread_mutex_unlock(&m_in_th_lock);
218}
219
220void omx_amr_aenc::out_th_goto_sleep()
221{
222
223    pthread_mutex_lock(&m_out_th_lock);
224    while (0 == m_is_out_th_sleep)
225    {
226        pthread_cond_wait(&out_cond, &m_out_th_lock);
227    }
228    m_is_out_th_sleep = 0;
229    pthread_mutex_unlock(&m_out_th_lock);
230}
231
232void omx_amr_aenc::out_th_wakeup()
233{
234    pthread_mutex_lock(&m_out_th_lock);
235    if (0 == m_is_out_th_sleep)
236    {
237        m_is_out_th_sleep = 1;
238        pthread_cond_signal(&out_cond);
239    }
240    pthread_mutex_unlock(&m_out_th_lock);
241}
242/* ======================================================================
243FUNCTION
244  omx_amr_aenc::omx_amr_aenc
245
246DESCRIPTION
247  Constructor
248
249PARAMETERS
250  None
251
252RETURN VALUE
253  None.
254========================================================================== */
255omx_amr_aenc::omx_amr_aenc(): m_tmp_meta_buf(NULL),
256        m_tmp_out_meta_buf(NULL),
257        m_flush_cnt(255),
258        m_comp_deinit(0),
259        m_volume(25),
260        m_app_data(NULL),
261        nNumInputBuf(0),
262        nNumOutputBuf(0),
263        m_drv_fd(-1),
264        bFlushinprogress(0),
265        is_in_th_sleep(false),
266        is_out_th_sleep(false),
267        m_flags(0),
268        nTimestamp(0),
269        ts(0),
270        pcm_input(0),
271        m_inp_act_buf_count (OMX_CORE_NUM_INPUT_BUFFERS),
272        m_out_act_buf_count (OMX_CORE_NUM_OUTPUT_BUFFERS),
273        m_inp_current_buf_count(0),
274        m_out_current_buf_count(0),
275        output_buffer_size((OMX_U32)OMX_AMR_OUTPUT_BUFFER_SIZE),
276        input_buffer_size(OMX_CORE_INPUT_BUFFER_SIZE),
277        m_session_id(0),
278        m_inp_bEnabled(OMX_TRUE),
279        m_out_bEnabled(OMX_TRUE),
280        m_inp_bPopulated(OMX_FALSE),
281        m_out_bPopulated(OMX_FALSE),
282        m_is_event_done(0),
283        m_state(OMX_StateInvalid),
284        m_ipc_to_in_th(NULL),
285        m_ipc_to_out_th(NULL),
286        m_ipc_to_cmd_th(NULL)
287{
288    int cond_ret = 0;
289    component_Role.nSize = 0;
290    memset(&m_cmp, 0, sizeof(m_cmp));
291    memset(&m_cb, 0, sizeof(m_cb));
292    memset(&m_pcm_param, 0, sizeof(m_pcm_param));
293    memset(&m_amr_param, 0, sizeof(m_amr_param));
294    memset(&m_amr_pb_stats, 0, sizeof(m_amr_pb_stats));
295    memset(&m_buffer_supplier, 0, sizeof(m_buffer_supplier));
296    memset(&m_priority_mgm, 0, sizeof(m_priority_mgm));
297
298    pthread_mutexattr_init(&m_lock_attr);
299    pthread_mutex_init(&m_lock, &m_lock_attr);
300    pthread_mutexattr_init(&m_commandlock_attr);
301    pthread_mutex_init(&m_commandlock, &m_commandlock_attr);
302
303    pthread_mutexattr_init(&m_outputlock_attr);
304    pthread_mutex_init(&m_outputlock, &m_outputlock_attr);
305
306    pthread_mutexattr_init(&m_state_attr);
307    pthread_mutex_init(&m_state_lock, &m_state_attr);
308
309    pthread_mutexattr_init(&m_event_attr);
310    pthread_mutex_init(&m_event_lock, &m_event_attr);
311
312    pthread_mutexattr_init(&m_flush_attr);
313    pthread_mutex_init(&m_flush_lock, &m_flush_attr);
314
315    pthread_mutexattr_init(&m_event_attr);
316    pthread_mutex_init(&m_event_lock, &m_event_attr);
317
318    pthread_mutexattr_init(&m_in_th_attr);
319    pthread_mutex_init(&m_in_th_lock, &m_in_th_attr);
320
321    pthread_mutexattr_init(&m_out_th_attr);
322    pthread_mutex_init(&m_out_th_lock, &m_out_th_attr);
323
324    pthread_mutexattr_init(&m_in_th_attr_1);
325    pthread_mutex_init(&m_in_th_lock_1, &m_in_th_attr_1);
326
327    pthread_mutexattr_init(&m_out_th_attr_1);
328    pthread_mutex_init(&m_out_th_lock_1, &m_out_th_attr_1);
329
330    pthread_mutexattr_init(&out_buf_count_lock_attr);
331    pthread_mutex_init(&out_buf_count_lock, &out_buf_count_lock_attr);
332
333    pthread_mutexattr_init(&in_buf_count_lock_attr);
334    pthread_mutex_init(&in_buf_count_lock, &in_buf_count_lock_attr);
335    if ((cond_ret = pthread_cond_init (&cond, NULL)) != 0)
336    {
337       DEBUG_PRINT_ERROR("pthread_cond_init returns non zero for cond\n");
338       if (cond_ret == EAGAIN)
339         DEBUG_PRINT_ERROR("The system lacked necessary \
340				resources(other than mem)\n");
341       else if (cond_ret == ENOMEM)
342          DEBUG_PRINT_ERROR("Insufficient memory to initialise \
343				condition variable\n");
344    }
345    if ((cond_ret = pthread_cond_init (&in_cond, NULL)) != 0)
346    {
347       DEBUG_PRINT_ERROR("pthread_cond_init returns non zero for in_cond\n");
348       if (cond_ret == EAGAIN)
349         DEBUG_PRINT_ERROR("The system lacked necessary \
350				resources(other than mem)\n");
351       else if (cond_ret == ENOMEM)
352          DEBUG_PRINT_ERROR("Insufficient memory to initialise \
353				condition variable\n");
354    }
355    if ((cond_ret = pthread_cond_init (&out_cond, NULL)) != 0)
356    {
357       DEBUG_PRINT_ERROR("pthread_cond_init returns non zero for out_cond\n");
358       if (cond_ret == EAGAIN)
359         DEBUG_PRINT_ERROR("The system lacked necessary \
360				resources(other than mem)\n");
361       else if (cond_ret == ENOMEM)
362          DEBUG_PRINT_ERROR("Insufficient memory to initialise \
363				condition variable\n");
364    }
365
366    sem_init(&sem_read_msg,0, 0);
367    sem_init(&sem_write_msg,0, 0);
368    sem_init(&sem_States,0, 0);
369    return;
370}
371
372
373/* ======================================================================
374FUNCTION
375  omx_amr_aenc::~omx_amr_aenc
376
377DESCRIPTION
378  Destructor
379
380PARAMETERS
381  None
382
383RETURN VALUE
384  None.
385========================================================================== */
386omx_amr_aenc::~omx_amr_aenc()
387{
388    DEBUG_PRINT_ERROR("AMR Object getting destroyed comp-deinit=%d\n",
389			m_comp_deinit);
390    if ( !m_comp_deinit )
391    {
392        deinit_encoder();
393    }
394    pthread_mutexattr_destroy(&m_lock_attr);
395    pthread_mutex_destroy(&m_lock);
396
397    pthread_mutexattr_destroy(&m_commandlock_attr);
398    pthread_mutex_destroy(&m_commandlock);
399
400    pthread_mutexattr_destroy(&m_outputlock_attr);
401    pthread_mutex_destroy(&m_outputlock);
402
403    pthread_mutexattr_destroy(&m_state_attr);
404    pthread_mutex_destroy(&m_state_lock);
405
406    pthread_mutexattr_destroy(&m_event_attr);
407    pthread_mutex_destroy(&m_event_lock);
408
409    pthread_mutexattr_destroy(&m_flush_attr);
410    pthread_mutex_destroy(&m_flush_lock);
411
412    pthread_mutexattr_destroy(&m_in_th_attr);
413    pthread_mutex_destroy(&m_in_th_lock);
414
415    pthread_mutexattr_destroy(&m_out_th_attr);
416    pthread_mutex_destroy(&m_out_th_lock);
417
418    pthread_mutexattr_destroy(&out_buf_count_lock_attr);
419    pthread_mutex_destroy(&out_buf_count_lock);
420
421    pthread_mutexattr_destroy(&in_buf_count_lock_attr);
422    pthread_mutex_destroy(&in_buf_count_lock);
423
424    pthread_mutexattr_destroy(&m_in_th_attr_1);
425    pthread_mutex_destroy(&m_in_th_lock_1);
426
427    pthread_mutexattr_destroy(&m_out_th_attr_1);
428    pthread_mutex_destroy(&m_out_th_lock_1);
429    pthread_mutex_destroy(&out_buf_count_lock);
430    pthread_mutex_destroy(&in_buf_count_lock);
431    pthread_cond_destroy(&cond);
432    pthread_cond_destroy(&in_cond);
433    pthread_cond_destroy(&out_cond);
434    sem_destroy (&sem_read_msg);
435    sem_destroy (&sem_write_msg);
436    sem_destroy (&sem_States);
437    DEBUG_PRINT_ERROR("OMX AMR component destroyed\n");
438    return;
439}
440
441/**
442  @brief memory function for sending EmptyBufferDone event
443   back to IL client
444
445  @param bufHdr OMX buffer header to be passed back to IL client
446  @return none
447 */
448void omx_amr_aenc::buffer_done_cb(OMX_BUFFERHEADERTYPE *bufHdr)
449{
450    if (m_cb.EmptyBufferDone)
451    {
452        PrintFrameHdr(OMX_COMPONENT_GENERATE_BUFFER_DONE,bufHdr);
453        bufHdr->nFilledLen = 0;
454
455        m_cb.EmptyBufferDone(&m_cmp, m_app_data, bufHdr);
456        pthread_mutex_lock(&in_buf_count_lock);
457        m_amr_pb_stats.ebd_cnt++;
458        nNumInputBuf--;
459        DEBUG_DETAIL("EBD CB:: in_buf_len=%d nNumInputBuf=%d ebd_cnt=%d\n",\
460                     m_amr_pb_stats.tot_in_buf_len,
461                     nNumInputBuf, m_amr_pb_stats.ebd_cnt);
462        pthread_mutex_unlock(&in_buf_count_lock);
463    }
464
465    return;
466}
467
468/*=============================================================================
469FUNCTION:
470  flush_ack
471
472DESCRIPTION:
473
474
475INPUT/OUTPUT PARAMETERS:
476  None
477
478RETURN VALUE:
479  None
480
481Dependency:
482  None
483
484SIDE EFFECTS:
485  None
486=============================================================================*/
487void omx_amr_aenc::flush_ack()
488{
489    // Decrement the FLUSH ACK count and notify the waiting recepients
490    pthread_mutex_lock(&m_flush_lock);
491    --m_flush_cnt;
492    if (0 == m_flush_cnt)
493    {
494        event_complete();
495    }
496    DEBUG_PRINT("Rxed FLUSH ACK cnt=%d\n",m_flush_cnt);
497    pthread_mutex_unlock(&m_flush_lock);
498}
499void omx_amr_aenc::frame_done_cb(OMX_BUFFERHEADERTYPE *bufHdr)
500{
501    if (m_cb.FillBufferDone)
502    {
503        PrintFrameHdr(OMX_COMPONENT_GENERATE_FRAME_DONE,bufHdr);
504        m_amr_pb_stats.fbd_cnt++;
505        pthread_mutex_lock(&out_buf_count_lock);
506        nNumOutputBuf--;
507        DEBUG_PRINT("FBD CB:: nNumOutputBuf=%d out_buf_len=%u fbd_cnt=%u\n",\
508                    nNumOutputBuf,
509                    m_amr_pb_stats.tot_out_buf_len,
510                    m_amr_pb_stats.fbd_cnt);
511        m_amr_pb_stats.tot_out_buf_len += bufHdr->nFilledLen;
512        m_amr_pb_stats.tot_pb_time     = bufHdr->nTimeStamp;
513        DEBUG_PRINT("FBD:in_buf_len=%u out_buf_len=%u\n",
514                    m_amr_pb_stats.tot_in_buf_len,
515                    m_amr_pb_stats.tot_out_buf_len);
516
517        pthread_mutex_unlock(&out_buf_count_lock);
518        m_cb.FillBufferDone(&m_cmp, m_app_data, bufHdr);
519    }
520    return;
521}
522
523/*=============================================================================
524FUNCTION:
525  process_out_port_msg
526
527DESCRIPTION:
528  Function for handling all commands from IL client
529IL client commands are processed and callbacks are generated through
530this routine  Audio Command Server provides the thread context for this routine
531
532INPUT/OUTPUT PARAMETERS:
533  [INOUT] client_data
534  [IN] id
535
536RETURN VALUE:
537  None
538
539Dependency:
540  None
541
542SIDE EFFECTS:
543  None
544=============================================================================*/
545void omx_amr_aenc::process_out_port_msg(void *client_data, unsigned char id)
546{
547    unsigned long p1 = 0;                            // Parameter - 1
548    unsigned long p2 = 0;                            // Parameter - 2
549    unsigned char ident = 0;
550    unsigned      qsize     = 0;                 // qsize
551    unsigned      tot_qsize = 0;
552    omx_amr_aenc  *pThis    = (omx_amr_aenc *) client_data;
553    OMX_STATETYPE state;
554
555loopback_out:
556    pthread_mutex_lock(&pThis->m_state_lock);
557    pThis->get_state(&pThis->m_cmp, &state);
558    pthread_mutex_unlock(&pThis->m_state_lock);
559    if ( state == OMX_StateLoaded )
560    {
561        DEBUG_PRINT(" OUT: IN LOADED STATE RETURN\n");
562        return;
563    }
564    pthread_mutex_lock(&pThis->m_outputlock);
565
566    qsize = pThis->m_output_ctrl_cmd_q.m_size;
567    tot_qsize = pThis->m_output_ctrl_cmd_q.m_size;
568    tot_qsize += pThis->m_output_ctrl_fbd_q.m_size;
569    tot_qsize += pThis->m_output_q.m_size;
570
571    if ( 0 == tot_qsize )
572    {
573        pthread_mutex_unlock(&pThis->m_outputlock);
574        DEBUG_DETAIL("OUT-->BREAK FROM LOOP...%d\n",tot_qsize);
575        return;
576    }
577    if ( (state != OMX_StateExecuting) && !qsize )
578    {
579        pthread_mutex_unlock(&pThis->m_outputlock);
580        pthread_mutex_lock(&pThis->m_state_lock);
581        pThis->get_state(&pThis->m_cmp, &state);
582        pthread_mutex_unlock(&pThis->m_state_lock);
583        if ( state == OMX_StateLoaded )
584            return;
585
586        DEBUG_DETAIL("OUT:1.SLEEPING OUT THREAD\n");
587        pthread_mutex_lock(&pThis->m_out_th_lock_1);
588        pThis->is_out_th_sleep = true;
589        pthread_mutex_unlock(&pThis->m_out_th_lock_1);
590        pThis->out_th_goto_sleep();
591
592        /* Get the updated state */
593        pthread_mutex_lock(&pThis->m_state_lock);
594        pThis->get_state(&pThis->m_cmp, &state);
595        pthread_mutex_unlock(&pThis->m_state_lock);
596    }
597
598    if ( ((!pThis->m_output_ctrl_cmd_q.m_size) && !pThis->m_out_bEnabled) )
599    {
600        // case where no port reconfig and nothing in the flush q
601        DEBUG_DETAIL("No flush/port reconfig qsize=%d tot_qsize=%d",\
602            qsize,tot_qsize);
603        pthread_mutex_unlock(&pThis->m_outputlock);
604        pthread_mutex_lock(&pThis->m_state_lock);
605        pThis->get_state(&pThis->m_cmp, &state);
606        pthread_mutex_unlock(&pThis->m_state_lock);
607        if ( state == OMX_StateLoaded )
608            return;
609
610        if(pThis->m_output_ctrl_cmd_q.m_size || !(pThis->bFlushinprogress))
611        {
612            DEBUG_PRINT("OUT:2. SLEEPING OUT THREAD \n");
613            pthread_mutex_lock(&pThis->m_out_th_lock_1);
614            pThis->is_out_th_sleep = true;
615            pthread_mutex_unlock(&pThis->m_out_th_lock_1);
616            pThis->out_th_goto_sleep();
617        }
618        /* Get the updated state */
619        pthread_mutex_lock(&pThis->m_state_lock);
620        pThis->get_state(&pThis->m_cmp, &state);
621        pthread_mutex_unlock(&pThis->m_state_lock);
622    }
623    qsize = pThis->m_output_ctrl_cmd_q.m_size;
624    tot_qsize = pThis->m_output_ctrl_cmd_q.m_size;
625    tot_qsize += pThis->m_output_ctrl_fbd_q.m_size;
626    tot_qsize += pThis->m_output_q.m_size;
627    pthread_mutex_lock(&pThis->m_state_lock);
628    pThis->get_state(&pThis->m_cmp, &state);
629    pthread_mutex_unlock(&pThis->m_state_lock);
630    DEBUG_DETAIL("OUT-->QSIZE-flush=%d,fbd=%d QSIZE=%d state=%d\n",\
631        pThis->m_output_ctrl_cmd_q.m_size,
632        pThis->m_output_ctrl_fbd_q.m_size,
633        pThis->m_output_q.m_size,state);
634
635
636    if (qsize)
637    {
638        // process FLUSH message
639        pThis->m_output_ctrl_cmd_q.pop_entry(&p1,&p2,&ident);
640    } else if ( (qsize = pThis->m_output_ctrl_fbd_q.m_size) &&
641        (pThis->m_out_bEnabled) && (state == OMX_StateExecuting) )
642    {
643        // then process EBD's
644        pThis->m_output_ctrl_fbd_q.pop_entry(&p1,&p2,&ident);
645    } else if ( (qsize = pThis->m_output_q.m_size) &&
646        (pThis->m_out_bEnabled) && (state == OMX_StateExecuting) )
647    {
648        // if no FLUSH and FBD's then process FTB's
649        pThis->m_output_q.pop_entry(&p1,&p2,&ident);
650    } else if ( state == OMX_StateLoaded )
651    {
652        pthread_mutex_unlock(&pThis->m_outputlock);
653        DEBUG_PRINT("IN: ***in OMX_StateLoaded so exiting\n");
654        return ;
655    } else
656    {
657        qsize = 0;
658        DEBUG_PRINT("OUT--> Empty Queue state=%d %d %d %d\n",state,
659                     pThis->m_output_ctrl_cmd_q.m_size,
660		     pThis->m_output_ctrl_fbd_q.m_size,
661                     pThis->m_output_q.m_size);
662
663        if(state == OMX_StatePause)
664        {
665            DEBUG_DETAIL("OUT: SLEEPING AGAIN OUT THREAD\n");
666            pthread_mutex_lock(&pThis->m_out_th_lock_1);
667            pThis->is_out_th_sleep = true;
668            pthread_mutex_unlock(&pThis->m_out_th_lock_1);
669            pthread_mutex_unlock(&pThis->m_outputlock);
670            pThis->out_th_goto_sleep();
671            goto loopback_out;
672        }
673    }
674    pthread_mutex_unlock(&pThis->m_outputlock);
675
676    if ( qsize > 0 )
677    {
678        id = ident;
679        ident = 0;
680        DEBUG_DETAIL("OUT->state[%d]ident[%d]flushq[%d]fbd[%d]dataq[%d]\n",\
681            pThis->m_state,
682            ident,
683            pThis->m_output_ctrl_cmd_q.m_size,
684            pThis->m_output_ctrl_fbd_q.m_size,
685            pThis->m_output_q.m_size);
686
687        if ( OMX_COMPONENT_GENERATE_FRAME_DONE == id )
688        {
689            pThis->frame_done_cb((OMX_BUFFERHEADERTYPE *)p2);
690        } else if ( OMX_COMPONENT_GENERATE_FTB == id )
691        {
692            pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,
693                (OMX_BUFFERHEADERTYPE *)p2);
694        } else if ( OMX_COMPONENT_GENERATE_EOS == id )
695        {
696            pThis->m_cb.EventHandler(&pThis->m_cmp,
697                pThis->m_app_data,
698                OMX_EventBufferFlag,
699                1, 1, NULL );
700
701        }
702        else if(id == OMX_COMPONENT_RESUME)
703        {
704             DEBUG_PRINT("RESUMED...\n");
705        }
706        else if(id == OMX_COMPONENT_GENERATE_COMMAND)
707        {
708            // Execute FLUSH command
709            if ( OMX_CommandFlush == p1 )
710            {
711                DEBUG_DETAIL("Executing FLUSH command on Output port\n");
712                pThis->execute_output_omx_flush();
713            } else
714            {
715                DEBUG_DETAIL("Invalid command[%lu]\n",p1);
716            }
717        } else
718        {
719            DEBUG_PRINT_ERROR("ERROR:OUT-->Invalid Id[%d]\n",id);
720        }
721    } else
722    {
723        DEBUG_DETAIL("ERROR: OUT--> Empty OUTPUTQ\n");
724    }
725
726    return;
727}
728
729/*=============================================================================
730FUNCTION:
731  process_command_msg
732
733DESCRIPTION:
734
735
736INPUT/OUTPUT PARAMETERS:
737  [INOUT] client_data
738  [IN] id
739
740RETURN VALUE:
741  None
742
743Dependency:
744  None
745
746SIDE EFFECTS:
747  None
748=============================================================================*/
749void omx_amr_aenc::process_command_msg(void *client_data, unsigned char id)
750{
751    unsigned long  p1 = 0;                             // Parameter - 1
752    unsigned long  p2 = 0;                             // Parameter - 2
753    unsigned char ident = 0;
754    unsigned     qsize  = 0;
755    omx_amr_aenc *pThis = (omx_amr_aenc*)client_data;
756    pthread_mutex_lock(&pThis->m_commandlock);
757
758    qsize = pThis->m_command_q.m_size;
759    DEBUG_DETAIL("CMD-->QSIZE=%d state=%d\n",pThis->m_command_q.m_size,
760                 pThis->m_state);
761
762    if (!qsize)
763    {
764        DEBUG_DETAIL("CMD-->BREAKING FROM LOOP\n");
765        pthread_mutex_unlock(&pThis->m_commandlock);
766        return;
767    } else
768    {
769        pThis->m_command_q.pop_entry(&p1,&p2,&ident);
770    }
771    pthread_mutex_unlock(&pThis->m_commandlock);
772
773    id = ident;
774    DEBUG_DETAIL("CMD->state[%d]id[%d]cmdq[%d]n",\
775                 pThis->m_state,ident, \
776                 pThis->m_command_q.m_size);
777
778    if (OMX_COMPONENT_GENERATE_EVENT == id)
779    {
780        if (pThis->m_cb.EventHandler)
781        {
782            if (OMX_CommandStateSet == p1)
783            {
784                pthread_mutex_lock(&pThis->m_state_lock);
785                pThis->m_state = (OMX_STATETYPE) p2;
786                pthread_mutex_unlock(&pThis->m_state_lock);
787                DEBUG_PRINT("CMD:Process->state set to %d \n", \
788                            pThis->m_state);
789
790                if (pThis->m_state == OMX_StateExecuting ||
791                    pThis->m_state == OMX_StateLoaded)
792                {
793
794                    pthread_mutex_lock(&pThis->m_in_th_lock_1);
795                    if (pThis->is_in_th_sleep)
796                    {
797                        pThis->is_in_th_sleep = false;
798                        DEBUG_DETAIL("CMD:WAKING UP IN THREADS\n");
799                        pThis->in_th_wakeup();
800                    }
801                    pthread_mutex_unlock(&pThis->m_in_th_lock_1);
802
803                    pthread_mutex_lock(&pThis->m_out_th_lock_1);
804                    if (pThis->is_out_th_sleep)
805                    {
806                        DEBUG_DETAIL("CMD:WAKING UP OUT THREADS\n");
807                        pThis->is_out_th_sleep = false;
808                        pThis->out_th_wakeup();
809                    }
810                    pthread_mutex_unlock(&pThis->m_out_th_lock_1);
811                }
812            }
813            if (OMX_StateInvalid == pThis->m_state)
814            {
815                pThis->m_cb.EventHandler(&pThis->m_cmp,
816                                         pThis->m_app_data,
817                                         OMX_EventError,
818                                         OMX_ErrorInvalidState,
819                                         0, NULL );
820            } else if ((signed)p2 == OMX_ErrorPortUnpopulated)
821            {
822                pThis->m_cb.EventHandler(&pThis->m_cmp,
823                                         pThis->m_app_data,
824                                         OMX_EventError,
825                                         (OMX_U32)p2,
826                                         0,
827                                         0 );
828            } else
829            {
830                pThis->m_cb.EventHandler(&pThis->m_cmp,
831                                         pThis->m_app_data,
832                                         OMX_EventCmdComplete,
833                                         (OMX_U32)p1, (OMX_U32)p2, NULL );
834            }
835        } else
836        {
837            DEBUG_PRINT_ERROR("ERROR:CMD-->EventHandler NULL \n");
838        }
839    } else if (OMX_COMPONENT_GENERATE_COMMAND == id)
840    {
841        pThis->send_command_proxy(&pThis->m_cmp,
842                                  (OMX_COMMANDTYPE)p1,
843                                  (OMX_U32)p2,(OMX_PTR)NULL);
844    } else if (OMX_COMPONENT_PORTSETTINGS_CHANGED == id)
845    {
846        DEBUG_DETAIL("CMD-->RXED PORTSETTINGS_CHANGED");
847        pThis->m_cb.EventHandler(&pThis->m_cmp,
848                                 pThis->m_app_data,
849                                 OMX_EventPortSettingsChanged,
850                                 1, 1, NULL );
851    }
852    else
853    {
854       DEBUG_PRINT_ERROR("CMD->state[%d]id[%d]\n",pThis->m_state,ident);
855    }
856    return;
857}
858
859/*=============================================================================
860FUNCTION:
861  process_in_port_msg
862
863DESCRIPTION:
864
865
866INPUT/OUTPUT PARAMETERS:
867  [INOUT] client_data
868  [IN] id
869
870RETURN VALUE:
871  None
872
873Dependency:
874  None
875
876SIDE EFFECTS:
877  None
878=============================================================================*/
879void omx_amr_aenc::process_in_port_msg(void *client_data, unsigned char id)
880{
881    unsigned long p1 = 0;                            // Parameter - 1
882    unsigned long p2 = 0;                            // Parameter - 2
883    unsigned char ident = 0;
884    unsigned      qsize     = 0;
885    unsigned      tot_qsize = 0;
886    omx_amr_aenc  *pThis    = (omx_amr_aenc *) client_data;
887    OMX_STATETYPE state;
888
889    if (!pThis)
890    {
891        DEBUG_PRINT_ERROR("ERROR:IN--> Invalid Obj \n");
892        return;
893    }
894loopback_in:
895    pthread_mutex_lock(&pThis->m_state_lock);
896    pThis->get_state(&pThis->m_cmp, &state);
897    pthread_mutex_unlock(&pThis->m_state_lock);
898    if ( state == OMX_StateLoaded )
899    {
900        DEBUG_PRINT(" IN: IN LOADED STATE RETURN\n");
901        return;
902    }
903    // Protect the shared queue data structure
904    pthread_mutex_lock(&pThis->m_lock);
905
906    qsize = pThis->m_input_ctrl_cmd_q.m_size;
907    tot_qsize = qsize;
908    tot_qsize += pThis->m_input_ctrl_ebd_q.m_size;
909    tot_qsize += pThis->m_input_q.m_size;
910
911    if ( 0 == tot_qsize )
912    {
913        DEBUG_DETAIL("IN-->BREAKING FROM IN LOOP");
914        pthread_mutex_unlock(&pThis->m_lock);
915        return;
916    }
917
918    if ( (state != OMX_StateExecuting) && ! (pThis->m_input_ctrl_cmd_q.m_size))
919    {
920        pthread_mutex_unlock(&pThis->m_lock);
921        DEBUG_DETAIL("SLEEPING IN THREAD\n");
922        pthread_mutex_lock(&pThis->m_in_th_lock_1);
923        pThis->is_in_th_sleep = true;
924        pthread_mutex_unlock(&pThis->m_in_th_lock_1);
925        pThis->in_th_goto_sleep();
926
927        /* Get the updated state */
928        pthread_mutex_lock(&pThis->m_state_lock);
929        pThis->get_state(&pThis->m_cmp, &state);
930        pthread_mutex_unlock(&pThis->m_state_lock);
931    }
932    else if ((state == OMX_StatePause))
933    {
934        if(!(pThis->m_input_ctrl_cmd_q.m_size))
935        {
936           pthread_mutex_unlock(&pThis->m_lock);
937
938           DEBUG_DETAIL("IN: SLEEPING IN THREAD\n");
939           pthread_mutex_lock(&pThis->m_in_th_lock_1);
940           pThis->is_in_th_sleep = true;
941           pthread_mutex_unlock(&pThis->m_in_th_lock_1);
942           pThis->in_th_goto_sleep();
943
944           pthread_mutex_lock(&pThis->m_state_lock);
945           pThis->get_state(&pThis->m_cmp, &state);
946           pthread_mutex_unlock(&pThis->m_state_lock);
947        }
948    }
949
950    qsize = pThis->m_input_ctrl_cmd_q.m_size;
951    tot_qsize = qsize;
952    tot_qsize += pThis->m_input_ctrl_ebd_q.m_size;
953    tot_qsize += pThis->m_input_q.m_size;
954
955    DEBUG_DETAIL("Input-->QSIZE-flush=%d,ebd=%d QSIZE=%d state=%d\n",\
956        pThis->m_input_ctrl_cmd_q.m_size,
957        pThis->m_input_ctrl_ebd_q.m_size,
958        pThis->m_input_q.m_size, state);
959
960
961    if ( qsize )
962    {
963        // process FLUSH message
964        pThis->m_input_ctrl_cmd_q.pop_entry(&p1,&p2,&ident);
965    } else if ( (qsize = pThis->m_input_ctrl_ebd_q.m_size) &&
966        (state == OMX_StateExecuting) )
967    {
968        // then process EBD's
969        pThis->m_input_ctrl_ebd_q.pop_entry(&p1,&p2,&ident);
970    } else if ((qsize = pThis->m_input_q.m_size) &&
971               (state == OMX_StateExecuting))
972    {
973        // if no FLUSH and EBD's then process ETB's
974        pThis->m_input_q.pop_entry(&p1, &p2, &ident);
975    } else if ( state == OMX_StateLoaded )
976    {
977        pthread_mutex_unlock(&pThis->m_lock);
978        DEBUG_PRINT("IN: ***in OMX_StateLoaded so exiting\n");
979        return ;
980    } else
981    {
982        qsize = 0;
983        DEBUG_PRINT("IN-->state[%d]cmdq[%d]ebdq[%d]in[%d]\n",\
984                             state,pThis->m_input_ctrl_cmd_q.m_size,
985                             pThis->m_input_ctrl_ebd_q.m_size,
986		             pThis->m_input_q.m_size);
987
988        if(state == OMX_StatePause)
989        {
990            DEBUG_DETAIL("IN: SLEEPING AGAIN IN THREAD\n");
991            pthread_mutex_lock(&pThis->m_in_th_lock_1);
992            pThis->is_in_th_sleep = true;
993            pthread_mutex_unlock(&pThis->m_in_th_lock_1);
994            pthread_mutex_unlock(&pThis->m_lock);
995            pThis->in_th_goto_sleep();
996            goto loopback_in;
997        }
998    }
999    pthread_mutex_unlock(&pThis->m_lock);
1000
1001    if ( qsize > 0 )
1002    {
1003        id = ident;
1004        DEBUG_DETAIL("Input->state[%d]id[%d]flushq[%d]ebdq[%d]dataq[%d]\n",\
1005            pThis->m_state,
1006            ident,
1007            pThis->m_input_ctrl_cmd_q.m_size,
1008            pThis->m_input_ctrl_ebd_q.m_size,
1009            pThis->m_input_q.m_size);
1010        if ( OMX_COMPONENT_GENERATE_BUFFER_DONE == id )
1011        {
1012            pThis->buffer_done_cb((OMX_BUFFERHEADERTYPE *)p2);
1013        }
1014        else if(id == OMX_COMPONENT_GENERATE_EOS)
1015        {
1016            pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1017                OMX_EventBufferFlag, 0, 1, NULL );
1018        } else if ( OMX_COMPONENT_GENERATE_ETB == id )
1019        {
1020            pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,
1021                (OMX_BUFFERHEADERTYPE *)p2);
1022        } else if ( OMX_COMPONENT_GENERATE_COMMAND == id )
1023        {
1024            // Execute FLUSH command
1025            if ( OMX_CommandFlush == p1 )
1026            {
1027                DEBUG_DETAIL(" Executing FLUSH command on Input port\n");
1028                pThis->execute_input_omx_flush();
1029            } else
1030            {
1031                DEBUG_DETAIL("Invalid command[%lu]\n",p1);
1032            }
1033        }
1034        else
1035        {
1036            DEBUG_PRINT_ERROR("ERROR:IN-->Invalid Id[%d]\n",id);
1037        }
1038    } else
1039    {
1040        DEBUG_DETAIL("ERROR:IN-->Empty INPUT Q\n");
1041    }
1042    return;
1043}
1044
1045/**
1046 @brief member function for performing component initialization
1047
1048 @param role C string mandating role of this component
1049 @return Error status
1050 */
1051OMX_ERRORTYPE omx_amr_aenc::component_init(OMX_STRING role)
1052{
1053
1054    OMX_ERRORTYPE eRet = OMX_ErrorNone;
1055    m_state                   = OMX_StateLoaded;
1056
1057    /* DSP does not give information about the bitstream
1058    randomly assign the value right now. Query will result in
1059    incorrect param */
1060    memset(&m_amr_param, 0, sizeof(m_amr_param));
1061    m_amr_param.nSize = (OMX_U32)sizeof(m_amr_param);
1062    m_amr_param.nChannels = OMX_AMR_DEFAULT_CH_CFG;
1063    m_volume = OMX_AMR_DEFAULT_VOL;             /* Close to unity gain */
1064    memset(&m_amr_pb_stats,0,sizeof(AMR_PB_STATS));
1065    memset(&m_pcm_param, 0, sizeof(m_pcm_param));
1066    m_pcm_param.nSize = (OMX_U32)sizeof(m_pcm_param);
1067    m_pcm_param.nChannels = OMX_AMR_DEFAULT_CH_CFG;
1068    m_pcm_param.nSamplingRate = OMX_AMR_DEFAULT_SF;
1069    nTimestamp = 0;
1070    ts = 0;
1071
1072    nNumInputBuf = 0;
1073    nNumOutputBuf = 0;
1074    m_ipc_to_in_th = NULL;  // Command server instance
1075    m_ipc_to_out_th = NULL;  // Client server instance
1076    m_ipc_to_cmd_th = NULL;  // command instance
1077    m_is_out_th_sleep = 0;
1078    m_is_in_th_sleep = 0;
1079    is_out_th_sleep= false;
1080
1081    is_in_th_sleep=false;
1082
1083    memset(&m_priority_mgm, 0, sizeof(m_priority_mgm));
1084    m_priority_mgm.nGroupID =0;
1085    m_priority_mgm.nGroupPriority=0;
1086
1087    memset(&m_buffer_supplier, 0, sizeof(m_buffer_supplier));
1088    m_buffer_supplier.nPortIndex=OMX_BufferSupplyUnspecified;
1089
1090    DEBUG_PRINT_ERROR(" component init: role = %s\n",role);
1091
1092    DEBUG_PRINT(" component init: role = %s\n",role);
1093    component_Role.nVersion.nVersion = OMX_SPEC_VERSION;
1094    if (!strcmp(role,"OMX.qcom.audio.encoder.amrnb"))
1095    {
1096        pcm_input = 1;
1097        component_Role.nSize = (OMX_U32)sizeof(role);
1098        strlcpy((char *)component_Role.cRole, (const char*)role,
1099		sizeof(component_Role.cRole));
1100        DEBUG_PRINT("\ncomponent_init: Component %s LOADED \n", role);
1101    } else if (!strcmp(role,"OMX.qcom.audio.encoder.tunneled.amrnb"))
1102    {
1103        pcm_input = 0;
1104        component_Role.nSize = (OMX_U32)sizeof(role);
1105        strlcpy((char *)component_Role.cRole, (const char*)role,
1106		sizeof(component_Role.cRole));
1107        DEBUG_PRINT("\ncomponent_init: Component %s LOADED \n", role);
1108    } else
1109    {
1110        component_Role.nSize = (OMX_U32)sizeof("\0");
1111        strlcpy((char *)component_Role.cRole, (const char*)"\0",
1112		sizeof(component_Role.cRole));
1113        DEBUG_PRINT("\ncomponent_init: Component %s LOADED is invalid\n", role);
1114    }
1115    if(pcm_input)
1116    {
1117        m_tmp_meta_buf = (OMX_U8*) malloc(sizeof(OMX_U8) *
1118                         (OMX_CORE_INPUT_BUFFER_SIZE + sizeof(META_IN)));
1119
1120        if (m_tmp_meta_buf == NULL){
1121            DEBUG_PRINT_ERROR("Mem alloc failed for tmp meta buf\n");
1122                return OMX_ErrorInsufficientResources;
1123	}
1124    }
1125    m_tmp_out_meta_buf =
1126		(OMX_U8*)malloc(sizeof(OMX_U8)*OMX_AMR_OUTPUT_BUFFER_SIZE);
1127        if ( m_tmp_out_meta_buf == NULL ){
1128            DEBUG_PRINT_ERROR("Mem alloc failed for out meta buf\n");
1129                return OMX_ErrorInsufficientResources;
1130            }
1131
1132    if(0 == pcm_input)
1133    {
1134        m_drv_fd = open("/dev/msm_amrnb_in",O_RDONLY);
1135    DEBUG_PRINT("Driver in Tunnel mode open\n");
1136    }
1137    else
1138    {
1139        m_drv_fd = open("/dev/msm_amrnb_in",O_RDWR);
1140    DEBUG_PRINT("Driver in Non Tunnel mode open\n");
1141    }
1142    if (m_drv_fd < 0)
1143    {
1144        DEBUG_PRINT_ERROR("Component_init Open Failed[%d] errno[%d]",\
1145                                      m_drv_fd,errno);
1146
1147        return OMX_ErrorInsufficientResources;
1148    }
1149    if(ioctl(m_drv_fd, AUDIO_GET_SESSION_ID,&m_session_id) == -1)
1150    {
1151        DEBUG_PRINT_ERROR("AUDIO_GET_SESSION_ID FAILED\n");
1152    }
1153    if(pcm_input)
1154    {
1155        if (!m_ipc_to_in_th)
1156        {
1157            m_ipc_to_in_th = omx_amr_thread_create(process_in_port_msg,
1158                this, (char *)"INPUT_THREAD");
1159            if (!m_ipc_to_in_th)
1160            {
1161                DEBUG_PRINT_ERROR("ERROR!!! Failed to start \
1162					Input port thread\n");
1163                return OMX_ErrorInsufficientResources;
1164            }
1165        }
1166    }
1167
1168    if (!m_ipc_to_cmd_th)
1169    {
1170        m_ipc_to_cmd_th = omx_amr_thread_create(process_command_msg,
1171            this, (char *)"CMD_THREAD");
1172        if (!m_ipc_to_cmd_th)
1173        {
1174            DEBUG_PRINT_ERROR("ERROR!!!Failed to start "
1175                              "command message thread\n");
1176            return OMX_ErrorInsufficientResources;
1177        }
1178    }
1179
1180        if (!m_ipc_to_out_th)
1181        {
1182            m_ipc_to_out_th = omx_amr_thread_create(process_out_port_msg,
1183                this, (char *)"OUTPUT_THREAD");
1184            if (!m_ipc_to_out_th)
1185            {
1186                DEBUG_PRINT_ERROR("ERROR!!! Failed to start output "
1187                                  "port thread\n");
1188                return OMX_ErrorInsufficientResources;
1189            }
1190        }
1191    return eRet;
1192}
1193
1194/**
1195
1196 @brief member function to retrieve version of component
1197
1198
1199
1200 @param hComp handle to this component instance
1201 @param componentName name of component
1202 @param componentVersion  pointer to memory space which stores the
1203       version number
1204 @param specVersion pointer to memory sapce which stores version of
1205        openMax specification
1206 @param componentUUID
1207 @return Error status
1208 */
1209OMX_ERRORTYPE  omx_amr_aenc::get_component_version
1210(
1211    OMX_IN OMX_HANDLETYPE               hComp,
1212    OMX_OUT OMX_STRING          componentName,
1213    OMX_OUT OMX_VERSIONTYPE* componentVersion,
1214    OMX_OUT OMX_VERSIONTYPE*      specVersion,
1215    OMX_OUT OMX_UUIDTYPE*       componentUUID)
1216{
1217    if((hComp == NULL) || (componentName == NULL) ||
1218        (specVersion == NULL) || (componentUUID == NULL))
1219    {
1220        componentVersion = NULL;
1221        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
1222        return OMX_ErrorBadParameter;
1223    }
1224    if (m_state == OMX_StateInvalid)
1225    {
1226        DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
1227        return OMX_ErrorInvalidState;
1228    }
1229    componentVersion->nVersion = OMX_SPEC_VERSION;
1230    specVersion->nVersion = OMX_SPEC_VERSION;
1231    return OMX_ErrorNone;
1232}
1233/**
1234  @brief member function handles command from IL client
1235
1236  This function simply queue up commands from IL client.
1237  Commands will be processed in command server thread context later
1238
1239  @param hComp handle to component instance
1240  @param cmd type of command
1241  @param param1 parameters associated with the command type
1242  @param cmdData
1243  @return Error status
1244*/
1245OMX_ERRORTYPE  omx_amr_aenc::send_command(OMX_IN OMX_HANDLETYPE hComp,
1246                                           OMX_IN OMX_COMMANDTYPE  cmd,
1247                                           OMX_IN OMX_U32       param1,
1248                                           OMX_IN OMX_PTR      cmdData)
1249{
1250    int portIndex = (int)param1;
1251
1252    if(hComp == NULL)
1253    {
1254        cmdData = cmdData;
1255        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
1256        return OMX_ErrorBadParameter;
1257    }
1258    if (OMX_StateInvalid == m_state)
1259    {
1260        return OMX_ErrorInvalidState;
1261    }
1262    if ( (cmd == OMX_CommandFlush) && (portIndex > 1) )
1263    {
1264        return OMX_ErrorBadPortIndex;
1265    }
1266    post_command((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1267    DEBUG_PRINT("Send Command : returns with OMX_ErrorNone \n");
1268    DEBUG_PRINT("send_command : recieved state before semwait= %u\n",param1);
1269    sem_wait (&sem_States);
1270    DEBUG_PRINT("send_command : recieved state after semwait\n");
1271    return OMX_ErrorNone;
1272}
1273
1274/**
1275 @brief member function performs actual processing of commands excluding
1276  empty buffer call
1277
1278 @param hComp handle to component
1279 @param cmd command type
1280 @param param1 parameter associated with the command
1281 @param cmdData
1282
1283 @return error status
1284*/
1285OMX_ERRORTYPE  omx_amr_aenc::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1286                                                 OMX_IN OMX_COMMANDTYPE  cmd,
1287                                                 OMX_IN OMX_U32       param1,
1288                                                 OMX_IN OMX_PTR      cmdData)
1289{
1290    OMX_ERRORTYPE eRet = OMX_ErrorNone;
1291    //   Handle only IDLE and executing
1292    OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1293    int bFlag = 1;
1294    nState = eState;
1295
1296    if(hComp == NULL)
1297    {
1298        cmdData = cmdData;
1299        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
1300        return OMX_ErrorBadParameter;
1301    }
1302    if (OMX_CommandStateSet == cmd)
1303    {
1304        /***************************/
1305        /* Current State is Loaded */
1306        /***************************/
1307        if (OMX_StateLoaded == m_state)
1308        {
1309            if (OMX_StateIdle == eState)
1310            {
1311
1312                 if (allocate_done() ||
1313                        (m_inp_bEnabled == OMX_FALSE
1314                         && m_out_bEnabled == OMX_FALSE))
1315                 {
1316                       DEBUG_PRINT("SCP-->Allocate Done Complete\n");
1317                 }
1318                 else
1319                 {
1320                        DEBUG_PRINT("SCP-->Loaded to Idle-Pending\n");
1321                        BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1322                        bFlag = 0;
1323                 }
1324
1325            } else if (eState == OMX_StateLoaded)
1326            {
1327                DEBUG_PRINT("OMXCORE-SM: Loaded-->Loaded\n");
1328                m_cb.EventHandler(&this->m_cmp,
1329                                  this->m_app_data,
1330                                  OMX_EventError,
1331                                  OMX_ErrorSameState,
1332                                  0, NULL );
1333                eRet = OMX_ErrorSameState;
1334            }
1335
1336            else if (eState == OMX_StateWaitForResources)
1337            {
1338                DEBUG_PRINT("OMXCORE-SM: Loaded-->WaitForResources\n");
1339                eRet = OMX_ErrorNone;
1340            }
1341
1342            else if (eState == OMX_StateExecuting)
1343            {
1344                DEBUG_PRINT("OMXCORE-SM: Loaded-->Executing\n");
1345                m_cb.EventHandler(&this->m_cmp,
1346                                  this->m_app_data,
1347                                  OMX_EventError,
1348                                  OMX_ErrorIncorrectStateTransition,
1349                                  0, NULL );
1350                eRet = OMX_ErrorIncorrectStateTransition;
1351            }
1352
1353            else if (eState == OMX_StatePause)
1354            {
1355                DEBUG_PRINT("OMXCORE-SM: Loaded-->Pause\n");
1356                m_cb.EventHandler(&this->m_cmp,
1357                                  this->m_app_data,
1358                                  OMX_EventError,
1359                                  OMX_ErrorIncorrectStateTransition,
1360                                  0, NULL );
1361                eRet = OMX_ErrorIncorrectStateTransition;
1362            }
1363
1364            else if (eState == OMX_StateInvalid)
1365            {
1366                DEBUG_PRINT("OMXCORE-SM: Loaded-->Invalid\n");
1367                m_cb.EventHandler(&this->m_cmp,
1368                                  this->m_app_data,
1369                                  OMX_EventError,
1370                                  OMX_ErrorInvalidState,
1371                                  0, NULL );
1372                m_state = OMX_StateInvalid;
1373                eRet = OMX_ErrorInvalidState;
1374            } else
1375            {
1376                DEBUG_PRINT_ERROR("SCP-->Loaded to Invalid(%d))\n",eState);
1377                eRet = OMX_ErrorBadParameter;
1378            }
1379        }
1380
1381        /***************************/
1382        /* Current State is IDLE */
1383        /***************************/
1384        else if (OMX_StateIdle == m_state)
1385        {
1386            if (OMX_StateLoaded == eState)
1387            {
1388                if (release_done(-1))
1389                {
1390                    if (ioctl(m_drv_fd, AUDIO_STOP, 0) == -1)
1391                    {
1392                        DEBUG_PRINT_ERROR("SCP:Idle->Loaded,\
1393					ioctl stop failed %d\n", errno);
1394                    }
1395
1396                    nTimestamp=0;
1397                    ts = 0;
1398                    DEBUG_PRINT("SCP-->Idle to Loaded\n");
1399                } else
1400                {
1401                    DEBUG_PRINT("SCP--> Idle to Loaded-Pending\n");
1402                    BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1403                    // Skip the event notification
1404                    bFlag = 0;
1405                }
1406            }
1407            else if (OMX_StateExecuting == eState)
1408            {
1409
1410                struct msm_audio_amrnb_enc_config_v2 drv_amr_enc_config;
1411                struct msm_audio_stream_config drv_stream_config;
1412                struct msm_audio_buf_cfg buf_cfg;
1413                struct msm_audio_config pcm_cfg;
1414
1415                if(ioctl(m_drv_fd, AUDIO_GET_STREAM_CONFIG, &drv_stream_config)
1416			== -1)
1417                {
1418                    DEBUG_PRINT_ERROR("ioctl AUDIO_GET_STREAM_CONFIG failed, \
1419					errno[%d]\n", errno);
1420                }
1421                if(ioctl(m_drv_fd, AUDIO_SET_STREAM_CONFIG, &drv_stream_config)
1422			== -1)
1423                {
1424                    DEBUG_PRINT_ERROR("ioctl AUDIO_SET_STREAM_CONFIG failed, \
1425					errno[%d]\n", errno);
1426                }
1427
1428                if(ioctl(m_drv_fd, AUDIO_GET_AMRNB_ENC_CONFIG_V2,
1429			&drv_amr_enc_config) == -1)
1430                {
1431                    DEBUG_PRINT_ERROR("ioctl AUDIO_GET_AMRNB_ENC_CONFIG_V2 \
1432					failed, errno[%d]\n", errno);
1433                }
1434        drv_amr_enc_config.band_mode = m_amr_param.eAMRBandMode;
1435        drv_amr_enc_config.dtx_enable = m_amr_param.eAMRDTXMode;
1436        drv_amr_enc_config.frame_format = m_amr_param.eAMRFrameFormat;
1437        if(ioctl(m_drv_fd, AUDIO_SET_AMRNB_ENC_CONFIG_V2, &drv_amr_enc_config)
1438		== -1)
1439                {
1440                    DEBUG_PRINT_ERROR("ioctl AUDIO_SET_AMRNB_ENC_CONFIG_V2 \
1441					failed, errno[%d]\n", errno);
1442                }
1443                if (ioctl(m_drv_fd, AUDIO_GET_BUF_CFG, &buf_cfg) == -1)
1444                {
1445                    DEBUG_PRINT_ERROR("ioctl AUDIO_GET_BUF_CFG, errno[%d]\n",
1446					errno);
1447                }
1448                buf_cfg.meta_info_enable = 1;
1449                buf_cfg.frames_per_buf = NUMOFFRAMES;
1450                if (ioctl(m_drv_fd, AUDIO_SET_BUF_CFG, &buf_cfg) == -1)
1451                {
1452                    DEBUG_PRINT_ERROR("ioctl AUDIO_SET_BUF_CFG, errno[%d]\n",
1453					errno);
1454                }
1455                if(pcm_input)
1456                {
1457                    if (ioctl(m_drv_fd, AUDIO_GET_CONFIG, &pcm_cfg) == -1)
1458                    {
1459                        DEBUG_PRINT_ERROR("ioctl AUDIO_GET_CONFIG, errno[%d]\n",
1460					errno);
1461                    }
1462                    pcm_cfg.channel_count = m_pcm_param.nChannels;
1463                    pcm_cfg.sample_rate  =  m_pcm_param.nSamplingRate;
1464                    DEBUG_PRINT("pcm config %u %u\n",m_pcm_param.nChannels,
1465				m_pcm_param.nSamplingRate);
1466
1467                    if (ioctl(m_drv_fd, AUDIO_SET_CONFIG, &pcm_cfg) == -1)
1468                    {
1469                        DEBUG_PRINT_ERROR("ioctl AUDIO_SET_CONFIG, errno[%d]\n",
1470					errno);
1471                    }
1472                }
1473                if(ioctl(m_drv_fd, AUDIO_START, 0) == -1)
1474                {
1475                    DEBUG_PRINT_ERROR("ioctl AUDIO_START failed, errno[%d]\n",
1476					errno);
1477		    m_state = OMX_StateInvalid;
1478                    this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1479                                        OMX_EventError, OMX_ErrorInvalidState,
1480                                        0, NULL );
1481                    eRet = OMX_ErrorInvalidState;
1482                }
1483                DEBUG_PRINT("SCP-->Idle to Executing\n");
1484                nState = eState;
1485            } else if (eState == OMX_StateIdle)
1486            {
1487                DEBUG_PRINT("OMXCORE-SM: Idle-->Idle\n");
1488                m_cb.EventHandler(&this->m_cmp,
1489                                  this->m_app_data,
1490                                  OMX_EventError,
1491                                  OMX_ErrorSameState,
1492                                  0, NULL );
1493                eRet = OMX_ErrorSameState;
1494            } else if (eState == OMX_StateWaitForResources)
1495            {
1496                DEBUG_PRINT("OMXCORE-SM: Idle-->WaitForResources\n");
1497                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1498                                        OMX_EventError,
1499                                        OMX_ErrorIncorrectStateTransition,
1500                                        0, NULL );
1501                eRet = OMX_ErrorIncorrectStateTransition;
1502            }
1503
1504            else if (eState == OMX_StatePause)
1505            {
1506                DEBUG_PRINT("OMXCORE-SM: Idle-->Pause\n");
1507            }
1508
1509            else if (eState == OMX_StateInvalid)
1510            {
1511                DEBUG_PRINT("OMXCORE-SM: Idle-->Invalid\n");
1512                m_state = OMX_StateInvalid;
1513                this->m_cb.EventHandler(&this->m_cmp,
1514                                        this->m_app_data,
1515                                        OMX_EventError,
1516                                        OMX_ErrorInvalidState,
1517                                        0, NULL );
1518                eRet = OMX_ErrorInvalidState;
1519            } else
1520            {
1521                DEBUG_PRINT_ERROR("SCP--> Idle to %d Not Handled\n",eState);
1522                eRet = OMX_ErrorBadParameter;
1523            }
1524        }
1525
1526        /******************************/
1527        /* Current State is Executing */
1528        /******************************/
1529        else if (OMX_StateExecuting == m_state)
1530        {
1531            if (OMX_StateIdle == eState)
1532            {
1533                DEBUG_PRINT("SCP-->Executing to Idle \n");
1534                if(pcm_input)
1535                    execute_omx_flush(-1,false);
1536                else
1537                    execute_omx_flush(1,false);
1538
1539
1540            } else if (OMX_StatePause == eState)
1541            {
1542                DEBUG_DETAIL("*************************\n");
1543                DEBUG_PRINT("SCP-->RXED PAUSE STATE\n");
1544                DEBUG_DETAIL("*************************\n");
1545                //ioctl(m_drv_fd, AUDIO_PAUSE, 0);
1546            } else if (eState == OMX_StateLoaded)
1547            {
1548                DEBUG_PRINT("\n OMXCORE-SM: Executing --> Loaded \n");
1549                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1550                                        OMX_EventError,
1551                                        OMX_ErrorIncorrectStateTransition,
1552                                        0, NULL );
1553                eRet = OMX_ErrorIncorrectStateTransition;
1554            } else if (eState == OMX_StateWaitForResources)
1555            {
1556                DEBUG_PRINT("\n OMXCORE-SM: Executing --> WaitForResources \n");
1557                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1558                                        OMX_EventError,
1559                                        OMX_ErrorIncorrectStateTransition,
1560                                        0, NULL );
1561                eRet = OMX_ErrorIncorrectStateTransition;
1562            } else if (eState == OMX_StateExecuting)
1563            {
1564                DEBUG_PRINT("\n OMXCORE-SM: Executing --> Executing \n");
1565                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1566                                        OMX_EventError, OMX_ErrorSameState,
1567                                        0, NULL );
1568                eRet = OMX_ErrorSameState;
1569            } else if (eState == OMX_StateInvalid)
1570            {
1571                DEBUG_PRINT("\n OMXCORE-SM: Executing --> Invalid \n");
1572                m_state = OMX_StateInvalid;
1573                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1574                                        OMX_EventError, OMX_ErrorInvalidState,
1575                                        0, NULL );
1576                eRet = OMX_ErrorInvalidState;
1577            } else
1578            {
1579                DEBUG_PRINT_ERROR("SCP--> Executing to %d Not Handled\n",
1580					eState);
1581                eRet = OMX_ErrorBadParameter;
1582            }
1583        }
1584        /***************************/
1585        /* Current State is Pause  */
1586        /***************************/
1587        else if (OMX_StatePause == m_state)
1588        {
1589            if( (eState == OMX_StateExecuting || eState == OMX_StateIdle) )
1590            {
1591                pthread_mutex_lock(&m_out_th_lock_1);
1592                if(is_out_th_sleep)
1593                {
1594                    DEBUG_DETAIL("PE: WAKING UP OUT THREAD\n");
1595                    is_out_th_sleep = false;
1596                    out_th_wakeup();
1597                }
1598                pthread_mutex_unlock(&m_out_th_lock_1);
1599            }
1600            if ( OMX_StateExecuting == eState )
1601            {
1602                nState = eState;
1603            } else if ( OMX_StateIdle == eState )
1604            {
1605                DEBUG_PRINT("SCP-->Paused to Idle \n");
1606                DEBUG_PRINT ("\n Internal flush issued");
1607                pthread_mutex_lock(&m_flush_lock);
1608                m_flush_cnt = 2;
1609                pthread_mutex_unlock(&m_flush_lock);
1610                if(pcm_input)
1611                    execute_omx_flush(-1,false);
1612                else
1613                    execute_omx_flush(1,false);
1614
1615            } else if ( eState == OMX_StateLoaded )
1616            {
1617                DEBUG_PRINT("\n Pause --> loaded \n");
1618                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1619                                        OMX_EventError,
1620					OMX_ErrorIncorrectStateTransition,
1621                                        0, NULL );
1622                eRet = OMX_ErrorIncorrectStateTransition;
1623            } else if (eState == OMX_StateWaitForResources)
1624            {
1625                DEBUG_PRINT("\n Pause --> WaitForResources \n");
1626                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1627                                        OMX_EventError,
1628					OMX_ErrorIncorrectStateTransition,
1629                                        0, NULL );
1630                eRet = OMX_ErrorIncorrectStateTransition;
1631            } else if (eState == OMX_StatePause)
1632            {
1633                DEBUG_PRINT("\n Pause --> Pause \n");
1634                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1635                                        OMX_EventError, OMX_ErrorSameState,
1636                                        0, NULL );
1637                eRet = OMX_ErrorSameState;
1638            } else if (eState == OMX_StateInvalid)
1639            {
1640                DEBUG_PRINT("\n Pause --> Invalid \n");
1641                m_state = OMX_StateInvalid;
1642                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1643                                        OMX_EventError, OMX_ErrorInvalidState,
1644                                        0, NULL );
1645                eRet = OMX_ErrorInvalidState;
1646            } else
1647            {
1648                DEBUG_PRINT("SCP-->Paused to %d Not Handled\n",eState);
1649                eRet = OMX_ErrorBadParameter;
1650            }
1651        }
1652        /**************************************/
1653        /* Current State is WaitForResources  */
1654        /**************************************/
1655        else if (m_state == OMX_StateWaitForResources)
1656        {
1657            if (eState == OMX_StateLoaded)
1658            {
1659                DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Loaded\n");
1660            } else if (eState == OMX_StateWaitForResources)
1661            {
1662                DEBUG_PRINT("OMXCORE-SM: \
1663				WaitForResources-->WaitForResources\n");
1664                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1665                                        OMX_EventError, OMX_ErrorSameState,
1666                                        0, NULL );
1667                eRet = OMX_ErrorSameState;
1668            } else if (eState == OMX_StateExecuting)
1669            {
1670                DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Executing\n");
1671                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1672                                        OMX_EventError,
1673                                        OMX_ErrorIncorrectStateTransition,
1674                                        0, NULL );
1675                eRet = OMX_ErrorIncorrectStateTransition;
1676            } else if (eState == OMX_StatePause)
1677            {
1678                DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Pause\n");
1679                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1680                                        OMX_EventError,
1681                                        OMX_ErrorIncorrectStateTransition,
1682                                        0, NULL );
1683                eRet = OMX_ErrorIncorrectStateTransition;
1684            } else if (eState == OMX_StateInvalid)
1685            {
1686                DEBUG_PRINT("OMXCORE-SM: WaitForResources-->Invalid\n");
1687                m_state = OMX_StateInvalid;
1688                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1689                                        OMX_EventError,
1690                                        OMX_ErrorInvalidState,
1691                                        0, NULL );
1692                eRet = OMX_ErrorInvalidState;
1693            } else
1694            {
1695                DEBUG_PRINT_ERROR("SCP--> %d to %d(Not Handled)\n",
1696					m_state,eState);
1697                eRet = OMX_ErrorBadParameter;
1698            }
1699        }
1700        /****************************/
1701        /* Current State is Invalid */
1702        /****************************/
1703        else if (m_state == OMX_StateInvalid)
1704        {
1705            if (OMX_StateLoaded == eState || OMX_StateWaitForResources == eState
1706                || OMX_StateIdle == eState || OMX_StateExecuting == eState
1707                || OMX_StatePause == eState || OMX_StateInvalid == eState)
1708            {
1709                DEBUG_PRINT("OMXCORE-SM: Invalid-->Loaded/Idle/Executing"
1710                            "/Pause/Invalid/WaitForResources\n");
1711                m_state = OMX_StateInvalid;
1712                this->m_cb.EventHandler(&this->m_cmp, this->m_app_data,
1713                                        OMX_EventError, OMX_ErrorInvalidState,
1714                                        0, NULL );
1715                eRet = OMX_ErrorInvalidState;
1716            }
1717        } else
1718        {
1719            DEBUG_PRINT_ERROR("OMXCORE-SM: %d --> %d(Not Handled)\n",\
1720                              m_state,eState);
1721            eRet = OMX_ErrorBadParameter;
1722        }
1723    } else if (OMX_CommandFlush == cmd)
1724    {
1725        DEBUG_DETAIL("*************************\n");
1726        DEBUG_PRINT("SCP-->RXED FLUSH COMMAND port=%u\n",param1);
1727        DEBUG_DETAIL("*************************\n");
1728        bFlag = 0;
1729        if ( param1 == OMX_CORE_INPUT_PORT_INDEX ||
1730             param1 == OMX_CORE_OUTPUT_PORT_INDEX ||
1731            (signed)param1 == -1 )
1732        {
1733            execute_omx_flush(param1);
1734        } else
1735        {
1736            eRet = OMX_ErrorBadPortIndex;
1737            m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventError,
1738                OMX_CommandFlush, OMX_ErrorBadPortIndex, NULL );
1739        }
1740    } else if ( cmd == OMX_CommandPortDisable )
1741    {
1742    bFlag = 0;
1743        if ( param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL )
1744        {
1745            DEBUG_PRINT("SCP: Disabling Input port Indx\n");
1746            m_inp_bEnabled = OMX_FALSE;
1747            if ( (m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1748                && release_done(0) )
1749            {
1750                DEBUG_PRINT("send_command_proxy:OMX_CommandPortDisable:\
1751                            OMX_CORE_INPUT_PORT_INDEX:release_done \n");
1752                DEBUG_PRINT("************* OMX_CommandPortDisable:\
1753                            m_inp_bEnabled=%d********\n",m_inp_bEnabled);
1754
1755                post_command(OMX_CommandPortDisable,
1756                             OMX_CORE_INPUT_PORT_INDEX,
1757                             OMX_COMPONENT_GENERATE_EVENT);
1758            }
1759
1760            else
1761            {
1762                if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1763                {
1764                    DEBUG_PRINT("SCP: execute_omx_flush in Disable in "\
1765                                " param1=%u m_state=%d \n",param1, m_state);
1766                    execute_omx_flush(param1);
1767                }
1768                DEBUG_PRINT("send_command_proxy:OMX_CommandPortDisable:\
1769                            OMX_CORE_INPUT_PORT_INDEX \n");
1770                BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
1771                // Skip the event notification
1772
1773            }
1774
1775        }
1776        if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
1777        {
1778
1779            DEBUG_PRINT("SCP: Disabling Output port Indx\n");
1780            m_out_bEnabled = OMX_FALSE;
1781            if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1782                && release_done(1))
1783            {
1784                DEBUG_PRINT("send_command_proxy:OMX_CommandPortDisable:\
1785                            OMX_CORE_OUTPUT_PORT_INDEX:release_done \n");
1786                DEBUG_PRINT("************* OMX_CommandPortDisable:\
1787                            m_out_bEnabled=%d********\n",m_inp_bEnabled);
1788
1789                post_command(OMX_CommandPortDisable,
1790                             OMX_CORE_OUTPUT_PORT_INDEX,
1791                             OMX_COMPONENT_GENERATE_EVENT);
1792            } else
1793            {
1794                if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1795                {
1796                    DEBUG_PRINT("SCP: execute_omx_flush in Disable out "\
1797                                "param1=%u m_state=%d \n",param1, m_state);
1798                    execute_omx_flush(param1);
1799                }
1800                BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
1801                // Skip the event notification
1802
1803            }
1804        } else
1805        {
1806            DEBUG_PRINT_ERROR("OMX_CommandPortDisable: disable wrong port ID");
1807        }
1808
1809    } else if (cmd == OMX_CommandPortEnable)
1810    {
1811    bFlag = 0;
1812        if (param1 == OMX_CORE_INPUT_PORT_INDEX  || param1 == OMX_ALL)
1813        {
1814            m_inp_bEnabled = OMX_TRUE;
1815            DEBUG_PRINT("SCP: Enabling Input port Indx\n");
1816            if ((m_state == OMX_StateLoaded
1817                 && !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1818                || (m_state == OMX_StateWaitForResources)
1819                || (m_inp_bPopulated == OMX_TRUE))
1820            {
1821                post_command(OMX_CommandPortEnable,
1822                             OMX_CORE_INPUT_PORT_INDEX,
1823                             OMX_COMPONENT_GENERATE_EVENT);
1824
1825
1826            } else
1827            {
1828                BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
1829                // Skip the event notification
1830
1831            }
1832        }
1833
1834        if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
1835        {
1836            DEBUG_PRINT("SCP: Enabling Output port Indx\n");
1837            m_out_bEnabled = OMX_TRUE;
1838            if ((m_state == OMX_StateLoaded
1839                 && !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1840                || (m_state == OMX_StateWaitForResources)
1841                || (m_out_bPopulated == OMX_TRUE))
1842            {
1843                post_command(OMX_CommandPortEnable,
1844                             OMX_CORE_OUTPUT_PORT_INDEX,
1845                             OMX_COMPONENT_GENERATE_EVENT);
1846            } else
1847            {
1848                DEBUG_PRINT("send_command_proxy:OMX_CommandPortEnable:\
1849                            OMX_CORE_OUTPUT_PORT_INDEX:release_done \n");
1850                BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
1851                // Skip the event notification
1852
1853            }
1854            pthread_mutex_lock(&m_in_th_lock_1);
1855            if(is_in_th_sleep)
1856            {
1857                    is_in_th_sleep = false;
1858                    DEBUG_DETAIL("SCP:WAKING UP IN THREADS\n");
1859                    in_th_wakeup();
1860            }
1861            pthread_mutex_unlock(&m_in_th_lock_1);
1862            pthread_mutex_lock(&m_out_th_lock_1);
1863            if (is_out_th_sleep)
1864            {
1865                is_out_th_sleep = false;
1866                DEBUG_PRINT("SCP:WAKING OUT THR, OMX_CommandPortEnable\n");
1867                out_th_wakeup();
1868            }
1869            pthread_mutex_unlock(&m_out_th_lock_1);
1870        } else
1871        {
1872            DEBUG_PRINT_ERROR("OMX_CommandPortEnable: disable wrong port ID");
1873        }
1874
1875    } else
1876    {
1877        DEBUG_PRINT_ERROR("SCP-->ERROR: Invali Command [%d]\n",cmd);
1878        eRet = OMX_ErrorNotImplemented;
1879    }
1880    DEBUG_PRINT("posting sem_States\n");
1881    sem_post (&sem_States);
1882    if (eRet == OMX_ErrorNone && bFlag)
1883    {
1884        post_command(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
1885    }
1886    return eRet;
1887}
1888
1889/*=============================================================================
1890FUNCTION:
1891  execute_omx_flush
1892
1893DESCRIPTION:
1894  Function that flushes buffers that are pending to be written to driver
1895
1896INPUT/OUTPUT PARAMETERS:
1897  [IN] param1
1898  [IN] cmd_cmpl
1899
1900RETURN VALUE:
1901  true
1902  false
1903
1904Dependency:
1905  None
1906
1907SIDE EFFECTS:
1908  None
1909=============================================================================*/
1910bool omx_amr_aenc::execute_omx_flush(OMX_IN OMX_U32 param1, bool cmd_cmpl)
1911{
1912    bool bRet = true;
1913
1914    DEBUG_PRINT("Execute_omx_flush Port[%u]", param1);
1915    struct timespec abs_timeout;
1916    abs_timeout.tv_sec = 1;
1917    abs_timeout.tv_nsec = 0;
1918
1919    if ((signed)param1 == -1)
1920    {
1921        bFlushinprogress = true;
1922        DEBUG_PRINT("Execute flush for both I/p O/p port\n");
1923        pthread_mutex_lock(&m_flush_lock);
1924        m_flush_cnt = 2;
1925        pthread_mutex_unlock(&m_flush_lock);
1926
1927        // Send Flush commands to input and output threads
1928        post_input(OMX_CommandFlush,
1929                   OMX_CORE_INPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND);
1930        post_output(OMX_CommandFlush,
1931                    OMX_CORE_OUTPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND);
1932        // Send Flush to the kernel so that the in and out buffers are released
1933        if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) == -1)
1934            DEBUG_PRINT_ERROR("FLush:ioctl flush failed errno=%d\n",errno);
1935        DEBUG_DETAIL("****************************************");
1936        DEBUG_DETAIL("is_in_th_sleep=%d is_out_th_sleep=%d\n",\
1937                     is_in_th_sleep,is_out_th_sleep);
1938        DEBUG_DETAIL("****************************************");
1939
1940        pthread_mutex_lock(&m_in_th_lock_1);
1941        if (is_in_th_sleep)
1942        {
1943            is_in_th_sleep = false;
1944            DEBUG_DETAIL("For FLUSH-->WAKING UP IN THREADS\n");
1945            in_th_wakeup();
1946        }
1947        pthread_mutex_unlock(&m_in_th_lock_1);
1948
1949        pthread_mutex_lock(&m_out_th_lock_1);
1950        if (is_out_th_sleep)
1951        {
1952            is_out_th_sleep = false;
1953            DEBUG_DETAIL("For FLUSH-->WAKING UP OUT THREADS\n");
1954            out_th_wakeup();
1955        }
1956        pthread_mutex_unlock(&m_out_th_lock_1);
1957
1958
1959        // sleep till the FLUSH ACK are done by both the input and
1960        // output threads
1961        DEBUG_DETAIL("WAITING FOR FLUSH ACK's param1=%d",param1);
1962        wait_for_event();
1963
1964        DEBUG_PRINT("RECIEVED BOTH FLUSH ACK's param1=%u cmd_cmpl=%d",\
1965                    param1,cmd_cmpl);
1966
1967        // If not going to idle state, Send FLUSH complete message
1968	// to the Client, now that FLUSH ACK's have been recieved.
1969        if (cmd_cmpl)
1970        {
1971            m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete,
1972                              OMX_CommandFlush, OMX_CORE_INPUT_PORT_INDEX,
1973				NULL );
1974            m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete,
1975                              OMX_CommandFlush, OMX_CORE_OUTPUT_PORT_INDEX,
1976				NULL );
1977            DEBUG_PRINT("Inside FLUSH.. sending FLUSH CMPL\n");
1978        }
1979        bFlushinprogress = false;
1980    }
1981    else if (param1 == OMX_CORE_INPUT_PORT_INDEX)
1982    {
1983        DEBUG_PRINT("Execute FLUSH for I/p port\n");
1984        pthread_mutex_lock(&m_flush_lock);
1985        m_flush_cnt = 1;
1986        pthread_mutex_unlock(&m_flush_lock);
1987        post_input(OMX_CommandFlush,
1988                   OMX_CORE_INPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND);
1989        if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) == -1)
1990            DEBUG_PRINT_ERROR("Flush:Input port, ioctl flush failed %d\n",
1991				errno);
1992        DEBUG_DETAIL("****************************************");
1993        DEBUG_DETAIL("is_in_th_sleep=%d is_out_th_sleep=%d\n",\
1994                     is_in_th_sleep,is_out_th_sleep);
1995        DEBUG_DETAIL("****************************************");
1996
1997        if (is_in_th_sleep)
1998        {
1999            pthread_mutex_lock(&m_in_th_lock_1);
2000            is_in_th_sleep = false;
2001            pthread_mutex_unlock(&m_in_th_lock_1);
2002            DEBUG_DETAIL("For FLUSH-->WAKING UP IN THREADS\n");
2003            in_th_wakeup();
2004        }
2005
2006        if (is_out_th_sleep)
2007        {
2008            pthread_mutex_lock(&m_out_th_lock_1);
2009            is_out_th_sleep = false;
2010            pthread_mutex_unlock(&m_out_th_lock_1);
2011            DEBUG_DETAIL("For FLUSH-->WAKING UP OUT THREADS\n");
2012            out_th_wakeup();
2013        }
2014
2015        //sleep till the FLUSH ACK are done by both the input and output threads
2016        DEBUG_DETAIL("Executing FLUSH for I/p port\n");
2017        DEBUG_DETAIL("WAITING FOR FLUSH ACK's param1=%d",param1);
2018        wait_for_event();
2019        DEBUG_DETAIL(" RECIEVED FLUSH ACK FOR I/P PORT param1=%d",param1);
2020
2021        // Send FLUSH complete message to the Client,
2022        // now that FLUSH ACK's have been recieved.
2023        if (cmd_cmpl)
2024        {
2025            m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete,
2026                              OMX_CommandFlush, OMX_CORE_INPUT_PORT_INDEX,
2027				NULL );
2028        }
2029    } else if (OMX_CORE_OUTPUT_PORT_INDEX == param1)
2030    {
2031        DEBUG_PRINT("Executing FLUSH for O/p port\n");
2032        pthread_mutex_lock(&m_flush_lock);
2033        m_flush_cnt = 1;
2034        pthread_mutex_unlock(&m_flush_lock);
2035        DEBUG_DETAIL("Executing FLUSH for O/p port\n");
2036        DEBUG_DETAIL("WAITING FOR FLUSH ACK's param1=%d",param1);
2037        post_output(OMX_CommandFlush,
2038                    OMX_CORE_OUTPUT_PORT_INDEX,OMX_COMPONENT_GENERATE_COMMAND);
2039        if (ioctl( m_drv_fd, AUDIO_FLUSH, 0) ==-1)
2040            DEBUG_PRINT_ERROR("Flush:Output port, ioctl flush failed %d\n",
2041				errno);
2042        DEBUG_DETAIL("****************************************");
2043        DEBUG_DETAIL("is_in_th_sleep=%d is_out_th_sleep=%d\n",\
2044                     is_in_th_sleep,is_out_th_sleep);
2045        DEBUG_DETAIL("****************************************");
2046        if (is_in_th_sleep)
2047        {
2048            pthread_mutex_lock(&m_in_th_lock_1);
2049            is_in_th_sleep = false;
2050            pthread_mutex_unlock(&m_in_th_lock_1);
2051            DEBUG_DETAIL("For FLUSH-->WAKING UP IN THREADS\n");
2052            in_th_wakeup();
2053        }
2054
2055        if (is_out_th_sleep)
2056        {
2057            pthread_mutex_lock(&m_out_th_lock_1);
2058            is_out_th_sleep = false;
2059            pthread_mutex_unlock(&m_out_th_lock_1);
2060            DEBUG_DETAIL("For FLUSH-->WAKING UP OUT THREADS\n");
2061            out_th_wakeup();
2062        }
2063
2064        // sleep till the FLUSH ACK are done by both the input and
2065	// output threads
2066        wait_for_event();
2067        // Send FLUSH complete message to the Client,
2068        // now that FLUSH ACK's have been recieved.
2069        if (cmd_cmpl)
2070        {
2071            m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete,
2072                              OMX_CommandFlush, OMX_CORE_OUTPUT_PORT_INDEX,
2073				NULL );
2074        }
2075        DEBUG_DETAIL("RECIEVED FLUSH ACK FOR O/P PORT param1=%d",param1);
2076    } else
2077    {
2078        DEBUG_PRINT("Invalid Port ID[%u]",param1);
2079    }
2080    return bRet;
2081}
2082
2083/*=============================================================================
2084FUNCTION:
2085  execute_input_omx_flush
2086
2087DESCRIPTION:
2088  Function that flushes buffers that are pending to be written to driver
2089
2090INPUT/OUTPUT PARAMETERS:
2091  None
2092
2093RETURN VALUE:
2094  true
2095  false
2096
2097Dependency:
2098  None
2099
2100SIDE EFFECTS:
2101  None
2102=============================================================================*/
2103bool omx_amr_aenc::execute_input_omx_flush()
2104{
2105    OMX_BUFFERHEADERTYPE *omx_buf;
2106    unsigned long p1 = 0;                            // Parameter - 1
2107    unsigned long p2 = 0;                            // Parameter - 2
2108    unsigned char ident = 0;
2109    unsigned      qsize=0;                       // qsize
2110    unsigned      tot_qsize=0;                   // qsize
2111
2112    DEBUG_PRINT("Execute_omx_flush on input port");
2113
2114    pthread_mutex_lock(&m_lock);
2115    do
2116    {
2117        qsize = m_input_q.m_size;
2118        tot_qsize = qsize;
2119        tot_qsize += m_input_ctrl_ebd_q.m_size;
2120
2121        DEBUG_DETAIL("Input FLUSH-->flushq[%d] ebd[%d]dataq[%d]",\
2122                     m_input_ctrl_cmd_q.m_size,
2123                     m_input_ctrl_ebd_q.m_size,qsize);
2124        if (!tot_qsize)
2125        {
2126            DEBUG_DETAIL("Input-->BREAKING FROM execute_input_flush LOOP");
2127            pthread_mutex_unlock(&m_lock);
2128            break;
2129        }
2130        if (qsize)
2131        {
2132            m_input_q.pop_entry(&p1, &p2, &ident);
2133            if ((ident == OMX_COMPONENT_GENERATE_ETB) ||
2134                (ident == OMX_COMPONENT_GENERATE_BUFFER_DONE))
2135            {
2136                omx_buf = (OMX_BUFFERHEADERTYPE *) p2;
2137                DEBUG_DETAIL("Flush:Input dataq=%p \n", omx_buf);
2138                omx_buf->nFilledLen = 0;
2139                buffer_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf);
2140            }
2141        } else if (m_input_ctrl_ebd_q.m_size)
2142        {
2143            m_input_ctrl_ebd_q.pop_entry(&p1, &p2, &ident);
2144            if (ident == OMX_COMPONENT_GENERATE_BUFFER_DONE)
2145            {
2146                omx_buf = (OMX_BUFFERHEADERTYPE *) p2;
2147                omx_buf->nFilledLen = 0;
2148                DEBUG_DETAIL("Flush:ctrl dataq=%p \n", omx_buf);
2149                buffer_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf);
2150            }
2151        } else
2152        {
2153        }
2154    }while (tot_qsize>0);
2155    DEBUG_DETAIL("*************************\n");
2156    DEBUG_DETAIL("IN-->FLUSHING DONE\n");
2157    DEBUG_DETAIL("*************************\n");
2158    flush_ack();
2159    pthread_mutex_unlock(&m_lock);
2160    return true;
2161}
2162
2163/*=============================================================================
2164FUNCTION:
2165  execute_output_omx_flush
2166
2167DESCRIPTION:
2168  Function that flushes buffers that are pending to be written to driver
2169
2170INPUT/OUTPUT PARAMETERS:
2171  None
2172
2173RETURN VALUE:
2174  true
2175  false
2176
2177Dependency:
2178  None
2179
2180SIDE EFFECTS:
2181  None
2182=============================================================================*/
2183bool omx_amr_aenc::execute_output_omx_flush()
2184{
2185    OMX_BUFFERHEADERTYPE *omx_buf;
2186    unsigned long p1 = 0;                            // Parameter - 1
2187    unsigned long p2 = 0;                            // Parameter - 2
2188    unsigned char ident = 0;
2189    unsigned      qsize=0;                       // qsize
2190    unsigned      tot_qsize=0;                   // qsize
2191
2192    DEBUG_PRINT("Execute_omx_flush on output port");
2193
2194    pthread_mutex_lock(&m_outputlock);
2195    do
2196    {
2197        qsize = m_output_q.m_size;
2198        DEBUG_DETAIL("OUT FLUSH-->flushq[%d] fbd[%d]dataq[%d]",\
2199                     m_output_ctrl_cmd_q.m_size,
2200                     m_output_ctrl_fbd_q.m_size,qsize);
2201        tot_qsize = qsize;
2202        tot_qsize += m_output_ctrl_fbd_q.m_size;
2203        if (!tot_qsize)
2204        {
2205            DEBUG_DETAIL("OUT-->BREAKING FROM execute_input_flush LOOP");
2206            pthread_mutex_unlock(&m_outputlock);
2207            break;
2208        }
2209        if (qsize)
2210        {
2211            m_output_q.pop_entry(&p1,&p2,&ident);
2212            if ( (OMX_COMPONENT_GENERATE_FTB == ident) ||
2213                 (OMX_COMPONENT_GENERATE_FRAME_DONE == ident))
2214            {
2215                omx_buf = (OMX_BUFFERHEADERTYPE *) p2;
2216                DEBUG_DETAIL("Ouput Buf_Addr=%p TS[0x%x] \n",\
2217                             omx_buf,nTimestamp);
2218                omx_buf->nTimeStamp = nTimestamp;
2219                omx_buf->nFilledLen = 0;
2220                frame_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf);
2221                DEBUG_DETAIL("CALLING FBD FROM FLUSH");
2222            }
2223        } else if ((qsize = m_output_ctrl_fbd_q.m_size))
2224        {
2225            m_output_ctrl_fbd_q.pop_entry(&p1, &p2, &ident);
2226            if (OMX_COMPONENT_GENERATE_FRAME_DONE == ident)
2227            {
2228                omx_buf = (OMX_BUFFERHEADERTYPE *) p2;
2229                DEBUG_DETAIL("Ouput Buf_Addr=%p TS[0x%x] \n", \
2230                             omx_buf,nTimestamp);
2231                omx_buf->nTimeStamp = nTimestamp;
2232                omx_buf->nFilledLen = 0;
2233                frame_done_cb((OMX_BUFFERHEADERTYPE *)omx_buf);
2234                DEBUG_DETAIL("CALLING FROM CTRL-FBDQ FROM FLUSH");
2235            }
2236        }
2237    }while (qsize>0);
2238    DEBUG_DETAIL("*************************\n");
2239    DEBUG_DETAIL("OUT-->FLUSHING DONE\n");
2240    DEBUG_DETAIL("*************************\n");
2241    flush_ack();
2242    pthread_mutex_unlock(&m_outputlock);
2243    return true;
2244}
2245
2246/*=============================================================================
2247FUNCTION:
2248  post_input
2249
2250DESCRIPTION:
2251  Function that posts command in the command queue
2252
2253INPUT/OUTPUT PARAMETERS:
2254  [IN] p1
2255  [IN] p2
2256  [IN] id - command ID
2257  [IN] lock - self-locking mode
2258
2259RETURN VALUE:
2260  true
2261  false
2262
2263Dependency:
2264  None
2265
2266SIDE EFFECTS:
2267  None
2268=============================================================================*/
2269bool omx_amr_aenc::post_input(unsigned long p1,
2270                               unsigned long p2,
2271                               unsigned char id)
2272{
2273    bool bRet = false;
2274    pthread_mutex_lock(&m_lock);
2275
2276    if((OMX_COMPONENT_GENERATE_COMMAND == id) || (id == OMX_COMPONENT_SUSPEND))
2277    {
2278        // insert flush message and ebd
2279        m_input_ctrl_cmd_q.insert_entry(p1,p2,id);
2280    } else if ((OMX_COMPONENT_GENERATE_BUFFER_DONE == id))
2281    {
2282        // insert ebd
2283        m_input_ctrl_ebd_q.insert_entry(p1,p2,id);
2284    } else
2285    {
2286        // ETBS in this queue
2287        m_input_q.insert_entry(p1,p2,id);
2288    }
2289
2290    if (m_ipc_to_in_th)
2291    {
2292        bRet = true;
2293        omx_amr_post_msg(m_ipc_to_in_th, id);
2294    }
2295
2296    DEBUG_DETAIL("PostInput-->state[%d]id[%d]flushq[%d]ebdq[%d]dataq[%d] \n",\
2297                 m_state,
2298                 id,
2299                 m_input_ctrl_cmd_q.m_size,
2300                 m_input_ctrl_ebd_q.m_size,
2301                 m_input_q.m_size);
2302
2303    pthread_mutex_unlock(&m_lock);
2304    return bRet;
2305}
2306
2307/*=============================================================================
2308FUNCTION:
2309  post_command
2310
2311DESCRIPTION:
2312  Function that posts command in the command queue
2313
2314INPUT/OUTPUT PARAMETERS:
2315  [IN] p1
2316  [IN] p2
2317  [IN] id - command ID
2318  [IN] lock - self-locking mode
2319
2320RETURN VALUE:
2321  true
2322  false
2323
2324Dependency:
2325  None
2326
2327SIDE EFFECTS:
2328  None
2329=============================================================================*/
2330bool omx_amr_aenc::post_command(unsigned int p1,
2331                                 unsigned int p2,
2332                                 unsigned char id)
2333{
2334    bool bRet  = false;
2335
2336    pthread_mutex_lock(&m_commandlock);
2337
2338    m_command_q.insert_entry(p1,p2,id);
2339
2340    if (m_ipc_to_cmd_th)
2341    {
2342        bRet = true;
2343        omx_amr_post_msg(m_ipc_to_cmd_th, id);
2344    }
2345
2346    DEBUG_DETAIL("PostCmd-->state[%d]id[%d]cmdq[%d]flags[%x]\n",\
2347                 m_state,
2348                 id,
2349                 m_command_q.m_size,
2350                 m_flags >> 3);
2351
2352    pthread_mutex_unlock(&m_commandlock);
2353    return bRet;
2354}
2355
2356/*=============================================================================
2357FUNCTION:
2358  post_output
2359
2360DESCRIPTION:
2361  Function that posts command in the command queue
2362
2363INPUT/OUTPUT PARAMETERS:
2364  [IN] p1
2365  [IN] p2
2366  [IN] id - command ID
2367  [IN] lock - self-locking mode
2368
2369RETURN VALUE:
2370  true
2371  false
2372
2373Dependency:
2374  None
2375
2376SIDE EFFECTS:
2377  None
2378=============================================================================*/
2379bool omx_amr_aenc::post_output(unsigned long p1,
2380                                unsigned long p2,
2381                                unsigned char id)
2382{
2383    bool bRet = false;
2384
2385    pthread_mutex_lock(&m_outputlock);
2386    if((OMX_COMPONENT_GENERATE_COMMAND == id) || (id == OMX_COMPONENT_SUSPEND)
2387        || (id == OMX_COMPONENT_RESUME))
2388    {
2389        // insert flush message and fbd
2390        m_output_ctrl_cmd_q.insert_entry(p1,p2,id);
2391    } else if ( (OMX_COMPONENT_GENERATE_FRAME_DONE == id) )
2392    {
2393        // insert flush message and fbd
2394        m_output_ctrl_fbd_q.insert_entry(p1,p2,id);
2395    } else
2396    {
2397        m_output_q.insert_entry(p1,p2,id);
2398    }
2399    if ( m_ipc_to_out_th )
2400    {
2401        bRet = true;
2402        omx_amr_post_msg(m_ipc_to_out_th, id);
2403    }
2404    DEBUG_DETAIL("PostOutput-->state[%d]id[%d]flushq[%d]ebdq[%d]dataq[%d]\n",\
2405                 m_state,
2406                 id,
2407                 m_output_ctrl_cmd_q.m_size,
2408                 m_output_ctrl_fbd_q.m_size,
2409                 m_output_q.m_size);
2410
2411    pthread_mutex_unlock(&m_outputlock);
2412    return bRet;
2413}
2414/**
2415  @brief member function that return parameters to IL client
2416
2417  @param hComp handle to component instance
2418  @param paramIndex Parameter type
2419  @param paramData pointer to memory space which would hold the
2420        paramter
2421  @return error status
2422*/
2423OMX_ERRORTYPE  omx_amr_aenc::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
2424                                            OMX_IN OMX_INDEXTYPE paramIndex,
2425                                            OMX_INOUT OMX_PTR     paramData)
2426{
2427    OMX_ERRORTYPE eRet = OMX_ErrorNone;
2428
2429    if(hComp == NULL)
2430    {
2431        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
2432        return OMX_ErrorBadParameter;
2433    }
2434    if (m_state == OMX_StateInvalid)
2435    {
2436        DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2437        return OMX_ErrorInvalidState;
2438    }
2439    if (paramData == NULL)
2440    {
2441        DEBUG_PRINT("get_parameter: paramData is NULL\n");
2442        return OMX_ErrorBadParameter;
2443    }
2444
2445    switch ((int)paramIndex)
2446    {
2447        case OMX_IndexParamPortDefinition:
2448            {
2449                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2450                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2451
2452                DEBUG_PRINT("OMX_IndexParamPortDefinition " \
2453                            "portDefn->nPortIndex = %u\n",
2454				portDefn->nPortIndex);
2455
2456                portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
2457                portDefn->nSize = (OMX_U32)sizeof(portDefn);
2458                portDefn->eDomain    = OMX_PortDomainAudio;
2459
2460                if (0 == portDefn->nPortIndex)
2461                {
2462                    portDefn->eDir       = OMX_DirInput;
2463                    portDefn->bEnabled   = m_inp_bEnabled;
2464                    portDefn->bPopulated = m_inp_bPopulated;
2465                    portDefn->nBufferCountActual = m_inp_act_buf_count;
2466                    portDefn->nBufferCountMin    = OMX_CORE_NUM_INPUT_BUFFERS;
2467                    portDefn->nBufferSize        = input_buffer_size;
2468                    portDefn->format.audio.bFlagErrorConcealment = OMX_TRUE;
2469                    portDefn->format.audio.eEncoding = OMX_AUDIO_CodingPCM;
2470                    portDefn->format.audio.pNativeRender = 0;
2471                } else if (1 == portDefn->nPortIndex)
2472                {
2473                    portDefn->eDir =  OMX_DirOutput;
2474                    portDefn->bEnabled   = m_out_bEnabled;
2475                    portDefn->bPopulated = m_out_bPopulated;
2476                    portDefn->nBufferCountActual = m_out_act_buf_count;
2477                    portDefn->nBufferCountMin    = OMX_CORE_NUM_OUTPUT_BUFFERS;
2478                    portDefn->nBufferSize        = output_buffer_size;
2479                    portDefn->format.audio.bFlagErrorConcealment = OMX_TRUE;
2480                    portDefn->format.audio.eEncoding = OMX_AUDIO_CodingAMR;
2481                    portDefn->format.audio.pNativeRender = 0;
2482                } else
2483                {
2484                    portDefn->eDir =  OMX_DirMax;
2485                    DEBUG_PRINT_ERROR("Bad Port idx %d\n",\
2486                                       (int)portDefn->nPortIndex);
2487                    eRet = OMX_ErrorBadPortIndex;
2488                }
2489                break;
2490            }
2491
2492        case OMX_IndexParamAudioInit:
2493            {
2494                OMX_PORT_PARAM_TYPE *portParamType =
2495                (OMX_PORT_PARAM_TYPE *) paramData;
2496                DEBUG_PRINT("OMX_IndexParamAudioInit\n");
2497
2498                portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2499                portParamType->nSize = (OMX_U32)sizeof(portParamType);
2500                portParamType->nPorts           = 2;
2501                portParamType->nStartPortNumber = 0;
2502                break;
2503            }
2504
2505        case OMX_IndexParamAudioPortFormat:
2506            {
2507                OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormatType =
2508                (OMX_AUDIO_PARAM_PORTFORMATTYPE *) paramData;
2509                DEBUG_PRINT("OMX_IndexParamAudioPortFormat\n");
2510                portFormatType->nVersion.nVersion = OMX_SPEC_VERSION;
2511                portFormatType->nSize = (OMX_U32)sizeof(portFormatType);
2512
2513                if (OMX_CORE_INPUT_PORT_INDEX == portFormatType->nPortIndex)
2514                {
2515
2516                    portFormatType->eEncoding = OMX_AUDIO_CodingPCM;
2517                } else if (OMX_CORE_OUTPUT_PORT_INDEX==
2518				portFormatType->nPortIndex)
2519                {
2520                    DEBUG_PRINT("get_parameter: OMX_IndexParamAudioFormat: "\
2521                                "%u\n", portFormatType->nIndex);
2522
2523            portFormatType->eEncoding = OMX_AUDIO_CodingAMR;
2524                } else
2525                {
2526                    DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2527                                      (int)portFormatType->nPortIndex);
2528                    eRet = OMX_ErrorBadPortIndex;
2529                }
2530                break;
2531            }
2532
2533        case OMX_IndexParamAudioAmr:
2534            {
2535                OMX_AUDIO_PARAM_AMRTYPE *amrParam =
2536                (OMX_AUDIO_PARAM_AMRTYPE *) paramData;
2537                DEBUG_PRINT("OMX_IndexParamAudioAmr\n");
2538                if (OMX_CORE_OUTPUT_PORT_INDEX== amrParam->nPortIndex)
2539                {
2540                    memcpy(amrParam,&m_amr_param,
2541                    sizeof(OMX_AUDIO_PARAM_AMRTYPE));
2542                } else
2543                {
2544                    DEBUG_PRINT_ERROR("get_parameter:OMX_IndexParamAudioAmr "\
2545                                      "OMX_ErrorBadPortIndex %d\n", \
2546                                      (int)amrParam->nPortIndex);
2547                    eRet = OMX_ErrorBadPortIndex;
2548                }
2549                break;
2550            }
2551    case QOMX_IndexParamAudioSessionId:
2552    {
2553       QOMX_AUDIO_STREAM_INFO_DATA *streaminfoparam =
2554               (QOMX_AUDIO_STREAM_INFO_DATA *) paramData;
2555       streaminfoparam->sessionId = (OMX_U8)m_session_id;
2556       break;
2557    }
2558
2559        case OMX_IndexParamAudioPcm:
2560            {
2561                OMX_AUDIO_PARAM_PCMMODETYPE *pcmparam =
2562                (OMX_AUDIO_PARAM_PCMMODETYPE *) paramData;
2563
2564                if (OMX_CORE_INPUT_PORT_INDEX== pcmparam->nPortIndex)
2565                {
2566                    memcpy(pcmparam,&m_pcm_param,\
2567                        sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
2568                    DEBUG_PRINT("get_parameter: Sampling rate %u",\
2569                                 pcmparam->nSamplingRate);
2570                    DEBUG_PRINT("get_parameter: Number of channels %u",\
2571                                 pcmparam->nChannels);
2572                } else
2573                {
2574                    DEBUG_PRINT_ERROR("get_parameter:OMX_IndexParamAudioPcm "\
2575                                      "OMX_ErrorBadPortIndex %d\n", \
2576                                      (int)pcmparam->nPortIndex);
2577                     eRet = OMX_ErrorBadPortIndex;
2578                }
2579                break;
2580         }
2581        case OMX_IndexParamComponentSuspended:
2582        {
2583            OMX_PARAM_SUSPENSIONTYPE *suspend=
2584			(OMX_PARAM_SUSPENSIONTYPE *) paramData;
2585            DEBUG_PRINT("get_parameter: OMX_IndexParamComponentSuspended %p\n",
2586			suspend);
2587            break;
2588        }
2589        case OMX_IndexParamVideoInit:
2590            {
2591                OMX_PORT_PARAM_TYPE *portParamType =
2592                    (OMX_PORT_PARAM_TYPE *) paramData;
2593                DEBUG_PRINT("get_parameter: OMX_IndexParamVideoInit\n");
2594                portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2595                portParamType->nSize = (OMX_U32)sizeof(portParamType);
2596                portParamType->nPorts           = 0;
2597                portParamType->nStartPortNumber = 0;
2598                break;
2599            }
2600        case OMX_IndexParamPriorityMgmt:
2601            {
2602                OMX_PRIORITYMGMTTYPE *priorityMgmtType =
2603                (OMX_PRIORITYMGMTTYPE*)paramData;
2604                DEBUG_PRINT("get_parameter: OMX_IndexParamPriorityMgmt\n");
2605                priorityMgmtType->nSize = (OMX_U32)sizeof(priorityMgmtType);
2606                priorityMgmtType->nVersion.nVersion = OMX_SPEC_VERSION;
2607                priorityMgmtType->nGroupID = m_priority_mgm.nGroupID;
2608                priorityMgmtType->nGroupPriority =
2609				m_priority_mgm.nGroupPriority;
2610                break;
2611            }
2612        case OMX_IndexParamImageInit:
2613            {
2614                OMX_PORT_PARAM_TYPE *portParamType =
2615                (OMX_PORT_PARAM_TYPE *) paramData;
2616                DEBUG_PRINT("get_parameter: OMX_IndexParamImageInit\n");
2617                portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2618                portParamType->nSize = (OMX_U32)sizeof(portParamType);
2619                portParamType->nPorts           = 0;
2620                portParamType->nStartPortNumber = 0;
2621                break;
2622            }
2623
2624        case OMX_IndexParamCompBufferSupplier:
2625            {
2626                DEBUG_PRINT("get_parameter: \
2627				OMX_IndexParamCompBufferSupplier\n");
2628                OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType
2629                = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2630                DEBUG_PRINT("get_parameter: \
2631				OMX_IndexParamCompBufferSupplier\n");
2632
2633                bufferSupplierType->nSize = (OMX_U32)sizeof(bufferSupplierType);
2634                bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2635                if (OMX_CORE_INPUT_PORT_INDEX   ==
2636				bufferSupplierType->nPortIndex)
2637                {
2638                    bufferSupplierType->nPortIndex =
2639				OMX_BufferSupplyUnspecified;
2640                } else if (OMX_CORE_OUTPUT_PORT_INDEX ==
2641				bufferSupplierType->nPortIndex)
2642                {
2643                    bufferSupplierType->nPortIndex =
2644				OMX_BufferSupplyUnspecified;
2645                } else
2646                {
2647                    DEBUG_PRINT_ERROR("get_parameter:"\
2648                                      "OMX_IndexParamCompBufferSupplier eRet"\
2649                                      "%08x\n", eRet);
2650                    eRet = OMX_ErrorBadPortIndex;
2651                }
2652                 break;
2653            }
2654
2655            /*Component should support this port definition*/
2656        case OMX_IndexParamOtherInit:
2657            {
2658                OMX_PORT_PARAM_TYPE *portParamType =
2659                    (OMX_PORT_PARAM_TYPE *) paramData;
2660                DEBUG_PRINT("get_parameter: OMX_IndexParamOtherInit\n");
2661                portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2662                portParamType->nSize = (OMX_U32)sizeof(portParamType);
2663                portParamType->nPorts           = 0;
2664                portParamType->nStartPortNumber = 0;
2665                break;
2666            }
2667	case OMX_IndexParamStandardComponentRole:
2668            {
2669                OMX_PARAM_COMPONENTROLETYPE *componentRole;
2670                componentRole = (OMX_PARAM_COMPONENTROLETYPE*)paramData;
2671                componentRole->nSize = component_Role.nSize;
2672                componentRole->nVersion = component_Role.nVersion;
2673                strlcpy((char *)componentRole->cRole,
2674			(const char*)component_Role.cRole,
2675			sizeof(componentRole->cRole));
2676                DEBUG_PRINT_ERROR("nSize = %d , nVersion = %d, cRole = %s\n",
2677				component_Role.nSize,
2678				component_Role.nVersion,
2679				component_Role.cRole);
2680                break;
2681
2682            }
2683        default:
2684            {
2685                DEBUG_PRINT_ERROR("unknown param %08x\n", paramIndex);
2686                eRet = OMX_ErrorUnsupportedIndex;
2687            }
2688    }
2689    return eRet;
2690
2691}
2692
2693/**
2694 @brief member function that set paramter from IL client
2695
2696 @param hComp handle to component instance
2697 @param paramIndex parameter type
2698 @param paramData pointer to memory space which holds the paramter
2699 @return error status
2700 */
2701OMX_ERRORTYPE  omx_amr_aenc::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
2702                                            OMX_IN OMX_INDEXTYPE paramIndex,
2703                                            OMX_IN OMX_PTR        paramData)
2704{
2705    OMX_ERRORTYPE eRet = OMX_ErrorNone;
2706
2707    if(hComp == NULL)
2708    {
2709        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
2710        return OMX_ErrorBadParameter;
2711    }
2712    if (m_state != OMX_StateLoaded)
2713    {
2714        DEBUG_PRINT_ERROR("set_parameter is not in proper state\n");
2715        return OMX_ErrorIncorrectStateOperation;
2716    }
2717    if (paramData == NULL)
2718    {
2719        DEBUG_PRINT("param data is NULL");
2720        return OMX_ErrorBadParameter;
2721    }
2722
2723    switch (paramIndex)
2724    {
2725        case OMX_IndexParamAudioAmr:
2726            {
2727                DEBUG_PRINT("OMX_IndexParamAudioAmr");
2728                OMX_AUDIO_PARAM_AMRTYPE *amrparam
2729                = (OMX_AUDIO_PARAM_AMRTYPE *) paramData;
2730                memcpy(&m_amr_param,amrparam,
2731                                      sizeof(OMX_AUDIO_PARAM_AMRTYPE));
2732                break;
2733            }
2734        case OMX_IndexParamPortDefinition:
2735            {
2736                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2737                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2738
2739                if (((m_state == OMX_StateLoaded)&&
2740                     !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2741                    || (m_state == OMX_StateWaitForResources &&
2742                        ((OMX_DirInput == portDefn->eDir &&
2743			m_inp_bEnabled == true)||
2744                         (OMX_DirInput == portDefn->eDir &&
2745			m_out_bEnabled == true)))
2746                    ||(((OMX_DirInput == portDefn->eDir &&
2747			m_inp_bEnabled == false)||
2748                        (OMX_DirInput == portDefn->eDir &&
2749			m_out_bEnabled == false)) &&
2750                       (m_state != OMX_StateWaitForResources)))
2751                {
2752                    DEBUG_PRINT("Set Parameter called in valid state\n");
2753                } else
2754                {
2755                    DEBUG_PRINT_ERROR("Set Parameter called in \
2756					Invalid State\n");
2757                    return OMX_ErrorIncorrectStateOperation;
2758                }
2759                DEBUG_PRINT("OMX_IndexParamPortDefinition portDefn->nPortIndex "
2760                            "= %u\n",portDefn->nPortIndex);
2761                if (OMX_CORE_INPUT_PORT_INDEX == portDefn->nPortIndex)
2762                {
2763                    if ( portDefn->nBufferCountActual >
2764					OMX_CORE_NUM_INPUT_BUFFERS )
2765                    {
2766                        m_inp_act_buf_count = portDefn->nBufferCountActual;
2767                    } else
2768                    {
2769                        m_inp_act_buf_count =OMX_CORE_NUM_INPUT_BUFFERS;
2770                    }
2771                    input_buffer_size = portDefn->nBufferSize;
2772
2773                } else if (OMX_CORE_OUTPUT_PORT_INDEX == portDefn->nPortIndex)
2774                {
2775                    if ( portDefn->nBufferCountActual >
2776					OMX_CORE_NUM_OUTPUT_BUFFERS )
2777                    {
2778                        m_out_act_buf_count = portDefn->nBufferCountActual;
2779                    } else
2780                    {
2781                        m_out_act_buf_count =OMX_CORE_NUM_OUTPUT_BUFFERS;
2782                    }
2783                    output_buffer_size = portDefn->nBufferSize;
2784                } else
2785                {
2786                    DEBUG_PRINT(" set_parameter: Bad Port idx %d",\
2787                                  (int)portDefn->nPortIndex);
2788                    eRet = OMX_ErrorBadPortIndex;
2789                }
2790                break;
2791            }
2792        case OMX_IndexParamPriorityMgmt:
2793            {
2794                DEBUG_PRINT("set_parameter: OMX_IndexParamPriorityMgmt\n");
2795
2796                if (m_state != OMX_StateLoaded)
2797                {
2798                    DEBUG_PRINT_ERROR("Set Parameter called in \
2799						Invalid State\n");
2800                    return OMX_ErrorIncorrectStateOperation;
2801                }
2802                OMX_PRIORITYMGMTTYPE *priorityMgmtype
2803                = (OMX_PRIORITYMGMTTYPE*) paramData;
2804                DEBUG_PRINT("set_parameter: OMX_IndexParamPriorityMgmt %u\n",
2805                            priorityMgmtype->nGroupID);
2806
2807                DEBUG_PRINT("set_parameter: priorityMgmtype %u\n",
2808                            priorityMgmtype->nGroupPriority);
2809
2810                m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
2811                m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
2812
2813                break;
2814            }
2815        case  OMX_IndexParamAudioPortFormat:
2816            {
2817
2818                OMX_AUDIO_PARAM_PORTFORMATTYPE *portFormatType =
2819                (OMX_AUDIO_PARAM_PORTFORMATTYPE *) paramData;
2820                DEBUG_PRINT("set_parameter: OMX_IndexParamAudioPortFormat\n");
2821
2822                if (OMX_CORE_INPUT_PORT_INDEX== portFormatType->nPortIndex)
2823                {
2824                    portFormatType->eEncoding = OMX_AUDIO_CodingPCM;
2825                } else if (OMX_CORE_OUTPUT_PORT_INDEX ==
2826				portFormatType->nPortIndex)
2827                {
2828                    DEBUG_PRINT("set_parameter: OMX_IndexParamAudioFormat:"\
2829                                " %u\n", portFormatType->nIndex);
2830                    portFormatType->eEncoding = OMX_AUDIO_CodingAMR;
2831                } else
2832                {
2833                    DEBUG_PRINT_ERROR("set_parameter: Bad port index %d\n", \
2834                                      (int)portFormatType->nPortIndex);
2835                    eRet = OMX_ErrorBadPortIndex;
2836                }
2837                break;
2838            }
2839
2840
2841        case OMX_IndexParamCompBufferSupplier:
2842            {
2843                DEBUG_PRINT("set_parameter: \
2844				OMX_IndexParamCompBufferSupplier\n");
2845                OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType
2846                = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2847                DEBUG_PRINT("set_param: OMX_IndexParamCompBufferSupplier %d",\
2848                            bufferSupplierType->eBufferSupplier);
2849
2850                if (bufferSupplierType->nPortIndex == OMX_CORE_INPUT_PORT_INDEX
2851                    || bufferSupplierType->nPortIndex ==
2852				OMX_CORE_OUTPUT_PORT_INDEX)
2853                {
2854                    DEBUG_PRINT("set_parameter:\
2855					OMX_IndexParamCompBufferSupplier\n");
2856                    m_buffer_supplier.eBufferSupplier =
2857				bufferSupplierType->eBufferSupplier;
2858                } else
2859                {
2860                    DEBUG_PRINT_ERROR("set_param:\
2861					IndexParamCompBufferSup %08x\n", eRet);
2862                    eRet = OMX_ErrorBadPortIndex;
2863                }
2864
2865                break; }
2866
2867        case OMX_IndexParamAudioPcm:
2868            {
2869                DEBUG_PRINT("set_parameter: OMX_IndexParamAudioPcm\n");
2870                OMX_AUDIO_PARAM_PCMMODETYPE *pcmparam
2871                = (OMX_AUDIO_PARAM_PCMMODETYPE *) paramData;
2872
2873                if (OMX_CORE_INPUT_PORT_INDEX== pcmparam->nPortIndex)
2874                {
2875                    memcpy(&m_pcm_param,pcmparam,\
2876                        sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
2877                    DEBUG_PRINT("set_pcm_parameter: %u %u",\
2878                                 m_pcm_param.nChannels,
2879				m_pcm_param.nSamplingRate);
2880                } else
2881                {
2882                    DEBUG_PRINT_ERROR("Set_parameter:OMX_IndexParamAudioPcm "
2883                                      "OMX_ErrorBadPortIndex %d\n",
2884                                      (int)pcmparam->nPortIndex);
2885                    eRet = OMX_ErrorBadPortIndex;
2886                }
2887                break;
2888            }
2889        case OMX_IndexParamSuspensionPolicy:
2890            {
2891                eRet = OMX_ErrorNotImplemented;
2892                break;
2893            }
2894        case OMX_IndexParamStandardComponentRole:
2895            {
2896                OMX_PARAM_COMPONENTROLETYPE *componentRole;
2897                componentRole = (OMX_PARAM_COMPONENTROLETYPE*)paramData;
2898                component_Role.nSize = componentRole->nSize;
2899                component_Role.nVersion = componentRole->nVersion;
2900                strlcpy((char *)component_Role.cRole,
2901                       (const char*)componentRole->cRole,
2902			sizeof(component_Role.cRole));
2903                break;
2904            }
2905
2906        default:
2907            {
2908                DEBUG_PRINT_ERROR("unknown param %d\n", paramIndex);
2909                eRet = OMX_ErrorUnsupportedIndex;
2910            }
2911    }
2912    return eRet;
2913}
2914
2915/* ======================================================================
2916FUNCTION
2917  omx_amr_aenc::GetConfig
2918
2919DESCRIPTION
2920  OMX Get Config Method implementation.
2921
2922PARAMETERS
2923  <TBD>.
2924
2925RETURN VALUE
2926  OMX Error None if successful.
2927
2928========================================================================== */
2929OMX_ERRORTYPE  omx_amr_aenc::get_config(OMX_IN OMX_HANDLETYPE      hComp,
2930                                         OMX_IN OMX_INDEXTYPE configIndex,
2931                                         OMX_INOUT OMX_PTR     configData)
2932{
2933    OMX_ERRORTYPE eRet = OMX_ErrorNone;
2934
2935    if(hComp == NULL)
2936    {
2937        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
2938        return OMX_ErrorBadParameter;
2939    }
2940    if (m_state == OMX_StateInvalid)
2941    {
2942        DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
2943        return OMX_ErrorInvalidState;
2944    }
2945
2946    switch (configIndex)
2947    {
2948        case OMX_IndexConfigAudioVolume:
2949            {
2950                OMX_AUDIO_CONFIG_VOLUMETYPE *volume =
2951                (OMX_AUDIO_CONFIG_VOLUMETYPE*) configData;
2952
2953                if (OMX_CORE_INPUT_PORT_INDEX == volume->nPortIndex)
2954                {
2955                    volume->nSize = (OMX_U32)sizeof(volume);
2956                    volume->nVersion.nVersion = OMX_SPEC_VERSION;
2957                    volume->bLinear = OMX_TRUE;
2958                    volume->sVolume.nValue = m_volume;
2959                    volume->sVolume.nMax   = OMX_AENC_MAX;
2960                    volume->sVolume.nMin   = OMX_AENC_MIN;
2961                } else
2962                {
2963                    eRet = OMX_ErrorBadPortIndex;
2964                }
2965            }
2966            break;
2967
2968        case OMX_IndexConfigAudioMute:
2969            {
2970                OMX_AUDIO_CONFIG_MUTETYPE *mute =
2971                (OMX_AUDIO_CONFIG_MUTETYPE*) configData;
2972
2973                if (OMX_CORE_INPUT_PORT_INDEX == mute->nPortIndex)
2974                {
2975                    mute->nSize = (OMX_U32)sizeof(mute);
2976                    mute->nVersion.nVersion = OMX_SPEC_VERSION;
2977                    mute->bMute = (BITMASK_PRESENT(&m_flags,
2978                                      OMX_COMPONENT_MUTED)?OMX_TRUE:OMX_FALSE);
2979                } else
2980                {
2981                    eRet = OMX_ErrorBadPortIndex;
2982                }
2983            }
2984            break;
2985
2986        default:
2987            eRet = OMX_ErrorUnsupportedIndex;
2988            break;
2989    }
2990    return eRet;
2991}
2992
2993/* ======================================================================
2994FUNCTION
2995  omx_amr_aenc::SetConfig
2996
2997DESCRIPTION
2998  OMX Set Config method implementation
2999
3000PARAMETERS
3001  <TBD>.
3002
3003RETURN VALUE
3004  OMX Error None if successful.
3005========================================================================== */
3006OMX_ERRORTYPE  omx_amr_aenc::set_config(OMX_IN OMX_HANDLETYPE      hComp,
3007                                         OMX_IN OMX_INDEXTYPE configIndex,
3008                                         OMX_IN OMX_PTR        configData)
3009{
3010    OMX_ERRORTYPE eRet = OMX_ErrorNone;
3011
3012    if(hComp == NULL)
3013    {
3014        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
3015        return OMX_ErrorBadParameter;
3016    }
3017    if (m_state == OMX_StateInvalid)
3018    {
3019        DEBUG_PRINT_ERROR("Set Config in Invalid State\n");
3020        return OMX_ErrorInvalidState;
3021    }
3022    if ( m_state == OMX_StateExecuting)
3023    {
3024        DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
3025        return OMX_ErrorInvalidState;
3026    }
3027
3028    switch (configIndex)
3029    {
3030        case OMX_IndexConfigAudioVolume:
3031            {
3032                OMX_AUDIO_CONFIG_VOLUMETYPE *vol =
3033			(OMX_AUDIO_CONFIG_VOLUMETYPE*)configData;
3034                if (vol->nPortIndex == OMX_CORE_INPUT_PORT_INDEX)
3035                {
3036                    if ((vol->sVolume.nValue <= OMX_AENC_MAX) &&
3037                        (vol->sVolume.nValue >= OMX_AENC_MIN))
3038                    {
3039                        m_volume = vol->sVolume.nValue;
3040                        if (BITMASK_ABSENT(&m_flags, OMX_COMPONENT_MUTED))
3041                        {
3042                            /* ioctl(m_drv_fd, AUDIO_VOLUME,
3043                            m_volume * OMX_AENC_VOLUME_STEP); */
3044                        }
3045
3046                    } else
3047                    {
3048                        eRet = OMX_ErrorBadParameter;
3049                    }
3050                } else
3051                {
3052                    eRet = OMX_ErrorBadPortIndex;
3053                }
3054            }
3055            break;
3056
3057        case OMX_IndexConfigAudioMute:
3058            {
3059                OMX_AUDIO_CONFIG_MUTETYPE *mute = (OMX_AUDIO_CONFIG_MUTETYPE*)
3060                                                  configData;
3061                if (mute->nPortIndex == OMX_CORE_INPUT_PORT_INDEX)
3062                {
3063                    if (mute->bMute == OMX_TRUE)
3064                    {
3065                        BITMASK_SET(&m_flags, OMX_COMPONENT_MUTED);
3066                        /* ioctl(m_drv_fd, AUDIO_VOLUME, 0); */
3067                    } else
3068                    {
3069                        BITMASK_CLEAR(&m_flags, OMX_COMPONENT_MUTED);
3070                        /* ioctl(m_drv_fd, AUDIO_VOLUME,
3071                        m_volume * OMX_AENC_VOLUME_STEP); */
3072                    }
3073                } else
3074                {
3075                    eRet = OMX_ErrorBadPortIndex;
3076                }
3077            }
3078            break;
3079
3080        default:
3081            eRet = OMX_ErrorUnsupportedIndex;
3082            break;
3083    }
3084    return eRet;
3085}
3086
3087/* ======================================================================
3088FUNCTION
3089  omx_amr_aenc::GetExtensionIndex
3090
3091DESCRIPTION
3092  OMX GetExtensionIndex method implementaion.  <TBD>
3093
3094PARAMETERS
3095  <TBD>.
3096
3097RETURN VALUE
3098  OMX Error None if everything successful.
3099
3100========================================================================== */
3101OMX_ERRORTYPE  omx_amr_aenc::get_extension_index(
3102				OMX_IN OMX_HANDLETYPE      hComp,
3103				OMX_IN OMX_STRING      paramName,
3104				OMX_OUT OMX_INDEXTYPE* indexType)
3105{
3106    if((hComp == NULL) || (paramName == NULL) || (indexType == NULL))
3107    {
3108        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
3109        return OMX_ErrorBadParameter;
3110    }
3111    if (m_state == OMX_StateInvalid)
3112    {
3113        DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3114        return OMX_ErrorInvalidState;
3115    }
3116  if(strncmp(paramName,"OMX.Qualcomm.index.audio.sessionId",
3117		strlen("OMX.Qualcomm.index.audio.sessionId")) == 0)
3118  {
3119      *indexType =(OMX_INDEXTYPE)QOMX_IndexParamAudioSessionId;
3120      DEBUG_PRINT("Extension index type - %d\n", *indexType);
3121
3122  }
3123  else
3124  {
3125      return OMX_ErrorBadParameter;
3126
3127  }
3128  return OMX_ErrorNone;
3129}
3130
3131/* ======================================================================
3132FUNCTION
3133  omx_amr_aenc::GetState
3134
3135DESCRIPTION
3136  Returns the state information back to the caller.<TBD>
3137
3138PARAMETERS
3139  <TBD>.
3140
3141RETURN VALUE
3142  Error None if everything is successful.
3143========================================================================== */
3144OMX_ERRORTYPE  omx_amr_aenc::get_state(OMX_IN OMX_HANDLETYPE  hComp,
3145                                        OMX_OUT OMX_STATETYPE* state)
3146{
3147    if(hComp == NULL)
3148    {
3149        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
3150        return OMX_ErrorBadParameter;
3151    }
3152    *state = m_state;
3153    DEBUG_PRINT("Returning the state %d\n",*state);
3154    return OMX_ErrorNone;
3155}
3156
3157/* ======================================================================
3158FUNCTION
3159  omx_amr_aenc::ComponentTunnelRequest
3160
3161DESCRIPTION
3162  OMX Component Tunnel Request method implementation. <TBD>
3163
3164PARAMETERS
3165  None.
3166
3167RETURN VALUE
3168  OMX Error None if everything successful.
3169
3170========================================================================== */
3171OMX_ERRORTYPE  omx_amr_aenc::component_tunnel_request
3172(
3173    OMX_IN OMX_HANDLETYPE                hComp,
3174    OMX_IN OMX_U32                        port,
3175    OMX_IN OMX_HANDLETYPE        peerComponent,
3176    OMX_IN OMX_U32                    peerPort,
3177    OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
3178{
3179    DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3180
3181    if((hComp == NULL) || (peerComponent == NULL) || (tunnelSetup == NULL))
3182    {
3183        port = port;
3184        peerPort = peerPort;
3185        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
3186        return OMX_ErrorBadParameter;
3187    }
3188    return OMX_ErrorNotImplemented;
3189}
3190
3191/* ======================================================================
3192FUNCTION
3193  omx_amr_aenc::AllocateInputBuffer
3194
3195DESCRIPTION
3196  Helper function for allocate buffer in the input pin
3197
3198PARAMETERS
3199  None.
3200
3201RETURN VALUE
3202  true/false
3203
3204========================================================================== */
3205OMX_ERRORTYPE  omx_amr_aenc::allocate_input_buffer
3206(
3207    OMX_IN OMX_HANDLETYPE                hComp,
3208    OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3209    OMX_IN OMX_U32                        port,
3210    OMX_IN OMX_PTR                     appData,
3211    OMX_IN OMX_U32                       bytes)
3212{
3213    OMX_ERRORTYPE         eRet = OMX_ErrorNone;
3214    OMX_BUFFERHEADERTYPE  *bufHdr;
3215    unsigned              nBufSize = MAX(bytes, input_buffer_size);
3216    char                  *buf_ptr;
3217  if(m_inp_current_buf_count < m_inp_act_buf_count)
3218  {
3219    buf_ptr = (char *) calloc((nBufSize + \
3220		sizeof(OMX_BUFFERHEADERTYPE)+sizeof(META_IN)) , 1);
3221
3222    if(hComp == NULL)
3223    {
3224        port = port;
3225        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
3226        free(buf_ptr);
3227        return OMX_ErrorBadParameter;
3228    }
3229    if (buf_ptr != NULL)
3230    {
3231        bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr;
3232        *bufferHdr = bufHdr;
3233        memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE));
3234
3235        bufHdr->pBuffer           = (OMX_U8 *)((buf_ptr) + sizeof(META_IN)+
3236                                               sizeof(OMX_BUFFERHEADERTYPE));
3237        bufHdr->nSize             = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE);
3238        bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
3239        bufHdr->nAllocLen         = nBufSize;
3240        bufHdr->pAppPrivate       = appData;
3241        bufHdr->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
3242        m_input_buf_hdrs.insert(bufHdr, NULL);
3243
3244        m_inp_current_buf_count++;
3245        DEBUG_PRINT("AIB:bufHdr %p bufHdr->pBuffer %p m_inp_buf_cnt=%d \
3246		bytes=%u", bufHdr, bufHdr->pBuffer,m_inp_current_buf_count,
3247                    bytes);
3248
3249    } else
3250    {
3251        DEBUG_PRINT("Input buffer memory allocation failed 1 \n");
3252        eRet =  OMX_ErrorInsufficientResources;
3253    }
3254  }
3255  else
3256  {
3257     DEBUG_PRINT("Input buffer memory allocation failed 2\n");
3258    eRet =  OMX_ErrorInsufficientResources;
3259  }
3260    return eRet;
3261}
3262
3263OMX_ERRORTYPE  omx_amr_aenc::allocate_output_buffer
3264(
3265    OMX_IN OMX_HANDLETYPE                hComp,
3266    OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3267    OMX_IN OMX_U32                        port,
3268    OMX_IN OMX_PTR                     appData,
3269    OMX_IN OMX_U32                       bytes)
3270{
3271    OMX_ERRORTYPE         eRet = OMX_ErrorNone;
3272    OMX_BUFFERHEADERTYPE  *bufHdr;
3273    unsigned                   nBufSize = MAX(bytes,output_buffer_size);
3274    char                  *buf_ptr;
3275
3276    if(hComp == NULL)
3277    {
3278        port = port;
3279        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
3280        return OMX_ErrorBadParameter;
3281    }
3282    if (m_out_current_buf_count < m_out_act_buf_count)
3283    {
3284        buf_ptr = (char *) calloc( (nBufSize + sizeof(OMX_BUFFERHEADERTYPE)),1);
3285
3286        if (buf_ptr != NULL)
3287        {
3288            bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr;
3289            *bufferHdr = bufHdr;
3290            memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE));
3291
3292            bufHdr->pBuffer           = (OMX_U8 *)((buf_ptr) +
3293					sizeof(OMX_BUFFERHEADERTYPE));
3294            bufHdr->nSize             = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE);
3295            bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
3296            bufHdr->nAllocLen         = nBufSize;
3297            bufHdr->pAppPrivate       = appData;
3298            bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
3299            m_output_buf_hdrs.insert(bufHdr, NULL);
3300            m_out_current_buf_count++;
3301            DEBUG_PRINT("AOB::bufHdr %p bufHdr->pBuffer %p m_out_buf_cnt=%d"\
3302                        "bytes=%u",bufHdr, bufHdr->pBuffer,\
3303                        m_out_current_buf_count, bytes);
3304        } else
3305        {
3306            DEBUG_PRINT("Output buffer memory allocation failed 1 \n");
3307            eRet =  OMX_ErrorInsufficientResources;
3308        }
3309    } else
3310    {
3311        DEBUG_PRINT("Output buffer memory allocation failed\n");
3312        eRet =  OMX_ErrorInsufficientResources;
3313    }
3314    return eRet;
3315}
3316
3317
3318// AllocateBuffer  -- API Call
3319/* ======================================================================
3320FUNCTION
3321  omx_amr_aenc::AllocateBuffer
3322
3323DESCRIPTION
3324  Returns zero if all the buffers released..
3325
3326PARAMETERS
3327  None.
3328
3329RETURN VALUE
3330  true/false
3331
3332========================================================================== */
3333OMX_ERRORTYPE  omx_amr_aenc::allocate_buffer
3334(
3335    OMX_IN OMX_HANDLETYPE                hComp,
3336    OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3337    OMX_IN OMX_U32                        port,
3338    OMX_IN OMX_PTR                     appData,
3339    OMX_IN OMX_U32                       bytes)
3340{
3341
3342    OMX_ERRORTYPE eRet = OMX_ErrorNone;          // OMX return type
3343
3344    if (m_state == OMX_StateInvalid)
3345    {
3346        DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
3347        return OMX_ErrorInvalidState;
3348    }
3349    // What if the client calls again.
3350    if (OMX_CORE_INPUT_PORT_INDEX == port)
3351    {
3352        eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
3353    } else if (OMX_CORE_OUTPUT_PORT_INDEX == port)
3354    {
3355        eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
3356    } else
3357    {
3358        DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",
3359                          (int)port);
3360        eRet = OMX_ErrorBadPortIndex;
3361    }
3362
3363    if (eRet == OMX_ErrorNone)
3364    {
3365        DEBUG_PRINT("allocate_buffer:  before allocate_done \n");
3366        if (allocate_done())
3367        {
3368            DEBUG_PRINT("allocate_buffer:  after allocate_done \n");
3369            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3370            {
3371                BITMASK_CLEAR(&m_flags, OMX_COMPONENT_IDLE_PENDING);
3372                post_command(OMX_CommandStateSet,OMX_StateIdle,
3373                             OMX_COMPONENT_GENERATE_EVENT);
3374                DEBUG_PRINT("allocate_buffer:  post idle transition event \n");
3375            }
3376            DEBUG_PRINT("allocate_buffer:  complete \n");
3377        }
3378        if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
3379        {
3380            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
3381            {
3382                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
3383                post_command(OMX_CommandPortEnable, OMX_CORE_INPUT_PORT_INDEX,
3384                             OMX_COMPONENT_GENERATE_EVENT);
3385            }
3386        }
3387        if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
3388        {
3389            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
3390            {
3391                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
3392                m_out_bEnabled = OMX_TRUE;
3393
3394                DEBUG_PRINT("AllocBuf-->is_out_th_sleep=%d\n",is_out_th_sleep);
3395                pthread_mutex_lock(&m_out_th_lock_1);
3396                if (is_out_th_sleep)
3397                {
3398                    is_out_th_sleep = false;
3399                    DEBUG_DETAIL("AllocBuf:WAKING UP OUT THREADS\n");
3400                    out_th_wakeup();
3401                }
3402                pthread_mutex_unlock(&m_out_th_lock_1);
3403                pthread_mutex_lock(&m_in_th_lock_1);
3404                if(is_in_th_sleep)
3405                {
3406                   is_in_th_sleep = false;
3407                   DEBUG_DETAIL("AB:WAKING UP IN THREADS\n");
3408                   in_th_wakeup();
3409                }
3410                pthread_mutex_unlock(&m_in_th_lock_1);
3411                post_command(OMX_CommandPortEnable, OMX_CORE_OUTPUT_PORT_INDEX,
3412                             OMX_COMPONENT_GENERATE_EVENT);
3413            }
3414        }
3415    }
3416    DEBUG_PRINT("Allocate Buffer exit with ret Code %d\n", eRet);
3417    return eRet;
3418}
3419
3420/*=============================================================================
3421FUNCTION:
3422  use_buffer
3423
3424DESCRIPTION:
3425  OMX Use Buffer method implementation.
3426
3427INPUT/OUTPUT PARAMETERS:
3428  [INOUT] bufferHdr
3429  [IN] hComp
3430  [IN] port
3431  [IN] appData
3432  [IN] bytes
3433  [IN] buffer
3434
3435RETURN VALUE:
3436  OMX_ERRORTYPE
3437
3438Dependency:
3439  None
3440
3441SIDE EFFECTS:
3442  None
3443=============================================================================*/
3444OMX_ERRORTYPE  omx_amr_aenc::use_buffer
3445(
3446    OMX_IN OMX_HANDLETYPE            hComp,
3447    OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3448    OMX_IN OMX_U32                   port,
3449    OMX_IN OMX_PTR                   appData,
3450    OMX_IN OMX_U32                   bytes,
3451    OMX_IN OMX_U8*                   buffer)
3452{
3453    OMX_ERRORTYPE eRet = OMX_ErrorNone;
3454
3455    if (OMX_CORE_INPUT_PORT_INDEX == port)
3456    {
3457        eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
3458
3459    } else if (OMX_CORE_OUTPUT_PORT_INDEX == port)
3460    {
3461        eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
3462    } else
3463    {
3464        DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
3465        eRet = OMX_ErrorBadPortIndex;
3466    }
3467
3468    if (eRet == OMX_ErrorNone)
3469    {
3470        DEBUG_PRINT("Checking for Output Allocate buffer Done");
3471        if (allocate_done())
3472        {
3473            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3474            {
3475                BITMASK_CLEAR(&m_flags, OMX_COMPONENT_IDLE_PENDING);
3476                post_command(OMX_CommandStateSet,OMX_StateIdle,
3477                             OMX_COMPONENT_GENERATE_EVENT);
3478            }
3479        }
3480        if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
3481        {
3482            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
3483            {
3484                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
3485                post_command(OMX_CommandPortEnable, OMX_CORE_INPUT_PORT_INDEX,
3486                             OMX_COMPONENT_GENERATE_EVENT);
3487
3488            }
3489        }
3490        if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
3491        {
3492            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
3493            {
3494                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
3495                post_command(OMX_CommandPortEnable, OMX_CORE_OUTPUT_PORT_INDEX,
3496                             OMX_COMPONENT_GENERATE_EVENT);
3497                pthread_mutex_lock(&m_out_th_lock_1);
3498                if (is_out_th_sleep)
3499                {
3500                    is_out_th_sleep = false;
3501                    DEBUG_DETAIL("UseBuf:WAKING UP OUT THREADS\n");
3502                    out_th_wakeup();
3503                }
3504                pthread_mutex_unlock(&m_out_th_lock_1);
3505                pthread_mutex_lock(&m_in_th_lock_1);
3506                if(is_in_th_sleep)
3507                {
3508                   is_in_th_sleep = false;
3509                   DEBUG_DETAIL("UB:WAKING UP IN THREADS\n");
3510                   in_th_wakeup();
3511                }
3512                pthread_mutex_unlock(&m_in_th_lock_1);
3513        }
3514    }
3515  }
3516    DEBUG_PRINT("Use Buffer for port[%u] eRet[%d]\n", port,eRet);
3517    return eRet;
3518}
3519/*=============================================================================
3520FUNCTION:
3521  use_input_buffer
3522
3523DESCRIPTION:
3524  Helper function for Use buffer in the input pin
3525
3526INPUT/OUTPUT PARAMETERS:
3527  [INOUT] bufferHdr
3528  [IN] hComp
3529  [IN] port
3530  [IN] appData
3531  [IN] bytes
3532  [IN] buffer
3533
3534RETURN VALUE:
3535  OMX_ERRORTYPE
3536
3537Dependency:
3538  None
3539
3540SIDE EFFECTS:
3541  None
3542=============================================================================*/
3543OMX_ERRORTYPE  omx_amr_aenc::use_input_buffer
3544(
3545    OMX_IN OMX_HANDLETYPE            hComp,
3546    OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3547    OMX_IN OMX_U32                   port,
3548    OMX_IN OMX_PTR                   appData,
3549    OMX_IN OMX_U32                   bytes,
3550    OMX_IN OMX_U8*                   buffer)
3551{
3552    OMX_ERRORTYPE         eRet = OMX_ErrorNone;
3553    OMX_BUFFERHEADERTYPE  *bufHdr;
3554    unsigned              nBufSize = MAX(bytes, input_buffer_size);
3555    char                  *buf_ptr;
3556
3557    if(hComp == NULL)
3558    {
3559        port = port;
3560        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
3561        return OMX_ErrorBadParameter;
3562    }
3563    if(bytes < input_buffer_size)
3564    {
3565      /* return if i\p buffer size provided by client
3566       is less than min i\p buffer size supported by omx component*/
3567      return OMX_ErrorInsufficientResources;
3568    }
3569    if (m_inp_current_buf_count < m_inp_act_buf_count)
3570    {
3571        buf_ptr = (char *) calloc(sizeof(OMX_BUFFERHEADERTYPE), 1);
3572
3573        if (buf_ptr != NULL)
3574        {
3575            bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr;
3576            *bufferHdr = bufHdr;
3577            memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE));
3578
3579            bufHdr->pBuffer           = (OMX_U8 *)(buffer);
3580            DEBUG_PRINT("use_input_buffer:bufHdr %p bufHdr->pBuffer %p \
3581			bytes=%u", bufHdr, bufHdr->pBuffer,bytes);
3582            bufHdr->nSize             = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE);
3583            bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
3584            bufHdr->nAllocLen         = nBufSize;
3585            input_buffer_size         = nBufSize;
3586            bufHdr->pAppPrivate       = appData;
3587            bufHdr->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
3588            bufHdr->nOffset           = 0;
3589            m_input_buf_hdrs.insert(bufHdr, NULL);
3590            m_inp_current_buf_count++;
3591        } else
3592        {
3593            DEBUG_PRINT("Input buffer memory allocation failed 1 \n");
3594            eRet =  OMX_ErrorInsufficientResources;
3595        }
3596    } else
3597    {
3598        DEBUG_PRINT("Input buffer memory allocation failed\n");
3599        eRet =  OMX_ErrorInsufficientResources;
3600    }
3601    return eRet;
3602}
3603
3604/*=============================================================================
3605FUNCTION:
3606  use_output_buffer
3607
3608DESCRIPTION:
3609  Helper function for Use buffer in the output pin
3610
3611INPUT/OUTPUT PARAMETERS:
3612  [INOUT] bufferHdr
3613  [IN] hComp
3614  [IN] port
3615  [IN] appData
3616  [IN] bytes
3617  [IN] buffer
3618
3619RETURN VALUE:
3620  OMX_ERRORTYPE
3621
3622Dependency:
3623  None
3624
3625SIDE EFFECTS:
3626  None
3627=============================================================================*/
3628OMX_ERRORTYPE  omx_amr_aenc::use_output_buffer
3629(
3630    OMX_IN OMX_HANDLETYPE            hComp,
3631    OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3632    OMX_IN OMX_U32                   port,
3633    OMX_IN OMX_PTR                   appData,
3634    OMX_IN OMX_U32                   bytes,
3635    OMX_IN OMX_U8*                   buffer)
3636{
3637    OMX_ERRORTYPE         eRet = OMX_ErrorNone;
3638    OMX_BUFFERHEADERTYPE  *bufHdr;
3639    unsigned              nBufSize = MAX(bytes,output_buffer_size);
3640    char                  *buf_ptr;
3641
3642    if(hComp == NULL)
3643    {
3644        port = port;
3645        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
3646        return OMX_ErrorBadParameter;
3647    }
3648    if (bytes < output_buffer_size)
3649    {
3650        /* return if o\p buffer size provided by client
3651        is less than min o\p buffer size supported by omx component*/
3652        return OMX_ErrorInsufficientResources;
3653    }
3654
3655    DEBUG_PRINT("Inside omx_amr_aenc::use_output_buffer");
3656    if (m_out_current_buf_count < m_out_act_buf_count)
3657    {
3658
3659        buf_ptr = (char *) calloc(sizeof(OMX_BUFFERHEADERTYPE), 1);
3660
3661        if (buf_ptr != NULL)
3662        {
3663            bufHdr = (OMX_BUFFERHEADERTYPE *) buf_ptr;
3664            DEBUG_PRINT("BufHdr=%p buffer=%p\n",bufHdr,buffer);
3665            *bufferHdr = bufHdr;
3666            memset(bufHdr,0,sizeof(OMX_BUFFERHEADERTYPE));
3667
3668            bufHdr->pBuffer           = (OMX_U8 *)(buffer);
3669            DEBUG_PRINT("use_output_buffer:bufHdr %p bufHdr->pBuffer %p \
3670			len=%u", bufHdr, bufHdr->pBuffer,bytes);
3671            bufHdr->nSize             = (OMX_U32)sizeof(OMX_BUFFERHEADERTYPE);
3672            bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
3673            bufHdr->nAllocLen         = nBufSize;
3674            output_buffer_size        = nBufSize;
3675            bufHdr->pAppPrivate       = appData;
3676            bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
3677            bufHdr->nOffset           = 0;
3678            m_output_buf_hdrs.insert(bufHdr, NULL);
3679            m_out_current_buf_count++;
3680
3681        } else
3682        {
3683            DEBUG_PRINT("Output buffer memory allocation failed\n");
3684            eRet =  OMX_ErrorInsufficientResources;
3685        }
3686    } else
3687    {
3688        DEBUG_PRINT("Output buffer memory allocation failed 2\n");
3689        eRet =  OMX_ErrorInsufficientResources;
3690    }
3691    return eRet;
3692}
3693/**
3694 @brief member function that searches for caller buffer
3695
3696 @param buffer pointer to buffer header
3697 @return bool value indicating whether buffer is found
3698 */
3699bool omx_amr_aenc::search_input_bufhdr(OMX_BUFFERHEADERTYPE *buffer)
3700{
3701
3702    bool eRet = false;
3703    OMX_BUFFERHEADERTYPE *temp = NULL;
3704
3705    //access only in IL client context
3706    temp = m_input_buf_hdrs.find_ele(buffer);
3707    if (buffer && temp)
3708    {
3709        DEBUG_DETAIL("search_input_bufhdr %p \n", buffer);
3710        eRet = true;
3711    }
3712    return eRet;
3713}
3714
3715/**
3716 @brief member function that searches for caller buffer
3717
3718 @param buffer pointer to buffer header
3719 @return bool value indicating whether buffer is found
3720 */
3721bool omx_amr_aenc::search_output_bufhdr(OMX_BUFFERHEADERTYPE *buffer)
3722{
3723
3724    bool eRet = false;
3725    OMX_BUFFERHEADERTYPE *temp = NULL;
3726
3727    //access only in IL client context
3728    temp = m_output_buf_hdrs.find_ele(buffer);
3729    if (buffer && temp)
3730    {
3731        DEBUG_DETAIL("search_output_bufhdr %p \n", buffer);
3732        eRet = true;
3733    }
3734    return eRet;
3735}
3736
3737// Free Buffer - API call
3738/**
3739  @brief member function that handles free buffer command from IL client
3740
3741  This function is a block-call function that handles IL client request to
3742  freeing the buffer
3743
3744  @param hComp handle to component instance
3745  @param port id of port which holds the buffer
3746  @param buffer buffer header
3747  @return Error status
3748*/
3749OMX_ERRORTYPE  omx_amr_aenc::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
3750                                          OMX_IN OMX_U32                 port,
3751                                          OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3752{
3753    OMX_ERRORTYPE eRet = OMX_ErrorNone;
3754
3755    DEBUG_PRINT("Free_Buffer buf %p\n", buffer);
3756    if(hComp == NULL)
3757    {
3758        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
3759        return OMX_ErrorBadParameter;
3760    }
3761    if (m_state == OMX_StateIdle &&
3762        (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
3763    {
3764        DEBUG_PRINT(" free buffer while Component in Loading pending\n");
3765    } else if ((m_inp_bEnabled == OMX_FALSE &&
3766		port == OMX_CORE_INPUT_PORT_INDEX)||
3767               (m_out_bEnabled == OMX_FALSE &&
3768		port == OMX_CORE_OUTPUT_PORT_INDEX))
3769    {
3770        DEBUG_PRINT("Free Buffer while port %u disabled\n", port);
3771    } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause)
3772    {
3773        DEBUG_PRINT("Invalid state to free buffer,ports need to be disabled:\
3774                    OMX_ErrorPortUnpopulated\n");
3775        post_command(OMX_EventError,
3776                     OMX_ErrorPortUnpopulated,
3777                     OMX_COMPONENT_GENERATE_EVENT);
3778
3779        return eRet;
3780    } else
3781    {
3782        DEBUG_PRINT("free_buffer: Invalid state to free buffer,ports need to be\
3783                    disabled:OMX_ErrorPortUnpopulated\n");
3784        post_command(OMX_EventError,
3785                     OMX_ErrorPortUnpopulated,
3786                     OMX_COMPONENT_GENERATE_EVENT);
3787    }
3788    if (OMX_CORE_INPUT_PORT_INDEX == port)
3789    {
3790        if (m_inp_current_buf_count != 0)
3791        {
3792            m_inp_bPopulated = OMX_FALSE;
3793            if (true == search_input_bufhdr(buffer))
3794            {
3795                /* Buffer exist */
3796                //access only in IL client context
3797                DEBUG_PRINT("Free_Buf:in_buffer[%p]\n",buffer);
3798                m_input_buf_hdrs.erase(buffer);
3799                free(buffer);
3800                m_inp_current_buf_count--;
3801            } else
3802            {
3803                DEBUG_PRINT_ERROR("Free_Buf:Error-->free_buffer, \
3804                                  Invalid Input buffer header\n");
3805                eRet = OMX_ErrorBadParameter;
3806            }
3807        } else
3808        {
3809            DEBUG_PRINT_ERROR("Error: free_buffer,Port Index calculation \
3810                              came out Invalid\n");
3811            eRet = OMX_ErrorBadPortIndex;
3812        }
3813        if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
3814            && release_done(0))
3815        {
3816            DEBUG_PRINT("INPUT PORT MOVING TO DISABLED STATE \n");
3817            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
3818            post_command(OMX_CommandPortDisable,
3819                         OMX_CORE_INPUT_PORT_INDEX,
3820                         OMX_COMPONENT_GENERATE_EVENT);
3821        }
3822    } else if (OMX_CORE_OUTPUT_PORT_INDEX == port)
3823    {
3824        if (m_out_current_buf_count != 0)
3825        {
3826            m_out_bPopulated = OMX_FALSE;
3827            if (true == search_output_bufhdr(buffer))
3828            {
3829                /* Buffer exist */
3830                //access only in IL client context
3831                DEBUG_PRINT("Free_Buf:out_buffer[%p]\n",buffer);
3832                m_output_buf_hdrs.erase(buffer);
3833                free(buffer);
3834                m_out_current_buf_count--;
3835            } else
3836            {
3837                DEBUG_PRINT("Free_Buf:Error-->free_buffer , \
3838                            Invalid Output buffer header\n");
3839                eRet = OMX_ErrorBadParameter;
3840            }
3841        } else
3842        {
3843            eRet = OMX_ErrorBadPortIndex;
3844        }
3845
3846        if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
3847            && release_done(1))
3848        {
3849            DEBUG_PRINT("OUTPUT PORT MOVING TO DISABLED STATE \n");
3850            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
3851            post_command(OMX_CommandPortDisable,
3852                         OMX_CORE_OUTPUT_PORT_INDEX,
3853                         OMX_COMPONENT_GENERATE_EVENT);
3854
3855        }
3856    } else
3857    {
3858        eRet = OMX_ErrorBadPortIndex;
3859    }
3860    if ((OMX_ErrorNone == eRet) &&
3861        (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
3862    {
3863        if (release_done(-1))
3864        {
3865            if(ioctl(m_drv_fd, AUDIO_STOP, 0) < 0)
3866               DEBUG_PRINT_ERROR("AUDIO STOP in free buffer failed\n");
3867            else
3868               DEBUG_PRINT("AUDIO STOP in free buffer passed\n");
3869
3870
3871            DEBUG_PRINT("Free_Buf: Free buffer\n");
3872
3873
3874            // Send the callback now
3875            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
3876            DEBUG_PRINT("Before OMX_StateLoaded \
3877				OMX_COMPONENT_GENERATE_EVENT\n");
3878            post_command(OMX_CommandStateSet,
3879                         OMX_StateLoaded,OMX_COMPONENT_GENERATE_EVENT);
3880            DEBUG_PRINT("After OMX_StateLoaded OMX_COMPONENT_GENERATE_EVENT\n");
3881
3882        }
3883    }
3884    return eRet;
3885}
3886
3887
3888/**
3889 @brief member function that that handles empty this buffer command
3890
3891 This function meremly queue up the command and data would be consumed
3892 in command server thread context
3893
3894 @param hComp handle to component instance
3895 @param buffer pointer to buffer header
3896 @return error status
3897 */
3898OMX_ERRORTYPE  omx_amr_aenc::empty_this_buffer(
3899				OMX_IN OMX_HANDLETYPE         hComp,
3900				OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3901{
3902    OMX_ERRORTYPE eRet = OMX_ErrorNone;
3903
3904    DEBUG_PRINT("ETB:Buf:%p Len %u TS %lld numInBuf=%d\n", \
3905                buffer, buffer->nFilledLen, buffer->nTimeStamp, (nNumInputBuf));
3906    if (m_state == OMX_StateInvalid)
3907    {
3908        DEBUG_PRINT("Empty this buffer in Invalid State\n");
3909        return OMX_ErrorInvalidState;
3910    }
3911    if (!m_inp_bEnabled)
3912    {
3913        DEBUG_PRINT("empty_this_buffer OMX_ErrorIncorrectStateOperation "\
3914                    "Port Status %d \n", m_inp_bEnabled);
3915        return OMX_ErrorIncorrectStateOperation;
3916    }
3917    if (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))
3918    {
3919        DEBUG_PRINT("omx_amr_aenc::etb--> Buffer Size Invalid\n");
3920        return OMX_ErrorBadParameter;
3921    }
3922    if (buffer->nVersion.nVersion != OMX_SPEC_VERSION)
3923    {
3924        DEBUG_PRINT("omx_amr_aenc::etb--> OMX Version Invalid\n");
3925        return OMX_ErrorVersionMismatch;
3926    }
3927
3928    if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
3929    {
3930        return OMX_ErrorBadPortIndex;
3931    }
3932    if ((m_state != OMX_StateExecuting) &&
3933        (m_state != OMX_StatePause))
3934    {
3935        DEBUG_PRINT_ERROR("Invalid state\n");
3936        eRet = OMX_ErrorInvalidState;
3937    }
3938    if (OMX_ErrorNone == eRet)
3939    {
3940        if (search_input_bufhdr(buffer) == true)
3941        {
3942            post_input((unsigned long)hComp,
3943                       (unsigned long) buffer,OMX_COMPONENT_GENERATE_ETB);
3944        } else
3945        {
3946            DEBUG_PRINT_ERROR("Bad header %p \n", buffer);
3947            eRet = OMX_ErrorBadParameter;
3948        }
3949    }
3950    pthread_mutex_lock(&in_buf_count_lock);
3951    nNumInputBuf++;
3952    m_amr_pb_stats.etb_cnt++;
3953    pthread_mutex_unlock(&in_buf_count_lock);
3954    return eRet;
3955}
3956/**
3957  @brief member function that writes data to kernel driver
3958
3959  @param hComp handle to component instance
3960  @param buffer pointer to buffer header
3961  @return error status
3962 */
3963OMX_ERRORTYPE  omx_amr_aenc::empty_this_buffer_proxy
3964(
3965    OMX_IN OMX_HANDLETYPE         hComp,
3966    OMX_BUFFERHEADERTYPE* buffer)
3967{
3968    OMX_STATETYPE state;
3969    META_IN meta_in;
3970    //Pointer to the starting location of the data to be transcoded
3971    OMX_U8 *srcStart;
3972    //The total length of the data to be transcoded
3973    srcStart = buffer->pBuffer;
3974    OMX_U8 *data = NULL;
3975    PrintFrameHdr(OMX_COMPONENT_GENERATE_ETB,buffer);
3976    memset(&meta_in,0,sizeof(meta_in));
3977    if ( search_input_bufhdr(buffer) == false )
3978    {
3979        DEBUG_PRINT("ETBP: INVALID BUF HDR\n");
3980        buffer_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
3981        return OMX_ErrorBadParameter;
3982    }
3983    if (m_tmp_meta_buf)
3984    {
3985        data = m_tmp_meta_buf;
3986
3987        // copy the metadata info from the BufHdr and insert to payload
3988        meta_in.offsetVal  = (OMX_U16)sizeof(META_IN);
3989        meta_in.nTimeStamp.LowPart =
3990          (unsigned int)((((OMX_BUFFERHEADERTYPE*)buffer)->nTimeStamp)& 0xFFFFFFFF);
3991        meta_in.nTimeStamp.HighPart =
3992          (unsigned int) (((((OMX_BUFFERHEADERTYPE*)buffer)->nTimeStamp) >> 32) & 0xFFFFFFFF);
3993        meta_in.nFlags &= ~OMX_BUFFERFLAG_EOS;
3994        if(buffer->nFlags & OMX_BUFFERFLAG_EOS)
3995        {
3996            DEBUG_PRINT("EOS OCCURED \n");
3997            meta_in.nFlags  |= OMX_BUFFERFLAG_EOS;
3998        }
3999        memcpy(data,&meta_in, meta_in.offsetVal);
4000        DEBUG_PRINT("meta_in.nFlags = %d\n",meta_in.nFlags);
4001    }
4002
4003    memcpy(&data[sizeof(META_IN)],buffer->pBuffer,buffer->nFilledLen);
4004    write(m_drv_fd, data, buffer->nFilledLen+sizeof(META_IN));
4005
4006    pthread_mutex_lock(&m_state_lock);
4007    get_state(&m_cmp, &state);
4008    pthread_mutex_unlock(&m_state_lock);
4009
4010    if (OMX_StateExecuting == state)
4011    {
4012        DEBUG_DETAIL("In Exe state, EBD CB");
4013        buffer_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
4014    } else
4015    {
4016        /* Assume empty this buffer function has already checked
4017        validity of buffer */
4018        DEBUG_PRINT("Empty buffer %p to kernel driver\n", buffer);
4019        post_input((unsigned long) & hComp,(unsigned long) buffer,
4020                   OMX_COMPONENT_GENERATE_BUFFER_DONE);
4021    }
4022    return OMX_ErrorNone;
4023}
4024
4025OMX_ERRORTYPE  omx_amr_aenc::fill_this_buffer_proxy
4026(
4027    OMX_IN OMX_HANDLETYPE         hComp,
4028    OMX_BUFFERHEADERTYPE* buffer)
4029{
4030    OMX_STATETYPE state;
4031    ENC_META_OUT *meta_out = NULL;
4032    ssize_t nReadbytes = 0;
4033
4034    pthread_mutex_lock(&m_state_lock);
4035    get_state(&m_cmp, &state);
4036    pthread_mutex_unlock(&m_state_lock);
4037
4038    if (true == search_output_bufhdr(buffer))
4039    {
4040          DEBUG_PRINT("\nBefore Read..m_drv_fd = %d,\n",m_drv_fd);
4041          nReadbytes = read(m_drv_fd,buffer->pBuffer,output_buffer_size );
4042          DEBUG_DETAIL("FTBP->Al_len[%lu]buf[%p]size[%d]numOutBuf[%d]\n",\
4043                         buffer->nAllocLen,buffer->pBuffer,
4044                         nReadbytes,nNumOutputBuf);
4045      if (nReadbytes <= 0) {
4046                  buffer->nFilledLen = 0;
4047            buffer->nOffset = 0;
4048                buffer->nTimeStamp = nTimestamp;
4049             frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
4050                  return OMX_ErrorNone;
4051      } else
4052              DEBUG_PRINT("Read bytes %d\n",nReadbytes);
4053      // Buffer from Driver will have
4054      // 1 byte => Nr of frame field
4055      // (sizeof(ENC_META_OUT) * Nr of frame) bytes => meta_out->offset_to_frame
4056      // Frame Size * Nr of frame =>
4057
4058          meta_out = (ENC_META_OUT *)(buffer->pBuffer + sizeof(unsigned char));
4059          buffer->nTimeStamp = (((OMX_TICKS)meta_out->msw_ts << 32)+
4060					meta_out->lsw_ts);
4061          buffer->nFlags |= meta_out->nflags;
4062          buffer->nOffset = (OMX_U32)(meta_out->offset_to_frame +
4063                                    sizeof(unsigned char));
4064          buffer->nFilledLen = (OMX_U32)(nReadbytes - buffer->nOffset);
4065          ts += FRAMEDURATION;
4066          buffer->nTimeStamp = ts;
4067          nTimestamp = buffer->nTimeStamp;
4068          DEBUG_PRINT("nflags %d frame_size %d offset_to_frame %d \
4069		timestamp %lld\n", meta_out->nflags, meta_out->frame_size,
4070		meta_out->offset_to_frame, buffer->nTimeStamp);
4071
4072          if ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS )
4073          {
4074              buffer->nFilledLen = 0;
4075              buffer->nOffset = 0;
4076              buffer->nTimeStamp = nTimestamp;
4077              frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
4078              if ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == OMX_BUFFERFLAG_EOS )
4079              {
4080                  DEBUG_PRINT("FTBP: Now, Send EOS flag to Client \n");
4081                  m_cb.EventHandler(&m_cmp,
4082                                  m_app_data,
4083                                  OMX_EventBufferFlag,
4084                                  1, 1, NULL );
4085              }
4086
4087              return OMX_ErrorNone;
4088          }
4089          DEBUG_PRINT("nState %d \n",nState );
4090
4091          pthread_mutex_lock(&m_state_lock);
4092          get_state(&m_cmp, &state);
4093          pthread_mutex_unlock(&m_state_lock);
4094
4095          if (state == OMX_StatePause)
4096          {
4097              DEBUG_PRINT("FTBP:Post the FBD to event thread currstate=%d\n",\
4098                            state);
4099              post_output((unsigned long) & hComp,(unsigned long) buffer,
4100                            OMX_COMPONENT_GENERATE_FRAME_DONE);
4101          }
4102          else
4103          {
4104              frame_done_cb((OMX_BUFFERHEADERTYPE *)buffer);
4105
4106          }
4107
4108    }
4109    else
4110        DEBUG_PRINT("\n FTBP-->Invalid buffer in FTB \n");
4111
4112
4113    return OMX_ErrorNone;
4114}
4115
4116/* ======================================================================
4117FUNCTION
4118  omx_amr_aenc::FillThisBuffer
4119
4120DESCRIPTION
4121  IL client uses this method to release the frame buffer
4122  after displaying them.
4123
4124
4125
4126PARAMETERS
4127
4128  None.
4129
4130RETURN VALUE
4131  true/false
4132
4133========================================================================== */
4134OMX_ERRORTYPE  omx_amr_aenc::fill_this_buffer
4135(
4136    OMX_IN OMX_HANDLETYPE         hComp,
4137    OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4138{
4139    OMX_ERRORTYPE eRet = OMX_ErrorNone;
4140    if (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))
4141    {
4142        DEBUG_PRINT("omx_amr_aenc::ftb--> Buffer Size Invalid\n");
4143        return OMX_ErrorBadParameter;
4144    }
4145    if (m_out_bEnabled == OMX_FALSE)
4146    {
4147        return OMX_ErrorIncorrectStateOperation;
4148    }
4149
4150    if (buffer->nVersion.nVersion != OMX_SPEC_VERSION)
4151    {
4152        DEBUG_PRINT("omx_amr_aenc::ftb--> OMX Version Invalid\n");
4153        return OMX_ErrorVersionMismatch;
4154    }
4155    if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
4156    {
4157        return OMX_ErrorBadPortIndex;
4158    }
4159    pthread_mutex_lock(&out_buf_count_lock);
4160    nNumOutputBuf++;
4161    m_amr_pb_stats.ftb_cnt++;
4162    DEBUG_DETAIL("FTB:nNumOutputBuf is %d", nNumOutputBuf);
4163    pthread_mutex_unlock(&out_buf_count_lock);
4164    post_output((unsigned long)hComp,
4165                (unsigned long) buffer,OMX_COMPONENT_GENERATE_FTB);
4166    return eRet;
4167}
4168
4169/* ======================================================================
4170FUNCTION
4171  omx_amr_aenc::SetCallbacks
4172
4173DESCRIPTION
4174  Set the callbacks.
4175
4176PARAMETERS
4177  None.
4178
4179RETURN VALUE
4180  OMX Error None if everything successful.
4181
4182========================================================================== */
4183OMX_ERRORTYPE  omx_amr_aenc::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
4184                                            OMX_IN OMX_CALLBACKTYPE* callbacks,
4185                                            OMX_IN OMX_PTR             appData)
4186{
4187    if(hComp == NULL)
4188    {
4189        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
4190        return OMX_ErrorBadParameter;
4191    }
4192    m_cb       = *callbacks;
4193    m_app_data =    appData;
4194
4195    return OMX_ErrorNone;
4196}
4197
4198/* ======================================================================
4199FUNCTION
4200  omx_amr_aenc::ComponentDeInit
4201
4202DESCRIPTION
4203  Destroys the component and release memory allocated to the heap.
4204
4205PARAMETERS
4206  <TBD>.
4207
4208RETURN VALUE
4209  OMX Error None if everything successful.
4210
4211========================================================================== */
4212OMX_ERRORTYPE  omx_amr_aenc::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
4213{
4214    if(hComp == NULL)
4215    {
4216        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
4217        return OMX_ErrorBadParameter;
4218    }
4219    if (OMX_StateLoaded != m_state && OMX_StateInvalid != m_state)
4220    {
4221        DEBUG_PRINT_ERROR("Warning: Rxed DeInit when not in LOADED state %d\n",
4222            m_state);
4223    }
4224  deinit_encoder();
4225
4226DEBUG_PRINT_ERROR("%s:COMPONENT DEINIT...\n", __FUNCTION__);
4227  return OMX_ErrorNone;
4228}
4229
4230/* ======================================================================
4231FUNCTION
4232  omx_amr_aenc::deinit_encoder
4233
4234DESCRIPTION
4235  Closes all the threads and release memory allocated to the heap.
4236
4237PARAMETERS
4238  None.
4239
4240RETURN VALUE
4241  None.
4242
4243========================================================================== */
4244void  omx_amr_aenc::deinit_encoder()
4245{
4246    DEBUG_PRINT("Component-deinit being processed\n");
4247    DEBUG_PRINT("********************************\n");
4248    DEBUG_PRINT("STATS: in-buf-len[%u]out-buf-len[%u] tot-pb-time[%lld]",\
4249                m_amr_pb_stats.tot_in_buf_len,
4250                m_amr_pb_stats.tot_out_buf_len,
4251                m_amr_pb_stats.tot_pb_time);
4252    DEBUG_PRINT("STATS: fbd-cnt[%u]ftb-cnt[%u]etb-cnt[%u]ebd-cnt[%u]",\
4253                m_amr_pb_stats.fbd_cnt,m_amr_pb_stats.ftb_cnt,
4254                m_amr_pb_stats.etb_cnt,
4255                m_amr_pb_stats.ebd_cnt);
4256   memset(&m_amr_pb_stats,0,sizeof(AMR_PB_STATS));
4257
4258    if((OMX_StateLoaded != m_state) && (OMX_StateInvalid != m_state))
4259    {
4260        DEBUG_PRINT_ERROR("%s,Deinit called in state[%d]\n",__FUNCTION__,\
4261                                                                m_state);
4262        // Get back any buffers from driver
4263        if(pcm_input)
4264            execute_omx_flush(-1,false);
4265        else
4266            execute_omx_flush(1,false);
4267        // force state change to loaded so that all threads can be exited
4268        pthread_mutex_lock(&m_state_lock);
4269        m_state = OMX_StateLoaded;
4270        pthread_mutex_unlock(&m_state_lock);
4271        DEBUG_PRINT_ERROR("Freeing Buf:inp_current_buf_count[%d][%d]\n",\
4272        m_inp_current_buf_count,
4273        m_input_buf_hdrs.size());
4274        m_input_buf_hdrs.eraseall();
4275        DEBUG_PRINT_ERROR("Freeing Buf:out_current_buf_count[%d][%d]\n",\
4276        m_out_current_buf_count,
4277        m_output_buf_hdrs.size());
4278        m_output_buf_hdrs.eraseall();
4279
4280    }
4281    if(pcm_input)
4282    {
4283        pthread_mutex_lock(&m_in_th_lock_1);
4284        if (is_in_th_sleep)
4285        {
4286            is_in_th_sleep = false;
4287            DEBUG_DETAIL("Deinit:WAKING UP IN THREADS\n");
4288            in_th_wakeup();
4289        }
4290        pthread_mutex_unlock(&m_in_th_lock_1);
4291    }
4292    pthread_mutex_lock(&m_out_th_lock_1);
4293    if (is_out_th_sleep)
4294    {
4295        is_out_th_sleep = false;
4296        DEBUG_DETAIL("SCP:WAKING UP OUT THREADS\n");
4297        out_th_wakeup();
4298    }
4299    pthread_mutex_unlock(&m_out_th_lock_1);
4300    if(pcm_input)
4301    {
4302        if (m_ipc_to_in_th != NULL)
4303        {
4304            omx_amr_thread_stop(m_ipc_to_in_th);
4305            m_ipc_to_in_th = NULL;
4306        }
4307    }
4308
4309    if (m_ipc_to_cmd_th != NULL)
4310    {
4311        omx_amr_thread_stop(m_ipc_to_cmd_th);
4312        m_ipc_to_cmd_th = NULL;
4313    }
4314    if (m_ipc_to_out_th != NULL)
4315    {
4316         DEBUG_DETAIL("Inside omx_amr_thread_stop\n");
4317        omx_amr_thread_stop(m_ipc_to_out_th);
4318        m_ipc_to_out_th = NULL;
4319     }
4320
4321
4322    if(ioctl(m_drv_fd, AUDIO_STOP, 0) <0)
4323          DEBUG_PRINT_ERROR("De-init: AUDIO_STOP FAILED\n");
4324
4325    if(pcm_input && m_tmp_meta_buf )
4326    {
4327        free(m_tmp_meta_buf);
4328    }
4329
4330    if(m_tmp_out_meta_buf)
4331    {
4332        free(m_tmp_out_meta_buf);
4333    }
4334    nNumInputBuf = 0;
4335    nNumOutputBuf = 0;
4336    bFlushinprogress = 0;
4337
4338    m_inp_current_buf_count=0;
4339    m_out_current_buf_count=0;
4340    m_out_act_buf_count = 0;
4341    m_inp_act_buf_count = 0;
4342    m_inp_bEnabled = OMX_FALSE;
4343    m_out_bEnabled = OMX_FALSE;
4344    m_inp_bPopulated = OMX_FALSE;
4345    m_out_bPopulated = OMX_FALSE;
4346    nTimestamp = 0;
4347    ts = 0;
4348
4349    if ( m_drv_fd >= 0 )
4350    {
4351        if(close(m_drv_fd) < 0)
4352        DEBUG_PRINT("De-init: Driver Close Failed \n");
4353        m_drv_fd = -1;
4354    }
4355    else
4356    {
4357        DEBUG_PRINT_ERROR(" AMR device already closed\n");
4358    }
4359    m_comp_deinit=1;
4360    m_is_out_th_sleep = 1;
4361    m_is_in_th_sleep = 1;
4362    DEBUG_PRINT("************************************\n");
4363    DEBUG_PRINT(" DEINIT COMPLETED");
4364    DEBUG_PRINT("************************************\n");
4365
4366}
4367
4368/* ======================================================================
4369FUNCTION
4370  omx_amr_aenc::UseEGLImage
4371
4372DESCRIPTION
4373  OMX Use EGL Image method implementation <TBD>.
4374
4375PARAMETERS
4376  <TBD>.
4377
4378RETURN VALUE
4379  Not Implemented error.
4380
4381========================================================================== */
4382OMX_ERRORTYPE  omx_amr_aenc::use_EGL_image
4383(
4384    OMX_IN OMX_HANDLETYPE                hComp,
4385    OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4386    OMX_IN OMX_U32                        port,
4387    OMX_IN OMX_PTR                     appData,
4388    OMX_IN void*                      eglImage)
4389{
4390    DEBUG_PRINT_ERROR("Error : use_EGL_image:  Not Implemented \n");
4391
4392    if((hComp == NULL) || (appData == NULL) || (eglImage == NULL))
4393    {
4394        bufferHdr = bufferHdr;
4395        port = port;
4396        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
4397        return OMX_ErrorBadParameter;
4398    }
4399    return OMX_ErrorNotImplemented;
4400}
4401
4402/* ======================================================================
4403FUNCTION
4404  omx_amr_aenc::ComponentRoleEnum
4405
4406DESCRIPTION
4407  OMX Component Role Enum method implementation.
4408
4409PARAMETERS
4410  <TBD>.
4411
4412RETURN VALUE
4413  OMX Error None if everything is successful.
4414========================================================================== */
4415OMX_ERRORTYPE  omx_amr_aenc::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
4416                                                  OMX_OUT OMX_U8*        role,
4417                                                  OMX_IN OMX_U32        index)
4418{
4419    OMX_ERRORTYPE eRet = OMX_ErrorNone;
4420    const char *cmp_role = "audio_encoder.amr";
4421
4422    if(hComp == NULL)
4423    {
4424        DEBUG_PRINT_ERROR("Returning OMX_ErrorBadParameter\n");
4425        return OMX_ErrorBadParameter;
4426    }
4427    if (index == 0 && role)
4428    {
4429        memcpy(role, cmp_role, strlen(cmp_role));
4430        *(((char *) role) + strlen(cmp_role) +1) = '\0';
4431    } else
4432    {
4433        eRet = OMX_ErrorNoMore;
4434    }
4435    return eRet;
4436}
4437
4438
4439
4440
4441/* ======================================================================
4442FUNCTION
4443  omx_amr_aenc::AllocateDone
4444
4445DESCRIPTION
4446  Checks if entire buffer pool is allocated by IL Client or not.
4447  Need this to move to IDLE state.
4448
4449PARAMETERS
4450  None.
4451
4452RETURN VALUE
4453  true/false.
4454
4455========================================================================== */
4456bool omx_amr_aenc::allocate_done(void)
4457{
4458    OMX_BOOL bRet = OMX_FALSE;
4459    if (pcm_input==1)
4460    {
4461        if ((m_inp_act_buf_count == m_inp_current_buf_count)
4462            &&(m_out_act_buf_count == m_out_current_buf_count))
4463        {
4464            bRet=OMX_TRUE;
4465
4466        }
4467        if ((m_inp_act_buf_count == m_inp_current_buf_count) && m_inp_bEnabled )
4468        {
4469            m_inp_bPopulated = OMX_TRUE;
4470        }
4471
4472        if ((m_out_act_buf_count == m_out_current_buf_count) && m_out_bEnabled )
4473        {
4474            m_out_bPopulated = OMX_TRUE;
4475        }
4476    } else if (pcm_input==0)
4477    {
4478        if (m_out_act_buf_count == m_out_current_buf_count)
4479        {
4480            bRet=OMX_TRUE;
4481
4482        }
4483        if ((m_out_act_buf_count == m_out_current_buf_count) && m_out_bEnabled )
4484        {
4485            m_out_bPopulated = OMX_TRUE;
4486        }
4487
4488    }
4489    return bRet;
4490}
4491
4492
4493/* ======================================================================
4494FUNCTION
4495  omx_amr_aenc::ReleaseDone
4496
4497DESCRIPTION
4498  Checks if IL client has released all the buffers.
4499
4500PARAMETERS
4501  None.
4502
4503RETURN VALUE
4504  true/false
4505
4506========================================================================== */
4507bool omx_amr_aenc::release_done(OMX_U32 param1)
4508{
4509    DEBUG_PRINT("Inside omx_amr_aenc::release_done");
4510    OMX_BOOL bRet = OMX_FALSE;
4511
4512    if (param1 == OMX_ALL)
4513    {
4514        if ((0 == m_inp_current_buf_count)&&(0 == m_out_current_buf_count))
4515        {
4516            bRet=OMX_TRUE;
4517        }
4518    } else if (param1 == OMX_CORE_INPUT_PORT_INDEX )
4519    {
4520        if ((0 == m_inp_current_buf_count))
4521        {
4522            bRet=OMX_TRUE;
4523        }
4524    } else if (param1 == OMX_CORE_OUTPUT_PORT_INDEX)
4525    {
4526        if ((0 == m_out_current_buf_count))
4527        {
4528            bRet=OMX_TRUE;
4529        }
4530    }
4531    return bRet;
4532}
4533