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_IndexParamVideoSliceFMO: 2072 default: 2073 { 2074 DEBUG_PRINT_LOW("ERROR: get_parameter: unknown param %08x", paramIndex); 2075 eRet =OMX_ErrorUnsupportedIndex; 2076 break; 2077 } 2078 2079 } 2080 2081 return eRet; 2082 2083} 2084/* ====================================================================== 2085 FUNCTION 2086 omx_video::GetConfig 2087 2088 DESCRIPTION 2089 OMX Get Config Method implementation. 2090 2091 PARAMETERS 2092 <TBD>. 2093 2094 RETURN VALUE 2095 OMX Error None if successful. 2096 2097 ========================================================================== */ 2098OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp, 2099 OMX_IN OMX_INDEXTYPE configIndex, 2100 OMX_INOUT OMX_PTR configData) 2101{ 2102 (void)hComp; 2103 //////////////////////////////////////////////////////////////// 2104 // Supported Config Index Type 2105 // ============================================================= 2106 // OMX_IndexConfigVideoBitrate OMX_VIDEO_CONFIG_BITRATETYPE 2107 // OMX_IndexConfigVideoFramerate OMX_CONFIG_FRAMERATETYPE 2108 // OMX_IndexConfigCommonRotate OMX_CONFIG_ROTATIONTYPE 2109 //////////////////////////////////////////////////////////////// 2110 2111 if (configData == NULL) { 2112 DEBUG_PRINT_ERROR("ERROR: param is null"); 2113 return OMX_ErrorBadParameter; 2114 } 2115 2116 if (m_state == OMX_StateInvalid) { 2117 DEBUG_PRINT_ERROR("ERROR: can't be in invalid state"); 2118 return OMX_ErrorIncorrectStateOperation; 2119 } 2120 2121 //@todo need to validate params 2122 switch ((int)configIndex) { 2123 case OMX_IndexConfigVideoBitrate: 2124 { 2125 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_BITRATETYPE); 2126 OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData); 2127 memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate)); 2128 break; 2129 } 2130 case OMX_IndexConfigVideoFramerate: 2131 { 2132 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_FRAMERATETYPE); 2133 OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData); 2134 memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate)); 2135 break; 2136 } 2137 case OMX_IndexConfigCommonRotate: 2138 { 2139 VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ROTATIONTYPE); 2140 OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData); 2141 memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation)); 2142 break; 2143 } 2144 case QOMX_IndexConfigVideoIntraperiod: 2145 { 2146 DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod"); 2147 VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_INTRAPERIODTYPE); 2148 QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData); 2149 memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod)); 2150 break; 2151 } 2152 case OMX_IndexConfigVideoAVCIntraPeriod: 2153 { 2154 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_AVCINTRAPERIOD); 2155 OMX_VIDEO_CONFIG_AVCINTRAPERIOD *pParam = 2156 reinterpret_cast<OMX_VIDEO_CONFIG_AVCINTRAPERIOD*>(configData); 2157 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoAVCIntraPeriod"); 2158 memcpy(pParam, &m_sConfigAVCIDRPeriod, sizeof(m_sConfigAVCIDRPeriod)); 2159 break; 2160 } 2161 case OMX_IndexConfigCommonDeinterlace: 2162 { 2163 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_DEINTERLACE); 2164 OMX_VIDEO_CONFIG_DEINTERLACE *pParam = 2165 reinterpret_cast<OMX_VIDEO_CONFIG_DEINTERLACE*>(configData); 2166 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigCommonDeinterlace"); 2167 memcpy(pParam, &m_sConfigDeinterlace, sizeof(m_sConfigDeinterlace)); 2168 break; 2169 } 2170 case OMX_IndexConfigVideoVp8ReferenceFrame: 2171 { 2172 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_VP8REFERENCEFRAMETYPE); 2173 OMX_VIDEO_VP8REFERENCEFRAMETYPE* pParam = 2174 reinterpret_cast<OMX_VIDEO_VP8REFERENCEFRAMETYPE*>(configData); 2175 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigVideoVp8ReferenceFrame"); 2176 memcpy(pParam, &m_sConfigVp8ReferenceFrame, sizeof(m_sConfigVp8ReferenceFrame)); 2177 break; 2178 } 2179 case OMX_QcomIndexConfigPerfLevel: 2180 { 2181 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL); 2182 OMX_U32 perflevel; 2183 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *pParam = 2184 reinterpret_cast<OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL*>(configData); 2185 DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigPerfLevel"); 2186 if (!dev_get_performance_level(&perflevel)) { 2187 DEBUG_PRINT_ERROR("Invalid entry returned from get_performance_level %d", 2188 pParam->ePerfLevel); 2189 } else { 2190 pParam->ePerfLevel = (QOMX_VIDEO_PERF_LEVEL)perflevel; 2191 } 2192 break; 2193 } 2194 case OMX_QcomIndexConfigMaxHierPLayers: 2195 { 2196 VALIDATE_OMX_PARAM_DATA(configData, QOMX_EXTNINDEX_VIDEO_MAX_HIER_P_LAYERS); 2197 QOMX_EXTNINDEX_VIDEO_MAX_HIER_P_LAYERS* pParam = 2198 reinterpret_cast<QOMX_EXTNINDEX_VIDEO_MAX_HIER_P_LAYERS*>(configData); 2199 DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigMaxHierPLayers"); 2200 memcpy(pParam, &m_sMaxHPlayers, sizeof(m_sMaxHPlayers)); 2201 break; 2202 } 2203 case OMX_QcomIndexConfigQp: 2204 { 2205 VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_QP); 2206 OMX_SKYPE_VIDEO_CONFIG_QP* pParam = 2207 reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_QP*>(configData); 2208 DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigQp"); 2209 memcpy(pParam, &m_sConfigQP, sizeof(m_sConfigQP)); 2210 break; 2211 } 2212 case OMX_QcomIndexConfigBaseLayerId: 2213 { 2214 VALIDATE_OMX_PARAM_DATA(configData, OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID); 2215 OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID* pParam = 2216 reinterpret_cast<OMX_SKYPE_VIDEO_CONFIG_BASELAYERPID*>(configData); 2217 DEBUG_PRINT_LOW("get_config: OMX_QcomIndexConfigBaseLayerId"); 2218 memcpy(pParam, &m_sBaseLayerID, sizeof(m_sBaseLayerID)); 2219 break; 2220 } 2221 case OMX_IndexConfigAndroidIntraRefresh: 2222 { 2223 VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE); 2224 OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE* pParam = 2225 reinterpret_cast<OMX_VIDEO_CONFIG_ANDROID_INTRAREFRESHTYPE*>(configData); 2226 DEBUG_PRINT_LOW("get_config: OMX_IndexConfigAndroidIntraRefresh"); 2227 memcpy(pParam, &m_sConfigIntraRefresh, sizeof(m_sConfigIntraRefresh)); 2228 break; 2229 } 2230 default: 2231 DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex); 2232 return OMX_ErrorUnsupportedIndex; 2233 } 2234 return OMX_ErrorNone; 2235 2236} 2237 2238#define extn_equals(param, extn) (!strcmp(param, extn)) 2239 2240/* ====================================================================== 2241 FUNCTION 2242 omx_video::GetExtensionIndex 2243 2244 DESCRIPTION 2245 OMX GetExtensionIndex method implementaion. <TBD> 2246 2247 PARAMETERS 2248 <TBD>. 2249 2250 RETURN VALUE 2251 OMX Error None if everything successful. 2252 2253 ========================================================================== */ 2254OMX_ERRORTYPE omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE hComp, 2255 OMX_IN OMX_STRING paramName, 2256 OMX_OUT OMX_INDEXTYPE* indexType) 2257{ 2258 (void)hComp; 2259 if (m_state == OMX_StateInvalid) { 2260 DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State"); 2261 return OMX_ErrorInvalidState; 2262 } 2263#ifdef MAX_RES_1080P 2264 if (extn_equals(paramName, "OMX.QCOM.index.param.SliceDeliveryMode")) { 2265 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode; 2266 return OMX_ErrorNone; 2267 } 2268#endif 2269#ifdef _ANDROID_ICS_ 2270 if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) { 2271 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode; 2272 return OMX_ErrorNone; 2273 } 2274#endif 2275 if (extn_equals(paramName, "OMX.google.android.index.prependSPSPPSToIDRFrames")) { 2276 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR; 2277 return OMX_ErrorNone; 2278 } 2279 2280 if (extn_equals(paramName, "OMX.QCOM.index.param.video.HierStructure")) { 2281 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexHierarchicalStructure; 2282 return OMX_ErrorNone; 2283 } 2284 2285 if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRCount")) { 2286 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoLTRCount; 2287 return OMX_ErrorNone; 2288 } 2289 2290 if (extn_equals(paramName, "OMX.QCOM.index.param.video.LTRPeriod")) { 2291 *indexType = (OMX_INDEXTYPE)QOMX_IndexConfigVideoLTRPeriod; 2292 return OMX_ErrorNone; 2293 } 2294 2295 if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRUse")) { 2296 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRUse; 2297 return OMX_ErrorNone; 2298 } 2299 2300 if (extn_equals(paramName, "OMX.QCOM.index.config.video.LTRMark")) { 2301 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoLTRMark; 2302 return OMX_ErrorNone; 2303 } 2304 2305 if (extn_equals(paramName, "OMX.QCOM.index.config.video.hierplayers")) { 2306 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigMaxHierPLayers; 2307 return OMX_ErrorNone; 2308 } 2309 2310 if (extn_equals(paramName, "OMX.QCOM.index.param.video.baselayerid")) { 2311 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigBaseLayerId; 2312 return OMX_ErrorNone; 2313 } 2314 2315 if (extn_equals(paramName, "OMX.QCOM.index.config.video.qp")) { 2316 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigQp; 2317 return OMX_ErrorNone; 2318 } 2319 2320 if (extn_equals(paramName, "OMX.QCOM.index.param.video.sar")) { 2321 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVencAspectRatio; 2322 return OMX_ErrorNone; 2323 } 2324 2325 if (extn_equals(paramName, "OMX.QCOM.index.param.video.InputBatch")) { 2326 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamBatchSize; 2327 return OMX_ErrorNone; 2328 } 2329 2330 if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_ENABLE_ROIINFO)) { 2331 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoEnableRoiInfo; 2332 return OMX_ErrorNone; 2333 } 2334 if (extn_equals(paramName, OMX_QTI_INDEX_CONFIG_VIDEO_ROIINFO)) { 2335 *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigVideoRoiInfo; 2336 return OMX_ErrorNone; 2337 } 2338 2339 return OMX_ErrorNotImplemented; 2340} 2341 2342/* ====================================================================== 2343 FUNCTION 2344 omx_video::GetState 2345 2346 DESCRIPTION 2347 Returns the state information back to the caller.<TBD> 2348 2349 PARAMETERS 2350 <TBD>. 2351 2352 RETURN VALUE 2353 Error None if everything is successful. 2354 ========================================================================== */ 2355OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp, 2356 OMX_OUT OMX_STATETYPE* state) 2357{ 2358 (void)hComp; 2359 *state = m_state; 2360 DEBUG_PRINT_LOW("get_state: Returning the state %d",*state); 2361 return OMX_ErrorNone; 2362} 2363 2364/* ====================================================================== 2365 FUNCTION 2366 omx_video::ComponentTunnelRequest 2367 2368 DESCRIPTION 2369 OMX Component Tunnel Request method implementation. <TBD> 2370 2371 PARAMETERS 2372 None. 2373 2374 RETURN VALUE 2375 OMX Error None if everything successful. 2376 2377 ========================================================================== */ 2378OMX_ERRORTYPE omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp, 2379 OMX_IN OMX_U32 port, 2380 OMX_IN OMX_HANDLETYPE peerComponent, 2381 OMX_IN OMX_U32 peerPort, 2382 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup) 2383{ 2384 (void) hComp, (void) port, (void) peerComponent, (void) peerPort, (void) tunnelSetup; 2385 DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented"); 2386 return OMX_ErrorNotImplemented; 2387} 2388 2389/* ====================================================================== 2390 FUNCTION 2391 omx_video::UseInputBuffer 2392 2393 DESCRIPTION 2394 Helper function for Use buffer in the input pin 2395 2396 PARAMETERS 2397 None. 2398 2399 RETURN VALUE 2400 true/false 2401 2402 ========================================================================== */ 2403OMX_ERRORTYPE omx_video::use_input_buffer( 2404 OMX_IN OMX_HANDLETYPE hComp, 2405 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2406 OMX_IN OMX_U32 port, 2407 OMX_IN OMX_PTR appData, 2408 OMX_IN OMX_U32 bytes, 2409 OMX_IN OMX_U8* buffer) 2410{ 2411 (void) hComp; 2412 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2413 2414 unsigned i = 0; 2415 unsigned char *buf_addr = NULL; 2416 2417 DEBUG_PRINT_HIGH("use_input_buffer: port = %u appData = %p bytes = %u buffer = %p",(unsigned int)port,appData,(unsigned int)bytes,buffer); 2418 if (bytes < m_sInPortDef.nBufferSize) { 2419 DEBUG_PRINT_ERROR("ERROR: use_input_buffer: Size Mismatch!! " 2420 "bytes[%u] < Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize); 2421 return OMX_ErrorBadParameter; 2422 } 2423 2424 if (!m_inp_mem_ptr) { 2425 input_use_buffer = true; 2426 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 2427 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); 2428 if (m_inp_mem_ptr == NULL) { 2429 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr"); 2430 return OMX_ErrorInsufficientResources; 2431 } 2432 DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr); 2433 2434 2435 m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); 2436 if (m_pInput_pmem == NULL) { 2437 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_pmem"); 2438 return OMX_ErrorInsufficientResources; 2439 } 2440#ifdef USE_ION 2441 m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual); 2442 if (m_pInput_ion == NULL) { 2443 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_ion"); 2444 return OMX_ErrorInsufficientResources; 2445 } 2446#endif 2447 2448 for (i=0; i< m_sInPortDef.nBufferCountActual; i++) { 2449 m_pInput_pmem[i].fd = -1; 2450#ifdef USE_ION 2451 m_pInput_ion[i].ion_device_fd =-1; 2452 m_pInput_ion[i].fd_ion_data.fd =-1; 2453 m_pInput_ion[i].ion_alloc_data.handle = 0; 2454#endif 2455 } 2456 2457 } 2458 2459 for (i=0; i< m_sInPortDef.nBufferCountActual; i++) { 2460 if (BITMASK_ABSENT(&m_inp_bm_count,i)) { 2461 break; 2462 } 2463 } 2464 2465 if (i < m_sInPortDef.nBufferCountActual) { 2466 2467 *bufferHdr = (m_inp_mem_ptr + i); 2468 BITMASK_SET(&m_inp_bm_count,i); 2469 2470 (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; 2471 (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2472 (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; 2473 (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; 2474 (*bufferHdr)->pAppPrivate = appData; 2475 (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; 2476 2477 if (!m_use_input_pmem) { 2478#ifdef USE_ION 2479#ifdef _MSM8974_ 2480 m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, 2481 &m_pInput_ion[i].ion_alloc_data, 2482 &m_pInput_ion[i].fd_ion_data, 2483 secure_session ? SECURE_FLAGS_INPUT_BUFFER : 0); 2484#else 2485 m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, 2486 &m_pInput_ion[i].ion_alloc_data, 2487 &m_pInput_ion[i].fd_ion_data, ION_FLAG_CACHED); 2488#endif 2489 if (m_pInput_ion[i].ion_device_fd < 0) { 2490 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed"); 2491 return OMX_ErrorInsufficientResources; 2492 } 2493 m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd; 2494#else 2495 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2496 if (m_pInput_pmem[i].fd == 0) { 2497 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2498 } 2499 2500 if (m_pInput_pmem[i] .fd < 0) { 2501 DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed"); 2502 return OMX_ErrorInsufficientResources; 2503 } 2504#endif 2505 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; 2506 m_pInput_pmem[i].offset = 0; 2507 2508 m_pInput_pmem[i].buffer = NULL; 2509 if(!secure_session) { 2510 m_pInput_pmem[i].buffer = (unsigned char *)mmap( 2511 NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, 2512 MAP_SHARED,m_pInput_pmem[i].fd,0); 2513 2514 if (m_pInput_pmem[i].buffer == MAP_FAILED) { 2515 DEBUG_PRINT_ERROR("ERROR: mmap() Failed"); 2516 m_pInput_pmem[i].buffer = NULL; 2517 close(m_pInput_pmem[i].fd); 2518#ifdef USE_ION 2519 free_ion_memory(&m_pInput_ion[i]); 2520#endif 2521 return OMX_ErrorInsufficientResources; 2522 } 2523 } 2524 2525 } else { 2526 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate); 2527 DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (unsigned)pParam->offset); 2528 2529 if (pParam) { 2530 m_pInput_pmem[i].fd = pParam->pmem_fd; 2531 m_pInput_pmem[i].offset = pParam->offset; 2532 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; 2533 m_pInput_pmem[i].buffer = (unsigned char *)buffer; 2534 DEBUG_PRINT_LOW("DBG:: pParam->pmem_fd = %u, pParam->offset = %u", 2535 (unsigned int)pParam->pmem_fd, (unsigned int)pParam->offset); 2536 } else { 2537 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case"); 2538 return OMX_ErrorBadParameter; 2539 } 2540 } 2541 2542 DEBUG_PRINT_LOW("use_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p", 2543 (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer); 2544 if ( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true) { 2545 DEBUG_PRINT_ERROR("ERROR: dev_use_buf() Failed for i/p buf"); 2546 return OMX_ErrorInsufficientResources; 2547 } 2548 } else { 2549 DEBUG_PRINT_ERROR("ERROR: All buffers are already used, invalid use_buf call for " 2550 "index = %u", i); 2551 eRet = OMX_ErrorInsufficientResources; 2552 } 2553 2554 return eRet; 2555} 2556 2557 2558 2559/* ====================================================================== 2560 FUNCTION 2561 omx_video::UseOutputBuffer 2562 2563 DESCRIPTION 2564 Helper function for Use buffer in the input pin 2565 2566 PARAMETERS 2567 None. 2568 2569 RETURN VALUE 2570 true/false 2571 2572 ========================================================================== */ 2573OMX_ERRORTYPE omx_video::use_output_buffer( 2574 OMX_IN OMX_HANDLETYPE hComp, 2575 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2576 OMX_IN OMX_U32 port, 2577 OMX_IN OMX_PTR appData, 2578 OMX_IN OMX_U32 bytes, 2579 OMX_IN OMX_U8* buffer) 2580{ 2581 (void)hComp, (void)port; 2582 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2583 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 2584 unsigned i= 0; // Temporary counter 2585 unsigned char *buf_addr = NULL; 2586#ifdef _MSM8974_ 2587 int align_size; 2588#endif 2589 2590 DEBUG_PRINT_HIGH("Inside use_output_buffer()"); 2591 if (bytes < m_sOutPortDef.nBufferSize) { 2592 DEBUG_PRINT_ERROR("ERROR: use_output_buffer: Size Mismatch!! " 2593 "bytes[%u] < Port.nBufferSize[%u]", (unsigned int)bytes, (unsigned int)m_sOutPortDef.nBufferSize); 2594 return OMX_ErrorBadParameter; 2595 } 2596 2597 if (!m_out_mem_ptr) { 2598 output_use_buffer = true; 2599 int nBufHdrSize = 0; 2600 2601 DEBUG_PRINT_LOW("Allocating First Output Buffer(%u)",(unsigned int)m_sOutPortDef.nBufferCountActual); 2602 nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); 2603 /* 2604 * Memory for output side involves the following: 2605 * 1. Array of Buffer Headers 2606 * 2. Bitmask array to hold the buffer allocation details 2607 * In order to minimize the memory management entire allocation 2608 * is done in one step. 2609 */ 2610 //OMX Buffer header 2611 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 2612 if (m_out_mem_ptr == NULL) { 2613 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_out_mem_ptr"); 2614 return OMX_ErrorInsufficientResources; 2615 } 2616 2617 m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual); 2618 if (m_pOutput_pmem == NULL) { 2619 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_pmem"); 2620 return OMX_ErrorInsufficientResources; 2621 } 2622#ifdef USE_ION 2623 m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); 2624 if (m_pOutput_ion == NULL) { 2625 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_ion"); 2626 return OMX_ErrorInsufficientResources; 2627 } 2628#endif 2629 if (m_out_mem_ptr) { 2630 bufHdr = m_out_mem_ptr; 2631 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr); 2632 // Settting the entire storage nicely 2633 for (i=0; i < m_sOutPortDef.nBufferCountActual ; i++) { 2634 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 2635 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 2636 bufHdr->nAllocLen = bytes; 2637 bufHdr->nFilledLen = 0; 2638 bufHdr->pAppPrivate = appData; 2639 bufHdr->nOutputPortIndex = PORT_INDEX_OUT; 2640 bufHdr->pBuffer = NULL; 2641 bufHdr++; 2642 m_pOutput_pmem[i].fd = -1; 2643#ifdef USE_ION 2644 m_pOutput_ion[i].ion_device_fd =-1; 2645 m_pOutput_ion[i].fd_ion_data.fd=-1; 2646 m_pOutput_ion[i].ion_alloc_data.handle = 0; 2647#endif 2648 } 2649 } else { 2650 DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%p]",m_out_mem_ptr); 2651 eRet = OMX_ErrorInsufficientResources; 2652 } 2653 } 2654 2655 for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) { 2656 if (BITMASK_ABSENT(&m_out_bm_count,i)) { 2657 break; 2658 } 2659 } 2660 2661 if (eRet == OMX_ErrorNone) { 2662 if (i < m_sOutPortDef.nBufferCountActual) { 2663 *bufferHdr = (m_out_mem_ptr + i ); 2664 (*bufferHdr)->pBuffer = (OMX_U8 *)buffer; 2665 (*bufferHdr)->pAppPrivate = appData; 2666 2667 if (!m_use_output_pmem) { 2668#ifdef USE_ION 2669#ifdef _MSM8974_ 2670 align_size = (m_sOutPortDef.nBufferSize + (SZ_4K - 1)) & ~(SZ_4K - 1); 2671 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size, 2672 &m_pOutput_ion[i].ion_alloc_data, 2673 &m_pOutput_ion[i].fd_ion_data, 2674 secure_session ? SECURE_FLAGS_OUTPUT_BUFFER : 0); 2675#else 2676 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory( 2677 m_sOutPortDef.nBufferSize, 2678 &m_pOutput_ion[i].ion_alloc_data, 2679 &m_pOutput_ion[i].fd_ion_data, ION_FLAG_CACHED); 2680#endif 2681 if (m_pOutput_ion[i].ion_device_fd < 0) { 2682 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed"); 2683 return OMX_ErrorInsufficientResources; 2684 } 2685 m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; 2686#else 2687 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2688 2689 if (m_pOutput_pmem[i].fd == 0) { 2690 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 2691 } 2692 2693 if (m_pOutput_pmem[i].fd < 0) { 2694 DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed"); 2695 return OMX_ErrorInsufficientResources; 2696 } 2697#endif 2698 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; 2699 m_pOutput_pmem[i].offset = 0; 2700 2701 m_pOutput_pmem[i].buffer = NULL; 2702 if(!secure_session) { 2703#ifdef _MSM8974_ 2704 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL, 2705 align_size,PROT_READ|PROT_WRITE, 2706 MAP_SHARED,m_pOutput_pmem[i].fd,0); 2707#else 2708 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL, 2709 m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, 2710 MAP_SHARED,m_pOutput_pmem[i].fd,0); 2711#endif 2712 if (m_pOutput_pmem[i].buffer == MAP_FAILED) { 2713 DEBUG_PRINT_ERROR("ERROR: mmap() Failed"); 2714 m_pOutput_pmem[i].buffer = NULL; 2715 close(m_pOutput_pmem[i].fd); 2716#ifdef USE_ION 2717 free_ion_memory(&m_pOutput_ion[i]); 2718#endif 2719 return OMX_ErrorInsufficientResources; 2720 } 2721 } 2722 } else { 2723 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate); 2724 DEBUG_PRINT_LOW("Inside qcom_ext pParam: %p", pParam); 2725 2726 if (pParam) { 2727 DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%lu,offset:0x%x)", pParam->pmem_fd, (int)pParam->offset); 2728 m_pOutput_pmem[i].fd = pParam->pmem_fd; 2729 m_pOutput_pmem[i].offset = pParam->offset; 2730 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; 2731 m_pOutput_pmem[i].buffer = (unsigned char *)buffer; 2732 } else { 2733 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case"); 2734 return OMX_ErrorBadParameter; 2735 } 2736 buf_addr = (unsigned char *)buffer; 2737 } 2738 2739 DEBUG_PRINT_LOW("use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p", 2740 (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer); 2741 if (dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) { 2742 DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf"); 2743 return OMX_ErrorInsufficientResources; 2744 } 2745 2746 BITMASK_SET(&m_out_bm_count,i); 2747 } else { 2748 DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for " 2749 "index = %u", i); 2750 eRet = OMX_ErrorInsufficientResources; 2751 } 2752 } 2753 return eRet; 2754} 2755 2756 2757/* ====================================================================== 2758 FUNCTION 2759 omx_video::UseBuffer 2760 2761 DESCRIPTION 2762 OMX Use Buffer method implementation. 2763 2764 PARAMETERS 2765 <TBD>. 2766 2767 RETURN VALUE 2768 OMX Error None , if everything successful. 2769 2770 ========================================================================== */ 2771OMX_ERRORTYPE omx_video::use_buffer( 2772 OMX_IN OMX_HANDLETYPE hComp, 2773 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 2774 OMX_IN OMX_U32 port, 2775 OMX_IN OMX_PTR appData, 2776 OMX_IN OMX_U32 bytes, 2777 OMX_IN OMX_U8* buffer) 2778{ 2779 OMX_ERRORTYPE eRet = OMX_ErrorNone; 2780 if (m_state == OMX_StateInvalid) { 2781 DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State"); 2782 return OMX_ErrorInvalidState; 2783 } 2784 if (port == PORT_INDEX_IN) { 2785 eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer); 2786 } else if (port == PORT_INDEX_OUT) { 2787 eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); 2788 } else { 2789 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port); 2790 eRet = OMX_ErrorBadPortIndex; 2791 } 2792 2793 if (eRet == OMX_ErrorNone) { 2794 if (allocate_done()) { 2795 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { 2796 // Send the callback now 2797 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 2798 post_event(OMX_CommandStateSet,OMX_StateIdle, 2799 OMX_COMPONENT_GENERATE_EVENT); 2800 } 2801 } 2802 if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) { 2803 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) { 2804 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 2805 post_event(OMX_CommandPortEnable, 2806 PORT_INDEX_IN, 2807 OMX_COMPONENT_GENERATE_EVENT); 2808 } 2809 2810 } else if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) { 2811 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 2812 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 2813 post_event(OMX_CommandPortEnable, 2814 PORT_INDEX_OUT, 2815 OMX_COMPONENT_GENERATE_EVENT); 2816 m_event_port_settings_sent = false; 2817 } 2818 } 2819 } 2820 return eRet; 2821} 2822 2823OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 2824{ 2825 unsigned int index = 0; 2826 OMX_U8 *temp_buff ; 2827 2828 if (bufferHdr == NULL || m_inp_mem_ptr == NULL) { 2829 DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]", 2830 bufferHdr, m_inp_mem_ptr); 2831 return OMX_ErrorBadParameter; 2832 } 2833 2834 index = bufferHdr - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr); 2835#ifdef _ANDROID_ICS_ 2836 if (meta_mode_enable) { 2837 if (index < m_sInPortDef.nBufferCountActual) { 2838 memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); 2839 memset(&meta_buffers[index], 0, sizeof(meta_buffers[index])); 2840 } 2841 if (!mUseProxyColorFormat) 2842 return OMX_ErrorNone; 2843 else { 2844 c2d_conv.close(); 2845 opaque_buffer_hdr[index] = NULL; 2846 } 2847 } 2848#endif 2849 if (index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat && 2850 dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) { 2851 DEBUG_PRINT_LOW("ERROR: dev_free_buf() Failed for i/p buf"); 2852 } 2853 2854 if (index < m_sInPortDef.nBufferCountActual && m_pInput_pmem) { 2855 auto_lock l(m_lock); 2856 2857 if (m_pInput_pmem[index].fd > 0 && input_use_buffer == false) { 2858 DEBUG_PRINT_LOW("FreeBuffer:: i/p AllocateBuffer case"); 2859 if(!secure_session) { 2860 munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); 2861 } else { 2862 free(m_pInput_pmem[index].buffer); 2863 } 2864 m_pInput_pmem[index].buffer = NULL; 2865 close (m_pInput_pmem[index].fd); 2866#ifdef USE_ION 2867 free_ion_memory(&m_pInput_ion[index]); 2868#endif 2869 m_pInput_pmem[index].fd = -1; 2870 } else if (m_pInput_pmem[index].fd > 0 && (input_use_buffer == true && 2871 m_use_input_pmem == OMX_FALSE)) { 2872 DEBUG_PRINT_LOW("FreeBuffer:: i/p Heap UseBuffer case"); 2873 if (dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true) { 2874 DEBUG_PRINT_ERROR("ERROR: dev_free_buf() Failed for i/p buf"); 2875 } 2876 if(!secure_session) { 2877 munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size); 2878 m_pInput_pmem[index].buffer = NULL; 2879 } 2880 close (m_pInput_pmem[index].fd); 2881#ifdef USE_ION 2882 free_ion_memory(&m_pInput_ion[index]); 2883#endif 2884 m_pInput_pmem[index].fd = -1; 2885 } else { 2886 DEBUG_PRINT_ERROR("FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case"); 2887 } 2888 } 2889 return OMX_ErrorNone; 2890} 2891 2892OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr) 2893{ 2894 unsigned int index = 0; 2895 OMX_U8 *temp_buff ; 2896 2897 if (bufferHdr == NULL || m_out_mem_ptr == NULL) { 2898 DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]", 2899 bufferHdr, m_out_mem_ptr); 2900 return OMX_ErrorBadParameter; 2901 } 2902 index = bufferHdr - m_out_mem_ptr; 2903 2904 if (index < m_sOutPortDef.nBufferCountActual && 2905 dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) { 2906 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); 2907 } 2908 2909 if (index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem) { 2910 if (m_pOutput_pmem[index].fd > 0 && output_use_buffer == false ) { 2911 DEBUG_PRINT_LOW("FreeBuffer:: o/p AllocateBuffer case"); 2912 if(!secure_session) { 2913 munmap (m_pOutput_pmem[index].buffer, 2914 m_pOutput_pmem[index].size); 2915 } else { 2916 char *data = (char*) m_pOutput_pmem[index].buffer; 2917 native_handle_t *handle = NULL; 2918 memcpy(&handle, data + sizeof(OMX_U32), sizeof(native_handle_t*)); 2919 native_handle_delete(handle); 2920 free(m_pOutput_pmem[index].buffer); 2921 } 2922 close (m_pOutput_pmem[index].fd); 2923#ifdef USE_ION 2924 free_ion_memory(&m_pOutput_ion[index]); 2925#endif 2926 m_pOutput_pmem[index].fd = -1; 2927 } else if ( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true 2928 && m_use_output_pmem == OMX_FALSE)) { 2929 DEBUG_PRINT_LOW("FreeBuffer:: o/p Heap UseBuffer case"); 2930 if (dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true) { 2931 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf"); 2932 } 2933 if(!secure_session) { 2934 munmap (m_pOutput_pmem[index].buffer, 2935 m_pOutput_pmem[index].size); 2936 } 2937 close (m_pOutput_pmem[index].fd); 2938#ifdef USE_ION 2939 free_ion_memory(&m_pOutput_ion[index]); 2940#endif 2941 m_pOutput_pmem[index].fd = -1; 2942 } else { 2943 DEBUG_PRINT_LOW("FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case"); 2944 } 2945 } 2946 return OMX_ErrorNone; 2947} 2948#ifdef _ANDROID_ICS_ 2949OMX_ERRORTYPE omx_video::allocate_input_meta_buffer( 2950 OMX_HANDLETYPE hComp, 2951 OMX_BUFFERHEADERTYPE **bufferHdr, 2952 OMX_PTR appData, 2953 OMX_U32 bytes) 2954{ 2955 unsigned index = 0; 2956 if (!bufferHdr || bytes < sizeof(encoder_media_buffer_type)) { 2957 DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %u", 2958 bufferHdr, (unsigned int)bytes); 2959 return OMX_ErrorBadParameter; 2960 } 2961 2962 if (!m_inp_mem_ptr && !mUseProxyColorFormat) { 2963 m_inp_mem_ptr = meta_buffer_hdr; 2964 DEBUG_PRINT_LOW("use meta_buffer_hdr (%p) as m_inp_mem_ptr = %p", 2965 meta_buffer_hdr, m_inp_mem_ptr); 2966 } 2967 for (index = 0; ((index < m_sInPortDef.nBufferCountActual) && 2968 meta_buffer_hdr[index].pBuffer); index++); 2969 if (index == m_sInPortDef.nBufferCountActual) { 2970 DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer"); 2971 return OMX_ErrorBadParameter; 2972 } 2973 if (mUseProxyColorFormat) { 2974 if (opaque_buffer_hdr[index]) { 2975 DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr"); 2976 return OMX_ErrorBadParameter; 2977 } 2978 if (allocate_input_buffer(hComp,&opaque_buffer_hdr[index], 2979 PORT_INDEX_IN,appData,m_sInPortDef.nBufferSize) != OMX_ErrorNone) { 2980 DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr"); 2981 return OMX_ErrorBadParameter; 2982 } 2983 } 2984 BITMASK_SET(&m_inp_bm_count,index); 2985 *bufferHdr = &meta_buffer_hdr[index]; 2986 memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index])); 2987 meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]); 2988 meta_buffer_hdr[index].nAllocLen = sizeof(meta_buffers[index]); 2989 meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION; 2990 meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN; 2991 meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index]; 2992 meta_buffer_hdr[index].pAppPrivate = appData; 2993 if (mUseProxyColorFormat) { 2994 m_opq_pmem_q.insert_entry((unsigned long)opaque_buffer_hdr[index],0,0); 2995 DEBUG_PRINT_HIGH("opaque_buffer_hdr insert %p", opaque_buffer_hdr[index]); 2996 } 2997 return OMX_ErrorNone; 2998} 2999#endif 3000/* ====================================================================== 3001 FUNCTION 3002 omx_venc::AllocateInputBuffer 3003 3004 DESCRIPTION 3005 Helper function for allocate buffer in the input pin 3006 3007 PARAMETERS 3008 None. 3009 3010 RETURN VALUE 3011 true/false 3012 3013 ========================================================================== */ 3014OMX_ERRORTYPE omx_video::allocate_input_buffer( 3015 OMX_IN OMX_HANDLETYPE hComp, 3016 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3017 OMX_IN OMX_U32 port, 3018 OMX_IN OMX_PTR appData, 3019 OMX_IN OMX_U32 bytes) 3020{ 3021 (void)hComp, (void)port; 3022 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3023 unsigned i = 0; 3024 3025 DEBUG_PRINT_HIGH("allocate_input_buffer()::"); 3026 if (bytes < m_sInPortDef.nBufferSize) { 3027 DEBUG_PRINT_ERROR("ERROR: Buffer size mismatch error: bytes[%u] < nBufferSize[%u]", 3028 (unsigned int)bytes, (unsigned int)m_sInPortDef.nBufferSize); 3029 return OMX_ErrorBadParameter; 3030 } 3031 3032 if (!m_inp_mem_ptr) { 3033 DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__, 3034 (unsigned int)m_sInPortDef.nBufferSize, (unsigned int)m_sInPortDef.nBufferCountActual); 3035 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \ 3036 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual); 3037 if (m_inp_mem_ptr == NULL) { 3038 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_inp_mem_ptr"); 3039 return OMX_ErrorInsufficientResources; 3040 } 3041 3042 DEBUG_PRINT_LOW("Successfully allocated m_inp_mem_ptr = %p", m_inp_mem_ptr); 3043 m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual); 3044 3045 if (m_pInput_pmem == NULL) { 3046 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_pmem"); 3047 return OMX_ErrorInsufficientResources; 3048 } 3049#ifdef USE_ION 3050 m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual); 3051 if (m_pInput_ion == NULL) { 3052 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pInput_ion"); 3053 return OMX_ErrorInsufficientResources; 3054 } 3055#endif 3056 for (i=0; i< m_sInPortDef.nBufferCountActual; i++) { 3057 m_pInput_pmem[i].fd = -1; 3058#ifdef USE_ION 3059 m_pInput_ion[i].ion_device_fd =-1; 3060 m_pInput_ion[i].fd_ion_data.fd =-1; 3061 m_pInput_ion[i].ion_alloc_data.handle = 0; 3062#endif 3063 } 3064 } 3065 3066 for (i=0; i< m_sInPortDef.nBufferCountActual; i++) { 3067 if (BITMASK_ABSENT(&m_inp_bm_count,i)) { 3068 break; 3069 } 3070 } 3071 if (i < m_sInPortDef.nBufferCountActual) { 3072 3073 *bufferHdr = (m_inp_mem_ptr + i); 3074 (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE); 3075 (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION; 3076 (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize; 3077 (*bufferHdr)->pAppPrivate = appData; 3078 (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN; 3079 // make fd available to app layer, help with testing 3080 (*bufferHdr)->pInputPortPrivate = (OMX_PTR)&m_pInput_pmem[i]; 3081 3082#ifdef USE_ION 3083#ifdef _MSM8974_ 3084 m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, 3085 &m_pInput_ion[i].ion_alloc_data, 3086 &m_pInput_ion[i].fd_ion_data, 3087 secure_session ? SECURE_FLAGS_INPUT_BUFFER : 0); 3088#else 3089 m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize, 3090 &m_pInput_ion[i].ion_alloc_data, 3091 &m_pInput_ion[i].fd_ion_data, ION_FLAG_CACHED); 3092#endif 3093 if (m_pInput_ion[i].ion_device_fd < 0) { 3094 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed"); 3095 return OMX_ErrorInsufficientResources; 3096 } 3097 3098 m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd; 3099#else 3100 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 3101 3102 if (m_pInput_pmem[i].fd == 0) { 3103 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 3104 } 3105 3106 if (m_pInput_pmem[i].fd < 0) { 3107 DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() Failed"); 3108 return OMX_ErrorInsufficientResources; 3109 } 3110#endif 3111 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize; 3112 m_pInput_pmem[i].offset = 0; 3113 3114 m_pInput_pmem[i].buffer = NULL; 3115 if(!secure_session) { 3116 m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL, 3117 m_pInput_pmem[i].size,PROT_READ|PROT_WRITE, 3118 MAP_SHARED,m_pInput_pmem[i].fd,0); 3119 if (m_pInput_pmem[i].buffer == MAP_FAILED) { 3120 DEBUG_PRINT_ERROR("ERROR: mmap FAILED= %d", errno); 3121 m_pInput_pmem[i].buffer = NULL; 3122 close(m_pInput_pmem[i].fd); 3123#ifdef USE_ION 3124 free_ion_memory(&m_pInput_ion[i]); 3125#endif 3126 return OMX_ErrorInsufficientResources; 3127 } 3128 } else { 3129 //This should only be used for passing reference to source type and 3130 //secure handle fd struct native_handle_t* 3131 m_pInput_pmem[i].buffer = malloc(sizeof(OMX_U32) + sizeof(native_handle_t*)); 3132 if (m_pInput_pmem[i].buffer == NULL) { 3133 DEBUG_PRINT_ERROR("%s: failed to allocate native-handle", __func__); 3134 return OMX_ErrorInsufficientResources; 3135 } 3136 } 3137 3138 (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer; 3139 DEBUG_PRINT_LOW("Virtual address in allocate buffer is %p", m_pInput_pmem[i].buffer); 3140 BITMASK_SET(&m_inp_bm_count,i); 3141 //here change the I/P param here from buf_adr to pmem 3142 if (!mUseProxyColorFormat && (dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)) { 3143 DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for i/p buf"); 3144 return OMX_ErrorInsufficientResources; 3145 } 3146 } else { 3147 DEBUG_PRINT_ERROR("ERROR: All i/p buffers are allocated, invalid allocate buf call" 3148 "for index [%d]", i); 3149 eRet = OMX_ErrorInsufficientResources; 3150 } 3151 3152 return eRet; 3153} 3154 3155 3156/* ====================================================================== 3157 FUNCTION 3158 omx_venc::AllocateOutputBuffer 3159 3160 DESCRIPTION 3161 Helper fn for AllocateBuffer in the output pin 3162 3163 PARAMETERS 3164 <TBD>. 3165 3166 RETURN VALUE 3167 OMX Error None if everything went well. 3168 3169 ========================================================================== */ 3170OMX_ERRORTYPE omx_video::allocate_output_buffer( 3171 OMX_IN OMX_HANDLETYPE hComp, 3172 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3173 OMX_IN OMX_U32 port, 3174 OMX_IN OMX_PTR appData, 3175 OMX_IN OMX_U32 bytes) 3176{ 3177 (void)hComp, (void)port; 3178 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3179 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header 3180 unsigned i= 0; // Temporary counter 3181#ifdef _MSM8974_ 3182 int align_size; 3183#endif 3184 DEBUG_PRINT_HIGH("allocate_output_buffer()for %u bytes", (unsigned int)bytes); 3185 if (!m_out_mem_ptr) { 3186 int nBufHdrSize = 0; 3187 DEBUG_PRINT_HIGH("%s: size = %u, actual cnt %u", __FUNCTION__, 3188 (unsigned int)m_sOutPortDef.nBufferSize, (unsigned int)m_sOutPortDef.nBufferCountActual); 3189 nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE); 3190 3191 /* 3192 * Memory for output side involves the following: 3193 * 1. Array of Buffer Headers 3194 * 2. Bitmask array to hold the buffer allocation details 3195 * In order to minimize the memory management entire allocation 3196 * is done in one step. 3197 */ 3198 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1); 3199 3200#ifdef USE_ION 3201 m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual); 3202 if (m_pOutput_ion == NULL) { 3203 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_ion"); 3204 return OMX_ErrorInsufficientResources; 3205 } 3206#endif 3207 m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual); 3208 if (m_pOutput_pmem == NULL) { 3209 DEBUG_PRINT_ERROR("ERROR: calloc() Failed for m_pOutput_pmem"); 3210 return OMX_ErrorInsufficientResources; 3211 } 3212 if (m_out_mem_ptr && m_pOutput_pmem) { 3213 bufHdr = m_out_mem_ptr; 3214 3215 for (i=0; i < m_sOutPortDef.nBufferCountActual ; i++) { 3216 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE); 3217 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION; 3218 // Set the values when we determine the right HxW param 3219 bufHdr->nAllocLen = m_sOutPortDef.nBufferSize; 3220 bufHdr->nFilledLen = 0; 3221 bufHdr->pAppPrivate = appData; 3222 bufHdr->nOutputPortIndex = PORT_INDEX_OUT; 3223 // make fd available to app layer, help with testing 3224 bufHdr->pOutputPortPrivate = (OMX_PTR)&m_pOutput_pmem[i]; 3225 bufHdr->pBuffer = NULL; 3226 bufHdr++; 3227 m_pOutput_pmem[i].fd = -1; 3228#ifdef USE_ION 3229 m_pOutput_ion[i].ion_device_fd =-1; 3230 m_pOutput_ion[i].fd_ion_data.fd=-1; 3231 m_pOutput_ion[i].ion_alloc_data.handle = 0; 3232#endif 3233 } 3234 } else { 3235 DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem"); 3236 eRet = OMX_ErrorInsufficientResources; 3237 } 3238 } 3239 3240 DEBUG_PRINT_HIGH("actual cnt = %u", (unsigned int)m_sOutPortDef.nBufferCountActual); 3241 for (i=0; i< m_sOutPortDef.nBufferCountActual; i++) { 3242 if (BITMASK_ABSENT(&m_out_bm_count,i)) { 3243 DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i); 3244 break; 3245 } 3246 } 3247 if (eRet == OMX_ErrorNone) { 3248 if (i < m_sOutPortDef.nBufferCountActual) { 3249#ifdef USE_ION 3250#ifdef _MSM8974_ 3251 align_size = ((m_sOutPortDef.nBufferSize + 4095)/4096) * 4096; 3252 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(align_size, 3253 &m_pOutput_ion[i].ion_alloc_data, 3254 &m_pOutput_ion[i].fd_ion_data, 3255 secure_session ? SECURE_FLAGS_OUTPUT_BUFFER : ION_FLAG_CACHED); 3256#else 3257 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize, 3258 &m_pOutput_ion[i].ion_alloc_data, 3259 &m_pOutput_ion[i].fd_ion_data, ION_FLAG_CACHED); 3260#endif 3261 if (m_pOutput_ion[i].ion_device_fd < 0) { 3262 DEBUG_PRINT_ERROR("ERROR:ION device open() Failed"); 3263 return OMX_ErrorInsufficientResources; 3264 } 3265 3266 m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd; 3267#else 3268 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 3269 if (m_pOutput_pmem[i].fd == 0) { 3270 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR); 3271 } 3272 3273 if (m_pOutput_pmem[i].fd < 0) { 3274 DEBUG_PRINT_ERROR("ERROR: /dev/pmem_adsp open() failed"); 3275 return OMX_ErrorInsufficientResources; 3276 } 3277#endif 3278 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize; 3279 m_pOutput_pmem[i].offset = 0; 3280 3281 m_pOutput_pmem[i].buffer = NULL; 3282 if(!secure_session) { 3283#ifdef _MSM8974_ 3284 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL, 3285 align_size,PROT_READ|PROT_WRITE, 3286 MAP_SHARED,m_pOutput_pmem[i].fd,0); 3287#else 3288 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL, 3289 m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE, 3290 MAP_SHARED,m_pOutput_pmem[i].fd,0); 3291#endif 3292 if (m_pOutput_pmem[i].buffer == MAP_FAILED) { 3293 DEBUG_PRINT_ERROR("ERROR: MMAP_FAILED in o/p alloc buffer"); 3294 m_pOutput_pmem[i].buffer = NULL; 3295 close (m_pOutput_pmem[i].fd); 3296#ifdef USE_ION 3297 free_ion_memory(&m_pOutput_ion[i]); 3298#endif 3299 return OMX_ErrorInsufficientResources; 3300 } 3301 } 3302 else { 3303 //This should only be used for passing reference to source type and 3304 //secure handle fd struct native_handle_t* 3305 m_pOutput_pmem[i].buffer = malloc(sizeof(OMX_U32) + sizeof(native_handle_t*)); 3306 if (m_pOutput_pmem[i].buffer == NULL) { 3307 DEBUG_PRINT_ERROR("%s: failed to allocate native-handle", __func__); 3308 return OMX_ErrorInsufficientResources; 3309 } 3310 native_handle_t *handle = native_handle_create(1, 0); 3311 handle->data[0] = m_pOutput_pmem[i].fd; 3312 char *data = (char*) m_pOutput_pmem[i].buffer; 3313 OMX_U32 type = 1; 3314 memcpy(data, &type, sizeof(OMX_U32)); 3315 memcpy(data + sizeof(OMX_U32), &handle, sizeof(native_handle_t*)); 3316 } 3317 3318 *bufferHdr = (m_out_mem_ptr + i ); 3319 (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer; 3320 (*bufferHdr)->pAppPrivate = appData; 3321 3322 BITMASK_SET(&m_out_bm_count,i); 3323 3324 if (dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true) { 3325 DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for o/p buf"); 3326 return OMX_ErrorInsufficientResources; 3327 } 3328 } else { 3329 DEBUG_PRINT_ERROR("ERROR: All o/p buffers are allocated, invalid allocate buf call" 3330 "for index [%d] actual: %u", i, (unsigned int)m_sOutPortDef.nBufferCountActual); 3331 } 3332 } 3333 3334 return eRet; 3335} 3336 3337 3338// AllocateBuffer -- API Call 3339/* ====================================================================== 3340 FUNCTION 3341 omx_video::AllocateBuffer 3342 3343 DESCRIPTION 3344 Returns zero if all the buffers released.. 3345 3346 PARAMETERS 3347 None. 3348 3349 RETURN VALUE 3350 true/false 3351 3352 ========================================================================== */ 3353OMX_ERRORTYPE omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp, 3354 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3355 OMX_IN OMX_U32 port, 3356 OMX_IN OMX_PTR appData, 3357 OMX_IN OMX_U32 bytes) 3358{ 3359 3360 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type 3361 3362 DEBUG_PRINT_LOW("Allocate buffer of size = %u on port %d", (unsigned int)bytes, (int)port); 3363 if (m_state == OMX_StateInvalid) { 3364 DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State"); 3365 return OMX_ErrorInvalidState; 3366 } 3367 3368 // What if the client calls again. 3369 if (port == PORT_INDEX_IN) { 3370#ifdef _ANDROID_ICS_ 3371 if (meta_mode_enable) 3372 eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes); 3373 else 3374#endif 3375 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes); 3376 } else if (port == PORT_INDEX_OUT) { 3377 eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes); 3378 } else { 3379 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port); 3380 eRet = OMX_ErrorBadPortIndex; 3381 } 3382 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done"); 3383 if (eRet == OMX_ErrorNone) { 3384 if (allocate_done()) { 3385 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) { 3386 // Send the callback now 3387 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING); 3388 post_event(OMX_CommandStateSet,OMX_StateIdle, 3389 OMX_COMPONENT_GENERATE_EVENT); 3390 } 3391 } 3392 if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) { 3393 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) { 3394 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING); 3395 post_event(OMX_CommandPortEnable, 3396 PORT_INDEX_IN, 3397 OMX_COMPONENT_GENERATE_EVENT); 3398 } 3399 } 3400 if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) { 3401 if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) { 3402 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING); 3403 post_event(OMX_CommandPortEnable, 3404 PORT_INDEX_OUT, 3405 OMX_COMPONENT_GENERATE_EVENT); 3406 m_event_port_settings_sent = false; 3407 } 3408 } 3409 } 3410 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet); 3411 return eRet; 3412} 3413 3414 3415// Free Buffer - API call 3416/* ====================================================================== 3417 FUNCTION 3418 omx_video::FreeBuffer 3419 3420 DESCRIPTION 3421 3422 PARAMETERS 3423 None. 3424 3425 RETURN VALUE 3426 true/false 3427 3428 ========================================================================== */ 3429OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp, 3430 OMX_IN OMX_U32 port, 3431 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 3432{ 3433 (void)hComp; 3434 OMX_ERRORTYPE eRet = OMX_ErrorNone; 3435 unsigned int nPortIndex; 3436 3437 DEBUG_PRINT_LOW("In for encoder free_buffer"); 3438 3439 if (m_state == OMX_StateIdle && 3440 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) { 3441 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending"); 3442 } else if ((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)|| 3443 (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) { 3444 DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port); 3445 } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) { 3446 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled"); 3447 post_event(OMX_EventError, 3448 OMX_ErrorPortUnpopulated, 3449 OMX_COMPONENT_GENERATE_EVENT); 3450 return eRet; 3451 } else { 3452 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers"); 3453 post_event(OMX_EventError, 3454 OMX_ErrorPortUnpopulated, 3455 OMX_COMPONENT_GENERATE_EVENT); 3456 } 3457 3458 if (port == PORT_INDEX_IN) { 3459 // check if the buffer is valid 3460 nPortIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr); 3461 3462 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %u, actual cnt %u", 3463 nPortIndex, (unsigned int)m_sInPortDef.nBufferCountActual); 3464 if (nPortIndex < m_sInPortDef.nBufferCountActual && 3465 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) { 3466 // Clear the bit associated with it. 3467 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex); 3468 free_input_buffer (buffer); 3469 m_sInPortDef.bPopulated = OMX_FALSE; 3470 3471 /*Free the Buffer Header*/ 3472 if (release_input_done() 3473#ifdef _ANDROID_ICS_ 3474 && !meta_mode_enable 3475#endif 3476 ) { 3477 input_use_buffer = false; 3478 if (m_inp_mem_ptr) { 3479 DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr"); 3480 free (m_inp_mem_ptr); 3481 m_inp_mem_ptr = NULL; 3482 } 3483 if (m_pInput_pmem) { 3484 DEBUG_PRINT_LOW("Freeing m_pInput_pmem"); 3485 free(m_pInput_pmem); 3486 m_pInput_pmem = NULL; 3487 } 3488#ifdef USE_ION 3489 if (m_pInput_ion) { 3490 DEBUG_PRINT_LOW("Freeing m_pInput_ion"); 3491 free(m_pInput_ion); 3492 m_pInput_ion = NULL; 3493 } 3494#endif 3495 } 3496 } else { 3497 DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid"); 3498 eRet = OMX_ErrorBadPortIndex; 3499 } 3500 3501 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING) 3502 && release_input_done()) { 3503 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); 3504 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING); 3505 post_event(OMX_CommandPortDisable, 3506 PORT_INDEX_IN, 3507 OMX_COMPONENT_GENERATE_EVENT); 3508 } 3509 } else if (port == PORT_INDEX_OUT) { 3510 // check if the buffer is valid 3511 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr; 3512 3513 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %u, actual cnt %u", 3514 nPortIndex, (unsigned int)m_sOutPortDef.nBufferCountActual); 3515 if (nPortIndex < m_sOutPortDef.nBufferCountActual && 3516 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) { 3517 // Clear the bit associated with it. 3518 BITMASK_CLEAR(&m_out_bm_count,nPortIndex); 3519 m_sOutPortDef.bPopulated = OMX_FALSE; 3520 free_output_buffer (buffer); 3521 3522 if (release_output_done()) { 3523 output_use_buffer = false; 3524 if (m_out_mem_ptr) { 3525 DEBUG_PRINT_LOW("Freeing m_out_mem_ptr"); 3526 free (m_out_mem_ptr); 3527 m_out_mem_ptr = NULL; 3528 } 3529 if (m_pOutput_pmem) { 3530 DEBUG_PRINT_LOW("Freeing m_pOutput_pmem"); 3531 free(m_pOutput_pmem); 3532 m_pOutput_pmem = NULL; 3533 } 3534#ifdef USE_ION 3535 if (m_pOutput_ion) { 3536 DEBUG_PRINT_LOW("Freeing m_pOutput_ion"); 3537 free(m_pOutput_ion); 3538 m_pOutput_ion = NULL; 3539 } 3540#endif 3541 } 3542 } else { 3543 DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid"); 3544 eRet = OMX_ErrorBadPortIndex; 3545 } 3546 if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING) 3547 && release_output_done() ) { 3548 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it"); 3549 3550 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE"); 3551 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING); 3552 post_event(OMX_CommandPortDisable, 3553 PORT_INDEX_OUT, 3554 OMX_COMPONENT_GENERATE_EVENT); 3555 3556 } 3557 } else { 3558 eRet = OMX_ErrorBadPortIndex; 3559 } 3560 if ((eRet == OMX_ErrorNone) && 3561 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) { 3562 if (release_done()) { 3563 if (dev_stop() != 0) { 3564 DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED"); 3565 eRet = OMX_ErrorHardware; 3566 } 3567 // Send the callback now 3568 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING); 3569 post_event(OMX_CommandStateSet, OMX_StateLoaded, 3570 OMX_COMPONENT_GENERATE_EVENT); 3571 } else { 3572 DEBUG_PRINT_HIGH("in free buffer, release not done, need to free more buffers input %" PRIx64" output %" PRIx64, 3573 m_out_bm_count, m_inp_bm_count); 3574 } 3575 } 3576 3577 return eRet; 3578} 3579 3580 3581/* ====================================================================== 3582 FUNCTION 3583 omx_video::EmptyThisBuffer 3584 3585 DESCRIPTION 3586 This routine is used to push the encoded video frames to 3587 the video decoder. 3588 3589 PARAMETERS 3590 None. 3591 3592 RETURN VALUE 3593 OMX Error None if everything went successful. 3594 3595 ========================================================================== */ 3596OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 3597 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 3598{ 3599 OMX_ERRORTYPE ret1 = OMX_ErrorNone; 3600 unsigned int nBufferIndex ; 3601 3602 dev_set_extradata_cookie((void *)buffer); 3603 DEBUG_PRINT_LOW("ETB: buffer = %p, buffer->pBuffer[%p]", buffer, buffer->pBuffer); 3604 if (m_state != OMX_StateExecuting && 3605 m_state != OMX_StatePause && 3606 m_state != OMX_StateIdle) { 3607 DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State"); 3608 return OMX_ErrorInvalidState; 3609 } 3610 3611 if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) { 3612 DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> buffer is null or buffer size is invalid"); 3613 return OMX_ErrorBadParameter; 3614 } 3615 3616 if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) { 3617 DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> OMX Version Invalid"); 3618 return OMX_ErrorVersionMismatch; 3619 } 3620 3621 if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) { 3622 DEBUG_PRINT_ERROR("ERROR: Bad port index to call empty_this_buffer"); 3623 return OMX_ErrorBadPortIndex; 3624 } 3625 if (!m_sInPortDef.bEnabled) { 3626 DEBUG_PRINT_ERROR("ERROR: Cannot call empty_this_buffer while I/P port is disabled"); 3627 return OMX_ErrorIncorrectStateOperation; 3628 } 3629 3630 nBufferIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr); 3631 3632 if (nBufferIndex > m_sInPortDef.nBufferCountActual ) { 3633 DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]", nBufferIndex); 3634 return OMX_ErrorBadParameter; 3635 } 3636 3637 m_etb_count++; 3638 DEBUG_PRINT_LOW("DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp); 3639 post_event ((unsigned long)hComp,(unsigned long)buffer,m_input_msg_id); 3640 return OMX_ErrorNone; 3641} 3642/* ====================================================================== 3643 FUNCTION 3644 omx_video::empty_this_buffer_proxy 3645 3646 DESCRIPTION 3647 This routine is used to push the encoded video frames to 3648 the video decoder. 3649 3650 PARAMETERS 3651 None. 3652 3653 RETURN VALUE 3654 OMX Error None if everything went successful. 3655 3656 ========================================================================== */ 3657OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp, 3658 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 3659{ 3660 (void)hComp; 3661 OMX_U8 *pmem_data_buf = NULL; 3662 int push_cnt = 0; 3663 unsigned nBufIndex = 0; 3664 OMX_ERRORTYPE ret = OMX_ErrorNone; 3665 encoder_media_buffer_type *media_buffer = NULL; 3666 3667#ifdef _MSM8974_ 3668 int fd = 0; 3669#endif 3670 DEBUG_PRINT_LOW("ETBProxy: buffer->pBuffer[%p]", buffer->pBuffer); 3671 if (buffer == NULL) { 3672 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid buffer[%p]", buffer); 3673 return OMX_ErrorBadParameter; 3674 } 3675 3676 // Buffer sanity checks 3677 if (meta_mode_enable && !mUsesColorConversion) { 3678 //For color-conversion case, we have an internal buffer and not a meta buffer 3679 bool met_error = false; 3680 nBufIndex = buffer - meta_buffer_hdr; 3681 if (nBufIndex >= m_sInPortDef.nBufferCountActual) { 3682 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid meta-bufIndex = %u", nBufIndex); 3683 return OMX_ErrorBadParameter; 3684 } 3685 media_buffer = (encoder_media_buffer_type *)meta_buffer_hdr[nBufIndex].pBuffer; 3686 if (media_buffer) { 3687 if (media_buffer->buffer_type != kMetadataBufferTypeCameraSource && 3688 media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) { 3689 met_error = true; 3690 } else { 3691 if (media_buffer->buffer_type == kMetadataBufferTypeCameraSource) { 3692 if (media_buffer->meta_handle == NULL) 3693 met_error = true; 3694 else { 3695 int nFds = media_buffer->meta_handle->numFds, 3696 nInt = media_buffer->meta_handle->numInts; 3697 met_error = ((nFds == 1 && nInt >= 2) /*normal*/ || 3698 (nFds < 16 && nInt >= nFds*3) /*batch*/) ? false : true; 3699 if (met_error) { 3700 DEBUG_PRINT_ERROR("Unbalanced fds in handle: fds=%d ints=%d", 3701 nFds, nInt); 3702 } 3703 } 3704 } 3705 } 3706 } else 3707 met_error = true; 3708 if (met_error) { 3709 DEBUG_PRINT_ERROR("ERROR: Unkown source/metahandle in ETB call"); 3710 post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD); 3711 return OMX_ErrorBadParameter; 3712 } 3713 } else { 3714 nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr); 3715 if (nBufIndex >= m_sInPortDef.nBufferCountActual) { 3716 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid bufIndex = %u", nBufIndex); 3717 return OMX_ErrorBadParameter; 3718 } 3719 } 3720 3721 pending_input_buffers++; 3722 if (input_flush_progress == true) { 3723 post_event ((unsigned long)buffer,0, 3724 OMX_COMPONENT_GENERATE_EBD); 3725 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Input flush in progress"); 3726 return OMX_ErrorNone; 3727 } 3728#ifdef _MSM8974_ 3729 if (!meta_mode_enable) { 3730 fd = m_pInput_pmem[nBufIndex].fd; 3731 } 3732#endif 3733#ifdef _ANDROID_ICS_ 3734 if (meta_mode_enable && !mUsesColorConversion) { 3735 // Camera or Gralloc-source meta-buffers queued with encodeable color-format 3736 struct pmem Input_pmem_info; 3737 if (!media_buffer) { 3738 DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__); 3739 return OMX_ErrorBadParameter; 3740 } 3741 if (media_buffer->buffer_type == kMetadataBufferTypeCameraSource) { 3742 Input_pmem_info.buffer = media_buffer; 3743 Input_pmem_info.fd = media_buffer->meta_handle->data[0]; 3744#ifdef _MSM8974_ 3745 fd = Input_pmem_info.fd; 3746#endif 3747 Input_pmem_info.offset = media_buffer->meta_handle->data[1]; 3748 Input_pmem_info.size = media_buffer->meta_handle->data[2]; 3749 DEBUG_PRINT_LOW("ETB (meta-Camera) fd = %d, offset = %d, size = %d", 3750 Input_pmem_info.fd, Input_pmem_info.offset, 3751 Input_pmem_info.size); 3752 } else { 3753 private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; 3754 Input_pmem_info.buffer = media_buffer; 3755 Input_pmem_info.fd = handle->fd; 3756#ifdef _MSM8974_ 3757 fd = Input_pmem_info.fd; 3758#endif 3759 Input_pmem_info.offset = 0; 3760 Input_pmem_info.size = handle->size; 3761 DEBUG_PRINT_LOW("ETB (meta-gralloc) fd = %d, offset = %d, size = %d", 3762 Input_pmem_info.fd, Input_pmem_info.offset, 3763 Input_pmem_info.size); 3764 } 3765 if (dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,nBufIndex) != true) { 3766 DEBUG_PRINT_ERROR("ERROR: in dev_use_buf"); 3767 post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD); 3768 return OMX_ErrorBadParameter; 3769 } 3770 } else if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer) 3771#else 3772 if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer) 3773#endif 3774 { 3775 DEBUG_PRINT_LOW("Heap UseBuffer case, so memcpy the data"); 3776 3777 auto_lock l(m_lock); 3778 pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer; 3779 if (pmem_data_buf) { 3780 memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset), 3781 buffer->nFilledLen); 3782 } 3783 DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf"); 3784 } else if (mUseProxyColorFormat) { 3785 // Gralloc-source buffers with color-conversion 3786 fd = m_pInput_pmem[nBufIndex].fd; 3787 DEBUG_PRINT_LOW("ETB (color-converted) fd = %d, size = %u", 3788 fd, (unsigned int)buffer->nFilledLen); 3789 } else if (m_sInPortDef.format.video.eColorFormat == 3790 OMX_COLOR_FormatYUV420SemiPlanar) { 3791 //For the case where YUV420SP buffers are qeueued to component 3792 //by sources other than camera (Apps via MediaCodec), conversion 3793 //to vendor flavoured NV12 color format is required. 3794 if (!dev_color_align(buffer, m_sInPortDef.format.video.nFrameWidth, 3795 m_sInPortDef.format.video.nFrameHeight)) { 3796 DEBUG_PRINT_ERROR("Failed to adjust buffer color"); 3797 post_event((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD); 3798 return OMX_ErrorUndefined; 3799 } 3800 } 3801 if (m_sExtraData && !dev_handle_input_extradata((void *)buffer, fd)) { 3802 DEBUG_PRINT_ERROR("Failed to parse input extradata\n"); 3803#ifdef _ANDROID_ICS_ 3804 omx_release_meta_buffer(buffer); 3805#endif 3806 post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD); 3807 /*Generate an async error and move to invalid state*/ 3808 pending_input_buffers--; 3809 return OMX_ErrorBadParameter; 3810 } 3811#ifdef _MSM8974_ 3812 if (dev_empty_buf(buffer, pmem_data_buf,nBufIndex,fd) != true) 3813#else 3814 if (dev_empty_buf(buffer, pmem_data_buf,0,0) != true) 3815#endif 3816 { 3817 DEBUG_PRINT_ERROR("ERROR: ETBProxy: dev_empty_buf failed"); 3818#ifdef _ANDROID_ICS_ 3819 omx_release_meta_buffer(buffer); 3820#endif 3821 post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD); 3822 /*Generate an async error and move to invalid state*/ 3823 pending_input_buffers--; 3824 if (hw_overload) { 3825 return OMX_ErrorInsufficientResources; 3826 } 3827 return OMX_ErrorBadParameter; 3828 } 3829 return ret; 3830} 3831 3832/* ====================================================================== 3833 FUNCTION 3834 omx_video::FillThisBuffer 3835 3836 DESCRIPTION 3837 IL client uses this method to release the frame buffer 3838 after displaying them. 3839 3840 PARAMETERS 3841 None. 3842 3843 RETURN VALUE 3844 true/false 3845 3846 ========================================================================== */ 3847OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp, 3848 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 3849{ 3850 DEBUG_PRINT_LOW("FTB: buffer->pBuffer[%p]", buffer->pBuffer); 3851 if (m_state != OMX_StateExecuting && 3852 m_state != OMX_StatePause && 3853 m_state != OMX_StateIdle) { 3854 DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State"); 3855 return OMX_ErrorInvalidState; 3856 } 3857 3858 if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) { 3859 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size"); 3860 return OMX_ErrorBadParameter; 3861 } 3862 3863 if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) { 3864 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid"); 3865 return OMX_ErrorVersionMismatch; 3866 } 3867 3868 if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) { 3869 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index"); 3870 return OMX_ErrorBadPortIndex; 3871 } 3872 3873 if (!m_sOutPortDef.bEnabled) { 3874 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled"); 3875 return OMX_ErrorIncorrectStateOperation; 3876 } 3877 3878 post_event((unsigned long) hComp, (unsigned long)buffer,OMX_COMPONENT_GENERATE_FTB); 3879 return OMX_ErrorNone; 3880} 3881 3882/* ====================================================================== 3883 FUNCTION 3884 omx_video::fill_this_buffer_proxy 3885 3886 DESCRIPTION 3887 IL client uses this method to release the frame buffer 3888 after displaying them. 3889 3890 PARAMETERS 3891 None. 3892 3893 RETURN VALUE 3894 true/false 3895 3896 ========================================================================== */ 3897OMX_ERRORTYPE omx_video::fill_this_buffer_proxy( 3898 OMX_IN OMX_HANDLETYPE hComp, 3899 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd) 3900{ 3901 (void)hComp; 3902 OMX_U8 *pmem_data_buf = NULL; 3903 OMX_ERRORTYPE nRet = OMX_ErrorNone; 3904 3905 DEBUG_PRINT_LOW("FTBProxy: bufferAdd->pBuffer[%p]", bufferAdd->pBuffer); 3906 3907 if (bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= (int)m_sOutPortDef.nBufferCountActual) ) { 3908 DEBUG_PRINT_ERROR("ERROR: FTBProxy: Invalid i/p params"); 3909 return OMX_ErrorBadParameter; 3910 } 3911 3912 pending_output_buffers++; 3913 /*Return back the output buffer to client*/ 3914 if ( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) { 3915 DEBUG_PRINT_LOW("o/p port is Disabled or Flush in Progress"); 3916 post_event ((unsigned long)bufferAdd,0, 3917 OMX_COMPONENT_GENERATE_FBD); 3918 return OMX_ErrorNone; 3919 } 3920 3921 if (output_use_buffer && !m_use_output_pmem) { 3922 DEBUG_PRINT_LOW("Heap UseBuffer case"); 3923 pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer; 3924 } 3925 3926 if (dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) { 3927 DEBUG_PRINT_ERROR("ERROR: dev_fill_buf() Failed"); 3928 post_event ((unsigned long)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD); 3929 pending_output_buffers--; 3930 return OMX_ErrorBadParameter; 3931 } 3932 3933 return OMX_ErrorNone; 3934} 3935 3936/* ====================================================================== 3937 FUNCTION 3938 omx_video::SetCallbacks 3939 3940 DESCRIPTION 3941 Set the callbacks. 3942 3943 PARAMETERS 3944 None. 3945 3946 RETURN VALUE 3947 OMX Error None if everything successful. 3948 3949 ========================================================================== */ 3950OMX_ERRORTYPE omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE hComp, 3951 OMX_IN OMX_CALLBACKTYPE* callbacks, 3952 OMX_IN OMX_PTR appData) 3953{ 3954 (void)hComp; 3955 m_pCallbacks = *callbacks; 3956 DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\ 3957 m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone); 3958 m_app_data = appData; 3959 return OMX_ErrorNotImplemented; 3960} 3961 3962 3963/* ====================================================================== 3964 FUNCTION 3965 omx_venc::UseEGLImage 3966 3967 DESCRIPTION 3968 OMX Use EGL Image method implementation <TBD>. 3969 3970 PARAMETERS 3971 <TBD>. 3972 3973 RETURN VALUE 3974 Not Implemented error. 3975 3976 ========================================================================== */ 3977OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp, 3978 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr, 3979 OMX_IN OMX_U32 port, 3980 OMX_IN OMX_PTR appData, 3981 OMX_IN void* eglImage) 3982{ 3983 (void)hComp, (void)bufferHdr, (void)port, (void)appData, (void)eglImage; 3984 DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented"); 3985 return OMX_ErrorNotImplemented; 3986} 3987 3988/* ====================================================================== 3989 FUNCTION 3990 omx_venc::ComponentRoleEnum 3991 3992 DESCRIPTION 3993 OMX Component Role Enum method implementation. 3994 3995 PARAMETERS 3996 <TBD>. 3997 3998 RETURN VALUE 3999 OMX Error None if everything is successful. 4000 ========================================================================== */ 4001OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp, 4002 OMX_OUT OMX_U8* role, 4003 OMX_IN OMX_U32 index) 4004{ 4005 (void)hComp; 4006 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4007 if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 4008 if ((0 == index) && role) { 4009 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 4010 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 4011 } else { 4012 eRet = OMX_ErrorNoMore; 4013 } 4014 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) { 4015 if ((0 == index) && role) { 4016 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE); 4017 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 4018 } else { 4019 DEBUG_PRINT_ERROR("ERROR: No more roles"); 4020 eRet = OMX_ErrorNoMore; 4021 } 4022 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 4023 if ((0 == index) && role) { 4024 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE); 4025 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 4026 } else { 4027 DEBUG_PRINT_ERROR("ERROR: No more roles"); 4028 eRet = OMX_ErrorNoMore; 4029 } 4030 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) { 4031 if ((0 == index) && role) { 4032 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE); 4033 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 4034 } else { 4035 DEBUG_PRINT_ERROR("ERROR: No more roles"); 4036 eRet = OMX_ErrorNoMore; 4037 } 4038 } 4039 if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) { 4040 if ((0 == index) && role) { 4041 strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE); 4042 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 4043 } else { 4044 eRet = OMX_ErrorNoMore; 4045 } 4046 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE)) { 4047 if ((0 == index) && role) { 4048 strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE); 4049 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 4050 } else { 4051 DEBUG_PRINT_ERROR("ERROR: No more roles"); 4052 eRet = OMX_ErrorNoMore; 4053 } 4054 } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) { 4055 if ((0 == index) && role) { 4056 strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE); 4057 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 4058 } else { 4059 DEBUG_PRINT_ERROR("ERROR: No more roles"); 4060 eRet = OMX_ErrorNoMore; 4061 } 4062 } 4063#ifdef _MSM8974_ 4064 else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) { 4065 if ((0 == index) && role) { 4066 strlcpy((char *)role, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE); 4067 DEBUG_PRINT_LOW("component_role_enum: role %s",role); 4068 } else { 4069 DEBUG_PRINT_ERROR("ERROR: No more roles"); 4070 eRet = OMX_ErrorNoMore; 4071 } 4072 } 4073#endif 4074 else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE)) { 4075 if ((0 == index) && role) { 4076 strlcpy((char *)role, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE); 4077 DEBUG_PRINT_LOW("component_role_enum: role %s", role); 4078 } else { 4079 DEBUG_PRINT_ERROR("ERROR: No more roles"); 4080 eRet = OMX_ErrorNoMore; 4081 } 4082 } 4083 else { 4084 DEBUG_PRINT_ERROR("ERROR: Querying Role on Unknown Component"); 4085 eRet = OMX_ErrorInvalidComponentName; 4086 } 4087 return eRet; 4088} 4089 4090 4091 4092 4093/* ====================================================================== 4094 FUNCTION 4095 omx_venc::AllocateDone 4096 4097 DESCRIPTION 4098 Checks if entire buffer pool is allocated by IL Client or not. 4099 Need this to move to IDLE state. 4100 4101 PARAMETERS 4102 None. 4103 4104 RETURN VALUE 4105 true/false. 4106 4107 ========================================================================== */ 4108bool omx_video::allocate_done(void) 4109{ 4110 bool bRet = false; 4111 bool bRet_In = false; 4112 bool bRet_Out = false; 4113 4114 bRet_In = allocate_input_done(); 4115 bRet_Out = allocate_output_done(); 4116 4117 if (bRet_In && bRet_Out) { 4118 bRet = true; 4119 } 4120 4121 return bRet; 4122} 4123/* ====================================================================== 4124 FUNCTION 4125 omx_venc::AllocateInputDone 4126 4127 DESCRIPTION 4128 Checks if I/P buffer pool is allocated by IL Client or not. 4129 4130 PARAMETERS 4131 None. 4132 4133 RETURN VALUE 4134 true/false. 4135 4136 ========================================================================== */ 4137bool omx_video::allocate_input_done(void) 4138{ 4139 bool bRet = false; 4140 unsigned i=0; 4141 4142 if (m_inp_mem_ptr == NULL) { 4143 return bRet; 4144 } 4145 if (m_inp_mem_ptr ) { 4146 for (; i<m_sInPortDef.nBufferCountActual; i++) { 4147 if (BITMASK_ABSENT(&m_inp_bm_count,i)) { 4148 break; 4149 } 4150 } 4151 } 4152 if (i==m_sInPortDef.nBufferCountActual) { 4153 bRet = true; 4154 } 4155 if (i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled) { 4156 m_sInPortDef.bPopulated = OMX_TRUE; 4157 } 4158 return bRet; 4159} 4160/* ====================================================================== 4161 FUNCTION 4162 omx_venc::AllocateOutputDone 4163 4164 DESCRIPTION 4165 Checks if entire O/P buffer pool is allocated by IL Client or not. 4166 4167 PARAMETERS 4168 None. 4169 4170 RETURN VALUE 4171 true/false. 4172 4173 ========================================================================== */ 4174bool omx_video::allocate_output_done(void) 4175{ 4176 bool bRet = false; 4177 unsigned j=0; 4178 4179 if (m_out_mem_ptr == NULL) { 4180 return bRet; 4181 } 4182 4183 if (m_out_mem_ptr ) { 4184 for (; j<m_sOutPortDef.nBufferCountActual; j++) { 4185 if (BITMASK_ABSENT(&m_out_bm_count,j)) { 4186 break; 4187 } 4188 } 4189 } 4190 4191 if (j==m_sOutPortDef.nBufferCountActual) { 4192 bRet = true; 4193 } 4194 4195 if (j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled) { 4196 m_sOutPortDef.bPopulated = OMX_TRUE; 4197 } 4198 return bRet; 4199} 4200 4201/* ====================================================================== 4202 FUNCTION 4203 omx_venc::ReleaseDone 4204 4205 DESCRIPTION 4206 Checks if IL client has released all the buffers. 4207 4208 PARAMETERS 4209 None. 4210 4211 RETURN VALUE 4212 true/false 4213 4214 ========================================================================== */ 4215bool omx_video::release_done(void) 4216{ 4217 bool bRet = false; 4218 DEBUG_PRINT_LOW("Inside release_done()"); 4219 if (release_input_done()) { 4220 if (release_output_done()) { 4221 bRet = true; 4222 } 4223 } 4224 return bRet; 4225} 4226 4227 4228/* ====================================================================== 4229 FUNCTION 4230 omx_venc::ReleaseOutputDone 4231 4232 DESCRIPTION 4233 Checks if IL client has released all the buffers. 4234 4235 PARAMETERS 4236 None. 4237 4238 RETURN VALUE 4239 true/false 4240 4241 ========================================================================== */ 4242bool omx_video::release_output_done(void) 4243{ 4244 bool bRet = false; 4245 unsigned i=0,j=0; 4246 4247 DEBUG_PRINT_LOW("Inside release_output_done()"); 4248 if (m_out_mem_ptr) { 4249 for (; j<m_sOutPortDef.nBufferCountActual; j++) { 4250 if (BITMASK_PRESENT(&m_out_bm_count,j)) { 4251 break; 4252 } 4253 } 4254 if (j==m_sOutPortDef.nBufferCountActual) { 4255 bRet = true; 4256 } 4257 } else { 4258 bRet = true; 4259 } 4260 return bRet; 4261} 4262/* ====================================================================== 4263 FUNCTION 4264 omx_venc::ReleaseInputDone 4265 4266 DESCRIPTION 4267 Checks if IL client has released all the buffers. 4268 4269 PARAMETERS 4270 None. 4271 4272 RETURN VALUE 4273 true/false 4274 4275 ========================================================================== */ 4276bool omx_video::release_input_done(void) 4277{ 4278 bool bRet = false; 4279 unsigned i=0,j=0; 4280 4281 DEBUG_PRINT_LOW("Inside release_input_done()"); 4282 if (m_inp_mem_ptr) { 4283 for (; j<m_sInPortDef.nBufferCountActual; j++) { 4284 if ( BITMASK_PRESENT(&m_inp_bm_count,j)) { 4285 break; 4286 } 4287 } 4288 if (j==m_sInPortDef.nBufferCountActual) { 4289 bRet = true; 4290 } 4291 } else { 4292 bRet = true; 4293 } 4294 return bRet; 4295} 4296 4297OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp, 4298 OMX_BUFFERHEADERTYPE * buffer) 4299{ 4300#ifdef _MSM8974_ 4301 int index = buffer - m_out_mem_ptr; 4302#endif 4303 DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x size = %u", 4304 buffer->pBuffer, (unsigned)buffer->nFlags, (unsigned int)buffer->nFilledLen); 4305 if (buffer == NULL || ((buffer - m_out_mem_ptr) > (int)m_sOutPortDef.nBufferCountActual)) { 4306 return OMX_ErrorBadParameter; 4307 } 4308 4309 pending_output_buffers--; 4310 4311 if(!secure_session) { 4312 extra_data_handle.create_extra_data(buffer); 4313#ifndef _MSM8974_ 4314 if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) { 4315 DEBUG_PRINT_LOW("parsing extradata"); 4316 extra_data_handle.parse_extra_data(buffer); 4317 } 4318#endif 4319 } 4320 4321 /* For use buffer we need to copy the data */ 4322 if (m_pCallbacks.FillBufferDone) { 4323 if (buffer->nFilledLen > 0) { 4324 m_fbd_count++; 4325 4326 if (dev_get_output_log_flag()) { 4327 dev_output_log_buffers((const char*)buffer->pBuffer, buffer->nFilledLen); 4328 } 4329 } 4330 if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) { 4331 if (!dev_handle_output_extradata((void *)buffer)) 4332 DEBUG_PRINT_ERROR("Failed to parse output extradata"); 4333 4334 dev_extradata_log_buffers((char *)(((unsigned long)buffer->pBuffer + buffer->nOffset + 4335 buffer->nFilledLen + 3) & (~3))); 4336 } 4337 m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer); 4338 } else { 4339 return OMX_ErrorBadParameter; 4340 } 4341 return OMX_ErrorNone; 4342} 4343 4344OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp, 4345 OMX_BUFFERHEADERTYPE* buffer) 4346{ 4347 int buffer_index = -1; 4348 4349 buffer_index = buffer - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr); 4350 DEBUG_PRINT_LOW("empty_buffer_done: buffer[%p]", buffer); 4351 if (buffer == NULL || 4352 ((buffer_index > (int)m_sInPortDef.nBufferCountActual))) { 4353 DEBUG_PRINT_ERROR("ERROR in empty_buffer_done due to index buffer"); 4354 return OMX_ErrorBadParameter; 4355 } 4356 4357 pending_input_buffers--; 4358 4359 if (mUseProxyColorFormat && 4360 (buffer_index >= 0 && (buffer_index < (int)m_sInPortDef.nBufferCountActual))) { 4361 if (!pdest_frame && !input_flush_progress && mUsesColorConversion) { 4362 pdest_frame = buffer; 4363 DEBUG_PRINT_LOW("empty_buffer_done pdest_frame address is %p",pdest_frame); 4364 return push_input_buffer(hComp); 4365 } 4366 //check if empty-EOS-buffer is being returned, treat this same as the 4367 //color-conversion case as we queued a color-conversion buffer to encoder 4368 bool handleEmptyEosBuffer = (mEmptyEosBuffer == buffer); 4369 if (mUsesColorConversion || handleEmptyEosBuffer) { 4370 if (handleEmptyEosBuffer) { 4371 mEmptyEosBuffer = NULL; 4372 } 4373 // return color-conversion buffer back to the pool 4374 DEBUG_PRINT_LOW("empty_buffer_done insert address is %p",buffer); 4375 if (!m_opq_pmem_q.insert_entry((unsigned long)buffer, 0, 0)) { 4376 DEBUG_PRINT_ERROR("empty_buffer_done: pmem queue is full"); 4377 return OMX_ErrorBadParameter; 4378 } 4379 } else { 4380 // We are not dealing with color-conversion, Buffer being returned 4381 // here is client's buffer, return it back to client 4382 if (m_pCallbacks.EmptyBufferDone && buffer) { 4383 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer); 4384 DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p", buffer); 4385 } 4386 } 4387 } else if (m_pCallbacks.EmptyBufferDone) { 4388 m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer); 4389 } 4390 return OMX_ErrorNone; 4391} 4392 4393void omx_video::complete_pending_buffer_done_cbs() 4394{ 4395 unsigned long p1; 4396 unsigned long p2; 4397 unsigned long ident; 4398 omx_cmd_queue tmp_q, pending_bd_q; 4399 pthread_mutex_lock(&m_lock); 4400 // pop all pending GENERATE FDB from ftb queue 4401 while (m_ftb_q.m_size) { 4402 m_ftb_q.pop_entry(&p1,&p2,&ident); 4403 if (ident == OMX_COMPONENT_GENERATE_FBD) { 4404 pending_bd_q.insert_entry(p1,p2,ident); 4405 } else { 4406 tmp_q.insert_entry(p1,p2,ident); 4407 } 4408 } 4409 //return all non GENERATE FDB to ftb queue 4410 while (tmp_q.m_size) { 4411 tmp_q.pop_entry(&p1,&p2,&ident); 4412 m_ftb_q.insert_entry(p1,p2,ident); 4413 } 4414 // pop all pending GENERATE EDB from etb queue 4415 while (m_etb_q.m_size) { 4416 m_etb_q.pop_entry(&p1,&p2,&ident); 4417 if (ident == OMX_COMPONENT_GENERATE_EBD) { 4418 pending_bd_q.insert_entry(p1,p2,ident); 4419 } else { 4420 tmp_q.insert_entry(p1,p2,ident); 4421 } 4422 } 4423 //return all non GENERATE FDB to etb queue 4424 while (tmp_q.m_size) { 4425 tmp_q.pop_entry(&p1,&p2,&ident); 4426 m_etb_q.insert_entry(p1,p2,ident); 4427 } 4428 pthread_mutex_unlock(&m_lock); 4429 // process all pending buffer dones 4430 while (pending_bd_q.m_size) { 4431 pending_bd_q.pop_entry(&p1,&p2,&ident); 4432 switch (ident) { 4433 case OMX_COMPONENT_GENERATE_EBD: 4434 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) { 4435 DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!"); 4436 omx_report_error (); 4437 } 4438 break; 4439 4440 case OMX_COMPONENT_GENERATE_FBD: 4441 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) { 4442 DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!"); 4443 omx_report_error (); 4444 } 4445 break; 4446 } 4447 } 4448} 4449 4450#ifdef MAX_RES_720P 4451OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) 4452{ 4453 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4454 if (!profileLevelType) 4455 return OMX_ErrorBadParameter; 4456 4457 if (profileLevelType->nPortIndex == 1) { 4458 if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) { 4459 if (profileLevelType->nProfileIndex == 0) { 4460 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; 4461 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; 4462 } else if (profileLevelType->nProfileIndex == 1) { 4463 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; 4464 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; 4465 } else if (profileLevelType->nProfileIndex == 2) { 4466 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; 4467 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31; 4468 } else { 4469 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", 4470 (int)profileLevelType->nProfileIndex); 4471 eRet = OMX_ErrorNoMore; 4472 } 4473 } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) { 4474 if (profileLevelType->nProfileIndex == 0) { 4475 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; 4476 profileLevelType->eLevel = OMX_VIDEO_H263Level70; 4477 } else { 4478 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", (int)profileLevelType->nProfileIndex); 4479 eRet = OMX_ErrorNoMore; 4480 } 4481 } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 4482 if (profileLevelType->nProfileIndex == 0) { 4483 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; 4484 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 4485 } else if (profileLevelType->nProfileIndex == 1) { 4486 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 4487 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 4488 } else { 4489 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", (int)profileLevelType->nProfileIndex); 4490 eRet = OMX_ErrorNoMore; 4491 } 4492 } 4493 } else { 4494 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %d", (int)profileLevelType->nPortIndex); 4495 eRet = OMX_ErrorBadPortIndex; 4496 } 4497 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d", 4498 (int)profileLevelType->eProfile, (int)profileLevelType->eLevel); 4499 return eRet; 4500} 4501#endif 4502 4503#ifdef MAX_RES_1080P 4504OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType) 4505{ 4506 OMX_ERRORTYPE eRet = OMX_ErrorNone; 4507 if (!profileLevelType) 4508 return OMX_ErrorBadParameter; 4509 4510 if (profileLevelType->nPortIndex == 1) { 4511 if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC) { 4512#if defined _MSM8974_ && !defined _MSM8226_ 4513 if (profileLevelType->nProfileIndex == 0) { 4514 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; 4515 profileLevelType->eLevel = OMX_VIDEO_AVCLevel52; 4516 } else if (profileLevelType->nProfileIndex == 1) { 4517 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; 4518 profileLevelType->eLevel = OMX_VIDEO_AVCLevel52; 4519 } else if (profileLevelType->nProfileIndex == 2) { 4520 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; 4521 profileLevelType->eLevel = OMX_VIDEO_AVCLevel52; 4522 } else if (profileLevelType->nProfileIndex == 3) { 4523 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline; 4524 profileLevelType->eLevel = OMX_VIDEO_AVCLevel52; 4525 } else if (profileLevelType->nProfileIndex == 4) { 4526 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh; 4527 profileLevelType->eLevel = OMX_VIDEO_AVCLevel52; 4528 } else { 4529 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 4530 (unsigned int)profileLevelType->nProfileIndex); 4531 eRet = OMX_ErrorNoMore; 4532 } 4533#else 4534 if (profileLevelType->nProfileIndex == 0) { 4535 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline; 4536 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 4537 4538 } else if (profileLevelType->nProfileIndex == 1) { 4539 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain; 4540 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 4541 } else if (profileLevelType->nProfileIndex == 2) { 4542 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh; 4543 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 4544#ifdef _MSM8226_ 4545 } else if (profileLevelType->nProfileIndex == 3) { 4546 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline; 4547 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4; 4548#endif 4549 } else { 4550 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d", 4551 (int)profileLevelType->nProfileIndex); 4552 eRet = OMX_ErrorNoMore; 4553 } 4554#endif 4555 } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263) { 4556 if (profileLevelType->nProfileIndex == 0) { 4557 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline; 4558 profileLevelType->eLevel = OMX_VIDEO_H263Level70; 4559 } else { 4560 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", (unsigned int)profileLevelType->nProfileIndex); 4561 eRet = OMX_ErrorNoMore; 4562 } 4563 } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4) { 4564 if (profileLevelType->nProfileIndex == 0) { 4565 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple; 4566 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 4567 } else if (profileLevelType->nProfileIndex == 1) { 4568 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple; 4569 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5; 4570 } else { 4571 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", (unsigned int)profileLevelType->nProfileIndex); 4572 eRet = OMX_ErrorNoMore; 4573 } 4574 } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingVP8) { 4575 if (profileLevelType->nProfileIndex == 0) { 4576 profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain; 4577 profileLevelType->eLevel = OMX_VIDEO_VP8Level_Version0; 4578 } else if (profileLevelType->nProfileIndex == 1) { 4579 profileLevelType->eProfile = OMX_VIDEO_VP8ProfileMain; 4580 profileLevelType->eLevel = OMX_VIDEO_VP8Level_Version1; 4581 } else { 4582 DEBUG_PRINT_LOW("VP8: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 4583 (unsigned int)profileLevelType->nProfileIndex); 4584 eRet = OMX_ErrorNoMore; 4585 } 4586 } else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingHEVC) { 4587 if (profileLevelType->nProfileIndex == 0) { 4588 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain; 4589 profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel52; 4590 } else if (profileLevelType->nProfileIndex == 1) { 4591 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10; 4592 profileLevelType->eLevel = OMX_VIDEO_HEVCMainTierLevel52; 4593 } else { 4594 DEBUG_PRINT_LOW("HEVC: get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u", 4595 (unsigned int)profileLevelType->nProfileIndex); 4596 eRet = OMX_ErrorNoMore; 4597 } 4598 } else { 4599 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore"); 4600 eRet = OMX_ErrorNoMore; 4601 } 4602 } else { 4603 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queried on Input port only %u", (unsigned int)profileLevelType->nPortIndex); 4604 eRet = OMX_ErrorBadPortIndex; 4605 } 4606 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%u, Level:%u", 4607 (unsigned int)profileLevelType->eProfile, (unsigned int)profileLevelType->eLevel); 4608 return eRet; 4609} 4610#endif 4611 4612#ifdef USE_ION 4613int omx_video::alloc_map_ion_memory(int size, 4614 struct ion_allocation_data *alloc_data, 4615 struct ion_fd_data *fd_data,int flag) 4616{ 4617 struct venc_ion buf_ion_info; 4618 int ion_device_fd =-1,rc=0,ion_dev_flags = 0; 4619 if (size <=0 || !alloc_data || !fd_data) { 4620 DEBUG_PRINT_ERROR("Invalid input to alloc_map_ion_memory"); 4621 return -EINVAL; 4622 } 4623 4624 ion_dev_flags = O_RDONLY; 4625 ion_device_fd = open (MEM_DEVICE,ion_dev_flags); 4626 if (ion_device_fd < 0) { 4627 DEBUG_PRINT_ERROR("ERROR: ION Device open() Failed"); 4628 return ion_device_fd; 4629 } 4630 4631 if(secure_session) { 4632 alloc_data->len = (size + (SECURE_ALIGN - 1)) & ~(SECURE_ALIGN - 1); 4633 alloc_data->align = SECURE_ALIGN; 4634 alloc_data->flags = flag; 4635 alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID); 4636 if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) { 4637 alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID); 4638 } 4639 DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %u align %u flags %x", 4640 (unsigned int)alloc_data->len, (unsigned int)alloc_data->align, 4641 alloc_data->flags); 4642 } else { 4643 alloc_data->len = (size + (SZ_4K - 1)) & ~(SZ_4K - 1); 4644 alloc_data->align = SZ_4K; 4645 alloc_data->flags = (flag & ION_FLAG_CACHED ? ION_FLAG_CACHED : 0); 4646#ifdef MAX_RES_720P 4647 alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID); 4648#else 4649 alloc_data->heap_id_mask = (ION_HEAP(MEM_HEAP_ID) | 4650 ION_HEAP(ION_IOMMU_HEAP_ID)); 4651#endif 4652 DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %u align %u flags %x", 4653 (unsigned int)alloc_data->len, (unsigned int)alloc_data->align, 4654 alloc_data->flags); 4655 } 4656 4657 rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data); 4658 if (rc || !alloc_data->handle) { 4659 DEBUG_PRINT_ERROR("ION ALLOC memory failed 0x%x", rc); 4660 alloc_data->handle = 0; 4661 close(ion_device_fd); 4662 ion_device_fd = -1; 4663 return ion_device_fd; 4664 } 4665 fd_data->handle = alloc_data->handle; 4666 rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data); 4667 if (rc) { 4668 DEBUG_PRINT_ERROR("ION MAP failed "); 4669 buf_ion_info.ion_alloc_data = *alloc_data; 4670 buf_ion_info.ion_device_fd = ion_device_fd; 4671 buf_ion_info.fd_ion_data = *fd_data; 4672 free_ion_memory(&buf_ion_info); 4673 fd_data->fd =-1; 4674 ion_device_fd =-1; 4675 } 4676 return ion_device_fd; 4677} 4678 4679void omx_video::free_ion_memory(struct venc_ion *buf_ion_info) 4680{ 4681 if (!buf_ion_info) { 4682 DEBUG_PRINT_ERROR("Invalid input to free_ion_memory"); 4683 return; 4684 } 4685 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE, 4686 &buf_ion_info->ion_alloc_data.handle)) { 4687 DEBUG_PRINT_ERROR("ION free failed "); 4688 return; 4689 } 4690 close(buf_ion_info->ion_device_fd); 4691 buf_ion_info->ion_alloc_data.handle = 0; 4692 buf_ion_info->ion_device_fd = -1; 4693 buf_ion_info->fd_ion_data.fd = -1; 4694} 4695#endif 4696 4697#ifdef _ANDROID_ICS_ 4698void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer) 4699{ 4700 if (buffer && meta_mode_enable) { 4701 encoder_media_buffer_type *media_ptr; 4702 struct pmem Input_pmem; 4703 unsigned int index_pmem = 0; 4704 bool meta_error = false; 4705 4706 index_pmem = (buffer - m_inp_mem_ptr); 4707 if (mUsesColorConversion && 4708 (index_pmem < m_sInPortDef.nBufferCountActual)) { 4709 if (!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)) { 4710 DEBUG_PRINT_ERROR("omx_release_meta_buffer dev free failed"); 4711 } 4712 } else { 4713 media_ptr = (encoder_media_buffer_type *) buffer->pBuffer; 4714 if (media_ptr && media_ptr->meta_handle) { 4715 if (media_ptr->buffer_type == kMetadataBufferTypeCameraSource && 4716 media_ptr->meta_handle->numFds == 1 && 4717 media_ptr->meta_handle->numInts >= 2) { 4718 Input_pmem.fd = media_ptr->meta_handle->data[0]; 4719 Input_pmem.buffer = media_ptr; 4720 Input_pmem.size = media_ptr->meta_handle->data[2]; 4721 Input_pmem.offset = media_ptr->meta_handle->data[1]; 4722 DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd, 4723 Input_pmem.offset, 4724 Input_pmem.size); 4725 } else if (media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) { 4726 private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle; 4727 Input_pmem.buffer = media_ptr; 4728 Input_pmem.fd = handle->fd; 4729 Input_pmem.offset = 0; 4730 Input_pmem.size = handle->size; 4731 } else { 4732 meta_error = true; 4733 DEBUG_PRINT_ERROR(" Meta Error set in EBD"); 4734 } 4735 if (!meta_error) 4736 meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN); 4737 if (meta_error) { 4738 DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d", 4739 input_flush_progress); 4740 } 4741 } 4742 } 4743 } 4744} 4745#endif 4746omx_video::omx_c2d_conv::omx_c2d_conv() 4747{ 4748 c2dcc = NULL; 4749 mLibHandle = NULL; 4750 mConvertOpen = NULL; 4751 mConvertClose = NULL; 4752 src_format = NV12_128m; 4753 pthread_mutex_init(&c_lock, NULL); 4754} 4755 4756bool omx_video::omx_c2d_conv::init() 4757{ 4758 bool status = true; 4759 if (mLibHandle || mConvertOpen || mConvertClose) { 4760 DEBUG_PRINT_ERROR("omx_c2d_conv::init called twice"); 4761 status = false; 4762 } 4763 if (status) { 4764 mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY); 4765 if (mLibHandle) { 4766 mConvertOpen = (createC2DColorConverter_t *) 4767 dlsym(mLibHandle,"createC2DColorConverter"); 4768 mConvertClose = (destroyC2DColorConverter_t *) 4769 dlsym(mLibHandle,"destroyC2DColorConverter"); 4770 if (!mConvertOpen || !mConvertClose) 4771 status = false; 4772 } else 4773 status = false; 4774 } 4775 if (!status && mLibHandle) { 4776 dlclose(mLibHandle); 4777 mLibHandle = NULL; 4778 mConvertOpen = NULL; 4779 mConvertClose = NULL; 4780 } 4781 return status; 4782} 4783 4784bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr, 4785 int dest_fd, void *dest_base, void *dest_viraddr) 4786{ 4787 int result; 4788 if (!src_viraddr || !dest_viraddr || !c2dcc || !src_base || !dest_base) { 4789 DEBUG_PRINT_ERROR("Invalid arguments omx_c2d_conv::convert"); 4790 return false; 4791 } 4792 pthread_mutex_lock(&c_lock); 4793 result = c2dcc->convertC2D(src_fd, src_base, src_viraddr, 4794 dest_fd, dest_base, dest_viraddr); 4795 pthread_mutex_unlock(&c_lock); 4796 DEBUG_PRINT_LOW("Color convert status %d",result); 4797 return ((result < 0)?false:true); 4798} 4799 4800bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width, 4801 ColorConvertFormat src, ColorConvertFormat dest,unsigned int src_stride) 4802{ 4803 bool status = false; 4804 pthread_mutex_lock(&c_lock); 4805 if (!c2dcc) { 4806 c2dcc = mConvertOpen(width, height, width, height, 4807 src,dest,0,src_stride); 4808 if (c2dcc) { 4809 src_format = src; 4810 status = true; 4811 } else 4812 DEBUG_PRINT_ERROR("mConvertOpen failed"); 4813 } 4814 pthread_mutex_unlock(&c_lock); 4815 return status; 4816} 4817 4818void omx_video::omx_c2d_conv::close() 4819{ 4820 if (mLibHandle) { 4821 pthread_mutex_lock(&c_lock); 4822 if (mConvertClose && c2dcc) 4823 mConvertClose(c2dcc); 4824 pthread_mutex_unlock(&c_lock); 4825 c2dcc = NULL; 4826 } 4827} 4828omx_video::omx_c2d_conv::~omx_c2d_conv() 4829{ 4830 DEBUG_PRINT_HIGH("Destroy C2D instance"); 4831 if (mLibHandle) { 4832 if (mConvertClose && c2dcc) { 4833 pthread_mutex_lock(&c_lock); 4834 mConvertClose(c2dcc); 4835 pthread_mutex_unlock(&c_lock); 4836 } 4837 dlclose(mLibHandle); 4838 } 4839 c2dcc = NULL; 4840 mLibHandle = NULL; 4841 mConvertOpen = NULL; 4842 mConvertClose = NULL; 4843 pthread_mutex_destroy(&c_lock); 4844} 4845 4846int omx_video::omx_c2d_conv::get_src_format() 4847{ 4848 int format = -1; 4849 if (src_format == NV12_128m) { 4850 format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; 4851 } else if (src_format == RGBA8888) { 4852 format = HAL_PIXEL_FORMAT_RGBA_8888; 4853 } 4854 return format; 4855} 4856 4857bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size) 4858{ 4859 int cret = 0; 4860 bool ret = false; 4861 C2DBuffReq bufferreq; 4862 if (c2dcc) { 4863 bufferreq.size = 0; 4864 pthread_mutex_lock(&c_lock); 4865 cret = c2dcc->getBuffReq(port,&bufferreq); 4866 pthread_mutex_unlock(&c_lock); 4867 DEBUG_PRINT_LOW("Status of getbuffer is %d", cret); 4868 ret = (cret)?false:true; 4869 buf_size = bufferreq.size; 4870 } 4871 return ret; 4872} 4873 4874bool omx_video::is_conv_needed(int hal_fmt, int hal_flags) 4875{ 4876 bool bRet = hal_fmt == HAL_PIXEL_FORMAT_RGBA_8888 && 4877 !(hal_flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED); 4878#ifdef _HW_RGBA 4879 bRet = false; 4880#endif 4881 DEBUG_PRINT_LOW("RGBA conversion %s", bRet ? "Needed":"Not-Needed"); 4882 return bRet; 4883} 4884 4885OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp, 4886 OMX_IN OMX_BUFFERHEADERTYPE* buffer) 4887{ 4888 unsigned nBufIndex = 0; 4889 OMX_ERRORTYPE ret = OMX_ErrorNone; 4890 encoder_media_buffer_type *media_buffer; 4891 private_handle_t *handle = NULL; 4892 DEBUG_PRINT_LOW("ETBProxyOpaque: buffer[%p]", buffer); 4893 4894 if (buffer == NULL) { 4895 DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid buffer[%p]",buffer); 4896 return OMX_ErrorBadParameter; 4897 } 4898 nBufIndex = buffer - meta_buffer_hdr; 4899 if (nBufIndex >= m_sInPortDef.nBufferCountActual) { 4900 DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid bufindex = %u", 4901 nBufIndex); 4902 return OMX_ErrorBadParameter; 4903 } 4904 media_buffer = (encoder_media_buffer_type *)buffer->pBuffer; 4905 if ((!media_buffer || !media_buffer->meta_handle) && 4906 !(buffer->nFlags & OMX_BUFFERFLAG_EOS)) { 4907 DEBUG_PRINT_ERROR("Incorrect Buffer queued media buffer = %p", 4908 media_buffer); 4909 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer); 4910 return OMX_ErrorBadParameter; 4911 } else if (media_buffer) { 4912 handle = (private_handle_t *)media_buffer->meta_handle; 4913 } 4914 4915 if (media_buffer && media_buffer->buffer_type == 4916 kMetadataBufferTypeCameraSource) { 4917 return empty_this_buffer_proxy(hComp, buffer); 4918 } 4919 4920 /*Enable following code once private handle color format is 4921 updated correctly*/ 4922 4923 if (buffer->nFilledLen > 0 && handle) { 4924 if (c2d_opened && handle->format != c2d_conv.get_src_format()) { 4925 c2d_conv.close(); 4926 c2d_opened = false; 4927 } 4928 4929 if (!c2d_opened) { 4930 mUsesColorConversion = is_conv_needed(handle->format, handle->flags); 4931 if (mUsesColorConversion) { 4932 DEBUG_PRINT_INFO("open Color conv forW: %u, H: %u", 4933 (unsigned int)m_sInPortDef.format.video.nFrameWidth, 4934 (unsigned int)m_sInPortDef.format.video.nFrameHeight); 4935 if (!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight, 4936 m_sInPortDef.format.video.nFrameWidth, 4937 RGBA8888, NV12_128m, handle->width)) { 4938 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); 4939 DEBUG_PRINT_ERROR("Color conv open failed"); 4940 return OMX_ErrorBadParameter; 4941 } 4942 c2d_opened = true; 4943#ifdef _MSM8974_ 4944 if (!dev_set_format(NV12_128m)) 4945 DEBUG_PRINT_ERROR("cannot set color format"); 4946#endif 4947 } 4948 } 4949 } 4950 if (input_flush_progress == true) { 4951 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); 4952 DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Input flush in progress"); 4953 return OMX_ErrorNone; 4954 } 4955 4956 if (!psource_frame) { 4957 psource_frame = buffer; 4958 ret = push_input_buffer(hComp); 4959 } else { 4960 if (!m_opq_meta_q.insert_entry((unsigned long)buffer,0,0)) { 4961 DEBUG_PRINT_ERROR("ERROR: ETBProxy: Queue is full"); 4962 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer); 4963 ret = OMX_ErrorBadParameter; 4964 } 4965 } 4966 return ret; 4967} 4968 4969OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp, 4970 struct pmem &Input_pmem_info) 4971{ 4972 4973 OMX_ERRORTYPE ret = OMX_ErrorNone; 4974 unsigned long address = 0,p2,id; 4975 4976 DEBUG_PRINT_LOW("In queue Meta Buffer"); 4977 if (!psource_frame || !pdest_frame) { 4978 DEBUG_PRINT_ERROR("convert_queue_buffer invalid params"); 4979 return OMX_ErrorBadParameter; 4980 } 4981 4982 if (psource_frame->nFilledLen > 0) { 4983 if (dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) { 4984 DEBUG_PRINT_ERROR("ERROR: in dev_use_buf"); 4985 post_event ((unsigned long)psource_frame,0,OMX_COMPONENT_GENERATE_EBD); 4986 ret = OMX_ErrorBadParameter; 4987 } 4988 } 4989 4990 if (ret == OMX_ErrorNone) 4991 ret = empty_this_buffer_proxy(hComp,psource_frame); 4992 4993 if (ret == OMX_ErrorNone) { 4994 psource_frame = NULL; 4995 if (!psource_frame && m_opq_meta_q.m_size) { 4996 m_opq_meta_q.pop_entry(&address,&p2,&id); 4997 psource_frame = (OMX_BUFFERHEADERTYPE* ) address; 4998 } 4999 } else { 5000 // there has been an error and source frame has been scheduled for an EBD 5001 psource_frame = NULL; 5002 } 5003 return ret; 5004} 5005 5006OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp, 5007 struct pmem &Input_pmem_info,unsigned long &index) 5008{ 5009 5010 unsigned char *uva; 5011 OMX_ERRORTYPE ret = OMX_ErrorNone; 5012 unsigned long address = 0,p2,id; 5013 5014 DEBUG_PRINT_LOW("In Convert and queue Meta Buffer"); 5015 if (!psource_frame || !pdest_frame) { 5016 DEBUG_PRINT_ERROR("convert_queue_buffer invalid params"); 5017 return OMX_ErrorBadParameter; 5018 } 5019 if (secure_session) { 5020 DEBUG_PRINT_ERROR("cannot convert buffer during secure session"); 5021 return OMX_ErrorInvalidState; 5022 } 5023 5024 if (!psource_frame->nFilledLen) { 5025 if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS) { 5026 pdest_frame->nFilledLen = psource_frame->nFilledLen; 5027 pdest_frame->nTimeStamp = psource_frame->nTimeStamp; 5028 pdest_frame->nFlags = psource_frame->nFlags; 5029 DEBUG_PRINT_HIGH("Skipping color conversion for empty EOS Buffer " 5030 "header=%p filled-len=%u", pdest_frame, (unsigned int)pdest_frame->nFilledLen); 5031 } else { 5032 pdest_frame->nOffset = 0; 5033 pdest_frame->nFilledLen = 0; 5034 pdest_frame->nTimeStamp = psource_frame->nTimeStamp; 5035 pdest_frame->nFlags = psource_frame->nFlags; 5036 DEBUG_PRINT_LOW("Buffer header %p Filled len size %u", 5037 pdest_frame, (unsigned int)pdest_frame->nFilledLen); 5038 } 5039 } else { 5040 uva = (unsigned char *)mmap(NULL, Input_pmem_info.size, 5041 PROT_READ|PROT_WRITE, 5042 MAP_SHARED,Input_pmem_info.fd,0); 5043 if (uva == MAP_FAILED) { 5044 ret = OMX_ErrorBadParameter; 5045 } else { 5046 if (!c2d_conv.convert(Input_pmem_info.fd, uva, uva, 5047 m_pInput_pmem[index].fd, pdest_frame->pBuffer, pdest_frame->pBuffer)) { 5048 DEBUG_PRINT_ERROR("Color Conversion failed"); 5049 ret = OMX_ErrorBadParameter; 5050 } else { 5051 unsigned int buf_size = 0; 5052 if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size)) 5053 ret = OMX_ErrorBadParameter; 5054 else { 5055 pdest_frame->nOffset = 0; 5056 pdest_frame->nFilledLen = buf_size; 5057 pdest_frame->nTimeStamp = psource_frame->nTimeStamp; 5058 pdest_frame->nFlags = psource_frame->nFlags; 5059 DEBUG_PRINT_LOW("Buffer header %p Filled len size %u", 5060 pdest_frame, (unsigned int)pdest_frame->nFilledLen); 5061 } 5062 } 5063 munmap(uva,Input_pmem_info.size); 5064 } 5065 } 5066 if (dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) { 5067 DEBUG_PRINT_ERROR("ERROR: in dev_use_buf"); 5068 post_event ((unsigned long)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD); 5069 ret = OMX_ErrorBadParameter; 5070 } 5071 if (ret == OMX_ErrorNone) 5072 ret = empty_this_buffer_proxy(hComp,pdest_frame); 5073 if (ret == OMX_ErrorNone) { 5074 m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame); 5075 psource_frame = NULL; 5076 pdest_frame = NULL; 5077 if (!psource_frame && m_opq_meta_q.m_size) { 5078 m_opq_meta_q.pop_entry(&address,&p2,&id); 5079 psource_frame = (OMX_BUFFERHEADERTYPE* ) address; 5080 } 5081 if (!pdest_frame && m_opq_pmem_q.m_size) { 5082 m_opq_pmem_q.pop_entry(&address,&p2,&id); 5083 pdest_frame = (OMX_BUFFERHEADERTYPE* ) address; 5084 DEBUG_PRINT_LOW("pdest_frame pop address is %p",pdest_frame); 5085 } 5086 } else { 5087 // there has been an error and source frame has been scheduled for an EBD 5088 psource_frame = NULL; 5089 } 5090 return ret; 5091} 5092 5093OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp) 5094{ 5095 unsigned long address = 0,p2,id, index = 0; 5096 OMX_ERRORTYPE ret = OMX_ErrorNone; 5097 5098 DEBUG_PRINT_LOW("In push input buffer"); 5099 if (!psource_frame && m_opq_meta_q.m_size) { 5100 m_opq_meta_q.pop_entry(&address,&p2,&id); 5101 psource_frame = (OMX_BUFFERHEADERTYPE* ) address; 5102 } 5103 if (!pdest_frame && m_opq_pmem_q.m_size) { 5104 m_opq_pmem_q.pop_entry(&address,&p2,&id); 5105 pdest_frame = (OMX_BUFFERHEADERTYPE* ) address; 5106 } 5107 while (psource_frame != NULL && pdest_frame != NULL && 5108 ret == OMX_ErrorNone) { 5109 struct pmem Input_pmem_info; 5110 encoder_media_buffer_type *media_buffer; 5111 index = pdest_frame - m_inp_mem_ptr; 5112 if (index >= m_sInPortDef.nBufferCountActual) { 5113 DEBUG_PRINT_ERROR("Output buffer index is wrong %u act count %u", 5114 (unsigned int)index, (unsigned int)m_sInPortDef.nBufferCountActual); 5115 return OMX_ErrorBadParameter; 5116 } 5117 5118 //Meta-Buffer with empty filled-length can contain garbage handle 5119 //Some clients queue such buffers to signal EOS. Handle this case 5120 // separately by queueing an intermediate color-conversion buffer 5121 // and propagate the EOS. 5122 if (psource_frame->nFilledLen == 0 && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) { 5123 return push_empty_eos_buffer(hComp, psource_frame); 5124 } 5125 media_buffer = (encoder_media_buffer_type *)psource_frame->pBuffer; 5126 /*Will enable to verify camcorder in current TIPS can be removed*/ 5127 if (media_buffer->buffer_type == kMetadataBufferTypeCameraSource) { 5128 Input_pmem_info.buffer = media_buffer; 5129 Input_pmem_info.fd = media_buffer->meta_handle->data[0]; 5130 Input_pmem_info.offset = media_buffer->meta_handle->data[1]; 5131 Input_pmem_info.size = media_buffer->meta_handle->data[2]; 5132 DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd, 5133 Input_pmem_info.offset, 5134 Input_pmem_info.size); 5135 ret = queue_meta_buffer(hComp,Input_pmem_info); 5136 } else { 5137 private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle; 5138 Input_pmem_info.buffer = media_buffer; 5139 Input_pmem_info.fd = handle->fd; 5140 Input_pmem_info.offset = 0; 5141 Input_pmem_info.size = handle->size; 5142 m_graphicBufferSize = handle->size; 5143 if (is_conv_needed(handle->format, handle->flags)) 5144 ret = convert_queue_buffer(hComp,Input_pmem_info,index); 5145 else if (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE || 5146 handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m || 5147 handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed || 5148 handle->format == HAL_PIXEL_FORMAT_RGBA_8888 || 5149 handle->format == QOMX_COLOR_Format32bitRGBA8888Compressed) 5150 ret = queue_meta_buffer(hComp,Input_pmem_info); 5151 else 5152 ret = OMX_ErrorBadParameter; 5153 } 5154 } 5155 return ret; 5156} 5157 5158OMX_ERRORTYPE omx_video::push_empty_eos_buffer(OMX_HANDLETYPE hComp, 5159 OMX_BUFFERHEADERTYPE* buffer) { 5160 OMX_BUFFERHEADERTYPE* opqBuf = NULL; 5161 OMX_ERRORTYPE retVal = OMX_ErrorNone; 5162 unsigned index = 0; 5163 5164 DEBUG_PRINT_LOW("In push empty eos buffer"); 5165 do { 5166 if (mUsesColorConversion) { 5167 if (pdest_frame) { 5168 //[1] use a checked out conversion buffer, if one is available 5169 opqBuf = pdest_frame; 5170 pdest_frame = NULL; 5171 } else if (m_opq_pmem_q.m_size) { 5172 //[2] else pop out one from the queue, if available 5173 unsigned long address = 0, p2, id; 5174 m_opq_pmem_q.pop_entry(&address,&p2,&id); 5175 opqBuf = (OMX_BUFFERHEADERTYPE* ) address; 5176 } 5177 index = opqBuf - m_inp_mem_ptr; 5178 } else { 5179 opqBuf = (OMX_BUFFERHEADERTYPE* ) buffer; 5180 index = opqBuf - meta_buffer_hdr; 5181 } 5182 5183 if (!opqBuf || index >= m_sInPortDef.nBufferCountActual) { 5184 DEBUG_PRINT_ERROR("push_empty_eos_buffer: Could not find a " 5185 "color-conversion buffer to queue ! defer until available"); 5186 //[3] else, returning back will defer calling this function again 5187 //until a conversion buffer is returned by the encoder and also 5188 //hold on to the client's buffer 5189 return OMX_ErrorNone; 5190 } 5191 struct pmem Input_pmem_info; 5192 Input_pmem_info.buffer = opqBuf; 5193 Input_pmem_info.fd = m_pInput_pmem[index].fd; 5194 Input_pmem_info.offset = 0; 5195 Input_pmem_info.size = m_pInput_pmem[index].size; 5196 5197 if (dev_use_buf(&Input_pmem_info, PORT_INDEX_IN, 0) != true) { 5198 DEBUG_PRINT_ERROR("ERROR: in dev_use_buf for empty eos buffer"); 5199 retVal = OMX_ErrorBadParameter; 5200 break; 5201 } 5202 5203 //Queue with null pBuffer, as pBuffer in client's hdr can be junk 5204 //Clone the color-conversion buffer to avoid overwriting original buffer 5205 OMX_BUFFERHEADERTYPE emptyEosBufHdr; 5206 memcpy(&emptyEosBufHdr, opqBuf, sizeof(OMX_BUFFERHEADERTYPE)); 5207 emptyEosBufHdr.nFilledLen = 0; 5208 emptyEosBufHdr.nTimeStamp = buffer->nTimeStamp; 5209 emptyEosBufHdr.nFlags = buffer->nFlags; 5210 emptyEosBufHdr.pBuffer = NULL; 5211 if (!mUsesColorConversion && !mUseProxyColorFormat) 5212 emptyEosBufHdr.nAllocLen = m_sInPortDef.nBufferSize; 5213 else if (mUseProxyColorFormat) 5214 emptyEosBufHdr.nAllocLen = m_graphicBufferSize > 0 ? m_graphicBufferSize : m_sInPortDef.nBufferSize; 5215 if (dev_empty_buf(&emptyEosBufHdr, 0, index, m_pInput_pmem[index].fd) != true) { 5216 DEBUG_PRINT_ERROR("ERROR: in dev_empty_buf for empty eos buffer"); 5217 dev_free_buf(&Input_pmem_info, PORT_INDEX_IN); 5218 retVal = OMX_ErrorBadParameter; 5219 break; 5220 } 5221 mEmptyEosBuffer = opqBuf; 5222 } while(false); 5223 5224 //return client's buffer regardless since intermediate color-conversion 5225 //buffer is sent to the the encoder 5226 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer); 5227 --pending_input_buffers; 5228 return retVal; 5229} 5230