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