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