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