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