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