1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2010, Code Aurora Forum. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are met: 6 * Redistributions of source code must retain the above copyright 7 notice, this list of conditions and the following disclaimer. 8 * Redistributions in binary form must reproduce the above copyright 9 notice, this list of conditions and the following disclaimer in the 10 documentation and/or other materials provided with the distribution. 11 * Neither the name of Code Aurora nor 12 the names of its contributors may be used to endorse or promote 13 products derived from this software without specific prior written 14 permission. 15 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 --------------------------------------------------------------------------*/ 28 /*============================================================================ 29 O p e n M A X w r a p p e r s 30 O p e n M A X C o r e 31 32 *//** @file omx_video_base.cpp 33 This module contains the implementation of the OpenMAX core & component. 34 35 *//*========================================================================*/ 36 37 ////////////////////////////////////////////////////////////////////////////// 38 // Include Files 39 ////////////////////////////////////////////////////////////////////////////// 40 41 #include <string.h> 42 #include "omx_video_base.h" 43 #include <stdlib.h> 44 #include <errno.h> 45 #include <fcntl.h> 46 #include <unistd.h> 47 48 #define H264_SUPPORTED_WIDTH (480) 49 #define H264_SUPPORTED_HEIGHT (368) 50 51 #define MPEG4_SUPPORTED_WIDTH (480) 52 #define MPEG4_SUPPORTED_HEIGHT (368) 53 54 #define VC1_SP_MP_START_CODE 0xC5000000 55 #define VC1_SP_MP_START_CODE_MASK 0xFF000000 56 #define VC1_AP_START_CODE 0x00000100 57 #define VC1_AP_START_CODE_MASK 0xFFFFFF00 58 #define VC1_STRUCT_C_PROFILE_MASK 0xF0 59 #define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 60 #define VC1_SIMPLE_PROFILE 0 61 #define VC1_MAIN_PROFILE 1 62 #define VC1_ADVANCE_PROFILE 3 63 #define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 64 #define VC1_SIMPLE_PROFILE_MED_LEVEL 2 65 #define VC1_STRUCT_C_LEN 4 66 #define VC1_STRUCT_C_POS 8 67 #define VC1_STRUCT_A_POS 12 68 #define VC1_STRUCT_B_POS 24 69 #define VC1_SEQ_LAYER_SIZE 36 70 71 typedef struct OMXComponentCapabilityFlagsType 72 { 73 ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS 74 OMX_BOOL iIsOMXComponentMultiThreaded; 75 OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc; 76 OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc; 77 OMX_BOOL iOMXComponentSupportsMovableInputBuffers; 78 OMX_BOOL iOMXComponentSupportsPartialFrames; 79 OMX_BOOL iOMXComponentUsesNALStartCodes; 80 OMX_BOOL iOMXComponentCanHandleIncompleteFrames; 81 OMX_BOOL iOMXComponentUsesFullAVCFrames; 82 83 } OMXComponentCapabilityFlagsType; 84 #define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347 85 86 void* message_thread(void *input) 87 { 88 omx_video* omx = reinterpret_cast<omx_video*>(input); 89 unsigned char id; 90 int n; 91 92 DEBUG_PRINT_LOW("omx_venc: message thread start\n"); 93 while(1) 94 { 95 n = read(omx->m_pipe_in, &id, 1); 96 if(0 == n) 97 { 98 break; 99 } 100 101 if(1 == n) 102 { 103 omx->process_event_cb(omx, id); 104 } 105 #ifdef QLE_BUILD 106 if(n < 0) break; 107 #else 108 if((n < 0) && (errno != EINTR)) break; 109 #endif 110 } 111 DEBUG_PRINT_LOW("omx_venc: message thread stop\n"); 112 return 0; 113 } 114 115 void post_message(omx_video *omx, unsigned char id) 116 { 117 DEBUG_PRINT_LOW("omx_venc: post_message %d\n", id); 118 write(omx->m_pipe_out, &id, 1); 119 } 120 121 // omx_cmd_queue destructor 122 omx_video::omx_cmd_queue::~omx_cmd_queue() 123 { 124 // Nothing to do 125 } 126 127 // omx cmd queue constructor 128 omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) 129 { 130 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); 131 } 132 133 // omx cmd queue insert 134 bool omx_video::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) 135 { 136 bool ret = true; 137 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) 138 { 139 m_q[m_write].id = id; 140 m_q[m_write].param1 = p1; 141 m_q[m_write].param2 = p2; 142 m_write++; 143 m_size ++; 144 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) 145 { 146 m_write = 0; 147 } 148 } 149 else 150 { 151 ret = false; 152 DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full\n"); 153 } 154 return ret; 155 } 156 157 // omx cmd queue pop 158 bool omx_video::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) 159 { 160 bool ret = true; 161 if(m_size > 0) 162 { 163 *id = m_q[m_read].id; 164 *p1 = m_q[m_read].param1; 165 *p2 = m_q[m_read].param2; 166 // Move the read pointer ahead 167 ++m_read; 168 --m_size; 169 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) 170 { 171 m_read = 0; 172 } 173 } 174 else 175 { 176 ret = false; 177 } 178 return ret; 179 } 180 181 // Retrieve the first mesg type in the queue 182 unsigned omx_video::omx_cmd_queue::get_q_msg_type() 183 { 184 return m_q[m_read].id; 185 } 186 187 188 189 #ifdef _ANDROID_ 190 VideoHeap::VideoHeap(int fd, size_t size, void* base) 191 { 192 // dup file descriptor, map once, use pmem 193 init(dup(fd), base, size, 0 , "/dev/pmem_adsp"); 194 } 195 #endif // _ANDROID_ 196 197 /* ====================================================================== 198 FUNCTION 199 omx_venc::omx_venc 200 201 DESCRIPTION 202 Constructor 203 204 PARAMETERS 205 None 206 207 RETURN VALUE 208 None. 209 ========================================================================== */ 210 omx_video::omx_video(): m_state(OMX_StateInvalid), 211 m_app_data(NULL), 212 m_inp_mem_ptr(NULL), 213 m_out_mem_ptr(NULL), 214 pending_input_buffers(0), 215 pending_output_buffers(0), 216 m_out_bm_count(0), 217 m_inp_bm_count(0), 218 m_flags(0), 219 m_event_port_settings_sent(false), 220 output_flush_progress (false), 221 input_flush_progress (false), 222 input_use_buffer (false), 223 output_use_buffer (false), 224 m_use_input_pmem(OMX_FALSE), 225 m_use_output_pmem(OMX_FALSE), 226 m_etb_count(0), 227 m_fbd_count(0) 228 { 229 DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()"); 230 memset(&m_cmp,0,sizeof(m_cmp)); 231 memset(&m_pCallbacks,0,sizeof(m_pCallbacks)); 232 233 pthread_mutex_init(&m_lock, NULL); 234 sem_init(&m_cmd_lock,0,0); 235 } 236 237 238 /* ====================================================================== 239 FUNCTION 240 omx_venc::~omx_venc 241 242 DESCRIPTION 243 Destructor 244 245 PARAMETERS 246 None 247 248 RETURN VALUE 249 None. 250 ========================================================================== */ 251 omx_video::~omx_video() 252 { 253 DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()"); 254 if(m_pipe_in) close(m_pipe_in); 255 if(m_pipe_out) close(m_pipe_out); 256 DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n"); 257 pthread_join(msg_thread_id,NULL); 258 DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n"); 259 pthread_join(async_thread_id,NULL); 260 pthread_mutex_destroy(&m_lock); 261 sem_destroy(&m_cmd_lock); 262 DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count, 263 m_fbd_count); 264 DEBUG_PRINT_HIGH("omx_video: Destructor exit\n"); 265 DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n"); 266 } 267 268 /* ====================================================================== 269 FUNCTION 270 omx_venc::OMXCntrlProcessMsgCb 271 272 DESCRIPTION 273 IL Client callbacks are generated through this routine. The decoder 274 provides the thread context for this routine. 275 276 PARAMETERS 277 ctxt -- Context information related to the self. 278 id -- Event identifier. This could be any of the following: 279 1. Command completion event 280 2. Buffer done callback event 281 3. Frame done callback event 282 283 RETURN VALUE 284 None. 285 286 ========================================================================== */ 287 void omx_video::process_event_cb(void *ctxt, unsigned char id) 288 { 289 unsigned p1; // Parameter - 1 290 unsigned p2; // Parameter - 2 291 unsigned ident; 292 unsigned qsize=0; // qsize 293 omx_video *pThis = (omx_video *) ctxt; 294 295 if(!pThis) 296 { 297 DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n"); 298 return; 299 } 300 301 // Protect the shared queue data structure 302 do 303 { 304 /*Read the message id's from the queue*/ 305 306 pthread_mutex_lock(&pThis->m_lock); 307 qsize = pThis->m_cmd_q.m_size; 308 if(qsize) 309 { 310 pThis->m_cmd_q.pop_entry(&p1,&p2,&ident); 311 } 312 313 if(qsize == 0) 314 { 315 qsize = pThis->m_ftb_q.m_size; 316 if(qsize) 317 { 318 pThis->m_ftb_q.pop_entry(&p1,&p2,&ident); 319 } 320 } 321 322 if(qsize == 0) 323 { 324 qsize = pThis->m_etb_q.m_size; 325 if(qsize) 326 { 327 pThis->m_etb_q.pop_entry(&p1,&p2,&ident); 328 } 329 } 330 331 pthread_mutex_unlock(&pThis->m_lock); 332 333 /*process message if we have one*/ 334 if(qsize > 0) 335 { 336 id = ident; 337 switch(id) 338 { 339 case OMX_COMPONENT_GENERATE_EVENT: 340 if(pThis->m_pCallbacks.EventHandler) 341 { 342 switch(p1) 343 { 344 case OMX_CommandStateSet: 345 pThis->m_state = (OMX_STATETYPE) p2; 346 DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state); 347 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 348 OMX_EventCmdComplete, p1, p2, NULL); 349 break; 350 351 case OMX_EventError: 352 DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2); 353 if(p2 == OMX_StateInvalid) 354 { 355 pThis->m_state = (OMX_STATETYPE) p2; 356 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 357 OMX_EventError, OMX_ErrorInvalidState, p2, NULL); 358 } 359 else if(p2 == OMX_ErrorHardware) 360 { 361 pThis->m_state = OMX_StateInvalid; 362 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 363 OMX_EventError,OMX_ErrorHardware,0,NULL); 364 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 365 OMX_EventError, OMX_ErrorInvalidState, p2, NULL); 366 367 } 368 else 369 { 370 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 371 OMX_EventError, p2, NULL, NULL ); 372 373 } 374 break; 375 376 case OMX_CommandPortDisable: 377 DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \ 378 "state \n", p2); 379 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 380 OMX_EventCmdComplete, p1, p2, NULL ); 381 break; 382 case OMX_CommandPortEnable: 383 DEBUG_PRINT_LOW("Process ->Port %d set PORT_STATE_ENABLED state\n" \ 384 , p2); 385 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ 386 OMX_EventCmdComplete, p1, p2, NULL ); 387 break; 388 389 default: 390 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 391 OMX_EventCmdComplete, p1, p2, NULL ); 392 break; 393 394 } 395 } 396 else 397 { 398 DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks\n"); 399 } 400 break; 401 402 case OMX_COMPONENT_GENERATE_ETB: 403 if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 404 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 405 { 406 DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n"); 407 pThis->omx_report_error (); 408 } 409 break; 410 411 case OMX_COMPONENT_GENERATE_FTB: 412 if( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 413 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 414 { 415 DEBUG_PRINT_ERROR("\nERROR: FTBProxy() failed!\n"); 416 pThis->omx_report_error (); 417 } 418 break; 419 420 case OMX_COMPONENT_GENERATE_COMMAND: 421 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ 422 (OMX_U32)p2,(OMX_PTR)NULL); 423 break; 424 425 case OMX_COMPONENT_GENERATE_EBD: 426 if( pThis->empty_buffer_done(&pThis->m_cmp, 427 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) 428 { 429 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); 430 pThis->omx_report_error (); 431 } 432 break; 433 434 case OMX_COMPONENT_GENERATE_FBD: 435 if( pThis->fill_buffer_done(&pThis->m_cmp, 436 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) 437 { 438 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); 439 pThis->omx_report_error (); 440 } 441 break; 442 443 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: 444 445 pThis->input_flush_progress = false; 446 DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", m_etb_count); 447 m_etb_count = 0; 448 if(pThis->m_pCallbacks.EventHandler) 449 { 450 /*Check if we need generate event for Flush done*/ 451 if(BITMASK_PRESENT(&pThis->m_flags, 452 OMX_COMPONENT_INPUT_FLUSH_PENDING)) 453 { 454 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); 455 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 456 OMX_EventCmdComplete,OMX_CommandFlush, 457 PORT_INDEX_IN,NULL ); 458 } 459 else if(BITMASK_PRESENT(&pThis->m_flags, 460 OMX_COMPONENT_IDLE_PENDING)) 461 { 462 if(!pThis->output_flush_progress) 463 { 464 printf("\n dev_stop called after input flush complete\n"); 465 if(dev_stop() != 0) 466 { 467 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n"); 468 pThis->omx_report_error (); 469 } 470 } 471 } 472 } 473 474 break; 475 476 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: 477 478 pThis->output_flush_progress = false; 479 DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", m_fbd_count); 480 m_fbd_count = 0; 481 if(pThis->m_pCallbacks.EventHandler) 482 { 483 /*Check if we need generate event for Flush done*/ 484 if(BITMASK_PRESENT(&pThis->m_flags, 485 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) 486 { 487 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 488 489 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 490 OMX_EventCmdComplete,OMX_CommandFlush, 491 PORT_INDEX_OUT,NULL ); 492 } 493 else if(BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) 494 { 495 printf("\n dev_stop called after Output flush complete\n"); 496 if(!pThis->input_flush_progress) 497 { 498 if(dev_stop() != 0) 499 { 500 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n"); 501 pThis->omx_report_error (); 502 } 503 } 504 } 505 } 506 break; 507 508 case OMX_COMPONENT_GENERATE_START_DONE: 509 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg"); 510 511 if(pThis->m_pCallbacks.EventHandler) 512 { 513 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); 514 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) 515 { 516 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Move to \ 517 executing"); 518 // Send the callback now 519 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 520 pThis->m_state = OMX_StateExecuting; 521 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 522 OMX_EventCmdComplete,OMX_CommandStateSet, 523 OMX_StateExecuting, NULL); 524 } 525 else if(BITMASK_PRESENT(&pThis->m_flags, 526 OMX_COMPONENT_PAUSE_PENDING)) 527 { 528 if(dev_pause()) 529 { 530 DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in Start Done!\n"); 531 pThis->omx_report_error (); 532 } 533 } 534 } 535 else 536 { 537 DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); 538 } 539 break; 540 541 case OMX_COMPONENT_GENERATE_PAUSE_DONE: 542 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE msg"); 543 if(pThis->m_pCallbacks.EventHandler) 544 { 545 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) 546 { 547 //Send the callback now 548 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); 549 pThis->m_state = OMX_StatePause; 550 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 551 OMX_EventCmdComplete,OMX_CommandStateSet, 552 OMX_StatePause, NULL); 553 } 554 } 555 556 break; 557 558 case OMX_COMPONENT_GENERATE_RESUME_DONE: 559 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_RESUME_DONE msg"); 560 if(pThis->m_pCallbacks.EventHandler) 561 { 562 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) 563 { 564 // Send the callback now 565 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 566 pThis->m_state = OMX_StateExecuting; 567 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 568 OMX_EventCmdComplete,OMX_CommandStateSet, 569 OMX_StateExecuting,NULL); 570 } 571 } 572 573 break; 574 575 case OMX_COMPONENT_GENERATE_STOP_DONE: 576 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE msg"); 577 if(pThis->m_pCallbacks.EventHandler) 578 { 579 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) 580 { 581 // Send the callback now 582 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); 583 pThis->m_state = OMX_StateIdle; 584 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data, 585 OMX_EventCmdComplete,OMX_CommandStateSet, 586 OMX_StateIdle,NULL); 587 } 588 } 589 590 break; 591 592 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: 593 DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n"); 594 pThis->omx_report_error (); 595 break; 596 597 default: 598 break; 599 } 600 } 601 602 pthread_mutex_lock(&pThis->m_lock); 603 qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\ 604 pThis->m_etb_q.m_size; 605 606 pthread_mutex_unlock(&pThis->m_lock); 607 608 } 609 while(qsize>0); 610 printf("\n exited the while loop\n"); 611 612 } 613 614 615 616 617 /* ====================================================================== 618 FUNCTION 619 omx_venc::GetComponentVersion 620 621 DESCRIPTION 622 Returns the component version. 623 624 PARAMETERS 625 TBD. 626 627 RETURN VALUE 628 OMX_ErrorNone. 629 630 ========================================================================== */ 631 OMX_ERRORTYPE omx_video::get_component_version 632 ( 633 OMX_IN OMX_HANDLETYPE hComp, 634 OMX_OUT OMX_STRING componentName, 635 OMX_OUT OMX_VERSIONTYPE* componentVersion, 636 OMX_OUT OMX_VERSIONTYPE* specVersion, 637 OMX_OUT OMX_UUIDTYPE* componentUUID 638 ) 639 { 640 if(m_state == OMX_StateInvalid) 641 { 642 DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n"); 643 return OMX_ErrorInvalidState; 644 } 645 /* TBD -- Return the proper version */ 646 return OMX_ErrorNone; 647 } 648 /* ====================================================================== 649 FUNCTION 650 omx_venc::SendCommand 651 652 DESCRIPTION 653 Returns zero if all the buffers released.. 654 655 PARAMETERS 656 None. 657 658 RETURN VALUE 659 true/false 660 661 ========================================================================== */ 662 OMX_ERRORTYPE omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp, 663 OMX_IN OMX_COMMANDTYPE cmd, 664 OMX_IN OMX_U32 param1, 665 OMX_IN OMX_PTR cmdData 666 ) 667 { 668 if(m_state == OMX_StateInvalid) 669 { 670 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); 671 return OMX_ErrorInvalidState; 672 } 673 674 if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable) 675 { 676 if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH)) 677 { 678 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n"); 679 return OMX_ErrorBadPortIndex; 680 } 681 } 682 if(cmd == OMX_CommandMarkBuffer) 683 { 684 if(param1 != PORT_INDEX_IN) 685 { 686 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n"); 687 return OMX_ErrorBadPortIndex; 688 } 689 if(!cmdData) 690 { 691 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null"); 692 return OMX_ErrorBadParameter; 693 } 694 } 695 696 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); 697 sem_wait(&m_cmd_lock); 698 return OMX_ErrorNone; 699 } 700 701 /* ====================================================================== 702 FUNCTION 703 omx_venc::SendCommand 704 705 DESCRIPTION 706 Returns zero if all the buffers released.. 707 708 PARAMETERS 709 None. 710 711 RETURN VALUE 712 true/false 713 714 ========================================================================== */ 715 OMX_ERRORTYPE omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, 716 OMX_IN OMX_COMMANDTYPE cmd, 717 OMX_IN OMX_U32 param1, 718 OMX_IN OMX_PTR cmdData 719 ) 720 { 721 OMX_ERRORTYPE eRet = OMX_ErrorNone; 722 OMX_STATETYPE eState = (OMX_STATETYPE) param1; 723 int bFlag = 1; 724 725 if(cmd == OMX_CommandStateSet) 726 { 727 /***************************/ 728 /* Current State is Loaded */ 729 /***************************/ 730 if(m_state == OMX_StateLoaded) 731 { 732 if(eState == OMX_StateIdle) 733 { 734 //if all buffers are allocated or all ports disabled 735 if(allocate_done() || 736 ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE)) 737 { 738 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle\n"); 739 } 740 else 741 { 742 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n"); 743 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); 744 // Skip the event notification 745 bFlag = 0; 746 } 747 } 748 /* Requesting transition from Loaded to Loaded */ 749 else if(eState == OMX_StateLoaded) 750 { 751 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded\n"); 752 post_event(OMX_EventError,OMX_ErrorSameState,\ 753 OMX_COMPONENT_GENERATE_EVENT); 754 eRet = OMX_ErrorSameState; 755 } 756 /* Requesting transition from Loaded to WaitForResources */ 757 else if(eState == OMX_StateWaitForResources) 758 { 759 /* Since error is None , we will post an event 760 at the end of this function definition */ 761 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources\n"); 762 } 763 /* Requesting transition from Loaded to Executing */ 764 else if(eState == OMX_StateExecuting) 765 { 766 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n"); 767 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 768 OMX_COMPONENT_GENERATE_EVENT); 769 eRet = OMX_ErrorIncorrectStateTransition; 770 } 771 /* Requesting transition from Loaded to Pause */ 772 else if(eState == OMX_StatePause) 773 { 774 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause\n"); 775 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 776 OMX_COMPONENT_GENERATE_EVENT); 777 eRet = OMX_ErrorIncorrectStateTransition; 778 } 779 /* Requesting transition from Loaded to Invalid */ 780 else if(eState == OMX_StateInvalid) 781 { 782 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid\n"); 783 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 784 eRet = OMX_ErrorInvalidState; 785 } 786 else 787 { 788 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid(%d Not Handled)\n",\ 789 eState); 790 eRet = OMX_ErrorBadParameter; 791 } 792 } 793 794 /***************************/ 795 /* Current State is IDLE */ 796 /***************************/ 797 else if(m_state == OMX_StateIdle) 798 { 799 if(eState == OMX_StateLoaded) 800 { 801 if(release_done()) 802 { 803 /* 804 Since error is None , we will post an event at the end 805 of this function definition 806 */ 807 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded\n"); 808 if(dev_stop() != 0) 809 { 810 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded"); 811 eRet = OMX_ErrorHardware; 812 } 813 } 814 else 815 { 816 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n"); 817 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); 818 // Skip the event notification 819 bFlag = 0; 820 } 821 } 822 /* Requesting transition from Idle to Executing */ 823 else if(eState == OMX_StateExecuting) 824 { 825 if( dev_start() ) 826 { 827 DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Exe\n"); 828 omx_report_error (); 829 eRet = OMX_ErrorHardware; 830 } 831 else 832 { 833 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); 834 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n"); 835 bFlag = 0; 836 } 837 838 } 839 /* Requesting transition from Idle to Idle */ 840 else if(eState == OMX_StateIdle) 841 { 842 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n"); 843 post_event(OMX_EventError,OMX_ErrorSameState,\ 844 OMX_COMPONENT_GENERATE_EVENT); 845 eRet = OMX_ErrorSameState; 846 } 847 /* Requesting transition from Idle to WaitForResources */ 848 else if(eState == OMX_StateWaitForResources) 849 { 850 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources\n"); 851 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 852 OMX_COMPONENT_GENERATE_EVENT); 853 eRet = OMX_ErrorIncorrectStateTransition; 854 } 855 /* Requesting transition from Idle to Pause */ 856 else if(eState == OMX_StatePause) 857 { 858 /*To pause the Video core we need to start the driver*/ 859 if( dev_start() ) 860 { 861 DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Pause\n"); 862 omx_report_error (); 863 eRet = OMX_ErrorHardware; 864 } 865 else 866 { 867 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 868 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n"); 869 bFlag = 0; 870 } 871 } 872 /* Requesting transition from Idle to Invalid */ 873 else if(eState == OMX_StateInvalid) 874 { 875 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n"); 876 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 877 eRet = OMX_ErrorInvalidState; 878 } 879 else 880 { 881 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",eState); 882 eRet = OMX_ErrorBadParameter; 883 } 884 } 885 886 /******************************/ 887 /* Current State is Executing */ 888 /******************************/ 889 else if(m_state == OMX_StateExecuting) 890 { 891 /* Requesting transition from Executing to Idle */ 892 if(eState == OMX_StateIdle) 893 { 894 /* Since error is None , we will post an event 895 at the end of this function definition 896 */ 897 DEBUG_PRINT_LOW("\n OMXCORE-SM: Executing --> Idle \n"); 898 //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle 899 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 900 execute_omx_flush(OMX_ALL); 901 bFlag = 0; 902 } 903 /* Requesting transition from Executing to Paused */ 904 else if(eState == OMX_StatePause) 905 { 906 907 if(dev_pause()) 908 { 909 DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n"); 910 post_event(OMX_EventError,OMX_ErrorHardware,\ 911 OMX_COMPONENT_GENERATE_EVENT); 912 eRet = OMX_ErrorHardware; 913 } 914 else 915 { 916 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 917 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n"); 918 bFlag = 0; 919 } 920 } 921 /* Requesting transition from Executing to Loaded */ 922 else if(eState == OMX_StateLoaded) 923 { 924 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n"); 925 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 926 OMX_COMPONENT_GENERATE_EVENT); 927 eRet = OMX_ErrorIncorrectStateTransition; 928 } 929 /* Requesting transition from Executing to WaitForResources */ 930 else if(eState == OMX_StateWaitForResources) 931 { 932 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n"); 933 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 934 OMX_COMPONENT_GENERATE_EVENT); 935 eRet = OMX_ErrorIncorrectStateTransition; 936 } 937 /* Requesting transition from Executing to Executing */ 938 else if(eState == OMX_StateExecuting) 939 { 940 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Executing \n"); 941 post_event(OMX_EventError,OMX_ErrorSameState,\ 942 OMX_COMPONENT_GENERATE_EVENT); 943 eRet = OMX_ErrorSameState; 944 } 945 /* Requesting transition from Executing to Invalid */ 946 else if(eState == OMX_StateInvalid) 947 { 948 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Invalid \n"); 949 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 950 eRet = OMX_ErrorInvalidState; 951 } 952 else 953 { 954 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",eState); 955 eRet = OMX_ErrorBadParameter; 956 } 957 } 958 /***************************/ 959 /* Current State is Pause */ 960 /***************************/ 961 else if(m_state == OMX_StatePause) 962 { 963 /* Requesting transition from Pause to Executing */ 964 if(eState == OMX_StateExecuting) 965 { 966 DEBUG_PRINT_LOW("\n Pause --> Executing \n"); 967 if( dev_resume() ) 968 { 969 post_event(OMX_EventError,OMX_ErrorHardware,\ 970 OMX_COMPONENT_GENERATE_EVENT); 971 eRet = OMX_ErrorHardware; 972 } 973 else 974 { 975 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); 976 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n"); 977 bFlag = 0; 978 } 979 } 980 /* Requesting transition from Pause to Idle */ 981 else if(eState == OMX_StateIdle) 982 { 983 /* Since error is None , we will post an event 984 at the end of this function definition */ 985 DEBUG_PRINT_LOW("\n Pause --> Idle \n"); 986 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 987 execute_omx_flush(OMX_ALL); 988 bFlag = 0; 989 } 990 /* Requesting transition from Pause to loaded */ 991 else if(eState == OMX_StateLoaded) 992 { 993 DEBUG_PRINT_ERROR("\nERROR: Pause --> loaded \n"); 994 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 995 OMX_COMPONENT_GENERATE_EVENT); 996 eRet = OMX_ErrorIncorrectStateTransition; 997 } 998 /* Requesting transition from Pause to WaitForResources */ 999 else if(eState == OMX_StateWaitForResources) 1000 { 1001 DEBUG_PRINT_ERROR("\nERROR: Pause --> WaitForResources \n"); 1002 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1003 OMX_COMPONENT_GENERATE_EVENT); 1004 eRet = OMX_ErrorIncorrectStateTransition; 1005 } 1006 /* Requesting transition from Pause to Pause */ 1007 else if(eState == OMX_StatePause) 1008 { 1009 DEBUG_PRINT_ERROR("\nERROR: Pause --> Pause \n"); 1010 post_event(OMX_EventError,OMX_ErrorSameState,\ 1011 OMX_COMPONENT_GENERATE_EVENT); 1012 eRet = OMX_ErrorSameState; 1013 } 1014 /* Requesting transition from Pause to Invalid */ 1015 else if(eState == OMX_StateInvalid) 1016 { 1017 DEBUG_PRINT_ERROR("\nERROR: Pause --> Invalid \n"); 1018 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1019 eRet = OMX_ErrorInvalidState; 1020 } 1021 else 1022 { 1023 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",eState); 1024 eRet = OMX_ErrorBadParameter; 1025 } 1026 } 1027 /***************************/ 1028 /* Current State is WaitForResources */ 1029 /***************************/ 1030 else if(m_state == OMX_StateWaitForResources) 1031 { 1032 /* Requesting transition from WaitForResources to Loaded */ 1033 if(eState == OMX_StateLoaded) 1034 { 1035 /* Since error is None , we will post an event 1036 at the end of this function definition */ 1037 DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded\n"); 1038 } 1039 /* Requesting transition from WaitForResources to WaitForResources */ 1040 else if(eState == OMX_StateWaitForResources) 1041 { 1042 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n"); 1043 post_event(OMX_EventError,OMX_ErrorSameState, 1044 OMX_COMPONENT_GENERATE_EVENT); 1045 eRet = OMX_ErrorSameState; 1046 } 1047 /* Requesting transition from WaitForResources to Executing */ 1048 else if(eState == OMX_StateExecuting) 1049 { 1050 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing\n"); 1051 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1052 OMX_COMPONENT_GENERATE_EVENT); 1053 eRet = OMX_ErrorIncorrectStateTransition; 1054 } 1055 /* Requesting transition from WaitForResources to Pause */ 1056 else if(eState == OMX_StatePause) 1057 { 1058 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause\n"); 1059 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1060 OMX_COMPONENT_GENERATE_EVENT); 1061 eRet = OMX_ErrorIncorrectStateTransition; 1062 } 1063 /* Requesting transition from WaitForResources to Invalid */ 1064 else if(eState == OMX_StateInvalid) 1065 { 1066 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid\n"); 1067 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1068 eRet = OMX_ErrorInvalidState; 1069 } 1070 /* Requesting transition from WaitForResources to Loaded - 1071 is NOT tested by Khronos TS */ 1072 1073 } 1074 else 1075 { 1076 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)\n",m_state,eState); 1077 eRet = OMX_ErrorBadParameter; 1078 } 1079 } 1080 /********************************/ 1081 /* Current State is Invalid */ 1082 /*******************************/ 1083 else if(m_state == OMX_StateInvalid) 1084 { 1085 /* State Transition from Inavlid to any state */ 1086 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources 1087 || OMX_StateIdle || OMX_StateExecuting 1088 || OMX_StatePause || OMX_StateInvalid)) 1089 { 1090 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded\n"); 1091 post_event(OMX_EventError,OMX_ErrorInvalidState,\ 1092 OMX_COMPONENT_GENERATE_EVENT); 1093 eRet = OMX_ErrorInvalidState; 1094 } 1095 } 1096 else if(cmd == OMX_CommandFlush) 1097 { 1098 if(0 == param1 || OMX_ALL == param1) 1099 { 1100 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); 1101 } 1102 if(1 == param1 || OMX_ALL == param1) 1103 { 1104 //generate output flush event only. 1105 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 1106 } 1107 1108 execute_omx_flush(param1); 1109 bFlag = 0; 1110 } 1111 else if( cmd == OMX_CommandPortEnable) 1112 { 1113 if(param1 == PORT_INDEX_IN || param1 == OMX_ALL) 1114 { 1115 m_sInPortDef.bEnabled = OMX_TRUE; 1116 1117 if( (m_state == OMX_StateLoaded && 1118 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 1119 || allocate_input_done()) 1120 { 1121 post_event(OMX_CommandPortEnable,PORT_INDEX_IN, 1122 OMX_COMPONENT_GENERATE_EVENT); 1123 } 1124 else 1125 { 1126 DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n"); 1127 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); 1128 // Skip the event notification 1129 bFlag = 0; 1130 } 1131 } 1132 if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL) 1133 { 1134 m_sOutPortDef.bEnabled = OMX_TRUE; 1135 1136 if( (m_state == OMX_StateLoaded && 1137 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 1138 || (allocate_output_done())) 1139 { 1140 post_event(OMX_CommandPortEnable,PORT_INDEX_OUT, 1141 OMX_COMPONENT_GENERATE_EVENT); 1142 1143 } 1144 else 1145 { 1146 DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n"); 1147 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 1148 // Skip the event notification 1149 bFlag = 0; 1150 } 1151 } 1152 } 1153 else if(cmd == OMX_CommandPortDisable) 1154 { 1155 if(param1 == PORT_INDEX_IN || param1 == OMX_ALL) 1156 { 1157 m_sInPortDef.bEnabled = OMX_FALSE; 1158 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 1159 && release_input_done()) 1160 { 1161 post_event(OMX_CommandPortDisable,PORT_INDEX_IN, 1162 OMX_COMPONENT_GENERATE_EVENT); 1163 } 1164 else 1165 { 1166 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); 1167 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) 1168 { 1169 execute_omx_flush(PORT_INDEX_IN); 1170 } 1171 1172 // Skip the event notification 1173 bFlag = 0; 1174 } 1175 } 1176 if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL) 1177 { 1178 m_sOutPortDef.bEnabled = OMX_FALSE; 1179 1180 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 1181 && release_output_done()) 1182 { 1183 post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\ 1184 OMX_COMPONENT_GENERATE_EVENT); 1185 } 1186 else 1187 { 1188 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 1189 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) 1190 { 1191 execute_omx_flush(PORT_INDEX_OUT); 1192 } 1193 // Skip the event notification 1194 bFlag = 0; 1195 1196 } 1197 } 1198 } 1199 else 1200 { 1201 DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)\n",cmd); 1202 eRet = OMX_ErrorNotImplemented; 1203 } 1204 if(eRet == OMX_ErrorNone && bFlag) 1205 { 1206 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); 1207 } 1208 sem_post(&m_cmd_lock); 1209 return eRet; 1210 } 1211 1212 /* ====================================================================== 1213 FUNCTION 1214 omx_venc::ExecuteOmxFlush 1215 1216 DESCRIPTION 1217 Executes the OMX flush. 1218 1219 PARAMETERS 1220 flushtype - input flush(1)/output flush(0)/ both. 1221 1222 RETURN VALUE 1223 true/false 1224 1225 ========================================================================== */ 1226 bool omx_video::execute_omx_flush(OMX_U32 flushType) 1227 { 1228 bool bRet = false; 1229 DEBUG_PRINT_LOW("\n execute_omx_flush - %d\n", flushType); 1230 if(flushType == 0 || flushType == OMX_ALL) 1231 { 1232 input_flush_progress = true; 1233 //flush input only 1234 bRet = execute_input_flush(); 1235 } 1236 if(flushType == 1 || flushType == OMX_ALL) 1237 { 1238 //flush output only 1239 output_flush_progress = true; 1240 bRet = execute_output_flush(); 1241 } 1242 return bRet; 1243 } 1244 /*========================================================================= 1245 FUNCTION : execute_output_flush 1246 1247 DESCRIPTION 1248 Executes the OMX flush at OUTPUT PORT. 1249 1250 PARAMETERS 1251 None. 1252 1253 RETURN VALUE 1254 true/false 1255 ==========================================================================*/ 1256 bool omx_video::execute_output_flush(void) 1257 { 1258 unsigned p1 = 0; // Parameter - 1 1259 unsigned p2 = 0; // Parameter - 2 1260 unsigned ident = 0; 1261 bool bRet = true; 1262 1263 /*Generate FBD for all Buffers in the FTBq*/ 1264 DEBUG_PRINT_LOW("\n execute_output_flush\n"); 1265 pthread_mutex_lock(&m_lock); 1266 while(m_ftb_q.m_size) 1267 { 1268 m_ftb_q.pop_entry(&p1,&p2,&ident); 1269 1270 if(ident == OMX_COMPONENT_GENERATE_FTB ) 1271 { 1272 pending_output_buffers++; 1273 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 1274 } 1275 else if(ident == OMX_COMPONENT_GENERATE_FBD) 1276 { 1277 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 1278 } 1279 } 1280 1281 pthread_mutex_unlock(&m_lock); 1282 /*Check if there are buffers with the Driver*/ 1283 if(dev_flush(PORT_INDEX_OUT)) 1284 { 1285 DEBUG_PRINT_ERROR("\nERROR: o/p dev_flush() Failed"); 1286 return false; 1287 } 1288 1289 return bRet; 1290 } 1291 /*========================================================================= 1292 FUNCTION : execute_input_flush 1293 1294 DESCRIPTION 1295 Executes the OMX flush at INPUT PORT. 1296 1297 PARAMETERS 1298 None. 1299 1300 RETURN VALUE 1301 true/false 1302 ==========================================================================*/ 1303 bool omx_video::execute_input_flush(void) 1304 { 1305 unsigned p1 = 0; // Parameter - 1 1306 unsigned p2 = 0; // Parameter - 2 1307 unsigned ident = 0; 1308 bool bRet = true; 1309 1310 /*Generate EBD for all Buffers in the ETBq*/ 1311 DEBUG_PRINT_LOW("\n execute_input_flush\n"); 1312 1313 pthread_mutex_lock(&m_lock); 1314 while(m_etb_q.m_size) 1315 { 1316 m_etb_q.pop_entry(&p1,&p2,&ident); 1317 if(ident == OMX_COMPONENT_GENERATE_ETB) 1318 { 1319 pending_input_buffers++; 1320 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 1321 } 1322 else if(ident == OMX_COMPONENT_GENERATE_EBD) 1323 { 1324 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 1325 } 1326 } 1327 1328 pthread_mutex_unlock(&m_lock); 1329 /*Check if there are buffers with the Driver*/ 1330 if(dev_flush(PORT_INDEX_IN)) 1331 { 1332 DEBUG_PRINT_ERROR("\nERROR: i/p dev_flush() Failed"); 1333 return false; 1334 } 1335 1336 return bRet; 1337 } 1338 1339 1340 /* ====================================================================== 1341 FUNCTION 1342 omx_venc::SendCommandEvent 1343 1344 DESCRIPTION 1345 Send the event to decoder pipe. This is needed to generate the callbacks 1346 in decoder thread context. 1347 1348 PARAMETERS 1349 None. 1350 1351 RETURN VALUE 1352 true/false 1353 1354 ========================================================================== */ 1355 bool omx_video::post_event(unsigned int p1, 1356 unsigned int p2, 1357 unsigned int id) 1358 { 1359 bool bRet = false; 1360 1361 1362 pthread_mutex_lock(&m_lock); 1363 1364 if( id == OMX_COMPONENT_GENERATE_FTB || \ 1365 (id == OMX_COMPONENT_GENERATE_FRAME_DONE)) 1366 { 1367 m_ftb_q.insert_entry(p1,p2,id); 1368 } 1369 else if((id == OMX_COMPONENT_GENERATE_ETB) \ 1370 || (id == OMX_COMPONENT_GENERATE_EBD)) 1371 { 1372 m_etb_q.insert_entry(p1,p2,id); 1373 } 1374 else 1375 { 1376 m_cmd_q.insert_entry(p1,p2,id); 1377 } 1378 1379 bRet = true; 1380 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this); 1381 post_message(this, id); 1382 pthread_mutex_unlock(&m_lock); 1383 1384 return bRet; 1385 } 1386 1387 /* ====================================================================== 1388 FUNCTION 1389 omx_venc::GetParameter 1390 1391 DESCRIPTION 1392 OMX Get Parameter method implementation 1393 1394 PARAMETERS 1395 <TBD>. 1396 1397 RETURN VALUE 1398 Error None if successful. 1399 1400 ========================================================================== */ 1401 OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, 1402 OMX_IN OMX_INDEXTYPE paramIndex, 1403 OMX_INOUT OMX_PTR paramData) 1404 { 1405 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1406 unsigned int height=0,width = 0; 1407 1408 DEBUG_PRINT_LOW("get_parameter: \n"); 1409 if(m_state == OMX_StateInvalid) 1410 { 1411 DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n"); 1412 return OMX_ErrorInvalidState; 1413 } 1414 if(paramData == NULL) 1415 { 1416 DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n"); 1417 return OMX_ErrorBadParameter; 1418 } 1419 switch(paramIndex) 1420 { 1421 case OMX_IndexParamPortDefinition: 1422 { 1423 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 1424 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 1425 1426 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); 1427 if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) 1428 { 1429 DEBUG_PRINT_LOW("\n i/p actual cnt = %d\n", m_sInPortDef.nBufferCountActual); 1430 DEBUG_PRINT_LOW("\n i/p min cnt = %d\n", m_sInPortDef.nBufferCountMin); 1431 memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef)); 1432 } 1433 else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 1434 { 1435 DEBUG_PRINT_LOW("\n o/p actual cnt = %d\n", m_sOutPortDef.nBufferCountActual); 1436 DEBUG_PRINT_LOW("\n o/p min cnt = %d\n", m_sOutPortDef.nBufferCountMin); 1437 memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef)); 1438 } 1439 else 1440 { 1441 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); 1442 eRet = OMX_ErrorBadPortIndex; 1443 } 1444 break; 1445 } 1446 case OMX_IndexParamVideoInit: 1447 { 1448 OMX_PORT_PARAM_TYPE *portParamType = 1449 (OMX_PORT_PARAM_TYPE *) paramData; 1450 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); 1451 1452 memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam)); 1453 break; 1454 } 1455 case OMX_IndexParamVideoPortFormat: 1456 { 1457 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 1458 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 1459 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); 1460 1461 if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) 1462 { 1463 memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat)); 1464 } 1465 else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 1466 { 1467 memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat)); 1468 } 1469 else 1470 { 1471 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); 1472 eRet = OMX_ErrorBadPortIndex; 1473 } 1474 break; 1475 } 1476 case OMX_IndexParamVideoBitrate: 1477 { 1478 OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; 1479 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n"); 1480 1481 if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 1482 { 1483 memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate)); 1484 } 1485 else 1486 { 1487 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); 1488 eRet = OMX_ErrorBadPortIndex; 1489 } 1490 1491 break; 1492 } 1493 case OMX_IndexParamVideoMpeg4: 1494 { 1495 OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; 1496 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n"); 1497 memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4)); 1498 break; 1499 } 1500 case OMX_IndexParamVideoH263: 1501 { 1502 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; 1503 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n"); 1504 memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263)); 1505 break; 1506 } 1507 case OMX_IndexParamVideoAvc: 1508 { 1509 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; 1510 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n"); 1511 memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC)); 1512 break; 1513 } 1514 case OMX_IndexParamVideoProfileLevelQuerySupported: 1515 { 1516 1517 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; 1518 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n"); 1519 //TODO include all the profiles and corresponding levels 1520 if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) 1521 { 1522 static const OMX_U32 MPEG4Profile[][2] = 1523 { { (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple, (OMX_U32) OMX_VIDEO_MPEG4Level0}, 1524 { (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple, (OMX_U32) OMX_VIDEO_MPEG4Level0b}, 1525 { (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple, (OMX_U32) OMX_VIDEO_MPEG4Level1}, 1526 { (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple, (OMX_U32) OMX_VIDEO_MPEG4Level2}, 1527 { (OMX_U32) OMX_VIDEO_MPEG4ProfileSimple, (OMX_U32) OMX_VIDEO_MPEG4Level3}}; 1528 1529 static const OMX_U32 nSupport = sizeof(MPEG4Profile) / (sizeof(OMX_U32) * 2); 1530 if(pParam->nProfileIndex >= 0 && pParam->nProfileIndex < nSupport) 1531 { 1532 pParam->eProfile = (OMX_VIDEO_MPEG4PROFILETYPE) MPEG4Profile[pParam->nProfileIndex][0]; 1533 pParam->eLevel = (OMX_VIDEO_MPEG4LEVELTYPE) MPEG4Profile[pParam->nProfileIndex][1]; 1534 } 1535 else 1536 { 1537 eRet = OMX_ErrorNoMore; 1538 } 1539 } 1540 else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) 1541 { 1542 static const OMX_U32 H263Profile[][2] = 1543 { { (OMX_U32) OMX_VIDEO_H263ProfileBaseline, (OMX_U32) OMX_VIDEO_H263Level10}, 1544 { (OMX_U32) OMX_VIDEO_H263ProfileBaseline, (OMX_U32) OMX_VIDEO_H263Level20}, 1545 { (OMX_U32) OMX_VIDEO_H263ProfileBaseline, (OMX_U32) OMX_VIDEO_H263Level30}, 1546 { (OMX_U32) OMX_VIDEO_H263ProfileBaseline, (OMX_U32) OMX_VIDEO_H263Level45}, 1547 { (OMX_U32) OMX_VIDEO_H263ProfileISWV2, (OMX_U32) OMX_VIDEO_H263Level10}, 1548 { (OMX_U32) OMX_VIDEO_H263ProfileISWV2, (OMX_U32) OMX_VIDEO_H263Level45}}; 1549 1550 static const OMX_U32 nSupport = sizeof(H263Profile) / (sizeof(OMX_U32) * 2); 1551 if(pParam->nProfileIndex >= 0 && pParam->nProfileIndex < nSupport) 1552 { 1553 pParam->eProfile = (OMX_VIDEO_H263PROFILETYPE) H263Profile[pParam->nProfileIndex][0]; 1554 pParam->eLevel = (OMX_VIDEO_H263LEVELTYPE) H263Profile[pParam->nProfileIndex][1]; 1555 } 1556 else 1557 { 1558 eRet = OMX_ErrorNoMore; 1559 } 1560 } 1561 else if(m_sOutPortDef.format.video.eCompressionFormat = OMX_VIDEO_CodingAVC) 1562 { 1563 //TODO 1564 } 1565 break; 1566 } 1567 case OMX_IndexParamVideoProfileLevelCurrent: 1568 { 1569 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; 1570 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n"); 1571 memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel)); 1572 break; 1573 } 1574 /*Component should support this port definition*/ 1575 case OMX_IndexParamAudioInit: 1576 { 1577 OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData; 1578 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); 1579 memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio)); 1580 break; 1581 } 1582 /*Component should support this port definition*/ 1583 case OMX_IndexParamImageInit: 1584 { 1585 OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData; 1586 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); 1587 memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img)); 1588 break; 1589 1590 } 1591 /*Component should support this port definition*/ 1592 case OMX_IndexParamOtherInit: 1593 { 1594 DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x\n", paramIndex); 1595 eRet =OMX_ErrorUnsupportedIndex; 1596 break; 1597 } 1598 case OMX_IndexParamStandardComponentRole: 1599 { 1600 OMX_PARAM_COMPONENTROLETYPE *comp_role; 1601 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 1602 comp_role->nVersion.nVersion = OMX_SPEC_VERSION; 1603 comp_role->nSize = sizeof(*comp_role); 1604 1605 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",paramIndex); 1606 if(NULL != comp_role->cRole) 1607 { 1608 strncpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE); 1609 } 1610 else 1611 { 1612 DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role\n",paramIndex); 1613 eRet =OMX_ErrorBadParameter; 1614 } 1615 break; 1616 } 1617 /* Added for parameter test */ 1618 case OMX_IndexParamPriorityMgmt: 1619 { 1620 1621 OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData; 1622 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); 1623 memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt)); 1624 break; 1625 } 1626 /* Added for parameter test */ 1627 case OMX_IndexParamCompBufferSupplier: 1628 { 1629 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 1630 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); 1631 if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN) 1632 { 1633 memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier)); 1634 } 1635 else if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT) 1636 { 1637 memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier)); 1638 } 1639 else 1640 { 1641 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); 1642 eRet = OMX_ErrorBadPortIndex; 1643 } 1644 break; 1645 } 1646 1647 case OMX_IndexParamVideoQuantization: 1648 { 1649 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; 1650 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization\n"); 1651 memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization)); 1652 break; 1653 } 1654 1655 case OMX_QcomIndexPortDefn: 1656 //TODO 1657 break; 1658 case OMX_COMPONENT_CAPABILITY_TYPE_INDEX: 1659 { 1660 OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData); 1661 DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX\n"); 1662 pParam->iIsOMXComponentMultiThreaded = OMX_TRUE; 1663 pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE; 1664 pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; 1665 pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE; 1666 pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE; 1667 pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE; 1668 pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE; 1669 pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE; 1670 m_use_input_pmem = OMX_TRUE; 1671 DEBUG_PRINT_LOW("Supporting capability index in encoder node"); 1672 break; 1673 } 1674 case OMX_IndexParamVideoSliceFMO: 1675 { 1676 OMX_VIDEO_PARAM_AVCSLICEFMO *avc_slice_fmo = (OMX_VIDEO_PARAM_AVCSLICEFMO*)paramData; 1677 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoSliceFMO\n"); 1678 if(!strncmp((char *)m_nkind, "OMX.qcom.video.encoder.avc",\ 1679 OMX_MAX_STRINGNAME_SIZE)) 1680 { 1681 memcpy(avc_slice_fmo, &m_sAVCSliceFMO, sizeof(m_sAVCSliceFMO)); 1682 } 1683 else 1684 { 1685 DEBUG_PRINT_ERROR("ERROR: get_parameter: AVCSliceFMO queried non-AVC codec\n"); 1686 eRet = OMX_ErrorBadParameter; 1687 } 1688 break; 1689 } 1690 default: 1691 { 1692 DEBUG_PRINT_ERROR("ERROR: get_parameter: unknown param %08x\n", paramIndex); 1693 eRet =OMX_ErrorUnsupportedIndex; 1694 break; 1695 } 1696 1697 } 1698 1699 return eRet; 1700 1701 } 1702 /* ====================================================================== 1703 FUNCTION 1704 omx_video::GetConfig 1705 1706 DESCRIPTION 1707 OMX Get Config Method implementation. 1708 1709 PARAMETERS 1710 <TBD>. 1711 1712 RETURN VALUE 1713 OMX Error None if successful. 1714 1715 ========================================================================== */ 1716 OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, 1717 OMX_IN OMX_INDEXTYPE configIndex, 1718 OMX_INOUT OMX_PTR configData) 1719 { 1720 //////////////////////////////////////////////////////////////// 1721 // Supported Config Index Type 1722 // ============================================================= 1723 // OMX_IndexConfigVideoBitrate OMX_VIDEO_CONFIG_BITRATETYPE 1724 // OMX_IndexConfigVideoFramerate OMX_CONFIG_FRAMERATETYPE 1725 // OMX_IndexConfigCommonRotate OMX_CONFIG_ROTATIONTYPE 1726 //////////////////////////////////////////////////////////////// 1727 1728 if(configData == NULL) 1729 { 1730 DEBUG_PRINT_ERROR("ERROR: param is null"); 1731 return OMX_ErrorBadParameter; 1732 } 1733 1734 if(m_state == OMX_StateInvalid) 1735 { 1736 DEBUG_PRINT_ERROR("ERROR: can't be in invalid state"); 1737 return OMX_ErrorIncorrectStateOperation; 1738 } 1739 1740 //@todo need to validate params 1741 switch(configIndex) 1742 { 1743 case OMX_IndexConfigVideoBitrate: 1744 { 1745 OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData); 1746 memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate)); 1747 break; 1748 } 1749 case OMX_IndexConfigVideoFramerate: 1750 { 1751 OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData); 1752 if(m_state != OMX_StateLoaded) 1753 { 1754 // we only allow this at init time! 1755 DEBUG_PRINT_ERROR("ERROR: frame rate can only be configured in loaded state"); 1756 return OMX_ErrorIncorrectStateOperation; 1757 } 1758 memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate)); 1759 break; 1760 } 1761 case OMX_IndexConfigCommonRotate: 1762 { 1763 OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData); 1764 if(m_state != OMX_StateLoaded) 1765 { 1766 // we only allow this at init time! 1767 DEBUG_PRINT_ERROR("ERROR: frame rate can only be configured in loaded state",0,0,0); 1768 return OMX_ErrorIncorrectStateOperation; 1769 } 1770 memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation)); 1771 break; 1772 } 1773 default: 1774 DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); 1775 return OMX_ErrorUnsupportedIndex; 1776 } 1777 return OMX_ErrorNone; 1778 1779 } 1780 1781 /* ====================================================================== 1782 FUNCTION 1783 omx_video::GetExtensionIndex 1784 1785 DESCRIPTION 1786 OMX GetExtensionIndex method implementaion. <TBD> 1787 1788 PARAMETERS 1789 <TBD>. 1790 1791 RETURN VALUE 1792 OMX Error None if everything successful. 1793 1794 ========================================================================== */ 1795 OMX_ERRORTYPE omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, 1796 OMX_IN OMX_STRING paramName, 1797 OMX_OUT OMX_INDEXTYPE* indexType) 1798 { 1799 DEBUG_PRINT_ERROR("ERROR: get_extension_index: Error, Not implemented\n"); 1800 if(m_state == OMX_StateInvalid) 1801 { 1802 DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State\n"); 1803 return OMX_ErrorInvalidState; 1804 } 1805 return OMX_ErrorNotImplemented; 1806 } 1807 1808 /* ====================================================================== 1809 FUNCTION 1810 omx_video::GetState 1811 1812 DESCRIPTION 1813 Returns the state information back to the caller.<TBD> 1814 1815 PARAMETERS 1816 <TBD>. 1817 1818 RETURN VALUE 1819 Error None if everything is successful. 1820 ========================================================================== */ 1821 OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp, 1822 OMX_OUT OMX_STATETYPE* state) 1823 { 1824 *state = m_state; 1825 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); 1826 return OMX_ErrorNone; 1827 } 1828 1829 /* ====================================================================== 1830 FUNCTION 1831 omx_video::ComponentTunnelRequest 1832 1833 DESCRIPTION 1834 OMX Component Tunnel Request method implementation. <TBD> 1835 1836 PARAMETERS 1837 None. 1838 1839 RETURN VALUE 1840 OMX Error None if everything successful. 1841 1842 ========================================================================== */ 1843 OMX_ERRORTYPE omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, 1844 OMX_IN OMX_U32 port, 1845 OMX_IN OMX_HANDLETYPE peerComponent, 1846 OMX_IN OMX_U32 peerPort, 1847 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) 1848 { 1849 DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented\n"); 1850 return OMX_ErrorNotImplemented; 1851 } 1852 1853 /* ====================================================================== 1854 FUNCTION 1855 omx_video::UseInputBuffer 1856 1857 DESCRIPTION 1858 Helper function for Use buffer in the input pin 1859 1860 PARAMETERS 1861 None. 1862 1863 RETURN VALUE 1864 true/false 1865 1866 ========================================================================== */ 1867 OMX_ERRORTYPE omx_video::use_input_buffer( 1868 OMX_IN OMX_HANDLETYPE hComp, 1869 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 1870 OMX_IN OMX_U32 port, 1871 OMX_IN OMX_PTR appData, 1872 OMX_IN OMX_U32 bytes, 1873 OMX_IN OMX_U8* buffer) 1874 { 1875 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1876 1877 unsigned i = 0; 1878 unsigned char *buf_addr = NULL; 1879 1880 DEBUG_PRINT_HIGH("use_input_buffer: port = %d appData = %p bytes = %d buffer = %p",port,appData,bytes,buffer); 1881 if(bytes != m_sInPortDef.nBufferSize) 1882 { 1883 DEBUG_PRINT_ERROR("\nERROR: use_input_buffer: Size Mismatch!! " 1884 "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sInPortDef.nBufferSize); 1885 return OMX_ErrorBadParameter; 1886 } 1887 1888 if(!m_inp_mem_ptr) 1889 { 1890 input_use_buffer = true; 1891 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 1892 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); 1893 if(m_inp_mem_ptr == NULL) 1894 { 1895 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr"); 1896 return OMX_ErrorInsufficientResources; 1897 } 1898 1899 m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); 1900 if(m_pInput_pmem == NULL) 1901 { 1902 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem"); 1903 return OMX_ErrorInsufficientResources; 1904 } 1905 for(i=0; i< m_sInPortDef.nBufferCountActual; i++) 1906 { 1907 m_pInput_pmem[i].fd = -1; 1908 } 1909 1910 } 1911 1912 for(i=0; i< m_sInPortDef.nBufferCountActual; i++) 1913 { 1914 if(BITMASK_ABSENT(&m_inp_bm_count,i)) 1915 { 1916 break; 1917 } 1918 } 1919 1920 if(i < m_sInPortDef.nBufferCountActual) 1921 { 1922 1923 *bufferHdr = (m_inp_mem_ptr + i); 1924 BITMASK_SET(&m_inp_bm_count,i); 1925 1926 (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; 1927 (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); 1928 (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; 1929 (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; 1930 (*bufferHdr)->pAppPrivate = appData; 1931 (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; 1932 1933 if(!m_use_input_pmem) 1934 { 1935 m_pInput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 1936 if(m_pInput_pmem[i].fd == 0) 1937 { 1938 m_pInput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 1939 } 1940 1941 if(m_pInput_pmem[i] .fd < 0) 1942 { 1943 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed"); 1944 return OMX_ErrorInsufficientResources; 1945 } 1946 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; 1947 m_pInput_pmem[i].offset = 0; 1948 m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, 1949 MAP_SHARED,m_pInput_pmem[i].fd,0); 1950 1951 if(m_pInput_pmem[i].buffer == MAP_FAILED) 1952 { 1953 DEBUG_PRINT_ERROR("\nERROR: mmap() Failed"); 1954 return OMX_ErrorInsufficientResources; 1955 } 1956 } 1957 else 1958 { 1959 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate); 1960 DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset); 1961 1962 if(pParam) 1963 { 1964 m_pInput_pmem[i].fd = pParam->pmem_fd; 1965 m_pInput_pmem[i].offset = pParam->offset; 1966 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; 1967 m_pInput_pmem[i].buffer = (unsigned char *)buffer; 1968 DEBUG_PRINT_LOW("\n DBG:: pParam->pmem_fd = %u, pParam->offset = %u", 1969 pParam->pmem_fd, pParam->offset); 1970 } 1971 else 1972 { 1973 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case"); 1974 return OMX_ErrorBadParameter; 1975 } 1976 } 1977 1978 DEBUG_PRINT_LOW("\n use_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p", 1979 (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer); 1980 if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN) != true) 1981 { 1982 DEBUG_PRINT_ERROR("\nERROR: dev_use_buf() Failed for i/p buf"); 1983 return OMX_ErrorInsufficientResources; 1984 } 1985 } 1986 else 1987 { 1988 DEBUG_PRINT_ERROR("\nERROR: All buffers are already used, invalid use_buf call for " 1989 "index = %u", i); 1990 eRet = OMX_ErrorInsufficientResources; 1991 } 1992 1993 return eRet; 1994 } 1995 1996 1997 1998 /* ====================================================================== 1999 FUNCTION 2000 omx_video::UseOutputBuffer 2001 2002 DESCRIPTION 2003 Helper function for Use buffer in the input pin 2004 2005 PARAMETERS 2006 None. 2007 2008 RETURN VALUE 2009 true/false 2010 2011 ========================================================================== */ 2012 OMX_ERRORTYPE omx_video::use_output_buffer( 2013 OMX_IN OMX_HANDLETYPE hComp, 2014 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2015 OMX_IN OMX_U32 port, 2016 OMX_IN OMX_PTR appData, 2017 OMX_IN OMX_U32 bytes, 2018 OMX_IN OMX_U8* buffer) 2019 { 2020 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2021 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 2022 unsigned i= 0; // Temporary counter 2023 unsigned char *buf_addr = NULL; 2024 2025 DEBUG_PRINT_HIGH("\n Inside use_output_buffer()"); 2026 if(bytes != m_sOutPortDef.nBufferSize) 2027 { 2028 DEBUG_PRINT_ERROR("\nERROR: use_output_buffer: Size Mismatch!! " 2029 "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sOutPortDef.nBufferSize); 2030 return OMX_ErrorBadParameter; 2031 } 2032 2033 if(!m_out_mem_ptr) 2034 { 2035 output_use_buffer = true; 2036 int nBufHdrSize = 0; 2037 2038 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual); 2039 nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); 2040 /* 2041 * Memory for output side involves the following: 2042 * 1. Array of Buffer Headers 2043 * 2. Bitmask array to hold the buffer allocation details 2044 * In order to minimize the memory management entire allocation 2045 * is done in one step. 2046 */ 2047 //OMX Buffer header 2048 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 2049 if(m_out_mem_ptr == NULL) 2050 { 2051 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_out_mem_ptr"); 2052 return OMX_ErrorInsufficientResources; 2053 } 2054 2055 m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual); 2056 if(m_pOutput_pmem == NULL) 2057 { 2058 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem"); 2059 return OMX_ErrorInsufficientResources; 2060 } 2061 2062 if(m_out_mem_ptr) 2063 { 2064 bufHdr = m_out_mem_ptr; 2065 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); 2066 2067 // Settting the entire storage nicely 2068 for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) 2069 { 2070 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2071 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 2072 bufHdr->nAllocLen = bytes; 2073 bufHdr->nFilledLen = 0; 2074 bufHdr->pAppPrivate = appData; 2075 bufHdr->nOutputPortIndex = PORT_INDEX_OUT; 2076 bufHdr->pBuffer = NULL; 2077 bufHdr++; 2078 m_pOutput_pmem[i].fd = -1; 2079 } 2080 } 2081 else 2082 { 2083 DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%x]\n",m_out_mem_ptr); 2084 eRet = OMX_ErrorInsufficientResources; 2085 } 2086 } 2087 2088 for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) 2089 { 2090 if(BITMASK_ABSENT(&m_out_bm_count,i)) 2091 { 2092 break; 2093 } 2094 } 2095 2096 if(eRet == OMX_ErrorNone) 2097 { 2098 if(i < m_sOutPortDef.nBufferCountActual) 2099 { 2100 *bufferHdr = (m_out_mem_ptr + i ); 2101 (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; 2102 BITMASK_SET(&m_out_bm_count,i); 2103 2104 if(!m_use_output_pmem) 2105 { 2106 m_pOutput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 2107 2108 if(m_pOutput_pmem[i].fd == 0) 2109 { 2110 m_pOutput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 2111 } 2112 2113 if(m_pOutput_pmem[i].fd < 0) 2114 { 2115 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed"); 2116 return OMX_ErrorInsufficientResources; 2117 } 2118 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; 2119 m_pOutput_pmem[i].offset = 0; 2120 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, 2121 MAP_SHARED,m_pOutput_pmem[i].fd,0); 2122 if(m_pOutput_pmem[i].buffer == MAP_FAILED) 2123 { 2124 DEBUG_PRINT_ERROR("\nERROR: mmap() Failed"); 2125 return OMX_ErrorInsufficientResources; 2126 } 2127 } 2128 else 2129 { 2130 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate); 2131 DEBUG_PRINT_LOW("Inside qcom_ext pParam:0x%x )", pParam); 2132 2133 if(pParam) 2134 { 2135 DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset); 2136 m_pOutput_pmem[i].fd = pParam->pmem_fd; 2137 m_pOutput_pmem[i].offset = pParam->offset; 2138 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; 2139 m_pOutput_pmem[i].buffer = (unsigned char *)buffer; 2140 } 2141 else 2142 { 2143 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case"); 2144 return OMX_ErrorBadParameter; 2145 } 2146 buf_addr = (unsigned char *)buffer; 2147 } 2148 2149 DEBUG_PRINT_LOW("\n use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p", 2150 (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer); 2151 if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT) != true) 2152 { 2153 DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf"); 2154 return OMX_ErrorInsufficientResources; 2155 } 2156 } 2157 else 2158 { 2159 DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for " 2160 "index = %u", i); 2161 eRet = OMX_ErrorInsufficientResources; 2162 } 2163 } 2164 return eRet; 2165 } 2166 2167 2168 /* ====================================================================== 2169 FUNCTION 2170 omx_video::UseBuffer 2171 2172 DESCRIPTION 2173 OMX Use Buffer method implementation. 2174 2175 PARAMETERS 2176 <TBD>. 2177 2178 RETURN VALUE 2179 OMX Error None , if everything successful. 2180 2181 ========================================================================== */ 2182 OMX_ERRORTYPE omx_video::use_buffer( 2183 OMX_IN OMX_HANDLETYPE hComp, 2184 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2185 OMX_IN OMX_U32 port, 2186 OMX_IN OMX_PTR appData, 2187 OMX_IN OMX_U32 bytes, 2188 OMX_IN OMX_U8* buffer) 2189 { 2190 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2191 if(m_state == OMX_StateInvalid) 2192 { 2193 DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State\n"); 2194 return OMX_ErrorInvalidState; 2195 } 2196 if(port == PORT_INDEX_IN) 2197 { 2198 eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer); 2199 } 2200 else if(port == PORT_INDEX_OUT) 2201 { 2202 eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); 2203 } 2204 else 2205 { 2206 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); 2207 eRet = OMX_ErrorBadPortIndex; 2208 } 2209 2210 if(eRet == OMX_ErrorNone) 2211 { 2212 if(allocate_done()) 2213 { 2214 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 2215 { 2216 // Send the callback now 2217 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 2218 post_event(OMX_CommandStateSet,OMX_StateIdle, 2219 OMX_COMPONENT_GENERATE_EVENT); 2220 } 2221 } 2222 if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) 2223 { 2224 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) 2225 { 2226 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 2227 post_event(OMX_CommandPortEnable, 2228 PORT_INDEX_IN, 2229 OMX_COMPONENT_GENERATE_EVENT); 2230 } 2231 2232 } 2233 else if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) 2234 { 2235 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) 2236 { 2237 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 2238 post_event(OMX_CommandPortEnable, 2239 PORT_INDEX_OUT, 2240 OMX_COMPONENT_GENERATE_EVENT); 2241 m_event_port_settings_sent = false; 2242 } 2243 } 2244 } 2245 return eRet; 2246 } 2247 2248 OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 2249 { 2250 unsigned int index = 0; 2251 OMX_U8 *temp_buff ; 2252 2253 if(bufferHdr == NULL || m_inp_mem_ptr == NULL) 2254 { 2255 DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]", 2256 bufferHdr, m_inp_mem_ptr); 2257 return OMX_ErrorBadParameter; 2258 } 2259 2260 index = bufferHdr - m_inp_mem_ptr; 2261 2262 if(index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) 2263 { 2264 if(m_pInput_pmem[index].fd > 0 && input_use_buffer == false) 2265 { 2266 DEBUG_PRINT_LOW("\n FreeBuffer:: i/p AllocateBuffer case"); 2267 if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) 2268 { 2269 DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf"); 2270 } 2271 munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); 2272 close (m_pInput_pmem[index].fd); 2273 m_pInput_pmem[index].fd = -1; 2274 } 2275 else if(m_pInput_pmem[index].fd > 0 && (input_use_buffer == true && 2276 m_use_input_pmem == OMX_FALSE)) 2277 { 2278 DEBUG_PRINT_LOW("\n FreeBuffer:: i/p Heap UseBuffer case"); 2279 if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) 2280 { 2281 DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf"); 2282 } 2283 munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); 2284 close (m_pInput_pmem[index].fd); 2285 m_pInput_pmem[index].fd = -1; 2286 } 2287 else 2288 { 2289 DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case"); 2290 } 2291 } 2292 return OMX_ErrorNone; 2293 } 2294 2295 OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 2296 { 2297 unsigned int index = 0; 2298 OMX_U8 *temp_buff ; 2299 2300 if(bufferHdr == NULL || m_out_mem_ptr == NULL) 2301 { 2302 DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]", 2303 bufferHdr, m_out_mem_ptr); 2304 return OMX_ErrorBadParameter; 2305 } 2306 index = bufferHdr - m_out_mem_ptr; 2307 2308 if(index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) 2309 { 2310 if(m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) 2311 { 2312 DEBUG_PRINT_LOW("\n FreeBuffer:: o/p AllocateBuffer case"); 2313 if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) 2314 { 2315 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); 2316 } 2317 munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); 2318 close (m_pOutput_pmem[index].fd); 2319 m_pOutput_pmem[index].fd = -1; 2320 } 2321 else if( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true 2322 && m_use_output_pmem == OMX_FALSE)) 2323 { 2324 DEBUG_PRINT_LOW("\n FreeBuffer:: o/p Heap UseBuffer case"); 2325 if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) 2326 { 2327 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); 2328 } 2329 munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); 2330 close (m_pOutput_pmem[index].fd); 2331 m_pOutput_pmem[index].fd = -1; 2332 } 2333 else 2334 { 2335 DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case"); 2336 } 2337 } 2338 return OMX_ErrorNone; 2339 } 2340 2341 2342 /* ====================================================================== 2343 FUNCTION 2344 omx_venc::AllocateInputBuffer 2345 2346 DESCRIPTION 2347 Helper function for allocate buffer in the input pin 2348 2349 PARAMETERS 2350 None. 2351 2352 RETURN VALUE 2353 true/false 2354 2355 ========================================================================== */ 2356 OMX_ERRORTYPE omx_video::allocate_input_buffer( 2357 OMX_IN OMX_HANDLETYPE hComp, 2358 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2359 OMX_IN OMX_U32 port, 2360 OMX_IN OMX_PTR appData, 2361 OMX_IN OMX_U32 bytes) 2362 { 2363 2364 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2365 unsigned i = 0; 2366 2367 DEBUG_PRINT_HIGH("\n allocate_input_buffer()::"); 2368 if(bytes != m_sInPortDef.nBufferSize) 2369 { 2370 DEBUG_PRINT_ERROR("\nERROR: Buffer size mismatch error: bytes[%u] != nBufferSize[%u]\n", 2371 bytes, m_sInPortDef.nBufferSize); 2372 return OMX_ErrorBadParameter; 2373 } 2374 2375 if(!m_inp_mem_ptr) 2376 { 2377 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 2378 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); 2379 if(m_inp_mem_ptr == NULL) 2380 { 2381 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr"); 2382 return OMX_ErrorInsufficientResources; 2383 } 2384 2385 m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); 2386 2387 if(m_pInput_pmem == NULL) 2388 { 2389 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem"); 2390 return OMX_ErrorInsufficientResources; 2391 } 2392 2393 for(i=0; i< m_sInPortDef.nBufferCountActual; i++) 2394 { 2395 m_pInput_pmem[i].fd = -1; 2396 } 2397 } 2398 2399 for(i=0; i< m_sInPortDef.nBufferCountActual; i++) 2400 { 2401 if(BITMASK_ABSENT(&m_inp_bm_count,i)) 2402 { 2403 break; 2404 } 2405 } 2406 2407 if(i < m_sInPortDef.nBufferCountActual) 2408 { 2409 2410 *bufferHdr = (m_inp_mem_ptr + i); 2411 (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2412 (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; 2413 (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; 2414 (*bufferHdr)->pAppPrivate = appData; 2415 (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; 2416 2417 m_pInput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 2418 2419 if(m_pInput_pmem[i].fd == 0) 2420 { 2421 m_pInput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 2422 } 2423 2424 if(m_pInput_pmem[i].fd < 0) 2425 { 2426 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed\n"); 2427 return OMX_ErrorInsufficientResources; 2428 } 2429 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; 2430 m_pInput_pmem[i].offset = 0; 2431 2432 m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, 2433 MAP_SHARED,m_pInput_pmem[i].fd,0); 2434 if(m_pInput_pmem[i].buffer == MAP_FAILED) 2435 { 2436 DEBUG_PRINT_ERROR("\nERROR: mmap FAILED\n"); 2437 return OMX_ErrorInsufficientResources; 2438 } 2439 2440 (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer; 2441 2442 BITMASK_SET(&m_inp_bm_count,i); 2443 //here change the I/P param here from buf_adr to pmem 2444 if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN) != true) 2445 { 2446 DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for i/p buf\n"); 2447 return OMX_ErrorInsufficientResources; 2448 } 2449 } 2450 else 2451 { 2452 DEBUG_PRINT_ERROR("\nERROR: All i/p buffers are allocated, invalid allocate buf call" 2453 "for index [%d]\n", i); 2454 eRet = OMX_ErrorInsufficientResources; 2455 } 2456 2457 return eRet; 2458 } 2459 2460 2461 /* ====================================================================== 2462 FUNCTION 2463 omx_venc::AllocateOutputBuffer 2464 2465 DESCRIPTION 2466 Helper fn for AllocateBuffer in the output pin 2467 2468 PARAMETERS 2469 <TBD>. 2470 2471 RETURN VALUE 2472 OMX Error None if everything went well. 2473 2474 ========================================================================== */ 2475 OMX_ERRORTYPE omx_video::allocate_output_buffer( 2476 OMX_IN OMX_HANDLETYPE hComp, 2477 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2478 OMX_IN OMX_U32 port, 2479 OMX_IN OMX_PTR appData, 2480 OMX_IN OMX_U32 bytes) 2481 { 2482 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2483 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 2484 unsigned i= 0; // Temporary counter 2485 DEBUG_PRINT_HIGH("\n allocate_output_buffer()::"); 2486 if(!m_out_mem_ptr) 2487 { 2488 int nBufHdrSize = 0; 2489 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual); 2490 nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); 2491 2492 /* 2493 * Memory for output side involves the following: 2494 * 1. Array of Buffer Headers 2495 * 2. Bitmask array to hold the buffer allocation details 2496 * In order to minimize the memory management entire allocation 2497 * is done in one step. 2498 */ 2499 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 2500 2501 m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual); 2502 2503 if(m_out_mem_ptr && m_pOutput_pmem) 2504 { 2505 bufHdr = m_out_mem_ptr; 2506 2507 for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) 2508 { 2509 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2510 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 2511 // Set the values when we determine the right HxW param 2512 bufHdr->nAllocLen = bytes; 2513 bufHdr->nFilledLen = 0; 2514 bufHdr->pAppPrivate = appData; 2515 bufHdr->nOutputPortIndex = PORT_INDEX_OUT; 2516 bufHdr->pBuffer = NULL; 2517 bufHdr++; 2518 m_pOutput_pmem[i].fd = -1; 2519 } 2520 } 2521 else 2522 { 2523 DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem"); 2524 eRet = OMX_ErrorInsufficientResources; 2525 } 2526 } 2527 2528 DEBUG_PRINT_HIGH("\n actual cnt = %u", m_sOutPortDef.nBufferCountActual); 2529 for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) 2530 { 2531 if(BITMASK_ABSENT(&m_out_bm_count,i)) 2532 { 2533 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i); 2534 break; 2535 } 2536 } 2537 2538 if(eRet == OMX_ErrorNone) 2539 { 2540 if(i < m_sOutPortDef.nBufferCountActual) 2541 { 2542 m_pOutput_pmem[i].fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC); 2543 if(m_pOutput_pmem[i].fd == 0) 2544 { 2545 m_pOutput_pmem[i].fd = open ("/dev/pmem_adsp",O_RDWR | O_SYNC); 2546 } 2547 2548 if(m_pOutput_pmem[i].fd < 0) 2549 { 2550 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() failed"); 2551 return OMX_ErrorInsufficientResources; 2552 } 2553 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; 2554 m_pOutput_pmem[i].offset = 0; 2555 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, 2556 MAP_SHARED,m_pOutput_pmem[i].fd,0); 2557 if(m_pOutput_pmem[i].buffer == MAP_FAILED) 2558 { 2559 DEBUG_PRINT_ERROR("\nERROR: MMAP_FAILED in o/p alloc buffer"); 2560 return OMX_ErrorInsufficientResources; 2561 } 2562 2563 *bufferHdr = (m_out_mem_ptr + i ); 2564 (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer; 2565 2566 BITMASK_SET(&m_out_bm_count,i); 2567 2568 if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT) != true) 2569 { 2570 DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for o/p buf"); 2571 return OMX_ErrorInsufficientResources; 2572 } 2573 } 2574 else 2575 { 2576 DEBUG_PRINT_ERROR("\nERROR: All o/p buffers are allocated, invalid allocate buf call" 2577 "for index [%d]\n", i); 2578 } 2579 } 2580 2581 return eRet; 2582 } 2583 2584 2585 // AllocateBuffer -- API Call 2586 /* ====================================================================== 2587 FUNCTION 2588 omx_video::AllocateBuffer 2589 2590 DESCRIPTION 2591 Returns zero if all the buffers released.. 2592 2593 PARAMETERS 2594 None. 2595 2596 RETURN VALUE 2597 true/false 2598 2599 ========================================================================== */ 2600 OMX_ERRORTYPE omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, 2601 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2602 OMX_IN OMX_U32 port, 2603 OMX_IN OMX_PTR appData, 2604 OMX_IN OMX_U32 bytes) 2605 { 2606 2607 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type 2608 2609 DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port); 2610 if(m_state == OMX_StateInvalid) 2611 { 2612 DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State\n"); 2613 return OMX_ErrorInvalidState; 2614 } 2615 2616 // What if the client calls again. 2617 if(port == PORT_INDEX_IN) 2618 { 2619 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); 2620 } 2621 else if(port == PORT_INDEX_OUT) 2622 { 2623 eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); 2624 } 2625 else 2626 { 2627 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); 2628 eRet = OMX_ErrorBadPortIndex; 2629 } 2630 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); 2631 if(eRet == OMX_ErrorNone) 2632 { 2633 if(allocate_done()) 2634 { 2635 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 2636 { 2637 // Send the callback now 2638 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 2639 post_event(OMX_CommandStateSet,OMX_StateIdle, 2640 OMX_COMPONENT_GENERATE_EVENT); 2641 } 2642 } 2643 if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) 2644 { 2645 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) 2646 { 2647 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 2648 post_event(OMX_CommandPortEnable, 2649 PORT_INDEX_IN, 2650 OMX_COMPONENT_GENERATE_EVENT); 2651 } 2652 } 2653 if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) 2654 { 2655 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) 2656 { 2657 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 2658 post_event(OMX_CommandPortEnable, 2659 PORT_INDEX_OUT, 2660 OMX_COMPONENT_GENERATE_EVENT); 2661 m_event_port_settings_sent = false; 2662 } 2663 } 2664 } 2665 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); 2666 return eRet; 2667 } 2668 2669 2670 // Free Buffer - API call 2671 /* ====================================================================== 2672 FUNCTION 2673 omx_video::FreeBuffer 2674 2675 DESCRIPTION 2676 2677 PARAMETERS 2678 None. 2679 2680 RETURN VALUE 2681 true/false 2682 2683 ========================================================================== */ 2684 OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp, 2685 OMX_IN OMX_U32 port, 2686 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 2687 { 2688 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2689 unsigned int nPortIndex; 2690 2691 DEBUG_PRINT_LOW("In for decoder free_buffer \n"); 2692 2693 if(m_state == OMX_StateIdle && 2694 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) 2695 { 2696 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); 2697 } 2698 else if((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)|| 2699 (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) 2700 { 2701 DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port); 2702 } 2703 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) 2704 { 2705 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled\n"); 2706 post_event(OMX_EventError, 2707 OMX_ErrorPortUnpopulated, 2708 OMX_COMPONENT_GENERATE_EVENT); 2709 2710 return eRet; 2711 } 2712 else 2713 { 2714 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers\n"); 2715 post_event(OMX_EventError, 2716 OMX_ErrorPortUnpopulated, 2717 OMX_COMPONENT_GENERATE_EVENT); 2718 } 2719 2720 if(port == PORT_INDEX_IN) 2721 { 2722 // check if the buffer is valid 2723 nPortIndex = buffer - m_inp_mem_ptr; 2724 2725 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d, actual cnt %d \n", 2726 nPortIndex, m_sInPortDef.nBufferCountActual); 2727 if(nPortIndex < m_sInPortDef.nBufferCountActual) 2728 { 2729 // Clear the bit associated with it. 2730 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); 2731 free_input_buffer (buffer); 2732 m_sInPortDef.bPopulated = OMX_FALSE; 2733 2734 /*Free the Buffer Header*/ 2735 if(release_input_done()) 2736 { 2737 input_use_buffer = false; 2738 if(m_inp_mem_ptr) 2739 { 2740 DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr\n"); 2741 free (m_inp_mem_ptr); 2742 m_inp_mem_ptr = NULL; 2743 } 2744 if(m_pInput_pmem) 2745 { 2746 DEBUG_PRINT_LOW("Freeing m_pInput_pmem\n"); 2747 free(m_pInput_pmem); 2748 m_pInput_pmem = NULL; 2749 } 2750 2751 } 2752 } 2753 else 2754 { 2755 DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid\n"); 2756 eRet = OMX_ErrorBadPortIndex; 2757 } 2758 2759 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) 2760 && release_input_done()) 2761 { 2762 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); 2763 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); 2764 post_event(OMX_CommandPortDisable, 2765 PORT_INDEX_IN, 2766 OMX_COMPONENT_GENERATE_EVENT); 2767 } 2768 } 2769 else if(port == PORT_INDEX_OUT) 2770 { 2771 // check if the buffer is valid 2772 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr; 2773 2774 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d, actual cnt %d \n", 2775 nPortIndex, m_sOutPortDef.nBufferCountActual); 2776 if(nPortIndex < m_sOutPortDef.nBufferCountActual) 2777 { 2778 // Clear the bit associated with it. 2779 BITMASK_CLEAR(&m_out_bm_count,nPortIndex); 2780 m_sOutPortDef.bPopulated = OMX_FALSE; 2781 free_output_buffer (buffer); 2782 2783 if(release_output_done()) 2784 { 2785 output_use_buffer = false; 2786 if(m_out_mem_ptr) 2787 { 2788 DEBUG_PRINT_LOW("Freeing m_out_mem_ptr\n"); 2789 free (m_out_mem_ptr); 2790 m_out_mem_ptr = NULL; 2791 } 2792 if(m_pOutput_pmem) 2793 { 2794 DEBUG_PRINT_LOW("Freeing m_pOutput_pmem\n"); 2795 free(m_pOutput_pmem); 2796 m_pOutput_pmem = NULL; 2797 } 2798 } 2799 } 2800 else 2801 { 2802 DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid\n"); 2803 eRet = OMX_ErrorBadPortIndex; 2804 } 2805 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) 2806 && release_output_done() ) 2807 { 2808 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); 2809 2810 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); 2811 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 2812 post_event(OMX_CommandPortDisable, 2813 PORT_INDEX_OUT, 2814 OMX_COMPONENT_GENERATE_EVENT); 2815 2816 } 2817 } 2818 else 2819 { 2820 eRet = OMX_ErrorBadPortIndex; 2821 } 2822 if((eRet == OMX_ErrorNone) && 2823 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) 2824 { 2825 if(release_done()) 2826 { 2827 if(dev_stop() != 0) 2828 { 2829 DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED\n"); 2830 eRet = OMX_ErrorHardware; 2831 } 2832 // Send the callback now 2833 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); 2834 post_event(OMX_CommandStateSet, OMX_StateLoaded, 2835 OMX_COMPONENT_GENERATE_EVENT); 2836 } 2837 } 2838 2839 return eRet; 2840 } 2841 2842 2843 /* ====================================================================== 2844 FUNCTION 2845 omx_video::EmptyThisBuffer 2846 2847 DESCRIPTION 2848 This routine is used to push the encoded video frames to 2849 the video decoder. 2850 2851 PARAMETERS 2852 None. 2853 2854 RETURN VALUE 2855 OMX Error None if everything went successful. 2856 2857 ========================================================================== */ 2858 OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 2859 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 2860 { 2861 OMX_ERRORTYPE ret1 = OMX_ErrorNone; 2862 unsigned int nBufferIndex ; 2863 2864 DEBUG_PRINT_LOW("\n ETB: buffer = %p, buffer->pBuffer[%p]\n", buffer, buffer->pBuffer); 2865 if(m_state == OMX_StateInvalid) 2866 { 2867 DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State\n"); 2868 return OMX_ErrorInvalidState; 2869 } 2870 2871 if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) 2872 { 2873 DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> buffer is null or buffer size is invalid"); 2874 return OMX_ErrorBadParameter; 2875 } 2876 2877 if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) 2878 { 2879 DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> OMX Version Invalid"); 2880 return OMX_ErrorVersionMismatch; 2881 } 2882 2883 if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) 2884 { 2885 DEBUG_PRINT_ERROR("\nERROR: Bad port index to call empty_this_buffer"); 2886 return OMX_ErrorBadPortIndex; 2887 } 2888 if(!m_sInPortDef.bEnabled) 2889 { 2890 DEBUG_PRINT_ERROR("\nERROR: Cannot call empty_this_buffer while I/P port is disabled"); 2891 return OMX_ErrorIncorrectStateOperation; 2892 } 2893 2894 nBufferIndex = buffer - m_inp_mem_ptr; 2895 2896 if(nBufferIndex > m_sInPortDef.nBufferCountActual ) 2897 { 2898 DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]\n", nBufferIndex); 2899 return OMX_ErrorBadParameter; 2900 } 2901 2902 m_etb_count++; 2903 DEBUG_PRINT_LOW("\n DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp); 2904 post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB); 2905 return OMX_ErrorNone; 2906 } 2907 2908 2909 /* ====================================================================== 2910 FUNCTION 2911 omx_video::empty_this_buffer_proxy 2912 2913 DESCRIPTION 2914 This routine is used to push the encoded video frames to 2915 the video decoder. 2916 2917 PARAMETERS 2918 None. 2919 2920 RETURN VALUE 2921 OMX Error None if everything went successful. 2922 2923 ========================================================================== */ 2924 OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, 2925 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 2926 { 2927 OMX_U8 *pmem_data_buf = NULL; 2928 int push_cnt = 0; 2929 unsigned nBufIndex = 0; 2930 OMX_ERRORTYPE ret = OMX_ErrorNone; 2931 2932 DEBUG_PRINT_LOW("\n ETBProxy: buffer->pBuffer[%p]\n", buffer->pBuffer); 2933 2934 if(buffer == NULL) 2935 { 2936 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid buffer[%p]\n", buffer); 2937 return OMX_ErrorBadParameter; 2938 } 2939 2940 nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 2941 2942 if(nBufIndex >= m_sInPortDef.nBufferCountActual) 2943 { 2944 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid bufindex = %u\n", nBufIndex); 2945 return OMX_ErrorBadParameter; 2946 } 2947 2948 pending_input_buffers++; 2949 if(input_flush_progress == true) 2950 { 2951 post_event ((unsigned int)buffer,0, 2952 OMX_COMPONENT_GENERATE_EBD); 2953 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Input flush in progress"); 2954 return OMX_ErrorNone; 2955 } 2956 2957 if(input_use_buffer && !m_use_input_pmem) 2958 { 2959 DEBUG_PRINT_LOW("\n Heap UseBuffer case, so memcpy the data"); 2960 pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer; 2961 2962 memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset), 2963 buffer->nFilledLen); 2964 DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf"); 2965 } 2966 2967 if(dev_empty_buf(buffer, pmem_data_buf) != true) 2968 { 2969 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: dev_empty_buf failed"); 2970 /*Generate an async error and move to invalid state*/ 2971 pending_input_buffers--; 2972 return OMX_ErrorBadParameter; 2973 } 2974 2975 return ret; 2976 } 2977 2978 /* ====================================================================== 2979 FUNCTION 2980 omx_video::FillThisBuffer 2981 2982 DESCRIPTION 2983 IL client uses this method to release the frame buffer 2984 after displaying them. 2985 2986 PARAMETERS 2987 None. 2988 2989 RETURN VALUE 2990 true/false 2991 2992 ========================================================================== */ 2993 OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 2994 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 2995 { 2996 DEBUG_PRINT_LOW("\n FTB: buffer->pBuffer[%p]\n", buffer->pBuffer); 2997 if(m_state == OMX_StateInvalid) 2998 { 2999 DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State\n"); 3000 return OMX_ErrorInvalidState; 3001 } 3002 3003 if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) 3004 { 3005 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size\n"); 3006 return OMX_ErrorBadParameter; 3007 } 3008 3009 if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) 3010 { 3011 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid\n"); 3012 return OMX_ErrorVersionMismatch; 3013 } 3014 3015 if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) 3016 { 3017 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index\n"); 3018 return OMX_ErrorBadPortIndex; 3019 } 3020 3021 if(!m_sOutPortDef.bEnabled) 3022 { 3023 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled\n"); 3024 return OMX_ErrorIncorrectStateOperation; 3025 } 3026 3027 post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB); 3028 return OMX_ErrorNone; 3029 } 3030 3031 /* ====================================================================== 3032 FUNCTION 3033 omx_video::fill_this_buffer_proxy 3034 3035 DESCRIPTION 3036 IL client uses this method to release the frame buffer 3037 after displaying them. 3038 3039 PARAMETERS 3040 None. 3041 3042 RETURN VALUE 3043 true/false 3044 3045 ========================================================================== */ 3046 OMX_ERRORTYPE omx_video::fill_this_buffer_proxy( 3047 OMX_IN OMX_HANDLETYPE hComp, 3048 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) 3049 { 3050 OMX_U8 *pmem_data_buf = NULL; 3051 OMX_ERRORTYPE nRet = OMX_ErrorNone; 3052 3053 DEBUG_PRINT_LOW("\n FTBProxy: bufferAdd->pBuffer[%p]\n", bufferAdd->pBuffer); 3054 3055 if(bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= m_sOutPortDef.nBufferCountActual) ) 3056 { 3057 DEBUG_PRINT_ERROR("\nERROR: FTBProxy: Invalid i/p params\n"); 3058 return OMX_ErrorBadParameter; 3059 } 3060 3061 pending_output_buffers++; 3062 /*Return back the output buffer to client*/ 3063 if( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) 3064 { 3065 DEBUG_PRINT_LOW("\n o/p port is Disabled or Flush in Progress"); 3066 post_event ((unsigned int)bufferAdd,0, 3067 OMX_COMPONENT_GENERATE_FBD); 3068 return OMX_ErrorNone; 3069 } 3070 3071 if(output_use_buffer && !m_use_output_pmem) 3072 { 3073 DEBUG_PRINT_LOW("\n Heap UseBuffer case"); 3074 pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer; 3075 } 3076 3077 if(dev_fill_buf(bufferAdd, pmem_data_buf) != true) 3078 { 3079 DEBUG_PRINT_ERROR("\nERROR: dev_fill_buf() Failed"); 3080 pending_output_buffers--; 3081 return OMX_ErrorBadParameter; 3082 } 3083 3084 return OMX_ErrorNone; 3085 } 3086 3087 /* ====================================================================== 3088 FUNCTION 3089 omx_video::SetCallbacks 3090 3091 DESCRIPTION 3092 Set the callbacks. 3093 3094 PARAMETERS 3095 None. 3096 3097 RETURN VALUE 3098 OMX Error None if everything successful. 3099 3100 ========================================================================== */ 3101 OMX_ERRORTYPE omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, 3102 OMX_IN OMX_CALLBACKTYPE* callbacks, 3103 OMX_IN OMX_PTR appData) 3104 { 3105 3106 m_pCallbacks = *callbacks; 3107 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\ 3108 m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone); 3109 m_app_data = appData; 3110 return OMX_ErrorNotImplemented; 3111 } 3112 3113 3114 /* ====================================================================== 3115 FUNCTION 3116 omx_venc::UseEGLImage 3117 3118 DESCRIPTION 3119 OMX Use EGL Image method implementation <TBD>. 3120 3121 PARAMETERS 3122 <TBD>. 3123 3124 RETURN VALUE 3125 Not Implemented error. 3126 3127 ========================================================================== */ 3128 OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, 3129 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3130 OMX_IN OMX_U32 port, 3131 OMX_IN OMX_PTR appData, 3132 OMX_IN void* eglImage) 3133 { 3134 DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented \n"); 3135 return OMX_ErrorNotImplemented; 3136 } 3137 3138 /* ====================================================================== 3139 FUNCTION 3140 omx_venc::ComponentRoleEnum 3141 3142 DESCRIPTION 3143 OMX Component Role Enum method implementation. 3144 3145 PARAMETERS 3146 <TBD>. 3147 3148 RETURN VALUE 3149 OMX Error None if everything is successful. 3150 ========================================================================== */ 3151 OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, 3152 OMX_OUT OMX_U8* role, 3153 OMX_IN OMX_U32 index) 3154 { 3155 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3156 if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 3157 { 3158 if((0 == index) && role) 3159 { 3160 strncpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 3161 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3162 } 3163 else 3164 { 3165 eRet = OMX_ErrorNoMore; 3166 } 3167 } 3168 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) 3169 { 3170 if((0 == index) && role) 3171 { 3172 strncpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 3173 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3174 } 3175 else 3176 { 3177 DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); 3178 eRet = OMX_ErrorNoMore; 3179 } 3180 } 3181 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) 3182 { 3183 if((0 == index) && role) 3184 { 3185 strncpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 3186 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3187 } 3188 else 3189 { 3190 DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); 3191 eRet = OMX_ErrorNoMore; 3192 } 3193 } 3194 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) 3195 { 3196 if((0 == index) && role) 3197 { 3198 strncpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 3199 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3200 } 3201 else 3202 { 3203 DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); 3204 eRet = OMX_ErrorNoMore; 3205 } 3206 } 3207 if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 3208 { 3209 if((0 == index) && role) 3210 { 3211 strncpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 3212 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3213 } 3214 else 3215 { 3216 eRet = OMX_ErrorNoMore; 3217 } 3218 } 3219 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) 3220 { 3221 if((0 == index) && role) 3222 { 3223 strncpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); 3224 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3225 } 3226 else 3227 { 3228 DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); 3229 eRet = OMX_ErrorNoMore; 3230 } 3231 } 3232 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) 3233 { 3234 if((0 == index) && role) 3235 { 3236 strncpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); 3237 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3238 } 3239 else 3240 { 3241 DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); 3242 eRet = OMX_ErrorNoMore; 3243 } 3244 } 3245 else 3246 { 3247 DEBUG_PRINT_ERROR("\nERROR: Querying Role on Unknown Component\n"); 3248 eRet = OMX_ErrorInvalidComponentName; 3249 } 3250 return eRet; 3251 } 3252 3253 3254 3255 3256 /* ====================================================================== 3257 FUNCTION 3258 omx_venc::AllocateDone 3259 3260 DESCRIPTION 3261 Checks if entire buffer pool is allocated by IL Client or not. 3262 Need this to move to IDLE state. 3263 3264 PARAMETERS 3265 None. 3266 3267 RETURN VALUE 3268 true/false. 3269 3270 ========================================================================== */ 3271 bool omx_video::allocate_done(void) 3272 { 3273 bool bRet = false; 3274 bool bRet_In = false; 3275 bool bRet_Out = false; 3276 3277 bRet_In = allocate_input_done(); 3278 bRet_Out = allocate_output_done(); 3279 3280 if(bRet_In && bRet_Out) 3281 { 3282 bRet = true; 3283 } 3284 3285 return bRet; 3286 } 3287 /* ====================================================================== 3288 FUNCTION 3289 omx_venc::AllocateInputDone 3290 3291 DESCRIPTION 3292 Checks if I/P buffer pool is allocated by IL Client or not. 3293 3294 PARAMETERS 3295 None. 3296 3297 RETURN VALUE 3298 true/false. 3299 3300 ========================================================================== */ 3301 bool omx_video::allocate_input_done(void) 3302 { 3303 bool bRet = false; 3304 unsigned i=0; 3305 3306 if(m_inp_mem_ptr == NULL) 3307 { 3308 return bRet; 3309 } 3310 if(m_inp_mem_ptr ) 3311 { 3312 for(;i<m_sInPortDef.nBufferCountActual;i++) 3313 { 3314 if(BITMASK_ABSENT(&m_inp_bm_count,i)) 3315 { 3316 break; 3317 } 3318 } 3319 } 3320 if(i==m_sInPortDef.nBufferCountActual) 3321 { 3322 bRet = true; 3323 } 3324 if(i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled) 3325 { 3326 m_sInPortDef.bPopulated = OMX_TRUE; 3327 } 3328 return bRet; 3329 } 3330 /* ====================================================================== 3331 FUNCTION 3332 omx_venc::AllocateOutputDone 3333 3334 DESCRIPTION 3335 Checks if entire O/P buffer pool is allocated by IL Client or not. 3336 3337 PARAMETERS 3338 None. 3339 3340 RETURN VALUE 3341 true/false. 3342 3343 ========================================================================== */ 3344 bool omx_video::allocate_output_done(void) 3345 { 3346 bool bRet = false; 3347 unsigned j=0; 3348 3349 if(m_out_mem_ptr == NULL) 3350 { 3351 return bRet; 3352 } 3353 3354 if(m_out_mem_ptr ) 3355 { 3356 for(;j<m_sOutPortDef.nBufferCountActual;j++) 3357 { 3358 if(BITMASK_ABSENT(&m_out_bm_count,j)) 3359 { 3360 break; 3361 } 3362 } 3363 } 3364 3365 if(j==m_sOutPortDef.nBufferCountActual) 3366 { 3367 bRet = true; 3368 } 3369 3370 if(j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled) 3371 { 3372 m_sOutPortDef.bPopulated = OMX_TRUE; 3373 } 3374 return bRet; 3375 } 3376 3377 /* ====================================================================== 3378 FUNCTION 3379 omx_venc::ReleaseDone 3380 3381 DESCRIPTION 3382 Checks if IL client has released all the buffers. 3383 3384 PARAMETERS 3385 None. 3386 3387 RETURN VALUE 3388 true/false 3389 3390 ========================================================================== */ 3391 bool omx_video::release_done(void) 3392 { 3393 bool bRet = false; 3394 DEBUG_PRINT_LOW("Inside release_done()\n"); 3395 if(release_input_done()) 3396 { 3397 if(release_output_done()) 3398 { 3399 bRet = true; 3400 } 3401 } 3402 return bRet; 3403 } 3404 3405 3406 /* ====================================================================== 3407 FUNCTION 3408 omx_venc::ReleaseOutputDone 3409 3410 DESCRIPTION 3411 Checks if IL client has released all the buffers. 3412 3413 PARAMETERS 3414 None. 3415 3416 RETURN VALUE 3417 true/false 3418 3419 ========================================================================== */ 3420 bool omx_video::release_output_done(void) 3421 { 3422 bool bRet = false; 3423 unsigned i=0,j=0; 3424 3425 DEBUG_PRINT_LOW("Inside release_output_done()\n"); 3426 if(m_out_mem_ptr) 3427 { 3428 for(;j<m_sOutPortDef.nBufferCountActual;j++) 3429 { 3430 if(BITMASK_PRESENT(&m_out_bm_count,j)) 3431 { 3432 break; 3433 } 3434 } 3435 if(j==m_sOutPortDef.nBufferCountActual) 3436 { 3437 bRet = true; 3438 } 3439 } 3440 else 3441 { 3442 bRet = true; 3443 } 3444 return bRet; 3445 } 3446 /* ====================================================================== 3447 FUNCTION 3448 omx_venc::ReleaseInputDone 3449 3450 DESCRIPTION 3451 Checks if IL client has released all the buffers. 3452 3453 PARAMETERS 3454 None. 3455 3456 RETURN VALUE 3457 true/false 3458 3459 ========================================================================== */ 3460 bool omx_video::release_input_done(void) 3461 { 3462 bool bRet = false; 3463 unsigned i=0,j=0; 3464 3465 DEBUG_PRINT_LOW("Inside release_input_done()\n"); 3466 if(m_inp_mem_ptr) 3467 { 3468 for(;j<m_sInPortDef.nBufferCountActual;j++) 3469 { 3470 if( BITMASK_PRESENT(&m_inp_bm_count,j)) 3471 { 3472 break; 3473 } 3474 } 3475 if(j==m_sInPortDef.nBufferCountActual) 3476 { 3477 bRet = true; 3478 } 3479 } 3480 else 3481 { 3482 bRet = true; 3483 } 3484 return bRet; 3485 } 3486 3487 OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp, 3488 OMX_BUFFERHEADERTYPE * buffer) 3489 { 3490 DEBUG_PRINT_LOW("\nfill_buffer_done: buffer->pBuffer[%p]\n", buffer->pBuffer); 3491 if(buffer == NULL || ((buffer - m_out_mem_ptr) > m_sOutPortDef.nBufferCountActual)) 3492 { 3493 return OMX_ErrorBadParameter; 3494 } 3495 3496 pending_output_buffers--; 3497 3498 /* For use buffer we need to copy the data */ 3499 if(m_pCallbacks.FillBufferDone) 3500 { 3501 if(buffer->nFilledLen > 0) 3502 { 3503 m_fbd_count++; 3504 } 3505 m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer); 3506 } 3507 else 3508 { 3509 return OMX_ErrorBadParameter; 3510 } 3511 3512 return OMX_ErrorNone; 3513 } 3514 3515 OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp, 3516 OMX_BUFFERHEADERTYPE* buffer) 3517 { 3518 DEBUG_PRINT_LOW("\nempty_buffer_done: buffer->pBuffer[%p]\n", buffer->pBuffer); 3519 if(buffer == NULL || ((buffer - m_inp_mem_ptr) > m_sInPortDef.nBufferCountActual)) 3520 { 3521 return OMX_ErrorBadParameter; 3522 } 3523 3524 pending_input_buffers--; 3525 if(m_pCallbacks.EmptyBufferDone) 3526 { 3527 m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer); 3528 } 3529 return OMX_ErrorNone; 3530 } 3531