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