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