1 /*-------------------------------------------------------------------------- 2 Copyright (c) 2010-2012, 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 #include <sys/prctl.h> 48 #ifdef _ANDROID_ICS_ 49 #include <media/hardware/HardwareAPI.h> 50 #include <gralloc_priv.h> 51 #endif 52 #ifndef _ANDROID_ 53 #include <glib.h> 54 #define strlcpy g_strlcpy 55 #endif 56 #define H264_SUPPORTED_WIDTH (480) 57 #define H264_SUPPORTED_HEIGHT (368) 58 59 #define MPEG4_SUPPORTED_WIDTH (480) 60 #define MPEG4_SUPPORTED_HEIGHT (368) 61 62 #define VC1_SP_MP_START_CODE 0xC5000000 63 #define VC1_SP_MP_START_CODE_MASK 0xFF000000 64 #define VC1_AP_START_CODE 0x00000100 65 #define VC1_AP_START_CODE_MASK 0xFFFFFF00 66 #define VC1_STRUCT_C_PROFILE_MASK 0xF0 67 #define VC1_STRUCT_B_LEVEL_MASK 0xE0000000 68 #define VC1_SIMPLE_PROFILE 0 69 #define VC1_MAIN_PROFILE 1 70 #define VC1_ADVANCE_PROFILE 3 71 #define VC1_SIMPLE_PROFILE_LOW_LEVEL 0 72 #define VC1_SIMPLE_PROFILE_MED_LEVEL 2 73 #define VC1_STRUCT_C_LEN 4 74 #define VC1_STRUCT_C_POS 8 75 #define VC1_STRUCT_A_POS 12 76 #define VC1_STRUCT_B_POS 24 77 #define VC1_SEQ_LAYER_SIZE 36 78 79 #define IS_NOT_ALIGNED( num, to) (num & (to-1)) 80 #define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1))) 81 #define SZ_2K (2048) 82 83 typedef struct OMXComponentCapabilityFlagsType 84 { 85 ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS 86 OMX_BOOL iIsOMXComponentMultiThreaded; 87 OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc; 88 OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc; 89 OMX_BOOL iOMXComponentSupportsMovableInputBuffers; 90 OMX_BOOL iOMXComponentSupportsPartialFrames; 91 OMX_BOOL iOMXComponentUsesNALStartCodes; 92 OMX_BOOL iOMXComponentCanHandleIncompleteFrames; 93 OMX_BOOL iOMXComponentUsesFullAVCFrames; 94 95 } OMXComponentCapabilityFlagsType; 96 #define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347 97 #ifdef OUTPUT_BUFFER_LOG 98 extern FILE *outputBufferFile1; 99 #endif 100 101 void* message_thread(void *input) 102 { 103 omx_video* omx = reinterpret_cast<omx_video*>(input); 104 unsigned char id; 105 int n; 106 107 DEBUG_PRINT_LOW("omx_venc: message thread start\n"); 108 prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0); 109 while(1) 110 { 111 n = read(omx->m_pipe_in, &id, 1); 112 if(0 == n) 113 { 114 break; 115 } 116 117 if(1 == n) 118 { 119 omx->process_event_cb(omx, id); 120 } 121 #ifdef QLE_BUILD 122 if(n < 0) break; 123 #else 124 if((n < 0) && (errno != EINTR)) break; 125 #endif 126 } 127 DEBUG_PRINT_LOW("omx_venc: message thread stop\n"); 128 return 0; 129 } 130 131 void post_message(omx_video *omx, unsigned char id) 132 { 133 DEBUG_PRINT_LOW("omx_venc: post_message %d\n", id); 134 write(omx->m_pipe_out, &id, 1); 135 } 136 137 // omx_cmd_queue destructor 138 omx_video::omx_cmd_queue::~omx_cmd_queue() 139 { 140 // Nothing to do 141 } 142 143 // omx cmd queue constructor 144 omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0) 145 { 146 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE); 147 } 148 149 // omx cmd queue insert 150 bool omx_video::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id) 151 { 152 bool ret = true; 153 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE) 154 { 155 m_q[m_write].id = id; 156 m_q[m_write].param1 = p1; 157 m_q[m_write].param2 = p2; 158 m_write++; 159 m_size ++; 160 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) 161 { 162 m_write = 0; 163 } 164 } 165 else 166 { 167 ret = false; 168 DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full\n"); 169 } 170 return ret; 171 } 172 173 // omx cmd queue pop 174 bool omx_video::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id) 175 { 176 bool ret = true; 177 if(m_size > 0) 178 { 179 *id = m_q[m_read].id; 180 *p1 = m_q[m_read].param1; 181 *p2 = m_q[m_read].param2; 182 // Move the read pointer ahead 183 ++m_read; 184 --m_size; 185 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) 186 { 187 m_read = 0; 188 } 189 } 190 else 191 { 192 ret = false; 193 } 194 return ret; 195 } 196 197 // Retrieve the first mesg type in the queue 198 unsigned omx_video::omx_cmd_queue::get_q_msg_type() 199 { 200 return m_q[m_read].id; 201 } 202 203 204 205 #ifdef _ANDROID_ 206 VideoHeap::VideoHeap(int fd, size_t size, void* base) 207 { 208 // dup file descriptor, map once, use pmem 209 init(dup(fd), base, size, 0 , MEM_DEVICE); 210 } 211 #endif // _ANDROID_ 212 213 /* ====================================================================== 214 FUNCTION 215 omx_venc::omx_venc 216 217 DESCRIPTION 218 Constructor 219 220 PARAMETERS 221 None 222 223 RETURN VALUE 224 None. 225 ========================================================================== */ 226 omx_video::omx_video(): m_state(OMX_StateInvalid), 227 m_app_data(NULL), 228 m_inp_mem_ptr(NULL), 229 m_out_mem_ptr(NULL), 230 m_pInput_pmem(NULL), 231 m_pOutput_pmem(NULL), 232 #ifdef USE_ION 233 m_pInput_ion(NULL), 234 m_pOutput_ion(NULL), 235 #endif 236 pending_input_buffers(0), 237 pending_output_buffers(0), 238 m_out_bm_count(0), 239 m_inp_bm_count(0), 240 m_flags(0), 241 m_event_port_settings_sent(false), 242 output_flush_progress (false), 243 input_flush_progress (false), 244 input_use_buffer (false), 245 output_use_buffer (false), 246 m_use_input_pmem(OMX_FALSE), 247 m_use_output_pmem(OMX_FALSE), 248 m_etb_count(0), 249 m_fbd_count(0), 250 m_error_propogated(false), 251 m_input_msg_id(OMX_COMPONENT_GENERATE_ETB), 252 psource_frame(NULL), 253 pdest_frame(NULL), 254 c2d_opened(false), 255 secure_session(false) 256 { 257 DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()"); 258 memset(&m_cmp,0,sizeof(m_cmp)); 259 memset(&m_pCallbacks,0,sizeof(m_pCallbacks)); 260 secure_color_format = (int) OMX_COLOR_FormatYUV420SemiPlanar; 261 pthread_mutex_init(&m_lock, NULL); 262 sem_init(&m_cmd_lock,0,0); 263 } 264 265 266 /* ====================================================================== 267 FUNCTION 268 omx_venc::~omx_venc 269 270 DESCRIPTION 271 Destructor 272 273 PARAMETERS 274 None 275 276 RETURN VALUE 277 None. 278 ========================================================================== */ 279 omx_video::~omx_video() 280 { 281 DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()"); 282 if(m_pipe_in) close(m_pipe_in); 283 if(m_pipe_out) close(m_pipe_out); 284 DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n"); 285 pthread_join(msg_thread_id,NULL); 286 DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n"); 287 pthread_join(async_thread_id,NULL); 288 pthread_mutex_destroy(&m_lock); 289 sem_destroy(&m_cmd_lock); 290 DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count, 291 m_fbd_count); 292 DEBUG_PRINT_HIGH("omx_video: Destructor exit\n"); 293 DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n"); 294 } 295 296 /* ====================================================================== 297 FUNCTION 298 omx_venc::OMXCntrlProcessMsgCb 299 300 DESCRIPTION 301 IL Client callbacks are generated through this routine. The decoder 302 provides the thread context for this routine. 303 304 PARAMETERS 305 ctxt -- Context information related to the self. 306 id -- Event identifier. This could be any of the following: 307 1. Command completion event 308 2. Buffer done callback event 309 3. Frame done callback event 310 311 RETURN VALUE 312 None. 313 314 ========================================================================== */ 315 void omx_video::process_event_cb(void *ctxt, unsigned char id) 316 { 317 unsigned p1; // Parameter - 1 318 unsigned p2; // Parameter - 2 319 unsigned ident; 320 unsigned qsize=0; // qsize 321 omx_video *pThis = (omx_video *) ctxt; 322 323 if(!pThis) 324 { 325 DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n"); 326 return; 327 } 328 329 // Protect the shared queue data structure 330 do 331 { 332 /*Read the message id's from the queue*/ 333 334 pthread_mutex_lock(&pThis->m_lock); 335 qsize = pThis->m_cmd_q.m_size; 336 if(qsize) 337 { 338 pThis->m_cmd_q.pop_entry(&p1,&p2,&ident); 339 } 340 341 if(qsize == 0) 342 { 343 qsize = pThis->m_ftb_q.m_size; 344 if(qsize) 345 { 346 pThis->m_ftb_q.pop_entry(&p1,&p2,&ident); 347 } 348 } 349 350 if(qsize == 0) 351 { 352 qsize = pThis->m_etb_q.m_size; 353 if(qsize) 354 { 355 pThis->m_etb_q.pop_entry(&p1,&p2,&ident); 356 } 357 } 358 359 pthread_mutex_unlock(&pThis->m_lock); 360 361 /*process message if we have one*/ 362 if(qsize > 0) 363 { 364 id = ident; 365 switch(id) 366 { 367 case OMX_COMPONENT_GENERATE_EVENT: 368 if(pThis->m_pCallbacks.EventHandler) 369 { 370 switch(p1) 371 { 372 case OMX_CommandStateSet: 373 pThis->m_state = (OMX_STATETYPE) p2; 374 DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state); 375 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 376 OMX_EventCmdComplete, p1, p2, NULL); 377 break; 378 379 case OMX_EventError: 380 DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2); 381 if(p2 == OMX_ErrorHardware) 382 { 383 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 384 OMX_EventError,OMX_ErrorHardware,0,NULL); 385 } 386 else 387 { 388 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 389 OMX_EventError, p2, NULL, NULL ); 390 391 } 392 break; 393 394 case OMX_CommandPortDisable: 395 DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \ 396 "state \n", p2); 397 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 398 OMX_EventCmdComplete, p1, p2, NULL ); 399 break; 400 case OMX_CommandPortEnable: 401 DEBUG_PRINT_LOW("Process ->Port %d set PORT_STATE_ENABLED state\n" \ 402 , p2); 403 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\ 404 OMX_EventCmdComplete, p1, p2, NULL ); 405 break; 406 407 default: 408 DEBUG_PRINT_LOW("\n process_event_cb forwarding EventCmdComplete %d \n", p1); 409 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 410 OMX_EventCmdComplete, p1, p2, NULL ); 411 break; 412 413 } 414 } 415 else 416 { 417 DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks\n"); 418 } 419 break; 420 case OMX_COMPONENT_GENERATE_ETB_OPQ: 421 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ\n"); 422 if(pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\ 423 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 424 { 425 DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n"); 426 pThis->omx_report_error (); 427 } 428 break; 429 case OMX_COMPONENT_GENERATE_ETB: 430 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB\n"); 431 if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 432 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 433 { 434 DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n"); 435 pThis->omx_report_error (); 436 } 437 break; 438 439 case OMX_COMPONENT_GENERATE_FTB: 440 if( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\ 441 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) 442 { 443 DEBUG_PRINT_ERROR("\nERROR: FTBProxy() failed!\n"); 444 pThis->omx_report_error (); 445 } 446 break; 447 448 case OMX_COMPONENT_GENERATE_COMMAND: 449 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\ 450 (OMX_U32)p2,(OMX_PTR)NULL); 451 break; 452 453 case OMX_COMPONENT_GENERATE_EBD: 454 if( pThis->empty_buffer_done(&pThis->m_cmp, 455 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) 456 { 457 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); 458 pThis->omx_report_error (); 459 } 460 break; 461 462 case OMX_COMPONENT_GENERATE_FBD: 463 if( pThis->fill_buffer_done(&pThis->m_cmp, 464 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) 465 { 466 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); 467 pThis->omx_report_error (); 468 } 469 break; 470 471 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH: 472 473 pThis->input_flush_progress = false; 474 DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", m_etb_count); 475 m_etb_count = 0; 476 if(pThis->m_pCallbacks.EventHandler) 477 { 478 /*Check if we need generate event for Flush done*/ 479 if(BITMASK_PRESENT(&pThis->m_flags, 480 OMX_COMPONENT_INPUT_FLUSH_PENDING)) 481 { 482 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING); 483 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 484 OMX_EventCmdComplete,OMX_CommandFlush, 485 PORT_INDEX_IN,NULL ); 486 } 487 else if(BITMASK_PRESENT(&pThis->m_flags, 488 OMX_COMPONENT_IDLE_PENDING)) 489 { 490 if(!pThis->output_flush_progress) 491 { 492 DEBUG_PRINT_LOW("\n dev_stop called after input flush complete\n"); 493 if(dev_stop() != 0) 494 { 495 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n"); 496 pThis->omx_report_error (); 497 } 498 } 499 } 500 } 501 502 break; 503 504 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH: 505 506 pThis->output_flush_progress = false; 507 DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", m_fbd_count); 508 m_fbd_count = 0; 509 if(pThis->m_pCallbacks.EventHandler) 510 { 511 /*Check if we need generate event for Flush done*/ 512 if(BITMASK_PRESENT(&pThis->m_flags, 513 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) 514 { 515 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 516 517 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 518 OMX_EventCmdComplete,OMX_CommandFlush, 519 PORT_INDEX_OUT,NULL ); 520 } 521 else if(BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) 522 { 523 DEBUG_PRINT_LOW("\n dev_stop called after Output flush complete\n"); 524 if(!pThis->input_flush_progress) 525 { 526 if(dev_stop() != 0) 527 { 528 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n"); 529 pThis->omx_report_error (); 530 } 531 } 532 } 533 } 534 break; 535 536 case OMX_COMPONENT_GENERATE_START_DONE: 537 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg"); 538 539 if(pThis->m_pCallbacks.EventHandler) 540 { 541 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success"); 542 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) 543 { 544 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Move to \ 545 executing"); 546 // Send the callback now 547 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 548 pThis->m_state = OMX_StateExecuting; 549 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 550 OMX_EventCmdComplete,OMX_CommandStateSet, 551 OMX_StateExecuting, NULL); 552 } 553 else if(BITMASK_PRESENT(&pThis->m_flags, 554 OMX_COMPONENT_PAUSE_PENDING)) 555 { 556 if(dev_pause()) 557 { 558 DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in Start Done!\n"); 559 pThis->omx_report_error (); 560 } 561 } 562 else if (BITMASK_PRESENT(&pThis->m_flags, 563 OMX_COMPONENT_LOADED_START_PENDING)) 564 { 565 if(dev_loaded_start_done()) 566 { 567 DEBUG_PRINT_LOW("successful loaded Start Done!"); 568 } 569 else 570 { 571 DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!"); 572 pThis->omx_report_error (); 573 } 574 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING); 575 } 576 else 577 { 578 DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags); 579 } 580 } 581 else 582 { 583 DEBUG_PRINT_LOW("\n Event Handler callback is NULL"); 584 } 585 break; 586 587 case OMX_COMPONENT_GENERATE_PAUSE_DONE: 588 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE msg"); 589 if(pThis->m_pCallbacks.EventHandler) 590 { 591 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) 592 { 593 //Send the callback now 594 pThis->complete_pending_buffer_done_cbs(); 595 DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD\n"); 596 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING); 597 pThis->m_state = OMX_StatePause; 598 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 599 OMX_EventCmdComplete,OMX_CommandStateSet, 600 OMX_StatePause, NULL); 601 } 602 } 603 604 break; 605 606 case OMX_COMPONENT_GENERATE_RESUME_DONE: 607 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_RESUME_DONE msg"); 608 if(pThis->m_pCallbacks.EventHandler) 609 { 610 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) 611 { 612 // Send the callback now 613 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING); 614 pThis->m_state = OMX_StateExecuting; 615 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data, 616 OMX_EventCmdComplete,OMX_CommandStateSet, 617 OMX_StateExecuting,NULL); 618 } 619 } 620 621 break; 622 623 case OMX_COMPONENT_GENERATE_STOP_DONE: 624 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE msg"); 625 if(pThis->m_pCallbacks.EventHandler) 626 { 627 pThis->complete_pending_buffer_done_cbs(); 628 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) 629 { 630 // Send the callback now 631 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING); 632 pThis->m_state = OMX_StateIdle; 633 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data, 634 OMX_EventCmdComplete,OMX_CommandStateSet, 635 OMX_StateIdle,NULL); 636 } 637 else if (BITMASK_PRESENT(&pThis->m_flags, 638 OMX_COMPONENT_LOADED_STOP_PENDING)) 639 { 640 if(dev_loaded_stop_done()) 641 { 642 DEBUG_PRINT_LOW("successful loaded Stop Done!"); 643 } 644 else 645 { 646 DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!"); 647 pThis->omx_report_error (); 648 } 649 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING); 650 } 651 else 652 { 653 DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags); 654 } 655 } 656 657 break; 658 659 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR: 660 DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n"); 661 pThis->omx_report_error (); 662 break; 663 664 default: 665 DEBUG_PRINT_LOW("\n process_event_cb unknown msg id 0x%02x", id); 666 break; 667 } 668 } 669 670 pthread_mutex_lock(&pThis->m_lock); 671 qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\ 672 pThis->m_etb_q.m_size; 673 674 pthread_mutex_unlock(&pThis->m_lock); 675 676 } 677 while(qsize>0); 678 DEBUG_PRINT_LOW("\n exited the while loop\n"); 679 680 } 681 682 683 684 685 /* ====================================================================== 686 FUNCTION 687 omx_venc::GetComponentVersion 688 689 DESCRIPTION 690 Returns the component version. 691 692 PARAMETERS 693 TBD. 694 695 RETURN VALUE 696 OMX_ErrorNone. 697 698 ========================================================================== */ 699 OMX_ERRORTYPE omx_video::get_component_version 700 ( 701 OMX_IN OMX_HANDLETYPE hComp, 702 OMX_OUT OMX_STRING componentName, 703 OMX_OUT OMX_VERSIONTYPE* componentVersion, 704 OMX_OUT OMX_VERSIONTYPE* specVersion, 705 OMX_OUT OMX_UUIDTYPE* componentUUID 706 ) 707 { 708 if(m_state == OMX_StateInvalid) 709 { 710 DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n"); 711 return OMX_ErrorInvalidState; 712 } 713 /* TBD -- Return the proper version */ 714 if (specVersion) 715 { 716 specVersion->nVersion = OMX_SPEC_VERSION; 717 } 718 return OMX_ErrorNone; 719 } 720 /* ====================================================================== 721 FUNCTION 722 omx_venc::SendCommand 723 724 DESCRIPTION 725 Returns zero if all the buffers released.. 726 727 PARAMETERS 728 None. 729 730 RETURN VALUE 731 true/false 732 733 ========================================================================== */ 734 OMX_ERRORTYPE omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp, 735 OMX_IN OMX_COMMANDTYPE cmd, 736 OMX_IN OMX_U32 param1, 737 OMX_IN OMX_PTR cmdData 738 ) 739 { 740 if(m_state == OMX_StateInvalid) 741 { 742 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n"); 743 return OMX_ErrorInvalidState; 744 } 745 746 if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable) 747 { 748 if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH)) 749 { 750 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n"); 751 return OMX_ErrorBadPortIndex; 752 } 753 } 754 if(cmd == OMX_CommandMarkBuffer) 755 { 756 if(param1 != PORT_INDEX_IN) 757 { 758 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n"); 759 return OMX_ErrorBadPortIndex; 760 } 761 if(!cmdData) 762 { 763 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null"); 764 return OMX_ErrorBadParameter; 765 } 766 } 767 768 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND); 769 sem_wait(&m_cmd_lock); 770 return OMX_ErrorNone; 771 } 772 773 /* ====================================================================== 774 FUNCTION 775 omx_venc::SendCommand 776 777 DESCRIPTION 778 Returns zero if all the buffers released.. 779 780 PARAMETERS 781 None. 782 783 RETURN VALUE 784 true/false 785 786 ========================================================================== */ 787 OMX_ERRORTYPE omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp, 788 OMX_IN OMX_COMMANDTYPE cmd, 789 OMX_IN OMX_U32 param1, 790 OMX_IN OMX_PTR cmdData 791 ) 792 { 793 OMX_ERRORTYPE eRet = OMX_ErrorNone; 794 OMX_STATETYPE eState = (OMX_STATETYPE) param1; 795 int bFlag = 1; 796 797 if(cmd == OMX_CommandStateSet) 798 { 799 /***************************/ 800 /* Current State is Loaded */ 801 /***************************/ 802 if(m_state == OMX_StateLoaded) 803 { 804 if(eState == OMX_StateIdle) 805 { 806 //if all buffers are allocated or all ports disabled 807 if(allocate_done() || 808 ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE)) 809 { 810 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle\n"); 811 } 812 else 813 { 814 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n"); 815 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING); 816 // Skip the event notification 817 bFlag = 0; 818 } 819 } 820 /* Requesting transition from Loaded to Loaded */ 821 else if(eState == OMX_StateLoaded) 822 { 823 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded\n"); 824 post_event(OMX_EventError,OMX_ErrorSameState,\ 825 OMX_COMPONENT_GENERATE_EVENT); 826 eRet = OMX_ErrorSameState; 827 } 828 /* Requesting transition from Loaded to WaitForResources */ 829 else if(eState == OMX_StateWaitForResources) 830 { 831 /* Since error is None , we will post an event 832 at the end of this function definition */ 833 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources\n"); 834 } 835 /* Requesting transition from Loaded to Executing */ 836 else if(eState == OMX_StateExecuting) 837 { 838 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n"); 839 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 840 OMX_COMPONENT_GENERATE_EVENT); 841 eRet = OMX_ErrorIncorrectStateTransition; 842 } 843 /* Requesting transition from Loaded to Pause */ 844 else if(eState == OMX_StatePause) 845 { 846 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause\n"); 847 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 848 OMX_COMPONENT_GENERATE_EVENT); 849 eRet = OMX_ErrorIncorrectStateTransition; 850 } 851 /* Requesting transition from Loaded to Invalid */ 852 else if(eState == OMX_StateInvalid) 853 { 854 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid\n"); 855 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 856 eRet = OMX_ErrorInvalidState; 857 } 858 else 859 { 860 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled\n",\ 861 eState); 862 eRet = OMX_ErrorBadParameter; 863 } 864 } 865 866 /***************************/ 867 /* Current State is IDLE */ 868 /***************************/ 869 else if(m_state == OMX_StateIdle) 870 { 871 if(eState == OMX_StateLoaded) 872 { 873 if(release_done()) 874 { 875 /* 876 Since error is None , we will post an event at the end 877 of this function definition 878 */ 879 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded\n"); 880 if(dev_stop() != 0) 881 { 882 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded"); 883 eRet = OMX_ErrorHardware; 884 } 885 } 886 else 887 { 888 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n"); 889 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING); 890 // Skip the event notification 891 bFlag = 0; 892 } 893 } 894 /* Requesting transition from Idle to Executing */ 895 else if(eState == OMX_StateExecuting) 896 { 897 if( dev_start() ) 898 { 899 DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Exe\n"); 900 omx_report_error (); 901 eRet = OMX_ErrorHardware; 902 } 903 else 904 { 905 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); 906 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n"); 907 bFlag = 0; 908 } 909 910 dev_start_done(); 911 } 912 /* Requesting transition from Idle to Idle */ 913 else if(eState == OMX_StateIdle) 914 { 915 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n"); 916 post_event(OMX_EventError,OMX_ErrorSameState,\ 917 OMX_COMPONENT_GENERATE_EVENT); 918 eRet = OMX_ErrorSameState; 919 } 920 /* Requesting transition from Idle to WaitForResources */ 921 else if(eState == OMX_StateWaitForResources) 922 { 923 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources\n"); 924 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 925 OMX_COMPONENT_GENERATE_EVENT); 926 eRet = OMX_ErrorIncorrectStateTransition; 927 } 928 /* Requesting transition from Idle to Pause */ 929 else if(eState == OMX_StatePause) 930 { 931 /*To pause the Video core we need to start the driver*/ 932 if( dev_start() ) 933 { 934 DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Pause\n"); 935 omx_report_error (); 936 eRet = OMX_ErrorHardware; 937 } 938 else 939 { 940 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 941 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause\n"); 942 bFlag = 0; 943 } 944 } 945 /* Requesting transition from Idle to Invalid */ 946 else if(eState == OMX_StateInvalid) 947 { 948 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->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: Idle --> %d Not Handled\n",eState); 955 eRet = OMX_ErrorBadParameter; 956 } 957 } 958 959 /******************************/ 960 /* Current State is Executing */ 961 /******************************/ 962 else if(m_state == OMX_StateExecuting) 963 { 964 /* Requesting transition from Executing to Idle */ 965 if(eState == OMX_StateIdle) 966 { 967 /* Since error is None , we will post an event 968 at the end of this function definition 969 */ 970 DEBUG_PRINT_LOW("\n OMXCORE-SM: Executing --> Idle \n"); 971 //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle 972 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 973 execute_omx_flush(OMX_ALL); 974 bFlag = 0; 975 dev_stop_done(); 976 } 977 /* Requesting transition from Executing to Paused */ 978 else if(eState == OMX_StatePause) 979 { 980 981 if(dev_pause()) 982 { 983 DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n"); 984 post_event(OMX_EventError,OMX_ErrorHardware,\ 985 OMX_COMPONENT_GENERATE_EVENT); 986 eRet = OMX_ErrorHardware; 987 } 988 else 989 { 990 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING); 991 DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause\n"); 992 bFlag = 0; 993 } 994 } 995 /* Requesting transition from Executing to Loaded */ 996 else if(eState == OMX_StateLoaded) 997 { 998 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n"); 999 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1000 OMX_COMPONENT_GENERATE_EVENT); 1001 eRet = OMX_ErrorIncorrectStateTransition; 1002 } 1003 /* Requesting transition from Executing to WaitForResources */ 1004 else if(eState == OMX_StateWaitForResources) 1005 { 1006 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n"); 1007 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1008 OMX_COMPONENT_GENERATE_EVENT); 1009 eRet = OMX_ErrorIncorrectStateTransition; 1010 } 1011 /* Requesting transition from Executing to Executing */ 1012 else if(eState == OMX_StateExecuting) 1013 { 1014 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Executing \n"); 1015 post_event(OMX_EventError,OMX_ErrorSameState,\ 1016 OMX_COMPONENT_GENERATE_EVENT); 1017 eRet = OMX_ErrorSameState; 1018 } 1019 /* Requesting transition from Executing to Invalid */ 1020 else if(eState == OMX_StateInvalid) 1021 { 1022 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Invalid \n"); 1023 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1024 eRet = OMX_ErrorInvalidState; 1025 } 1026 else 1027 { 1028 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",eState); 1029 eRet = OMX_ErrorBadParameter; 1030 } 1031 } 1032 /***************************/ 1033 /* Current State is Pause */ 1034 /***************************/ 1035 else if(m_state == OMX_StatePause) 1036 { 1037 /* Requesting transition from Pause to Executing */ 1038 if(eState == OMX_StateExecuting) 1039 { 1040 DEBUG_PRINT_LOW("\n Pause --> Executing \n"); 1041 if( dev_resume() ) 1042 { 1043 post_event(OMX_EventError,OMX_ErrorHardware,\ 1044 OMX_COMPONENT_GENERATE_EVENT); 1045 eRet = OMX_ErrorHardware; 1046 } 1047 else 1048 { 1049 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING); 1050 DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing\n"); 1051 post_event (NULL, NULL, OMX_COMPONENT_GENERATE_RESUME_DONE); 1052 bFlag = 0; 1053 } 1054 } 1055 /* Requesting transition from Pause to Idle */ 1056 else if(eState == OMX_StateIdle) 1057 { 1058 /* Since error is None , we will post an event 1059 at the end of this function definition */ 1060 DEBUG_PRINT_LOW("\n Pause --> Idle \n"); 1061 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING); 1062 execute_omx_flush(OMX_ALL); 1063 bFlag = 0; 1064 } 1065 /* Requesting transition from Pause to loaded */ 1066 else if(eState == OMX_StateLoaded) 1067 { 1068 DEBUG_PRINT_ERROR("\nERROR: Pause --> loaded \n"); 1069 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1070 OMX_COMPONENT_GENERATE_EVENT); 1071 eRet = OMX_ErrorIncorrectStateTransition; 1072 } 1073 /* Requesting transition from Pause to WaitForResources */ 1074 else if(eState == OMX_StateWaitForResources) 1075 { 1076 DEBUG_PRINT_ERROR("\nERROR: Pause --> WaitForResources \n"); 1077 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1078 OMX_COMPONENT_GENERATE_EVENT); 1079 eRet = OMX_ErrorIncorrectStateTransition; 1080 } 1081 /* Requesting transition from Pause to Pause */ 1082 else if(eState == OMX_StatePause) 1083 { 1084 DEBUG_PRINT_ERROR("\nERROR: Pause --> Pause \n"); 1085 post_event(OMX_EventError,OMX_ErrorSameState,\ 1086 OMX_COMPONENT_GENERATE_EVENT); 1087 eRet = OMX_ErrorSameState; 1088 } 1089 /* Requesting transition from Pause to Invalid */ 1090 else if(eState == OMX_StateInvalid) 1091 { 1092 DEBUG_PRINT_ERROR("\nERROR: Pause --> Invalid \n"); 1093 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1094 eRet = OMX_ErrorInvalidState; 1095 } 1096 else 1097 { 1098 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",eState); 1099 eRet = OMX_ErrorBadParameter; 1100 } 1101 } 1102 /***************************/ 1103 /* Current State is WaitForResources */ 1104 /***************************/ 1105 else if(m_state == OMX_StateWaitForResources) 1106 { 1107 /* Requesting transition from WaitForResources to Loaded */ 1108 if(eState == OMX_StateLoaded) 1109 { 1110 /* Since error is None , we will post an event 1111 at the end of this function definition */ 1112 DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded\n"); 1113 } 1114 /* Requesting transition from WaitForResources to WaitForResources */ 1115 else if(eState == OMX_StateWaitForResources) 1116 { 1117 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n"); 1118 post_event(OMX_EventError,OMX_ErrorSameState, 1119 OMX_COMPONENT_GENERATE_EVENT); 1120 eRet = OMX_ErrorSameState; 1121 } 1122 /* Requesting transition from WaitForResources to Executing */ 1123 else if(eState == OMX_StateExecuting) 1124 { 1125 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing\n"); 1126 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1127 OMX_COMPONENT_GENERATE_EVENT); 1128 eRet = OMX_ErrorIncorrectStateTransition; 1129 } 1130 /* Requesting transition from WaitForResources to Pause */ 1131 else if(eState == OMX_StatePause) 1132 { 1133 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause\n"); 1134 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\ 1135 OMX_COMPONENT_GENERATE_EVENT); 1136 eRet = OMX_ErrorIncorrectStateTransition; 1137 } 1138 /* Requesting transition from WaitForResources to Invalid */ 1139 else if(eState == OMX_StateInvalid) 1140 { 1141 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid\n"); 1142 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT); 1143 eRet = OMX_ErrorInvalidState; 1144 } 1145 /* Requesting transition from WaitForResources to Loaded - 1146 is NOT tested by Khronos TS */ 1147 1148 } 1149 else 1150 { 1151 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)\n",m_state,eState); 1152 eRet = OMX_ErrorBadParameter; 1153 } 1154 } 1155 /********************************/ 1156 /* Current State is Invalid */ 1157 /*******************************/ 1158 else if(m_state == OMX_StateInvalid) 1159 { 1160 /* State Transition from Inavlid to any state */ 1161 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources 1162 || OMX_StateIdle || OMX_StateExecuting 1163 || OMX_StatePause || OMX_StateInvalid)) 1164 { 1165 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded\n"); 1166 post_event(OMX_EventError,OMX_ErrorInvalidState,\ 1167 OMX_COMPONENT_GENERATE_EVENT); 1168 eRet = OMX_ErrorInvalidState; 1169 } 1170 } 1171 else if(cmd == OMX_CommandFlush) 1172 { 1173 if(0 == param1 || OMX_ALL == param1) 1174 { 1175 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING); 1176 } 1177 if(1 == param1 || OMX_ALL == param1) 1178 { 1179 //generate output flush event only. 1180 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING); 1181 } 1182 1183 execute_omx_flush(param1); 1184 bFlag = 0; 1185 } 1186 else if( cmd == OMX_CommandPortEnable) 1187 { 1188 if(param1 == PORT_INDEX_IN || param1 == OMX_ALL) 1189 { 1190 m_sInPortDef.bEnabled = OMX_TRUE; 1191 1192 if( (m_state == OMX_StateLoaded && 1193 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 1194 || allocate_input_done()) 1195 { 1196 post_event(OMX_CommandPortEnable,PORT_INDEX_IN, 1197 OMX_COMPONENT_GENERATE_EVENT); 1198 } 1199 else 1200 { 1201 DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n"); 1202 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING); 1203 // Skip the event notification 1204 bFlag = 0; 1205 } 1206 } 1207 if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL) 1208 { 1209 m_sOutPortDef.bEnabled = OMX_TRUE; 1210 1211 if( (m_state == OMX_StateLoaded && 1212 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 1213 || (allocate_output_done())) 1214 { 1215 post_event(OMX_CommandPortEnable,PORT_INDEX_OUT, 1216 OMX_COMPONENT_GENERATE_EVENT); 1217 1218 } 1219 else 1220 { 1221 DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n"); 1222 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 1223 // Skip the event notification 1224 bFlag = 0; 1225 } 1226 } 1227 } 1228 else if(cmd == OMX_CommandPortDisable) 1229 { 1230 if(param1 == PORT_INDEX_IN || param1 == OMX_ALL) 1231 { 1232 m_sInPortDef.bEnabled = OMX_FALSE; 1233 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 1234 && release_input_done()) 1235 { 1236 post_event(OMX_CommandPortDisable,PORT_INDEX_IN, 1237 OMX_COMPONENT_GENERATE_EVENT); 1238 } 1239 else 1240 { 1241 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING); 1242 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) 1243 { 1244 execute_omx_flush(PORT_INDEX_IN); 1245 } 1246 1247 // Skip the event notification 1248 bFlag = 0; 1249 } 1250 } 1251 if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL) 1252 { 1253 m_sOutPortDef.bEnabled = OMX_FALSE; 1254 1255 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle) 1256 && release_output_done()) 1257 { 1258 post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\ 1259 OMX_COMPONENT_GENERATE_EVENT); 1260 } 1261 else 1262 { 1263 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 1264 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting) 1265 { 1266 execute_omx_flush(PORT_INDEX_OUT); 1267 } 1268 // Skip the event notification 1269 bFlag = 0; 1270 1271 } 1272 } 1273 } 1274 else 1275 { 1276 DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)\n",cmd); 1277 eRet = OMX_ErrorNotImplemented; 1278 } 1279 if(eRet == OMX_ErrorNone && bFlag) 1280 { 1281 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT); 1282 } 1283 sem_post(&m_cmd_lock); 1284 return eRet; 1285 } 1286 1287 /* ====================================================================== 1288 FUNCTION 1289 omx_venc::ExecuteOmxFlush 1290 1291 DESCRIPTION 1292 Executes the OMX flush. 1293 1294 PARAMETERS 1295 flushtype - input flush(1)/output flush(0)/ both. 1296 1297 RETURN VALUE 1298 true/false 1299 1300 ========================================================================== */ 1301 bool omx_video::execute_omx_flush(OMX_U32 flushType) 1302 { 1303 bool bRet = false; 1304 DEBUG_PRINT_LOW("\n execute_omx_flush - %d\n", flushType); 1305 if(flushType == 0 || flushType == OMX_ALL) 1306 { 1307 input_flush_progress = true; 1308 //flush input only 1309 bRet = execute_input_flush(); 1310 } 1311 if(flushType == 1 || flushType == OMX_ALL) 1312 { 1313 //flush output only 1314 output_flush_progress = true; 1315 bRet = execute_output_flush(); 1316 } 1317 return bRet; 1318 } 1319 /*========================================================================= 1320 FUNCTION : execute_output_flush 1321 1322 DESCRIPTION 1323 Executes the OMX flush at OUTPUT PORT. 1324 1325 PARAMETERS 1326 None. 1327 1328 RETURN VALUE 1329 true/false 1330 ==========================================================================*/ 1331 bool omx_video::execute_output_flush(void) 1332 { 1333 unsigned p1 = 0; // Parameter - 1 1334 unsigned p2 = 0; // Parameter - 2 1335 unsigned ident = 0; 1336 bool bRet = true; 1337 1338 /*Generate FBD for all Buffers in the FTBq*/ 1339 DEBUG_PRINT_LOW("\n execute_output_flush\n"); 1340 pthread_mutex_lock(&m_lock); 1341 while(m_ftb_q.m_size) 1342 { 1343 m_ftb_q.pop_entry(&p1,&p2,&ident); 1344 1345 if(ident == OMX_COMPONENT_GENERATE_FTB ) 1346 { 1347 pending_output_buffers++; 1348 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 1349 } 1350 else if(ident == OMX_COMPONENT_GENERATE_FBD) 1351 { 1352 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 1353 } 1354 } 1355 1356 pthread_mutex_unlock(&m_lock); 1357 /*Check if there are buffers with the Driver*/ 1358 if(dev_flush(PORT_INDEX_OUT)) 1359 { 1360 DEBUG_PRINT_ERROR("\nERROR: o/p dev_flush() Failed"); 1361 return false; 1362 } 1363 1364 return bRet; 1365 } 1366 /*========================================================================= 1367 FUNCTION : execute_input_flush 1368 1369 DESCRIPTION 1370 Executes the OMX flush at INPUT PORT. 1371 1372 PARAMETERS 1373 None. 1374 1375 RETURN VALUE 1376 true/false 1377 ==========================================================================*/ 1378 bool omx_video::execute_input_flush(void) 1379 { 1380 unsigned p1 = 0; // Parameter - 1 1381 unsigned p2 = 0; // Parameter - 2 1382 unsigned ident = 0; 1383 bool bRet = true; 1384 1385 /*Generate EBD for all Buffers in the ETBq*/ 1386 DEBUG_PRINT_LOW("\n execute_input_flush\n"); 1387 1388 pthread_mutex_lock(&m_lock); 1389 while(m_etb_q.m_size) 1390 { 1391 m_etb_q.pop_entry(&p1,&p2,&ident); 1392 if(ident == OMX_COMPONENT_GENERATE_ETB) 1393 { 1394 pending_input_buffers++; 1395 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2); 1396 } 1397 else if(ident == OMX_COMPONENT_GENERATE_EBD) 1398 { 1399 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1); 1400 } 1401 else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ) 1402 { 1403 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2); 1404 } 1405 } 1406 if(mUseProxyColorFormat) { 1407 if(psource_frame) { 1408 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame); 1409 psource_frame = NULL; 1410 } 1411 while(m_opq_meta_q.m_size) { 1412 unsigned p1,p2,id; 1413 m_opq_meta_q.pop_entry(&p1,&p2,&id); 1414 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data, 1415 (OMX_BUFFERHEADERTYPE *)p1); 1416 } 1417 if(pdest_frame){ 1418 m_opq_pmem_q.insert_entry((unsigned int)pdest_frame,0,0); 1419 pdest_frame = NULL; 1420 } 1421 } 1422 pthread_mutex_unlock(&m_lock); 1423 /*Check if there are buffers with the Driver*/ 1424 if(dev_flush(PORT_INDEX_IN)) 1425 { 1426 DEBUG_PRINT_ERROR("\nERROR: i/p dev_flush() Failed"); 1427 return false; 1428 } 1429 1430 return bRet; 1431 } 1432 1433 1434 /* ====================================================================== 1435 FUNCTION 1436 omx_venc::SendCommandEvent 1437 1438 DESCRIPTION 1439 Send the event to decoder pipe. This is needed to generate the callbacks 1440 in decoder thread context. 1441 1442 PARAMETERS 1443 None. 1444 1445 RETURN VALUE 1446 true/false 1447 1448 ========================================================================== */ 1449 bool omx_video::post_event(unsigned int p1, 1450 unsigned int p2, 1451 unsigned int id) 1452 { 1453 bool bRet = false; 1454 1455 1456 pthread_mutex_lock(&m_lock); 1457 1458 if( id == OMX_COMPONENT_GENERATE_FTB || \ 1459 (id == OMX_COMPONENT_GENERATE_FRAME_DONE)) 1460 { 1461 m_ftb_q.insert_entry(p1,p2,id); 1462 } 1463 else if((id == m_input_msg_id) \ 1464 || (id == OMX_COMPONENT_GENERATE_EBD)) 1465 { 1466 m_etb_q.insert_entry(p1,p2,id); 1467 } 1468 else 1469 { 1470 m_cmd_q.insert_entry(p1,p2,id); 1471 } 1472 1473 bRet = true; 1474 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this); 1475 post_message(this, id); 1476 pthread_mutex_unlock(&m_lock); 1477 1478 return bRet; 1479 } 1480 1481 /* ====================================================================== 1482 FUNCTION 1483 omx_venc::GetParameter 1484 1485 DESCRIPTION 1486 OMX Get Parameter method implementation 1487 1488 PARAMETERS 1489 <TBD>. 1490 1491 RETURN VALUE 1492 Error None if successful. 1493 1494 ========================================================================== */ 1495 OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp, 1496 OMX_IN OMX_INDEXTYPE paramIndex, 1497 OMX_INOUT OMX_PTR paramData) 1498 { 1499 OMX_ERRORTYPE eRet = OMX_ErrorNone; 1500 unsigned int height=0,width = 0; 1501 1502 DEBUG_PRINT_LOW("get_parameter: \n"); 1503 if(m_state == OMX_StateInvalid) 1504 { 1505 DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n"); 1506 return OMX_ErrorInvalidState; 1507 } 1508 if(paramData == NULL) 1509 { 1510 DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n"); 1511 return OMX_ErrorBadParameter; 1512 } 1513 switch(paramIndex) 1514 { 1515 case OMX_IndexParamPortDefinition: 1516 { 1517 OMX_PARAM_PORTDEFINITIONTYPE *portDefn; 1518 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData; 1519 1520 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n"); 1521 if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN) 1522 { 1523 DEBUG_PRINT_LOW("m_sInPortDef: size = %d, min cnt = %d, actual cnt = %d", 1524 m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountMin, 1525 m_sInPortDef.nBufferCountActual); 1526 memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef)); 1527 #ifdef _ANDROID_ICS_ 1528 if(meta_mode_enable) 1529 { 1530 portDefn->nBufferSize = sizeof(encoder_media_buffer_type); 1531 } 1532 if(secure_session) { 1533 portDefn->format.video.eColorFormat = 1534 (OMX_COLOR_FORMATTYPE)secure_color_format; 1535 } 1536 else if (mUseProxyColorFormat) { 1537 portDefn->format.video.eColorFormat = 1538 (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque; 1539 } 1540 #endif 1541 } 1542 else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 1543 { 1544 dev_get_buf_req (&m_sOutPortDef.nBufferCountMin, 1545 &m_sOutPortDef.nBufferCountActual, 1546 &m_sOutPortDef.nBufferSize, 1547 m_sOutPortDef.nPortIndex); 1548 DEBUG_PRINT_LOW("m_sOutPortDef: size = %d, min cnt = %d, actual cnt = %d", 1549 m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountMin, 1550 m_sOutPortDef.nBufferCountActual); 1551 memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef)); 1552 } 1553 else 1554 { 1555 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); 1556 eRet = OMX_ErrorBadPortIndex; 1557 } 1558 break; 1559 } 1560 case OMX_IndexParamVideoInit: 1561 { 1562 OMX_PORT_PARAM_TYPE *portParamType = 1563 (OMX_PORT_PARAM_TYPE *) paramData; 1564 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n"); 1565 1566 memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam)); 1567 break; 1568 } 1569 case OMX_IndexParamVideoPortFormat: 1570 { 1571 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt = 1572 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData; 1573 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n"); 1574 1575 if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN) 1576 { 1577 int index = portFmt->nIndex; 1578 1579 if (index > 1) { 1580 eRet = OMX_ErrorNoMore; 1581 } else { 1582 memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat)); 1583 #ifdef _ANDROID_ICS_ 1584 if (index == 1) { 1585 //we support two formats 1586 //index 0 - YUV420SP 1587 //index 1 - opaque which internally maps to YUV420SP. 1588 //this can be extended in the future 1589 portFmt->nIndex = index; //restore index set from client 1590 portFmt->eColorFormat = 1591 (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque; 1592 } 1593 } 1594 #endif 1595 } 1596 else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 1597 { 1598 memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat)); 1599 } 1600 else 1601 { 1602 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); 1603 eRet = OMX_ErrorBadPortIndex; 1604 } 1605 break; 1606 } 1607 case OMX_IndexParamVideoBitrate: 1608 { 1609 OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData; 1610 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n"); 1611 1612 if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT) 1613 { 1614 memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate)); 1615 } 1616 else 1617 { 1618 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); 1619 eRet = OMX_ErrorBadPortIndex; 1620 } 1621 1622 break; 1623 } 1624 case OMX_IndexParamVideoMpeg4: 1625 { 1626 OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData; 1627 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n"); 1628 memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4)); 1629 break; 1630 } 1631 case OMX_IndexParamVideoH263: 1632 { 1633 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData; 1634 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n"); 1635 memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263)); 1636 break; 1637 } 1638 case OMX_IndexParamVideoAvc: 1639 { 1640 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData; 1641 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n"); 1642 memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC)); 1643 break; 1644 } 1645 case OMX_IndexParamVideoProfileLevelQuerySupported: 1646 { 1647 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; 1648 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n"); 1649 eRet = get_supported_profile_level(pParam); 1650 if(eRet) 1651 DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %d, %d", 1652 pParam->eProfile, pParam->eLevel); 1653 break; 1654 } 1655 case OMX_IndexParamVideoProfileLevelCurrent: 1656 { 1657 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData; 1658 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n"); 1659 memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel)); 1660 break; 1661 } 1662 /*Component should support this port definition*/ 1663 case OMX_IndexParamAudioInit: 1664 { 1665 OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData; 1666 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n"); 1667 memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio)); 1668 break; 1669 } 1670 /*Component should support this port definition*/ 1671 case OMX_IndexParamImageInit: 1672 { 1673 OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData; 1674 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n"); 1675 memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img)); 1676 break; 1677 1678 } 1679 /*Component should support this port definition*/ 1680 case OMX_IndexParamOtherInit: 1681 { 1682 DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x\n", paramIndex); 1683 eRet =OMX_ErrorUnsupportedIndex; 1684 break; 1685 } 1686 case OMX_IndexParamStandardComponentRole: 1687 { 1688 OMX_PARAM_COMPONENTROLETYPE *comp_role; 1689 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData; 1690 comp_role->nVersion.nVersion = OMX_SPEC_VERSION; 1691 comp_role->nSize = sizeof(*comp_role); 1692 1693 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",paramIndex); 1694 if(NULL != comp_role->cRole) 1695 { 1696 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE); 1697 } 1698 else 1699 { 1700 DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role\n",paramIndex); 1701 eRet =OMX_ErrorBadParameter; 1702 } 1703 break; 1704 } 1705 /* Added for parameter test */ 1706 case OMX_IndexParamPriorityMgmt: 1707 { 1708 1709 OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData; 1710 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n"); 1711 memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt)); 1712 break; 1713 } 1714 /* Added for parameter test */ 1715 case OMX_IndexParamCompBufferSupplier: 1716 { 1717 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData; 1718 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n"); 1719 if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN) 1720 { 1721 memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier)); 1722 } 1723 else if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT) 1724 { 1725 memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier)); 1726 } 1727 else 1728 { 1729 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index"); 1730 eRet = OMX_ErrorBadPortIndex; 1731 } 1732 break; 1733 } 1734 1735 case OMX_IndexParamVideoQuantization: 1736 { 1737 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData; 1738 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization\n"); 1739 memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization)); 1740 break; 1741 } 1742 1743 case OMX_IndexParamVideoErrorCorrection: 1744 { 1745 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData; 1746 DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n"); 1747 errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC; 1748 errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync; 1749 errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing; 1750 break; 1751 } 1752 case OMX_IndexParamVideoIntraRefresh: 1753 { 1754 OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData; 1755 DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh\n"); 1756 DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET\n"); 1757 intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode; 1758 intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs; 1759 break; 1760 } 1761 case OMX_QcomIndexPortDefn: 1762 //TODO 1763 break; 1764 case OMX_COMPONENT_CAPABILITY_TYPE_INDEX: 1765 { 1766 OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData); 1767 DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX\n"); 1768 pParam->iIsOMXComponentMultiThreaded = OMX_TRUE; 1769 pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE; 1770 pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE; 1771 pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE; 1772 pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE; 1773 pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE; 1774 pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE; 1775 pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE; 1776 m_use_input_pmem = OMX_TRUE; 1777 DEBUG_PRINT_LOW("Supporting capability index in encoder node"); 1778 break; 1779 } 1780 #ifndef MAX_RES_720P 1781 case OMX_QcomIndexParamIndexExtraDataType: 1782 { 1783 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType"); 1784 QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData; 1785 if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo) 1786 { 1787 if (pParam->nPortIndex == PORT_INDEX_OUT) 1788 { 1789 pParam->bEnabled = 1790 (OMX_BOOL)((m_sExtraData & VEN_EXTRADATA_SLICEINFO) ? 1 : 0); 1791 DEBUG_PRINT_HIGH("Slice Info extradata %d", pParam->bEnabled); 1792 } 1793 else 1794 { 1795 DEBUG_PRINT_ERROR("get_parameter: slice information is " 1796 "valid for output port only"); 1797 eRet =OMX_ErrorUnsupportedIndex; 1798 } 1799 } 1800 else 1801 { 1802 DEBUG_PRINT_ERROR("get_parameter: unsupported index (%x), " 1803 "only slice information extradata is supported", pParam->nIndex); 1804 eRet =OMX_ErrorUnsupportedIndex; 1805 } 1806 break; 1807 } 1808 #endif 1809 case QOMX_IndexParamVideoSyntaxHdr: 1810 { 1811 DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr"); 1812 QOMX_EXTNINDEX_PARAMTYPE* pParam = 1813 reinterpret_cast<QOMX_EXTNINDEX_PARAMTYPE*>(paramData); 1814 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_START_PENDING); 1815 if(dev_loaded_start()) 1816 { 1817 DEBUG_PRINT_LOW("device start successful"); 1818 } 1819 else 1820 { 1821 DEBUG_PRINT_ERROR("device start failed"); 1822 BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_START_PENDING); 1823 return OMX_ErrorHardware; 1824 } 1825 if(dev_get_seq_hdr(pParam->pData, 1826 (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)), 1827 (unsigned *)&pParam->nDataSize)) 1828 { 1829 DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %d)", 1830 pParam->nDataSize); 1831 for (unsigned i = 0; i < pParam->nDataSize; i++) { 1832 DEBUG_PRINT_LOW("Header[%d] = %x", i, *((char *)pParam->pData + i)); 1833 } 1834 } 1835 else 1836 { 1837 DEBUG_PRINT_ERROR("Error returned from GetSyntaxHeader()"); 1838 eRet = OMX_ErrorHardware; 1839 } 1840 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING); 1841 if(dev_loaded_stop()) 1842 { 1843 DEBUG_PRINT_LOW("device stop successful"); 1844 } 1845 else 1846 { 1847 DEBUG_PRINT_ERROR("device stop failed"); 1848 BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING); 1849 eRet = OMX_ErrorHardware; 1850 } 1851 break; 1852 } 1853 case OMX_IndexParamVideoSliceFMO: 1854 default: 1855 { 1856 DEBUG_PRINT_ERROR("ERROR: get_parameter: unknown param %08x\n", paramIndex); 1857 eRet =OMX_ErrorUnsupportedIndex; 1858 break; 1859 } 1860 1861 } 1862 1863 return eRet; 1864 1865 } 1866 /* ====================================================================== 1867 FUNCTION 1868 omx_video::GetConfig 1869 1870 DESCRIPTION 1871 OMX Get Config Method implementation. 1872 1873 PARAMETERS 1874 <TBD>. 1875 1876 RETURN VALUE 1877 OMX Error None if successful. 1878 1879 ========================================================================== */ 1880 OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, 1881 OMX_IN OMX_INDEXTYPE configIndex, 1882 OMX_INOUT OMX_PTR configData) 1883 { 1884 //////////////////////////////////////////////////////////////// 1885 // Supported Config Index Type 1886 // ============================================================= 1887 // OMX_IndexConfigVideoBitrate OMX_VIDEO_CONFIG_BITRATETYPE 1888 // OMX_IndexConfigVideoFramerate OMX_CONFIG_FRAMERATETYPE 1889 // OMX_IndexConfigCommonRotate OMX_CONFIG_ROTATIONTYPE 1890 //////////////////////////////////////////////////////////////// 1891 1892 if(configData == NULL) 1893 { 1894 DEBUG_PRINT_ERROR("ERROR: param is null"); 1895 return OMX_ErrorBadParameter; 1896 } 1897 1898 if(m_state == OMX_StateInvalid) 1899 { 1900 DEBUG_PRINT_ERROR("ERROR: can't be in invalid state"); 1901 return OMX_ErrorIncorrectStateOperation; 1902 } 1903 1904 //@todo need to validate params 1905 switch(configIndex) 1906 { 1907 case OMX_IndexConfigVideoBitrate: 1908 { 1909 OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData); 1910 memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate)); 1911 break; 1912 } 1913 case OMX_IndexConfigVideoFramerate: 1914 { 1915 OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData); 1916 memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate)); 1917 break; 1918 } 1919 case OMX_IndexConfigCommonRotate: 1920 { 1921 OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData); 1922 memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation)); 1923 break; 1924 } 1925 case QOMX_IndexConfigVideoIntraperiod: 1926 { 1927 DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod\n"); 1928 QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData); 1929 memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod)); 1930 break; 1931 } 1932 default: 1933 DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); 1934 return OMX_ErrorUnsupportedIndex; 1935 } 1936 return OMX_ErrorNone; 1937 1938 } 1939 1940 /* ====================================================================== 1941 FUNCTION 1942 omx_video::GetExtensionIndex 1943 1944 DESCRIPTION 1945 OMX GetExtensionIndex method implementaion. <TBD> 1946 1947 PARAMETERS 1948 <TBD>. 1949 1950 RETURN VALUE 1951 OMX Error None if everything successful. 1952 1953 ========================================================================== */ 1954 OMX_ERRORTYPE omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, 1955 OMX_IN OMX_STRING paramName, 1956 OMX_OUT OMX_INDEXTYPE* indexType) 1957 { 1958 char *extns[] = { 1959 "OMX.QCOM.index.param.SliceDeliveryMode", 1960 "OMX.google.android.index.storeMetaDataInBuffers", 1961 "OMX.google.android.index.prependSPSPPSToIDRFrames", 1962 "OMX.google.android.index.setVUIStreamRestrictFlag" 1963 }; 1964 1965 if(m_state == OMX_StateInvalid) 1966 { 1967 DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State\n"); 1968 return OMX_ErrorInvalidState; 1969 } 1970 #ifdef MAX_RES_1080P 1971 if (!strncmp(paramName, extns[0], strlen(extns[0]))) { 1972 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode; 1973 return OMX_ErrorNone; 1974 } 1975 #endif 1976 #ifdef _ANDROID_ICS_ 1977 if (!strncmp(paramName, extns[1], strlen(extns[1]))) { 1978 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode; 1979 return OMX_ErrorNone; 1980 } else if (!strncmp(paramName, extns[2], strlen(extns[2]))) { 1981 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR; 1982 return OMX_ErrorNone; 1983 } else if (!strncmp(paramName, extns[3], strlen(extns[3]))) { 1984 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamEnableVUIStreamRestrictFlag; 1985 return OMX_ErrorNone; 1986 } 1987 #endif 1988 return OMX_ErrorNotImplemented; 1989 } 1990 1991 /* ====================================================================== 1992 FUNCTION 1993 omx_video::GetState 1994 1995 DESCRIPTION 1996 Returns the state information back to the caller.<TBD> 1997 1998 PARAMETERS 1999 <TBD>. 2000 2001 RETURN VALUE 2002 Error None if everything is successful. 2003 ========================================================================== */ 2004 OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp, 2005 OMX_OUT OMX_STATETYPE* state) 2006 { 2007 *state = m_state; 2008 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state); 2009 return OMX_ErrorNone; 2010 } 2011 2012 /* ====================================================================== 2013 FUNCTION 2014 omx_video::ComponentTunnelRequest 2015 2016 DESCRIPTION 2017 OMX Component Tunnel Request method implementation. <TBD> 2018 2019 PARAMETERS 2020 None. 2021 2022 RETURN VALUE 2023 OMX Error None if everything successful. 2024 2025 ========================================================================== */ 2026 OMX_ERRORTYPE omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, 2027 OMX_IN OMX_U32 port, 2028 OMX_IN OMX_HANDLETYPE peerComponent, 2029 OMX_IN OMX_U32 peerPort, 2030 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) 2031 { 2032 DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented\n"); 2033 return OMX_ErrorNotImplemented; 2034 } 2035 2036 /* ====================================================================== 2037 FUNCTION 2038 omx_video::UseInputBuffer 2039 2040 DESCRIPTION 2041 Helper function for Use buffer in the input pin 2042 2043 PARAMETERS 2044 None. 2045 2046 RETURN VALUE 2047 true/false 2048 2049 ========================================================================== */ 2050 OMX_ERRORTYPE omx_video::use_input_buffer( 2051 OMX_IN OMX_HANDLETYPE hComp, 2052 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2053 OMX_IN OMX_U32 port, 2054 OMX_IN OMX_PTR appData, 2055 OMX_IN OMX_U32 bytes, 2056 OMX_IN OMX_U8* buffer) 2057 { 2058 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2059 2060 unsigned i = 0; 2061 unsigned char *buf_addr = NULL; 2062 2063 DEBUG_PRINT_HIGH("use_input_buffer: port = %d appData = %p bytes = %d buffer = %p",port,appData,bytes,buffer); 2064 if(bytes != m_sInPortDef.nBufferSize || secure_session) 2065 { 2066 DEBUG_PRINT_ERROR("\nERROR: use_input_buffer: Size Mismatch!! " 2067 "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sInPortDef.nBufferSize); 2068 return OMX_ErrorBadParameter; 2069 } 2070 2071 if(!m_inp_mem_ptr) 2072 { 2073 input_use_buffer = true; 2074 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 2075 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); 2076 if(m_inp_mem_ptr == NULL) 2077 { 2078 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr"); 2079 return OMX_ErrorInsufficientResources; 2080 } 2081 2082 2083 m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); 2084 if(m_pInput_pmem == NULL) 2085 { 2086 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem"); 2087 return OMX_ErrorInsufficientResources; 2088 } 2089 #ifdef USE_ION 2090 m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual); 2091 if(m_pInput_ion == NULL) 2092 { 2093 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion"); 2094 return OMX_ErrorInsufficientResources; 2095 } 2096 #endif 2097 2098 for(i=0; i< m_sInPortDef.nBufferCountActual; i++) 2099 { 2100 m_pInput_pmem[i].fd = -1; 2101 #ifdef USE_ION 2102 m_pInput_ion[i].ion_device_fd =-1; 2103 m_pInput_ion[i].fd_ion_data.fd =-1; 2104 m_pInput_ion[i].ion_alloc_data.handle=NULL; 2105 #endif 2106 } 2107 2108 } 2109 2110 for(i=0; i< m_sInPortDef.nBufferCountActual; i++) 2111 { 2112 if(BITMASK_ABSENT(&m_inp_bm_count,i)) 2113 { 2114 break; 2115 } 2116 } 2117 2118 if(i < m_sInPortDef.nBufferCountActual) 2119 { 2120 2121 *bufferHdr = (m_inp_mem_ptr + i); 2122 BITMASK_SET(&m_inp_bm_count,i); 2123 2124 (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; 2125 (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2126 (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; 2127 (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; 2128 (*bufferHdr)->pAppPrivate = appData; 2129 (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; 2130 2131 if(!m_use_input_pmem) 2132 { 2133 #ifdef USE_ION 2134 m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, 2135 &m_pInput_ion[i].ion_alloc_data, 2136 &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED); 2137 if(m_pInput_ion[i].ion_device_fd < 0) { 2138 DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); 2139 return OMX_ErrorInsufficientResources; 2140 } 2141 m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd; 2142 #else 2143 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2144 if(m_pInput_pmem[i].fd == 0) 2145 { 2146 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2147 } 2148 2149 if(m_pInput_pmem[i] .fd < 0) 2150 { 2151 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed"); 2152 return OMX_ErrorInsufficientResources; 2153 } 2154 #endif 2155 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; 2156 m_pInput_pmem[i].offset = 0; 2157 m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, 2158 MAP_SHARED,m_pInput_pmem[i].fd,0); 2159 2160 if(m_pInput_pmem[i].buffer == MAP_FAILED) 2161 { 2162 DEBUG_PRINT_ERROR("\nERROR: mmap() Failed"); 2163 close(m_pInput_pmem[i].fd); 2164 #ifdef USE_ION 2165 free_ion_memory(&m_pInput_ion[i]); 2166 #endif 2167 return OMX_ErrorInsufficientResources; 2168 } 2169 } 2170 else 2171 { 2172 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate); 2173 DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset); 2174 2175 if(pParam) 2176 { 2177 m_pInput_pmem[i].fd = pParam->pmem_fd; 2178 m_pInput_pmem[i].offset = pParam->offset; 2179 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; 2180 m_pInput_pmem[i].buffer = (unsigned char *)buffer; 2181 DEBUG_PRINT_LOW("\n DBG:: pParam->pmem_fd = %u, pParam->offset = %u", 2182 pParam->pmem_fd, pParam->offset); 2183 } 2184 else 2185 { 2186 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case"); 2187 return OMX_ErrorBadParameter; 2188 } 2189 } 2190 2191 DEBUG_PRINT_LOW("\nuse_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p", 2192 (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer); 2193 if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true) 2194 { 2195 DEBUG_PRINT_ERROR("\nERROR: dev_use_buf() Failed for i/p buf"); 2196 return OMX_ErrorInsufficientResources; 2197 } 2198 } 2199 else 2200 { 2201 DEBUG_PRINT_ERROR("\nERROR: All buffers are already used, invalid use_buf call for " 2202 "index = %u", i); 2203 eRet = OMX_ErrorInsufficientResources; 2204 } 2205 2206 return eRet; 2207 } 2208 2209 2210 2211 /* ====================================================================== 2212 FUNCTION 2213 omx_video::UseOutputBuffer 2214 2215 DESCRIPTION 2216 Helper function for Use buffer in the input pin 2217 2218 PARAMETERS 2219 None. 2220 2221 RETURN VALUE 2222 true/false 2223 2224 ========================================================================== */ 2225 OMX_ERRORTYPE omx_video::use_output_buffer( 2226 OMX_IN OMX_HANDLETYPE hComp, 2227 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2228 OMX_IN OMX_U32 port, 2229 OMX_IN OMX_PTR appData, 2230 OMX_IN OMX_U32 bytes, 2231 OMX_IN OMX_U8* buffer) 2232 { 2233 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2234 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 2235 unsigned i= 0; // Temporary counter 2236 unsigned char *buf_addr = NULL; 2237 2238 DEBUG_PRINT_HIGH("\n Inside use_output_buffer()"); 2239 if(bytes != m_sOutPortDef.nBufferSize || secure_session) 2240 { 2241 DEBUG_PRINT_ERROR("\nERROR: use_output_buffer: Size Mismatch!! " 2242 "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sOutPortDef.nBufferSize); 2243 return OMX_ErrorBadParameter; 2244 } 2245 2246 if(!m_out_mem_ptr) 2247 { 2248 output_use_buffer = true; 2249 int nBufHdrSize = 0; 2250 2251 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual); 2252 nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); 2253 /* 2254 * Memory for output side involves the following: 2255 * 1. Array of Buffer Headers 2256 * 2. Bitmask array to hold the buffer allocation details 2257 * In order to minimize the memory management entire allocation 2258 * is done in one step. 2259 */ 2260 //OMX Buffer header 2261 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 2262 if(m_out_mem_ptr == NULL) 2263 { 2264 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_out_mem_ptr"); 2265 return OMX_ErrorInsufficientResources; 2266 } 2267 2268 m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual); 2269 if(m_pOutput_pmem == NULL) 2270 { 2271 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem"); 2272 return OMX_ErrorInsufficientResources; 2273 } 2274 #ifdef USE_ION 2275 m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); 2276 if(m_pOutput_ion == NULL) 2277 { 2278 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion"); 2279 return OMX_ErrorInsufficientResources; 2280 } 2281 #endif 2282 if(m_out_mem_ptr) 2283 { 2284 bufHdr = m_out_mem_ptr; 2285 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr); 2286 // Settting the entire storage nicely 2287 for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) 2288 { 2289 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2290 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 2291 bufHdr->nAllocLen = bytes; 2292 bufHdr->nFilledLen = 0; 2293 bufHdr->pAppPrivate = appData; 2294 bufHdr->nOutputPortIndex = PORT_INDEX_OUT; 2295 bufHdr->pBuffer = NULL; 2296 bufHdr++; 2297 m_pOutput_pmem[i].fd = -1; 2298 #ifdef USE_ION 2299 m_pOutput_ion[i].ion_device_fd =-1; 2300 m_pOutput_ion[i].fd_ion_data.fd=-1; 2301 m_pOutput_ion[i].ion_alloc_data.handle =NULL; 2302 #endif 2303 } 2304 } 2305 else 2306 { 2307 DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%x]\n",m_out_mem_ptr); 2308 eRet = OMX_ErrorInsufficientResources; 2309 } 2310 } 2311 2312 for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) 2313 { 2314 if(BITMASK_ABSENT(&m_out_bm_count,i)) 2315 { 2316 break; 2317 } 2318 } 2319 2320 if(eRet == OMX_ErrorNone) 2321 { 2322 if(i < m_sOutPortDef.nBufferCountActual) 2323 { 2324 *bufferHdr = (m_out_mem_ptr + i ); 2325 (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; 2326 (*bufferHdr)->pAppPrivate = appData; 2327 BITMASK_SET(&m_out_bm_count,i); 2328 2329 if(!m_use_output_pmem) 2330 { 2331 #ifdef USE_ION 2332 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory( 2333 m_sOutPortDef.nBufferSize, 2334 &m_pOutput_ion[i].ion_alloc_data, 2335 &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED); 2336 if(m_pOutput_ion[i].ion_device_fd < 0) { 2337 DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); 2338 return OMX_ErrorInsufficientResources; 2339 } 2340 m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; 2341 #else 2342 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2343 2344 if(m_pOutput_pmem[i].fd == 0) 2345 { 2346 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2347 } 2348 2349 if(m_pOutput_pmem[i].fd < 0) 2350 { 2351 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed"); 2352 return OMX_ErrorInsufficientResources; 2353 } 2354 #endif 2355 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; 2356 m_pOutput_pmem[i].offset = 0; 2357 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, 2358 MAP_SHARED,m_pOutput_pmem[i].fd,0); 2359 if(m_pOutput_pmem[i].buffer == MAP_FAILED) 2360 { 2361 DEBUG_PRINT_ERROR("\nERROR: mmap() Failed"); 2362 close(m_pOutput_pmem[i].fd); 2363 #ifdef USE_ION 2364 free_ion_memory(&m_pOutput_ion[i]); 2365 #endif 2366 return OMX_ErrorInsufficientResources; 2367 } 2368 } 2369 else 2370 { 2371 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate); 2372 DEBUG_PRINT_LOW("Inside qcom_ext pParam:0x%x )", pParam); 2373 2374 if(pParam) 2375 { 2376 DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset); 2377 m_pOutput_pmem[i].fd = pParam->pmem_fd; 2378 m_pOutput_pmem[i].offset = pParam->offset; 2379 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; 2380 m_pOutput_pmem[i].buffer = (unsigned char *)buffer; 2381 } 2382 else 2383 { 2384 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case"); 2385 return OMX_ErrorBadParameter; 2386 } 2387 buf_addr = (unsigned char *)buffer; 2388 } 2389 2390 DEBUG_PRINT_LOW("\n use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p", 2391 (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer); 2392 if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) 2393 { 2394 DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf"); 2395 return OMX_ErrorInsufficientResources; 2396 } 2397 } 2398 else 2399 { 2400 DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for " 2401 "index = %u", i); 2402 eRet = OMX_ErrorInsufficientResources; 2403 } 2404 } 2405 return eRet; 2406 } 2407 2408 2409 /* ====================================================================== 2410 FUNCTION 2411 omx_video::UseBuffer 2412 2413 DESCRIPTION 2414 OMX Use Buffer method implementation. 2415 2416 PARAMETERS 2417 <TBD>. 2418 2419 RETURN VALUE 2420 OMX Error None , if everything successful. 2421 2422 ========================================================================== */ 2423 OMX_ERRORTYPE omx_video::use_buffer( 2424 OMX_IN OMX_HANDLETYPE hComp, 2425 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2426 OMX_IN OMX_U32 port, 2427 OMX_IN OMX_PTR appData, 2428 OMX_IN OMX_U32 bytes, 2429 OMX_IN OMX_U8* buffer) 2430 { 2431 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2432 if(m_state == OMX_StateInvalid) 2433 { 2434 DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State\n"); 2435 return OMX_ErrorInvalidState; 2436 } 2437 if(port == PORT_INDEX_IN) 2438 { 2439 eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer); 2440 } 2441 else if(port == PORT_INDEX_OUT) 2442 { 2443 eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); 2444 } 2445 else 2446 { 2447 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); 2448 eRet = OMX_ErrorBadPortIndex; 2449 } 2450 2451 if(eRet == OMX_ErrorNone) 2452 { 2453 if(allocate_done()) 2454 { 2455 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 2456 { 2457 // Send the callback now 2458 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 2459 post_event(OMX_CommandStateSet,OMX_StateIdle, 2460 OMX_COMPONENT_GENERATE_EVENT); 2461 } 2462 } 2463 if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) 2464 { 2465 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) 2466 { 2467 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 2468 post_event(OMX_CommandPortEnable, 2469 PORT_INDEX_IN, 2470 OMX_COMPONENT_GENERATE_EVENT); 2471 } 2472 2473 } 2474 else if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) 2475 { 2476 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) 2477 { 2478 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 2479 post_event(OMX_CommandPortEnable, 2480 PORT_INDEX_OUT, 2481 OMX_COMPONENT_GENERATE_EVENT); 2482 m_event_port_settings_sent = false; 2483 } 2484 } 2485 } 2486 return eRet; 2487 } 2488 2489 OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 2490 { 2491 unsigned int index = 0; 2492 OMX_U8 *temp_buff ; 2493 2494 if(bufferHdr == NULL || m_inp_mem_ptr == NULL) 2495 { 2496 DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]", 2497 bufferHdr, m_inp_mem_ptr); 2498 return OMX_ErrorBadParameter; 2499 } 2500 2501 index = bufferHdr - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); 2502 #ifdef _ANDROID_ICS_ 2503 if(meta_mode_enable) 2504 { 2505 if(index < m_sInPortDef.nBufferCountActual) 2506 { 2507 memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); 2508 memset(&meta_buffers[index], 0, sizeof(meta_buffers[index])); 2509 } 2510 if(!mUseProxyColorFormat) 2511 return OMX_ErrorNone; 2512 else { 2513 c2d_conv.close(); 2514 opaque_buffer_hdr[index] = NULL; 2515 } 2516 } 2517 #endif 2518 if(index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat && 2519 dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) 2520 { 2521 DEBUG_PRINT_LOW("\nERROR: dev_free_buf() Failed for i/p buf"); 2522 } 2523 2524 if(index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) 2525 { 2526 if(m_pInput_pmem[index].fd > 0 && input_use_buffer == false) 2527 { 2528 DEBUG_PRINT_LOW("\n FreeBuffer:: i/p AllocateBuffer case"); 2529 munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); 2530 close (m_pInput_pmem[index].fd); 2531 #ifdef USE_ION 2532 free_ion_memory(&m_pInput_ion[index]); 2533 #endif 2534 m_pInput_pmem[index].fd = -1; 2535 } 2536 else if(m_pInput_pmem[index].fd > 0 && (input_use_buffer == true && 2537 m_use_input_pmem == OMX_FALSE)) 2538 { 2539 DEBUG_PRINT_LOW("\n FreeBuffer:: i/p Heap UseBuffer case"); 2540 if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) 2541 { 2542 DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf"); 2543 } 2544 munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); 2545 close (m_pInput_pmem[index].fd); 2546 #ifdef USE_ION 2547 free_ion_memory(&m_pInput_ion[index]); 2548 #endif 2549 m_pInput_pmem[index].fd = -1; 2550 } 2551 else 2552 { 2553 DEBUG_PRINT_ERROR("\n FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case"); 2554 } 2555 } 2556 return OMX_ErrorNone; 2557 } 2558 2559 OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 2560 { 2561 unsigned int index = 0; 2562 OMX_U8 *temp_buff ; 2563 2564 if(bufferHdr == NULL || m_out_mem_ptr == NULL) 2565 { 2566 DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]", 2567 bufferHdr, m_out_mem_ptr); 2568 return OMX_ErrorBadParameter; 2569 } 2570 index = bufferHdr - m_out_mem_ptr; 2571 2572 if(index < m_sOutPortDef.nBufferCountActual && 2573 dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) 2574 { 2575 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); 2576 } 2577 2578 if(index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) 2579 { 2580 if(m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) 2581 { 2582 DEBUG_PRINT_LOW("\n FreeBuffer:: o/p AllocateBuffer case"); 2583 if(!secure_session) 2584 munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); 2585 close (m_pOutput_pmem[index].fd); 2586 #ifdef USE_ION 2587 free_ion_memory(&m_pOutput_ion[index]); 2588 #endif 2589 m_pOutput_pmem[index].fd = -1; 2590 } 2591 else if( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true 2592 && m_use_output_pmem == OMX_FALSE)) 2593 { 2594 DEBUG_PRINT_LOW("\n FreeBuffer:: o/p Heap UseBuffer case"); 2595 if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) 2596 { 2597 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); 2598 } 2599 munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size); 2600 close (m_pOutput_pmem[index].fd); 2601 #ifdef USE_ION 2602 free_ion_memory(&m_pOutput_ion[index]); 2603 #endif 2604 m_pOutput_pmem[index].fd = -1; 2605 } 2606 else 2607 { 2608 DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case"); 2609 } 2610 } 2611 return OMX_ErrorNone; 2612 } 2613 #ifdef _ANDROID_ICS_ 2614 OMX_ERRORTYPE omx_video::allocate_input_meta_buffer( 2615 OMX_HANDLETYPE hComp, 2616 OMX_BUFFERHEADERTYPE **bufferHdr, 2617 OMX_PTR appData, 2618 OMX_U32 bytes) 2619 { 2620 unsigned index = 0; 2621 if(!bufferHdr || bytes != sizeof(encoder_media_buffer_type)) 2622 { 2623 DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %d", 2624 bufferHdr,bytes); 2625 return OMX_ErrorBadParameter; 2626 } 2627 if(!m_inp_mem_ptr && !mUseProxyColorFormat) 2628 m_inp_mem_ptr = meta_buffer_hdr; 2629 for(index = 0;((index < m_sInPortDef.nBufferCountActual) && 2630 meta_buffer_hdr[index].pBuffer); index++); 2631 if(index == m_sInPortDef.nBufferCountActual) 2632 { 2633 DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer"); 2634 return OMX_ErrorBadParameter; 2635 } 2636 if(mUseProxyColorFormat){ 2637 if(opaque_buffer_hdr[index]){ 2638 DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr"); 2639 return OMX_ErrorBadParameter; 2640 } 2641 if(allocate_input_buffer(hComp,&opaque_buffer_hdr[index], 2642 PORT_INDEX_IN,appData,m_sInPortDef.nBufferSize) != OMX_ErrorNone) { 2643 DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr"); 2644 return OMX_ErrorBadParameter; 2645 } 2646 } 2647 BITMASK_SET(&m_inp_bm_count,index); 2648 *bufferHdr = &meta_buffer_hdr[index]; 2649 memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); 2650 meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]); 2651 meta_buffer_hdr[index].nAllocLen = bytes; 2652 meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION; 2653 meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN; 2654 meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index]; 2655 meta_buffer_hdr[index].pAppPrivate = appData; 2656 if(mUseProxyColorFormat) { 2657 m_opq_pmem_q.insert_entry((unsigned int)opaque_buffer_hdr[index],0,0); 2658 DEBUG_PRINT_HIGH("\n opaque_buffer_hdr insert %p", opaque_buffer_hdr[index]); 2659 } 2660 return OMX_ErrorNone; 2661 } 2662 #endif 2663 /* ====================================================================== 2664 FUNCTION 2665 omx_venc::AllocateInputBuffer 2666 2667 DESCRIPTION 2668 Helper function for allocate buffer in the input pin 2669 2670 PARAMETERS 2671 None. 2672 2673 RETURN VALUE 2674 true/false 2675 2676 ========================================================================== */ 2677 OMX_ERRORTYPE omx_video::allocate_input_buffer( 2678 OMX_IN OMX_HANDLETYPE hComp, 2679 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2680 OMX_IN OMX_U32 port, 2681 OMX_IN OMX_PTR appData, 2682 OMX_IN OMX_U32 bytes) 2683 { 2684 2685 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2686 unsigned i = 0; 2687 2688 DEBUG_PRINT_HIGH("\n allocate_input_buffer()::"); 2689 if(bytes != m_sInPortDef.nBufferSize || secure_session) 2690 { 2691 DEBUG_PRINT_ERROR("\nERROR: Buffer size mismatch error: bytes[%u] != nBufferSize[%u]\n", 2692 bytes, m_sInPortDef.nBufferSize); 2693 return OMX_ErrorBadParameter; 2694 } 2695 2696 if(!m_inp_mem_ptr) 2697 { 2698 DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__, 2699 m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountActual); 2700 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 2701 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); 2702 if(m_inp_mem_ptr == NULL) 2703 { 2704 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr"); 2705 return OMX_ErrorInsufficientResources; 2706 } 2707 2708 m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); 2709 2710 if(m_pInput_pmem == NULL) 2711 { 2712 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem"); 2713 return OMX_ErrorInsufficientResources; 2714 } 2715 #ifdef USE_ION 2716 m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual); 2717 if(m_pInput_ion == NULL) 2718 { 2719 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion"); 2720 return OMX_ErrorInsufficientResources; 2721 } 2722 #endif 2723 for(i=0; i< m_sInPortDef.nBufferCountActual; i++) 2724 { 2725 m_pInput_pmem[i].fd = -1; 2726 #ifdef USE_ION 2727 m_pInput_ion[i].ion_device_fd =-1; 2728 m_pInput_ion[i].fd_ion_data.fd =-1; 2729 m_pInput_ion[i].ion_alloc_data.handle=NULL; 2730 #endif 2731 } 2732 } 2733 2734 for(i=0; i< m_sInPortDef.nBufferCountActual; i++) 2735 { 2736 if(BITMASK_ABSENT(&m_inp_bm_count,i)) 2737 { 2738 break; 2739 } 2740 } 2741 if(i < m_sInPortDef.nBufferCountActual) 2742 { 2743 2744 *bufferHdr = (m_inp_mem_ptr + i); 2745 (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2746 (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; 2747 (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; 2748 (*bufferHdr)->pAppPrivate = appData; 2749 (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; 2750 2751 #ifdef USE_ION 2752 m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, 2753 &m_pInput_ion[i].ion_alloc_data, 2754 &m_pInput_ion[i].fd_ion_data,0); 2755 if(m_pInput_ion[i].ion_device_fd < 0) { 2756 DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); 2757 return OMX_ErrorInsufficientResources; 2758 } 2759 2760 m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd; 2761 #else 2762 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2763 2764 if(m_pInput_pmem[i].fd == 0) 2765 { 2766 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2767 } 2768 2769 if(m_pInput_pmem[i].fd < 0) 2770 { 2771 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed\n"); 2772 return OMX_ErrorInsufficientResources; 2773 } 2774 #endif 2775 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; 2776 m_pInput_pmem[i].offset = 0; 2777 2778 m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, 2779 MAP_SHARED,m_pInput_pmem[i].fd,0); 2780 if(m_pInput_pmem[i].buffer == MAP_FAILED) 2781 { 2782 DEBUG_PRINT_ERROR("\nERROR: mmap FAILED= %d\n", errno); 2783 close(m_pInput_pmem[i].fd); 2784 #ifdef USE_ION 2785 free_ion_memory(&m_pInput_ion[i]); 2786 #endif 2787 return OMX_ErrorInsufficientResources; 2788 } 2789 2790 (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer; 2791 DEBUG_PRINT_LOW("\n Virtual address in allocate buffer is %p", m_pInput_pmem[i].buffer); 2792 BITMASK_SET(&m_inp_bm_count,i); 2793 //here change the I/P param here from buf_adr to pmem 2794 if(!mUseProxyColorFormat && (dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)) 2795 { 2796 DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for i/p buf\n"); 2797 return OMX_ErrorInsufficientResources; 2798 } 2799 } 2800 else 2801 { 2802 DEBUG_PRINT_ERROR("\nERROR: All i/p buffers are allocated, invalid allocate buf call" 2803 "for index [%d]\n", i); 2804 eRet = OMX_ErrorInsufficientResources; 2805 } 2806 2807 return eRet; 2808 } 2809 2810 2811 /* ====================================================================== 2812 FUNCTION 2813 omx_venc::AllocateOutputBuffer 2814 2815 DESCRIPTION 2816 Helper fn for AllocateBuffer in the output pin 2817 2818 PARAMETERS 2819 <TBD>. 2820 2821 RETURN VALUE 2822 OMX Error None if everything went well. 2823 2824 ========================================================================== */ 2825 OMX_ERRORTYPE omx_video::allocate_output_buffer( 2826 OMX_IN OMX_HANDLETYPE hComp, 2827 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2828 OMX_IN OMX_U32 port, 2829 OMX_IN OMX_PTR appData, 2830 OMX_IN OMX_U32 bytes) 2831 { 2832 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2833 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 2834 unsigned i= 0; // Temporary counter 2835 2836 DEBUG_PRINT_HIGH("\n allocate_output_buffer()::"); 2837 if(!m_out_mem_ptr) 2838 { 2839 int nBufHdrSize = 0; 2840 DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__, 2841 m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountActual); 2842 nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); 2843 2844 /* 2845 * Memory for output side involves the following: 2846 * 1. Array of Buffer Headers 2847 * 2. Bitmask array to hold the buffer allocation details 2848 * In order to minimize the memory management entire allocation 2849 * is done in one step. 2850 */ 2851 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 2852 2853 #ifdef USE_ION 2854 m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); 2855 if(m_pOutput_ion == NULL) 2856 { 2857 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion"); 2858 return OMX_ErrorInsufficientResources; 2859 } 2860 #endif 2861 m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual); 2862 if(m_pOutput_pmem == NULL) 2863 { 2864 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem"); 2865 return OMX_ErrorInsufficientResources; 2866 } 2867 if(m_out_mem_ptr && m_pOutput_pmem) 2868 { 2869 bufHdr = m_out_mem_ptr; 2870 2871 for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++) 2872 { 2873 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2874 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 2875 // Set the values when we determine the right HxW param 2876 bufHdr->nAllocLen = bytes; 2877 bufHdr->nFilledLen = 0; 2878 bufHdr->pAppPrivate = appData; 2879 bufHdr->nOutputPortIndex = PORT_INDEX_OUT; 2880 bufHdr->pBuffer = NULL; 2881 bufHdr++; 2882 m_pOutput_pmem[i].fd = -1; 2883 #ifdef USE_ION 2884 m_pOutput_ion[i].ion_device_fd =-1; 2885 m_pOutput_ion[i].fd_ion_data.fd=-1; 2886 m_pOutput_ion[i].ion_alloc_data.handle =NULL; 2887 #endif 2888 } 2889 } 2890 else 2891 { 2892 DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem"); 2893 eRet = OMX_ErrorInsufficientResources; 2894 } 2895 } 2896 2897 DEBUG_PRINT_HIGH("\n actual cnt = %u", m_sOutPortDef.nBufferCountActual); 2898 for(i=0; i< m_sOutPortDef.nBufferCountActual; i++) 2899 { 2900 if(BITMASK_ABSENT(&m_out_bm_count,i)) 2901 { 2902 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i); 2903 break; 2904 } 2905 } 2906 if(eRet == OMX_ErrorNone) 2907 { 2908 if(i < m_sOutPortDef.nBufferCountActual) 2909 { 2910 #ifdef USE_ION 2911 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize, 2912 &m_pOutput_ion[i].ion_alloc_data, 2913 &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED); 2914 if(m_pOutput_ion[i].ion_device_fd < 0) { 2915 DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed"); 2916 return OMX_ErrorInsufficientResources; 2917 } 2918 m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; 2919 #else 2920 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2921 if(m_pOutput_pmem[i].fd == 0) 2922 { 2923 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2924 } 2925 2926 if(m_pOutput_pmem[i].fd < 0) 2927 { 2928 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() failed"); 2929 return OMX_ErrorInsufficientResources; 2930 } 2931 #endif 2932 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; 2933 m_pOutput_pmem[i].offset = 0; 2934 if(!secure_session) { 2935 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, 2936 MAP_SHARED,m_pOutput_pmem[i].fd,0); 2937 if(m_pOutput_pmem[i].buffer == MAP_FAILED) 2938 { 2939 DEBUG_PRINT_ERROR("\nERROR: MMAP_FAILED in o/p alloc buffer"); 2940 close (m_pOutput_pmem[i].fd); 2941 #ifdef USE_ION 2942 free_ion_memory(&m_pOutput_ion[i]); 2943 #endif 2944 return OMX_ErrorInsufficientResources; 2945 } 2946 } 2947 2948 *bufferHdr = (m_out_mem_ptr + i ); 2949 if(!secure_session) 2950 (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer; 2951 else { 2952 m_pOutput_pmem[i].buffer = (OMX_U8 *)(i + 12345); 2953 (*bufferHdr)->pBuffer = (OMX_U8 *)(i + 12345); 2954 } 2955 (*bufferHdr)->pAppPrivate = appData; 2956 2957 BITMASK_SET(&m_out_bm_count,i); 2958 2959 if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) 2960 { 2961 DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for o/p buf"); 2962 return OMX_ErrorInsufficientResources; 2963 } 2964 } 2965 else 2966 { 2967 DEBUG_PRINT_ERROR("\nERROR: All o/p buffers are allocated, invalid allocate buf call" 2968 "for index [%d]\n", i); 2969 } 2970 } 2971 2972 return eRet; 2973 } 2974 2975 2976 // AllocateBuffer -- API Call 2977 /* ====================================================================== 2978 FUNCTION 2979 omx_video::AllocateBuffer 2980 2981 DESCRIPTION 2982 Returns zero if all the buffers released.. 2983 2984 PARAMETERS 2985 None. 2986 2987 RETURN VALUE 2988 true/false 2989 2990 ========================================================================== */ 2991 OMX_ERRORTYPE omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, 2992 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2993 OMX_IN OMX_U32 port, 2994 OMX_IN OMX_PTR appData, 2995 OMX_IN OMX_U32 bytes) 2996 { 2997 2998 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type 2999 3000 DEBUG_PRINT_LOW("\n Allocate buffer of size = %d on port %d \n", bytes, (int)port); 3001 if(m_state == OMX_StateInvalid) 3002 { 3003 DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State\n"); 3004 return OMX_ErrorInvalidState; 3005 } 3006 3007 // What if the client calls again. 3008 if(port == PORT_INDEX_IN) 3009 { 3010 #ifdef _ANDROID_ICS_ 3011 if(meta_mode_enable) 3012 eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes); 3013 else 3014 #endif 3015 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); 3016 } 3017 else if(port == PORT_INDEX_OUT) 3018 { 3019 eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); 3020 } 3021 else 3022 { 3023 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port); 3024 eRet = OMX_ErrorBadPortIndex; 3025 } 3026 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); 3027 if(eRet == OMX_ErrorNone) 3028 { 3029 if(allocate_done()) 3030 { 3031 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) 3032 { 3033 // Send the callback now 3034 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 3035 post_event(OMX_CommandStateSet,OMX_StateIdle, 3036 OMX_COMPONENT_GENERATE_EVENT); 3037 } 3038 } 3039 if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated) 3040 { 3041 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) 3042 { 3043 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 3044 post_event(OMX_CommandPortEnable, 3045 PORT_INDEX_IN, 3046 OMX_COMPONENT_GENERATE_EVENT); 3047 } 3048 } 3049 if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) 3050 { 3051 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) 3052 { 3053 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 3054 post_event(OMX_CommandPortEnable, 3055 PORT_INDEX_OUT, 3056 OMX_COMPONENT_GENERATE_EVENT); 3057 m_event_port_settings_sent = false; 3058 } 3059 } 3060 } 3061 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet); 3062 return eRet; 3063 } 3064 3065 3066 // Free Buffer - API call 3067 /* ====================================================================== 3068 FUNCTION 3069 omx_video::FreeBuffer 3070 3071 DESCRIPTION 3072 3073 PARAMETERS 3074 None. 3075 3076 RETURN VALUE 3077 true/false 3078 3079 ========================================================================== */ 3080 OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp, 3081 OMX_IN OMX_U32 port, 3082 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 3083 { 3084 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3085 unsigned int nPortIndex; 3086 3087 DEBUG_PRINT_LOW("In for decoder free_buffer \n"); 3088 3089 if(m_state == OMX_StateIdle && 3090 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) 3091 { 3092 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n"); 3093 } 3094 else if((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)|| 3095 (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) 3096 { 3097 DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port); 3098 } 3099 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause) 3100 { 3101 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled\n"); 3102 post_event(OMX_EventError, 3103 OMX_ErrorPortUnpopulated, 3104 OMX_COMPONENT_GENERATE_EVENT); 3105 3106 return eRet; 3107 } 3108 else 3109 { 3110 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers\n"); 3111 post_event(OMX_EventError, 3112 OMX_ErrorPortUnpopulated, 3113 OMX_COMPONENT_GENERATE_EVENT); 3114 } 3115 3116 if(port == PORT_INDEX_IN) 3117 { 3118 // check if the buffer is valid 3119 nPortIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); 3120 3121 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d, actual cnt %d \n", 3122 nPortIndex, m_sInPortDef.nBufferCountActual); 3123 if(nPortIndex < m_sInPortDef.nBufferCountActual) 3124 { 3125 // Clear the bit associated with it. 3126 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); 3127 free_input_buffer (buffer); 3128 m_sInPortDef.bPopulated = OMX_FALSE; 3129 3130 /*Free the Buffer Header*/ 3131 if(release_input_done() 3132 #ifdef _ANDROID_ICS_ 3133 && !meta_mode_enable 3134 #endif 3135 ) 3136 { 3137 input_use_buffer = false; 3138 if(m_inp_mem_ptr) 3139 { 3140 DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr\n"); 3141 free (m_inp_mem_ptr); 3142 m_inp_mem_ptr = NULL; 3143 } 3144 if(m_pInput_pmem) 3145 { 3146 DEBUG_PRINT_LOW("Freeing m_pInput_pmem\n"); 3147 free(m_pInput_pmem); 3148 m_pInput_pmem = NULL; 3149 } 3150 #ifdef USE_ION 3151 if(m_pInput_ion) 3152 { 3153 DEBUG_PRINT_LOW("Freeing m_pInput_ion\n"); 3154 free(m_pInput_ion); 3155 m_pInput_ion = NULL; 3156 } 3157 #endif 3158 } 3159 } 3160 else 3161 { 3162 DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid\n"); 3163 eRet = OMX_ErrorBadPortIndex; 3164 } 3165 3166 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) 3167 && release_input_done()) 3168 { 3169 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); 3170 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); 3171 post_event(OMX_CommandPortDisable, 3172 PORT_INDEX_IN, 3173 OMX_COMPONENT_GENERATE_EVENT); 3174 } 3175 } 3176 else if(port == PORT_INDEX_OUT) 3177 { 3178 // check if the buffer is valid 3179 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr; 3180 3181 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d, actual cnt %d \n", 3182 nPortIndex, m_sOutPortDef.nBufferCountActual); 3183 if(nPortIndex < m_sOutPortDef.nBufferCountActual) 3184 { 3185 // Clear the bit associated with it. 3186 BITMASK_CLEAR(&m_out_bm_count,nPortIndex); 3187 m_sOutPortDef.bPopulated = OMX_FALSE; 3188 free_output_buffer (buffer); 3189 3190 if(release_output_done()) 3191 { 3192 output_use_buffer = false; 3193 if(m_out_mem_ptr) 3194 { 3195 DEBUG_PRINT_LOW("Freeing m_out_mem_ptr\n"); 3196 free (m_out_mem_ptr); 3197 m_out_mem_ptr = NULL; 3198 } 3199 if(m_pOutput_pmem) 3200 { 3201 DEBUG_PRINT_LOW("Freeing m_pOutput_pmem\n"); 3202 free(m_pOutput_pmem); 3203 m_pOutput_pmem = NULL; 3204 } 3205 #ifdef USE_ION 3206 if(m_pOutput_ion) 3207 { 3208 DEBUG_PRINT_LOW("Freeing m_pOutput_ion\n"); 3209 free(m_pOutput_ion); 3210 m_pOutput_ion = NULL; 3211 } 3212 #endif 3213 } 3214 } 3215 else 3216 { 3217 DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid\n"); 3218 eRet = OMX_ErrorBadPortIndex; 3219 } 3220 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) 3221 && release_output_done() ) 3222 { 3223 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n"); 3224 3225 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n"); 3226 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 3227 post_event(OMX_CommandPortDisable, 3228 PORT_INDEX_OUT, 3229 OMX_COMPONENT_GENERATE_EVENT); 3230 3231 } 3232 } 3233 else 3234 { 3235 eRet = OMX_ErrorBadPortIndex; 3236 } 3237 if((eRet == OMX_ErrorNone) && 3238 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) 3239 { 3240 if(release_done()) 3241 { 3242 if(dev_stop() != 0) 3243 { 3244 DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED\n"); 3245 eRet = OMX_ErrorHardware; 3246 } 3247 // Send the callback now 3248 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); 3249 post_event(OMX_CommandStateSet, OMX_StateLoaded, 3250 OMX_COMPONENT_GENERATE_EVENT); 3251 } 3252 } 3253 3254 return eRet; 3255 } 3256 3257 3258 /* ====================================================================== 3259 FUNCTION 3260 omx_video::EmptyThisBuffer 3261 3262 DESCRIPTION 3263 This routine is used to push the encoded video frames to 3264 the video decoder. 3265 3266 PARAMETERS 3267 None. 3268 3269 RETURN VALUE 3270 OMX Error None if everything went successful. 3271 3272 ========================================================================== */ 3273 OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 3274 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 3275 { 3276 OMX_ERRORTYPE ret1 = OMX_ErrorNone; 3277 unsigned int nBufferIndex ; 3278 3279 DEBUG_PRINT_LOW("\n ETB: buffer = %p, buffer->pBuffer[%p]\n", buffer, buffer->pBuffer); 3280 if(m_state == OMX_StateInvalid) 3281 { 3282 DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State\n"); 3283 return OMX_ErrorInvalidState; 3284 } 3285 3286 if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) 3287 { 3288 DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> buffer is null or buffer size is invalid"); 3289 return OMX_ErrorBadParameter; 3290 } 3291 3292 if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) 3293 { 3294 DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> OMX Version Invalid"); 3295 return OMX_ErrorVersionMismatch; 3296 } 3297 3298 if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) 3299 { 3300 DEBUG_PRINT_ERROR("\nERROR: Bad port index to call empty_this_buffer"); 3301 return OMX_ErrorBadPortIndex; 3302 } 3303 if(!m_sInPortDef.bEnabled) 3304 { 3305 DEBUG_PRINT_ERROR("\nERROR: Cannot call empty_this_buffer while I/P port is disabled"); 3306 return OMX_ErrorIncorrectStateOperation; 3307 } 3308 3309 nBufferIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr); 3310 3311 if(nBufferIndex > m_sInPortDef.nBufferCountActual ) 3312 { 3313 DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]\n", nBufferIndex); 3314 return OMX_ErrorBadParameter; 3315 } 3316 3317 m_etb_count++; 3318 DEBUG_PRINT_LOW("\n DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp); 3319 post_event ((unsigned)hComp,(unsigned)buffer,m_input_msg_id); 3320 return OMX_ErrorNone; 3321 } 3322 /* ====================================================================== 3323 FUNCTION 3324 omx_video::empty_this_buffer_proxy 3325 3326 DESCRIPTION 3327 This routine is used to push the encoded video frames to 3328 the video decoder. 3329 3330 PARAMETERS 3331 None. 3332 3333 RETURN VALUE 3334 OMX Error None if everything went successful. 3335 3336 ========================================================================== */ 3337 OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, 3338 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 3339 { 3340 OMX_U8 *pmem_data_buf = NULL; 3341 int push_cnt = 0; 3342 unsigned nBufIndex = 0,nBufIndex_meta = 0; 3343 OMX_ERRORTYPE ret = OMX_ErrorNone; 3344 3345 DEBUG_PRINT_LOW("\n ETBProxy: buffer[%p]\n", buffer); 3346 3347 if(buffer == NULL) 3348 { 3349 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid buffer[%p]\n", buffer); 3350 return OMX_ErrorBadParameter; 3351 } 3352 3353 nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 3354 nBufIndex_meta = buffer - meta_buffer_hdr; 3355 if(nBufIndex >= m_sInPortDef.nBufferCountActual && 3356 nBufIndex_meta >= m_sInPortDef.nBufferCountActual) 3357 { 3358 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid bufindex = %u\n", nBufIndex); 3359 return OMX_ErrorBadParameter; 3360 } 3361 3362 pending_input_buffers++; 3363 if(input_flush_progress == true) 3364 { 3365 post_event ((unsigned int)buffer,0, 3366 OMX_COMPONENT_GENERATE_EBD); 3367 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Input flush in progress"); 3368 return OMX_ErrorNone; 3369 } 3370 #ifdef _ANDROID_ICS_ 3371 if(meta_mode_enable && !mUseProxyColorFormat) 3372 { 3373 encoder_media_buffer_type *media_buffer; 3374 bool met_error = false; 3375 media_buffer = (encoder_media_buffer_type *)meta_buffer_hdr[nBufIndex].pBuffer; 3376 if(media_buffer) 3377 { 3378 if (media_buffer->buffer_type != kMetadataBufferTypeCameraSource && 3379 media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) { 3380 met_error = true; 3381 } else { 3382 if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) 3383 { 3384 if(media_buffer->meta_handle == NULL) { 3385 met_error = true; 3386 } 3387 else if((media_buffer->meta_handle->numFds != 1 && 3388 media_buffer->meta_handle->numInts != 2)) 3389 { 3390 met_error = true; 3391 } 3392 } 3393 } 3394 } else { 3395 met_error = true; 3396 } 3397 if(met_error) 3398 { 3399 DEBUG_PRINT_ERROR("\nERROR: Unkown source/metahandle in ETB call"); 3400 post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); 3401 return OMX_ErrorBadParameter; 3402 } 3403 3404 struct pmem Input_pmem_info; 3405 if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) 3406 { 3407 Input_pmem_info.buffer = media_buffer; 3408 Input_pmem_info.fd = media_buffer->meta_handle->data[0]; 3409 Input_pmem_info.offset = media_buffer->meta_handle->data[1]; 3410 Input_pmem_info.size = media_buffer->meta_handle->data[2]; 3411 DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd, 3412 Input_pmem_info.offset, 3413 Input_pmem_info.size); 3414 3415 } else { 3416 private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; 3417 if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) { 3418 DEBUG_PRINT_ERROR("\n Incorrect pixel format"); 3419 post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); 3420 return OMX_ErrorBadParameter; 3421 } 3422 Input_pmem_info.buffer = media_buffer; 3423 Input_pmem_info.fd = handle->fd; 3424 Input_pmem_info.offset = 0; 3425 Input_pmem_info.size = handle->size; 3426 } 3427 if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) { 3428 DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); 3429 post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); 3430 return OMX_ErrorBadParameter; 3431 } 3432 } 3433 else if(input_use_buffer && !m_use_input_pmem) 3434 #else 3435 if(input_use_buffer && !m_use_input_pmem) 3436 #endif 3437 { 3438 DEBUG_PRINT_LOW("\n Heap UseBuffer case, so memcpy the data"); 3439 pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer; 3440 3441 memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset), 3442 buffer->nFilledLen); 3443 DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf"); 3444 } else if (m_sInPortDef.format.video.eColorFormat == 3445 OMX_COLOR_FormatYUV420SemiPlanar && !mUseProxyColorFormat) { 3446 //For the case where YUV420SP buffers are qeueued to component 3447 //by sources other than camera (Apps via MediaCodec), alignment 3448 //of chroma-plane to 2K is necessary. 3449 //For RGB buffers, color-conversion takes care of such alignment 3450 OMX_U32 width = m_sInPortDef.format.video.nFrameWidth; 3451 OMX_U32 height = m_sInPortDef.format.video.nFrameHeight; 3452 OMX_U32 chromaOffset = width * height; 3453 if (IS_NOT_ALIGNED(chromaOffset, SZ_2K)) { 3454 OMX_U32 chromaSize = (width * height)/2; 3455 chromaOffset = ALIGN(chromaOffset,SZ_2K); 3456 if (buffer->nAllocLen >= chromaOffset + chromaSize) { 3457 OMX_U8* buf = buffer->pBuffer; 3458 memmove(buf + chromaOffset, buf + (width*height), chromaSize); 3459 } else { 3460 DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \ 3461 Insufficient bufferLen=%u v/s Required=%u", 3462 (width*height), chromaOffset, buffer->nAllocLen, 3463 chromaOffset+chromaSize); 3464 } 3465 } 3466 } 3467 #ifdef _COPPER_ 3468 if(dev_empty_buf(buffer, pmem_data_buf,nBufIndex,m_pInput_pmem[nBufIndex].fd) != true) 3469 #else 3470 if(dev_empty_buf(buffer, pmem_data_buf,0,0) != true) 3471 #endif 3472 { 3473 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: dev_empty_buf failed"); 3474 #ifdef _ANDROID_ICS_ 3475 omx_release_meta_buffer(buffer); 3476 #endif 3477 post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD); 3478 /*Generate an async error and move to invalid state*/ 3479 pending_input_buffers--; 3480 return OMX_ErrorBadParameter; 3481 } 3482 3483 return ret; 3484 } 3485 3486 /* ====================================================================== 3487 FUNCTION 3488 omx_video::FillThisBuffer 3489 3490 DESCRIPTION 3491 IL client uses this method to release the frame buffer 3492 after displaying them. 3493 3494 PARAMETERS 3495 None. 3496 3497 RETURN VALUE 3498 true/false 3499 3500 ========================================================================== */ 3501 OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 3502 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 3503 { 3504 DEBUG_PRINT_LOW("\n FTB: buffer->pBuffer[%p]\n", buffer->pBuffer); 3505 if(m_state == OMX_StateInvalid) 3506 { 3507 DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State\n"); 3508 return OMX_ErrorInvalidState; 3509 } 3510 3511 if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) 3512 { 3513 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size\n"); 3514 return OMX_ErrorBadParameter; 3515 } 3516 3517 if(buffer->nVersion.nVersion != OMX_SPEC_VERSION) 3518 { 3519 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid\n"); 3520 return OMX_ErrorVersionMismatch; 3521 } 3522 3523 if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) 3524 { 3525 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index\n"); 3526 return OMX_ErrorBadPortIndex; 3527 } 3528 3529 if(!m_sOutPortDef.bEnabled) 3530 { 3531 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled\n"); 3532 return OMX_ErrorIncorrectStateOperation; 3533 } 3534 3535 post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB); 3536 return OMX_ErrorNone; 3537 } 3538 3539 /* ====================================================================== 3540 FUNCTION 3541 omx_video::fill_this_buffer_proxy 3542 3543 DESCRIPTION 3544 IL client uses this method to release the frame buffer 3545 after displaying them. 3546 3547 PARAMETERS 3548 None. 3549 3550 RETURN VALUE 3551 true/false 3552 3553 ========================================================================== */ 3554 OMX_ERRORTYPE omx_video::fill_this_buffer_proxy( 3555 OMX_IN OMX_HANDLETYPE hComp, 3556 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) 3557 { 3558 OMX_U8 *pmem_data_buf = NULL; 3559 OMX_ERRORTYPE nRet = OMX_ErrorNone; 3560 3561 DEBUG_PRINT_LOW("\n FTBProxy: bufferAdd->pBuffer[%p]\n", bufferAdd->pBuffer); 3562 3563 if(bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= m_sOutPortDef.nBufferCountActual) ) 3564 { 3565 DEBUG_PRINT_ERROR("\nERROR: FTBProxy: Invalid i/p params\n"); 3566 return OMX_ErrorBadParameter; 3567 } 3568 3569 pending_output_buffers++; 3570 /*Return back the output buffer to client*/ 3571 if( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) 3572 { 3573 DEBUG_PRINT_LOW("\n o/p port is Disabled or Flush in Progress"); 3574 post_event ((unsigned int)bufferAdd,0, 3575 OMX_COMPONENT_GENERATE_FBD); 3576 return OMX_ErrorNone; 3577 } 3578 3579 if(output_use_buffer && !m_use_output_pmem) 3580 { 3581 DEBUG_PRINT_LOW("\n Heap UseBuffer case"); 3582 pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer; 3583 } 3584 3585 if(dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) 3586 { 3587 DEBUG_PRINT_ERROR("\nERROR: dev_fill_buf() Failed"); 3588 post_event ((unsigned int)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD); 3589 pending_output_buffers--; 3590 return OMX_ErrorBadParameter; 3591 } 3592 3593 return OMX_ErrorNone; 3594 } 3595 3596 /* ====================================================================== 3597 FUNCTION 3598 omx_video::SetCallbacks 3599 3600 DESCRIPTION 3601 Set the callbacks. 3602 3603 PARAMETERS 3604 None. 3605 3606 RETURN VALUE 3607 OMX Error None if everything successful. 3608 3609 ========================================================================== */ 3610 OMX_ERRORTYPE omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, 3611 OMX_IN OMX_CALLBACKTYPE* callbacks, 3612 OMX_IN OMX_PTR appData) 3613 { 3614 3615 m_pCallbacks = *callbacks; 3616 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\ 3617 m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone); 3618 m_app_data = appData; 3619 return OMX_ErrorNotImplemented; 3620 } 3621 3622 3623 /* ====================================================================== 3624 FUNCTION 3625 omx_venc::UseEGLImage 3626 3627 DESCRIPTION 3628 OMX Use EGL Image method implementation <TBD>. 3629 3630 PARAMETERS 3631 <TBD>. 3632 3633 RETURN VALUE 3634 Not Implemented error. 3635 3636 ========================================================================== */ 3637 OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, 3638 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3639 OMX_IN OMX_U32 port, 3640 OMX_IN OMX_PTR appData, 3641 OMX_IN void* eglImage) 3642 { 3643 DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented \n"); 3644 return OMX_ErrorNotImplemented; 3645 } 3646 3647 /* ====================================================================== 3648 FUNCTION 3649 omx_venc::ComponentRoleEnum 3650 3651 DESCRIPTION 3652 OMX Component Role Enum method implementation. 3653 3654 PARAMETERS 3655 <TBD>. 3656 3657 RETURN VALUE 3658 OMX Error None if everything is successful. 3659 ========================================================================== */ 3660 OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, 3661 OMX_OUT OMX_U8* role, 3662 OMX_IN OMX_U32 index) 3663 { 3664 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3665 if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 3666 { 3667 if((0 == index) && role) 3668 { 3669 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 3670 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3671 } 3672 else 3673 { 3674 eRet = OMX_ErrorNoMore; 3675 } 3676 } 3677 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) 3678 { 3679 if((0 == index) && role) 3680 { 3681 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 3682 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3683 } 3684 else 3685 { 3686 DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); 3687 eRet = OMX_ErrorNoMore; 3688 } 3689 } 3690 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) 3691 { 3692 if((0 == index) && role) 3693 { 3694 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 3695 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3696 } 3697 else 3698 { 3699 DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); 3700 eRet = OMX_ErrorNoMore; 3701 } 3702 } 3703 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) 3704 { 3705 if((0 == index) && role) 3706 { 3707 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 3708 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3709 } 3710 else 3711 { 3712 DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); 3713 eRet = OMX_ErrorNoMore; 3714 } 3715 } 3716 if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) 3717 { 3718 if((0 == index) && role) 3719 { 3720 strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 3721 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3722 } 3723 else 3724 { 3725 eRet = OMX_ErrorNoMore; 3726 } 3727 } 3728 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) 3729 { 3730 if((0 == index) && role) 3731 { 3732 strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); 3733 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3734 } 3735 else 3736 { 3737 DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); 3738 eRet = OMX_ErrorNoMore; 3739 } 3740 } 3741 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) 3742 { 3743 if((0 == index) && role) 3744 { 3745 strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); 3746 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role); 3747 } 3748 else 3749 { 3750 DEBUG_PRINT_ERROR("\nERROR: No more roles \n"); 3751 eRet = OMX_ErrorNoMore; 3752 } 3753 } 3754 else 3755 { 3756 DEBUG_PRINT_ERROR("\nERROR: Querying Role on Unknown Component\n"); 3757 eRet = OMX_ErrorInvalidComponentName; 3758 } 3759 return eRet; 3760 } 3761 3762 3763 3764 3765 /* ====================================================================== 3766 FUNCTION 3767 omx_venc::AllocateDone 3768 3769 DESCRIPTION 3770 Checks if entire buffer pool is allocated by IL Client or not. 3771 Need this to move to IDLE state. 3772 3773 PARAMETERS 3774 None. 3775 3776 RETURN VALUE 3777 true/false. 3778 3779 ========================================================================== */ 3780 bool omx_video::allocate_done(void) 3781 { 3782 bool bRet = false; 3783 bool bRet_In = false; 3784 bool bRet_Out = false; 3785 3786 bRet_In = allocate_input_done(); 3787 bRet_Out = allocate_output_done(); 3788 3789 if(bRet_In && bRet_Out) 3790 { 3791 bRet = true; 3792 } 3793 3794 return bRet; 3795 } 3796 /* ====================================================================== 3797 FUNCTION 3798 omx_venc::AllocateInputDone 3799 3800 DESCRIPTION 3801 Checks if I/P buffer pool is allocated by IL Client or not. 3802 3803 PARAMETERS 3804 None. 3805 3806 RETURN VALUE 3807 true/false. 3808 3809 ========================================================================== */ 3810 bool omx_video::allocate_input_done(void) 3811 { 3812 bool bRet = false; 3813 unsigned i=0; 3814 3815 if(m_inp_mem_ptr == NULL) 3816 { 3817 return bRet; 3818 } 3819 if(m_inp_mem_ptr ) 3820 { 3821 for(;i<m_sInPortDef.nBufferCountActual;i++) 3822 { 3823 if(BITMASK_ABSENT(&m_inp_bm_count,i)) 3824 { 3825 break; 3826 } 3827 } 3828 } 3829 if(i==m_sInPortDef.nBufferCountActual) 3830 { 3831 bRet = true; 3832 } 3833 if(i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled) 3834 { 3835 m_sInPortDef.bPopulated = OMX_TRUE; 3836 } 3837 return bRet; 3838 } 3839 /* ====================================================================== 3840 FUNCTION 3841 omx_venc::AllocateOutputDone 3842 3843 DESCRIPTION 3844 Checks if entire O/P buffer pool is allocated by IL Client or not. 3845 3846 PARAMETERS 3847 None. 3848 3849 RETURN VALUE 3850 true/false. 3851 3852 ========================================================================== */ 3853 bool omx_video::allocate_output_done(void) 3854 { 3855 bool bRet = false; 3856 unsigned j=0; 3857 3858 if(m_out_mem_ptr == NULL) 3859 { 3860 return bRet; 3861 } 3862 3863 if(m_out_mem_ptr ) 3864 { 3865 for(;j<m_sOutPortDef.nBufferCountActual;j++) 3866 { 3867 if(BITMASK_ABSENT(&m_out_bm_count,j)) 3868 { 3869 break; 3870 } 3871 } 3872 } 3873 3874 if(j==m_sOutPortDef.nBufferCountActual) 3875 { 3876 bRet = true; 3877 } 3878 3879 if(j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled) 3880 { 3881 m_sOutPortDef.bPopulated = OMX_TRUE; 3882 } 3883 return bRet; 3884 } 3885 3886 /* ====================================================================== 3887 FUNCTION 3888 omx_venc::ReleaseDone 3889 3890 DESCRIPTION 3891 Checks if IL client has released all the buffers. 3892 3893 PARAMETERS 3894 None. 3895 3896 RETURN VALUE 3897 true/false 3898 3899 ========================================================================== */ 3900 bool omx_video::release_done(void) 3901 { 3902 bool bRet = false; 3903 DEBUG_PRINT_LOW("Inside release_done()\n"); 3904 if(release_input_done()) 3905 { 3906 if(release_output_done()) 3907 { 3908 bRet = true; 3909 } 3910 } 3911 return bRet; 3912 } 3913 3914 3915 /* ====================================================================== 3916 FUNCTION 3917 omx_venc::ReleaseOutputDone 3918 3919 DESCRIPTION 3920 Checks if IL client has released all the buffers. 3921 3922 PARAMETERS 3923 None. 3924 3925 RETURN VALUE 3926 true/false 3927 3928 ========================================================================== */ 3929 bool omx_video::release_output_done(void) 3930 { 3931 bool bRet = false; 3932 unsigned i=0,j=0; 3933 3934 DEBUG_PRINT_LOW("Inside release_output_done()\n"); 3935 if(m_out_mem_ptr) 3936 { 3937 for(;j<m_sOutPortDef.nBufferCountActual;j++) 3938 { 3939 if(BITMASK_PRESENT(&m_out_bm_count,j)) 3940 { 3941 break; 3942 } 3943 } 3944 if(j==m_sOutPortDef.nBufferCountActual) 3945 { 3946 bRet = true; 3947 } 3948 } 3949 else 3950 { 3951 bRet = true; 3952 } 3953 return bRet; 3954 } 3955 /* ====================================================================== 3956 FUNCTION 3957 omx_venc::ReleaseInputDone 3958 3959 DESCRIPTION 3960 Checks if IL client has released all the buffers. 3961 3962 PARAMETERS 3963 None. 3964 3965 RETURN VALUE 3966 true/false 3967 3968 ========================================================================== */ 3969 bool omx_video::release_input_done(void) 3970 { 3971 bool bRet = false; 3972 unsigned i=0,j=0; 3973 3974 DEBUG_PRINT_LOW("Inside release_input_done()\n"); 3975 if(m_inp_mem_ptr) 3976 { 3977 for(;j<m_sInPortDef.nBufferCountActual;j++) 3978 { 3979 if( BITMASK_PRESENT(&m_inp_bm_count,j)) 3980 { 3981 break; 3982 } 3983 } 3984 if(j==m_sInPortDef.nBufferCountActual) 3985 { 3986 bRet = true; 3987 } 3988 } 3989 else 3990 { 3991 bRet = true; 3992 } 3993 return bRet; 3994 } 3995 3996 OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp, 3997 OMX_BUFFERHEADERTYPE * buffer) 3998 { 3999 DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x size = %d", 4000 buffer->pBuffer, buffer->nFlags,buffer->nFilledLen); 4001 if(buffer == NULL || ((buffer - m_out_mem_ptr) > m_sOutPortDef.nBufferCountActual)) 4002 { 4003 return OMX_ErrorBadParameter; 4004 } 4005 4006 pending_output_buffers--; 4007 if(!secure_session) 4008 { 4009 extra_data_handle.create_extra_data(buffer); 4010 } 4011 4012 if (!secure_session && m_sDebugSliceinfo) { 4013 if(buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) { 4014 DEBUG_PRINT_HIGH("parsing extradata"); 4015 extra_data_handle.parse_extra_data(buffer); 4016 } 4017 } 4018 /* For use buffer we need to copy the data */ 4019 if(m_pCallbacks.FillBufferDone) 4020 { 4021 if(buffer->nFilledLen > 0) 4022 { 4023 m_fbd_count++; 4024 4025 #ifdef OUTPUT_BUFFER_LOG 4026 if(outputBufferFile1) 4027 { 4028 fwrite((const char *)buffer->pBuffer, buffer->nFilledLen, 1, outputBufferFile1); 4029 } 4030 #endif 4031 } 4032 m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer); 4033 } 4034 else 4035 { 4036 return OMX_ErrorBadParameter; 4037 } 4038 return OMX_ErrorNone; 4039 } 4040 4041 OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp, 4042 OMX_BUFFERHEADERTYPE* buffer) 4043 { 4044 int buffer_index = -1; 4045 int buffer_index_meta = -1; 4046 4047 buffer_index = (buffer - m_inp_mem_ptr); 4048 buffer_index_meta = (buffer - meta_buffer_hdr); 4049 DEBUG_PRINT_LOW("\n empty_buffer_done: buffer[%p]", buffer); 4050 if(buffer == NULL || 4051 ((buffer_index > m_sInPortDef.nBufferCountActual) && 4052 (buffer_index_meta > m_sInPortDef.nBufferCountActual))) 4053 { 4054 DEBUG_PRINT_ERROR("\n ERROR in empty_buffer_done due to index buffer"); 4055 return OMX_ErrorBadParameter; 4056 } 4057 4058 pending_input_buffers--; 4059 4060 if(mUseProxyColorFormat && (buffer_index < m_sInPortDef.nBufferCountActual)) { 4061 if(!pdest_frame) { 4062 pdest_frame = buffer; 4063 DEBUG_PRINT_LOW("\n empty_buffer_done pdest_frame address is %p",pdest_frame); 4064 return push_input_buffer(hComp); 4065 4066 } else { 4067 DEBUG_PRINT_LOW("\n empty_buffer_done insert address is %p",buffer); 4068 if (!m_opq_pmem_q.insert_entry((unsigned int)buffer, 0, 0)) { 4069 DEBUG_PRINT_ERROR("\n empty_buffer_done: pmem queue is full"); 4070 return OMX_ErrorBadParameter; 4071 } 4072 } 4073 } else if(m_pCallbacks.EmptyBufferDone) { 4074 m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer); 4075 } 4076 return OMX_ErrorNone; 4077 } 4078 4079 void omx_video::complete_pending_buffer_done_cbs() 4080 { 4081 unsigned p1; 4082 unsigned p2; 4083 unsigned ident; 4084 omx_cmd_queue tmp_q, pending_bd_q; 4085 pthread_mutex_lock(&m_lock); 4086 // pop all pending GENERATE FDB from ftb queue 4087 while (m_ftb_q.m_size) 4088 { 4089 m_ftb_q.pop_entry(&p1,&p2,&ident); 4090 if(ident == OMX_COMPONENT_GENERATE_FBD) 4091 { 4092 pending_bd_q.insert_entry(p1,p2,ident); 4093 } 4094 else 4095 { 4096 tmp_q.insert_entry(p1,p2,ident); 4097 } 4098 } 4099 //return all non GENERATE FDB to ftb queue 4100 while(tmp_q.m_size) 4101 { 4102 tmp_q.pop_entry(&p1,&p2,&ident); 4103 m_ftb_q.insert_entry(p1,p2,ident); 4104 } 4105 // pop all pending GENERATE EDB from etb queue 4106 while (m_etb_q.m_size) 4107 { 4108 m_etb_q.pop_entry(&p1,&p2,&ident); 4109 if(ident == OMX_COMPONENT_GENERATE_EBD) 4110 { 4111 pending_bd_q.insert_entry(p1,p2,ident); 4112 } 4113 else 4114 { 4115 tmp_q.insert_entry(p1,p2,ident); 4116 } 4117 } 4118 //return all non GENERATE FDB to etb queue 4119 while(tmp_q.m_size) 4120 { 4121 tmp_q.pop_entry(&p1,&p2,&ident); 4122 m_etb_q.insert_entry(p1,p2,ident); 4123 } 4124 pthread_mutex_unlock(&m_lock); 4125 // process all pending buffer dones 4126 while(pending_bd_q.m_size) 4127 { 4128 pending_bd_q.pop_entry(&p1,&p2,&ident); 4129 switch(ident) 4130 { 4131 case OMX_COMPONENT_GENERATE_EBD: 4132 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) 4133 { 4134 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n"); 4135 omx_report_error (); 4136 } 4137 break; 4138 4139 case OMX_COMPONENT_GENERATE_FBD: 4140 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) 4141 { 4142 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n"); 4143 omx_report_error (); 4144 } 4145 break; 4146 } 4147 } 4148 } 4149 4150 #ifdef MAX_RES_720P 4151 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) 4152 { 4153 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4154 if(!profileLevelType) 4155 return OMX_ErrorBadParameter; 4156 4157 if(profileLevelType->nPortIndex == 1) { 4158 if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) 4159 { 4160 if (profileLevelType->nProfileIndex == 0) 4161 { 4162 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; 4163 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; 4164 } 4165 else if (profileLevelType->nProfileIndex == 1) 4166 { 4167 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; 4168 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; 4169 } 4170 else if(profileLevelType->nProfileIndex == 2) 4171 { 4172 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; 4173 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; 4174 } 4175 else 4176 { 4177 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", 4178 profileLevelType->nProfileIndex); 4179 eRet = OMX_ErrorNoMore; 4180 } 4181 } 4182 else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) 4183 { 4184 if (profileLevelType->nProfileIndex == 0) 4185 { 4186 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; 4187 profileLevelType->eLevel = OMX_VIDEO_H263Level70; 4188 } 4189 else 4190 { 4191 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); 4192 eRet = OMX_ErrorNoMore; 4193 } 4194 } 4195 else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) 4196 { 4197 if (profileLevelType->nProfileIndex == 0) 4198 { 4199 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; 4200 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 4201 } 4202 else if(profileLevelType->nProfileIndex == 1) 4203 { 4204 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 4205 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 4206 } 4207 else 4208 { 4209 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); 4210 eRet = OMX_ErrorNoMore; 4211 } 4212 } 4213 } 4214 else 4215 { 4216 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); 4217 eRet = OMX_ErrorBadPortIndex; 4218 } 4219 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n", 4220 profileLevelType->eProfile,profileLevelType->eLevel); 4221 return eRet; 4222 } 4223 #endif 4224 4225 #ifdef MAX_RES_1080P 4226 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) 4227 { 4228 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4229 if(!profileLevelType) 4230 return OMX_ErrorBadParameter; 4231 4232 if(profileLevelType->nPortIndex == 1) { 4233 if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) 4234 { 4235 if (profileLevelType->nProfileIndex == 0) 4236 { 4237 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; 4238 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 4239 4240 } 4241 else if (profileLevelType->nProfileIndex == 1) 4242 { 4243 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; 4244 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 4245 } 4246 else if(profileLevelType->nProfileIndex == 2) 4247 { 4248 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; 4249 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 4250 } 4251 else 4252 { 4253 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", 4254 profileLevelType->nProfileIndex); 4255 eRet = OMX_ErrorNoMore; 4256 } 4257 } 4258 else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) 4259 { 4260 if (profileLevelType->nProfileIndex == 0) 4261 { 4262 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; 4263 profileLevelType->eLevel = OMX_VIDEO_H263Level70; 4264 } 4265 else 4266 { 4267 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); 4268 eRet = OMX_ErrorNoMore; 4269 } 4270 } 4271 else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) 4272 { 4273 if (profileLevelType->nProfileIndex == 0) 4274 { 4275 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; 4276 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 4277 } 4278 else if(profileLevelType->nProfileIndex == 1) 4279 { 4280 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 4281 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 4282 } 4283 else 4284 { 4285 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex); 4286 eRet = OMX_ErrorNoMore; 4287 } 4288 } 4289 } 4290 else 4291 { 4292 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex); 4293 eRet = OMX_ErrorBadPortIndex; 4294 } 4295 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n", 4296 profileLevelType->eProfile,profileLevelType->eLevel); 4297 return eRet; 4298 } 4299 4300 #ifdef USE_ION 4301 int omx_video::alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data, 4302 struct ion_fd_data *fd_data,int flag) 4303 { 4304 struct venc_ion buf_ion_info; 4305 int ion_device_fd =-1,rc=0,ion_dev_flags = 0; 4306 if (size <=0 || !alloc_data || !fd_data) { 4307 DEBUG_PRINT_ERROR("\nInvalid input to alloc_map_ion_memory"); 4308 return -EINVAL; 4309 } 4310 ion_dev_flags = O_RDONLY; 4311 ion_device_fd = open (MEM_DEVICE,ion_dev_flags); 4312 if(ion_device_fd < 0) 4313 { 4314 DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed"); 4315 return ion_device_fd; 4316 } 4317 alloc_data->len = size; 4318 alloc_data->align = 4096; 4319 alloc_data->flags = 0; 4320 if(!secure_session && (flag & ION_FLAG_CACHED)) 4321 { 4322 alloc_data->flags = ION_FLAG_CACHED; 4323 } 4324 4325 if (secure_session) 4326 alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) | ION_SECURE); 4327 else 4328 alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) | 4329 ION_HEAP(ION_IOMMU_HEAP_ID)); 4330 4331 rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data); 4332 if(rc || !alloc_data->handle) { 4333 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed "); 4334 alloc_data->handle =NULL; 4335 close(ion_device_fd); 4336 ion_device_fd = -1; 4337 return ion_device_fd; 4338 } 4339 fd_data->handle = alloc_data->handle; 4340 rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data); 4341 if(rc) { 4342 DEBUG_PRINT_ERROR("\n ION MAP failed "); 4343 buf_ion_info.ion_alloc_data = *alloc_data; 4344 buf_ion_info.ion_device_fd = ion_device_fd; 4345 buf_ion_info.fd_ion_data = *fd_data; 4346 free_ion_memory(&buf_ion_info); 4347 fd_data->fd =-1; 4348 ion_device_fd =-1; 4349 } 4350 return ion_device_fd; 4351 } 4352 4353 void omx_video::free_ion_memory(struct venc_ion *buf_ion_info) 4354 { 4355 if (!buf_ion_info) { 4356 DEBUG_PRINT_ERROR("\n Invalid input to free_ion_memory"); 4357 return; 4358 } 4359 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, 4360 &buf_ion_info->ion_alloc_data.handle)) { 4361 DEBUG_PRINT_ERROR("\n ION free failed "); 4362 return; 4363 } 4364 close(buf_ion_info->ion_device_fd); 4365 buf_ion_info->ion_alloc_data.handle = NULL; 4366 buf_ion_info->ion_device_fd = -1; 4367 buf_ion_info->fd_ion_data.fd = -1; 4368 } 4369 #endif 4370 #endif 4371 #ifdef _ANDROID_ICS_ 4372 void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer) 4373 { 4374 if(buffer && meta_mode_enable) 4375 { 4376 encoder_media_buffer_type *media_ptr; 4377 struct pmem Input_pmem; 4378 unsigned int index_pmem = 0; 4379 bool meta_error = false; 4380 4381 index_pmem = (buffer - m_inp_mem_ptr); 4382 if(mUseProxyColorFormat && 4383 (index_pmem < m_sInPortDef.nBufferCountActual)) { 4384 if(!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)){ 4385 DEBUG_PRINT_ERROR("\n omx_release_meta_buffer dev free failed"); 4386 } 4387 } else { 4388 media_ptr = (encoder_media_buffer_type *) buffer->pBuffer; 4389 if(media_ptr && media_ptr->meta_handle) 4390 { 4391 if(media_ptr->buffer_type == kMetadataBufferTypeCameraSource && 4392 media_ptr->meta_handle->numFds == 1 && 4393 media_ptr->meta_handle->numInts == 2) { 4394 Input_pmem.fd = media_ptr->meta_handle->data[0]; 4395 Input_pmem.buffer = media_ptr; 4396 Input_pmem.size = media_ptr->meta_handle->data[2]; 4397 Input_pmem.offset = media_ptr->meta_handle->data[1]; 4398 DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd, 4399 Input_pmem.offset, 4400 Input_pmem.size); 4401 } else if(media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) { 4402 private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle; 4403 Input_pmem.buffer = media_ptr; 4404 Input_pmem.fd = handle->fd; 4405 Input_pmem.offset = 0; 4406 Input_pmem.size = handle->size; 4407 } else { 4408 meta_error = true; 4409 DEBUG_PRINT_ERROR(" Meta Error set in EBD"); 4410 } 4411 if(!meta_error) 4412 meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN); 4413 if(meta_error) 4414 { 4415 DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d", 4416 input_flush_progress); 4417 } 4418 } 4419 } 4420 } 4421 } 4422 #endif 4423 omx_video::omx_c2d_conv::omx_c2d_conv() 4424 { 4425 c2dcc = NULL; 4426 mLibHandle = NULL; 4427 mConvertOpen = NULL; 4428 mConvertClose = NULL; 4429 src_format = NV12_2K; 4430 } 4431 4432 bool omx_video::omx_c2d_conv::init() { 4433 bool status = true; 4434 if(mLibHandle || mConvertOpen || mConvertClose) { 4435 DEBUG_PRINT_ERROR("\n omx_c2d_conv::init called twice"); 4436 status = false; 4437 } 4438 if(status) { 4439 mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY); 4440 if(mLibHandle){ 4441 mConvertOpen = (createC2DColorConverter_t *) 4442 dlsym(mLibHandle,"createC2DColorConverter"); 4443 mConvertClose = (destroyC2DColorConverter_t *) 4444 dlsym(mLibHandle,"destroyC2DColorConverter"); 4445 if(!mConvertOpen || !mConvertClose) 4446 status = false; 4447 } else 4448 status = false; 4449 } 4450 if(!status && mLibHandle){ 4451 dlclose(mLibHandle); 4452 mLibHandle = NULL; 4453 mConvertOpen = NULL; 4454 mConvertClose = NULL; 4455 } 4456 return status; 4457 } 4458 4459 bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr, 4460 int dest_fd, void *dest_base, void *dest_viraddr) 4461 { 4462 int result; 4463 if(!src_viraddr || !dest_viraddr || !c2dcc){ 4464 DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert"); 4465 return false; 4466 } 4467 result = c2dcc->convertC2D(src_fd, src_base, src_viraddr, 4468 dest_fd, dest_base, dest_viraddr); 4469 DEBUG_PRINT_LOW("\n Color convert status %d",result); 4470 return ((result < 0)?false:true); 4471 } 4472 4473 bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width, 4474 ColorConvertFormat src, ColorConvertFormat dest) 4475 { 4476 bool status = false; 4477 size_t srcStride = 0; 4478 if(!c2dcc) { 4479 c2dcc = mConvertOpen(width, height, width, height, 4480 src, dest, 0, srcStride); 4481 if(c2dcc) { 4482 src_format = src; 4483 status = true; 4484 } else 4485 DEBUG_PRINT_ERROR("\n mConvertOpen failed"); 4486 } 4487 return status; 4488 } 4489 void omx_video::omx_c2d_conv::close() 4490 { 4491 if(mLibHandle) { 4492 if(mConvertClose && c2dcc) 4493 mConvertClose(c2dcc); 4494 c2dcc = NULL; 4495 } 4496 } 4497 omx_video::omx_c2d_conv::~omx_c2d_conv() 4498 { 4499 DEBUG_PRINT_ERROR("\n Destroy C2D instance"); 4500 if(mLibHandle) { 4501 if(mConvertClose && c2dcc) 4502 mConvertClose(c2dcc); 4503 dlclose(mLibHandle); 4504 } 4505 c2dcc = NULL; 4506 mLibHandle = NULL; 4507 mConvertOpen = NULL; 4508 mConvertClose = NULL; 4509 } 4510 int omx_video::omx_c2d_conv::get_src_format() 4511 { 4512 int format = -1; 4513 if(src_format == NV12_2K) { 4514 format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; 4515 } else if(src_format == RGBA8888) { 4516 format = HAL_PIXEL_FORMAT_RGBA_8888; 4517 } 4518 return format; 4519 } 4520 bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size) 4521 { 4522 int cret = 0; 4523 bool ret = false; 4524 C2DBuffReq bufferreq; 4525 if(c2dcc){ 4526 bufferreq.size = 0; 4527 cret = c2dcc->getBuffReq(port,&bufferreq); 4528 DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret); 4529 ret = (cret)?false:true; 4530 buf_size = bufferreq.size; 4531 } 4532 return ret; 4533 } 4534 OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp, 4535 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 4536 { 4537 unsigned nBufIndex = 0; 4538 OMX_ERRORTYPE ret = OMX_ErrorNone; 4539 encoder_media_buffer_type *media_buffer; 4540 DEBUG_PRINT_LOW("\n ETBProxyOpaque: buffer[%p]\n", buffer); 4541 4542 if(buffer == NULL) { 4543 DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid buffer[%p]\n",buffer); 4544 return OMX_ErrorBadParameter; 4545 } 4546 nBufIndex = buffer - meta_buffer_hdr; 4547 if(nBufIndex >= m_sInPortDef.nBufferCountActual) { 4548 DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid bufindex = %u\n", 4549 nBufIndex); 4550 return OMX_ErrorBadParameter; 4551 } 4552 media_buffer = (encoder_media_buffer_type *)buffer->pBuffer; 4553 private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; 4554 /*Enable following code once private handle color format is 4555 updated correctly*/ 4556 4557 if(buffer->nFilledLen > 0) { 4558 if(c2d_opened && handle->format != c2d_conv.get_src_format()) { 4559 c2d_conv.close(); 4560 c2d_opened = false; 4561 } 4562 if (!c2d_opened) { 4563 if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) { 4564 DEBUG_PRINT_ERROR("\n open Color conv for RGBA888"); 4565 if(!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight, 4566 m_sInPortDef.format.video.nFrameWidth,RGBA8888,NV12_2K)){ 4567 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); 4568 DEBUG_PRINT_ERROR("\n Color conv open failed"); 4569 return OMX_ErrorBadParameter; 4570 } 4571 c2d_opened = true; 4572 } else if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) { 4573 DEBUG_PRINT_ERROR("\n Incorrect color format"); 4574 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); 4575 return OMX_ErrorBadParameter; 4576 } 4577 } 4578 } 4579 4580 if(input_flush_progress == true) 4581 { 4582 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); 4583 DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Input flush in progress"); 4584 return OMX_ErrorNone; 4585 } 4586 4587 if(!psource_frame) { 4588 psource_frame = buffer; 4589 ret = push_input_buffer(hComp); 4590 } else { 4591 if (!m_opq_meta_q.insert_entry((unsigned)buffer,0,0)) { 4592 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Queue is full"); 4593 ret = OMX_ErrorBadParameter; 4594 } 4595 } 4596 if(ret != OMX_ErrorNone) { 4597 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); 4598 DEBUG_PRINT_LOW("\nERROR: ETBOpaque failed:"); 4599 } 4600 return ret; 4601 } 4602 OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp, 4603 struct pmem &Input_pmem_info) { 4604 4605 OMX_ERRORTYPE ret = OMX_ErrorNone; 4606 unsigned address = 0,p2,id; 4607 4608 DEBUG_PRINT_LOW("\n In queue Meta Buffer"); 4609 if(!psource_frame || !pdest_frame) { 4610 DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params"); 4611 return OMX_ErrorBadParameter; 4612 } 4613 4614 if(psource_frame->nFilledLen > 0) { 4615 if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) { 4616 DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); 4617 post_event ((unsigned int)psource_frame,0,OMX_COMPONENT_GENERATE_EBD); 4618 ret = OMX_ErrorBadParameter; 4619 } 4620 } 4621 4622 if(ret == OMX_ErrorNone) 4623 ret = empty_this_buffer_proxy(hComp,psource_frame); 4624 4625 if(ret == OMX_ErrorNone) { 4626 psource_frame = NULL; 4627 if(!psource_frame && m_opq_meta_q.m_size) { 4628 m_opq_meta_q.pop_entry(&address,&p2,&id); 4629 psource_frame = (OMX_BUFFERHEADERTYPE* ) address; 4630 } 4631 } 4632 return ret; 4633 } 4634 4635 OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp, 4636 struct pmem &Input_pmem_info,unsigned &index){ 4637 4638 unsigned char *uva; 4639 OMX_ERRORTYPE ret = OMX_ErrorNone; 4640 unsigned address = 0,p2,id; 4641 4642 DEBUG_PRINT_LOW("\n In Convert and queue Meta Buffer"); 4643 if(!psource_frame || !pdest_frame) { 4644 DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params"); 4645 return OMX_ErrorBadParameter; 4646 } 4647 4648 if(!psource_frame->nFilledLen){ 4649 if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS){ 4650 pdest_frame->nFilledLen = psource_frame->nFilledLen; 4651 pdest_frame->nTimeStamp = psource_frame->nTimeStamp; 4652 pdest_frame->nFlags = psource_frame->nFlags; 4653 DEBUG_PRINT_HIGH("\n Skipping color conversion for empty EOS \ 4654 Buffer header=%p filled-len=%d", pdest_frame,pdest_frame->nFilledLen); 4655 } else { 4656 pdest_frame->nOffset = 0; 4657 pdest_frame->nFilledLen = 0; 4658 pdest_frame->nTimeStamp = psource_frame->nTimeStamp; 4659 pdest_frame->nFlags = psource_frame->nFlags; 4660 DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d", 4661 pdest_frame,pdest_frame->nFilledLen); 4662 } 4663 } else { 4664 uva = (unsigned char *)mmap(NULL, Input_pmem_info.size, 4665 PROT_READ|PROT_WRITE, 4666 MAP_SHARED,Input_pmem_info.fd,0); 4667 if(uva == MAP_FAILED) { 4668 ret = OMX_ErrorBadParameter; 4669 } else { 4670 if(!c2d_conv.convert(Input_pmem_info.fd, uva, uva, 4671 m_pInput_pmem[index].fd, pdest_frame->pBuffer, pdest_frame->pBuffer)) { 4672 DEBUG_PRINT_ERROR("\n Color Conversion failed"); 4673 ret = OMX_ErrorBadParameter; 4674 } else { 4675 unsigned int buf_size = 0; 4676 if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size)) 4677 ret = OMX_ErrorBadParameter; 4678 else { 4679 pdest_frame->nOffset = 0; 4680 if(!buf_size || buf_size > pdest_frame->nAllocLen) { 4681 DEBUG_PRINT_ERROR("\n convert_queue_buffer buffer" 4682 "size mismatch buf size %d alloc size %d", 4683 buf_size, pdest_frame->nAllocLen); 4684 ret = OMX_ErrorBadParameter; 4685 buf_size = 0; 4686 } 4687 pdest_frame->nFilledLen = buf_size; 4688 pdest_frame->nTimeStamp = psource_frame->nTimeStamp; 4689 pdest_frame->nFlags = psource_frame->nFlags; 4690 DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d", 4691 pdest_frame,pdest_frame->nFilledLen); 4692 } 4693 } 4694 munmap(uva,Input_pmem_info.size); 4695 } 4696 } 4697 if((ret == OMX_ErrorNone) && 4698 dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) { 4699 DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf"); 4700 post_event ((unsigned int)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD); 4701 ret = OMX_ErrorBadParameter; 4702 } 4703 if(ret == OMX_ErrorNone) 4704 ret = empty_this_buffer_proxy(hComp,pdest_frame); 4705 if(ret == OMX_ErrorNone) { 4706 m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame); 4707 psource_frame = NULL; 4708 pdest_frame = NULL; 4709 if(!psource_frame && m_opq_meta_q.m_size) { 4710 m_opq_meta_q.pop_entry(&address,&p2,&id); 4711 psource_frame = (OMX_BUFFERHEADERTYPE* ) address; 4712 } 4713 if(!pdest_frame && m_opq_pmem_q.m_size) { 4714 m_opq_pmem_q.pop_entry(&address,&p2,&id); 4715 pdest_frame = (OMX_BUFFERHEADERTYPE* ) address; 4716 DEBUG_PRINT_LOW("\n pdest_frame pop address is %p",pdest_frame); 4717 } 4718 } 4719 return ret; 4720 } 4721 4722 OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp) 4723 { 4724 unsigned address = 0,p2,id, index = 0; 4725 OMX_ERRORTYPE ret = OMX_ErrorNone; 4726 4727 if(!psource_frame && m_opq_meta_q.m_size) { 4728 m_opq_meta_q.pop_entry(&address,&p2,&id); 4729 psource_frame = (OMX_BUFFERHEADERTYPE* ) address; 4730 } 4731 if(!pdest_frame && m_opq_pmem_q.m_size) { 4732 m_opq_pmem_q.pop_entry(&address,&p2,&id); 4733 pdest_frame = (OMX_BUFFERHEADERTYPE* ) address; 4734 } 4735 while(psource_frame != NULL && pdest_frame != NULL && 4736 ret == OMX_ErrorNone) { 4737 struct pmem Input_pmem_info; 4738 encoder_media_buffer_type *media_buffer; 4739 index = pdest_frame - m_inp_mem_ptr; 4740 if(index >= m_sInPortDef.nBufferCountActual){ 4741 DEBUG_PRINT_ERROR("\n Output buffer index is wrong %d act count %d", 4742 index,m_sInPortDef.nBufferCountActual); 4743 return OMX_ErrorBadParameter; 4744 } 4745 media_buffer = (encoder_media_buffer_type *)psource_frame->pBuffer; 4746 /*Will enable to verify camcorder in current TIPS can be removed*/ 4747 if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) { 4748 Input_pmem_info.buffer = media_buffer; 4749 Input_pmem_info.fd = media_buffer->meta_handle->data[0]; 4750 Input_pmem_info.offset = media_buffer->meta_handle->data[1]; 4751 Input_pmem_info.size = media_buffer->meta_handle->data[2]; 4752 DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd, 4753 Input_pmem_info.offset, 4754 Input_pmem_info.size); 4755 ret = queue_meta_buffer(hComp,Input_pmem_info); 4756 } else if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS & mUseProxyColorFormat) { 4757 ret = convert_queue_buffer(hComp,Input_pmem_info,index); 4758 } else { 4759 private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; 4760 Input_pmem_info.buffer = media_buffer; 4761 Input_pmem_info.fd = handle->fd; 4762 Input_pmem_info.offset = 0; 4763 Input_pmem_info.size = handle->size; 4764 if(handle->format == HAL_PIXEL_FORMAT_RGBA_8888) 4765 ret = convert_queue_buffer(hComp,Input_pmem_info,index); 4766 else if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE) 4767 ret = queue_meta_buffer(hComp,Input_pmem_info); 4768 else 4769 ret = OMX_ErrorBadParameter; 4770 } 4771 } 4772 return ret; 4773 } 4774