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