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