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