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