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