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