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