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