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