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