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