1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010, 2014 The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, 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 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED 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 
44 using namespace std;
45 #define SLEEP_MS 100
46 
47 // omx_cmd_queue destructor
~omx_cmd_queue()48 omx_amr_aenc::omx_cmd_queue::~omx_cmd_queue()
49 {
50     // Nothing to do
51 }
52 
53 // omx cmd queue constructor
omx_cmd_queue()54 omx_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
insert_entry(unsigned long p1,unsigned long p2,unsigned char id)60 bool 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 
pop_entry(unsigned long * p1,unsigned long * p2,unsigned char * id)84 bool 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
get_omx_component_factory_fn(void)110 void *get_omx_component_factory_fn(void)
111 {
112     return(new omx_amr_aenc);
113 }
get_msg_id(unsigned char * id)114 bool 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 /*=============================================================================
127 FUNCTION:
128   wait_for_event
129 
130 DESCRIPTION:
131   waits for a particular event
132 
133 INPUT/OUTPUT PARAMETERS:
134   None
135 
136 RETURN VALUE:
137   None
138 
139 Dependency:
140   None
141 
142 SIDE EFFECTS:
143    None
144 =============================================================================*/
wait_for_event()145 void 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 /*=============================================================================
168 FUNCTION:
169   event_complete
170 
171 DESCRIPTION:
172   informs about the occurance of an event
173 
174 INPUT/OUTPUT PARAMETERS:
175   None
176 
177 RETURN VALUE:
178   None
179 
180 Dependency:
181   None
182 
183 SIDE EFFECTS:
184    None
185 =============================================================================*/
event_complete()186 void 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
in_th_goto_sleep()198 void 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 
in_th_wakeup()209 void 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 
out_th_goto_sleep()220 void 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 
out_th_wakeup()232 void 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 /* ======================================================================
243 FUNCTION
244   omx_amr_aenc::omx_amr_aenc
245 
246 DESCRIPTION
247   Constructor
248 
249 PARAMETERS
250   None
251 
252 RETURN VALUE
253   None.
254 ========================================================================== */
omx_amr_aenc()255 omx_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 /* ======================================================================
374 FUNCTION
375   omx_amr_aenc::~omx_amr_aenc
376 
377 DESCRIPTION
378   Destructor
379 
380 PARAMETERS
381   None
382 
383 RETURN VALUE
384   None.
385 ========================================================================== */
~omx_amr_aenc()386 omx_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  */
buffer_done_cb(OMX_BUFFERHEADERTYPE * bufHdr)448 void 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 /*=============================================================================
469 FUNCTION:
470   flush_ack
471 
472 DESCRIPTION:
473 
474 
475 INPUT/OUTPUT PARAMETERS:
476   None
477 
478 RETURN VALUE:
479   None
480 
481 Dependency:
482   None
483 
484 SIDE EFFECTS:
485   None
486 =============================================================================*/
flush_ack()487 void 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 }
frame_done_cb(OMX_BUFFERHEADERTYPE * bufHdr)499 void 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 /*=============================================================================
524 FUNCTION:
525   process_out_port_msg
526 
527 DESCRIPTION:
528   Function for handling all commands from IL client
529 IL client commands are processed and callbacks are generated through
530 this routine  Audio Command Server provides the thread context for this routine
531 
532 INPUT/OUTPUT PARAMETERS:
533   [INOUT] client_data
534   [IN] id
535 
536 RETURN VALUE:
537   None
538 
539 Dependency:
540   None
541 
542 SIDE EFFECTS:
543   None
544 =============================================================================*/
process_out_port_msg(void * client_data,unsigned char id)545 void 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 
555 loopback_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 /*=============================================================================
730 FUNCTION:
731   process_command_msg
732 
733 DESCRIPTION:
734 
735 
736 INPUT/OUTPUT PARAMETERS:
737   [INOUT] client_data
738   [IN] id
739 
740 RETURN VALUE:
741   None
742 
743 Dependency:
744   None
745 
746 SIDE EFFECTS:
747   None
748 =============================================================================*/
process_command_msg(void * client_data,unsigned char id)749 void 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 /*=============================================================================
860 FUNCTION:
861   process_in_port_msg
862 
863 DESCRIPTION:
864 
865 
866 INPUT/OUTPUT PARAMETERS:
867   [INOUT] client_data
868   [IN] id
869 
870 RETURN VALUE:
871   None
872 
873 Dependency:
874   None
875 
876 SIDE EFFECTS:
877   None
878 =============================================================================*/
process_in_port_msg(void * client_data,unsigned char id)879 void 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     }
894 loopback_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  */
component_init(OMX_STRING role)1051 OMX_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  */
get_component_version(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_STRING componentName,OMX_OUT OMX_VERSIONTYPE * componentVersion,OMX_OUT OMX_VERSIONTYPE * specVersion,OMX_OUT OMX_UUIDTYPE * componentUUID)1209 OMX_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 */
send_command(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)1245 OMX_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 */
send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)1285 OMX_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 /*=============================================================================
1890 FUNCTION:
1891   execute_omx_flush
1892 
1893 DESCRIPTION:
1894   Function that flushes buffers that are pending to be written to driver
1895 
1896 INPUT/OUTPUT PARAMETERS:
1897   [IN] param1
1898   [IN] cmd_cmpl
1899 
1900 RETURN VALUE:
1901   true
1902   false
1903 
1904 Dependency:
1905   None
1906 
1907 SIDE EFFECTS:
1908   None
1909 =============================================================================*/
execute_omx_flush(OMX_IN OMX_U32 param1,bool cmd_cmpl)1910 bool 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 /*=============================================================================
2084 FUNCTION:
2085   execute_input_omx_flush
2086 
2087 DESCRIPTION:
2088   Function that flushes buffers that are pending to be written to driver
2089 
2090 INPUT/OUTPUT PARAMETERS:
2091   None
2092 
2093 RETURN VALUE:
2094   true
2095   false
2096 
2097 Dependency:
2098   None
2099 
2100 SIDE EFFECTS:
2101   None
2102 =============================================================================*/
execute_input_omx_flush()2103 bool 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 /*=============================================================================
2164 FUNCTION:
2165   execute_output_omx_flush
2166 
2167 DESCRIPTION:
2168   Function that flushes buffers that are pending to be written to driver
2169 
2170 INPUT/OUTPUT PARAMETERS:
2171   None
2172 
2173 RETURN VALUE:
2174   true
2175   false
2176 
2177 Dependency:
2178   None
2179 
2180 SIDE EFFECTS:
2181   None
2182 =============================================================================*/
execute_output_omx_flush()2183 bool 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 /*=============================================================================
2247 FUNCTION:
2248   post_input
2249 
2250 DESCRIPTION:
2251   Function that posts command in the command queue
2252 
2253 INPUT/OUTPUT PARAMETERS:
2254   [IN] p1
2255   [IN] p2
2256   [IN] id - command ID
2257   [IN] lock - self-locking mode
2258 
2259 RETURN VALUE:
2260   true
2261   false
2262 
2263 Dependency:
2264   None
2265 
2266 SIDE EFFECTS:
2267   None
2268 =============================================================================*/
post_input(unsigned long p1,unsigned long p2,unsigned char id)2269 bool 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 /*=============================================================================
2308 FUNCTION:
2309   post_command
2310 
2311 DESCRIPTION:
2312   Function that posts command in the command queue
2313 
2314 INPUT/OUTPUT PARAMETERS:
2315   [IN] p1
2316   [IN] p2
2317   [IN] id - command ID
2318   [IN] lock - self-locking mode
2319 
2320 RETURN VALUE:
2321   true
2322   false
2323 
2324 Dependency:
2325   None
2326 
2327 SIDE EFFECTS:
2328   None
2329 =============================================================================*/
post_command(unsigned int p1,unsigned int p2,unsigned char id)2330 bool 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 /*=============================================================================
2357 FUNCTION:
2358   post_output
2359 
2360 DESCRIPTION:
2361   Function that posts command in the command queue
2362 
2363 INPUT/OUTPUT PARAMETERS:
2364   [IN] p1
2365   [IN] p2
2366   [IN] id - command ID
2367   [IN] lock - self-locking mode
2368 
2369 RETURN VALUE:
2370   true
2371   false
2372 
2373 Dependency:
2374   None
2375 
2376 SIDE EFFECTS:
2377   None
2378 =============================================================================*/
post_output(unsigned long p1,unsigned long p2,unsigned char id)2379 bool 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 */
get_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_INOUT OMX_PTR paramData)2423 OMX_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  */
set_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_IN OMX_PTR paramData)2701 OMX_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 /* ======================================================================
2916 FUNCTION
2917   omx_amr_aenc::GetConfig
2918 
2919 DESCRIPTION
2920   OMX Get Config Method implementation.
2921 
2922 PARAMETERS
2923   <TBD>.
2924 
2925 RETURN VALUE
2926   OMX Error None if successful.
2927 
2928 ========================================================================== */
get_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_INOUT OMX_PTR configData)2929 OMX_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 /* ======================================================================
2994 FUNCTION
2995   omx_amr_aenc::SetConfig
2996 
2997 DESCRIPTION
2998   OMX Set Config method implementation
2999 
3000 PARAMETERS
3001   <TBD>.
3002 
3003 RETURN VALUE
3004   OMX Error None if successful.
3005 ========================================================================== */
set_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_IN OMX_PTR configData)3006 OMX_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 /* ======================================================================
3088 FUNCTION
3089   omx_amr_aenc::GetExtensionIndex
3090 
3091 DESCRIPTION
3092   OMX GetExtensionIndex method implementaion.  <TBD>
3093 
3094 PARAMETERS
3095   <TBD>.
3096 
3097 RETURN VALUE
3098   OMX Error None if everything successful.
3099 
3100 ========================================================================== */
get_extension_index(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_STRING paramName,OMX_OUT OMX_INDEXTYPE * indexType)3101 OMX_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 /* ======================================================================
3132 FUNCTION
3133   omx_amr_aenc::GetState
3134 
3135 DESCRIPTION
3136   Returns the state information back to the caller.<TBD>
3137 
3138 PARAMETERS
3139   <TBD>.
3140 
3141 RETURN VALUE
3142   Error None if everything is successful.
3143 ========================================================================== */
get_state(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_STATETYPE * state)3144 OMX_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 /* ======================================================================
3158 FUNCTION
3159   omx_amr_aenc::ComponentTunnelRequest
3160 
3161 DESCRIPTION
3162   OMX Component Tunnel Request method implementation. <TBD>
3163 
3164 PARAMETERS
3165   None.
3166 
3167 RETURN VALUE
3168   OMX Error None if everything successful.
3169 
3170 ========================================================================== */
component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_HANDLETYPE peerComponent,OMX_IN OMX_U32 peerPort,OMX_INOUT OMX_TUNNELSETUPTYPE * tunnelSetup)3171 OMX_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 /* ======================================================================
3192 FUNCTION
3193   omx_amr_aenc::AllocateInputBuffer
3194 
3195 DESCRIPTION
3196   Helper function for allocate buffer in the input pin
3197 
3198 PARAMETERS
3199   None.
3200 
3201 RETURN VALUE
3202   true/false
3203 
3204 ========================================================================== */
allocate_input_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes)3205 OMX_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 
allocate_output_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes)3263 OMX_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 /* ======================================================================
3320 FUNCTION
3321   omx_amr_aenc::AllocateBuffer
3322 
3323 DESCRIPTION
3324   Returns zero if all the buffers released..
3325 
3326 PARAMETERS
3327   None.
3328 
3329 RETURN VALUE
3330   true/false
3331 
3332 ========================================================================== */
allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes)3333 OMX_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 /*=============================================================================
3421 FUNCTION:
3422   use_buffer
3423 
3424 DESCRIPTION:
3425   OMX Use Buffer method implementation.
3426 
3427 INPUT/OUTPUT PARAMETERS:
3428   [INOUT] bufferHdr
3429   [IN] hComp
3430   [IN] port
3431   [IN] appData
3432   [IN] bytes
3433   [IN] buffer
3434 
3435 RETURN VALUE:
3436   OMX_ERRORTYPE
3437 
3438 Dependency:
3439   None
3440 
3441 SIDE EFFECTS:
3442   None
3443 =============================================================================*/
use_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)3444 OMX_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 /*=============================================================================
3520 FUNCTION:
3521   use_input_buffer
3522 
3523 DESCRIPTION:
3524   Helper function for Use buffer in the input pin
3525 
3526 INPUT/OUTPUT PARAMETERS:
3527   [INOUT] bufferHdr
3528   [IN] hComp
3529   [IN] port
3530   [IN] appData
3531   [IN] bytes
3532   [IN] buffer
3533 
3534 RETURN VALUE:
3535   OMX_ERRORTYPE
3536 
3537 Dependency:
3538   None
3539 
3540 SIDE EFFECTS:
3541   None
3542 =============================================================================*/
use_input_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)3543 OMX_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 /*=============================================================================
3605 FUNCTION:
3606   use_output_buffer
3607 
3608 DESCRIPTION:
3609   Helper function for Use buffer in the output pin
3610 
3611 INPUT/OUTPUT PARAMETERS:
3612   [INOUT] bufferHdr
3613   [IN] hComp
3614   [IN] port
3615   [IN] appData
3616   [IN] bytes
3617   [IN] buffer
3618 
3619 RETURN VALUE:
3620   OMX_ERRORTYPE
3621 
3622 Dependency:
3623   None
3624 
3625 SIDE EFFECTS:
3626   None
3627 =============================================================================*/
use_output_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)3628 OMX_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  */
search_input_bufhdr(OMX_BUFFERHEADERTYPE * buffer)3699 bool 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  */
search_output_bufhdr(OMX_BUFFERHEADERTYPE * buffer)3721 bool 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 */
free_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3749 OMX_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  */
empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3898 OMX_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  */
empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)3963 OMX_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 
fill_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)4025 OMX_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 /* ======================================================================
4117 FUNCTION
4118   omx_amr_aenc::FillThisBuffer
4119 
4120 DESCRIPTION
4121   IL client uses this method to release the frame buffer
4122   after displaying them.
4123 
4124 
4125 
4126 PARAMETERS
4127 
4128   None.
4129 
4130 RETURN VALUE
4131   true/false
4132 
4133 ========================================================================== */
fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)4134 OMX_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 /* ======================================================================
4170 FUNCTION
4171   omx_amr_aenc::SetCallbacks
4172 
4173 DESCRIPTION
4174   Set the callbacks.
4175 
4176 PARAMETERS
4177   None.
4178 
4179 RETURN VALUE
4180   OMX Error None if everything successful.
4181 
4182 ========================================================================== */
set_callbacks(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_CALLBACKTYPE * callbacks,OMX_IN OMX_PTR appData)4183 OMX_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 /* ======================================================================
4199 FUNCTION
4200   omx_amr_aenc::ComponentDeInit
4201 
4202 DESCRIPTION
4203   Destroys the component and release memory allocated to the heap.
4204 
4205 PARAMETERS
4206   <TBD>.
4207 
4208 RETURN VALUE
4209   OMX Error None if everything successful.
4210 
4211 ========================================================================== */
component_deinit(OMX_IN OMX_HANDLETYPE hComp)4212 OMX_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 
4226 DEBUG_PRINT_ERROR("%s:COMPONENT DEINIT...\n", __FUNCTION__);
4227   return OMX_ErrorNone;
4228 }
4229 
4230 /* ======================================================================
4231 FUNCTION
4232   omx_amr_aenc::deinit_encoder
4233 
4234 DESCRIPTION
4235   Closes all the threads and release memory allocated to the heap.
4236 
4237 PARAMETERS
4238   None.
4239 
4240 RETURN VALUE
4241   None.
4242 
4243 ========================================================================== */
deinit_encoder()4244 void  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 /* ======================================================================
4369 FUNCTION
4370   omx_amr_aenc::UseEGLImage
4371 
4372 DESCRIPTION
4373   OMX Use EGL Image method implementation <TBD>.
4374 
4375 PARAMETERS
4376   <TBD>.
4377 
4378 RETURN VALUE
4379   Not Implemented error.
4380 
4381 ========================================================================== */
use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN void * eglImage)4382 OMX_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 /* ======================================================================
4403 FUNCTION
4404   omx_amr_aenc::ComponentRoleEnum
4405 
4406 DESCRIPTION
4407   OMX Component Role Enum method implementation.
4408 
4409 PARAMETERS
4410   <TBD>.
4411 
4412 RETURN VALUE
4413   OMX Error None if everything is successful.
4414 ========================================================================== */
component_role_enum(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_U8 * role,OMX_IN OMX_U32 index)4415 OMX_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 /* ======================================================================
4442 FUNCTION
4443   omx_amr_aenc::AllocateDone
4444 
4445 DESCRIPTION
4446   Checks if entire buffer pool is allocated by IL Client or not.
4447   Need this to move to IDLE state.
4448 
4449 PARAMETERS
4450   None.
4451 
4452 RETURN VALUE
4453   true/false.
4454 
4455 ========================================================================== */
allocate_done(void)4456 bool 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 /* ======================================================================
4494 FUNCTION
4495   omx_amr_aenc::ReleaseDone
4496 
4497 DESCRIPTION
4498   Checks if IL client has released all the buffers.
4499 
4500 PARAMETERS
4501   None.
4502 
4503 RETURN VALUE
4504   true/false
4505 
4506 ========================================================================== */
release_done(OMX_U32 param1)4507 bool 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