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