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