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