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