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