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