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