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