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